Initial commit

This commit is contained in:
2018-09-15 01:04:38 +08:00
commit f0d0f92fb4
72 changed files with 11246 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 1;
let init = () => {
this.log.debug('initiating read coils request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
this.log.debug('handling read coils request.');
if (pdu.length !== 5) {
cb(Put().word8(0x81).word8(0x02).buffer());
} else {
const fc = pdu.readUInt8(0);
const address = pdu.readUInt16BE(1);
const byteAddress = address * 2;
const value = pdu.readUInt16BE(3);
this.emit('preWriteSingleRegisterRequest', byteAddress, value);
let mem = this.getHolding();
if (byteAddress + 2 > mem.length) {
cb(Put().word8(0x86).word8(0x02).buffer());
} else {
let response = Put().word8(0x06).word16be(address).word16be(value).buffer();
mem.writeUInt16BE(value, byteAddress);
this.emit('postWriteSingleRegisterRequest', byteAddress, value);
cb(response);
}
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});

View File

@@ -0,0 +1,69 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 2;
let init = () => {
this.log.debug('initiating read discrete inputs request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
this.log.debug('handling read discrete inputs request.');
if (pdu.length !== 5) {
cb(Put().word8(0x82).word8(0x02).buffer());
} else {
const fc = pdu.readUInt8(0);
const start = pdu.readUInt16BE(1);
const quantity = pdu.readUInt16BE( 3);
this.emit('readDiscreteInputsRequest', start, quantity);
let mem = this.getDiscrete();
if (!quantity || start + quantity > mem.length * 8) {
cb(Put().word8(0x82).word8(0x02).buffer());
} else {
let val = 0;
let thisByteBitCount = 0;
let response = Put().word8(0x02).word8(Math.floor(quantity / 8) + (quantity % 8 === 0 ? 0 : 1));
for (let totalBitCount = start; totalBitCount < start + quantity; totalBitCount += 1) {
let buf = mem.readUInt8(Math.floor(totalBitCount / 8));
let mask = 1 << (totalBitCount % 8);
if (buf & mask) {
val += 1 << (thisByteBitCount % 8)
}
thisByteBitCount += 1;
if (thisByteBitCount % 8 === 0 || totalBitCount === (start + quantity) - 1) {
response.word8(val);
val = 0;
}
}
cb(response.buffer());
}
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});

View File

@@ -0,0 +1,55 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 3;
let init = () => {
this.log.debug('initiating read holding registers request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
if (pdu.length !== 5) {
this.log.warn('wrong pdu length.');
cb(Put().word8(0x83).word8(0x02).buffer());
} else {
const fc = pdu.readUInt8(0);
const start = pdu.readUInt16BE(1);
const byteStart = start * 2;
const quantity = pdu.readUInt16BE(3);
this.emit('readHoldingRegistersRequest', byteStart, quantity);
let mem = this.getHolding();
if (!quantity || byteStart + (quantity * 2) > mem.length) {
this.log.debug('request outside register boundaries.');
cb(Put().word8(0x83).word8(0x02).buffer());
return;
}
let response = Put().word8(0x03).word8(quantity * 2);
for (let i = byteStart; i < byteStart + (quantity * 2); i += 2) {
response.word16be(mem.readUInt16BE(i));
}
this.log.debug('finished read holding register request.');
cb(response.buffer());
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});

View File

@@ -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.log.debug('initiating read input registers request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
this.log.debug('handling read input registers request.');
if (pdu.length !== 5) {
cb(Put().word8(0x84).word8(0x02).buffer());
} else {
const fc = pdu.readUInt8(0);
const start = pdu.readUInt16BE(1);
const byteStart = start * 2;
const quantity = pdu.readUInt16BE(3);
this.emit('readInputRegistersRequest', byteStart, quantity);
let mem = this.getInput();
if (!quantity || byteStart + (quantity * 2) > mem.length) {
cb(Put().word8(0x84).word8(0x02).buffer());
} else {
let response = Put().word8(0x04).word8(quantity * 2);
for (let i = byteStart; i < byteStart + (quantity * 2); i += 2) {
response.word16be(mem.readUInt16BE(i));
}
cb(response.buffer());
}
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});

View File

@@ -0,0 +1,77 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 15;
let init = () => {
this.log.debug('initiating write multiple coils request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
this.log.debug('handling write multiple coils request.');
if (pdu.length < 3) {
cb(Put().word8(0x8F).word8(0x02).buffer());
} else {
// const fc = pdu.readUInt8(0);
const start = pdu.readUInt16BE(1);
const quantity = pdu.readUInt16BE(3);
const byteCount = pdu.readUInt8(5);
this.emit('preWriteMultipleCoilsRequest', start, quantity, byteCount);
let mem = this.getCoils();
// error response
if (!quantity || start + quantity > mem.length * 8) {
cb(Put().word8(0x8F).word8(0x02).buffer());
} else {
let response = Put().word8(0x0F).word16be(start).word16be(quantity).buffer();
let oldValue;
let newValue, current = pdu.readUInt8(6);
let j = 0;
for (let i = start; i < start + quantity; i += 1) {
// reading old value from the coils register
oldValue = mem.readUInt8(Math.floor(i / 8));
// apply new value
if ((Math.pow(2, j % 8) & current)) {
newValue = oldValue | Math.pow(2, i % 8);
} else {
newValue = oldValue & ~Math.pow(2, i % 8);
}
// write to buffer
mem.writeUInt8(newValue, Math.floor(i / 8));
// read new value from request pdu
j += 1;
if (j % 8 === 0 && j < quantity) {
current = pdu.readUInt8(6 + Math.floor(j / 8));
}
}
this.emit('postWriteMultipleCoilsRequest', start, quantity, byteCount);
cb(response);
}
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});

View File

@@ -0,0 +1,60 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 16;
let init = () => {
this.log.debug('initiating write multiple registers request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
if (pdu.length < 3) {
cb(Put().word8(0x90).word8(0x02).buffer());
} else {
// const fc = pdu.readUInt8(0);
const start = pdu.readUInt16BE(1);
const byteStart = start * 2;
const quantity = pdu.readUInt16BE(3);
const byteCount = pdu.readUInt8(5);
if (quantity > 0x007b) {
cb(Put().word8(0x90).word8(0x03).buffer());
} else {
this.emit('preWriteMultipleRegistersRequest', byteStart, quantity, byteCount);
let mem = this.getHolding();
if (!quantity || byteStart + (quantity * 2) > mem.length) {
cb(Put().word8(0x90).word8(0x02).buffer());
} else {
let response = Put().word8(0x10).word16be(start).word16be(quantity).buffer();
let j = 0;
for (let i = byteStart; i < byteStart + byteCount; i += 1) {
mem.writeUInt8(pdu.readUInt8(6 + j), i);
j++;
}
this.emit('postWriteMultipleRegistersRequest', byteStart, quantity, byteCount);
cb(response);
}
}
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});

View File

@@ -0,0 +1,62 @@
'use strict';
const Stampit = require('stampit');
const Put = require('put');
module.exports = Stampit()
.init(function () {
const FC = 5;
let init = () => {
this.log.debug('initiating write single coil request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
if (pdu.length !== 5) {
cb(Put().word8(0x85).word8(0x02).buffer());
} else {
// const fc = pdu.readUInt8(0);
const address = pdu.readUInt16BE(1);
const value = (pdu.readUInt16BE(3) === 0x0000);
if (pdu.readUInt16BE(3) !== 0x0000 && pdu.readUInt16BE(3) !== 0xFF00) {
cb(Put().word8(0x85).word8(0x03).buffer());
} else {
this.emit('preWriteSingleCoilRequest', address, value);
let mem = this.getCoils();
if (address + 1 > mem.length * 8) {
cb(Put().word8(0x85).word8(0x02).buffer());
} else {
let response = Put().word8(0x05).word16be(address).word16be(value ? 0xFF00 : 0x0000);
let oldValue = mem.readUInt8(Math.floor(address / 8));
let newValue;
if (value) {
newValue = oldValue | Math.pow(2, address % 8);
} else {
newValue = oldValue & ~Math.pow(2, address % 8);
}
mem.writeUInt8(newValue, Math.floor(address / 8));
this.emit('postWriteSingleCoilRequest', address, value);
cb(response.buffer());
}
}
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});

View File

@@ -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.log.debug('initiating write single register request handler.');
this.responseDelay = this.responseDelay || 0;
this.setRequestHandler(FC, onRequest);
};
let _onRequest = (pdu, cb) => {
this.log.debug('handling write single register request.');
if (pdu.length !== 5) {
cb(Put().word8(0x86).word8(0x02).buffer());
} else {
// const fc = pdu.readUInt8(0);
const address = pdu.readUInt16BE(1);
const byteAddress = address * 2;
const value = pdu.readUInt16BE(3);
this.emit('preWriteSingleRegisterRequest', byteAddress, value);
let mem = this.getHolding();
if (byteAddress + 2 > mem.length) {
cb(Put().word8(0x86).word8(0x02).buffer());
} else {
let response = Put().word8(0x06).word16be(address).word16be(value).buffer();
mem.writeUInt16BE(value, byteAddress);
this.emit('postWriteSingleRegisterRequest', byteAddress, value);
cb(response);
}
}
};
let onRequest = (pdu, cb) => {
if (this.responseDelay) {
setTimeout(_onRequest, this.responseDelay, pdu, cb);
} else {
setImmediate(_onRequest, pdu, cb);
}
};
init();
});