mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-15 02:54:26 +00:00
Those values are already collected from the sensor, so why not send them all in a single TTN message.
1322 lines
37 KiB
JavaScript
1322 lines
37 KiB
JavaScript
// Decoder for device payload encoder "PACKED"
|
|
// copy & paste to TTN Console V3 -> Applications -> Payload formatters -> Uplink -> Javascript
|
|
function decodeUplink(input) {
|
|
var data = {};
|
|
|
|
var decoded = false;
|
|
|
|
if (input.bytes.length === 0) {
|
|
// Do nothing
|
|
} else {
|
|
if (input.fPort === 1) {
|
|
switch (input.bytes[0]) {
|
|
case 26:
|
|
// SysInfo
|
|
data = decode_plugin(input.fPort, input.bytes,
|
|
[header, uint24, uint24, int8, vcc, pct_8, uint8, uint8, uint8, uint8, uint24, uint16],
|
|
['header', 'uptime', 'freeheap', 'rssi', 'vcc', 'load', 'ip1', 'ip2', 'ip3', 'ip4', 'web', 'freestack']);
|
|
decoded = true;
|
|
break;
|
|
|
|
case 82:
|
|
// GPS
|
|
if (input.bytes.length === 18) {
|
|
data = decode_plugin(input.fPort, input.bytes, [header, latLng, latLng, altitude, uint16_1e2, hdop, uint8, uint8],
|
|
['header', 'latitude', 'longitude', 'altitude', 'speed', 'hdop', 'max_snr', 'sat_tracked']);
|
|
decoded = true;
|
|
} else if (input.bytes.length === 21) {
|
|
data = decode_plugin(input.fPort, input.bytes, [header, latLng, latLng, altitude, uint16_1e2, hdop, uint8, uint8, uint24_1e2],
|
|
['header', 'latitude', 'longitude', 'altitude', 'speed', 'hdop', 'max_snr', 'sat_tracked', 'distance_total_km']);
|
|
decoded = true;
|
|
} else {
|
|
data = decode_plugin(input.fPort, input.bytes, [header, latLng, latLng, altitude, uint16_1e2, hdop, uint8, uint8, uint24_1e2, uint24_1e1],
|
|
['header', 'latitude', 'longitude', 'altitude', 'speed', 'hdop', 'max_snr', 'sat_tracked', 'distance_total_km', 'distance_ref']);
|
|
decoded = true;
|
|
}
|
|
break;
|
|
|
|
case 85:
|
|
// AcuDC243
|
|
// FIXME TD-er: Same code as in P108, Make new type for this with 4 selectable variables
|
|
data = decode_plugin(input.fPort, input.bytes, [header, uint8, int32_1e4, uint8, int32_1e4, uint8, int32_1e4, uint8, int32_1e4],
|
|
['header', 'unit1', 'val_1', 'unit2', 'val_2', 'unit3', 'val_3', 'unit4', 'val_4']);
|
|
decoded = true;
|
|
break;
|
|
|
|
case 102:
|
|
// PZEM004T v30
|
|
data = decode(bytes, [header, int16_1e1, int32_1e3, int32_1e1, int32_1e1, uint16_1e2, uint8_1e1],
|
|
['header', 'voltage', 'current', 'power', 'energy', 'powerfactor', 'frequency']);
|
|
data.frequency += 40;
|
|
decoded = true;
|
|
break;
|
|
|
|
case 108:
|
|
// DDS238-x ZN
|
|
// FIXME TD-er: Same code as in P085, Make new type for this with 4 selectable variables
|
|
data = decode_plugin(input.fPort, input.bytes, [header, uint8, int32_1e4, uint8, int32_1e4, uint8, int32_1e4, uint8, int32_1e4],
|
|
['header', 'unit1', 'val_1', 'unit2', 'val_2', 'unit3', 'val_3', 'unit4', 'val_4']);
|
|
decoded = true;
|
|
break;
|
|
|
|
}
|
|
|
|
if (!decoded) {
|
|
if (input.bytes.length === 9) {
|
|
data = decode_plugin(input.fPort, input.bytes, [header, int32_1e4], ['header', 'val_1']);
|
|
decoded = true;
|
|
}
|
|
// Dual value
|
|
if (input.bytes.length === 13) {
|
|
data = decode_plugin(input.fPort, input.bytes, [header, int32_1e4, int32_1e4], ['header', 'val_1', 'val_2']);
|
|
decoded = true;
|
|
}
|
|
// Triple value
|
|
if (input.bytes.length === 17) {
|
|
data = decode_plugin(input.fPort, input.bytes, [header, int32_1e4, int32_1e4, int32_1e4], ['header', 'val_1', 'val_2', 'val_3']);
|
|
decoded = true;
|
|
}
|
|
// Quad value
|
|
if (input.bytes.length === 21) {
|
|
data = decode_plugin(input.fPort, input.bytes, [header, int32_1e4, int32_1e4, int32_1e4, int32_1e4], ['header', 'val_1', 'val_2', 'val_3', 'val_4']);
|
|
decoded = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
data.bytes = input.bytes;
|
|
data.port = input.fPort;
|
|
|
|
return {
|
|
data: data,
|
|
warnings: [],
|
|
errors: []
|
|
};
|
|
}
|
|
|
|
|
|
// ----- contents of /src/decoder.js --------------------------------------------
|
|
// https://github.com/thesolarnomad/lora-serialization/blob/master/src/decoder.js
|
|
|
|
var bytesToInt = function(bytes) {
|
|
var i = 0;
|
|
for (var x = 0; x < bytes.length; x++) {
|
|
i |= (bytes[x] << (x * 8));
|
|
}
|
|
return i;
|
|
};
|
|
|
|
var version = function(bytes) {
|
|
if (bytes.length !== version.BYTES) {
|
|
throw new Error('version must have exactly 10 bytes');
|
|
}
|
|
return String.fromCharCode.apply(null, bytes).split('\u0000')[0];
|
|
};
|
|
version.BYTES = 10;
|
|
|
|
var uint8 = function(bytes) {
|
|
if (bytes.length !== uint8.BYTES) {
|
|
throw new Error('uint8 must have exactly 1 byte');
|
|
}
|
|
return bytesToInt(bytes);
|
|
};
|
|
uint8.BYTES = 1;
|
|
|
|
var uint16 = function(bytes) {
|
|
if (bytes.length !== uint16.BYTES) {
|
|
throw new Error('uint16 must have exactly 2 bytes');
|
|
}
|
|
return bytesToInt(bytes);
|
|
};
|
|
uint16.BYTES = 2;
|
|
|
|
var uint24 = function(bytes) {
|
|
if (bytes.length !== uint24.BYTES) {
|
|
throw new Error('uint24 must have exactly 3 bytes');
|
|
}
|
|
return bytesToInt(bytes);
|
|
};
|
|
uint24.BYTES = 3;
|
|
|
|
var uint32 = function(bytes) {
|
|
if (bytes.length !== uint32.BYTES) {
|
|
throw new Error('uint32 must have exactly 4 bytes');
|
|
}
|
|
return bytesToInt(bytes);
|
|
};
|
|
uint32.BYTES = 4;
|
|
|
|
var uint64 = function(bytes) {
|
|
if (bytes.length !== uint64.BYTES) {
|
|
throw new Error('uint64 must have exactly 8 bytes');
|
|
}
|
|
return bytesToInt(bytes);
|
|
};
|
|
uint64.BYTES = 8;
|
|
|
|
var int8 = function(bytes) {
|
|
if (bytes.length !== int8.BYTES) {
|
|
throw new Error('int8 must have exactly 1 byte');
|
|
}
|
|
var value = +(bytesToInt(bytes));
|
|
if (value > 127) {
|
|
value -= 256;
|
|
}
|
|
return value;
|
|
};
|
|
int8.BYTES = 1;
|
|
|
|
var int16 = function(bytes) {
|
|
if (bytes.length !== int16.BYTES) {
|
|
throw new Error('int16 must have exactly 2 bytes');
|
|
}
|
|
var value = +(bytesToInt(bytes));
|
|
if (value > 32767) {
|
|
value -= 65536;
|
|
}
|
|
return value;
|
|
};
|
|
int16.BYTES = 2;
|
|
|
|
|
|
var int24 = function(bytes) {
|
|
if (bytes.length !== int24.BYTES) {
|
|
throw new Error('int24 must have exactly 3 bytes');
|
|
}
|
|
var value = +(bytesToInt(bytes));
|
|
if (value > 8388608) {
|
|
value -= 16777216;
|
|
}
|
|
return value;
|
|
};
|
|
int24.BYTES = 3;
|
|
|
|
var int32 = function(bytes) {
|
|
if (bytes.length !== int32.BYTES) {
|
|
throw new Error('int32 must have exactly 4 bytes');
|
|
}
|
|
var value = +(bytesToInt(bytes));
|
|
if (value > 2147483647) {
|
|
value -= 4294967296;
|
|
}
|
|
return value;
|
|
};
|
|
int32.BYTES = 4;
|
|
|
|
// Basic types with a factor in them.
|
|
var uint8_1e3 = function(bytes) {
|
|
return +(uint8(bytes) / 1e3).toFixed(3);
|
|
};
|
|
uint8_1e3.BYTES = uint8.BYTES;
|
|
var uint8_1e2 = function(bytes) {
|
|
return +(uint8(bytes) / 1e2).toFixed(2);
|
|
};
|
|
uint8_1e2.BYTES = uint8.BYTES;
|
|
var uint8_1e1 = function(bytes) {
|
|
return +(uint8(bytes) / 1e1).toFixed(1);
|
|
};
|
|
uint8_1e1.BYTES = uint8.BYTES;
|
|
|
|
var uint16_1e5 = function(bytes) {
|
|
return +(uint16(bytes) / 1e5).toFixed(5);
|
|
};
|
|
uint16_1e5.BYTES = uint16.BYTES;
|
|
var uint16_1e4 = function(bytes) {
|
|
return +(uint16(bytes) / 1e4).toFixed(4);
|
|
};
|
|
uint16_1e4.BYTES = uint16.BYTES;
|
|
var uint16_1e3 = function(bytes) {
|
|
return +(uint16(bytes) / 1e3).toFixed(3);
|
|
};
|
|
uint16_1e3.BYTES = uint16.BYTES;
|
|
var uint16_1e2 = function(bytes) {
|
|
return +(uint16(bytes) / 1e2).toFixed(2);
|
|
};
|
|
uint16_1e2.BYTES = uint16.BYTES;
|
|
var uint16_1e1 = function(bytes) {
|
|
return +(uint16(bytes) / 1e1).toFixed(1);
|
|
};
|
|
uint16_1e1.BYTES = uint16.BYTES;
|
|
|
|
var uint24_1e6 = function(bytes) {
|
|
return +(uint24(bytes) / 1e6).toFixed(6);
|
|
};
|
|
uint24_1e6.BYTES = uint24.BYTES;
|
|
var uint24_1e5 = function(bytes) {
|
|
return +(uint24(bytes) / 1e5).toFixed(5);
|
|
};
|
|
uint24_1e5.BYTES = uint24.BYTES;
|
|
var uint24_1e4 = function(bytes) {
|
|
return +(uint24(bytes) / 1e4).toFixed(4);
|
|
};
|
|
uint24_1e4.BYTES = uint24.BYTES;
|
|
var uint24_1e3 = function(bytes) {
|
|
return +(uint24(bytes) / 1e3).toFixed(3);
|
|
};
|
|
uint24_1e3.BYTES = uint24.BYTES;
|
|
var uint24_1e2 = function(bytes) {
|
|
return +(uint24(bytes) / 1e2).toFixed(2);
|
|
};
|
|
uint24_1e2.BYTES = uint24.BYTES;
|
|
var uint24_1e1 = function(bytes) {
|
|
return +(uint24(bytes) / 1e1).toFixed(1);
|
|
};
|
|
uint24_1e1.BYTES = uint24.BYTES;
|
|
|
|
var uint32_1e6 = function(bytes) {
|
|
return +(uint32(bytes) / 1e6).toFixed(6);
|
|
};
|
|
uint32_1e6.BYTES = uint32.BYTES;
|
|
var uint32_1e5 = function(bytes) {
|
|
return +(uint32(bytes) / 1e5).toFixed(5);
|
|
};
|
|
uint32_1e5.BYTES = uint32.BYTES;
|
|
var uint32_1e4 = function(bytes) {
|
|
return +(uint32(bytes) / 1e4).toFixed(4);
|
|
};
|
|
uint32_1e4.BYTES = uint32.BYTES;
|
|
var uint32_1e3 = function(bytes) {
|
|
return +(uint32(bytes) / 1e3).toFixed(3);
|
|
};
|
|
uint32_1e3.BYTES = uint32.BYTES;
|
|
var uint32_1e2 = function(bytes) {
|
|
return +(uint32(bytes) / 1e2).toFixed(2);
|
|
};
|
|
uint32_1e2.BYTES = uint32.BYTES;
|
|
var uint32_1e1 = function(bytes) {
|
|
return +(uint32(bytes) / 1e1).toFixed(1);
|
|
};
|
|
uint32_1e1.BYTES = uint32.BYTES;
|
|
|
|
var int8_1e3 = function(bytes) {
|
|
return +(int8(bytes) / 1e3).toFixed(3);
|
|
};
|
|
int8_1e3.BYTES = int8.BYTES;
|
|
var int8_1e2 = function(bytes) {
|
|
return +(int8(bytes) / 1e2).toFixed(2);
|
|
};
|
|
int8_1e2.BYTES = int8.BYTES;
|
|
var int8_1e1 = function(bytes) {
|
|
return +(int8(bytes) / 1e1).toFixed(1);
|
|
};
|
|
int8_1e1.BYTES = int8.BYTES;
|
|
|
|
var int16_1e5 = function(bytes) {
|
|
return +(int16(bytes) / 1e5).toFixed(5);
|
|
};
|
|
int16_1e5.BYTES = int16.BYTES;
|
|
var int16_1e4 = function(bytes) {
|
|
return +(int16(bytes) / 1e4).toFixed(4);
|
|
};
|
|
int16_1e4.BYTES = int16.BYTES;
|
|
var int16_1e3 = function(bytes) {
|
|
return +(int16(bytes) / 1e3).toFixed(3);
|
|
};
|
|
int16_1e3.BYTES = int16.BYTES;
|
|
var int16_1e2 = function(bytes) {
|
|
return +(int16(bytes) / 1e2).toFixed(2);
|
|
};
|
|
int16_1e2.BYTES = int16.BYTES;
|
|
var int16_1e1 = function(bytes) {
|
|
return +(int16(bytes) / 1e1).toFixed(1);
|
|
};
|
|
int16_1e1.BYTES = int16.BYTES;
|
|
|
|
var int24_1e6 = function(bytes) {
|
|
return +(int24(bytes) / 1e6).toFixed(6);
|
|
};
|
|
int24_1e6.BYTES = int24.BYTES;
|
|
var int24_1e5 = function(bytes) {
|
|
return +(int24(bytes) / 1e5).toFixed(5);
|
|
};
|
|
int24_1e5.BYTES = int24.BYTES;
|
|
var int24_1e4 = function(bytes) {
|
|
return +(int24(bytes) / 1e4).toFixed(4);
|
|
};
|
|
int24_1e4.BYTES = int24.BYTES;
|
|
var int24_1e3 = function(bytes) {
|
|
return +(int24(bytes) / 1e3).toFixed(3);
|
|
};
|
|
int24_1e3.BYTES = int24.BYTES;
|
|
var int24_1e2 = function(bytes) {
|
|
return +(int24(bytes) / 1e2).toFixed(2);
|
|
};
|
|
int24_1e2.BYTES = int24.BYTES;
|
|
var int24_1e1 = function(bytes) {
|
|
return +(int24(bytes) / 1e1).toFixed(1);
|
|
};
|
|
int24_1e1.BYTES = int24.BYTES;
|
|
|
|
var int32_1e6 = function(bytes) {
|
|
return +(int32(bytes) / 1e6).toFixed(6);
|
|
};
|
|
int32_1e6.BYTES = int32.BYTES;
|
|
var int32_1e5 = function(bytes) {
|
|
return +(int32(bytes) / 1e5).toFixed(5);
|
|
};
|
|
int32_1e5.BYTES = int32.BYTES;
|
|
var int32_1e4 = function(bytes) {
|
|
return +(int32(bytes) / 1e4).toFixed(4);
|
|
};
|
|
int32_1e4.BYTES = int32.BYTES;
|
|
var int32_1e3 = function(bytes) {
|
|
return +(int32(bytes) / 1e3).toFixed(3);
|
|
};
|
|
int32_1e3.BYTES = int32.BYTES;
|
|
var int32_1e2 = function(bytes) {
|
|
return +(int32(bytes) / 1e2).toFixed(2);
|
|
};
|
|
int32_1e2.BYTES = int32.BYTES;
|
|
var int32_1e1 = function(bytes) {
|
|
return +(int32(bytes) / 1e1).toFixed(1);
|
|
};
|
|
int32_1e1.BYTES = int32.BYTES;
|
|
|
|
|
|
var pluginid = function(bytes) {
|
|
return +(uint8(bytes));
|
|
};
|
|
pluginid.BYTES = uint8.BYTES;
|
|
|
|
|
|
var latLng = function(bytes) {
|
|
// 2^23 / 180 = 46603...
|
|
return +(int24(bytes) / 46600);
|
|
};
|
|
latLng.BYTES = int24.BYTES;
|
|
|
|
var hdop = function(bytes) {
|
|
return +(uint8(bytes) / 10).toFixed(2);
|
|
};
|
|
hdop.BYTES = uint8.BYTES;
|
|
|
|
var altitude = function(bytes) {
|
|
// Option to increase altitude resolution (also on encoder side)
|
|
return +(int16(bytes) / 4 - 1000).toFixed(1);
|
|
};
|
|
altitude.BYTES = int16.BYTES;
|
|
|
|
// -1 .. 5.12V
|
|
var vcc = function(bytes) {
|
|
return +(uint8(bytes) / 41.83 - 1.0).toFixed(2);
|
|
};
|
|
vcc.BYTES = uint8.BYTES;
|
|
|
|
// 0 .. 100%
|
|
var pct_8 = function(bytes) {
|
|
return +(uint8(bytes) / 2.56).toFixed(2);
|
|
};
|
|
pct_8.BYTES = uint8.BYTES;
|
|
|
|
|
|
var bitmap1 = function(byte) {
|
|
if (byte.length !== bitmap1.BYTES) {
|
|
throw new Error('Bitmap must have exactly 1 byte');
|
|
}
|
|
var i = bytesToInt(byte);
|
|
var bm = ('00000000' + Number(i).toString(2)).substr(-8).split('').map(Number).map(Boolean);
|
|
return ['adr', 'screensaver', 'screen', 'countermode', 'blescan', 'antenna', 'filter', 'alarm']
|
|
.reduce(function(obj, pos, index) {
|
|
obj[pos] = +bm[index];
|
|
return obj;
|
|
}, {});
|
|
};
|
|
bitmap1.BYTES = 1;
|
|
|
|
var bitmap2 = function(byte) {
|
|
if (byte.length !== bitmap2.BYTES) {
|
|
throw new Error('Bitmap must have exactly 1 byte');
|
|
}
|
|
var i = bytesToInt(byte);
|
|
var bm = ('00000000' + Number(i).toString(2)).substr(-8).split('').map(Number).map(Boolean);
|
|
return ['gps', 'alarm', 'bme', 'counter', 'sensor1', 'sensor2', 'sensor3', 'battery']
|
|
.reduce(function(obj, pos, index) {
|
|
obj[pos] = +bm[index];
|
|
return obj;
|
|
}, {});
|
|
};
|
|
bitmap2.BYTES = 1;
|
|
|
|
var header = function(byte) {
|
|
if (byte.length !== header.BYTES) {
|
|
throw new Error('header must have exactly 5 bytes');
|
|
}
|
|
var values = [0, 0, 0, 0];
|
|
values[0] = bytesToInt(byte.slice(0, 1));
|
|
values[1] = bytesToInt(byte.slice(1, 3));
|
|
values[2] = bytesToInt(byte.slice(3, 4));
|
|
values[3] = bytesToInt(byte.slice(4, 5));
|
|
|
|
return ['plugin_id', 'IDX', 'samplesetcount', 'valuecount']
|
|
.reduce(function(obj, pos, index) {
|
|
obj[pos] = +values[index];
|
|
return obj;
|
|
}, {});
|
|
};
|
|
header.BYTES = 5;
|
|
|
|
|
|
var decode = function(bytes, mask, names) {
|
|
|
|
var maskLength = mask.reduce(function(prev, cur) {
|
|
return prev + cur.BYTES;
|
|
}, 0);
|
|
if (bytes.length < maskLength) {
|
|
throw new Error('Mask length is ' + maskLength + ' whereas input is ' + bytes.length);
|
|
}
|
|
|
|
names = names || [];
|
|
var offset = 0;
|
|
return mask
|
|
.map(function(decodeFn) {
|
|
var current = bytes.slice(offset, offset += decodeFn.BYTES);
|
|
return decodeFn(current);
|
|
})
|
|
.reduce(function(prev, cur, idx) {
|
|
prev[names[idx] || idx] = cur;
|
|
return prev;
|
|
}, {});
|
|
};
|
|
|
|
|
|
var decode_plugin = function(fPort, bytes, mask, names) {
|
|
return Converter(decode(bytes, mask, names), fPort);
|
|
};
|
|
|
|
|
|
function Converter(decoded, fPort) {
|
|
|
|
var converted = decoded;
|
|
var name = "";
|
|
|
|
if (fPort === 1) {
|
|
if ('header' in converted) {
|
|
switch (converted.header.plugin_id) {
|
|
case 1:
|
|
converted.name = "Switch";
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 2:
|
|
converted.name = "ADC";
|
|
converted.analog = converted.val_1;
|
|
break;
|
|
|
|
case 3:
|
|
converted.name = "Pulse";
|
|
converted.count = converted.val_1;
|
|
converted.total = converted.val_2;
|
|
converted.time = converted.val_3;
|
|
break;
|
|
|
|
case 4:
|
|
converted.name = "Dallas";
|
|
// For compatibility reasons, also include temp.
|
|
converted.temp = converted.val_1;
|
|
converted.temp1 = converted.val_1;
|
|
converted.temp2 = converted.val_2;
|
|
converted.temp3 = converted.val_3;
|
|
converted.temp4 = converted.val_4;
|
|
break;
|
|
|
|
case 5:
|
|
converted.name = "DHT";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
break;
|
|
|
|
case 6:
|
|
converted.name = "BMP085";
|
|
converted.temp = converted.val_1;
|
|
converted.pressure = converted.val_2;
|
|
break;
|
|
|
|
case 7:
|
|
converted.name = "PCF8591";
|
|
converted.analog = converted.val_1;
|
|
break;
|
|
|
|
case 8:
|
|
converted.name = "RFID"; {
|
|
// Not sure if it is present, since the sensor only has a single output value in ESPeasy.
|
|
var ulongvalue = converted.val_2 * 65536 + converted.val_1;
|
|
converted.tag = ulongvalue.toFixed(0);
|
|
}
|
|
break;
|
|
|
|
case 9:
|
|
converted.name = "MCP";
|
|
converted.state = converted.val_1;
|
|
break;
|
|
|
|
case 10:
|
|
converted.name = "BH1750";
|
|
converted.lux = converted.val_1;
|
|
break;
|
|
|
|
case 11:
|
|
converted.name = "PME";
|
|
converted.v1 = converted.val_1;
|
|
break;
|
|
|
|
case 12:
|
|
converted.name = "LCD";
|
|
// Should not output anything, echo the values just to be sure.
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 13:
|
|
converted.name = "HCSR04";
|
|
converted.dist = converted.val_1;
|
|
break;
|
|
|
|
case 14:
|
|
converted.name = "SI7021";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
break;
|
|
|
|
case 15:
|
|
converted.name = "TSL2561";
|
|
// Not sure if the last value is present.
|
|
converted.lux = converted.val_1;
|
|
converted.infrared = converted.val_2;
|
|
converted.broadband = converted.val_3;
|
|
converted.ratio = converted.val_4;
|
|
break;
|
|
|
|
case 16:
|
|
converted.name = "IR_rx";
|
|
converted.IR = converted.val_1;
|
|
break;
|
|
|
|
case 17:
|
|
converted.name = "PN532"; {
|
|
// Not sure if it is present, since the sensor only has a single output value in ESPeasy.
|
|
var ulongvalue = converted.val_2 * 65536 + converted.val_1;
|
|
converted.tag = ulongvalue.toFixed(0);
|
|
}
|
|
break;
|
|
|
|
case 18:
|
|
converted.name = "GP2Y10";
|
|
converted.dust = converted.val_1;
|
|
break;
|
|
|
|
case 19:
|
|
converted.name = "PCF8574";
|
|
converted.state = converted.val_1;
|
|
break;
|
|
|
|
case 20:
|
|
converted.name = "Ser2Net";
|
|
// Not sure if this one does output a useful value
|
|
converted.ser2net = converted.val_1;
|
|
break;
|
|
|
|
case 21:
|
|
converted.name = "Level";
|
|
converted.output = converted.val_1;
|
|
break;
|
|
|
|
case 22:
|
|
converted.name = "PCA9685";
|
|
// Should not output any value
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
break;
|
|
|
|
case 23:
|
|
converted.name = "OLED";
|
|
// Should not output any value
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
break;
|
|
|
|
case 24:
|
|
converted.name = "MLX90614";
|
|
converted.temp = converted.val_1;
|
|
break;
|
|
|
|
case 25:
|
|
converted.name = "ADS1115";
|
|
converted.analog = converted.val_1;
|
|
break;
|
|
|
|
case 26:
|
|
converted.name = "Sysinfo";
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
converted.ip = [converted.ip1, converted.ip2, converted.ip3, converted.ip4].join('.');
|
|
break;
|
|
|
|
case 27:
|
|
converted.name = "INA219";
|
|
converted.volt = converted.val_1;
|
|
converted.current = converted.val_2;
|
|
converted.power = converted.val_3;
|
|
break;
|
|
|
|
case 28:
|
|
converted.name = "BME280";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
converted.pressure = converted.val_3;
|
|
break;
|
|
|
|
case 29:
|
|
converted.name = "MQTThelper";
|
|
converted.output = converted.val_1;
|
|
break;
|
|
|
|
case 30:
|
|
converted.name = "BMP280";
|
|
converted.temp = converted.val_1;
|
|
converted.pressure = converted.val_2;
|
|
break;
|
|
|
|
case 31:
|
|
converted.name = "SHT1X";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
break;
|
|
|
|
case 32:
|
|
converted.name = "MS5611";
|
|
converted.temp = converted.val_1;
|
|
converted.pressure = converted.val_2;
|
|
break;
|
|
|
|
case 33:
|
|
converted.name = "Dummy";
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 34:
|
|
converted.name = "DHT12";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
break;
|
|
|
|
case 35:
|
|
converted.name = "IRTX";
|
|
// Should not output anything
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
break;
|
|
|
|
case 36:
|
|
converted.name = "FrameOLED";
|
|
// Should not output anything
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
break;
|
|
|
|
case 37:
|
|
converted.name = "MQTTImport";
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 38:
|
|
converted.name = "NeoPixel";
|
|
// Should not output anything
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
break;
|
|
|
|
case 39:
|
|
converted.name = "Thermocouple";
|
|
converted.temp = converted.val_1;
|
|
break;
|
|
|
|
case 40:
|
|
converted.name = "ID12"; {
|
|
// Not sure if it is present, since the sensor only has a single output value in ESPeasy.
|
|
var ulongvalue = converted.val_2 * 65536 + converted.val_1;
|
|
converted.tag = ulongvalue.toFixed(0);
|
|
}
|
|
break;
|
|
|
|
case 41:
|
|
converted.name = "NeoClock";
|
|
// Should not output anything
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
break;
|
|
|
|
case 42:
|
|
converted.name = "Candle";
|
|
converted.color = converted.val_1;
|
|
converted.brightness = converted.val_2;
|
|
converted.type = converted.val_3;
|
|
break;
|
|
|
|
case 43:
|
|
converted.name = "ClkOutput";
|
|
converted.output = converted.val_1;
|
|
break;
|
|
|
|
case 44:
|
|
converted.name = "P1WifiGateway";
|
|
converted.v1 = converted.val_1;
|
|
break;
|
|
|
|
case 45:
|
|
converted.name = "MPU6050";
|
|
// Not sure what to output here, since it uses "send data option"
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 46:
|
|
converted.name = "VentusW266";
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
break;
|
|
|
|
case 47:
|
|
converted.name = "i2c-soil-moisture-sensor";
|
|
converted.temp = converted.val_1;
|
|
converted.moisture = converted.val_2;
|
|
converted.light = converted.val_3;
|
|
break;
|
|
|
|
case 48:
|
|
converted.name = "Motorshield_v2";
|
|
break;
|
|
|
|
case 49:
|
|
converted.name = "MHZ19";
|
|
converted.ppm = converted.val_1;
|
|
converted.temp = converted.val_2;
|
|
converted.U = converted.val_3;
|
|
break;
|
|
|
|
case 50:
|
|
converted.name = "TCS34725";
|
|
converted.R = converted.val_1;
|
|
converted.G = converted.val_2;
|
|
converted.B = converted.val_3;
|
|
converted.colortemp = converted.val_4;
|
|
break;
|
|
|
|
case 51:
|
|
converted.name = "AM2320";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
break;
|
|
|
|
case 52:
|
|
converted.name = "SenseAir";
|
|
converted.ppm = converted.val_1;
|
|
converted.temp = converted.val_2;
|
|
break;
|
|
|
|
case 53:
|
|
converted.name = "PMSx003";
|
|
converted.pm1_0 = converted.val_1;
|
|
converted.pm2_5 = converted.val_2;
|
|
converted.pm10 = converted.val_3;
|
|
break;
|
|
|
|
case 54:
|
|
converted.name = "DMX512";
|
|
break;
|
|
|
|
case 55:
|
|
converted.name = "Chiming";
|
|
break;
|
|
|
|
case 56:
|
|
converted.name = "SDS011-Dust";
|
|
converted.pm2_5 = converted.val_1;
|
|
converted.pm10 = converted.val_2;
|
|
break;
|
|
|
|
case 57:
|
|
converted.name = "HT16K33_LED";
|
|
break;
|
|
|
|
case 58:
|
|
converted.name = "HT16K33_KeyPad";
|
|
converted.scancode = converted.val_1;
|
|
break;
|
|
|
|
case 59:
|
|
converted.name = "Encoder";
|
|
converted.counter = converted.val_1;
|
|
break;
|
|
|
|
case 60:
|
|
converted.name = "MCP3221";
|
|
converted.analog = converted.val_1;
|
|
break;
|
|
|
|
case 61:
|
|
converted.name = "KeyPad";
|
|
converted.scancode = converted.val_1;
|
|
break;
|
|
|
|
case 62:
|
|
converted.name = "MPR121_KeyPad";
|
|
converted.scancode = converted.val_1;
|
|
break;
|
|
|
|
case 63:
|
|
converted.name = "TTP229_KeyPad";
|
|
converted.scancode = converted.val_1;
|
|
break;
|
|
|
|
case 64:
|
|
converted.name = "APDS9960";
|
|
converted.gesture = converted.val_1;
|
|
converted.proximity = converted.val_2;
|
|
converted.light = converted.val_3;
|
|
break;
|
|
|
|
case 65:
|
|
converted.name = "DRF0299_MP3";
|
|
break;
|
|
|
|
case 66:
|
|
converted.name = "VEML6040";
|
|
converted.R = converted.val_1;
|
|
converted.G = converted.val_2;
|
|
converted.B = converted.val_3;
|
|
converted.W = converted.val_4;
|
|
break;
|
|
|
|
case 67:
|
|
converted.name = "HX711_Load_Cell";
|
|
converted.weight_A = converted.val_1;
|
|
converted.weight_B = converted.val_2;
|
|
break;
|
|
|
|
case 68:
|
|
converted.name = "SHT3x";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
break;
|
|
|
|
case 69:
|
|
converted.name = "LM75A";
|
|
converted.temp = converted.val_1;
|
|
break;
|
|
|
|
case 70:
|
|
converted.name = "NeoPixel_Clock";
|
|
converted.enabled = converted.val_1;
|
|
converted.brightness = converted.val_2;
|
|
converted.marks = converted.val_3;
|
|
break;
|
|
|
|
case 71:
|
|
converted.name = "Kamstrup401";
|
|
converted.heat = converted.val_1;
|
|
converted.volume = converted.val_2;
|
|
break;
|
|
|
|
case 72:
|
|
converted.name = "HDC1080";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
break;
|
|
|
|
case 73:
|
|
converted.name = "7DGT";
|
|
break;
|
|
|
|
case 74:
|
|
converted.name = "TSL2591";
|
|
converted.lux = converted.val_1;
|
|
converted.full = converted.val_2;
|
|
converted.visible = converted.val_3;
|
|
converted.infrared = converted.val_4;
|
|
break;
|
|
|
|
case 75:
|
|
converted.name = "Nextion";
|
|
converted.idx = converted.val_1;
|
|
converted.value = converted.val_2;
|
|
break;
|
|
|
|
case 76:
|
|
converted.name = "HLW8012";
|
|
converted.volt = converted.val_1;
|
|
converted.current = converted.val_2;
|
|
converted.power = converted.val_3;
|
|
converted.powerfactor = converted.val_4;
|
|
break;
|
|
|
|
case 77:
|
|
converted.name = "CSE7766";
|
|
converted.volt = converted.val_1;
|
|
converted.power = converted.val_2;
|
|
converted.current = converted.val_3;
|
|
converted.pulses = converted.val_4;
|
|
break;
|
|
|
|
case 78:
|
|
converted.name = "Eastron";
|
|
// Selectable outputs, so do not name them here
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 79:
|
|
converted.name = "Wemos_Motorshield";
|
|
break;
|
|
|
|
case 80:
|
|
converted.name = "DallasIButton"; {
|
|
// Not sure if it is present, since the sensor only has a single output value in ESPeasy.
|
|
var ulongvalue = converted.val_2 * 65536 + converted.val_1;
|
|
converted.ibutton = ulongvalue.toFixed(0);
|
|
}
|
|
break;
|
|
|
|
case 81:
|
|
converted.name = "Cron";
|
|
converted.lastexec = converted.val_1;
|
|
converted.nextexec = converted.val_2;
|
|
break;
|
|
|
|
case 82:
|
|
converted.name = "GPS";
|
|
// GPS data is already decoded in packed_decoder.js
|
|
// HDOP is needed by TTN mapper to weigh the quality of the data.
|
|
// When using TTN mapper, make sure to output these values.
|
|
break;
|
|
|
|
case 83:
|
|
converted.name = "SGP30";
|
|
converted.tvoc = converted.val_1;
|
|
converted.eco2 = converted.val_2;
|
|
break;
|
|
|
|
case 84:
|
|
converted.name = "VEML6070";
|
|
converted.uv_raw = converted.val_1;
|
|
converted.uv_risk = converted.val_2;
|
|
converted.uv_power = converted.val_3;
|
|
break;
|
|
|
|
case 85:
|
|
converted.name = "AcuDC243";
|
|
// This plugin can output any value, so show string representation
|
|
// of the unit of measure
|
|
converted.unit1 = getAcuDC243Unit(converted.unit1);
|
|
converted.unit2 = getAcuDC243Unit(converted.unit2);
|
|
converted.unit3 = getAcuDC243Unit(converted.unit3);
|
|
converted.unit4 = getAcuDC243Unit(converted.unit4);
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 86:
|
|
converted.name = "Homie";
|
|
// Can select a number of outputs
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 87:
|
|
converted.name = "SerialProxy";
|
|
// This plugin currently outputs strings, so not useful for LoRa
|
|
/*
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
*/
|
|
break;
|
|
|
|
case 89:
|
|
converted.name = "Ping";
|
|
converted.fails = converted.val_1;
|
|
break;
|
|
|
|
case 90:
|
|
converted.name = "CCS811";
|
|
converted.TVOC = converted.val_1;
|
|
converted.eCO2 = converted.val_2;
|
|
break;
|
|
|
|
case 91:
|
|
converted.name = "SerSwitch";
|
|
// Can select a number of outputs
|
|
converted.relay1 = converted.val_1;
|
|
converted.relay2 = converted.val_2;
|
|
converted.relay3 = converted.val_3;
|
|
converted.relay4 = converted.val_4;
|
|
break;
|
|
|
|
case 92:
|
|
converted.name = "DLbus";
|
|
// Can select a number of outputs
|
|
// TODO TD-er: Must add binary representation of all values
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 93:
|
|
converted.name = "MitsubishiHP";
|
|
// Outputs string
|
|
// TODO TD-er: Must add binary representation of all values
|
|
converted.v1 = converted.val_1;
|
|
break;
|
|
|
|
case 94:
|
|
converted.name = "CULreader";
|
|
// Outputs string
|
|
// TODO TD-er: Must add binary representation of all values
|
|
converted.v1 = converted.val_1;
|
|
break;
|
|
|
|
case 97:
|
|
converted.name = "ESP32Touch";
|
|
converted.touch = converted.val_1;
|
|
break;
|
|
|
|
case 100:
|
|
converted.name = "DS2423counter";
|
|
// TODO TD-er: This is probably the worst possible value to send over a LoRa network, as packets may get lost.
|
|
converted.countdelta = converted.val_1;
|
|
break;
|
|
|
|
case 102:
|
|
converted.name = "PZEM004T v30";
|
|
break;
|
|
|
|
case 106:
|
|
converted.name = "BME680";
|
|
converted.temp = converted.val_1;
|
|
converted.hum = converted.val_2;
|
|
converted.pressure = converted.val_3;
|
|
converted.gas = converted.val_4;
|
|
break;
|
|
|
|
case 107:
|
|
converted.name = "SI1145";
|
|
converted.visible = converted.val_1;
|
|
converted.infra = converted.val_2;
|
|
converted.uv = converted.val_3;
|
|
break;
|
|
|
|
case 108:
|
|
converted.name = "DDS238-x ZN";
|
|
// This plugin can output any value, so show string representation
|
|
// of the unit of measure
|
|
converted.unit1 = getDDS238_xUnit(converted.unit1);
|
|
converted.unit2 = getDDS238_xUnit(converted.unit2);
|
|
converted.unit3 = getDDS238_xUnit(converted.unit3);
|
|
converted.unit4 = getDDS238_xUnit(converted.unit4);
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
|
|
case 110:
|
|
converted.name = "VL53L0X";
|
|
converted.distance = converted.val_1;
|
|
break;
|
|
|
|
case 111:
|
|
converted.name = "RC522 RFID"; {
|
|
// Not sure if it is present, since the sensor only has a single output value in ESPeasy.
|
|
var ulongvalue = converted.val_2 * 65536 + converted.val_1;
|
|
converted.tag = ulongvalue.toFixed(0);
|
|
}
|
|
break;
|
|
|
|
case 113:
|
|
converted.name = "VL53L1X";
|
|
converted.distance = converted.val_1;
|
|
converted.ambient = converted.val_2;
|
|
break;
|
|
|
|
default:
|
|
converted.v1 = converted.val_1;
|
|
converted.v2 = converted.val_2;
|
|
converted.v3 = converted.val_3;
|
|
converted.v4 = converted.val_4;
|
|
break;
|
|
} // End Switch
|
|
delete converted["val_1"];
|
|
delete converted["val_2"];
|
|
delete converted["val_3"];
|
|
delete converted["val_4"];
|
|
}
|
|
|
|
}
|
|
|
|
return converted;
|
|
};
|
|
|
|
function getAcuDC243Unit(unit_id) {
|
|
switch (unit_id) {
|
|
case 0: // P085_QUERY_V 0
|
|
return "V";
|
|
case 1: // P085_QUERY_A 1
|
|
return "A";
|
|
case 2: // P085_QUERY_W 2
|
|
return "W";
|
|
case 3: // P085_QUERY_Wh_imp 3
|
|
return "Wh imp";
|
|
case 4: // P085_QUERY_Wh_exp 4
|
|
return "Wh exp";
|
|
case 5: // P085_QUERY_Wh_tot 5
|
|
return "Wh total";
|
|
case 6: // P085_QUERY_Wh_net 6
|
|
return "Wh net";
|
|
case 7: // P085_QUERY_h_tot 7
|
|
return "hours tot";
|
|
case 8: // P085_QUERY_h_load 8
|
|
return "hours load";
|
|
}
|
|
return "unknown" + unit_id;
|
|
};
|
|
|
|
|
|
function getDDS238_xUnit(unit_id) {
|
|
switch (unit_id) {
|
|
case 0: // P108_QUERY_V 0
|
|
return "V";
|
|
case 1: // P108_QUERY_A 1
|
|
return "A";
|
|
case 2: // P108_QUERY_W 2
|
|
return "W";
|
|
case 3: // P108_QUERY_VA 3
|
|
return "VA";
|
|
case 4: // P108_QUERY_PF 4
|
|
return "cosphi";
|
|
case 5: // P108_QUERY_F 5
|
|
return "Hz";
|
|
case 6: // P108_QUERY_Wh_imp 6
|
|
return "Wh imp";
|
|
case 7: // P108_QUERY_Wh_exp 7
|
|
return "Wh exp";
|
|
case 8: // P108_QUERY_Wh_tot 8
|
|
return "Wh total";
|
|
}
|
|
return "unknown" + unit_id;
|
|
};
|
|
|
|
|
|
|
|
if (typeof module === 'object' && typeof module.exports !== 'undefined') {
|
|
module.exports = {
|
|
uint8: uint8,
|
|
uint16: uint16,
|
|
uint24: uint24,
|
|
uint32: uint32,
|
|
int8: int8,
|
|
int16: int16,
|
|
int24: int24,
|
|
int32: int32,
|
|
uint8_1e3: uint8_1e3,
|
|
uint8_1e2: uint8_1e2,
|
|
uint8_1e1: uint8_1e1,
|
|
uint16_1e5: uint16_1e5,
|
|
uint16_1e4: uint16_1e4,
|
|
uint16_1e3: uint16_1e3,
|
|
uint16_1e2: uint16_1e2,
|
|
uint16_1e1: uint16_1e1,
|
|
uint24_1e6: uint24_1e6,
|
|
uint24_1e5: uint24_1e5,
|
|
uint24_1e4: uint24_1e4,
|
|
uint24_1e3: uint24_1e3,
|
|
uint24_1e2: uint24_1e2,
|
|
uint24_1e1: uint24_1e1,
|
|
uint32_1e6: uint32_1e6,
|
|
uint32_1e5: uint32_1e5,
|
|
uint32_1e4: uint32_1e4,
|
|
uint32_1e3: uint32_1e3,
|
|
uint32_1e2: uint32_1e2,
|
|
uint32_1e1: uint32_1e1,
|
|
int8_1e3: int8_1e3,
|
|
int8_1e2: int8_1e2,
|
|
int8_1e1: int8_1e1,
|
|
int16_1e5: int16_1e5,
|
|
int16_1e4: int16_1e4,
|
|
int16_1e3: int16_1e3,
|
|
int16_1e2: int16_1e2,
|
|
int16_1e1: int16_1e1,
|
|
int24_1e6: int24_1e6,
|
|
int24_1e5: int24_1e5,
|
|
int24_1e4: int24_1e4,
|
|
int24_1e3: int24_1e3,
|
|
int24_1e2: int24_1e2,
|
|
int24_1e1: int24_1e1,
|
|
int32_1e6: int32_1e6,
|
|
int32_1e5: int32_1e5,
|
|
int32_1e4: int32_1e4,
|
|
int32_1e3: int32_1e3,
|
|
int32_1e2: int32_1e2,
|
|
int32_1e1: int32_1e1,
|
|
pluginid: pluginid,
|
|
latLng: latLng,
|
|
hdop: hdop,
|
|
altitude: altitude,
|
|
vcc: vcc,
|
|
pct_8: pct_8,
|
|
bitmap1: bitmap1,
|
|
bitmap2: bitmap2,
|
|
header: header,
|
|
version: version,
|
|
decode: decode
|
|
};
|
|
} |