jsmodebus

This commit is contained in:
2019-01-16 12:38:53 +08:00
parent 36025dac53
commit 935d418fe3
25 changed files with 2079 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 1;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
let fc = pdu.readUInt8(0);
if (fc !== FC) {
cb(`ReadCoils: Invalid FC ${fc}`);
} else {
let byteCount = pdu.readUInt8(1);
// let bitCount = byteCount * 8;
let resp = {
unitId,
fc: fc,
byteCount: byteCount,
payload: pdu.slice(2),
data: []
};
let counter = 0;
for (let i = 0; i < byteCount; i+=1) {
let h = 1, cur = pdu.readUInt8(2 + i);
for (let j = 0; j < 8; j++) {
resp.data[counter] = (cur & h) > 0 ;
h = h << 1;
counter += 1;
}
}
cb && cb(null, resp);
}
};
this.readCoils = (unitId, start, quantity) => {
return new Promise((resolve, reject) => {
let pdu = Put().word8(FC).word16be(start).word16be(quantity).buffer();
this.queueRequest(unitId, FC, pdu, (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});
@@ -0,0 +1,62 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 2;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
let fc = pdu.readUInt8(0);
if (fc !== FC) {
cb(`ReadDiscreteInputs: Invalid FC ${fc}`);
} else {
let byteCount = pdu.readUInt8(1);
let counter = 0;
let resp = {
unitId,
fc: fc,
byteCount: byteCount,
payload: pdu.slice(2),
data: []
};
for (let i = 0; i < byteCount; i++) {
let h = 1, cur = pdu.readUInt8(2 + i);
for (let j = 0; j < 8; j+=1) {
resp.data[counter] = (cur & h) > 0 ;
h = h << 1;
counter += 1;
}
}
cb && cb(null, resp);
}
};
this.readDiscreteInputs = (unitId, start, quantity) => {
return new Promise((resolve, reject) => {
if (quantity > 2000) {
return reject('quantity is too big');
}
let pdu = Put().word8be(FC).word16be(start).word16be(quantity).buffer();
this.queueRequest(unitId, FC, pdu, (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});
@@ -0,0 +1,52 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 3;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
let fc = pdu.readUInt8(0);
if (fc !== FC) {
cb(`ReadHoldingRegisters: Invalid FC ${fc}`);
} else {
let byteCount = pdu.readUInt8(1);
let resp = {
unitId,
fc: fc,
byteCount: byteCount,
payload: pdu.slice(2),
register: []
};
const registerCount = byteCount / 2;
for (let i = 0; i < registerCount; i++) {
resp.register.push(pdu.readUInt16BE(2 + (i * 2)));
}
cb && cb(null, resp);
}
};
this.readHoldingRegisters = (unitId, start, quantity) => {
return new Promise((resolve, reject) => {
let pdu = Put().word8be(FC).word16be(start).word16be(quantity).buffer();
this.queueRequest(unitId, FC, pdu, (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});
@@ -0,0 +1,52 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 4;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
let fc = pdu.readUInt8(0);
if (fc !== FC) {
cb(`ReadInputRegisters: Invalid FC ${fc}`);
} else {
let byteCount = pdu.readUInt8(1);
let resp = {
unitId,
fc: fc,
byteCount: byteCount,
payload: pdu.slice(2),
register: []
};
const registerCount = byteCount / 2;
for (let i = 0; i < registerCount; i++) {
resp.register.push(pdu.readUInt16BE(2 + (i * 2)));
}
cb && cb(null, resp);
}
};
this.readInputRegisters = (unitId, start, quantity) => {
return new Promise((resolve, reject) => {
let pdu = Put().word8be(FC).word16be(start).word16be(quantity).buffer();
this.queueRequest(unitId, FC, pdu, (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});
@@ -0,0 +1,73 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 15;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
const fc = pdu.readUInt8(0);
const startAddress = pdu.readUInt16BE(1);
const quantity = pdu.readUInt16BE(3);
let resp = {
unitId: unitId,
fc: fc,
startAddress: startAddress,
quantity: quantity
};
if (fc !== FC) {
cb(`WriteMultipleCoils: Invalid FC ${fc}`);
} else {
cb(null, resp);
}
};
this.writeMultipleCoils = (unitId, startAddress, data, N) => {
return new Promise((resolve, reject) => {
let pdu = Put().word8(FC).word16be(startAddress);
if (data instanceof Buffer) {
pdu.word16be(N).word8(data.length).put(data);
} else if (data instanceof Array) {
if (data.length > 1968) {
reject('Length is too big');
return;
}
const byteCount = Math.ceil(data.length / 8);
let curByte = 0;
let cntr = 0;
pdu.word16be(data.length).word8(byteCount);
for (let i = 0; i < data.length; i += 1) {
curByte += data[i] ? Math.pow(2, cntr) : 0;
cntr = (cntr + 1) % 8;
if (cntr === 0 || i === coils.length - 1 ) {
pdu.word8(curByte);
curByte = 0;
}
}
}
this.queueRequest(unitId, FC, pdu.buffer(), (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});
@@ -0,0 +1,71 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 16;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
const fc = pdu.readUInt8(0);
if (fc !== FC) {
cb(`WriteMultipleRegisters: Invalid FC ${fc}`);
} else {
const startAddress = pdu.readUInt16BE(1);
const quantity = pdu.readUInt16BE(3);
let resp = {
unitId: unitId,
fc: fc,
startAddress: startAddress,
quantity: quantity
};
cb(null, resp);
}
};
this.writeMultipleRegisters = (unitId, startAddress, data) => {
return new Promise((resolve, reject) => {
let pdu = Put().word8(FC).word16be(startAddress);
if (data instanceof Buffer) {
if (data.length / 2 > 0x007b) {
reject('Length is too big');
return;
}
pdu.word16be(data.length / 2).word8(data.length).put(data);
} else if (data instanceof Array) {
if (data.length > 0x007b) {
reject('Length is too big');
return;
}
let byteCount = Math.ceil(data.length * 2);
pdu.word16be(data.length).word8(byteCount);
for (let i = 0; i < data.length; i += 1) {
pdu.word16be(data[i]);
}
} else {
reject('Invalid data');
return;
}
this.queueRequest(unitId, FC, pdu.buffer(), (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});
@@ -0,0 +1,47 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 5;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
const fc = pdu.readUInt8(0);
const outputAddress = pdu.readUInt16BE(1);
const outputValue = pdu.readUInt16BE(3);
let resp = {
unitId: unitId,
fc: fc,
outputAddress: outputAddress,
outputValue: outputValue === 0x0000 ? false : (outputValue === 0xFF00 ? true : undefined)
};
if (fc !== FC) {
cb(`WriteSingleCoil: Invalid FC ${fc}`);
} else {
cb(null, resp);
}
};
this.writeSingleCoil = (unitId, address, value) => {
return new Promise((resolve, reject) => {
const payload = (value instanceof Buffer) ? (value.readUInt8(0) > 0) : value;
const pdu = Put().word8be(FC).word16be(address).word16be(payload ? 0xff00 : 0x0000);
this.queueRequest(unitId, FC, pdu.buffer(), (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});
@@ -0,0 +1,50 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 6;
let init = () => this.addResponseHandler(FC, onResponse);
let onResponse = (unitId, pdu, cb) => {
const fc = pdu.readUInt8(0);
const registerAddress = pdu.readUInt16BE(1);
const registerValue = pdu.readUInt16BE(3);
let resp = {
unitId: unitId,
fc: fc,
registerAddress: registerAddress,
registerValue: registerValue,
registerAddressRaw: pdu.slice(1,2),
registerValueRaw: pdu.slice(3,2)
};
if (fc !== FC) {
cb(`WriteSingleRegister: Invalid FC ${fc}`);
} else {
cb(null, resp);
}
};
this.writeSingleRegister = (unitId, address, value) => {
return new Promise((resolve, reject) => {
const payload = (value instanceof Buffer) ? value : Put().word16be(value).buffer();
const pdu = Put().word8be(FC).word16be(address).put(payload);
this.queueRequest(unitId, FC, pdu.buffer(), (err, resp) => {
if (err) {
reject(err);
} else {
resolve(resp);
}
});
});
};
init();
});