TRP ERW700
Last updated
Last updated
ZLW Energie 1
heatMeterEnergy
telemetry
long
ZLW Energie 2
heatMeterEnergy
telemetry
long
ZLW Masse 1
waterMeter
telemetry
long
ZLW Volumen 1
waterMeterVolume
telemetry
long
ZLW Volumen 2
gasMeterVolume
telemetry
long
ZLW Volumen 3
heatMeterVolume
telemetry
long
Massefluss Qm 1
flowRate
telemetry
float
Volumen Durchfluss Qb 2
vB (Betriebsvolumen in m3)
telemetry
float
WarmTemp
flowTemperature
telemetry
float
KaltTemp
returnFlowTemperature
telemetry
float
Stromeingang 1
electricityMeterEnergy
telemetry
float
// V1.0, 29.09.2021, DS
if (msg.data) {
var decoded = decodeFromHex(msg.data);
decoded.ts = msg.ts;
decoded.rssi = msg.rssi;
decoded.snr = msg.snr;
decoded.toa = msg.toa;
decoded.frequency = msg.frequency;
decoded.dr = msg.dr;
decoded.bat = decodeBattery(msg.bat);
decoded.hex = msg.data;
return {
msg: decoded,
metadata: metadata,
msgType: msgType
};
} else {
return {
msg: msg,
metadata: metadata,
msgType: msgType
};
}
function decodeFromHex(data) {
// Decode an uplink message from a buffer
// (array) of bytes to an object of fields.
var telemetry = {};
if (data.substr(30,2) == "81")
{
var hexString = "0x" + data.substr(32,8);
var heatMeterEnergy = parseFloat(hexString);
telemetry.heatMeterEnergy = heatMeterEnergy;
}
if (data.substr(40,2) == "9b")
{
var hexString = "0x" + data.substr(42,8);
var waterMeter = parseFloat(hexString);
telemetry.waterMeter = waterMeter;
}
if (data.substr(50,2) == "8d")
{
var hexString = "0x" + data.substr(52,8);
var flowRate = parseFloat(hexString);
telemetry.flowRate = flowRate;
}
if (data.substr(60,2) == "8a")
{
var hexString = "0x" + data.substr(62,8);
var power = parseFloat(hexString);
telemetry.power = power;
}
return telemetry;
}
function decodeBattery(byte) {
if (byte == 0) {
return 'External power source';
} else if (byte > 0 && byte < 255) {
return byte / 254 * 100;
} else {
return 'Unknown battery state'
}
}
function parseHexString(hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes;
}
function decodeToString(payload) {
return String.fromCharCode.apply(String, payload);
}
function decodeToJson(payload) {
// covert payload to string.
var str = decodeToString(payload);
// parse string to JSON
var data = JSON.parse(str);
return data;
}
function twos_complement(input_value, num_bits) {
var mask = Math.pow(2, num_bits - 1);
return -(input_value & mask) + (input_value & ~mask);
}
function get_int(bytes) {
var length = bytes.length;
var int = 0;
var i;
for (i = 0; i < length; i++) {
int += bytes[length - i - 1] << (i * 8);
}
return int;
}
function get_float(bytes) {
var length = bytes.length;
var float = 0;
var int = get_int(bytes);
if (length == 4) {
var sign = (int & 0x80000000) ? -1 : 1;
var exponent = ((int >> 23) & 0xFF) - 127;
var significand = (int & ~(-1 << 23));
if (exponent == 128) {
float = sign * ((significand) ? Number.NaN :
Number.POSITIVE_INFINITY);
} else if (exponent == -127) {
if (significand == 0) {
float = sign * 0.0;
} else {
exponent = -126;
significand /= (1 << 22);
float = sign * significand * Math.pow(2,
exponent);
}
} else {
significand = (significand | (1 << 23)) / (1 <<
23);
float = sign * significand * Math.pow(2,
exponent);
}
} else if (length == 2) {
var left = (int >> 14) & 0x03;
var value0 = int & 0x3FFF;
float = value0;
if (left == 0) {
float = float * 0.001;
} else if (left == 1) {
float = float * 0.02;
float = float + 16.38;
} else if (left == 3) {
float = float * 5;
float = float + 16725;
} else if (left == 2) {
float = float + 344;
}
} else {
throw "Undefined floating point size";
}
return float;
}
function parseChunkTypeA(bytes) {
var telemetry = {};
var dataHeader = bytes[0];
var dataValue = get_int(bytes.slice(1));
if (dataHeader ==
1
) { // 1 = 0x01 Temperature. signed integer 16bits. 1 LSB = 0.01°C. 0: 0°C; 1: +0.01°C; 0xFFFF : -0.01°C
telemetry.temperature = twos_complement(dataValue,
16) / 100;
} else if (dataHeader ==
2
) { // 2 = 0x02 Relative Humidity. unsigned integer 16bits. 1 LSB = 0.01°RH
telemetry.humidity = twos_complement(dataValue,
16) / 100;
} else if (dataHeader ==
3
) { // 3 = 0x03 Oxygen concentration. 1 LSB = 0.001%
telemetry.oxygen = dataValue / 1000;
} else if (dataHeader ==
4) { // 4 = 0x04 CO2 concentration. 1 LSB = 0.001%
telemetry.co2 = dataValue / 1000;
} else if (dataHeader ==
5
) { // 5 = 0x05 Second temperature. signed integer 16bits. 1 LSB = 0.01°C. 0: 0°C; 1: +0.01°C; 0xFFFF : -0.01°C
telemetry.temperature2 = twos_complement(dataValue,
16) / 100;
} else if (dataHeader ==
6
) { // 6 = 0x06 Pressure. unsigned integer 16bits. 1 LSB = 0.5mbar
telemetry.pressure = dataValue / 2;
} else if (dataHeader ==
7) { // 7 = 0x07 analog channel #0. 1 LSB = 1 uA
telemetry.analogCurrent0 = dataValue;
} else if (dataHeader ==
8) { // 8 = 0x08 analog channel #1. 1 LSB = 1 uA
telemetry.analogCurrent1 = dataValue;
} else if (dataHeader ==
9) { // 9 = 0x09 analog channel #2. 1 LSB = 1 uA
telemetry.analogCurrent2 = dataValue;
} else if (dataHeader ==
10) { // 10 = 0x0A analog channel #3. 1 LSB = 1 uA
telemetry.analogCurrent3 = dataValue;
} else if (dataHeader ==
11) { // 11 = 0x0B digital inputs state
telemetry.digitalInputsState = dataValue;
} else if (dataHeader ==
12) { // 12 = 0x0C relative pulse counter 0
telemetry.relativePulseCounter0 = dataValue;
} else if (dataHeader ==
13) { // 13 = 0x0D relative pulse counter 1
telemetry.relativePulseCounter1 = dataValue;
} else if (dataHeader ==
14) { // 14 = 0x0E relative pulse counter 2
telemetry.relativePulseCounter2 = dataValue;
} else if (dataHeader ==
16) { // 16 = 0x10 analog channel #0. 1 LSB = 1 mV
telemetry.analogVoltage0 = dataValue;
} else if (dataHeader ==
17) { // 17 = 0x11 analog channel #1. 1 LSB = 1 mV
telemetry.analogVoltage1 = dataValue;
} else if (dataHeader ==
18) { // 18 = 0x12 analog channel #2. 1 LSB = 1 mV
telemetry.analogVoltage2 = dataValue;
} else if (dataHeader ==
19) { // 19 = 0x12 analog channel #3. 1 LSB = 1 mV
telemetry.analogVoltage3 = dataValue;
}
return telemetry;
}
function parseChunkTypeB(bytes) {
var telemetry = {};
var dataHeader = bytes[0];
var dataValue = bytes.slice(1);
// console.log(dataHeader)
if (dataHeader ==
128
) { // 128 = 0x80 timestamp of the measurement. unsigned integer 32 bits. UNIX timestamp
// console.log(dataValue)
// console.log(get_int(dataValue))
//telemetry.ts = twos_complement(get_int(dataValue), 32) *1000; // calculate it in miliseconds
} else if (dataHeader ==
129
) { // 129 = 0x81 Main energy index. IEEE754 floating point. Unit : kWh for electricity meters (register 1.8.0)
telemetry.electricityMeterEnergy = get_float(
dataValue);
} else if (dataHeader ==
133
) { // 133 = 0x85 Main energy index. IEEE754 floating point. Unit : m3 for water meter
telemetry.waterMeterVolume = get_float(dataValue);
} else if (dataHeader ==
134
) { // 134 = 0x86 Main energy index. IEEE754 floating point. Unit : m3 for uncorrected gas meter
telemetry.gasMeterVolume = get_float(dataValue);
} else if (dataHeader ==
135
) { // 135 = 0x87 Flow temperature. IEEE754 floating point. Unit : °C
telemetry.flowTemperature = get_float(dataValue);
} else if (dataHeader ==
138
) { // 138 = 0x8a Power register. IEEE754 floating point. Unit W.
telemetry.power = get_float(dataValue);
} else if (dataHeader ==
139
) { // 139 = 0x8b Volume index. IEEE754 floating point. Unit: m3 for heat meter
telemetry.heatMeterVolume = get_float(dataValue);
} else if (dataHeader ==
140
) { // 140 = 0x8c Return flow temperature. IEEE754 floating point. Unit: °C
telemetry.returnFlowTemperature = get_float(
dataValue);
} else if (dataHeader ==
141
) { // 141 = 0x8d Volume flow. IEEE754 floating point. Unit: m3/h
telemetry.volumeFlow = get_float(dataValue);
} else if (dataHeader ==
154
) { // 154 = 0x9A IEEE754 floating point. Unit : kWh for heat meters (register 1.8.0)
telemetry.heatMeterEnergy = get_float(dataValue);
}
return telemetry;
}
function parseChunkTypeC(bytes, timestamp) {
var telemetry = [];
var size = bytes.length;
var dataHeader = bytes[0];
var snr = get_int(bytes.slice(1, 5));
var status = bytes.slice(5, 6);
var interval =
900000; // accumulation interval in milliseconds
var lastReadIndex = get_float(bytes.slice(6, 10));
var idx = 10;
var counter = 1;
// Get the interval from the status
if ((status & 0x1c) == 0) {
interval = 3600000;
} else if ((status & 0x1c) == 0x4) {
interval = 900000;
} else if ((status & 0x1c) == 0x8) {
interval = 38400000;
}
// Loop through the deltas and change the timestamp accordingly
if (dataHeader ==
201
) { // 140 = 0x8c Return flow temperature. IEEE754 floating point. Unit: °C
telemetry.push({
//'ts': timestamp,
'waterMeterSNR': snr,
'waterMeterCounter': lastReadIndex,
'batteryError': Boolean(status &
0x2),
'otherError': Boolean(status & 1)
})
while (idx <= size) {
var slice = bytes.slice(idx, idx + 2);
if (!(get_int(slice) == 0xffff)) {
telemetry.push({
//'ts': timestamp - counter * interval,
'waterMeterCounter': lastReadIndex + get_float(slice)
})
}
idx += 2;
counter++;
}
} else if (dataHeader ==
202
) { // 141 = 0x8d Volume flow. IEEE754 floating point. Unit: m3/h
telemetry.push({
//'ts': timestamp,
'gasMeterSNR': snr,
'gasMeterCounter': lastReadIndex,
'batteryError': Boolean(status &
0x2),
'otherError': Boolean(status & 1)
})
while (idx <= size) {
var slice = bytes.slice(idx, idx + 2);
if (!(get_int(slice) == 0xffff)) {
telemetry.push({
//'ts': timestamp - counter * interval,
'gasMeterCounter': lastReadIndex +
get_float(slice)
})
}
idx += 2;
counter++;
}
}
return telemetry;
}
function parseChunkTypeD(bytes) {
var telemetry = {};
var dataHeader = bytes[0];
var dataValue = get_int(bytes.slice(1));
if (dataHeader == 96) { // 96 = 0x60 Battery voltage
var volt = 0;
if (dataValue >= 81) {
volt = 4.2 + (dataValue - 80) * 0.1
} else {
volt = 1.8 + dataValue * 0.03
}
telemetry.batteryVoltage = volt;
} else if (dataHeader ==
97) { // 97 = 0x61 M-BUS meter status byte
telemetry.mBusMeterStatus = dataValue;
}
return telemetry;
}
function decodeBattery(byte) {
if (byte == 0) {
return 'External power source';
} else if (byte > 0 && byte < 255) {
return byte / 254 * 100;
} else {
return 'Unknown battery state';
}
}
function parseFloat(str) {
var float = 0, sign, order, mantissa, exp,
int = 0, multi = 1;
if (/^0x/.exec(str)) {
int = parseInt(str, 16);
}
else {
for (var i = str.length -1; i >=0; i -= 1) {
if (str.charCodeAt(i) > 255) {
console.log('Wrong string parameter');
return false;
}
int += str.charCodeAt(i) * multi;
multi *= 256;
}
}
sign = (int >>> 31) ? -1 : 1;
exp = (int >>> 23 & 0xff) - 127;
mantissa = ((int & 0x7fffff) + 0x800000).toString(2);
for (i=0; i<mantissa.length; i+=1) {
float += parseInt(mantissa[i]) ? Math.pow(2, exp) : 0;
exp--;
}
return float*sign;
}