STREGA - Smart Emitter For Irrigation Valve Full Edition

Sensor

Codec Description

Codec for STREGA - Smart-Emitter-For-Irrigation-Valve-Full-Edition (v1.0.0).

Codec Preview

/* eslint-disable no-mixed-operators */ /* eslint-disable no-bitwise */ /* This is an example code for Everynet Parser. ** Everynet send several parameters to TagoIO. The job of this parse is to convert all these parameters into a TagoIO format. ** One of these parameters is the payload of your device. We find it too and apply the appropriate sensor parse. ** ** IMPORTANT: In most case, you will only need to edit the parsePayload function. ** ** Testing: ** You can do manual tests to this parse by using the Device Emulator. Copy and Paste the following code: ** [{ "variable": "everynet_payload", "value": "{ \"params\": { \"payload\": \"0109611395\" } }" }] ** ** The ignore_vars variable in this code should be used to ignore variables ** from the device that you don't want. */ // Add ignorable variables in this array. const ignore_vars = ['device_addr', 'port', 'duplicate', 'network', 'packet_hash', 'application', 'device', 'packet_id']; /** * Convert an object to TagoIO object format. * Can be used in two ways: * toTagoFormat({ myvariable: myvalue , anothervariable: anothervalue... }) * toTagoFormat({ myvariable: { value: myvalue, unit: 'C', metadata: { color: 'green' }} , anothervariable: anothervalue... }) * * @param {Object} object_item Object containing key and value. * @param {String} serie Serie for the variables * @param {String} prefix Add a prefix to the variables name */ function toTagoFormat(object_item, serie, prefix = '') { const result = []; for (const key in object_item) { if (ignore_vars.includes(key)) continue; if (typeof object_item[key] === 'object') { result.push({ variable: object_item[key].variable || `${prefix}${key}`.toLowerCase(), value: object_item[key].value, serie: object_item[key].serie || serie, metadata: object_item[key].metadata, location: object_item[key].location, unit: object_item[key].unit, }); } else { result.push({ variable: `${prefix}${key}`.toLowerCase(), value: object_item[key], serie, }); } } return result; } function pad(num, len) { return (`00000000${num}`).substr(-len); } function roundToTwo(num) { return +(`${Math.round(`${num}e+2`)}e-2`); } function dec_to_bho(n, base) { if (n < 0) { n = 0xFFFFFFFF + n + 1; } switch (base) { case 'B': return parseInt(n, 10).toString(2); case 'H': return parseInt(n, 10).toString(16); case 'O': return parseInt(n, 10).toString(8); default: return ('Wrong input.........'); } } function toHexString(hex_bytes) { return hex_bytes.map((byte) => { return (`00${(byte & 0xFF).toString(16)}`).slice(-2); }).join(''); } function hex2bin(hex) { return (`00000000${(parseInt(hex, 16)).toString(2)}`).substr(-8); } function Decoder(bytes, port) { const ports = port; const v4 = toHexString(bytes); const v4_1 = v4.substr(10, 2); const v4_2 = v4.substr(0, 2); const v4_3 = v4.substr(0, 1); const v3 = v4.substr(8, 1); const length = v4.length; let battery; let Tamper; let Valve; let status_v4; let Cable_v4; let conf_p; let conf_s; let unit1; let time1; let Cable; let unit2; let time2; let temperature; let hygrometry; let status; let DI_0; let DI_1; let Leakage; let Fraud; let clas; let power; let t; let t1; // Battery operated V3 Old if (v4_3 === '3') { const msg0 = String.fromCharCode.apply(null, bytes); const bat0 = msg0.substr(0, 4); battery = Math.round((bat0 - 2000) / 16); if (length === 10) { const st0 = msg0.substr(4, 1); const sta0 = dec_to_bho(st0, 'B'); status = pad(sta0, 8); Valve = status.substr(7, 1); Tamper = status.substr(6, 1); } } // Battery operated V3 & V4 & Class A if (v4_3 === '3') { const msg = String.fromCharCode.apply(null, bytes); const bat = msg.substr(0, 4); battery = Math.round((bat - 2000) / 16); if (length >= 10) { const st = msg.substr(4, 1); const sta = dec_to_bho(st, 'B'); status = pad(sta, 8); Valve = status.substr(7, 1); Tamper = status.substr(6, 1); } const st_1 = v4.substr(8, 2); t = st_1.substr(0, 1) - 3; t1 = st_1.substr(1, 1); const st1 = t + t1; const st01 = hex2bin(st1); status = pad(st01, 8); Valve = status.substr(7, 1); Tamper = status.substr(6, 1); Cable = status.substr(5, 1); DI_0 = status.substr(4, 1); DI_1 = status.substr(3, 1); Leakage = status.substr(2, 1); Fraud = status.substr(1, 1); conf_p = parseInt(msg.substr(6, 2), 16); conf_s = msg.substr(8, 2); unit1 = msg.substr(8, 2); time1 = msg.substr(10, 2); unit2 = msg.substr(12, 2); time2 = msg.substr(14, 2); const T_H = v4.substr(12, 8); const temp = T_H.substr(0, 4); const box_temp = parseInt((temp), 16); temperature = (((box_temp / 65536) * 165) - 40); const hum = T_H.substr(4, 8); const box_hum = parseInt((hum), 16); hygrometry = ((box_hum / 65536) * 100); } // Externally power V4 & Class variation if (v4_3 !== '3' || v4_3 !== 'B' || v4_3 !== 'b') { const msg1 = String.fromCharCode.apply(1, bytes); const st2 = hex2bin(v4_2); clas = st2.substr(0, 1); power = st2.substr(1, 1); const st_3 = v4.substr(8, 2); t = st_3.substr(0, 1) - 3; t1 = st_3.substr(1, 1); const st3 = t + t1; const st02 = hex2bin(st3); status = pad(st02, 8); Valve = status.substr(7, 1); Tamper = status.substr(6, 1); Cable = status.substr(5, 1); DI_0 = status.substr(4, 1); DI_1 = status.substr(3, 1); Leakage = status.substr(2, 1); Fraud = status.substr(1, 1); conf_p = parseInt(msg1.substr(6, 2), 16); conf_s = msg1.substr(8, 2); unit1 = msg1.substr(8, 2); time1 = msg1.substr(10, 2); unit2 = msg1.substr(12, 2); time2 = msg1.substr(14, 2); const T_H1 = v4.substr(12, 8); const temp1 = T_H1.substr(0, 4); const box_temp1 = parseInt((temp1), 16); temperature = (((box_temp1 / 65536) * 165) - 40); const hum1 = T_H1.substr(4, 8); const box_hum1 = parseInt((hum1), 16); hygrometry = ((box_hum1 / 65536) * 100); } // Battery operated V4 & Class variation if (v4_3 == 'B' || v4_3 == 'b') { const msg2 = String.fromCharCode.apply(1, bytes); const st4 = hex2bin(v4_2); clas = st4.substr(0, 1); power = st4.substr(1, 1); const b = v4.substr(1, 1); const b1 = msg2.substr(2, 3); const bat1 = b.concat(b1); battery = Math.round((bat1 - 2000) / 16); const st_5 = v4.substr(8, 2); t = st_5.substr(0, 1) - 3; t1 = st_5.substr(1, 1); const st5 = t + t1; const st03 = hex2bin(st5); status = pad(st03, 8); Valve = status.substr(7, 1); Tamper = status.substr(6, 1); Cable = status.substr(5, 1); DI_0 = status.substr(4, 1); DI_1 = status.substr(3, 1); Leakage = status.substr(2, 1); Fraud = status.substr(1, 1); conf_p = parseInt(msg2.substr(7, 2), 16); conf_s = msg2.substr(9, 2); unit1 = msg2.substr(9, 2); time1 = msg2.substr(11, 2); unit2 = msg2.substr(13, 2); time2 = msg2.substr(15, 2); const T_H2 = v4.substr(12, 8); const temp2 = T_H2.substr(0, 4); const box_temp2 = parseInt((temp2), 16); temperature = (((box_temp2 / 65536) * 165) - 40); const hum2 = T_H2.substr(4, 8); const box_hum2 = parseInt((hum2), 16); hygrometry = ((box_hum2 / 65536) * 100); } if (v4_1 === '40') { if (conf_p === 14 || conf_p === 15 || conf_p === 16 || conf_p === 17 || conf_p === 18 || conf_p === 19 || conf_p === 20) { return { Port: ports, Battery: battery, Valve, Tamper, Cable, DI_0, DI_1, Leakage, Fraud, Class: clas, Power: power, Schl_Port: conf_p || 0, Schl_status: conf_s || 0, }; } if (conf_p === 21) { return { Port: ports, Battery: battery, Valve, Tamper, Cable, DI_0, DI_1, Leakage, Fraud, Class: clas, Power: power, Schl_status_Port: conf_p || 0, Schl_status_ack: conf_s || 0, }; } if (conf_p === 12 || conf_p === 13) { return { Port: ports, Battery: battery, Valve, Tamper, Cable, DI_0, DI_1, Leakage, Fraud, Class: clas, Power: power, RTC_Port: conf_p || 0, RTC_status: conf_s || 0, }; } if (conf_p === 9) { return { Port: ports, Battery: battery, Valve, Tamper, Cable, DI_0, DI_1, Leakage, Fraud, Class: clas, Power: power, Class_Port: conf_p || 0, Class_status: conf_s || 0, }; } if (conf_p === 22) { return { Port: ports, Battery: battery, Valve, Tamper, Cable, DI_0, DI_1, Leakage, Fraud, Class: clas, Power: power, magnet_Port: conf_p || 0, magnet_status: conf_s || 0, }; } } if (v4_1 === '23') { return { Port: ports, Status: status, Battery: battery, Valve, Tamper, Cable, DI_0, DI_1, Leakage, Fraud, Class: clas, Power: power, Temperature: roundToTwo(temperature), Hygrometry: roundToTwo(hygrometry), }; } return { Port: ports, Battery: battery, Valve, Tamper, }; } // let payload = [ // { // variable: 'time', // value: 1571874770.422976, // serie: 1571874770524, // }, // { // variable: 'payload', // value: '4Be202000008000001', // serie: 1571874770524, // }, // { // variable: 'port', // value: 2, // serie: 1571874770524, // }, // { // variable: 'duplicate', // value: false, // serie: 1571874770524, // }, // { // variable: 'counter_up', // value: 38, // serie: 1571874770524, // }, // { // variable: 'rx_time', // value: 1571874770.3568993, // serie: 1571874770524, // }, // { // variable: 'encrypted_payload', // value: 'c12oeBn03DxbfqcD', // serie: 1571874770524, // }, // ]; // Check if what is being stored is the ttn_payload. // Payload is an environment variable. Is where what is being inserted to your device comes in. // Payload always is an array of objects. [ { variable, value...}, {variable, value...} ...] const payload_raw = payload.find(x => x.variable === 'payload' || x.variable === 'payload_raw' || x.variable === 'data'); const port = payload.find(x => x.variable === 'fport' || x.variable === 'port'); if (payload_raw) { // Get a unique serie for the incoming data. const serie = payload_raw.serie || new Date().getTime(); let vars_to_tago = []; // Parse the payload from your sensor to function parsePayload try { const decoded = Decoder(Buffer.from(payload_raw.value, 'hex'), port ? port.value : null); console.log(decoded); vars_to_tago = vars_to_tago.concat(toTagoFormat(decoded, serie)); } catch (e) { // Catch any error in the parse code and send to parse_error variable. vars_to_tago = vars_to_tago.concat({ variable: 'parse_error', value: e.message || e }); } payload = payload.concat(vars_to_tago); } payload = payload.filter((item) => { if (item.location) { if (item.location.lat === 0 && item.location.lng === 0) { return false; } } return true; }); // console.log(payload) 

This codec is sourced from TagoIO Github. All rights belong to TagoIO Github.

This codec is licensed under the GNU General Public License v3 (GPL v3). Modifications, if any, are clearly marked. You are free to use, modify, and distribute the codec under the terms of GPL v3.

Community Feedback