Skip to content

Instantly share code, notes, and snippets.

@groupsky
Last active October 15, 2020 18:39
Show Gist options
  • Save groupsky/d8379dafd1b202de787e28ee9b5770dc to your computer and use it in GitHub Desktop.
Save groupsky/d8379dafd1b202de787e28ee9b5770dc to your computer and use it in GitHub Desktop.
ModBus read for Sinotype DDS024MR Electric Meter (https://s.click.aliexpress.com/e/_eNIqlR)
#!/usr/bin/env node
/*
* ModBus read for Sinotype DDS024MR Electric Meter
* https://s.click.aliexpress.com/e/_eNIqlR
*/
////////////////
// CONFIGURATION
////////////////
const DEVICE = '/dev/ttyUSB0'
// possible values 1200, 2400, 4800, 9600, default 9600
const BAUD_RATE = 9600
// possible values 'even', 'odd', 'none', default 'even'
const PARITY = 'even'
// possible values 1-247, default 1
const ADDRESS = 1
////////////////////
// END CONFIGURATION
////////////////////
const ModbusRTU = require('modbus-serial')
const ieee754 = require('ieee754')
// create an empty modbus client
const client = new ModbusRTU()
// open connection to a serial port
client.connectRTUBuffered(DEVICE, { baudRate: BAUD_RATE, parity: PARITY })
// set timeout, if slave did not reply back
client.setTimeout(500)
// list of meter's id
const metersIdList = [ADDRESS]
const getMetersValue = async (meters) => {
try{
// get value of all meters
for(let meter of meters) {
// output value to console
console.log(`${meter}:`, await getMeterValue(meter));
// wait 100ms before get another device
await sleep(100)
}
} catch(e){
// if error, handle them here (it should not)
console.log(e)
} finally {
// after get all data from salve repeate it again
setTimeout(() => {
getMetersValue(metersIdList)
}, 1000)
}
}
const getMeterValue = async (id) => {
try {
// set ID of slave
await client.setID(id)
let val = await client.readHoldingRegisters(0x00, 0x12);
// Baud rate - 1200, 2400, 4800 or 9600
const baud = ieee754.read(val.buffer, 0x00<<1, false, 23, 4)
// Parity - 0: even, 1: odd, 2: none
const parity = ieee754.read(val.buffer, 0x02<<1, false, 23, 4)
// Device address
const address = ieee754.read(val.buffer, 0x08<<1, false, 23, 4)
// Relay control - according to docs 1 is on, 2 is off, but I read only 0
const relay = ieee754.read(val.buffer, 0x10<<1, false, 23, 4)
val = await client.readInputRegisters(0x00, 0x38)
// A phase voltage in Volts
const av = ieee754.read(val.buffer, 0x00<<1, false, 23, 4)
// B phase voltage in Volts
const bv = ieee754.read(val.buffer, 0x02<<1, false, 23, 4)
// C phase voltage in Volts
const cv = ieee754.read(val.buffer, 0x04<<1, false, 23, 4)
// A line current in Amps
const ac = ieee754.read(val.buffer, 0x08<<1, false, 23, 4)
// B line current in Amps
const bc = ieee754.read(val.buffer, 0x0A<<1, false, 23, 4)
// C line current in Amps
const cc = ieee754.read(val.buffer, 0x0C<<1, false, 23, 4)
// total active power in kWh
const tot_ap = ieee754.read(val.buffer, 0x10<<1, false, 23, 4)
// A phase active power in kWh
const a_ap = ieee754.read(val.buffer, 0x12<<1, false, 23, 4)
// B phase active power in kWh
const b_ap = ieee754.read(val.buffer, 0x14<<1, false, 23, 4)
// C phase active power in kWh
const c_ap = ieee754.read(val.buffer, 0x16<<1, false, 23, 4)
// total reactive power in kVAr
const tot_rp = ieee754.read(val.buffer, 0x18<<1, false, 23, 4)
// A phase reactive power in VAr (could be kVAr)
const a_rp = ieee754.read(val.buffer, 0x1A<<1, false, 23, 4)
// B phase reactive power in VAr (could be kVAr)
const b_rp = ieee754.read(val.buffer, 0x1C<<1, false, 23, 4)
// C phase reactive power in VAr (could be kVAr)
const c_rp = ieee754.read(val.buffer, 0x1E<<1, false, 23, 4)
// A phase power factor
const apf = ieee754.read(val.buffer, 0x2A<<1, false, 23, 4)
// B phase power factor
const bpf = ieee754.read(val.buffer, 0x2C<<1, false, 23, 4)
// C phase power factor
const cpf = ieee754.read(val.buffer, 0x2E<<1, false, 23, 4)
// frequency in Hz
const freq = ieee754.read(val.buffer, 0x36<<1, false, 23, 4)
val = await client.readInputRegisters(0x100, 2)
// total active electricity power in kWh
const tot_act = ieee754.read(val.buffer, 0x00, false, 23, 4)
val = await client.readInputRegisters(0x400, 2)
// total reactive electricity power in kVArh
const tot_react = ieee754.read(val.buffer, 0x00, false, 23, 4)
return {
baud, parity, address, relay,
av, bv, cv, ac, bc, cc,
tot_ap, a_ap, b_ap, c_ap,
tot_rp, a_rp, b_rp, c_rp,
apf, bpf, cpf, freq,
tot_act, tot_react
}
} catch(e){
// if error return -1
return -1
}
}
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
// start get value
getMetersValue(metersIdList)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment