modbus-serial
Advanced tools
Comparing version 3.7.1 to 4.0.0
{ | ||
"name": "modbus-serial", | ||
"version": "3.7.1", | ||
"version": "4.0.0", | ||
"description": "A pure JavaScript implemetation of MODBUS-RTU (and TCP) for NodeJS.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha" | ||
"test": "mocha --recursive" | ||
}, | ||
@@ -29,4 +29,5 @@ "repository": { | ||
"chai": "^3.4.0", | ||
"mocha": "^2.3.3" | ||
"mocha": "^2.3.3", | ||
"mockery": "^1.4.0" | ||
} | ||
} |
@@ -7,21 +7,5 @@ 'use strict'; | ||
var crc16 = require('./../utils/crc16'); | ||
var calculateLrc = require('./../utils/lrc'); | ||
/** | ||
* calculate lrc | ||
* | ||
* @param {Buffer} buf the buffer to to lrc on. | ||
* @return {number} the calculated lrc | ||
*/ | ||
function calculateLrc (buf) { | ||
var length = buf.length - 2; | ||
var lrc = 0; | ||
for (var i = 0; i < length; i++) { | ||
lrc += buf[i] & 0xFF; | ||
} | ||
return ((lrc ^ 0xFF) + 1) & 0xFF; | ||
} | ||
/** | ||
* Ascii encode a 'request' buffer and return it. This includes removing | ||
@@ -36,3 +20,3 @@ * the CRC bytes and replacing them with an LRC. | ||
// replace the 2 byte crc16 with a single byte lrc | ||
buf.writeUInt8(calculateLrc(buf), buf.length-2); | ||
buf.writeUInt8(calculateLrc(buf.slice(0, -2)), buf.length-2); | ||
@@ -73,3 +57,3 @@ // create a new buffer of the correct size | ||
var lrcIn = bufDecoded.readUInt8(bufDecoded.length - 2); | ||
if( calculateLrc(bufDecoded) != lrcIn ) { | ||
if( calculateLrc(bufDecoded.slice(0, -2)) != lrcIn ) { | ||
// return null if lrc error | ||
@@ -76,0 +60,0 @@ return null; |
@@ -16,2 +16,3 @@ 'use strict'; | ||
* 4 - a modbus slave that answer with bad unit number | ||
* 5 - a modbus slave that answer with an exception | ||
*/ | ||
@@ -26,3 +27,3 @@ var TestPort = function() { | ||
// simulate 16 coils / digital inputs | ||
this._coils = 0x0000; | ||
this._coils = 0x0000; // TODO 0xa12b, 1010 0001 0010 1011 | ||
@@ -241,2 +242,8 @@ events.call(this); | ||
break; | ||
case 5: | ||
// unit 5: answers with exception | ||
buffer.writeUInt8(functionCode + 128, 1); | ||
buffer.writeUInt8(4, 2); | ||
buffer = buffer.slice(0, 5); | ||
break; | ||
} | ||
@@ -243,0 +250,0 @@ |
391
test/test.js
@@ -11,239 +11,302 @@ 'use strict'; | ||
describe('#open() - open serial port.', function () { | ||
it('should open the port without errors', function (done) { | ||
modbusRTU.open(function(err) { | ||
expect(err).to.be.a('null'); | ||
describe('#open() - open serial port.', function () { | ||
it('should open the port without errors', function (done) { | ||
modbusRTU.open(function(err) { | ||
expect(err).to.be.a('null'); | ||
done(); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC3() - read holding registers.', function () { | ||
it('should read 3 registers [0xa12b, 0xffff, 0xb21a] without errors', function (done) { | ||
modbusRTU.writeFC3(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data').with.length(3); | ||
expect(data.data.toString()).to.equal([0xa12b, 0xffff, 0xb21a].toString()); | ||
describe('#writeFC3() - read holding registers.', function () { | ||
it('should read 3 registers [0xa12b, 0xffff, 0xb21a] without errors', function (done) { | ||
modbusRTU.writeFC3(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data').with.length(3); | ||
expect(data.data.toString()).to.equal([0xa12b, 0xffff, 0xb21a].toString()); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should read raw buffer "a12bffffb21a" without errors', function (done) { | ||
modbusRTU.writeFC3(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('buffer'); | ||
expect(data.buffer.toString('hex')).to.equal("a12bffffb21a"); | ||
it('should read raw buffer "a12bffffb21a" without errors', function (done) { | ||
modbusRTU.writeFC3(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('buffer'); | ||
expect(data.buffer.toString('hex')).to.equal("a12bffffb21a"); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC4() - read input registers.', function () { | ||
it('should read 3 registers [8, 9, 10] without errors', function (done) { | ||
modbusRTU.writeFC4(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data').with.length(3); | ||
expect(data.data.toString()).to.equal([8, 9, 10].toString()); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC3(2, 8, 3, function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC4(2, 8, 1, function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC3(3, 8, 3, function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC4(3, 8, 1, function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
it('should fail on unexpected reply', function (done) { | ||
modbusRTU.writeFC3(4, 8, 3, function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on unexpected replay', function (done) { | ||
modbusRTU.writeFC4(4, 8, 1, function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
it('should fail with an exception', function(done) { | ||
modbusRTU.writeFC3(5, 8, 3, function(err, data) { | ||
expect(err).to.have.string('Modbus exception'); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC6() - write single holding register.', function () { | ||
it('should write to register 1 42 without errors', function (done) { | ||
modbusRTU.writeFC6(1, 1, 42, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data.address).to.equal(1); | ||
expect(data.value).to.equal(42); | ||
describe('#writeFC4() - read input registers.', function () { | ||
it('should read 3 registers [8, 9, 10] without errors', function (done) { | ||
modbusRTU.writeFC4(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data').with.length(3); | ||
expect(data.data.toString()).to.equal([8, 9, 10].toString()); | ||
done() | ||
}); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC6(2, 1, 42, function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC4(2, 8, 1, function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
done() | ||
}); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC6(3, 1, 42, function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC4(3, 8, 1, function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
done() | ||
}); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on unexpected replay', function (done) { | ||
modbusRTU.writeFC6(4, 1, 42, function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
it('should fail on unexpected reply', function (done) { | ||
modbusRTU.writeFC4(4, 8, 1, function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
done() | ||
}); | ||
}); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
describe('#writeFC15() - force multiple coils.', function () { | ||
it('should write 3 coils [true, false, true] without errors', function (done) { | ||
modbusRTU.writeFC15(1, 8, [true, false, true], function(err, data) { | ||
expect(err).to.be.a('null'); | ||
it('should fail with an exception', function(done) { | ||
modbusRTU.writeFC4(5, 8, 3, function(err, data) { | ||
expect(err).to.have.string('Modbus exception'); | ||
done() | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC15(2, 8, [true, false, true], function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
describe('#writeFC6() - write single holding register.', function () { | ||
it('should write to register 1 42 without errors', function (done) { | ||
modbusRTU.writeFC6(1, 1, 42, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data.address).to.equal(1); | ||
expect(data.value).to.equal(42); | ||
done() | ||
}); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC15(3, 8, [true, false, true], function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC6(2, 1, 42, function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
done() | ||
}); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on unexpected replay', function (done) { | ||
modbusRTU.writeFC15(4, 8, [true, false, true], function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC6(3, 1, 42, function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
done() | ||
}); | ||
}); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
describe('#writeFC1() - read coils after force multiple coils.', function () { | ||
it('should read coil 8, 9 ,10 to be true, false, true', function (done) { | ||
modbusRTU.writeFC1(1, 8, 4, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data'); | ||
expect(data.data[0]).to.equal(true); | ||
expect(data.data[1]).to.equal(false); | ||
expect(data.data[2]).to.equal(true); | ||
it('should fail on unexpected reply', function (done) { | ||
modbusRTU.writeFC6(4, 1, 42, function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC16() - write holding registers.', function () { | ||
it('should write 3 registers [42, 128, 5] without errors', function (done) { | ||
modbusRTU.writeFC16(1, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.be.a('null'); | ||
done() | ||
it('should fail with an exception', function(done) { | ||
modbusRTU.writeFC6(5, 1, 42, function(err, data) { | ||
expect(err).to.have.string('Modbus exception'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC16(2, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
describe('#writeFC15() - force multiple coils.', function () { | ||
it('should write 3 coils [true, false, true] without errors', function (done) { | ||
modbusRTU.writeFC15(1, 8, [true, false, true], function(err, data) { | ||
expect(err).to.be.a('null'); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC15(2, 8, [true, false, true], function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC15(3, 8, [true, false, true], function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on unexpected reply', function (done) { | ||
modbusRTU.writeFC15(4, 8, [true, false, true], function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail with an exception', function(done) { | ||
modbusRTU.writeFC15(5, 8, [true, false, true], function(err, data) { | ||
expect(err).to.have.string('Modbus exception'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC16(3, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
describe('#writeFC1() - read coils after force multiple coils.', function () { | ||
it('should read coil 8, 9 ,10 to be true, false, true', function (done) { | ||
modbusRTU.writeFC1(1, 8, 4, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data'); | ||
expect(data.data[0]).to.equal(true); | ||
expect(data.data[1]).to.equal(false); | ||
expect(data.data[2]).to.equal(true); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on unexpected replay', function (done) { | ||
modbusRTU.writeFC16(4, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
describe('#writeFC16() - write holding registers.', function () { | ||
it('should write 3 registers [42, 128, 5] without errors', function (done) { | ||
modbusRTU.writeFC16(1, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.be.a('null'); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
it('should fail on short data answer', function (done) { | ||
modbusRTU.writeFC16(2, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.have.string('Data length error'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on CRC error', function (done) { | ||
modbusRTU.writeFC16(3, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.have.string('CRC error'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on unexpected reply', function (done) { | ||
modbusRTU.writeFC16(4, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.have.string('Unexpected data error'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail with an exception', function(done) { | ||
modbusRTU.writeFC16(5, 8, [42, 128, 5], function(err, data) { | ||
expect(err).to.have.string('Modbus exception'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC3() - read holding registers after write.', function () { | ||
it('should read 3 registers [42, 128, 5] without errors', function (done) { | ||
modbusRTU.writeFC3(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data').with.length(3); | ||
expect(data.data.toString()).to.equal([42, 128, 5].toString()); | ||
describe('#writeFC3() - read holding registers after write.', function () { | ||
it('should read 3 registers [42, 128, 5] without errors', function (done) { | ||
modbusRTU.writeFC3(1, 8, 3, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data').with.length(3); | ||
expect(data.data.toString()).to.equal([42, 128, 5].toString()); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC5() - force one coil.', function () { | ||
it('should force coil 3 to be true, without errors', function (done) { | ||
modbusRTU.writeFC5(1, 3, true, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('state'); | ||
expect(data.state).to.equal(true); | ||
describe('#writeFC5() - force one coil.', function () { | ||
it('should force coil 3 to be true, without errors', function (done) { | ||
modbusRTU.writeFC5(1, 3, true, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('state'); | ||
expect(data.state).to.equal(true); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC1() - read coils after force coil.', function () { | ||
it('should read coil 3 to be true, without errors', function (done) { | ||
modbusRTU.writeFC1(1, 3, 9, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data'); | ||
expect(data.data[0]).to.equal(true); | ||
expect(data.data[3]).to.equal(false); | ||
describe('#writeFC1() - read coils after force coil.', function () { | ||
it('should read coil 3 to be true, without errors', function (done) { | ||
modbusRTU.writeFC1(1, 3, 9, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data'); | ||
expect(data.data[0]).to.equal(true); | ||
expect(data.data[3]).to.equal(false); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('#writeFC1() - read inputs.', function () { | ||
it('should read input 0 to be false, without errors', function (done) { | ||
modbusRTU.writeFC1(1, 0, 9, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data'); | ||
expect(data.data[0]).to.equal(false); | ||
expect(data.data[3]).to.equal(true); | ||
describe('#writeFC1() - read inputs.', function () { | ||
it('should read input 0 to be false, without errors', function (done) { | ||
modbusRTU.writeFC1(1, 0, 9, function(err, data) { | ||
expect(err).to.be.a('null'); | ||
expect(data).to.have.property('data'); | ||
expect(data.data[0]).to.equal(false); | ||
expect(data.data[3]).to.equal(true); | ||
done() | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -8,5 +8,5 @@ 'use strict'; | ||
*/ | ||
module.exports = function (buffer) { | ||
module.exports = function crc16(buffer) { | ||
var crc = 0xFFFF; | ||
var tmp; | ||
var odd; | ||
@@ -17,5 +17,5 @@ for (var i = 0; i < buffer.length; i++) { | ||
for (var j = 0; j < 8; j++) { | ||
tmp = crc & 0x0001; | ||
odd = crc & 0x0001; | ||
crc = crc >> 1; | ||
if (tmp) { | ||
if (odd) { | ||
crc = crc ^ 0xA001; | ||
@@ -22,0 +22,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112932
38
2619
3