// Thermokon Sensortechnik GmbH // Payload Decoder for Thermokon LoRaWAN devices // Template: Adaption to corresponding NS/AS necessary // -Revision B- // -Subject to change without further notice! //********************************************************* // Changelog: - Added Identifiers for addtitional features (eg. NOVOS 3 INC EPD,...) // - Removed Identifiers which were not used // - Changed objectnames for quick access (1-Byte) identifier //********************************************************* // Questions or remarks:support@thermokon.de //Decoder Mode var DecoderLegacyMode = false; //Only set to "true" if former object identifier must be used var LPP_S_TEMP_0 = 0x0010; var LPP_S_RHUM_0 = 0x0011; var LPP_S_CO2_0 = 0x0012; var LPP_S_VOC_0 = 0x0013; var LPP_S_MOISTURE_0 = 0x0014; var LPP_S_ATM_P_0 = 0x0030; var LPP_S_DIF_P_0 = 0x0031; var LPP_S_FLOW_0 = 0x0032; var LPP_S_LIGHT_0 = 0x0040; var LPP_S_OCCU_0 = 0x0041; var LPP_S_REED_0 = 0x0050; var LPP_S_CONDENSATION_0 = 0x0051; var LPP_S_VBAT_0 = 0x0054; var LPP_S_BUTTON_0 = 0x0055; var LPP_S_DI_0 = 0x0058; var LPP_S_SETPOINT_0 = 0x0063; var LPP_TEMP_1 = 0x9100; var LPP_MOISTURE_1 = 0x9140; var LPP_DIF_P_1 = 0x9310; var LPP_FLOW_1 = 0x9320; var LPP_OCCU_1 = 0x9410; var LPP_REED_1 = 0x9500; var LPP_BUTTON_1 = 0x9550; var LPP_DI_1 = 0x9580; var LPP_SETPOINT_1 = 0x9630; var LPP_TEMP_2 = 0xA100; var LPP_DEV_KEY = 0xC000; var LPP_EPD_VALUE_EXT_OVERLOAD_0 = 0xC194; var LPP_EPD_VALUE_EXT_OVERLOAD_1 = 0xC19C; var LPP_EPD_VALUE_EXT_OVERLOAD_2 = 0xC1A4; var LPP_EPD_VALUE_EXT_OVERLOAD_3 = 0xC1AC; var LPP_FORCED_UPLINK = 0xC230; function u16_to_s16(u16) { var s16 = u16&0xFFFF; if (0x8000 & s16){s16 = - (0x010000 - s16);} return s16; } function u8_to_s8(u8) { var s8=u8&0xFF; if (0x80 & s8) {s8 = - (0x0100 - s8);} return s8; } function DecodeLPPPayload(data) { var obj = {}; for(i=0;i> 1;} else if(DecoderLegacyMode==true) {obj.OCCU0_STATE = data[i] & 0x01; obj.OCCU0_CNT = data[i] >> 1;} break; case LPP_S_REED_0: if(DecoderLegacyMode==false) {obj.REED_0_STATE = data[i] & 0x01; obj.REED_0_CNT = data[i] >> 1;} else if(DecoderLegacyMode==true) {obj.REED0_STATE = data[i] & 0x01; obj.REED0_CNT = data[i] >> 1;} break; case LPP_S_CONDENSATION_0: if(DecoderLegacyMode==false) {obj.CONDENSATION_0_STATE = (data[i] >>> 7); obj.CONDENSATION_0_RAW = (u16_to_s16(data[i] << 8 | data[i+1]) / 1)&0x0FFF; i++;} else if(DecoderLegacyMode==true) {obj.CONDENSATION_STATE = (data[i] >>> 7); obj.CONDENSATION_RAW = (u16_to_s16(data[i] << 8 | data[i+1]) / 1)&0x0FFF; i++;} break; case LPP_S_VBAT_0: if(DecoderLegacyMode==false) {obj.VBAT_0 = data[i] / (1.0/20);} else if(DecoderLegacyMode==true) {obj.VBAT = data[i] / (1.0/20);} break; case LPP_S_BUTTON_0: if(data[i]>=2) {obj.BUTTON_0_PRESSED = 1} else {obj.BUTTON_0_PRESSED = 0} if (data[i] & 0x01 >= 1) {obj.BUTTON_0_LAST_TYPE = "Long Press"} else {obj.BUTTON_0_LAST_TYPE = "Short Press"} obj.BUTTON_0_CNT = data[i] >> 1; break; case LPP_S_DI_0: obj.DI_0_STATE = data[i] & 0x01; obj.DI_0_CNT = data[i] >> 1; break; case LPP_S_SETPOINT_0: if(DecoderLegacyMode==false) {obj.SETPOINT_0 = data[i] / 1;} else if(DecoderLegacyMode==true) {obj.SETPOINT = data[i] / 1;} break; case LPP_TEMP_1: obj.TEMP_1 = u16_to_s16(data[i] << 8 | data[i+1]) / 10; i++; break; case LPP_MOISTURE_1: obj.MOISTURE_1 = (data[i] << 8 | data[i+1]) / 1; i++; break; case LPP_DIF_P_1 : obj.DIF_P_1 = u16_to_s16((data[i]<<8 | data[i+1]) / 1) i++; break; case LPP_FLOW_1: obj.FLOW_1 = (data[i]<<8 | data[i+1]) / 1; i++; break; case LPP_REED_1: if(DecoderLegacyMode==false) {obj.REED_1_STATE = data[i] & 0x01; obj.REED_1_CNT = data[i] >> 1;} else if(DecoderLegacyMode==true) {obj.REED1_STATE = data[i] & 0x01; obj.REED1_CNT = data[i] >> 1;} break; case LPP_BUTTON_1: if(data[i]>=2) {obj.BUTTON_1_PRESSED = 1} else {obj.BUTTON_1_PRESSED = 0} if (data[i] & 0x01 >= 1) {obj.BUTTON_1_LAST_TYPE = "Long Press"} else {obj.BUTTON_1_LAST_TYPE = "Short Press"} obj.BUTTON_1_CNT = data[i] >> 1; break; case LPP_DI_1: obj.DI_1_STATE = data[i] & 0x01; obj.DI_1_CNT = data[i] >> 1; break; case LPP_SETPOINT_1: obj.SETPOINT_1 = (data[i] << 8 | data[i+1]) / 10; i++; break; case LPP_TEMP_2: obj.TEMP_2 = u16_to_s16(data[i] << 8 | data[i+1]) / 10; i++; break; case LPP_DEV_KEY: obj.DEV_KEY = (data[i] << 8 | data[i+1]) / 1; i++; break; case LPP_EPD_VALUE_EXT_OVERLOAD_0: obj.EPD_VALUE_EXT_OVERLOAD_0 = u16_to_s16(data[i] << 8 | data[i+1]) / 1; i++; break; case LPP_EPD_VALUE_EXT_OVERLOAD_1: obj.EPD_VALUE_EXT_OVERLOAD_1 = u16_to_s16(data[i] << 8 | data[i+1]) / 1; i++; break; case LPP_EPD_VALUE_EXT_OVERLOAD_2: obj.EPD_VALUE_EXT_OVERLOAD_2 = u16_to_s16(data[i] << 8 | data[i+1]) / 1; i++; break; case LPP_EPD_VALUE_EXT_OVERLOAD_3: obj.EPD_VALUE_EXT_OVERLOAD_3 = u16_to_s16(data[i] << 8 | data[i+1]) / 1; i++; break; case LPP_FORCED_UPLINK: obj.FORCED_UPLINK = (data[i] << 8 | data[i+1]) / 1; i++; break; default: //somthing is wrong with data i = data.length; break; } } return obj; } function decodeUplink(input) { var warnings = []; warnings.push(); var data = DecodeLPPPayload(input.bytes); return {data,warnings}; }