diff --git a/schema.json b/schema.json index dd9b6b83ae..f5e5f74d65 100644 --- a/schema.json +++ b/schema.json @@ -972,6 +972,7 @@ "radar", "rainfall", "rssi", + "sapflow", "smart valve", "snr", "so2", diff --git a/vendor/decentlab/dl-isf-codec.yaml b/vendor/decentlab/dl-isf-codec.yaml new file mode 100644 index 0000000000..9a821aa7e1 --- /dev/null +++ b/vendor/decentlab/dl-isf-codec.yaml @@ -0,0 +1,161 @@ +uplinkDecoder: + fileName: dl-isf.js + examples: + - description: Example 1 + input: + fPort: 1 + bytes: + [ + 0x02, + 0x3d, + 0x01, + 0x00, + 0x03, + 0x0c, + 0x29, + 0x0b, + 0xab, + 0x0c, + 0x3e, + 0x79, + 0x70, + 0x7a, + 0x1d, + 0x78, + 0x43, + 0x79, + 0x91, + 0x49, + 0x08, + 0x45, + 0x99, + 0x7e, + 0x4c, + 0xac, + 0xde, + 0xaa, + 0x6e, + 0x00, + 0x00, + 0x00, + 0x00, + 0x45, + 0x7e, + 0x41, + 0x5a, + 0x0b, + 0x59, + ] + output: + data: + alpha_inner: + displayName: Alpha (inner) + value: 0.00352 + alpha_outer: + displayName: Alpha (outer) + value: -0.05184 + battery_voltage: + displayName: Battery voltage + unit: V + value: 2.905 + beta_inner: + displayName: Beta (inner) + value: -0.04128 + beta_outer: + displayName: Beta (outer) + value: -0.14816 + device_id: 15617 + diagnostic: + displayName: Diagnostic + value: 0 + heat_velocity_inner: + displayName: Heat velocity (inner) + unit: "cm\u22C5h\u207B\xB9" + value: 0.144 + heat_velocity_outer: + displayName: Heat velocity (outer) + unit: "cm\u22C5h\u207B\xB9" + value: -2.208 + max_voltage: + displayName: Max voltage + unit: V + value: 11.486 + min_voltage: + displayName: Min voltage + unit: V + value: 10.862 + protocol_version: 2 + sap_flow: + displayName: Sap flow + unit: "l\u22C5h\u207B\xB9" + value: -0.192 + temperature_outer: + displayName: Temperature (outer) + unit: "\xB0C" + value: -4.36 + tmax_inner: + displayName: Tmax (inner) + unit: s + value: 35.634 + tmax_outer: + displayName: Tmax (outer) + unit: s + value: 37.392 + upstream_tmax_inner: + displayName: Upstream Tmax (inner) + unit: s + value: 33.46 + upstream_tmax_outer: + displayName: Upstream Tmax (outer) + unit: s + value: 35.58 + - description: Example 2 + input: + fPort: 1 + bytes: [0x02, 0x3d, 0x01, 0x00, 0x02, 0x0b, 0x59] + output: + data: + battery_voltage: + displayName: Battery voltage + unit: V + value: 2.905 + device_id: 15617 + protocol_version: 2 + +downlinkEncoder: + fileName: dl-downlink-codec.js + examples: + - description: Set period 3600 seconds and save + input: + data: + command: set period + save + parameter: 3600 + output: + bytes: [0, 2, 14, 16, 72, 164] + fPort: 1 + - description: Set ADR off + input: + data: + command: set adr off + output: + bytes: [0, 7, 0, 0, 229, 177] + fPort: 1 + +downlinkDecoder: + fileName: dl-downlink-codec.js + examples: + - description: Set period 600 seconds + input: + fPort: 1 + bytes: [0x00, 0x01, 0x02, 0x58, 0x7E, 0x51] + output: + data: + command: set period + parameter: 600 + - description: Reset + input: + fPort: 1 + bytes: [0xFE, 0xFE, 0x00, 0x00, 0x3C, 0x50] + output: + data: + command: reset diff --git a/vendor/decentlab/dl-isf.js b/vendor/decentlab/dl-isf.js new file mode 100644 index 0000000000..b497876c6b --- /dev/null +++ b/vendor/decentlab/dl-isf.js @@ -0,0 +1,131 @@ + +/* https://www.decentlab.com/products/sapflow-sensor-for-lorawan */ + +var decentlab_decoder = { + PROTOCOL_VERSION: 2, + SENSORS: [ + {length: 16, + values: [{name: 'sap_flow', + displayName: 'Sap flow', + convert: function (x) { return (x[0] * 16 - 50000) / 1000; }, + unit: 'l⋅h⁻¹'}, + {name: 'heat_velocity_outer', + displayName: 'Heat velocity (outer)', + convert: function (x) { return (x[1] * 16 - 50000) / 1000; }, + unit: 'cm⋅h⁻¹'}, + {name: 'heat_velocity_inner', + displayName: 'Heat velocity (inner)', + convert: function (x) { return (x[2] * 16 - 50000) / 1000; }, + unit: 'cm⋅h⁻¹'}, + {name: 'alpha_outer', + displayName: 'Alpha (outer)', + convert: function (x) { return (x[3] * 32 - 1000000) / 100000; }}, + {name: 'alpha_inner', + displayName: 'Alpha (inner)', + convert: function (x) { return (x[4] * 32 - 1000000) / 100000; }}, + {name: 'beta_outer', + displayName: 'Beta (outer)', + convert: function (x) { return (x[5] * 32 - 1000000) / 100000; }}, + {name: 'beta_inner', + displayName: 'Beta (inner)', + convert: function (x) { return (x[6] * 32 - 1000000) / 100000; }}, + {name: 'tmax_outer', + displayName: 'Tmax (outer)', + convert: function (x) { return (x[7] * 2) / 1000; }, + unit: 's'}, + {name: 'tmax_inner', + displayName: 'Tmax (inner)', + convert: function (x) { return (x[8] * 2) / 1000; }, + unit: 's'}, + {name: 'temperature_outer', + displayName: 'Temperature (outer)', + convert: function (x) { return (x[9] - 32768) / 100; }, + unit: '°C'}, + {name: 'max_voltage', + displayName: 'Max voltage', + convert: function (x) { return (x[10] - 32768) / 1000; }, + unit: 'V'}, + {name: 'min_voltage', + displayName: 'Min voltage', + convert: function (x) { return (x[11] - 32768) / 1000; }, + unit: 'V'}, + {name: 'diagnostic', + displayName: 'Diagnostic', + convert: function (x) { return x[12] + x[13] * 65536; }}, + {name: 'upstream_tmax_outer', + displayName: 'Upstream Tmax (outer)', + convert: function (x) { return (x[14] * 2) / 1000; }, + unit: 's'}, + {name: 'upstream_tmax_inner', + displayName: 'Upstream Tmax (inner)', + convert: function (x) { return (x[15] * 2) / 1000; }, + unit: 's'}]}, + {length: 1, + values: [{name: 'battery_voltage', + displayName: 'Battery voltage', + convert: function (x) { return x[0] / 1000; }, + unit: 'V'}]} + ], + + read_int: function (bytes, pos) { + return (bytes[pos] << 8) + bytes[pos + 1]; + }, + + decode: function (msg) { + var bytes = msg; + var i, j; + if (typeof msg === 'string') { + bytes = []; + for (i = 0; i < msg.length; i += 2) { + bytes.push(parseInt(msg.substring(i, i + 2), 16)); + } + } + + var version = bytes[0]; + if (version != this.PROTOCOL_VERSION) { + return {error: "protocol version " + version + " doesn't match v2"}; + } + + var deviceId = this.read_int(bytes, 1); + var flags = this.read_int(bytes, 3); + var result = {'protocol_version': version, 'device_id': deviceId}; + // decode payload + var pos = 5; + for (i = 0; i < this.SENSORS.length; i++, flags >>= 1) { + if ((flags & 1) !== 1) + continue; + + var sensor = this.SENSORS[i]; + var x = []; + // convert data to 16-bit integer array + for (j = 0; j < sensor.length; j++) { + x.push(this.read_int(bytes, pos)); + pos += 2; + } + + // decode sensor values + for (j = 0; j < sensor.values.length; j++) { + var value = sensor.values[j]; + if ('convert' in value) { + result[value.name] = {displayName: value.displayName, + value: value.convert.bind(this)(x)}; + if ('unit' in value) + result[value.name]['unit'] = value.unit; + } + } + } + return result; + } +}; + +function decodeUplink(input) { + var res = decentlab_decoder.decode(input.bytes); + if (res.error) { + return { + errors: [res.error], + }; + } + return { + data: res, + }; +} diff --git a/vendor/decentlab/dl-isf.png b/vendor/decentlab/dl-isf.png new file mode 100644 index 0000000000..6a9f8c8183 Binary files /dev/null and b/vendor/decentlab/dl-isf.png differ diff --git a/vendor/decentlab/dl-isf.yaml b/vendor/decentlab/dl-isf.yaml new file mode 100644 index 0000000000..40d14c5f83 --- /dev/null +++ b/vendor/decentlab/dl-isf.yaml @@ -0,0 +1,87 @@ +name: DL-ISF +description: The Decentlab DL-ISF is a sapflow sensor for LoRaWAN®. Suitable for applications such as plant physiology, plant water use, hydraulic redistribution, hydrology, and irrigation scheduling. + +hardwareVersions: + - version: '1' + numeric: 1 + +firmwareVersions: + - version: 1.5.7 + numeric: 157 + hardwareVersions: + - '1' + profiles: + EU863-870: + id: profile-eu868 + lorawanCertified: true + codec: dl-isf-codec + AS923: + id: profile-as923 + lorawanCertified: false + codec: dl-isf-codec + US902-928: + id: profile-us915 + lorawanCertified: true + codec: dl-isf-codec + AU915-928: + id: profile-au915 + lorawanCertified: false + codec: dl-isf-codec + +sensors: + - sapflow + +dimensions: + length: 135 + width: 81 + height: 70 + +weight: 400 + +battery: + replaceable: true + type: 2 C alkaline + +operatingConditions: + temperature: + min: -20 + max: 50 + relativeHumidity: + min: 0 + max: 1.0 + +ipCode: IP67 + +keyProvisioning: + - custom +keySecurity: none + +productURL: https://www.decentlab.com/products/sapflow-sensor-for-lorawan +photos: + main: dl-isf.png + +compliances: + safety: + - body: IEC + norm: EN + standard: 62368-1 + radioEquipment: + - body: ETSI + norm: EN + standard: 301 489-1 + version: 2.2.0 + - body: ETSI + norm: EN + standard: 301 489-3 + version: 2.1.1 + - body: ETSI + norm: EN + standard: 300 220-1 + version: 3.1.1 + - body: ETSI + norm: EN + standard: 300 220-2 + version: 3.1.1 + - body: IEC + norm: EN + standard: 62479:2010 diff --git a/vendor/decentlab/index.yaml b/vendor/decentlab/index.yaml index 9e549747d3..49cceb3b76 100644 --- a/vendor/decentlab/index.yaml +++ b/vendor/decentlab/index.yaml @@ -16,6 +16,7 @@ endDevices: - dl-ds18 - dl-dws - dl-iam + - dl-isf - dl-itst - dl-kl66 - dl-lid