diff --git a/STM32CubeIDE/.project b/STM32CubeIDE/.project index e8fa120..44dd590 100644 --- a/STM32CubeIDE/.project +++ b/STM32CubeIDE/.project @@ -32,6 +32,11 @@ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + Doc/as923_jp_decoder.js + 1 + copy_PARENT/as923_jp_decoder.js + Doc/readme.txt 1 diff --git a/as923_jp_decoder.js b/as923_jp_decoder.js new file mode 100644 index 0000000..559af9b --- /dev/null +++ b/as923_jp_decoder.js @@ -0,0 +1,126 @@ +// Decode decodes an array of bytes into an object. +// - fPort contains the LoRaWAN fPort number +// - bytes is an array of bytes, e.g. [225, 230, 255, 0] +// - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string) +// The function must return an object, e.g. {"temperature": 22.5} +function Decode(fPort, bytes, variables) { + // O5 Door contact sensor + if (fPort === 4) { + return [ + { + led_state: bytes[0] === 0 ? "Off" : "On", + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + hw_code: bytes[3], + battery_level: bytes[4] + "%", + size_value: bytes[5], + HALL_1_state: bytes[6] === 1 ? "Door_Open" : "Door_Close", + HALL_2_state: bytes[7] === 1 ? "Door_Open" : "Door_Close", + } + ]; + } + // heart-beat of O5 + else if (fPort === 5) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[4] + " %", + } + ]; + } + // R4 soap/sanitizer sensor + else if (fPort === 7) { + return [ + { + led_state: bytes[0] === 0 ? "Off" : "On", + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + hw_code: bytes[3], + battery_level: bytes[4] + "%", + size_value: bytes[5], + measure_tech: bytes[6] === 0 ? "Capacitive" : "Other", + liquid_level_event: bytes[7] === 0 ? "Liquid Detected" : "No Liquid", + } + ]; + } + // R4 soap/sanitizer heart-beat + else if (fPort === 8) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[1] + " %", + } + ]; + } + // R1D dual roll toilet paper sensor + else if (fPort === 57) { + return [ + { + led_state: bytes[0] === 0 ? "Off" : "On", + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + hw_code: bytes[3], + battery_level: bytes[4] + "%", + size_value: bytes[5], + distance_1_mm: bytes[6] << 8 | bytes[7], + distance_2_mm: bytes[8] << 8 | bytes[9], + distance_unit: "mm", + } + ]; + } + // R1D, Heart-beat + else if (fPort === 58) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[4] + " %", + } + ]; + } + // R5 waste bin sensor + else if (fPort === 11) { + return [ + { + led_state: bytes[0] === 0 ? "Off" : "On", + mtm_code_1: bytes[1], + mtm_code_2: bytes[2], + hw_code: bytes[3], + battery_level: bytes[4] + "%", + size_value: bytes[5], + distance_1_mm: (bytes[6] << 8 | bytes[7]), + //distance_2_mm:bytes[8]*256+bytes[9], + //distance_3_mm:bytes[10]*256+bytes[11], + distance_unit: "mm", + } + ]; + } + // R5, Heart-beat + else if (fPort === 12) { + return [ + { + led_state: (bytes[0] & 0x7f) === 0 ? "Off" : "On", + battery_level: bytes[4] + " %", + } + ]; + } + // UPLINK, RFAC + else if (fPort === 1) { + var data = {}; + data.length = bytes.length; + if (bytes[0] === 0x59) { + if (bytes[1] === 0x44) { + data.Uplink_interval = (bytes[2] - 0x30) * 60 + (bytes[3] - 0x30); + data.Uplink_interval_unit = String.fromCharCode(bytes[4]); + } + else if (bytes[1] === 0x53) { + data.Heart_Beat_interval = (bytes[2] - 0x30) * 60 + (bytes[3] - 0x30); + data.Heart_Beat_interval_unit = String.fromCharCode(bytes[4]); + } + } + else if ((bytes[0] === 0x41) && (bytes[1] === 0x43)) { + data.RFAC = "OK"; + } + + return { "Yunhorn_SmarToilets_data": data }; + } +} \ No newline at end of file