diff --git a/vendor/enginko/EGK-LW20L00.jpg b/vendor/enginko/EGK-LW20L00.jpg new file mode 100644 index 0000000000..eef6f61890 Binary files /dev/null and b/vendor/enginko/EGK-LW20L00.jpg differ diff --git a/vendor/enginko/EGK-LW20W00.jpg b/vendor/enginko/EGK-LW20W00.jpg new file mode 100644 index 0000000000..c7555e5a98 Binary files /dev/null and b/vendor/enginko/EGK-LW20W00.jpg differ diff --git a/vendor/enginko/decodel-level.js b/vendor/enginko/decodel-level.js new file mode 100644 index 0000000000..7111b67829 --- /dev/null +++ b/vendor/enginko/decodel-level.js @@ -0,0 +1,446 @@ +'use strict'; + +function decodeUplink(payload) { + payload = TTNfrom(payload); + var uplinkId = payload.substring(0, 2); + var content; + + switch (uplinkId.toUpperCase()) { + case '01': + content = parseTimeSync(payload.trim()); + break; + + case '14': + content = parseLevel(payload.trim()); + break; + + default: + content = null; + break; + } + return TTNto(content); +} + +function TTNfrom(TTNpayload) { + var obj; + + if (typeof TTNpayload === 'string') { + obj = JSON.parse(TTNpayload); + } else { + obj = JSON.parse(JSON.stringify(TTNpayload)); + } + + var fPort = obj.fPort; + var payload = ''; + + for (var i = 0; i < obj.bytes.length; i++) { + payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, '0'); + } + + return payload; +} + +function TTNto(content) { + var TTNcontent = {}; + + if (content !== null) { + for (var i = 0; i < content.length; i++) { + TTNcontent[content[i].variable] = content[i].value; + } + + return { + data: TTNcontent, + }; + } else { + return { + data: content, + warnings: [], + errors: ['Error on decoding payload'], + }; + } +} +function parseLevel(payload) { + var r = []; + + var payloadToByteArray = hexStringToByteArray(payload); + var typeNumber = ((0x00 << 8) & 0xff00) | (payloadToByteArray[1] & 0xff); + const type = { + variable: 'type', + value: typeNumber, + }; + r.push(type); + + var date, ADC, distance1, battery, error; + + var startData = 2; + switch (typeNumber) { + case 0x00: + startData = 6; + date = { + variable: 'date', + value: parseDateByte(payloadToByteArray.slice(2, startData)), + }; + r.push(date); + + ADC = { + variable: 'ADC', + value: Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(), + unit: 'mV', + }; + r.push(ADC); + startData += 2; + startData += 2; + + if (startData + 2 <= payloadToByteArray.length) { + var distanceNumber = Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(); + if (distanceNumber <= 60000) { + distance1 = { + variable: 'distance1', + value: distanceNumber, + unit: 'mm', + }; + r.push(distance1); + } else { + error = { + variable: 'distance1', + value: 'distance error [' + distanceNumber + ']', + }; + r.push(error); + } + } + startData += 2; + + if (startData + 1 === payloadToByteArray.length) { + battery = { + variable: 'battery', + value: Number(parseInt(payloadToByteArray[startData])).toFixed(), + unit: '%', + }; + r.push(battery); + } + + return r; + case 0x01: + startData = 6; + date = { + variable: 'date', + value: parseDateByte(payloadToByteArray.slice(2, startData)), + }; + r.push(date); + + ADC = { + variable: 'ADC', + value: Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(), + unit: 'mV', + }; + r.push(ADC); + startData += 2; + startData += 2; + + if (startData + 2 <= payloadToByteArray.length) { + var distanceNumber = Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(); + if (distanceNumber <= 60000) { + distance1 = { + variable: 'distance1', + value: distanceNumber, + unit: 'mm', + }; + r.push(distance1); + } else { + error = { + variable: 'distance1', + value: 'distance error [' + distanceNumber + ']', + }; + r.push(error); + } + } + startData += 2; + + var fillLevel = { + variable: 'fillLevel', + value: Number(parseInt(payloadToByteArray[startData])).toFixed(), + unit: '%', + }; + r.push(fillLevel); + startData += 1; + + var temperature = { + variable: 'temperature', + value: getTemperature(payloadToByteArray[startData], payloadToByteArray[startData + 1]), + unit: '� C', + }; + r.push(temperature); + startData += 2; + + if (startData + 1 === payloadToByteArray.length) { + battery = { + variable: 'battery', + value: Number(parseInt(payloadToByteArray[startData])).toFixed(), + unit: '%', + }; + r.push(battery); + } + + return r; + case 0x02: + startData = 6; + date = { + variable: 'date', + value: parseDateByte(payloadToByteArray.slice(2, startData)), + }; + r.push(date); + + ADC = { + variable: 'ADC', + value: Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(), + unit: 'mV', + }; + r.push(ADC); + startData += 2; + startData += 2; + + if (startData + 2 <= payloadToByteArray.length) { + var distanceNumber = Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(); + if (distanceNumber <= 60000) { + distance1 = { + variable: 'distance1', + value: distanceNumber, + unit: 'mm', + }; + r.push(distance1); + } else { + error = { + variable: 'distance1', + value: 'distance error [' + distanceNumber + ']', + }; + r.push(error); + } + } + startData += 2; + + var temperature = { + variable: 'temperature', + value: getTemperature(payloadToByteArray[startData], payloadToByteArray[startData + 1]), + unit: '� C', + }; + r.push(temperature); + startData += 2; + + var humidity = { + variable: 'humidity', + value: getHumidity(parseInt(payloadToByteArray[startData])), + unit: '%', + }; + r.push(humidity); + startData += 1; + + var pressure = { + variable: 'pressure', + value: getPressure(payloadToByteArray[startData], payloadToByteArray[startData + 1], payloadToByteArray[startData + 2]), + unit: 'hPa', + }; + r.push(pressure); + startData += 3; + + if (startData + 1 === payloadToByteArray.length) { + battery = { + variable: 'battery', + value: Number(parseInt(payloadToByteArray[startData])).toFixed(), + unit: '%', + }; + r.push(battery); + } + + return r; + case 0x03: + startData = 6; + date = { + variable: 'date', + value: parseDateByte(payloadToByteArray.slice(2, startData)), + }; + r.push(date); + + ADC = { + variable: 'ADC', + value: Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(), + unit: 'mV', + }; + r.push(ADC); + startData += 2; + startData += 2; + + if (startData + 2 <= payloadToByteArray.length) { + var distanceNumber = Number(((payloadToByteArray[startData + 1] << 8) & 0xff00) | (payloadToByteArray[startData] & 0xff)).toFixed(); + if (distanceNumber <= 60000) { + distance1 = { + variable: 'distance1', + value: distanceNumber, + unit: 'mm', + }; + r.push(distance1); + } else { + error = { + variable: 'distance1', + value: 'distance error [' + distanceNumber + ']', + }; + r.push(error); + } + } + startData += 2; + + var fillLevel = { + variable: 'fillLevel', + value: Number(parseInt(payloadToByteArray[startData])).toFixed(), + unit: '%', + }; + r.push(fillLevel); + startData += 1; + + var temperature = { + variable: 'temperature', + value: getTemperature(payloadToByteArray[startData], payloadToByteArray[startData + 1]), + unit: '� C', + }; + r.push(temperature); + startData += 2; + + var humidity = { + variable: 'humidity', + value: getHumidity(parseInt(payloadToByteArray[startData])), + unit: '%', + }; + r.push(humidity); + startData += 1; + + var pressure = { + variable: 'pressure', + value: getPressure(payloadToByteArray[startData], payloadToByteArray[startData + 1], payloadToByteArray[startData + 2]), + unit: 'hPa', + }; + r.push(pressure); + startData += 3; + + if (startData + 1 === payloadToByteArray.length) { + battery = { + variable: 'battery', + value: Number(parseInt(payloadToByteArray[startData])).toFixed(), + unit: '%', + }; + r.push(battery); + } + + return r; + default: + return null; + } +} + +function getTemperature(lo, hi) { + var temperature = String((((lo & 0xff) + ((hi << 8) & 0xff00)) << 16) >> 16).padStart(3); + temperature = temperature.substring(0, temperature.length - 2) + '.' + temperature.substring(temperature.length - 2); + return Number(temperature).toFixed(2); +} + +function getHumidity(lo) { + var humidity = (((((0 & 0xff) << 8) | (lo & 0xff)) << 16) >> 16) / 2; + return Number(humidity).toFixed(2); +} + +function parseDate(payload) { + var date = new Date(); + var binary = Number(parseInt(reverseBytes(payload), 16)) + .toString(2) + .padStart(32, '0'); + var year = parseInt(binary.substring(0, 7), 2) + 2000; + var month = parseInt(binary.substring(7, 11), 2); + var day = parseInt(binary.substring(11, 16), 2); + var hour = parseInt(binary.substring(16, 21), 2); + var minute = parseInt(binary.substring(21, 27), 2); + var second = parseInt(binary.substring(27, 32), 2) * 2; + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); + return date; +} + +function parseSignedInt(bytes) { + bytes = reverseBytes(bytes); + var rno = hexStringToByteArray(bytes); + var n = 0; + + if (rno.length === 4) { + n = ((rno[0] << 24) & 0xff000000) | ((rno[1] << 16) & 0x00ff0000) | ((rno[2] << 8) & 0x0000ff00) | ((rno[3] << 0) & 0x000000ff); + } + + return n; +} + +function parseUnsignedInt(bytes) { + bytes = reverseBytes(bytes); + var n = parseInt(bytes, 16); + return n; +} + +function parseSignedShort(bytes) { + bytes = reverseBytes(bytes); + var rno = hexStringToByteArray(bytes); + var n = 0; + + if (rno.length === 2) { + var n = (((rno[0] << 8) | rno[1]) << 16) >> 16; + } + + return n; +} + +function parseUnsignedShort(bytes) { + bytes = reverseBytes(bytes); + var rno = hexStringToByteArray(bytes); + var n = 0; + + if (rno.length === 2) { + n = ((rno[0] << 8) & 0x0000ff00) | ((rno[1] << 0) & 0x000000ff); + } + + return n; +} + +function reverseBytes(bytes) { + var reversed = bytes; + + if (bytes.length % 2 === 0) { + reversed = ''; + + for (var starting = 0; starting + 2 <= bytes.length; starting += 2) { + reversed = bytes.substring(starting, starting + 2) + reversed; + } + } + + return reversed; +} + +function hexStringToByteArray(s) { + for (var bytes = [], c = 0; c < s.length; c += 2) { + bytes.push(parseInt(s.substr(c, 2), 16)); + } + + return bytes; +} + +function parseDateByte(payload) { + var date = new Date(); + var binary = (payload[0] & 0xff) + ((payload[1] << 8) & 0xff00) + ((payload[2] << 16) & 0xff0000) + ((payload[3] << 24) & 0xff000000); + var second = binary & 0x1f; + second *= 2; + binary = binary >> 5; + var minute = binary & 0x3f; + binary = binary >> 6; + var hour = binary & 0x1f; + binary = binary >> 5; + var day = binary & 0x1f; + binary = binary >> 5; + var month = binary & 0x0f; + binary = binary >> 4; + var year = binary & 0x7f; + year += 2000; + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); + return date; +} diff --git a/vendor/enginko/decoder-digital.js b/vendor/enginko/decoder-digital.js index d38e2dbfeb..d0c738cab7 100644 --- a/vendor/enginko/decoder-digital.js +++ b/vendor/enginko/decoder-digital.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; function decodeUplink(payload) { payload = TTNfrom(payload); @@ -6,50 +6,50 @@ function decodeUplink(payload) { var content; switch (uplinkId.toUpperCase()) { - case "01": + case '01': content = parseTimeSync(payload.trim()); break; - case "04": + case '04': content = parseTER(payload.trim()); break; - case "09": + case '09': content = parseMetering(payload.trim()); break; - case "10": + case '10': content = parseDigitalData(payload.trim()); break; - case "12": + case '12': content = parseVOC(payload.trim(), true); //true is for new sensor break; - case "13": + case '13': content = parseCo2(payload.trim(), true); //true is for new sensor break; - case "0A": + case '0A': content = parseIO(payload.trim()); break; - case "0B": + case '0B': content = parseReportData(payload.trim()); break; - case "0C": + case '0C': content = parseVOC(payload.trim(), false); //false is for new sensor break; - case "0D": + case '0D': content = parseAnalog(payload.trim()); break; - case "0E": + case '0E': content = parseCo2(payload.trim(), false); //false is for new sensor break; @@ -58,24 +58,23 @@ function decodeUplink(payload) { content = null; break; } - return TTNto(content); } function TTNfrom(TTNpayload) { var obj; - if (typeof TTNpayload === "string") { + if (typeof TTNpayload === 'string') { obj = JSON.parse(TTNpayload); } else { obj = JSON.parse(JSON.stringify(TTNpayload)); } var fPort = obj.fPort; - var payload = ""; + var payload = ''; for (var i = 0; i < obj.bytes.length; i++) { - payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, "0"); + payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, '0'); } return payload; @@ -90,13 +89,13 @@ function TTNto(content) { } return { - data: TTNcontent + data: TTNcontent, }; } else { return { data: content, warnings: [], - errors: ["Error on decoding payload"] + errors: ['Error on decoding payload'], }; } } @@ -104,7 +103,7 @@ function TTNto(content) { function parseDigitalData(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "10") { + if (uplinkId.toUpperCase() === '10') { var m = []; var payloadToByteArray = hexStringToByteArray(payload); var type = payloadToByteArray[1]; @@ -126,23 +125,17 @@ function parseDigitalData(payload) { var count = 0; - for ( - var i = 2; - count <= 16 && i + numberOfBytes - 1 < payloadToByteArray.length; - i += numberOfBytes - ) { + for (var i = 2; count <= 16 && i + numberOfBytes - 1 < payloadToByteArray.length; i += numberOfBytes) { switch (type) { case 0x00: count++; var measure1 = { - variable: "measure", - value: Number(count).toFixed() + variable: 'measure', + value: Number(count).toFixed(), }; var counter1 = { - variable: "counter", - value: Number( - ((payloadToByteArray[i + 1] & 0xff) << 8) + payloadToByteArray[i] - ).toFixed() + variable: 'counter', + value: Number(((payloadToByteArray[i + 1] & 0xff) << 8) + payloadToByteArray[i]).toFixed(), }; m.push(measure1, counter1); break; @@ -151,21 +144,17 @@ function parseDigitalData(payload) { count++; var detection1 = payloadToByteArray.slice(i, i + numberOfBytes); var measure2 = { - variable: "measure", - value: Number(count).toFixed() + variable: 'measure', + value: Number(count).toFixed(), }; var date1 = { - variable: "date", - value: parseDateByte(detection1.slice(0, 4)) + variable: 'date', + value: parseDateByte(detection1.slice(0, 4)), }; var frequency = { - variable: "frequency", - value: Number( - ((detection1[4] & 0x000000ff) + - ((detection1[5] << 8) & 0x0000ff00)) / - 10.0 - ).toFixed(2), - unit: "Hz" + variable: 'frequency', + value: Number(((detection1[4] & 0x000000ff) + ((detection1[5] << 8) & 0x0000ff00)) / 10.0).toFixed(2), + unit: 'Hz', }; m.push(measure2, date1, frequency); break; @@ -174,18 +163,16 @@ function parseDigitalData(payload) { count++; var detection2 = payloadToByteArray.slice(i, i + numberOfBytes); var measure3 = { - variable: "measure", - value: Number(count).toFixed() + variable: 'measure', + value: Number(count).toFixed(), }; var date2 = { - variable: "date", - value: parseDateByte(detection2.slice(0, 4)) + variable: 'date', + value: parseDateByte(detection2.slice(0, 4)), }; var counter2 = { - variable: "counter", - value: Number( - detection2[4] & (0x000000ff + ((detection2[5] << 8) & 0x0000ff00)) - ).toFixed() + variable: 'counter', + value: Number(detection2[4] & (0x000000ff + ((detection2[5] << 8) & 0x0000ff00))).toFixed(), }; m.push(measure3, date2, counter2); break; @@ -201,91 +188,76 @@ function parseDigitalData(payload) { function parseMetering(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "09") { + if (uplinkId.toUpperCase() === '09') { var date = { - variable: "date", - value: parseDate(payload.substring(2, 10)) + variable: 'date', + value: parseDate(payload.substring(2, 10)), }; var activeEnergy = { - variable: "activeEnergy", + variable: 'activeEnergy', value: Number(parseSignedInt(payload.substring(10, 18))).toFixed(), - unit: "Wh" + unit: 'Wh', }; var reactiveEnergy = { - variable: "reactiveEnergy", + variable: 'reactiveEnergy', value: Number(parseSignedInt(payload.substring(18, 26))).toFixed(), - unit: "VARh" + unit: 'VARh', }; var apparentEnergy = { - variable: "apparentEnergy", + variable: 'apparentEnergy', value: Number(parseSignedInt(payload.substring(26, 34))).toFixed(), - unit: "VAh" + unit: 'VAh', }; if (payload.length <= 42) { var activation = { - variable: "activation", + variable: 'activation', value: Number(parseUnsignedInt(payload.substring(34, 42))).toFixed(), - unit: "s" + unit: 's', }; return [date, activeEnergy, reactiveEnergy, apparentEnergy, activation]; } else { var activePower = { - variable: "activePower", + variable: 'activePower', value: Number(parseSignedShort(payload.substring(34, 38))).toFixed(), - unit: "W" + unit: 'W', }; var reactivePower = { - variable: "reactivePower", + variable: 'reactivePower', value: Number(parseSignedShort(payload.substring(38, 42))).toFixed(), - unit: "VAR" + unit: 'VAR', }; var apparentPower = { - variable: "apparentPower", + variable: 'apparentPower', value: Number(parseSignedShort(payload.substring(42, 46))).toFixed(), - unit: "VA" + unit: 'VA', }; var voltage = { - variable: "voltage", + variable: 'voltage', value: Number(parseUnsignedShort(payload.substring(46, 50))).toFixed(), - unit: "dV RMS" + unit: 'dV RMS', }; var current = { - variable: "current", + variable: 'current', value: Number(parseUnsignedShort(payload.substring(50, 54))).toFixed(), - unit: "mA RMS" + unit: 'mA RMS', }; var period = { - variable: "period", + variable: 'period', value: Number(parseUnsignedShort(payload.substring(54, 58))).toFixed(), - unit: "micro s" + unit: 'micro s', }; var frequency = { - variable: "frequency", - value: Number( - 1 / (parseUnsignedShort(payload.substring(54, 58)) / 1000000) - ).toFixed(2), - unit: "Hz" + variable: 'frequency', + value: Number(1 / (parseUnsignedShort(payload.substring(54, 58)) / 1000000)).toFixed(2), + unit: 'Hz', }; var activation = { - variable: "activation", + variable: 'activation', value: Number(parseUnsignedInt(payload.substring(58, 66))).toFixed(), - unit: "s" + unit: 's', }; - return [ - date, - activeEnergy, - reactiveEnergy, - apparentEnergy, - activePower, - reactivePower, - apparentPower, - voltage, - current, - period, - frequency, - activation - ]; + return [date, activeEnergy, reactiveEnergy, apparentEnergy, activePower, reactivePower, apparentPower, voltage, current, period, frequency, activation]; } } else { return null; @@ -295,10 +267,10 @@ function parseMetering(payload) { function parseIO(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0A") { + if (uplinkId.toUpperCase() === '0A') { var date = { - variable: "date", - value: parseDate(payload.substring(2, 10)) + variable: 'date', + value: parseDate(payload.substring(2, 10)), }; var firstByte = []; var secondByte = []; @@ -315,52 +287,52 @@ function parseIO(payload) { } var inputStatus8_1 = { - variable: "inputStatus8_1", - value: firstByte[0].toString(2) + variable: 'inputStatus8_1', + value: firstByte[0].toString(2), }; var inputStatus9_16 = { - variable: "inputStatus9_16", - value: secondByte[0].toString(2) + variable: 'inputStatus9_16', + value: secondByte[0].toString(2), }; var inputStatus17_24 = { - variable: "inputStatus17_24", - value: thirdByte[0].toString(2) + variable: 'inputStatus17_24', + value: thirdByte[0].toString(2), }; var inputStatus25_32 = { - variable: "inputStatus25_32", - value: fourthByte[0].toString(2) + variable: 'inputStatus25_32', + value: fourthByte[0].toString(2), }; var outputStatus8_1 = { - variable: "outputStatus8_1", - value: firstByte[1].toString(2) + variable: 'outputStatus8_1', + value: firstByte[1].toString(2), }; var outputStatus9_16 = { - variable: "outputStatus9_16", - value: secondByte[1].toString(2) + variable: 'outputStatus9_16', + value: secondByte[1].toString(2), }; var outputStatus17_24 = { - variable: "outputStatus17_24", - value: thirdByte[1].toString(2) + variable: 'outputStatus17_24', + value: thirdByte[1].toString(2), }; var outputStatus25_32 = { - variable: "outputStatus25_32", - value: fourthByte[1].toString(2) + variable: 'outputStatus25_32', + value: fourthByte[1].toString(2), }; var inputTrigger8_1 = { - variable: "inputTrigger8_1", - value: firstByte[2].toString(2) + variable: 'inputTrigger8_1', + value: firstByte[2].toString(2), }; var inputTrigger9_16 = { - variable: "inputTrigger9_16", - value: secondByte[2].toString(2) + variable: 'inputTrigger9_16', + value: secondByte[2].toString(2), }; var inputTrigger17_24 = { - variable: "inputTrigger17_24", - value: thirdByte[2].toString(2) + variable: 'inputTrigger17_24', + value: thirdByte[2].toString(2), }; var inputTrigger25_32 = { - variable: "inputTrigger25_32", - value: fourthByte[2].toString(2) + variable: 'inputTrigger25_32', + value: fourthByte[2].toString(2), }; return [ date, @@ -375,7 +347,7 @@ function parseIO(payload) { inputTrigger8_1, inputTrigger9_16, inputTrigger17_24, - inputTrigger25_32 + inputTrigger25_32, ]; } else { return null; @@ -386,22 +358,14 @@ function parseDate(payload) { var date = new Date(); var binary = Number(parseInt(reverseBytes(payload), 16)) .toString(2) - .padStart(32, "0"); + .padStart(32, '0'); var year = parseInt(binary.substring(0, 7), 2) + 2000; var month = parseInt(binary.substring(7, 11), 2); var day = parseInt(binary.substring(11, 16), 2); var hour = parseInt(binary.substring(16, 21), 2); var minute = parseInt(binary.substring(21, 27), 2); var second = parseInt(binary.substring(27, 32), 2) * 2; - date = new Date( - year, - month - 1, - day, - hour, - minute, - second, - 0 - ).toLocaleString(); + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); return date; } @@ -411,11 +375,7 @@ function parseSignedInt(bytes) { var n = 0; if (rno.length === 4) { - n = - ((rno[0] << 24) & 0xff000000) | - ((rno[1] << 16) & 0x00ff0000) | - ((rno[2] << 8) & 0x0000ff00) | - ((rno[3] << 0) & 0x000000ff); + n = ((rno[0] << 24) & 0xff000000) | ((rno[1] << 16) & 0x00ff0000) | ((rno[2] << 8) & 0x0000ff00) | ((rno[3] << 0) & 0x000000ff); } return n; @@ -455,7 +415,7 @@ function reverseBytes(bytes) { var reversed = bytes; if (bytes.length % 2 === 0) { - reversed = ""; + reversed = ''; for (var starting = 0; starting + 2 <= bytes.length; starting += 2) { reversed = bytes.substring(starting, starting + 2) + reversed; @@ -475,11 +435,7 @@ function hexStringToByteArray(s) { function parseDateByte(payload) { var date = new Date(); - var binary = - (payload[0] & 0xff) + - ((payload[1] << 8) & 0xff00) + - ((payload[2] << 16) & 0xff0000) + - ((payload[3] << 24) & 0xff000000); + var binary = (payload[0] & 0xff) + ((payload[1] << 8) & 0xff00) + ((payload[2] << 16) & 0xff0000) + ((payload[3] << 24) & 0xff000000); var second = binary & 0x1f; second *= 2; binary = binary >> 5; @@ -493,14 +449,6 @@ function parseDateByte(payload) { binary = binary >> 4; var year = binary & 0x7f; year += 2000; - date = new Date( - year, - month - 1, - day, - hour, - minute, - second, - 0 - ).toLocaleString(); + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); return date; -} \ No newline at end of file +} diff --git a/vendor/enginko/decoder-environmental.js b/vendor/enginko/decoder-environmental.js index 57be34842f..bca9269fa7 100644 --- a/vendor/enginko/decoder-environmental.js +++ b/vendor/enginko/decoder-environmental.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; function decodeUplink(payload) { payload = TTNfrom(payload); @@ -6,50 +6,50 @@ function decodeUplink(payload) { var content; switch (uplinkId.toUpperCase()) { - case "01": + case '01': content = parseTimeSync(payload.trim()); break; - case "04": + case '04': content = parseTER(payload.trim()); break; - case "09": + case '09': content = parseMetering(payload.trim()); break; - case "10": + case '10': content = parseDigitalData(payload.trim()); break; - case "12": + case '12': content = parseVOC(payload.trim(), true); //true is for new sensor break; - case "13": + case '13': content = parseCo2(payload.trim(), true); //true is for new sensor break; - case "0A": + case '0A': content = parseIO(payload.trim()); break; - case "0B": + case '0B': content = parseReportData(payload.trim()); break; - case "0C": + case '0C': content = parseVOC(payload.trim(), false); //false is for new sensor break; - case "0D": + case '0D': content = parseAnalog(payload.trim()); break; - case "0E": + case '0E': content = parseCo2(payload.trim(), false); //false is for new sensor break; @@ -65,17 +65,17 @@ function decodeUplink(payload) { function TTNfrom(TTNpayload) { var obj; - if (typeof TTNpayload === "string") { + if (typeof TTNpayload === 'string') { obj = JSON.parse(TTNpayload); } else { obj = JSON.parse(JSON.stringify(TTNpayload)); } var fPort = obj.fPort; - var payload = ""; + var payload = ''; for (var i = 0; i < obj.bytes.length; i++) { - payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, "0"); + payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, '0'); } return payload; @@ -90,13 +90,13 @@ function TTNto(content) { } return { - data: TTNcontent + data: TTNcontent, }; } else { return { data: content, warnings: [], - errors: ["Error on decoding payload"] + errors: ['Error on decoding payload'], }; } } @@ -104,18 +104,18 @@ function TTNto(content) { function parseTER(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "04") { + if (uplinkId.toUpperCase() === '04') { var m1 = parseTERMeasurement(payload.substring(2, 22)); var m2 = parseTERMeasurement(payload.substring(22, 42)); var m3 = parseTERMeasurement(payload.substring(42, 62)); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(62, 64), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(64) + variable: 'rfu', + value: payload.substring(64), }; return [].concat(m1, m2, m3, [battery, rfu]); } else { @@ -125,30 +125,23 @@ function parseTER(payload) { function parseTERMeasurement(payload) { var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; return [date, temperature, humidity, pressure]; } @@ -157,34 +150,34 @@ function parseVOC(payload, isNew) { var uplinkId = payload.substring(0, 2); if (!isNew) { - if (uplinkId.toUpperCase() === "0C") { + if (uplinkId.toUpperCase() === '0C') { var m1 = parseVOCMeasurement(payload.substring(2, 30), isNew); var m2 = parseVOCMeasurement(payload.substring(30, 58), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(58, 60), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(60) + variable: 'rfu', + value: payload.substring(60), }; return [].concat(m1, m2, [battery, rfu]); } else { return null; } } else { - if (uplinkId.toUpperCase() === "12") { + if (uplinkId.toUpperCase() === '12') { var m1 = parseVOCMeasurement(payload.substring(2, 32), isNew); var m2 = parseVOCMeasurement(payload.substring(32, 62), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(62, 64), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(64) + variable: 'rfu', + value: payload.substring(64), }; return [].concat(m1, m2, [battery, rfu]); } else { @@ -196,84 +189,65 @@ function parseVOC(payload, isNew) { function parseVOCMeasurement(payload, isNew) { if (!isNew) { var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", + variable: 'voc', value: Number(parseUnsignedShort(payload.substring(24, 28))).toFixed(), - unit: "IAQ/ppb" + unit: 'IAQ/ppb', }; return [date, temperature, humidity, pressure, lux, voc]; } else { var payloadToByteArray = hexStringToByteArray(payload); var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", - value: Number( - 0x00000000 | - (payloadToByteArray[12] & 0x000000ff) | - ((payloadToByteArray[13] << 8) & 0x0000ff00) | - ((payloadToByteArray[14] << 16) & 0x00ff0000) - ).toFixed(), - unit: "IAQ/ppb" + variable: 'voc', + value: Number(0x00000000 | (payloadToByteArray[12] & 0x000000ff) | ((payloadToByteArray[13] << 8) & 0x0000ff00) | ((payloadToByteArray[14] << 16) & 0x00ff0000)).toFixed(), + unit: 'IAQ/ppb', }; return [date, temperature, humidity, pressure, lux, voc]; } @@ -283,34 +257,34 @@ function parseCo2(payload, isNew) { var uplinkId = payload.substring(0, 2); if (!isNew) { - if (uplinkId.toUpperCase() === "0E") { + if (uplinkId.toUpperCase() === '0E') { var m1 = parseCo2Measurement(payload.substring(2, 34), isNew); var m2 = parseCo2Measurement(payload.substring(34, 66), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(66, 68), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(68) + variable: 'rfu', + value: payload.substring(68), }; return [].concat(m1, m2, [battery, rfu]); } else { return null; } } else { - if (uplinkId.toUpperCase() === "13") { + if (uplinkId.toUpperCase() === '13') { var m1 = parseCo2Measurement(payload.substring(2, 36), isNew); var m2 = parseCo2Measurement(payload.substring(36, 70), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(70, 72), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(72) + variable: 'rfu', + value: payload.substring(72), }; return [].concat(m1, m2, [battery, rfu]); } else { @@ -322,94 +296,75 @@ function parseCo2(payload, isNew) { function parseCo2Measurement(payload, isNew) { if (!isNew) { var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", + variable: 'voc', value: Number(parseUnsignedShort(payload.substring(24, 28))).toFixed(), - unit: "IAQ/ppb" + unit: 'IAQ/ppb', }; var co2 = { - variable: "co2", + variable: 'co2', value: Number(parseSignedShort(payload.substring(28, 32))).toFixed(), - unit: "ppm" + unit: 'ppm', }; return [date, temperature, humidity, pressure, lux, voc, co2]; } else { var payloadToByteArray = hexStringToByteArray(payload); var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", - value: Number( - 0x00000000 | - (payloadToByteArray[12] & 0x000000ff) | - ((payloadToByteArray[13] << 8) & 0x0000ff00) | - ((payloadToByteArray[14] << 16) & 0x00ff0000) - ).toFixed(), - unit: "IAQ/ppb" + variable: 'voc', + value: Number(0x00000000 | (payloadToByteArray[12] & 0x000000ff) | ((payloadToByteArray[13] << 8) & 0x0000ff00) | ((payloadToByteArray[14] << 16) & 0x00ff0000)).toFixed(), + unit: 'IAQ/ppb', }; var co2 = { - variable: "co2", + variable: 'co2', value: Number(parseSignedShort(payload.substring(30, 34))).toFixed(), - unit: "ppm" + unit: 'ppm', }; return [date, temperature, humidity, pressure, lux, voc, co2]; } @@ -419,20 +374,20 @@ function parseReportData(payload) { var uplinkId = payload.substring(0, 2); var content; - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { switch (payload.substring(2, 3)) { - case "1": - case "4": + case '1': + case '4': content = parseModBus(payload); break; - case "2": + case '2': switch (payload.substring(4, 6)) { - case "00": + case '00': content = parseWeather(payload); break; - case "01": + case '01': content = parsePM(payload); break; @@ -443,7 +398,7 @@ function parseReportData(payload) { break; - case "3": + case '3': content = parseTERPM(payload); break; @@ -459,68 +414,65 @@ function parseReportData(payload) { } function parseModBus(payloads) { - var splitted = payloads.split("\n"); //payloads must be on diffrent lines or change the \n split character + var splitted = payloads.split('\n'); //payloads must be on diffrent lines or change the \n split character var m = []; - var dP = ""; + var dP = ''; for (var i = 0; i < splitted.length; i++) { var payload = splitted[i]; var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(2); - if (payload.substring(2, 3) === "1" || payload.substring(2, 3) === "4") { + if (payload.substring(2, 3) === '1' || payload.substring(2, 3) === '4') { var id = Number(payloadToByteArray[0]).toFixed(); var frameId = { - variable: "frameId", - value: id + variable: 'frameId', + value: id, }; if (payload.length === 12) { - var e = ""; + var e = ''; switch (payload.substring(10, 12).toUpperCase()) { - case "05": - e = "Configuration error"; + case '05': + e = 'Configuration error'; break; - case "07": - e = "Error reading internal configuration"; + case '07': + e = 'Error reading internal configuration'; break; - case "7F": - e = "Command not implemented"; + case '7F': + e = 'Command not implemented'; break; - case "CC": - e = "Communication error"; + case 'CC': + e = 'Communication error'; break; } var error = { - variable: "error", - value: e + variable: 'error', + value: e, }; m.push.apply(m, [frameId, error]); } else { - var d = id === "0" ? payload.substring(10) : payload.substring(6); + var d = id === '0' ? payload.substring(10) : payload.substring(6); var data = { - variable: "data", - value: d + variable: 'data', + value: d, }; dP += d; - if (id === "0") { + if (id === '0') { //length is declared only on first payload var length = { - variable: "length", - value: Number( - ((payloadToByteArray[2] << 8) & 0x0000ff00) | - (payloadToByteArray[1] & 0x000000ff) - ).toFixed() + variable: 'length', + value: Number(((payloadToByteArray[2] << 8) & 0x0000ff00) | (payloadToByteArray[1] & 0x000000ff)).toFixed(), }; m.push.apply(m, [frameId, length, data]); } else { @@ -532,8 +484,8 @@ function parseModBus(payloads) { } var dataPayload = { - variable: "dataPayload", - value: dP + variable: 'dataPayload', + value: dP, }; return [].concat(m, [dataPayload]); } @@ -541,38 +493,29 @@ function parseModBus(payloads) { function parsePM(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(3); - if (payload.substring(2, 3) === "2" && payload.substring(4, 6) === "01") { + if (payload.substring(2, 3) === '2' && payload.substring(4, 6) === '01') { var date = { - variable: "date", - value: parseDate(payload.substring(6, 14)) + variable: 'date', + value: parseDate(payload.substring(6, 14)), }; var pm1 = { - variable: "pm1", - value: Number( - (payloadToByteArray[4] & 0xff) + - ((payloadToByteArray[5] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm1', + value: Number((payloadToByteArray[4] & 0xff) + ((payloadToByteArray[5] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm25 = { - variable: "pm25", - value: Number( - (payloadToByteArray[6] & 0xff) + - ((payloadToByteArray[7] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm25', + value: Number((payloadToByteArray[6] & 0xff) + ((payloadToByteArray[7] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm10 = { - variable: "pm10", - value: Number( - (payloadToByteArray[8] & 0xff) + - ((payloadToByteArray[9] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm10', + value: Number((payloadToByteArray[8] & 0xff) + ((payloadToByteArray[9] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; return [date, pm1, pm25, pm10]; } else { @@ -586,77 +529,55 @@ function parsePM(payload) { function parseTERPM(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(3); - if (payload.substring(2, 3) === "3" && payload.substring(4, 6) === "00") { + if (payload.substring(2, 3) === '3' && payload.substring(4, 6) === '00') { var date = { - variable: "date", - value: parseDate(payload.substring(6, 14)) + variable: 'date', + value: parseDate(payload.substring(6, 14)), }; var temperature = { - variable: "temperature", + variable: 'temperature', value: getTemperature(payloadToByteArray[4], payloadToByteArray[5]), - unit: "�C" + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(payloadToByteArray[6]), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - payloadToByteArray[7], - payloadToByteArray[8], - payloadToByteArray[9] - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(payloadToByteArray[7], payloadToByteArray[8], payloadToByteArray[9]), + unit: 'hPa', }; var pm1 = { - variable: "pm1", - value: Number( - (payloadToByteArray[10] & 0xff) + - ((payloadToByteArray[11] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm1', + value: Number((payloadToByteArray[10] & 0xff) + ((payloadToByteArray[11] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm25 = { - variable: "pm25", - value: Number( - (payloadToByteArray[12] & 0xff) + - ((payloadToByteArray[13] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm25', + value: Number((payloadToByteArray[12] & 0xff) + ((payloadToByteArray[13] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm10 = { - variable: "pm10", - value: Number( - (payloadToByteArray[14] & 0xff) + - ((payloadToByteArray[15] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm10', + value: Number((payloadToByteArray[14] & 0xff) + ((payloadToByteArray[15] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; if (payload.length <= 38) { return [date, temperature, humidity, pressure, pm1, pm25, pm10]; } else { var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payloadToByteArray[16])).toFixed(), - unit: "%" + unit: '%', }; - return [ - date, - temperature, - humidity, - pressure, - pm1, - pm25, - pm10, - battery - ]; + return [date, temperature, humidity, pressure, pm1, pm25, pm10, battery]; } } else { return null; @@ -669,94 +590,71 @@ function parseTERPM(payload) { function parseWeather(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(3); - if (payload.substring(2, 3) === "2" && payload.substring(4, 6) === "00") { + if (payload.substring(2, 3) === '2' && payload.substring(4, 6) === '00') { var pressure = { - variable: "pressure", - value: getAtmosphericPressure( - (((payloadToByteArray[3] << 8) & 0x0000ff00) | - (payloadToByteArray[2] & 0x000000ff)) / - 1000.0 - ), - unit: "hPa" + variable: 'pressure', + value: getAtmosphericPressure((((payloadToByteArray[3] << 8) & 0x0000ff00) | (payloadToByteArray[2] & 0x000000ff)) / 1000.0), + unit: 'hPa', }; var outsideTemperature = { - variable: "outsideTemperature", - value: getFahrenheitToCelsius( - (((payloadToByteArray[5] << 8) & 0x0000ff00) | - (payloadToByteArray[4] & 0x000000ff)) / - 10.0 - ), - unit: "�C" + variable: 'outsideTemperature', + value: getFahrenheitToCelsius((((payloadToByteArray[5] << 8) & 0x0000ff00) | (payloadToByteArray[4] & 0x000000ff)) / 10.0), + unit: '�C', }; var windSpeed = { - variable: "windSpeed", + variable: 'windSpeed', value: getWindSpeed(payloadToByteArray[6] & 0x00ff), - unit: "m/s" + unit: 'm/s', }; var tenMinutesAvgWindSpeed = { - variable: "tenMinutesAvgWindSpeed", + variable: 'tenMinutesAvgWindSpeed', value: getWindSpeed(payloadToByteArray[7] & 0x00ff), - unit: "m/s" + unit: 'm/s', }; var windDirection = { - variable: "windDirection", - value: Number( - ((payloadToByteArray[9] << 8) & 0x0000ff00) | - (payloadToByteArray[8] & 0x000000ff) - ).toFixed(2), - unit: "�" + variable: 'windDirection', + value: Number(((payloadToByteArray[9] << 8) & 0x0000ff00) | (payloadToByteArray[8] & 0x000000ff)).toFixed(2), + unit: '�', }; var outsideHumidity = { - variable: "outsideHumidity", + variable: 'outsideHumidity', value: Number(payloadToByteArray[10] & 0x00ff).toFixed(2), - unit: "%" + unit: '%', }; var rainRate = { - variable: "rainRate", - value: getRainRate( - ((payloadToByteArray[12] << 8) & 0x0000ff00) | - (payloadToByteArray[11] & 0x000000ff) - ), - unit: "mm/h" + variable: 'rainRate', + value: getRainRate(((payloadToByteArray[12] << 8) & 0x0000ff00) | (payloadToByteArray[11] & 0x000000ff)), + unit: 'mm/h', }; var uv = { - variable: "uv", - value: Number(payloadToByteArray[13] & 0x00ff).toFixed(2) + variable: 'uv', + value: Number(payloadToByteArray[13] & 0x00ff).toFixed(2), }; var solarRadiation = { - variable: "solarRadiation", - value: Number( - ((payloadToByteArray[15] << 8) & 0x0000ff00) | - (payloadToByteArray[14] & 0x000000ff) - ).toFixed(2), - unit: "W/m�" + variable: 'solarRadiation', + value: Number(((payloadToByteArray[15] << 8) & 0x0000ff00) | (payloadToByteArray[14] & 0x000000ff)).toFixed(2), + unit: 'W/m�', }; var dayRain = { - variable: "dayRain", - value: getRainRate( - ((payloadToByteArray[17] << 8) & 0x0000ff00) | - (payloadToByteArray[16] & 0x000000ff) - ) + variable: 'dayRain', + value: getRainRate(((payloadToByteArray[17] << 8) & 0x0000ff00) | (payloadToByteArray[16] & 0x000000ff)), }; var dayET = { - variable: "dayET", - value: getET( - ((payloadToByteArray[19] << 8) & 0x0000ff00) | - (payloadToByteArray[18] & 0x000000ff) - ), - unit: "mm" + variable: 'dayET', + value: getET(((payloadToByteArray[19] << 8) & 0x0000ff00) | (payloadToByteArray[18] & 0x000000ff)), + unit: 'mm', }; var soilMoistures = []; for (var i = 0; i < 4; i++) { var soilMoisture = { - variable: "soilMoisture", + variable: 'soilMoisture', value: Number(payloadToByteArray[20 + i]).toFixed(2), - unit: "centibar" + unit: 'centibar', }; soilMoistures.push(soilMoisture); } @@ -765,19 +663,19 @@ function parseWeather(payload) { for (var i = 0; i < 4; i++) { var leafWetness = { - variable: "leafWetness", - value: Number(payloadToByteArray[24 + i]) + variable: 'leafWetness', + value: Number(payloadToByteArray[24 + i]), }; leafWetnesses.push(leafWetness); } var forecastIcons = { - variable: "forecastIcons", - value: Number(payloadToByteArray[28]).toFixed() + variable: 'forecastIcons', + value: Number(payloadToByteArray[28]).toFixed(), }; var barTrend = { - variable: "barTrend", - value: Number(payloadToByteArray[29]).toFixed(2) + variable: 'barTrend', + value: Number(payloadToByteArray[29]).toFixed(2), }; return [ pressure, @@ -794,7 +692,7 @@ function parseWeather(payload) { soilMoistures, leafWetnesses, forecastIcons, - barTrend + barTrend, ]; } } else { @@ -831,22 +729,14 @@ function parseDate(payload) { var date = new Date(); var binary = Number(parseInt(reverseBytes(payload), 16)) .toString(2) - .padStart(32, "0"); + .padStart(32, '0'); var year = parseInt(binary.substring(0, 7), 2) + 2000; var month = parseInt(binary.substring(7, 11), 2); var day = parseInt(binary.substring(11, 16), 2); var hour = parseInt(binary.substring(16, 21), 2); var minute = parseInt(binary.substring(21, 27), 2); var second = parseInt(binary.substring(27, 32), 2) * 2; - date = new Date( - year, - month - 1, - day, - hour, - minute, - second, - 0 - ).toLocaleString(); + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); return date; } @@ -856,24 +746,14 @@ function getHumidity(lo) { } function getPressure(lo, mi, hi) { - var pressure = String( - (lo & 0xff) + ((mi << 8) & 0xff00) + ((hi << 16) & 0xff0000) - ).padStart(3); - pressure = - pressure.substring(0, pressure.length - 2) + - "." + - pressure.substring(pressure.length - 2); + var pressure = String((lo & 0xff) + ((mi << 8) & 0xff00) + ((hi << 16) & 0xff0000)).padStart(3); + pressure = pressure.substring(0, pressure.length - 2) + '.' + pressure.substring(pressure.length - 2); return Number(pressure).toFixed(2); } function getTemperature(lo, hi) { - var temperature = String( - (((lo & 0xff) + ((hi << 8) & 0xff00)) << 16) >> 16 - ).padStart(3); - temperature = - temperature.substring(0, temperature.length - 2) + - "." + - temperature.substring(temperature.length - 2); + var temperature = String((((lo & 0xff) + ((hi << 8) & 0xff00)) << 16) >> 16).padStart(3); + temperature = temperature.substring(0, temperature.length - 2) + '.' + temperature.substring(temperature.length - 2); return Number(temperature).toFixed(2); } @@ -913,7 +793,7 @@ function reverseBytes(bytes) { var reversed = bytes; if (bytes.length % 2 === 0) { - reversed = ""; + reversed = ''; for (var starting = 0; starting + 2 <= bytes.length; starting += 2) { reversed = bytes.substring(starting, starting + 2) + reversed; @@ -921,4 +801,4 @@ function reverseBytes(bytes) { } return reversed; -} \ No newline at end of file +} diff --git a/vendor/enginko/decoder-level.js b/vendor/enginko/decoder-level.js new file mode 100644 index 0000000000..5d03d6487f --- /dev/null +++ b/vendor/enginko/decoder-level.js @@ -0,0 +1,206 @@ +'use strict'; + +function decodeUplink(payload) { + payload = TTNfrom(payload); + var uplinkId = payload.substring(0, 2); + var content; + + switch (uplinkId.toUpperCase()) { + case '01': + content = parseTimeSync(payload.trim()); + break; + + case '04': + content = parseTER(payload.trim()); + break; + + case '09': + content = parseMetering(payload.trim()); + break; + + case '10': + content = parseDigitalData(payload.trim()); + break; + + case '12': + content = parseVOC(payload.trim(), true); //true is for new sensor + + break; + + case '13': + content = parseCo2(payload.trim(), true); //true is for new sensor + + break; + + case '0A': + content = parseIO(payload.trim()); + break; + + case '0B': + content = parseReportData(payload.trim()); + break; + + case '0C': + content = parseVOC(payload.trim(), false); //false is for new sensor + + break; + + case '0D': + content = parseAnalog(payload.trim()); + break; + + case '0E': + content = parseCo2(payload.trim(), false); //false is for new sensor + + break; + + case '14': + content = parseLevel(payload.trim(), false); //false is for new sensor + + break; + + default: + content = null; + break; + } + + return TTNto(content); +} + +function TTNfrom(TTNpayload) { + var obj; + + if (typeof TTNpayload === 'string') { + obj = JSON.parse(TTNpayload); + } else { + obj = JSON.parse(JSON.stringify(TTNpayload)); + } + + var fPort = obj.fPort; + var payload = ''; + + for (var i = 0; i < obj.bytes.length; i++) { + payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, '0'); + } + + return payload; +} + +function TTNto(content) { + var TTNcontent = {}; + + if (content !== null) { + for (var i = 0; i < content.length; i++) { + TTNcontent[content[i].variable] = content[i].value; + } + + return { + data: TTNcontent, + }; + } else { + return { + data: content, + warnings: [], + errors: ['Error on decoding payload'], + }; + } +} + +function parseDate(payload) { + var date = new Date(); + var binary = Number(parseInt(reverseBytes(payload), 16)) + .toString(2) + .padStart(32, '0'); + var year = parseInt(binary.substring(0, 7), 2) + 2000; + var month = parseInt(binary.substring(7, 11), 2); + var day = parseInt(binary.substring(11, 16), 2); + var hour = parseInt(binary.substring(16, 21), 2); + var minute = parseInt(binary.substring(21, 27), 2); + var second = parseInt(binary.substring(27, 32), 2) * 2; + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); + return date; +} + +function parseSignedInt(bytes) { + bytes = reverseBytes(bytes); + var rno = hexStringToByteArray(bytes); + var n = 0; + + if (rno.length === 4) { + n = ((rno[0] << 24) & 0xff000000) | ((rno[1] << 16) & 0x00ff0000) | ((rno[2] << 8) & 0x0000ff00) | ((rno[3] << 0) & 0x000000ff); + } + + return n; +} + +function parseUnsignedInt(bytes) { + bytes = reverseBytes(bytes); + var n = parseInt(bytes, 16); + return n; +} + +function parseSignedShort(bytes) { + bytes = reverseBytes(bytes); + var rno = hexStringToByteArray(bytes); + var n = 0; + + if (rno.length === 2) { + var n = (((rno[0] << 8) | rno[1]) << 16) >> 16; + } + + return n; +} + +function parseUnsignedShort(bytes) { + bytes = reverseBytes(bytes); + var rno = hexStringToByteArray(bytes); + var n = 0; + + if (rno.length === 2) { + n = ((rno[0] << 8) & 0x0000ff00) | ((rno[1] << 0) & 0x000000ff); + } + + return n; +} + +function reverseBytes(bytes) { + var reversed = bytes; + + if (bytes.length % 2 === 0) { + reversed = ''; + + for (var starting = 0; starting + 2 <= bytes.length; starting += 2) { + reversed = bytes.substring(starting, starting + 2) + reversed; + } + } + + return reversed; +} + +function hexStringToByteArray(s) { + for (var bytes = [], c = 0; c < s.length; c += 2) { + bytes.push(parseInt(s.substr(c, 2), 16)); + } + + return bytes; +} + +function parseDateByte(payload) { + var date = new Date(); + var binary = (payload[0] & 0xff) + ((payload[1] << 8) & 0xff00) + ((payload[2] << 16) & 0xff0000) + ((payload[3] << 24) & 0xff000000); + var second = binary & 0x1f; + second *= 2; + binary = binary >> 5; + var minute = binary & 0x3f; + binary = binary >> 6; + var hour = binary & 0x1f; + binary = binary >> 5; + var day = binary & 0x1f; + binary = binary >> 5; + var month = binary & 0x0f; + binary = binary >> 4; + var year = binary & 0x7f; + year += 2000; + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); + return date; +} diff --git a/vendor/enginko/decoder-power.js b/vendor/enginko/decoder-power.js index d38e2dbfeb..b175d6b150 100644 --- a/vendor/enginko/decoder-power.js +++ b/vendor/enginko/decoder-power.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; function decodeUplink(payload) { payload = TTNfrom(payload); @@ -6,50 +6,50 @@ function decodeUplink(payload) { var content; switch (uplinkId.toUpperCase()) { - case "01": + case '01': content = parseTimeSync(payload.trim()); break; - case "04": + case '04': content = parseTER(payload.trim()); break; - case "09": + case '09': content = parseMetering(payload.trim()); break; - case "10": + case '10': content = parseDigitalData(payload.trim()); break; - case "12": + case '12': content = parseVOC(payload.trim(), true); //true is for new sensor break; - case "13": + case '13': content = parseCo2(payload.trim(), true); //true is for new sensor break; - case "0A": + case '0A': content = parseIO(payload.trim()); break; - case "0B": + case '0B': content = parseReportData(payload.trim()); break; - case "0C": + case '0C': content = parseVOC(payload.trim(), false); //false is for new sensor break; - case "0D": + case '0D': content = parseAnalog(payload.trim()); break; - case "0E": + case '0E': content = parseCo2(payload.trim(), false); //false is for new sensor break; @@ -65,17 +65,17 @@ function decodeUplink(payload) { function TTNfrom(TTNpayload) { var obj; - if (typeof TTNpayload === "string") { + if (typeof TTNpayload === 'string') { obj = JSON.parse(TTNpayload); } else { obj = JSON.parse(JSON.stringify(TTNpayload)); } var fPort = obj.fPort; - var payload = ""; + var payload = ''; for (var i = 0; i < obj.bytes.length; i++) { - payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, "0"); + payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, '0'); } return payload; @@ -90,13 +90,13 @@ function TTNto(content) { } return { - data: TTNcontent + data: TTNcontent, }; } else { return { data: content, warnings: [], - errors: ["Error on decoding payload"] + errors: ['Error on decoding payload'], }; } } @@ -104,7 +104,7 @@ function TTNto(content) { function parseDigitalData(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "10") { + if (uplinkId.toUpperCase() === '10') { var m = []; var payloadToByteArray = hexStringToByteArray(payload); var type = payloadToByteArray[1]; @@ -126,23 +126,17 @@ function parseDigitalData(payload) { var count = 0; - for ( - var i = 2; - count <= 16 && i + numberOfBytes - 1 < payloadToByteArray.length; - i += numberOfBytes - ) { + for (var i = 2; count <= 16 && i + numberOfBytes - 1 < payloadToByteArray.length; i += numberOfBytes) { switch (type) { case 0x00: count++; var measure1 = { - variable: "measure", - value: Number(count).toFixed() + variable: 'measure', + value: Number(count).toFixed(), }; var counter1 = { - variable: "counter", - value: Number( - ((payloadToByteArray[i + 1] & 0xff) << 8) + payloadToByteArray[i] - ).toFixed() + variable: 'counter', + value: Number(((payloadToByteArray[i + 1] & 0xff) << 8) + payloadToByteArray[i]).toFixed(), }; m.push(measure1, counter1); break; @@ -151,21 +145,17 @@ function parseDigitalData(payload) { count++; var detection1 = payloadToByteArray.slice(i, i + numberOfBytes); var measure2 = { - variable: "measure", - value: Number(count).toFixed() + variable: 'measure', + value: Number(count).toFixed(), }; var date1 = { - variable: "date", - value: parseDateByte(detection1.slice(0, 4)) + variable: 'date', + value: parseDateByte(detection1.slice(0, 4)), }; var frequency = { - variable: "frequency", - value: Number( - ((detection1[4] & 0x000000ff) + - ((detection1[5] << 8) & 0x0000ff00)) / - 10.0 - ).toFixed(2), - unit: "Hz" + variable: 'frequency', + value: Number(((detection1[4] & 0x000000ff) + ((detection1[5] << 8) & 0x0000ff00)) / 10.0).toFixed(2), + unit: 'Hz', }; m.push(measure2, date1, frequency); break; @@ -174,18 +164,16 @@ function parseDigitalData(payload) { count++; var detection2 = payloadToByteArray.slice(i, i + numberOfBytes); var measure3 = { - variable: "measure", - value: Number(count).toFixed() + variable: 'measure', + value: Number(count).toFixed(), }; var date2 = { - variable: "date", - value: parseDateByte(detection2.slice(0, 4)) + variable: 'date', + value: parseDateByte(detection2.slice(0, 4)), }; var counter2 = { - variable: "counter", - value: Number( - detection2[4] & (0x000000ff + ((detection2[5] << 8) & 0x0000ff00)) - ).toFixed() + variable: 'counter', + value: Number(detection2[4] & (0x000000ff + ((detection2[5] << 8) & 0x0000ff00))).toFixed(), }; m.push(measure3, date2, counter2); break; @@ -201,91 +189,76 @@ function parseDigitalData(payload) { function parseMetering(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "09") { + if (uplinkId.toUpperCase() === '09') { var date = { - variable: "date", - value: parseDate(payload.substring(2, 10)) + variable: 'date', + value: parseDate(payload.substring(2, 10)), }; var activeEnergy = { - variable: "activeEnergy", + variable: 'activeEnergy', value: Number(parseSignedInt(payload.substring(10, 18))).toFixed(), - unit: "Wh" + unit: 'Wh', }; var reactiveEnergy = { - variable: "reactiveEnergy", + variable: 'reactiveEnergy', value: Number(parseSignedInt(payload.substring(18, 26))).toFixed(), - unit: "VARh" + unit: 'VARh', }; var apparentEnergy = { - variable: "apparentEnergy", + variable: 'apparentEnergy', value: Number(parseSignedInt(payload.substring(26, 34))).toFixed(), - unit: "VAh" + unit: 'VAh', }; if (payload.length <= 42) { var activation = { - variable: "activation", + variable: 'activation', value: Number(parseUnsignedInt(payload.substring(34, 42))).toFixed(), - unit: "s" + unit: 's', }; return [date, activeEnergy, reactiveEnergy, apparentEnergy, activation]; } else { var activePower = { - variable: "activePower", + variable: 'activePower', value: Number(parseSignedShort(payload.substring(34, 38))).toFixed(), - unit: "W" + unit: 'W', }; var reactivePower = { - variable: "reactivePower", + variable: 'reactivePower', value: Number(parseSignedShort(payload.substring(38, 42))).toFixed(), - unit: "VAR" + unit: 'VAR', }; var apparentPower = { - variable: "apparentPower", + variable: 'apparentPower', value: Number(parseSignedShort(payload.substring(42, 46))).toFixed(), - unit: "VA" + unit: 'VA', }; var voltage = { - variable: "voltage", + variable: 'voltage', value: Number(parseUnsignedShort(payload.substring(46, 50))).toFixed(), - unit: "dV RMS" + unit: 'dV RMS', }; var current = { - variable: "current", + variable: 'current', value: Number(parseUnsignedShort(payload.substring(50, 54))).toFixed(), - unit: "mA RMS" + unit: 'mA RMS', }; var period = { - variable: "period", + variable: 'period', value: Number(parseUnsignedShort(payload.substring(54, 58))).toFixed(), - unit: "micro s" + unit: 'micro s', }; var frequency = { - variable: "frequency", - value: Number( - 1 / (parseUnsignedShort(payload.substring(54, 58)) / 1000000) - ).toFixed(2), - unit: "Hz" + variable: 'frequency', + value: Number(1 / (parseUnsignedShort(payload.substring(54, 58)) / 1000000)).toFixed(2), + unit: 'Hz', }; var activation = { - variable: "activation", + variable: 'activation', value: Number(parseUnsignedInt(payload.substring(58, 66))).toFixed(), - unit: "s" + unit: 's', }; - return [ - date, - activeEnergy, - reactiveEnergy, - apparentEnergy, - activePower, - reactivePower, - apparentPower, - voltage, - current, - period, - frequency, - activation - ]; + return [date, activeEnergy, reactiveEnergy, apparentEnergy, activePower, reactivePower, apparentPower, voltage, current, period, frequency, activation]; } } else { return null; @@ -295,10 +268,10 @@ function parseMetering(payload) { function parseIO(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0A") { + if (uplinkId.toUpperCase() === '0A') { var date = { - variable: "date", - value: parseDate(payload.substring(2, 10)) + variable: 'date', + value: parseDate(payload.substring(2, 10)), }; var firstByte = []; var secondByte = []; @@ -315,52 +288,52 @@ function parseIO(payload) { } var inputStatus8_1 = { - variable: "inputStatus8_1", - value: firstByte[0].toString(2) + variable: 'inputStatus8_1', + value: firstByte[0].toString(2), }; var inputStatus9_16 = { - variable: "inputStatus9_16", - value: secondByte[0].toString(2) + variable: 'inputStatus9_16', + value: secondByte[0].toString(2), }; var inputStatus17_24 = { - variable: "inputStatus17_24", - value: thirdByte[0].toString(2) + variable: 'inputStatus17_24', + value: thirdByte[0].toString(2), }; var inputStatus25_32 = { - variable: "inputStatus25_32", - value: fourthByte[0].toString(2) + variable: 'inputStatus25_32', + value: fourthByte[0].toString(2), }; var outputStatus8_1 = { - variable: "outputStatus8_1", - value: firstByte[1].toString(2) + variable: 'outputStatus8_1', + value: firstByte[1].toString(2), }; var outputStatus9_16 = { - variable: "outputStatus9_16", - value: secondByte[1].toString(2) + variable: 'outputStatus9_16', + value: secondByte[1].toString(2), }; var outputStatus17_24 = { - variable: "outputStatus17_24", - value: thirdByte[1].toString(2) + variable: 'outputStatus17_24', + value: thirdByte[1].toString(2), }; var outputStatus25_32 = { - variable: "outputStatus25_32", - value: fourthByte[1].toString(2) + variable: 'outputStatus25_32', + value: fourthByte[1].toString(2), }; var inputTrigger8_1 = { - variable: "inputTrigger8_1", - value: firstByte[2].toString(2) + variable: 'inputTrigger8_1', + value: firstByte[2].toString(2), }; var inputTrigger9_16 = { - variable: "inputTrigger9_16", - value: secondByte[2].toString(2) + variable: 'inputTrigger9_16', + value: secondByte[2].toString(2), }; var inputTrigger17_24 = { - variable: "inputTrigger17_24", - value: thirdByte[2].toString(2) + variable: 'inputTrigger17_24', + value: thirdByte[2].toString(2), }; var inputTrigger25_32 = { - variable: "inputTrigger25_32", - value: fourthByte[2].toString(2) + variable: 'inputTrigger25_32', + value: fourthByte[2].toString(2), }; return [ date, @@ -375,7 +348,7 @@ function parseIO(payload) { inputTrigger8_1, inputTrigger9_16, inputTrigger17_24, - inputTrigger25_32 + inputTrigger25_32, ]; } else { return null; @@ -386,22 +359,14 @@ function parseDate(payload) { var date = new Date(); var binary = Number(parseInt(reverseBytes(payload), 16)) .toString(2) - .padStart(32, "0"); + .padStart(32, '0'); var year = parseInt(binary.substring(0, 7), 2) + 2000; var month = parseInt(binary.substring(7, 11), 2); var day = parseInt(binary.substring(11, 16), 2); var hour = parseInt(binary.substring(16, 21), 2); var minute = parseInt(binary.substring(21, 27), 2); var second = parseInt(binary.substring(27, 32), 2) * 2; - date = new Date( - year, - month - 1, - day, - hour, - minute, - second, - 0 - ).toLocaleString(); + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); return date; } @@ -411,11 +376,7 @@ function parseSignedInt(bytes) { var n = 0; if (rno.length === 4) { - n = - ((rno[0] << 24) & 0xff000000) | - ((rno[1] << 16) & 0x00ff0000) | - ((rno[2] << 8) & 0x0000ff00) | - ((rno[3] << 0) & 0x000000ff); + n = ((rno[0] << 24) & 0xff000000) | ((rno[1] << 16) & 0x00ff0000) | ((rno[2] << 8) & 0x0000ff00) | ((rno[3] << 0) & 0x000000ff); } return n; @@ -455,7 +416,7 @@ function reverseBytes(bytes) { var reversed = bytes; if (bytes.length % 2 === 0) { - reversed = ""; + reversed = ''; for (var starting = 0; starting + 2 <= bytes.length; starting += 2) { reversed = bytes.substring(starting, starting + 2) + reversed; @@ -475,11 +436,7 @@ function hexStringToByteArray(s) { function parseDateByte(payload) { var date = new Date(); - var binary = - (payload[0] & 0xff) + - ((payload[1] << 8) & 0xff00) + - ((payload[2] << 16) & 0xff0000) + - ((payload[3] << 24) & 0xff000000); + var binary = (payload[0] & 0xff) + ((payload[1] << 8) & 0xff00) + ((payload[2] << 16) & 0xff0000) + ((payload[3] << 24) & 0xff000000); var second = binary & 0x1f; second *= 2; binary = binary >> 5; @@ -493,14 +450,6 @@ function parseDateByte(payload) { binary = binary >> 4; var year = binary & 0x7f; year += 2000; - date = new Date( - year, - month - 1, - day, - hour, - minute, - second, - 0 - ).toLocaleString(); + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); return date; -} \ No newline at end of file +} diff --git a/vendor/enginko/decoder-weather.js b/vendor/enginko/decoder-weather.js index 57be34842f..bca9269fa7 100644 --- a/vendor/enginko/decoder-weather.js +++ b/vendor/enginko/decoder-weather.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; function decodeUplink(payload) { payload = TTNfrom(payload); @@ -6,50 +6,50 @@ function decodeUplink(payload) { var content; switch (uplinkId.toUpperCase()) { - case "01": + case '01': content = parseTimeSync(payload.trim()); break; - case "04": + case '04': content = parseTER(payload.trim()); break; - case "09": + case '09': content = parseMetering(payload.trim()); break; - case "10": + case '10': content = parseDigitalData(payload.trim()); break; - case "12": + case '12': content = parseVOC(payload.trim(), true); //true is for new sensor break; - case "13": + case '13': content = parseCo2(payload.trim(), true); //true is for new sensor break; - case "0A": + case '0A': content = parseIO(payload.trim()); break; - case "0B": + case '0B': content = parseReportData(payload.trim()); break; - case "0C": + case '0C': content = parseVOC(payload.trim(), false); //false is for new sensor break; - case "0D": + case '0D': content = parseAnalog(payload.trim()); break; - case "0E": + case '0E': content = parseCo2(payload.trim(), false); //false is for new sensor break; @@ -65,17 +65,17 @@ function decodeUplink(payload) { function TTNfrom(TTNpayload) { var obj; - if (typeof TTNpayload === "string") { + if (typeof TTNpayload === 'string') { obj = JSON.parse(TTNpayload); } else { obj = JSON.parse(JSON.stringify(TTNpayload)); } var fPort = obj.fPort; - var payload = ""; + var payload = ''; for (var i = 0; i < obj.bytes.length; i++) { - payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, "0"); + payload += parseInt(obj.bytes[i], 10).toString(16).padStart(2, '0'); } return payload; @@ -90,13 +90,13 @@ function TTNto(content) { } return { - data: TTNcontent + data: TTNcontent, }; } else { return { data: content, warnings: [], - errors: ["Error on decoding payload"] + errors: ['Error on decoding payload'], }; } } @@ -104,18 +104,18 @@ function TTNto(content) { function parseTER(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "04") { + if (uplinkId.toUpperCase() === '04') { var m1 = parseTERMeasurement(payload.substring(2, 22)); var m2 = parseTERMeasurement(payload.substring(22, 42)); var m3 = parseTERMeasurement(payload.substring(42, 62)); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(62, 64), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(64) + variable: 'rfu', + value: payload.substring(64), }; return [].concat(m1, m2, m3, [battery, rfu]); } else { @@ -125,30 +125,23 @@ function parseTER(payload) { function parseTERMeasurement(payload) { var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; return [date, temperature, humidity, pressure]; } @@ -157,34 +150,34 @@ function parseVOC(payload, isNew) { var uplinkId = payload.substring(0, 2); if (!isNew) { - if (uplinkId.toUpperCase() === "0C") { + if (uplinkId.toUpperCase() === '0C') { var m1 = parseVOCMeasurement(payload.substring(2, 30), isNew); var m2 = parseVOCMeasurement(payload.substring(30, 58), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(58, 60), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(60) + variable: 'rfu', + value: payload.substring(60), }; return [].concat(m1, m2, [battery, rfu]); } else { return null; } } else { - if (uplinkId.toUpperCase() === "12") { + if (uplinkId.toUpperCase() === '12') { var m1 = parseVOCMeasurement(payload.substring(2, 32), isNew); var m2 = parseVOCMeasurement(payload.substring(32, 62), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(62, 64), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(64) + variable: 'rfu', + value: payload.substring(64), }; return [].concat(m1, m2, [battery, rfu]); } else { @@ -196,84 +189,65 @@ function parseVOC(payload, isNew) { function parseVOCMeasurement(payload, isNew) { if (!isNew) { var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", + variable: 'voc', value: Number(parseUnsignedShort(payload.substring(24, 28))).toFixed(), - unit: "IAQ/ppb" + unit: 'IAQ/ppb', }; return [date, temperature, humidity, pressure, lux, voc]; } else { var payloadToByteArray = hexStringToByteArray(payload); var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", - value: Number( - 0x00000000 | - (payloadToByteArray[12] & 0x000000ff) | - ((payloadToByteArray[13] << 8) & 0x0000ff00) | - ((payloadToByteArray[14] << 16) & 0x00ff0000) - ).toFixed(), - unit: "IAQ/ppb" + variable: 'voc', + value: Number(0x00000000 | (payloadToByteArray[12] & 0x000000ff) | ((payloadToByteArray[13] << 8) & 0x0000ff00) | ((payloadToByteArray[14] << 16) & 0x00ff0000)).toFixed(), + unit: 'IAQ/ppb', }; return [date, temperature, humidity, pressure, lux, voc]; } @@ -283,34 +257,34 @@ function parseCo2(payload, isNew) { var uplinkId = payload.substring(0, 2); if (!isNew) { - if (uplinkId.toUpperCase() === "0E") { + if (uplinkId.toUpperCase() === '0E') { var m1 = parseCo2Measurement(payload.substring(2, 34), isNew); var m2 = parseCo2Measurement(payload.substring(34, 66), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(66, 68), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(68) + variable: 'rfu', + value: payload.substring(68), }; return [].concat(m1, m2, [battery, rfu]); } else { return null; } } else { - if (uplinkId.toUpperCase() === "13") { + if (uplinkId.toUpperCase() === '13') { var m1 = parseCo2Measurement(payload.substring(2, 36), isNew); var m2 = parseCo2Measurement(payload.substring(36, 70), isNew); var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payload.substring(70, 72), 16)).toFixed(), - unit: "%" + unit: '%', }; var rfu = { - variable: "rfu", - value: payload.substring(72) + variable: 'rfu', + value: payload.substring(72), }; return [].concat(m1, m2, [battery, rfu]); } else { @@ -322,94 +296,75 @@ function parseCo2(payload, isNew) { function parseCo2Measurement(payload, isNew) { if (!isNew) { var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", + variable: 'voc', value: Number(parseUnsignedShort(payload.substring(24, 28))).toFixed(), - unit: "IAQ/ppb" + unit: 'IAQ/ppb', }; var co2 = { - variable: "co2", + variable: 'co2', value: Number(parseSignedShort(payload.substring(28, 32))).toFixed(), - unit: "ppm" + unit: 'ppm', }; return [date, temperature, humidity, pressure, lux, voc, co2]; } else { var payloadToByteArray = hexStringToByteArray(payload); var date = { - variable: "date", - value: parseDate(payload.substring(0, 8)) + variable: 'date', + value: parseDate(payload.substring(0, 8)), }; var temperature = { - variable: "temperature", - value: getTemperature( - parseInt(payload.substring(8, 10), 16), - parseInt(payload.substring(10, 12), 16) - ), - unit: "�C" + variable: 'temperature', + value: getTemperature(parseInt(payload.substring(8, 10), 16), parseInt(payload.substring(10, 12), 16)), + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(parseInt(payload.substring(12, 14), 16)), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - parseInt(payload.substring(14, 16), 16), - parseInt(payload.substring(16, 18), 16), - parseInt(payload.substring(18, 20), 16) - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(parseInt(payload.substring(14, 16), 16), parseInt(payload.substring(16, 18), 16), parseInt(payload.substring(18, 20), 16)), + unit: 'hPa', }; var lux = { - variable: "lux", + variable: 'lux', value: Number(parseUnsignedShort(payload.substring(20, 24))).toFixed(), - unit: "lx" + unit: 'lx', }; var voc = { - variable: "voc", - value: Number( - 0x00000000 | - (payloadToByteArray[12] & 0x000000ff) | - ((payloadToByteArray[13] << 8) & 0x0000ff00) | - ((payloadToByteArray[14] << 16) & 0x00ff0000) - ).toFixed(), - unit: "IAQ/ppb" + variable: 'voc', + value: Number(0x00000000 | (payloadToByteArray[12] & 0x000000ff) | ((payloadToByteArray[13] << 8) & 0x0000ff00) | ((payloadToByteArray[14] << 16) & 0x00ff0000)).toFixed(), + unit: 'IAQ/ppb', }; var co2 = { - variable: "co2", + variable: 'co2', value: Number(parseSignedShort(payload.substring(30, 34))).toFixed(), - unit: "ppm" + unit: 'ppm', }; return [date, temperature, humidity, pressure, lux, voc, co2]; } @@ -419,20 +374,20 @@ function parseReportData(payload) { var uplinkId = payload.substring(0, 2); var content; - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { switch (payload.substring(2, 3)) { - case "1": - case "4": + case '1': + case '4': content = parseModBus(payload); break; - case "2": + case '2': switch (payload.substring(4, 6)) { - case "00": + case '00': content = parseWeather(payload); break; - case "01": + case '01': content = parsePM(payload); break; @@ -443,7 +398,7 @@ function parseReportData(payload) { break; - case "3": + case '3': content = parseTERPM(payload); break; @@ -459,68 +414,65 @@ function parseReportData(payload) { } function parseModBus(payloads) { - var splitted = payloads.split("\n"); //payloads must be on diffrent lines or change the \n split character + var splitted = payloads.split('\n'); //payloads must be on diffrent lines or change the \n split character var m = []; - var dP = ""; + var dP = ''; for (var i = 0; i < splitted.length; i++) { var payload = splitted[i]; var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(2); - if (payload.substring(2, 3) === "1" || payload.substring(2, 3) === "4") { + if (payload.substring(2, 3) === '1' || payload.substring(2, 3) === '4') { var id = Number(payloadToByteArray[0]).toFixed(); var frameId = { - variable: "frameId", - value: id + variable: 'frameId', + value: id, }; if (payload.length === 12) { - var e = ""; + var e = ''; switch (payload.substring(10, 12).toUpperCase()) { - case "05": - e = "Configuration error"; + case '05': + e = 'Configuration error'; break; - case "07": - e = "Error reading internal configuration"; + case '07': + e = 'Error reading internal configuration'; break; - case "7F": - e = "Command not implemented"; + case '7F': + e = 'Command not implemented'; break; - case "CC": - e = "Communication error"; + case 'CC': + e = 'Communication error'; break; } var error = { - variable: "error", - value: e + variable: 'error', + value: e, }; m.push.apply(m, [frameId, error]); } else { - var d = id === "0" ? payload.substring(10) : payload.substring(6); + var d = id === '0' ? payload.substring(10) : payload.substring(6); var data = { - variable: "data", - value: d + variable: 'data', + value: d, }; dP += d; - if (id === "0") { + if (id === '0') { //length is declared only on first payload var length = { - variable: "length", - value: Number( - ((payloadToByteArray[2] << 8) & 0x0000ff00) | - (payloadToByteArray[1] & 0x000000ff) - ).toFixed() + variable: 'length', + value: Number(((payloadToByteArray[2] << 8) & 0x0000ff00) | (payloadToByteArray[1] & 0x000000ff)).toFixed(), }; m.push.apply(m, [frameId, length, data]); } else { @@ -532,8 +484,8 @@ function parseModBus(payloads) { } var dataPayload = { - variable: "dataPayload", - value: dP + variable: 'dataPayload', + value: dP, }; return [].concat(m, [dataPayload]); } @@ -541,38 +493,29 @@ function parseModBus(payloads) { function parsePM(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(3); - if (payload.substring(2, 3) === "2" && payload.substring(4, 6) === "01") { + if (payload.substring(2, 3) === '2' && payload.substring(4, 6) === '01') { var date = { - variable: "date", - value: parseDate(payload.substring(6, 14)) + variable: 'date', + value: parseDate(payload.substring(6, 14)), }; var pm1 = { - variable: "pm1", - value: Number( - (payloadToByteArray[4] & 0xff) + - ((payloadToByteArray[5] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm1', + value: Number((payloadToByteArray[4] & 0xff) + ((payloadToByteArray[5] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm25 = { - variable: "pm25", - value: Number( - (payloadToByteArray[6] & 0xff) + - ((payloadToByteArray[7] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm25', + value: Number((payloadToByteArray[6] & 0xff) + ((payloadToByteArray[7] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm10 = { - variable: "pm10", - value: Number( - (payloadToByteArray[8] & 0xff) + - ((payloadToByteArray[9] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm10', + value: Number((payloadToByteArray[8] & 0xff) + ((payloadToByteArray[9] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; return [date, pm1, pm25, pm10]; } else { @@ -586,77 +529,55 @@ function parsePM(payload) { function parseTERPM(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(3); - if (payload.substring(2, 3) === "3" && payload.substring(4, 6) === "00") { + if (payload.substring(2, 3) === '3' && payload.substring(4, 6) === '00') { var date = { - variable: "date", - value: parseDate(payload.substring(6, 14)) + variable: 'date', + value: parseDate(payload.substring(6, 14)), }; var temperature = { - variable: "temperature", + variable: 'temperature', value: getTemperature(payloadToByteArray[4], payloadToByteArray[5]), - unit: "�C" + unit: '�C', }; var humidity = { - variable: "humidity", + variable: 'humidity', value: getHumidity(payloadToByteArray[6]), - unit: "%" + unit: '%', }; var pressure = { - variable: "pressure", - value: getPressure( - payloadToByteArray[7], - payloadToByteArray[8], - payloadToByteArray[9] - ), - unit: "hPa" + variable: 'pressure', + value: getPressure(payloadToByteArray[7], payloadToByteArray[8], payloadToByteArray[9]), + unit: 'hPa', }; var pm1 = { - variable: "pm1", - value: Number( - (payloadToByteArray[10] & 0xff) + - ((payloadToByteArray[11] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm1', + value: Number((payloadToByteArray[10] & 0xff) + ((payloadToByteArray[11] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm25 = { - variable: "pm25", - value: Number( - (payloadToByteArray[12] & 0xff) + - ((payloadToByteArray[13] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm25', + value: Number((payloadToByteArray[12] & 0xff) + ((payloadToByteArray[13] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; var pm10 = { - variable: "pm10", - value: Number( - (payloadToByteArray[14] & 0xff) + - ((payloadToByteArray[15] << 8) & 0xff00) - ).toFixed(), - unit: "micro g/m3" + variable: 'pm10', + value: Number((payloadToByteArray[14] & 0xff) + ((payloadToByteArray[15] << 8) & 0xff00)).toFixed(), + unit: 'micro g/m3', }; if (payload.length <= 38) { return [date, temperature, humidity, pressure, pm1, pm25, pm10]; } else { var battery = { - variable: "battery", + variable: 'battery', value: Number(parseInt(payloadToByteArray[16])).toFixed(), - unit: "%" + unit: '%', }; - return [ - date, - temperature, - humidity, - pressure, - pm1, - pm25, - pm10, - battery - ]; + return [date, temperature, humidity, pressure, pm1, pm25, pm10, battery]; } } else { return null; @@ -669,94 +590,71 @@ function parseTERPM(payload) { function parseWeather(payload) { var uplinkId = payload.substring(0, 2); - if (uplinkId.toUpperCase() === "0B") { + if (uplinkId.toUpperCase() === '0B') { var payloadToByteArray = hexStringToByteArray(payload); payloadToByteArray = payloadToByteArray.slice(3); - if (payload.substring(2, 3) === "2" && payload.substring(4, 6) === "00") { + if (payload.substring(2, 3) === '2' && payload.substring(4, 6) === '00') { var pressure = { - variable: "pressure", - value: getAtmosphericPressure( - (((payloadToByteArray[3] << 8) & 0x0000ff00) | - (payloadToByteArray[2] & 0x000000ff)) / - 1000.0 - ), - unit: "hPa" + variable: 'pressure', + value: getAtmosphericPressure((((payloadToByteArray[3] << 8) & 0x0000ff00) | (payloadToByteArray[2] & 0x000000ff)) / 1000.0), + unit: 'hPa', }; var outsideTemperature = { - variable: "outsideTemperature", - value: getFahrenheitToCelsius( - (((payloadToByteArray[5] << 8) & 0x0000ff00) | - (payloadToByteArray[4] & 0x000000ff)) / - 10.0 - ), - unit: "�C" + variable: 'outsideTemperature', + value: getFahrenheitToCelsius((((payloadToByteArray[5] << 8) & 0x0000ff00) | (payloadToByteArray[4] & 0x000000ff)) / 10.0), + unit: '�C', }; var windSpeed = { - variable: "windSpeed", + variable: 'windSpeed', value: getWindSpeed(payloadToByteArray[6] & 0x00ff), - unit: "m/s" + unit: 'm/s', }; var tenMinutesAvgWindSpeed = { - variable: "tenMinutesAvgWindSpeed", + variable: 'tenMinutesAvgWindSpeed', value: getWindSpeed(payloadToByteArray[7] & 0x00ff), - unit: "m/s" + unit: 'm/s', }; var windDirection = { - variable: "windDirection", - value: Number( - ((payloadToByteArray[9] << 8) & 0x0000ff00) | - (payloadToByteArray[8] & 0x000000ff) - ).toFixed(2), - unit: "�" + variable: 'windDirection', + value: Number(((payloadToByteArray[9] << 8) & 0x0000ff00) | (payloadToByteArray[8] & 0x000000ff)).toFixed(2), + unit: '�', }; var outsideHumidity = { - variable: "outsideHumidity", + variable: 'outsideHumidity', value: Number(payloadToByteArray[10] & 0x00ff).toFixed(2), - unit: "%" + unit: '%', }; var rainRate = { - variable: "rainRate", - value: getRainRate( - ((payloadToByteArray[12] << 8) & 0x0000ff00) | - (payloadToByteArray[11] & 0x000000ff) - ), - unit: "mm/h" + variable: 'rainRate', + value: getRainRate(((payloadToByteArray[12] << 8) & 0x0000ff00) | (payloadToByteArray[11] & 0x000000ff)), + unit: 'mm/h', }; var uv = { - variable: "uv", - value: Number(payloadToByteArray[13] & 0x00ff).toFixed(2) + variable: 'uv', + value: Number(payloadToByteArray[13] & 0x00ff).toFixed(2), }; var solarRadiation = { - variable: "solarRadiation", - value: Number( - ((payloadToByteArray[15] << 8) & 0x0000ff00) | - (payloadToByteArray[14] & 0x000000ff) - ).toFixed(2), - unit: "W/m�" + variable: 'solarRadiation', + value: Number(((payloadToByteArray[15] << 8) & 0x0000ff00) | (payloadToByteArray[14] & 0x000000ff)).toFixed(2), + unit: 'W/m�', }; var dayRain = { - variable: "dayRain", - value: getRainRate( - ((payloadToByteArray[17] << 8) & 0x0000ff00) | - (payloadToByteArray[16] & 0x000000ff) - ) + variable: 'dayRain', + value: getRainRate(((payloadToByteArray[17] << 8) & 0x0000ff00) | (payloadToByteArray[16] & 0x000000ff)), }; var dayET = { - variable: "dayET", - value: getET( - ((payloadToByteArray[19] << 8) & 0x0000ff00) | - (payloadToByteArray[18] & 0x000000ff) - ), - unit: "mm" + variable: 'dayET', + value: getET(((payloadToByteArray[19] << 8) & 0x0000ff00) | (payloadToByteArray[18] & 0x000000ff)), + unit: 'mm', }; var soilMoistures = []; for (var i = 0; i < 4; i++) { var soilMoisture = { - variable: "soilMoisture", + variable: 'soilMoisture', value: Number(payloadToByteArray[20 + i]).toFixed(2), - unit: "centibar" + unit: 'centibar', }; soilMoistures.push(soilMoisture); } @@ -765,19 +663,19 @@ function parseWeather(payload) { for (var i = 0; i < 4; i++) { var leafWetness = { - variable: "leafWetness", - value: Number(payloadToByteArray[24 + i]) + variable: 'leafWetness', + value: Number(payloadToByteArray[24 + i]), }; leafWetnesses.push(leafWetness); } var forecastIcons = { - variable: "forecastIcons", - value: Number(payloadToByteArray[28]).toFixed() + variable: 'forecastIcons', + value: Number(payloadToByteArray[28]).toFixed(), }; var barTrend = { - variable: "barTrend", - value: Number(payloadToByteArray[29]).toFixed(2) + variable: 'barTrend', + value: Number(payloadToByteArray[29]).toFixed(2), }; return [ pressure, @@ -794,7 +692,7 @@ function parseWeather(payload) { soilMoistures, leafWetnesses, forecastIcons, - barTrend + barTrend, ]; } } else { @@ -831,22 +729,14 @@ function parseDate(payload) { var date = new Date(); var binary = Number(parseInt(reverseBytes(payload), 16)) .toString(2) - .padStart(32, "0"); + .padStart(32, '0'); var year = parseInt(binary.substring(0, 7), 2) + 2000; var month = parseInt(binary.substring(7, 11), 2); var day = parseInt(binary.substring(11, 16), 2); var hour = parseInt(binary.substring(16, 21), 2); var minute = parseInt(binary.substring(21, 27), 2); var second = parseInt(binary.substring(27, 32), 2) * 2; - date = new Date( - year, - month - 1, - day, - hour, - minute, - second, - 0 - ).toLocaleString(); + date = new Date(year, month - 1, day, hour, minute, second, 0).toLocaleString(); return date; } @@ -856,24 +746,14 @@ function getHumidity(lo) { } function getPressure(lo, mi, hi) { - var pressure = String( - (lo & 0xff) + ((mi << 8) & 0xff00) + ((hi << 16) & 0xff0000) - ).padStart(3); - pressure = - pressure.substring(0, pressure.length - 2) + - "." + - pressure.substring(pressure.length - 2); + var pressure = String((lo & 0xff) + ((mi << 8) & 0xff00) + ((hi << 16) & 0xff0000)).padStart(3); + pressure = pressure.substring(0, pressure.length - 2) + '.' + pressure.substring(pressure.length - 2); return Number(pressure).toFixed(2); } function getTemperature(lo, hi) { - var temperature = String( - (((lo & 0xff) + ((hi << 8) & 0xff00)) << 16) >> 16 - ).padStart(3); - temperature = - temperature.substring(0, temperature.length - 2) + - "." + - temperature.substring(temperature.length - 2); + var temperature = String((((lo & 0xff) + ((hi << 8) & 0xff00)) << 16) >> 16).padStart(3); + temperature = temperature.substring(0, temperature.length - 2) + '.' + temperature.substring(temperature.length - 2); return Number(temperature).toFixed(2); } @@ -913,7 +793,7 @@ function reverseBytes(bytes) { var reversed = bytes; if (bytes.length % 2 === 0) { - reversed = ""; + reversed = ''; for (var starting = 0; starting + 2 <= bytes.length; starting += 2) { reversed = bytes.substring(starting, starting + 2) + reversed; @@ -921,4 +801,4 @@ function reverseBytes(bytes) { } return reversed; -} \ No newline at end of file +} diff --git a/vendor/enginko/egk-level-codec.yaml b/vendor/enginko/egk-level-codec.yaml new file mode 100644 index 0000000000..9e5957afdd --- /dev/null +++ b/vendor/enginko/egk-level-codec.yaml @@ -0,0 +1,2 @@ +uplinkDecoder: + fileName: decoder-level.js diff --git a/vendor/enginko/egk-lw20l00.yaml b/vendor/enginko/egk-lw20l00.yaml new file mode 100644 index 0000000000..cda1b553ec --- /dev/null +++ b/vendor/enginko/egk-lw20l00.yaml @@ -0,0 +1,72 @@ +name: EGK-LW20L00 +description: The enginko EGK-LW20L00 is a LoRaWAN® is a battery powered sensor intended for level measurement up to 7 meters. + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '0.02.61' + numeric: 1 + + # LoRaWAN Device Profiles per region + # Supported regions are EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + # Unique identifier of the profile (lowercase, alphanumeric with dashes, max 36 characters) + id: eu868-profile-a + lorawanCertified: false + codec: egk-level-codec + +# Sensors that this device features (optional) +# Valid values are: accelerometer, altitude, auxiliary, barometer, battery, button, co2, distance, dust, gps, gyroscope, +# humidity, light, link, magnetometer, moisture, ph, pir, proximity, rssi, snr, sound, temperature, tvoc, velocity, +# vibration, water, wind direction and wind speed. +sensors: + - distance + - battery + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 65 + length: 59 + height: 54 + +# Weight in grams (optional) +weight: 95 + +# Battery information (optional) +battery: + replaceable: true + type: pack + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -30 + max: 70 + # Relative humidity (fraction of 1) + relativeHumidity: + min: 0 + max: 1 + +# IP rating (optional) +ipCode: IP67 + +# Key provisioning (optional) +# Valid values are: custom (user can configure keys), join server and manifest. +keyProvisioning: + - custom + - join server + +# Key security (optional) +# Valid values are: none, read protected and secure element. +keySecurity: read protected + +# Product and data sheet URLs (optional) +productURL: https://enginko.com/en/solutions/multi-application-level-sensor/ +dataSheetURL: https://enginko.com/wp-content/uploads/2021/11/ENGINKO_datasheet_EGK-LW20L00_ENG.pdf + +# Photos +photos: + main: egk-lw20l00.jpg diff --git a/vendor/enginko/egk-lw20w00.yaml b/vendor/enginko/egk-lw20w00.yaml new file mode 100644 index 0000000000..565de18bf9 --- /dev/null +++ b/vendor/enginko/egk-lw20w00.yaml @@ -0,0 +1,74 @@ +name: EGK-LW20W00 +description: The enginko EGK-LW20W00 is a LoRaWAN® is a battery powered sensor intended for waste level measurement up to 1.5 meters. + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '0.02.61' + numeric: 1 + + # LoRaWAN Device Profiles per region + # Supported regions are EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + # Unique identifier of the profile (lowercase, alphanumeric with dashes, max 36 characters) + id: eu868-profile-a + lorawanCertified: false + codec: egk-level-codec + +# Sensors that this device features (optional) +# Valid values are: accelerometer, altitude, auxiliary, barometer, battery, button, co2, distance, dust, gps, gyroscope, +# humidity, light, link, magnetometer, moisture, ph, pir, proximity, rssi, snr, sound, temperature, tvoc, velocity, +# vibration, water, wind direction and wind speed. +sensors: + - distance + - level + - temperature + - battery + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 65 + length: 59 + height: 39 + +# Weight in grams (optional) +weight: 90 + +# Battery information (optional) +battery: + replaceable: true + type: pack + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -30 + max: 70 + # Relative humidity (fraction of 1) + relativeHumidity: + min: 0 + max: 1 + +# IP rating (optional) +ipCode: IP67 + +# Key provisioning (optional) +# Valid values are: custom (user can configure keys), join server and manifest. +keyProvisioning: + - custom + - join server + +# Key security (optional) +# Valid values are: none, read protected and secure element. +keySecurity: read protected + +# Product and data sheet URLs (optional) +productURL: https://enginko.com/en/solutions/waste-level-sensor-for-bins-and-containers/ +dataSheetURL: https://enginko.com/wp-content/uploads/2020/09/ENGINKO_datasheet-layout_EGK-LW20W00_ENG.pdf + +# Photos +photos: + main: egk-lw20w00.jpg diff --git a/vendor/enginko/egk-lw22plg.jpg b/vendor/enginko/egk-lw22plg.jpg new file mode 100644 index 0000000000..4aa2e96f6f Binary files /dev/null and b/vendor/enginko/egk-lw22plg.jpg differ diff --git a/vendor/enginko/egk-lw22plg.yaml b/vendor/enginko/egk-lw22plg.yaml new file mode 100644 index 0000000000..ff86fc1f43 --- /dev/null +++ b/vendor/enginko/egk-lw22plg.yaml @@ -0,0 +1,75 @@ +name: EGK-LW22PLG +description: The enginko EGK-LW22PLG is a LoRaWAN® Energy Meter plug with On/Off capability that supports metering and switching of a 230Vac – 16 Amp Load (active, reactive, and apparent energy; Class 0.2). + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '0.02.61' + numeric: 1 + + # LoRaWAN Device Profiles per region + # Supported regions are EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + # Unique identifier of the profile (lowercase, alphanumeric with dashes, max 36 characters) + id: eu868-profile-c + lorawanCertified: false + codec: mcf-power-codec + +# Sensors that this device features (optional) +# Valid values are: accelerometer, altitude, auxiliary, barometer, battery, button, co2, distance, dust, gps, gyroscope, +# humidity, light, link, magnetometer, moisture, ph, pir, proximity, rssi, snr, sound, temperature, tvoc, velocity, +# vibration, water, wind direction and wind speed. +sensors: + - voltage + - current + - energy + - power + - time + - button + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 110 + length: 62 + height: 35 + +# Weight in grams (optional) +weight: 140 + +# Battery information (optional) +battery: + replaceable: false + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -10 + max: 60 + # Relative humidity (fraction of 1) + relativeHumidity: + min: 0 + max: 1 + +# IP rating (optional) +ipCode: IP20 + +# Key provisioning (optional) +# Valid values are: custom (user can configure keys), join server and manifest. +keyProvisioning: + - custom + - join server + +# Key security (optional) +# Valid values are: none, read protected and secure element. +keySecurity: read protected + +# Product and data sheet URLs (optional) +productURL: https://www.enginko.it/prodotto/mcf-lw12plg/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12PLG.pdf + +# Photos +photos: + main: egk-lw22plg.jpg diff --git a/vendor/enginko/index.yaml b/vendor/enginko/index.yaml index df9b60e970..2baff956a8 100644 --- a/vendor/enginko/index.yaml +++ b/vendor/enginko/index.yaml @@ -1,4 +1,4 @@ -# mcf88 +# enginko endDevices: - mcf-lw06davk diff --git a/vendor/enginko/mcf-lw06010.jpg b/vendor/enginko/mcf-lw06010.jpg index ebcad5cb02..4739ae2f94 100644 Binary files a/vendor/enginko/mcf-lw06010.jpg and b/vendor/enginko/mcf-lw06010.jpg differ diff --git a/vendor/enginko/mcf-lw06420.jpg b/vendor/enginko/mcf-lw06420.jpg index ebcad5cb02..4739ae2f94 100644 Binary files a/vendor/enginko/mcf-lw06420.jpg and b/vendor/enginko/mcf-lw06420.jpg differ diff --git a/vendor/enginko/mcf-lw06424.jpg b/vendor/enginko/mcf-lw06424.jpg index ebcad5cb02..4739ae2f94 100644 Binary files a/vendor/enginko/mcf-lw06424.jpg and b/vendor/enginko/mcf-lw06424.jpg differ diff --git a/vendor/enginko/mcf-lw06485-codec.yaml b/vendor/enginko/mcf-lw06485-codec.yaml new file mode 100644 index 0000000000..94c710e5a4 --- /dev/null +++ b/vendor/enginko/mcf-lw06485-codec.yaml @@ -0,0 +1,2 @@ +uplinkDecoder: + fileName: decoder-weather.js diff --git a/vendor/enginko/mcf-lw06485.jpg b/vendor/enginko/mcf-lw06485.jpg new file mode 100644 index 0000000000..bcf1e03a4c Binary files /dev/null and b/vendor/enginko/mcf-lw06485.jpg differ diff --git a/vendor/enginko/mcf-lw06485.yaml b/vendor/enginko/mcf-lw06485.yaml new file mode 100644 index 0000000000..9f7f7e1808 --- /dev/null +++ b/vendor/enginko/mcf-lw06485.yaml @@ -0,0 +1,109 @@ +name: MCF-LW06485 +description: This device can be interfaced to any Modbus RTU RDS485 device to read and write any register of the connected device through the LoRaWAN® platform. +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '0.02.18' + numeric: 1 + + # LoRaWAN Device Profiles per region + # Supported regions are EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + # Unique identifier of the profile (lowercase, alphanumeric with dashes, max 36 characters) + id: eu868-profile-a + lorawanCertified: true + codec: mcf-lw06485-codec + US902-928: + id: us915-profile-a + lorawanCertified: false + codec: mcf-lw06485-codec + AU915-928: + id: au915-profile-a + lorawanCertified: false + codec: mcf-lw06485-codec + AS923: + id: as923-profile-a + lorawanCertified: false + codec: mcf-lw06485-codec + +# Sensors that this device features (optional) +# Valid values are: accelerometer, altitude, auxiliary, barometer, battery, button, co2, distance, dust, gps, gyroscope, +# humidity, light, link, magnetometer, moisture, ph, pir, proximity, rssi, snr, sound, temperature, tvoc, velocity, +# vibration, water, wind direction and wind speed. +sensors: + - auxiliary + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 81 + length: 60 + height: 50 + +# Weight in grams (optional) +weight: 250 + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -40 + max: 65 + # Relative humidity (fraction of 1) + relativeHumidity: + min: 0 + max: 1 + +# IP rating (optional) +ipCode: IP30 + +# Key provisioning (optional) +# Valid values are: custom (user can configure keys), join server and manifest. +keyProvisioning: + - custom + - join server + +# Key security (optional) +# Valid values are: none, read protected and secure element. +keySecurity: read protected + +# Product and data sheet URLs (optional) +productURL: https://enginko.com/en/solutions/modbus-to-lorawan-interface-mcf-lw06485/ +dataSheetURL: https://enginko.com/wp-content/uploads/2020/09/MCF-LW06485.pdf + +# Photos +photos: + main: mcf-lw06485.jpg + +# Regulatory compliances (optional) +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.2.3 + - body: ETSI + norm: EN + standard: 300 220-1 + version: 3.1.1 + - body: ETSI + norm: EN + standard: 300 220-2 + version: 3.2.1 + - body: FCC + norm: FCC + standard: Part 15 107 & 109 + version: 47:2014 + - body: FCC + norm: FCC + standard: Part 15 203, 209 & 247 + version: 47:2019 diff --git a/vendor/enginko/mcf-lw06davk.yaml b/vendor/enginko/mcf-lw06davk.yaml index 5c0888e3bc..f6a08a50cd 100644 --- a/vendor/enginko/mcf-lw06davk.yaml +++ b/vendor/enginko/mcf-lw06davk.yaml @@ -1,5 +1,5 @@ name: MCF-LW06DAVK -description: The mcf88 MCF-LW06DAVK is equipped with a wide range of sensors such as temperature, humidity, barometric pressure, rainfall, wind speed and direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, waste station control, etc. +description: The enginko MCF-LW06DAVK is equipped with a wide range of sensors such as temperature, humidity, barometric pressure, rainfall, wind speed and direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, waste station control, etc. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -39,6 +39,7 @@ sensors: - wind speed - wind direction - rainfall + - precipitation - solar radiation - uv @@ -77,8 +78,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw06davk/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LWWS06DAVK_DAVKP.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw06davk/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LWWS06DAVK_DAVKP.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw06davpk.yaml b/vendor/enginko/mcf-lw06davpk.yaml index f9d9d6b032..3181a5fb00 100644 --- a/vendor/enginko/mcf-lw06davpk.yaml +++ b/vendor/enginko/mcf-lw06davpk.yaml @@ -1,5 +1,5 @@ name: MCF-LW06DAVPK -description: The mcf88 MCF-LW06DAVPK integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. +description: The enginko MCF-LW06DAVPK integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -39,9 +39,13 @@ sensors: - wind speed - wind direction - rainfall + - precipitation - solar radiation - uv - dust + - particulate matter + - pm2.5 + - pm10 # Dimensions in mm (optional) # Use width, height, length and/or diameter @@ -78,8 +82,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw06davk/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LWWS06DAVK_DAVKP.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw06davk/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LWWS06DAVK_DAVKP.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw06kio.jpg b/vendor/enginko/mcf-lw06kio.jpg index 85690fbf38..fd68305e44 100644 Binary files a/vendor/enginko/mcf-lw06kio.jpg and b/vendor/enginko/mcf-lw06kio.jpg differ diff --git a/vendor/enginko/mcf-lw12co2.yaml b/vendor/enginko/mcf-lw12co2.yaml index fd2b483527..1e3838bc69 100644 --- a/vendor/enginko/mcf-lw12co2.yaml +++ b/vendor/enginko/mcf-lw12co2.yaml @@ -1,5 +1,5 @@ name: MCF-LW12CO2 -description: The mcf88 MCF-LW12CO2 LoRaWAN® indoor environmental sensor equipped with temperature, humidity, pressure, light intensity, air quality (expressed as IAQ or bVOC value), and CO2 sensors and sends collected data over the LoRaWAN® network. Ideally suited for a wide range of applications such as building automation, condition monitoring, predictive maintenance, security, healthcare, and many more use cases. +description: The enginko MCF-LW12CO2 LoRaWAN® indoor environmental sensor equipped with temperature, humidity, pressure, light intensity, air quality (expressed as IAQ or bVOC value), and CO2 sensors and sends collected data over the LoRaWAN® network. Ideally suited for a wide range of applications such as building automation, condition monitoring, predictive maintenance, security, healthcare, and many more use cases. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -80,8 +80,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw12co2/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW12CO2.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw12co2/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12CO2.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw12co2e.jpg b/vendor/enginko/mcf-lw12co2e.jpg new file mode 100644 index 0000000000..ec5f370ccc Binary files /dev/null and b/vendor/enginko/mcf-lw12co2e.jpg differ diff --git a/vendor/enginko/mcf-lw12co2e.yaml b/vendor/enginko/mcf-lw12co2e.yaml index b375d691d4..f8a9423f04 100644 --- a/vendor/enginko/mcf-lw12co2e.yaml +++ b/vendor/enginko/mcf-lw12co2e.yaml @@ -38,6 +38,7 @@ sensors: - barometer - light - bvoc + - iaq - co2 # Dimensions in mm (optional) @@ -81,10 +82,11 @@ keySecurity: read protected # Product and data sheet URLs (optional) productURL: http://www.enginko.com/support/doku.php?id=manual_mcf-lw12co2e +dataSheetURL: https://enginko.com/wp-content/uploads/2020/09/ENGINKO_datasheet-layout_MCF-LW12CO2E_ENG.pdf # Photos photos: - main: mcf-lw12co2e.png + main: mcf-lw12co2e.jpg # Regulatory compliances (optional) compliances: diff --git a/vendor/enginko/mcf-lw12met.jpg b/vendor/enginko/mcf-lw12met.jpg index 211acb4cad..97d2a3d4dd 100644 Binary files a/vendor/enginko/mcf-lw12met.jpg and b/vendor/enginko/mcf-lw12met.jpg differ diff --git a/vendor/enginko/mcf-lw12met.yaml b/vendor/enginko/mcf-lw12met.yaml index 00eb8a1e5c..b5e7f924e5 100644 --- a/vendor/enginko/mcf-lw12met.yaml +++ b/vendor/enginko/mcf-lw12met.yaml @@ -1,5 +1,5 @@ name: MCF-LW12MET -description: The mcf88 MCF-LW12MET is a LoRaWAN® Mono-Phase Energy Meter with I/O that can be used for monitoring and checking the power of electronic devices, and can remotely switch devices on/off and read the state of digital input. +description: The enginko MCF-LW12MET is a LoRaWAN® Mono-Phase Energy Meter with I/O that can be used for monitoring and checking the power of electronic devices, and can remotely switch devices on/off and read the state of digital input. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -75,8 +75,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw12met/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW12MET.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw12met/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12MET.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw12plg.yaml b/vendor/enginko/mcf-lw12plg.yaml index 733ddbc4b4..d08ef915d5 100644 --- a/vendor/enginko/mcf-lw12plg.yaml +++ b/vendor/enginko/mcf-lw12plg.yaml @@ -1,5 +1,5 @@ name: MCF-LW12PLG -description: The mcf88 MCF-LW12PLG is a LoRaWAN® Energy Meter plug with On/Off capability that supports metering and switching of a 230Vac – 16 Amp Load (active, reactive, and apparent energy; Class 0.2). +description: The enginko MCF-LW12PLG is a LoRaWAN® Energy Meter plug with On/Off capability that supports metering and switching of a 230Vac – 16 Amp Load (active, reactive, and apparent energy; Class 0.2). # Firmware versions (at least one is mandatory) firmwareVersions: @@ -78,8 +78,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw12plg/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW12PLG.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw12plg/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12PLG.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw12ter.yaml b/vendor/enginko/mcf-lw12ter.yaml index 33385fdae2..61901f7c3b 100644 --- a/vendor/enginko/mcf-lw12ter.yaml +++ b/vendor/enginko/mcf-lw12ter.yaml @@ -36,6 +36,7 @@ sensors: - temperature - humidity - barometer + - battery # Dimensions in mm (optional) # Use width, height, length and/or diameter @@ -77,8 +78,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw12ter/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW12TER.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw12ter/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12TER.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw12terpm.yaml b/vendor/enginko/mcf-lw12terpm.yaml index 0a4b575a48..461db5c4a3 100644 --- a/vendor/enginko/mcf-lw12terpm.yaml +++ b/vendor/enginko/mcf-lw12terpm.yaml @@ -1,5 +1,5 @@ name: MCF-LW12TERPM -description: The mcf88 MCF-LW12TERPM is an outdoor PM and environmental sensor that consists of temperature, humidity, pressure, and PM (PM1, PM2.5, PM10) sensors. It sends collected data over the LoRaWAN® network. Ideally suited for a wide range of applications such as weather stations, urban monitoring, air quality, industrial, environmental, or farming projects. +description: The enginko MCF-LW12TERPM is an outdoor PM and environmental sensor that consists of temperature, humidity, pressure, and PM (PM1, PM2.5, PM10) sensors. It sends collected data over the LoRaWAN® network. Ideally suited for a wide range of applications such as weather stations, urban monitoring, air quality, industrial, environmental, or farming projects. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -37,6 +37,10 @@ sensors: - humidity - barometer - dust + - particulate matter + - pm2.5 + - pm10 + - battery # Dimensions in mm (optional) # Use width, height, length and/or diameter @@ -78,8 +82,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw12terpm/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW12TERPM.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw12terpm/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12TERPM.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw12terwp.yaml b/vendor/enginko/mcf-lw12terwp.yaml index 9accb557b8..2af1c0ccbf 100644 --- a/vendor/enginko/mcf-lw12terwp.yaml +++ b/vendor/enginko/mcf-lw12terwp.yaml @@ -36,6 +36,7 @@ sensors: - temperature - humidity - barometer + - battery # Dimensions in mm (optional) # Use width, height, length and/or diameter @@ -77,8 +78,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw12terwp/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW12TERWP.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw12terwp/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12TERWP.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw12voc.yaml b/vendor/enginko/mcf-lw12voc.yaml index 6827f90342..9e2a0d5e97 100644 --- a/vendor/enginko/mcf-lw12voc.yaml +++ b/vendor/enginko/mcf-lw12voc.yaml @@ -38,6 +38,8 @@ sensors: - barometer - light - bvoc + - iaq + - battery # Dimensions in mm (optional) # Use width, height, length and/or diameter @@ -79,8 +81,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw12voc/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW12VOC.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw12voc/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW12VOC.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw13io.yaml b/vendor/enginko/mcf-lw13io.yaml index 63928c3779..6cd8668ba5 100644 --- a/vendor/enginko/mcf-lw13io.yaml +++ b/vendor/enginko/mcf-lw13io.yaml @@ -1,5 +1,5 @@ name: MCF-LW13IO -description: The mcf88 MCF-LW13IO is a wireless actuator that consists of an Opto-isolated input and a relay output. The device transmits the status of its input and controls the output through the LoRaWAN® network. Can be used for industrial process control and home automation, water treatment, agriculture irrigation, and similar applications. +description: The enginko MCF-LW13IO is a wireless actuator that consists of an Opto-isolated input and a relay output. The device transmits the status of its input and controls the output through the LoRaWAN® network. Can be used for industrial process control and home automation, water treatment, agriculture irrigation, and similar applications. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -70,8 +70,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw13io/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW13IO.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw13io/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW13IO.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lw13mio.yaml b/vendor/enginko/mcf-lw13mio.yaml index 63bf1a7a7b..f6567d4a93 100644 --- a/vendor/enginko/mcf-lw13mio.yaml +++ b/vendor/enginko/mcf-lw13mio.yaml @@ -1,5 +1,5 @@ name: MCF-LW13MIO -description: The mcf88 MCF-LW13MIO is a LoRaWAN® multi I/O module that transmits the state of its 16 inputs and controls 8 outputs through the LoRaWAN® network. All these inputs and outputs are galvanically isolated. It can be used for industrial process control, home automation, water treatment, agriculture irrigation, and similar applications. +description: The enginko MCF-LW13MIO is a LoRaWAN® multi I/O module that transmits the state of its 16 inputs and controls 8 outputs through the LoRaWAN® network. All these inputs and outputs are galvanically isolated. It can be used for industrial process control, home automation, water treatment, agriculture irrigation, and similar applications. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -69,8 +69,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lw13mio/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LW13MIO.pdf +productURL: https://www.enginko.it/prodotto/mcf-lw13mio/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LW13MIO.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lwws00.yaml b/vendor/enginko/mcf-lwws00.yaml index 88d7f3ca33..8be63a156f 100644 --- a/vendor/enginko/mcf-lwws00.yaml +++ b/vendor/enginko/mcf-lwws00.yaml @@ -1,5 +1,5 @@ name: MCF-LWWS00 -description: The mcf88 MCF-LWWS00 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. +description: The enginko MCF-LWWS00 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -39,6 +39,7 @@ sensors: - wind speed - wind direction - rainfall + - precipitation - solar radiation - uv @@ -75,8 +76,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lwws00/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf +productURL: https://www.enginko.it/prodotto/mcf-lwws00/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lwws01.yaml b/vendor/enginko/mcf-lwws01.yaml index 8ad4070c26..accb7a64f0 100644 --- a/vendor/enginko/mcf-lwws01.yaml +++ b/vendor/enginko/mcf-lwws01.yaml @@ -1,5 +1,5 @@ name: MCF-LWWS01 -description: The mcf88 MCF-LWWS01 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. +description: The enginko MCF-LWWS01 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -39,9 +39,13 @@ sensors: - wind speed - wind direction - rainfall + - precipitation - solar radiation - uv - dust + - particulate matter + - pm2.5 + - pm10 # Weight in grams (optional) weight: 20000 @@ -76,8 +80,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lwws00/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf +productURL: https://www.enginko.it/prodotto/mcf-lwws00/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lwws02.yaml b/vendor/enginko/mcf-lwws02.yaml index 0e16bc4190..b9bec1f36d 100644 --- a/vendor/enginko/mcf-lwws02.yaml +++ b/vendor/enginko/mcf-lwws02.yaml @@ -1,5 +1,5 @@ name: MCF-LWWS02 -description: The mcf88 MCF-LWWS02 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. +description: The enginko MCF-LWWS02 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -39,6 +39,7 @@ sensors: - wind speed - wind direction - rainfall + - precipitation - uv # Weight in grams (optional) @@ -74,8 +75,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lwws00/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf +productURL: https://www.enginko.it/prodotto/mcf-lwws00/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf # Photos photos: diff --git a/vendor/enginko/mcf-lwws03.yaml b/vendor/enginko/mcf-lwws03.yaml index 6981408c10..a480a571ab 100644 --- a/vendor/enginko/mcf-lwws03.yaml +++ b/vendor/enginko/mcf-lwws03.yaml @@ -1,5 +1,5 @@ name: MCF-LWWS03 -description: The mcf88 MCF-LWWS03 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. +description: The enginko MCF-LWWS03 integrates a LoRaWAN® communication system in a Davis Instruments Vantage Pro2 Weather Station. The station is equipped with a wide range of sensors such as temperature, humidity, pressure, rainfall, dew point, wind speed, wind direction, solar radiation, PM1, PM2.5, and PM10. Suitable for smart agriculture, industry, smart city, and waste station control applications. # Firmware versions (at least one is mandatory) firmwareVersions: @@ -39,8 +39,12 @@ sensors: - wind speed - wind direction - rainfall + - precipitation - uv - dust + - particulate matter + - pm2.5 + - pm10 # Dimensions in mm (optional) # Use width, height, length and/or diameter @@ -82,8 +86,8 @@ keyProvisioning: keySecurity: read protected # Product and data sheet URLs (optional) -productURL: https://www.mcf88.it/prodotto/mcf-lwws00/ -dataSheetURL: https://www.mcf88.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf +productURL: https://www.enginko.it/prodotto/mcf-lwws00/ +dataSheetURL: https://www.enginko.it/wp-content/uploads/2020/07/MCF-LWWS00-01.pdf # Photos photos: diff --git a/vendor/index.yaml b/vendor/index.yaml index cf815d1b75..e17742490a 100644 --- a/vendor/index.yaml +++ b/vendor/index.yaml @@ -434,6 +434,12 @@ vendors: ouis: - 0002CC + - id: mcf88 + name: mcf88 SRL + vendorID: 259 + website: https://www.enginko.com + logo: mcf88_logo.svg + - id: enginko name: enginko SRL vendorID: 259