Is there an example JavaScript decoder for Eastron meter payloads?
Example JavaScript Decoder for Easton meter payloads
Many LoRaWAN Network Servers (LNS) such Chirpstack, TTN and Loriot, as well as those found onboard LoRaWAN gateways, allow you to provide a JavaScript decoder to decode the raw LoRaWAN payload into the parameters you expect. Below is an example JavaScript decoder that can be adapted and used for your use case. This specific decoder matches the expected parameters returned by the default configuration of the SDM630MCT-LoRa (https://support.cthings.io/en/article/decoding-data-from-the-eastron-sdm630mct-lora-1n4i1eu/).
The helper functions can be used to parse bytes from the payload to a specific data type
/**
_____ _ _ _ _ _ _ _
__|_ _| |__ (_)_ __ __ _ ___ | | (_)_ __ ___ (_) |_ ___ __| |
/ __|| | | '_ \| | '_ \ / _` / __| | | | | '_ ` _ \| | __/ _ \/ _` |
| (__ | | | | | | | | | | (_| \__ \ | |___| | | | | | | | || __/ (_| |
\___||_| |_| |_|_|_| |_|\__, |___/ |_____|_|_| |_| |_|_|\__\___|\__,_|
|___/
This script is provided by cThings Limited for the purpose of assisting with LoRaWAN payload decoding for Eastron meters.
It is offered "as-is" without any warranties, express or implied.
cThings Limited is not responsible for any errors, data inaccuracies, or consequences resulting from its use. Use at your own risk.
**/
// round a number to a set number of places whilst avoiding floating point precision errors
function epsilonRound(num, places) {
return Math.round((num + Math.pow(2,-52)) * Math.pow(10,places)) / Math.pow(10,places);
}
// convert a byte to uint8
function bytesToUInt8(bytes) {
return parseInt(bytes[0]);
}
// convert 2 bytes to a uint16
function bytesToUInt16(bytes) {
console.log(bytes);
var result = (bytes[0] << 8) | bytes[1];
return parseInt(result);
}
// convert 4 bytes to a uint32
function bytesToUInt32(bytes) {
var result = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
return parseInt(result);
}
// convert 4 bytes to a float32
function bytesToFloat32(bytes) {
var bits = bytes[0]<<24 | bytes[1]<<16 | bytes[2]<<8 | bytes[3];
var sign = (bits>>>31 === 0) ? 1.0 : -1.0;
var e = bits>>>23 & 0xff;
var m = (e === 0) ? (bits & 0x7fffff)<<1 : (bits & 0x7fffff) | 0x800000;
var f = sign m Math.pow(2, e - 150);
return parseFloat(f);
}
// decode a lorawan payload
function Decode(fPort, bytes, variables) {
return {
serialNumber: bytesToUInt32(bytes.slice(0,4)),
energy: epsilonRound(bytesToFloat32(bytes.slice(6,10)),5),
frequency: epsilonRound(bytesToFloat32(bytes.slice(10,14)),5),
powerFactor: epsilonRound(bytesToFloat32(bytes.slice(14,18)),5),
maxDemand: epsilonRound(bytesToFloat32(bytes.slice(18,22)),5),
current: epsilonRound(bytesToFloat32(bytes.slice(22,26)),5)
};
}
Updated on: 11/02/2025
Thank you!