diff --git a/scripts/downlink_formatter.js b/scripts/downlink_formatter.js new file mode 100644 index 0000000..b9c1010 --- /dev/null +++ b/scripts/downlink_formatter.js @@ -0,0 +1,431 @@ +/////////////////////////////////////////////////////////////////////////////// +// downlink_formatter.js +// +// Bresser 868 MHz Weather Sensor Radio Receiver +// based on ESP32 and SX1262/SX1276 - +// sends data to a LoRaWAN network (e.g. The Things Network) +// +// This script allows to send downlink data to the The Things Network using +// parameters encoded in JSON format. +// The FPort must be set to the command. +// +/// Commands: +// ---------- +// (see constants for ports below) +// port = CMD_SET_WS_TIMEOUT, {"timeout": } +// port = CMD_SET_SLEEP_INTERVAL, {"sleep_interval": } +// port = CMD_SET_SLEEP_INTERVAL_LONG, {"sleep_interval_long": } +// port = CMD_GET_DATETIME, {"cmd": "CMD_GET_DATETIME"} / payload = 0x00 +// port = CMD_SET_DATETIME, {"epoch": } +// port = CMD_RESET_RAINGAUGE, {"reset_flags": } +// port = CMD_GET_LW_CONFIG, {"cmd": "CMD_GET_LW_CONFIG"} / payload = 0x00 +// port = CMD_GET_WS_TIMEOUT, {"cmd": "CMD_GET_WS_TIMEOUT" / payload = 0x00 +// port = CMD_SET_WS_TIMEOUT, {"ws_timeout": } +// port = CMD_GET_SENSORS_INC, {"cmd": "CMD_GET_SENSORS_INC"} / payload = 0x00 +// port = CMD_SET_SENSORS_INC, {"sensors_inc": [, ..., ]} +// port = CMD_GET_SENSORS_EXC, {"cmd": "CMD_GET_SENSORS_EXC"} / payload = 0x00 +// port = CMD_SET_SENSORS_EXC, {"sensors_exc": [, ..., ]} +// port = CMD_GET_BLE_ADDR, {"cmd": "CMD_GET_BLE_ADDR"} / payload = 0x00 +// port = CMD_SET_BLE_ADDR, {"ble_addr": [, ..., ]} +// +// Responses: +// ----------- +// (The response uses the same port as the request.) +// CMD_GET_LW_CONFIG {"sleep_interval": , +// "sleep_interval_long": } +// +// CMD_GET_DATETIME {"epoch": , "rtc_source": } +// +// CMD_GET_WS_TIMEOUT {"ws_timeout": } +// +// CMD_GET_SENSORS_INC {"sensors_inc": [, ...]} +// +// CMD_GET_SENSORS_EXC {"sensors_exc"}: [, ...]} +// +// CMD_GET_BLE_ADDR {"ble_addr": [, ...]} +// +// : 0...255 +// : 0...65535 +// : 0...65535 +// : unix epoch time, see https://www.epochconverter.com/ ( / "0x....") +// : 0...15 (1: hourly / 2: daily / 4: weekly / 8: monthly) / "0x0"..."0xF" +// : 0x00: GPS / 0x01: RTC / 0x02: LORA / 0x03: unsynched / 0x04: set (source unknown) +// : e.g. "0xDEADBEEF" +// : e.g. "0xDEADBEEF" +// : e.g. "DE:AD:BE:EF:12:23" +// +// +// Based on: +// --------- +// https://www.thethingsindustries.com/docs/integrations/payload-formatters/javascript/downlink/ +// +// created: 08/2023 +// +// +// MIT License +// +// Copyright (c) 2023 Matthias Prinke +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// +// History: +// 20230821 Created +// 20240420 Updated for BresserWeatherSensorLW, +// renamed from downlink_formatter.js +// +// ToDo: +// - +// +/////////////////////////////////////////////////////////////////////////////// + +// Commands +const CMD_SET_SLEEP_INTERVAL = 0xA8; +const CMD_SET_SLEEP_INTERVAL_LONG = 0xA9; +const CMD_GET_DATETIME = 0x86; +const CMD_SET_DATETIME = 0x88; +const CMD_GET_LW_CONFIG = 0xB1; +const CMD_SET_WS_TIMEOUT = 0xC1; +const CMD_RESET_RAINGAUGE = 0xC3; +const CMD_GET_SENSORS_INC = 0xC4; +const CMD_SET_SENSORS_INC = 0xC5; +const CMD_GET_SENSORS_EXC = 0xC6; +const CMD_SET_SENSORS_EXC = 0xC7; +const CMD_GET_BLE_ADDR = 0xC8; +const CMD_SET_BLE_ADDR = 0xC9; + + +// Source of Real Time Clock setting +var rtc_source_code = { + 0x00: "GPS", + 0x01: "RTC", + 0x02: "LORA", + 0x03: "unsynched", + 0x04: "set (source unknown)" +}; + +function bytesToInt(bytes) { + var i = 0; + for (var x = 0; x < bytes.length; x++) { + i |= +(bytes[x] << (x * 8)); + } + return i; +} + +// Big Endian +function bytesToIntBE(bytes) { + var i = 0; + for (var x = 0; x < bytes.length; x++) { + i |= +(bytes[x] << ((bytes.length - 1 - x) * 8)); + } + return i; +} + +function uint8(bytes) { + if (bytes.length !== 1) { + throw new Error('uint8 must have exactly 1 byte'); + } + return bytesToInt(bytes); +} + +function uint16BE(bytes) { + if (bytes.length !== 2) { + throw new Error('uint16BE must have exactly 2 bytes'); + } + return bytesToIntBE(bytes); +} + +function uint32BE(bytes) { + if (bytes.length !== 4) { + throw new Error('uint32BE must have exactly 4 bytes'); + } + return bytesToIntBE(bytes); +} + +function mac48(bytes) { + var res = []; + var size = bytes.length; + var j = 0; + for (var i = 0; i < bytes.length; i += 6) { + res[j++] = bytes[i].toString(16) + ":" + bytes[i + 1].toString(16) + ":" + bytes[i + 2].toString(16) + ":" + + bytes[i + 3].toString(16) + ":" + bytes[i + 4].toString(16) + ":" + bytes[i + 5].toString(16); + } + return res; +} +//mac48.BYTES = bytes.length; + +function id32(bytes) { + var res = []; + //var size = bytes.length; + var j = 0; + for (var i = 0; i < bytes.length; i += 4) { + res[j++] = "0x" + bytes[i].toString(16) + bytes[i + 1].toString(16) + bytes[i + 2].toString(16) + + bytes[i + 3].toString(16); + } + return res; +} +//id32.BYTES = bytes.length; + +// Encode Downlink from JSON to bytes +function encodeDownlink(input) { + var i; + var j; + var k; + var output = []; + var value; + if (input.data.hasOwnProperty('cmd')) { + if (input.data.cmd == "CMD_GET_DATETIME") { + return { + bytes: [0], + fPort: CMD_GET_DATETIME, + warnings: [], + errors: [] + }; + } + else if (input.data.cmd == "CMD_GET_LW_CONFIG") { + return { + bytes: [0], + fPort: CMD_GET_LW_CONFIG, + warnings: [], + errors: [] + }; + } + else if (input.data.cmd == "CMD_GET_WS_TIMEOUT") { + return { + bytes: [0], + fPort: CMD_GET_WS_TIMEOUT, + warnings: [], + errors: [] + }; + } + else if (input.data.cmd == "CMD_GET_SENSORS_INC") { + return { + bytes: [0], + fPort: CMD_GET_SENSORS_INC, + warnings: [], + errors: [] + }; + } + else if (input.data.cmd == "CMD_GET_SENSORS_EXC") { + return { + bytes: [0], + fPort: CMD_GET_SENSORS_EXC, + warnings: [], + errors: [] + }; + } + else if (input.data.cmd == "CMD_GET_BLE_ADDR") { + return { + bytes: [0], + fPort: CMD_GET_BLE_ADDR, + warnings: [], + errors: [] + }; + } + } + if (input.data.hasOwnProperty('sleep_interval')) { + return { + bytes: [ + input.data.sleep_interval >> 8, + input.data.sleep_interval & 0xFF + ], + fPort: CMD_SET_SLEEP_INTERVAL, + warnings: [], + errors: [] + }; + } + if (input.data.hasOwnProperty('sleep_interval_long')) { + return { + bytes: [ + input.data.sleep_interval_long >> 8, + input.data.sleep_interval_long & 0xFF + ], + fPort: CMD_SET_SLEEP_INTERVAL_LONG, + warnings: [], + errors: [] + }; + } + else if (input.data.hasOwnProperty('epoch')) { + if (typeof input.data.epoch == "string") { + if (input.data.epoch.substr(0,2) == "0x") { + value = parseInt(input.data.epoch.substr(2), 16); + } else { + return { + bytes: [], + warnings: [], + errors: ["Invalid hex value"] + }; + } + } else { + value = input.data.epoch; + } + return { + bytes: [ + value >> 24, + (value >> 16) & 0xFF, + (value >> 8) & 0xFF, + (value & 0xFF)], + fPort: CMD_SET_DATETIME, + warnings: [], + errors: [] + }; + } + else if (input.data.hasOwnProperty('ws_timeout')) { + return { + bytes: [input.data.ws_timeout], + fPort: CMD_SET_WS_TIMEOUT, + warnings: [], + errors: [] + }; + } else if (input.data.hasOwnProperty('reset_flags')) { + if (typeof input.data.epoch == "string") { + if (input.data.reset_flags.substr(0,2) == "0x") { + value = parseInt(input.data.reset_flags.substr(2), 16); + } else { + return { + bytes: [], + warnings: [], + errors: ["Invalid hex value"] + }; + } + } else { + value = input.data.reset_flags; + } + return { + bytes: [value], + fPort: CMD_RESET_RAINGAUGE, + warnings: [], + errors: [] + }; + } else if (input.data.hasOwnProperty('sensors_inc')) { + k = 0; + for (i = 0; i < input.data.sensors_inc.length; i++) { + for (j = 2; j < 10; j += 2) { + output[k++] = parseInt(input.data.sensors_inc[i].substr(j, 2), 16); + } + } + return { + bytes: output, + fPort: CMD_SET_SENSORS_INC, + warnings: [], + errors: [] + }; + } else if (input.data.hasOwnProperty('sensors_exc')) { + k = 0; + for (i = 0; i < input.data.sensors_exc.length; i++) { + for (j = 2; j < 10; j += 2) { + output[k++] = parseInt(input.data.sensors_exc[i].substr(j, 2), 16); + } + } + return { + bytes: output, + fPort: CMD_SET_SENSORS_EXC, + warnings: [], + errors: [] + }; + } else if (input.data.hasOwnProperty('ble_addr')) { + output = []; + k = 0; + for (i = 0; i < input.data.ble_addr.length; i++) { + var tmp = input.data.ble_addr[i].replace(/([^:]*):/g, '$1'); + for (j = 0; j < 12; j += 2) { + output[k++] = parseInt(tmp.substr(j, 2), 16); + } + } + return { + bytes: output, + fPort: CMD_SET_BLE_ADDR, + warnings: [], + errors: [] + }; + } + else { + return { + bytes: [], + errors: ["unknown command"], + fPort: 1, + warnings: [] + }; + } +} + +// Decode Downlink from bytes to JSON +function decodeDownlink(input) { + switch (input.fPort) { + case CMD_SET_DATETIME: + return { + data: { + unixtime: "0x" + uint32BE(input.bytes.slice(0, 4)).toString(16) + } + }; + case CMD_SET_SLEEP_INTERVAL: + return { + data: { + sleep_interval: uint16BE(input.bytes) + } + }; + case CMD_SET_SLEEP_INTERVAL_LONG: + return { + data: { + sleep_interval_long: uint16BE(input.bytes) + } + }; + case CMD_SET_WS_TIMEOUT: + return { + data: { + ws_timeout: uint8(input.bytes) + } + }; + case CMD_RESET_RAINGAUGE: + return { + data: { + reset_flags: "0x" + uint8(input.bytes).toString(16) + } + }; + case CMD_SET_SENSORS_INC: + return { + data: { + sensors_inc: id32(input.bytes) + } + }; + case CMD_SET_SENSORS_EXC: + return { + data: { + sensors_exc: id32(input.bytes) + } + }; + case CMD_SET_BLE_ADDR: + return { + data: { + ble_addr: mac48(input.bytes) + } + }; + case CMD_GET_LW_CONFIG: + return { + data: { + sleep_interval: uint16BE(input.bytes.slice(1, 2)), + sleep_interval_long: uint16BE(input.bytes.slice(3, 4)) + } + }; + default: + return { + errors: ["unknown FPort"] + }; + } +} diff --git a/scripts/ttn_downlink_formatter.js b/scripts/ttn_downlink_formatter.js deleted file mode 100644 index b829a2d..0000000 --- a/scripts/ttn_downlink_formatter.js +++ /dev/null @@ -1,238 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// ttn_downlink_formatter.js -// -// Bresser 5-in-1/6-in-1 868 MHz Weather Sensor Radio Receiver -// based on ESP32 and RFM95W - -// sends data to a LoRaWAN network (e.g. The Things Network) -// -// This script allows to send downlink data to the The Things Network with -// commands, parameters and responses are encoded in JSON format. -// Commands shall be sent via FPort=1. -// -// Commands: -// ---------- -// {"cmd": "CMD_SET_WEATHERSENSOR_TIMEOUT", "timeout": } -// {"cmd": "CMD_SET_SLEEP_INTERVAL", "interval": } -// {"cmd": "CMD_SET_SLEEP_INTERVAL_LONG", "interval": } -// {"cmd": "CMD_GET_DATETIME"} -// {"cmd": "CMD_SET_DATETIME", "epoch": } -// {"cmd": "CMD_RESET_RAINGAUGE" [, "flags": ], -// {"cmd": "CMD_GET_CONFIG"} -// -// Responses: -// ----------- -// CMD_GET_CONFIG -> FPort=3: {"ws_timeout": , -// "sleep_interval": , -// "sleep_interval_long": } -// -// CMD_GET_DATETIME -> FPort=2: {"epoch": , "rtc_source":} -// -// : 0...255 -// : 0...65535 -// : unix epoch time, see https://www.epochconverter.com/ -// : 0...15 (1: hourly / 2: daily / 4: weekly / 8: monthly) -// : 0x00: GPS / 0x01: RTC / 0x02: LORA / 0x03: unsynched / 0x04: set (source unknown) -// -// -// Based on: -// --------- -// https://www.thethingsindustries.com/docs/integrations/payload-formatters/javascript/downlink/ -// -// created: 08/2023 -// -// -// MIT License -// -// Copyright (c) 2023 Matthias Prinke -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// -// History: -// 20230821 Created -// -// ToDo: -// - -// -/////////////////////////////////////////////////////////////////////////////// - -// Commands -const cmd_code = new Map([ - ["CMD_SET_WEATHERSENSOR_TIMEOUT", 0xA0], - ["CMD_SET_SLEEP_INTERVAL", 0xA8], - ["CMD_SET_SLEEP_INTERVAL_LONG", 0xA9], - ["CMD_GET_DATETIME", 0x86], - ["CMD_SET_DATETIME", 0x88], - ["CMD_RESET_RAINGAUGE", 0xB0], - ["CMD_GET_CONFIG", 0xB1], -]); - -// Source of Real Time Clock setting -var rtc_source_code = { - 0x00: "GPS", - 0x01: "RTC", - 0x02: "LORA", - 0x03: "unsynched", - 0x04: "set (source unknown)" -}; - -function bytesToInt(bytes) { - var i = 0; - for (var x = 0; x < bytes.length; x++) { - i |= +(bytes[x] << (x * 8)); - } - return i; -} - -// Big Endian -function bytesToIntBE(bytes) { - var i = 0; - for (var x = 0; x < bytes.length; x++) { - i |= +(bytes[x] << ((bytes.length - 1 - x) * 8)); - } - return i; -} - -function uint8(bytes) { - if (bytes.length !== 1) { - throw new Error('uint8 must have exactly 1 byte'); - } - return bytesToInt(bytes); -} - -function uint16BE(bytes) { - if (bytes.length !== 2) { - throw new Error('uint16BE must have exactly 2 bytes'); - } - return bytesToIntBE(bytes); -} - -function uint32BE(bytes) { - if (bytes.length !== 4) { - throw new Error('uint32BE must have exactly 4 bytes'); - } - return bytesToIntBE(bytes); -} - -// Encode Downlink from JSON to bytes -function encodeDownlink(input) { - if ((input.data.cmd === "CMD_SET_SLEEP_INTERVAL") || - (input.data.cmd === "CMD_SET_SLEEP_INTERVAL_LONG")) { - - return { - bytes: [cmd_code.get(input.data.cmd), - input.data.interval >> 8, - input.data.interval & 0xFF - ], - fPort: 1, - warnings: [], - errors: [] - }; - } - else if (input.data.cmd === "CMD_SET_DATETIME") { - return { - bytes: [cmd_code.get(input.data.cmd), - input.data.epoch >> 24, - (input.data.epoch >> 16) & 0xFF, - (input.data.epoch >> 8) & 0xFF, - (input.data.epoch & 0xFF)], - fPort: 1, - warnings: [], - errors: [] - }; - } - else if ((input.data.cmd === "CMD_GET_CONFIG") || - (input.data.cmd === "CMD_GET_DATETIME")) { - return { - bytes: [cmd_code.get(input.data.cmd)], - fPort: 1, - warnings: [], - errors: [] - }; - } - else if (input.data.cmd === "CMD_SET_WEATHERSENSOR_TIMEOUT") { - return { - bytes: [cmd_code.get(input.data.cmd), input.data.timeout], - fPort: 1, - warnings: [], - errors: [] - }; - } else if (input.data.cmd === "CMD_RESET_RAINGAUGE") { - if (input.data.hasOwnProperty('flags')) { - return { - bytes: [cmd_code.get(input.data.cmd), input.data.flags], - fPort: 1, - warnings: [], - errors: [] - }; - } - else { - return { - bytes: [cmd_code.get(input.data.cmd)], - fPort: 1, - warnings: [], - errors: [] - }; - } - } else { - return { - bytes: [], - errors: ["unknown command"], - fPort: 1, - warnings: [] - }; - } -} - -// Decode Downlink from bytes to JSON -function decodeDownlink(input) { - switch (input.fPort) { - case 1: - for (const x of cmd_code.keys()) { - if (input.bytes[0] == cmd_code.get(x)) { - return { - cmd: x - }; - } - } - return { - cmd: [], - errors: ["unknown command"] - }; - case 2: - return { - data: { - unixtime: uint32BE(input.bytes.slice(0, 3)), - rtc_source: rtc_source_code[input.bytes[4]] - } - }; - case 3: - return { - data: { - ws_timeout: uint8(input.bytes[0]), - sleep_interval: uint16BE(input.bytes.slice(1, 2)), - sleep_interval_long: uint16BE(input.bytes.slice(3, 4)) - } - }; - default: - return { - errors: ["unknown FPort"] - }; - } -} diff --git a/scripts/uplink_formatter.js b/scripts/uplink_formatter.js index d106f06..a054d22 100644 --- a/scripts/uplink_formatter.js +++ b/scripts/uplink_formatter.js @@ -2,8 +2,8 @@ /////////////////////////////////////////////////////////////////////////////// // uplink_formatter.js // -// Bresser 5-in-1/6-in-1 868 MHz Weather Sensor Radio Receiver -// based on ESP32 and RFM95W - +// Bresser 868 MHz Weather Sensor Radio Receiver +// based on ESP32 and SX1262/SX1276 - // sends data to a LoRaWAN network (e.g. The Things Network) // // This script allows to decode payload received from The Things Network - @@ -14,26 +14,30 @@ // ---------- // (see constants for ports below) // port = CMD_SET_WS_TIMEOUT, {"timeout": } -// port = CMD_SET_SLEEP_INTERVAL, {"cmd": "", "interval": } -// port = CMD_SET_SLEEP_INTERVAL_LONG, {"cmd": "", "interval": } -// port = CMD_GET_DATETIME, payload = 0x00 +// port = CMD_SET_SLEEP_INTERVAL, {"sleep_interval": } +// port = CMD_SET_SLEEP_INTERVAL_LONG, {"sleep_interval_long": } +// port = CMD_GET_DATETIME, {"cmd": "CMD_GET_DATETIME"} / payload = 0x00 // port = CMD_SET_DATETIME, {"epoch": } -// port = CMD_RESET_RAINGAUGE, {"flags": } -// port = CMD_GET_LW_CONFIG, payload = 0x00 -// port = CMD_GET_WS_TIMEOUT, payload = 0x00 -// port = CMD_GET_SENSORS_INC, payload = 0x00 -// port = CMD_GET_SENSORS_EXC, payload = 0x00 -// port = CMD_GET_BLE_ADDR, payload = 0x00 +// port = CMD_RESET_RAINGAUGE, {"reset_flags": } +// port = CMD_GET_LW_CONFIG, {"cmd": "CMD_GET_LW_CONFIG"} / payload = 0x00 +// port = CMD_GET_WS_TIMEOUT, {"cmd": "CMD_GET_WS_TIMEOUT" / payload = 0x00 +// port = CMD_SET_WS_TIMEOUT, {"ws_timeout": } +// port = CMD_GET_SENSORS_INC, {"cmd": "CMD_GET_SENSORS_INC"} / payload = 0x00 +// port = CMD_SET_SENSORS_INC, {"sensors_inc": [, ..., ]} +// port = CMD_GET_SENSORS_EXC, {"cmd": "CMD_GET_SENSORS_EXC"} / payload = 0x00 +// port = CMD_SET_SENSORS_EXC, {"sensors_exc": [, ..., ]} +// port = CMD_GET_BLE_ADDR, {"cmd": "CMD_GET_BLE_ADDR"} / payload = 0x00 +// port = CMD_SET_BLE_ADDR, {"ble_addr": [, ..., ]} // // Responses: // ----------- // (The response uses the same port as the request.) -// CMD_GET_LW_CONFIG {"sleep_interval": , -// "sleep_interval_long": } +// CMD_GET_LW_CONFIG {"sleep_interval": , +// "sleep_interval_long": } // -// CMD_GET_DATETIME {"epoch": , "rtc_source":} +// CMD_GET_DATETIME {"epoch": , "rtc_source": } // -// CMD_GET_WS_TIMEOUT {"ws_timeout": } +// CMD_GET_WS_TIMEOUT {"ws_timeout": } // // CMD_GET_SENSORS_INC {"sensors_inc": [, ...]} // @@ -41,10 +45,11 @@ // // CMD_GET_BLE_ADDR {"ble_addr": [, ...]} // -// : 0...255 -// : 0...65535 -// : unix epoch time, see https://www.epochconverter.com/ -// : 0...15 (1: hourly / 2: daily / 4: weekly / 8: monthly) +// : 0...255 +// : 0...65535 +// : 0...65535 +// : unix epoch time, see https://www.epochconverter.com/ ( / "0x....") +// : 0...15 (1: hourly / 2: daily / 4: weekly / 8: monthly) / "0x0"..."0xF" // : 0x00: GPS / 0x01: RTC / 0x02: LORA / 0x03: unsynched / 0x04: set (source unknown) // : e.g. "0xDEADBEEF" // : e.g. "0xDEADBEEF" @@ -100,6 +105,8 @@ function decoder(bytes, port) { const CMD_GET_SENSORS_EXC = 0xC6; const CMD_GET_BLE_ADDR = 0xC8; + const ONEWIRE_EN = 0; + var rtc_source_code = { 0x00: "GPS", 0x01: "RTC", @@ -191,24 +198,24 @@ function decoder(bytes, port) { uint32BE.BYTES = 4; var mac48 = function (bytes) { - var res = []; + var res = []; var size = bytes.length; - var j=0; + var j = 0; for (var i = 0; i < bytes.length; i += 6) { - res[j++] = bytes[i].toString(16) + ":" + bytes[i+1].toString(16) + ":" + bytes[i+2].toString(16) + ":" + - bytes[i+3].toString(16) + ":" + bytes[i+4].toString(16) + ":" + bytes[i+5].toString(16); + res[j++] = bytes[i].toString(16) + ":" + bytes[i + 1].toString(16) + ":" + bytes[i + 2].toString(16) + ":" + + bytes[i + 3].toString(16) + ":" + bytes[i + 4].toString(16) + ":" + bytes[i + 5].toString(16); } return res; } mac48.BYTES = bytes.length; var id32 = function (bytes) { - var res = []; + var res = []; var size = bytes.length; - var j=0; + var j = 0; for (var i = 0; i < bytes.length; i += 4) { - res[j++] = "0x" + bytes[i].toString(16) + bytes[i+1].toString(16) + bytes[i+2].toString(16) + - bytes[i+3].toString(16); + res[j++] = "0x" + bytes[i].toString(16) + bytes[i + 1].toString(16) + bytes[i + 2].toString(16) + + bytes[i + 3].toString(16); } return res; } @@ -358,23 +365,44 @@ function decoder(bytes, port) { if (port === 1) { - return decode( - bytes, - [bitmap_node, bitmap_sensors, temperature, uint8, - uint16fp1, uint16fp1, uint16fp1, - rawfloat, uint16, temperature, - temperature, uint8, temperature, uint8, - rawfloat, rawfloat, rawfloat, rawfloat, - unixtime, uint16, uint8 - ], - ['status_node', 'status', 'air_temp_c', 'humidity', - 'wind_gust_meter_sec', 'wind_avg_meter_sec', 'wind_direction_deg', - 'rain_mm', 'supply_v', 'water_temp_c', - 'indoor_temp_c', 'indoor_humidity', 'soil_temp_c', 'soil_moisture', - 'rain_hr', 'rain_day', 'rain_week', 'rain_mon', - 'lightning_time', 'lightning_events', 'lightning_distance_km' - ] - ); + if (ONEWIRE_EN) { + return decode( + bytes, + [bitmap_node, bitmap_sensors, temperature, uint8, + uint16fp1, uint16fp1, uint16fp1, + rawfloat, uint16, temperature, + temperature, uint8, temperature, uint8, + rawfloat, rawfloat, rawfloat, rawfloat, + unixtime, uint16, uint8 + ], + ['status_node', 'status', 'air_temp_c', 'humidity', + 'wind_gust_meter_sec', 'wind_avg_meter_sec', 'wind_direction_deg', + 'rain_mm', 'supply_v', 'water_temp_c', + 'indoor_temp_c', 'indoor_humidity', 'soil_temp_c', 'soil_moisture', + 'rain_hr', 'rain_day', 'rain_week', 'rain_mon', + 'lightning_time', 'lightning_events', 'lightning_distance_km' + ] + ); + } else { + return decode( + bytes, + [bitmap_node, bitmap_sensors, temperature, uint8, + uint16fp1, uint16fp1, uint16fp1, + rawfloat, uint16, + temperature, uint8, temperature, uint8, + rawfloat, rawfloat, rawfloat, rawfloat, + unixtime, uint16, uint8 + ], + ['status_node', 'status', 'air_temp_c', 'humidity', + 'wind_gust_meter_sec', 'wind_avg_meter_sec', 'wind_direction_deg', + 'rain_mm', 'supply_v', + 'indoor_temp_c', 'indoor_humidity', 'soil_temp_c', 'soil_moisture', + 'rain_hr', 'rain_day', 'rain_week', 'rain_mon', + 'lightning_time', 'lightning_events', 'lightning_distance_km' + ] + ); + } + } else if (port === CMD_GET_DATETIME) { return decode( bytes,