function decodeUplink(input) { var data={}; var stringHex = bytesString(input.bytes); var octetTypeProduit = parseInt(stringHex.substring(0,2),16); var octetTypeMessage = parseInt(stringHex.substring(2,4),16); function bytesString(input) { var bufferString=''; var decToString=''; for(var i=0; i<input.length;i++) { decToString = input[i].toString(16).padStart(2,'0') bufferString=bufferString.concat(decToString) } return bufferString; } function typeOfProduct(octetTypeProduit) { if(octetTypeProduit==0xA3){return "ATMO"}; if(octetTypeProduit==0xA4){return "SENSE"}; if(octetTypeProduit==0xA5){return "AERO"}; if(octetTypeProduit==0xA6){return "PMI"}; if(octetTypeProduit==0xA7){return "AERO CO2"}; } function typeOfMessage(octetTypeMessage) { var message_name =["Reserved","Real Time","Product Status","Product Configuration" ,"Keepalive","Button Press"]; return message_name[octetTypeMessage]; } function dataOutput(octetTypeMessage) { outputTypeMessage=["reserved",realTimeDataOutput(stringHex),productStatusDataOutput(stringHex),productConfigurationDataOutput(stringHex),keepaliveDataOutput(stringHex),buttonPressDataOutput(stringHex)] return outputTypeMessage[octetTypeMessage] } ///////////////////////////////////////////////////////// /// Real Time functions //////////////////////////////////////////////////////// function pm(a) { if(a == 2047){return "Error"} else{ return{"value":a,"unit":"ug/m3"}} } function temperature(a) { if(a == 1023){return "Error"} else{ return{"value":((a*0.1)-30),"unit":"°C"}} } function humidity(a) { if(a == 255){return "Error"} else{ return{"value":(a*0.5),"unit":"%RH"}} } function co2(a) { if(a == 16383){return "Error"} else{ return{"value":a,"unit":"ppm"}} } function cov(a) { if(a == 16383){return "Error"} else{ return{"value":a,"unit":"ug/m3"}} } function formaldehyde(a) { if(a == 1023){return "Error"} else{ return{"value":a,"unit":"ppb"}} } function luminosity(a) { if(a == 255){return "Error"} else{ return{"value":a*5,"unit":"lux"}} } function noise(a) { if(a == 127){return "Error"} else{ return{"value":a,"unit":"dB"}} } function occupancy(a) { if(a == 255){return "Error"} else{ return{"value":a,"unit":"%"}} } function pressure(a) { if(a == 1024){return "Error"} else{ return{"value":a+300,"unit":"hPa"}} } /////////////////////////////////////////////////////////////// /////////////Product Status functions /////////////////////////////////////////////////////////////// function hwStatus(a) { if(a === 0){return "Hardware Ok"} if(a == 1){return "Hardware fault"} } function sensorStatus(a) { if(a === 0){return "Sensor Ok"} if(a == 1){return "Sensor fault"} if(a == 2){return "Sensor not populated"} if(a == 3){return "Sensor end of life"} } function joinRequest(a) { if(a === 0){return "No join request scheduled"} if(a == 1){return "join request scheduled"} } function productActivationTimeCounter(a) { if(a == 255){return "Error"} else{ return{"value":a,"unit":"month"}} } /////////////////////////////////////////////////////////////// /////////////Product Configuration functions /////////////////////////////////////////////////////////////// function reconfigurationSource(a) { if(a === 0){return "NFC"} if(a == 1){return "Downlink"} if(a == 2){return "Product Start-Up"} if(a == 3){return "RFU"} } function reconfigurationStatus(a) { if(a === 0){return "Total Sucess"} if(a == 1){return "Partial Sucess"} if(a == 2){return "Total Failure"} if(a == 3){return "RFU"} } function active(a) { if(a === 0){return "Not active"} if(a == 1){return "Active"} } function ledFunction(a) { if(a === 0){return "Global air quality"} if(a == 1){return "CO2 Level"} } function nfc(a) { if(a == 0){return "Discoverable"} if(a == 1){return "Not discoverable"} } function lora(a) { if(a == 0){return "EU68"} if(a > 0){return "RFU"} } function measuringPeriod(a) { return{"value":a,"unit":"minutes"} } function keepalivePeriod(a) { return{"value":a,"unit":"hours"} } function co2Threshold(a) { return{"value":a*20,"unit":"ppm"} } /////////////////////////////////////////////////////////////////////// ////// Product message decoding //////////////////////////////////////////////////////////////////// function realTimeDataOutput(stringHex) { var data_pm1 = (parseInt(stringHex.substring(4,7),16)>>1)&0x7FF; var data_pm2_5 = (parseInt(stringHex.substring(6,10),16)>>2)&0x7FF; var data_pm10 = (parseInt(stringHex.substring(9,13),16)>>3)&0x7FF; var data_temp = (parseInt(stringHex.substring(12,15),16)>>1)&0x3FF; var data_hum = (parseInt(stringHex.substring(14,17),16)>>1)&0xFF; var data_co2 = (parseInt(stringHex.substring(16,21),16)>>3)&0x3FFF; var data_cov = (parseInt(stringHex.substring(20,24),16)>>1)&0x3FFF; var data_formaldehyde = (parseInt(stringHex.substring(23,27),16)>>3)&0x3FF; var data_lum = (parseInt(stringHex.substring(33,36),16)>>3)&0xFF; var data_avg_noise = (parseInt(stringHex.substring(35,37),16))&0x7F; var data_peak_noise = (parseInt(stringHex.substring(37,39),16)>>1)&0x7F; var data_occupancy_rate = (parseInt(stringHex.substring(38,41),16)>>1)&0xFF; var data_pressure = (parseInt(stringHex.substring(40,44),16)>>3)&0x3FF; data = {"typeOfProduct": typeOfProduct(octetTypeProduit), "typeOfMessage": typeOfMessage(octetTypeMessage), "pm1":pm(data_pm1), "pm2_5":pm(data_pm2_5), "pm10":pm(data_pm10), "temperature":temperature(data_temp), "humidity":humidity(data_hum), "co2":co2(data_co2), "cov":cov(data_cov), "formaldehyde":formaldehyde(data_formaldehyde), "luminosity":luminosity(data_lum), "average noise":noise(data_avg_noise), "peak noise":noise(data_peak_noise), "occupancy rate":occupancy(data_occupancy_rate), "pressure":pressure(data_pressure) } return data; } function productStatusDataOutput(stringHex) { var data_hw_version = (parseInt(stringHex.substring(4,6),16)) & 0xFF; var data_sw_version = (parseInt(stringHex.substring(6,8),16)) & 0xFF; var data_hw_status = (parseInt(stringHex.substring(13,14),16)>>3) & 0x01; var data_pm_status = (parseInt(stringHex.substring(13,14),16)>>1) & 0x03; var data_temp_status = (parseInt(stringHex.substring(13,15),16)>>3) & 0x03; var data_formaldehyde_status = (parseInt(stringHex.substring(14,15),16)>>1) & 0x03; var data_co2_status = (parseInt(stringHex.substring(14,16),16)>>3) & 0x03; var data_cov_status = (parseInt(stringHex.substring(15,16),16)>>1) & 0x03; var data_pir_status = (parseInt(stringHex.substring(15,17),16)>>3) & 0x03; var data_micro_status = (parseInt(stringHex.substring(16,17),16)>>1) & 0x03; var data_pressure_status = (parseInt(stringHex.substring(16,18),16)>>3) & 0x03; var data_accel_status = (parseInt(stringHex.substring(17,18),16)>>1) & 0x03; var data_lum_status = (parseInt(stringHex.substring(17,19),16)>>3) & 0x03; var data_pending_join = (parseInt(stringHex.substring(18,19),16)>>2) & 0x03; var data_time_activation = (parseInt(stringHex.substring(18,21),16)>>2) & 0xFF; data = {"typeOfProduct": typeOfProduct(octetTypeProduit), "typeOfMessage": typeOfMessage(octetTypeMessage), "hwVersion":data_hw_version, "swVersion":data_sw_version*0.1, "hardwareStatus":hwStatus(data_hw_status), "pmSensorStatus":sensorStatus(data_pm_status), "tempHumSensorStatus":sensorStatus(data_temp_status), "formaldehydeSensorStatus":sensorStatus(data_formaldehyde_status), "co2SensorStatus":sensorStatus(data_co2_status), "covpmSensorStatus":sensorStatus(data_cov_status), "pirSensorStatus":sensorStatus(data_pir_status), "microSensorStatus":sensorStatus(data_micro_status), "pressureSensorStatus":sensorStatus(data_pressure_status), "accelerometerSensorStatus":sensorStatus(data_accel_status), "luminositySensorStatus":sensorStatus(data_lum_status), "pendingJoinStatus":joinRequest(data_pending_join), "timeSinceActivation":productActivationTimeCounter(data_time_activation) } return data; } function productConfigurationDataOutput(stringHex) { var data_reconfiguration_source = (parseInt(stringHex.substring(4,5),16)>>2)&0x03; var data_reconfiguration_status = (parseInt(stringHex.substring(4,5),16))&0x03; var data_led_enable = (parseInt(stringHex.substring(5,6),16)>>3)&0x01; var data_led_function = (parseInt(stringHex.substring(5,6),16)>>1)&0x03; var data_average_level_indication = (parseInt(stringHex.substring(5,6),16))&0x01; var data_button_notification = (parseInt(stringHex.substring(6,7),16)>>3)&0x01; var data_keepalive_enable = (parseInt(stringHex.substring(6,7),16)>>2)&0x01; var data_nfc_status = (parseInt(stringHex.substring(6,7),16))&0x03; var data_lora_regions = (parseInt(stringHex.substring(7,8),16))&0x07; var data_measuring_period = (parseInt(stringHex.substring(8,10),16))&0xFF; var data_co2_avg_threshold = (parseInt(stringHex.substring(14,16),16))&0xFF; var data_co2_high_threshold = (parseInt(stringHex.substring(16,18),16))&0xFF; data = {"typeOfProduct": typeOfProduct(octetTypeProduit), "typeOfMessage": typeOfMessage(octetTypeMessage), "reconfigurationSource":reconfigurationSource(data_reconfiguration_source), "reconfigurationStatus":reconfigurationStatus(data_reconfiguration_status), "ledEnable":active(data_led_enable), "ledFunction":ledFunction(data_led_function), "averageLevelIndication":active(data_average_level_indication), "buttonNotification":active(data_button_notification), "keepaliveEnable":active(data_keepalive_enable), "nfcStatus":nfc(data_nfc_status), "loraRegions":lora(data_lora_regions), "measuringPeriod":measuringPeriod(data_measuring_period), "co2AverageThreshold":co2Threshold(data_co2_avg_threshold), "co2HighThreshold":co2Threshold(data_co2_high_threshold) } return data; } function keepaliveDataOutput(stringHex) { data = { "typeOfProduct": typeOfProduct(octetTypeProduit), "typeOfMessage": typeOfMessage(octetTypeMessage) }; return data; } function buttonPressDataOutput(stringHex) { data = {"typeOfProduct": typeOfProduct(octetTypeProduit), "typeOfMessage": typeOfMessage(octetTypeMessage) } return data; } data=dataOutput(octetTypeMessage); return {data}; }