cloud-automation / node-modbus Goto Github PK
View Code? Open in Web Editor NEWModbus TCP Client/Server implementation for Node.JS
Modbus TCP Client/Server implementation for Node.JS
I've tested in linux and windows that if you just fresh install jsmodule it has some compatiblity issues with [email protected]
So it you run the example from its location, it behaves correctly because within jsmodbus/node_modules dir the older version of [email protected] is copied.
However if you just try to run the example outside of the jsmodbus (as it should be) it takes the reference of the project dir/node_modules, where the npm install process puts the latest version of stampit...
It might be a bug... Anyway thanks for your efforts
...but all tests in modbus-client-core.test.js pass.
I am running Ubuntu 14.04 LTS with node v0.10.25 and npm 1.3.10.
I am thinking the version of node might be too low but as this is an industrial unit we can't change it.
Modbus Server Core Tests.
Exception Tests.
1) should answer with 0x8x status code due to missing handler.
Read Coils Tests.
2) should handle a read coils request just fine.
3) should handle a read coils request with a start address outside the address space.
4) should handle a read coils request with a quantity value outside the address space.
Read Discrete Inputs Tests.
5) should handle a read discrete inputs request just fine.
6) should handle a read discrete inputs request with a start address outside the address space.
7) should handle a read discrete inputs request with a quantity value outside the address space.
Read Holding Registers Tests.
8) should handle a read holding registers request just fine.
9) should handle a read holding registers request with a start address outside the address space.
10) should handle a read holding registers request with a quantity value outside the address space.
Read Input Registers Tests.
11) should handle a read input registers request just fine.
12) should handle a read input registers request with a start address outside the address space.
13) should handle a read input registers request with a quantity value outside the address space.
Write Single Coil Tests.
14) should handle a write single coil request just fine.
15) should handle a write single coil request with a start address outside the address space.
16) should handle a write single coil request with a another value than 0x0000 (false) and 0xff00 (true).
Write Single Register Tests.
17) should handle a write single register request just fine.
18) should handle a write single register request with a start address outside the address space.
Write Multiple Coils Tests.
19) should handle a write multiple coils request just fine.
20) should handle a write multiple coils request with a start address outside the address space.
21) should handle a write multiple coils request with a start and quantity outside the address space.
Write Multiple Registers Tests.
22) should handle a write multiple registers request just fine.
23) should handle a write multiple registers request with a start address outside the address space.
24) should handle a write multiple registers request with a start and quantity outside the address space.
25) should handle a write multiple registers request with a quantity greater 0x007b.
0 passing (324ms)
25 failing
1) Modbus Server Core Tests. Exception Tests. should answer with 0x8x status code due to missing handler.:
TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:22:39)
at Object.<anonymous> (src/modbus-server-core.js:51:17)
at Context.<anonymous> (test/modbus-server-core.test.js:28:18)
2) Modbus Server Core Tests. Read Coils Tests. should handle a read coils request just fine.:
Uncaught TypeError: Object ��� has no method 'compare'
at resp (test/modbus-server-core.test.js:49:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadCoils.js:69:17)
3) Modbus Server Core Tests. Read Coils Tests. should handle a read coils request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:67:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadCoils.js:44:21)
4) Modbus Server Core Tests. Read Coils Tests. should handle a read coils request with a quantity value outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:85:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadCoils.js:44:21)
5) Modbus Server Core Tests. Read Discrete Inputs Tests. should handle a read discrete inputs request just fine.:
Uncaught TypeError: Object ��� has no method 'compare'
at resp (test/modbus-server-core.test.js:112:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadDiscreteInputs.js:69:17)
6) Modbus Server Core Tests. Read Discrete Inputs Tests. should handle a read discrete inputs request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:130:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadDiscreteInputs.js:44:21)
7) Modbus Server Core Tests. Read Discrete Inputs Tests. should handle a read discrete inputs request with a quantity value outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:148:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadDiscreteInputs.js:44:21)
8) Modbus Server Core Tests. Read Holding Registers Tests. should handle a read holding registers request just fine.:
Uncaught TypeError: Object �
���� has no method 'compare'
at resp (test/modbus-server-core.test.js:178:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadHoldingRegisters.js:62:17)
9) Modbus Server Core Tests. Read Holding Registers Tests. should handle a read holding registers request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:196:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadHoldingRegisters.js:47:21)
10) Modbus Server Core Tests. Read Holding Registers Tests. should handle a read holding registers request with a quantity value outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:214:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadHoldingRegisters.js:47:21)
11) Modbus Server Core Tests. Read Input Registers Tests. should handle a read input registers request just fine.:
Uncaught TypeError: Object �
���� has no method 'compare'
at resp (test/modbus-server-core.test.js:245:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadInputRegisters.js:57:17)
12) Modbus Server Core Tests. Read Input Registers Tests. should handle a read input registers request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:263:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadInputRegisters.js:44:21)
13) Modbus Server Core Tests. Read Input Registers Tests. should handle a read input registers request with a quantity value outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:281:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/ReadInputRegisters.js:44:21)
14) Modbus Server Core Tests. Write Single Coil Tests. should handle a write single coil request just fine.:
Uncaught TypeError: Object� has no method 'compare'
at resp (test/modbus-server-core.test.js:307:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteSingleCoil.js:69:17)
15) Modbus Server Core Tests. Write Single Coil Tests. should handle a write single coil request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:326:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteSingleCoil.js:50:21)
16) Modbus Server Core Tests. Write Single Coil Tests. should handle a write single coil request with a another value than 0x0000 (false) and 0xff00 (true).:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:344:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteSingleCoil.js:39:21)
17) Modbus Server Core Tests. Write Single Register Tests. should handle a write single register request just fine.:
Uncaught TypeError: Object �# has no method 'compare'
at resp (test/modbus-server-core.test.js:373:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteSingleRegister.js:55:17)
18) Modbus Server Core Tests. Write Single Register Tests. should handle a write single register request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:392:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteSingleRegister.js:44:21)
19) Modbus Server Core Tests. Write Multiple Coils Tests. should handle a write multiple coils request just fine.:
Uncaught TypeError: Object
� has no method 'compare'
at resp (test/modbus-server-core.test.js:419:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteMultipleCoils.js:76:17)
20) Modbus Server Core Tests. Write Multiple Coils Tests. should handle a write multiple coils request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:438:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteMultipleCoils.js:44:21)
21) Modbus Server Core Tests. Write Multiple Coils Tests. should handle a write multiple coils request with a start and quantity outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:456:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteMultipleCoils.js:44:21)
22) Modbus Server Core Tests. Write Multiple Registers Tests. should handle a write multiple registers request just fine.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:498:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteMultipleRegisters.js:70:17)
23) Modbus Server Core Tests. Write Multiple Registers Tests. should handle a write multiple registers request with a start address outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:519:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteMultipleRegisters.js:52:21)
24) Modbus Server Core Tests. Write Multiple Registers Tests. should handle a write multiple registers request with a start and quantity outside the address space.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:537:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteMultipleRegisters.js:52:21)
25) Modbus Server Core Tests. Write Multiple Registers Tests. should handle a write multiple registers request with a quantity greater 0x007b.:
Uncaught TypeError: Object �� has no method 'compare'
at resp (test/modbus-server-core.test.js:555:39)
at Object.<anonymous> (src/modbus-server-core.js:59:17)
at Object.<anonymous> (src/handler/server/WriteMultipleRegisters.js:41:21)
When using serialport 2.x (the current version in package.json), I am getting multiple deprecation warnings :
(node) v8::ObjectTemplate::Set() with non-primitive values is deprecated
(node) and will stop working in the next major release.
==== JS stack trace =========================================
Security context: 0x1ac4aa5c9fa9 <JS Object>#0#
1: .node [module.js:568] [pc=0xaa688c9eae4] (this=0x21bbad9cc241 <an Object with map 0x9feb7d17e49>#1#,module=0x2d49ae1766d9 <a Module with map 0x9feb7d18421>#2#,filename=0x2d49ae1766a1 <String[87]: /Users/warren/Sites/telegauge/TG4/node_modules/serialport/build/Release/serialport.node>)
2: load [module.js:456] [pc=0xaa688c39152] (this=0x2d49ae1766d9 <a Module with map 0x9feb7d18421>#2#,filename=0x2d49ae1766a1 <String[87]: /Users/warren/Sites/telegauge/TG4/node_modules/serialport/build/Release/serialport.node>)
3: tryModuleLoad(aka tryModuleLoad) [module.js:415] [pc=0xaa688c38c7d] (this=0x1ac4aa504189 <undefined>,module=0x2d49ae1766d9 <a Module with map 0x9feb7d18421>#2#,filename=0x2d49ae1766a1 <String[87]: /Users/warren/Sites/telegauge/TG4/node_modules/serialport/build/Release/serialport.node>)
4: _load [module.js:407] [pc=0xaa688c348c2] (this=0x21bbad9cc0f9 <JS Function Module (SharedFunctionInfo 0x21bbad922dd1)>#3#,request=0x2d49ae175791 <String[87]: /Users/warren/Sites/telegauge/TG4/node_modules/serialport/build/Release/serialport.node>,parent=0x2d49ae166259 <a Module with map 0x9feb7d18421>#4#,isMain=0x1ac4aa504299 <false>)
992ae] (this=0x2d49ae15fde9 <an Object with map 0x3876ef007ac1>#6#,exports=0x2d49ae15fde9 <an Object with map 0x3876ef007ac1>#6#,require=0x2d49ae161479 <JS Function require (SharedFunctionInfo 0x21bbad953b41)>#7#,module=0x2d49ae15fd99 <a Module with map 0x9feb7d18421>#8#,__filename=0x2d49ae15fd61 <String[73]: /Users/warren/Sites/telegauge/TG4/node_modules/serialport/lib/bindings.js>,__dirname=0x2d49ae161411 <String[61]: /Users/warren/Sites/telegauge/TG4/node_modules/serialport/lib>)
9: _compile [module.js:541] [pc=0xaa688c41c24] (this=0x2d49ae15fd99 <a Module with map 0x9feb7d18421>#8#,content=0x2d49ae160a91 <String[784]\: 'use strict';\n\nvar bindings = require('bindings')('serialport.node');\nvar listUnix = require('./list-unix');\n\nvar linux = pr
==== C stack trace ===============================
1: v8::Template::Set(v8::Local<v8::Name>, v8::Local<v8::Data>, v8::PropertyAttribute)
2: SerialportPoller::Init(v8::Local<v8::Object>)
3: init
4: node::DLOpen(v8::FunctionCallbackInfo<v8::Value> const&)
5: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&))
6: v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::(anonymous namespace)::BuiltinArguments<(v8::internal::BuiltinExtraArguments)1>)
7: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
8: 0xaa688b0961b
I updated my local copy to use serialport 3, and the warnings are gone. I didn't run any tests, so maybe it just breaks everything, but there's errors on the horizon anyway, using the current module.
SUGGESTION: The jsmodbus client reading always has the result output to console. This needs to be suppressed as log() as applications would produce theirs own outputs.
This code should be change to log() instead of console.log().
// SerialClient.js - #255 - replace console.log() with log()
proto.promiseCallback = function (defer) {
var that = this;
return function (resp, err) {
log(JSON.stringify(argument)); // console.log(arguments);
if (err) {
defer.reject(err);
return;
}
defer.resolve(resp);
};
};
I tested the serial communication and got:
DEPRECATION: Please use require('serialport')
instead of require('serialport').SerialPort
Hello
trying examples for serial - not working
whats wrong?
var ModbusClient = require('jsmodbus'),
client = ModbusClient('/dev/ttyUSB0', 9600);
client.on('connect', function () {
client.writeSingleCoil(4, true).then(function (resp) {
console.log(resp);
}).fail(function (err) {
console.log(err);
}).done(function () {
client.close();
});
});
client.on('error', function (err) {
console.log(err);
});
got this:
TypeError: ModbusClient is not a function
when i change second to this:
client = ModbusClient.createSerialClient('/dev/ttyUSB0', 9600);
got this:
TypeError: ModbusClient.createSerialClient is not a function
please update examples?
My devices which are offline are not getting the "error" event.
It looks like you need to add this.emit('error')
in onSocketError
in modbus-tcp-client.js maybe?
Hello, I am a user of the node-red-contrib-modus. The developer told me that in his sources he's using the node-modbus and whenever I have a problem with modbus I should submit an issue here.
I have the following problem:
First I have today that I am using the node-red-contrib-modbus in Modbus RTU serial mode.
When I am issuing a simple "Read Holding register" at addresss 0 with 1 register length I see the node pushing the stream 0x01 0x03 0x00 0x00 0x00 0x01 0x00 0x05 to the serial line. (I have made it visible through an analyser). The point is that the checksum at the end is sent as 0x00 0x05, but this is wrong and
must be 0x84 0x0A.
Watchching the source source code I see the following code sequence, which tells me that the checksum is build by a simple addition...but this is not right.
for (var i = 0; i < buf.length; i += 1) {
crc = (buf.readUInt8(i) + crc) % 0xFFFF;
}
The checksum of Modbus RTU has to be build in accordance to the Modbus RTU spec with a real cyclic redundancy check and polynomial. See the spec here
http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
There are some Modbus RTU <=> TCP gateways in the world.
They just take serial RTU frame and send them via TCP (no MBAP header, but with CRC).
Is it possible to support it?
Hi! i'm getting data from a modbus device and negative temperatures show up in node.js application as 65413-something. I can fix it by manually post-processing the inputs like this:
var decode = function(x){
if(x>1000) x = x - 65536; //substract Math.pow(2,16)
return x;
}
but i wonder if node-modbus already supposed to interpret this correectly on reading the registers. the "two's complement" and so on...
Here is my device i'm reading from
http://www.comet-america.com/products/temperature-humidity-pressure-transmitters-and-regulators/web-sensor-p8641-with-poe-four-channels-remote-thermometer-hygrometer/reg-P8641#downloadd
in the instruction manual here page 22 there is a register map (I'm interested in int*10 values):
Hi,
you have some handling of PDU for TCP but not for Serial.
Result of testing ModbusRTU and ASCII: serial doesn't work in my case
The handling with endian isn't ready:
there is just ...BE for BIG-Endian in use and there is now way to use the ..LE for Little-Endian
Serial connection type is just RTU? could be ASCII or RTU
ASCII needs a SerialPort parser with line ending '\r\n' or 0x0d 0x0a or (10,13)LE / (13,10)BE
Serial doesn't work for PDU's with UnitID and/or split of PDU:
DEBUG : received data PDU: {"type":"Buffer","data":[1,3,2,0]}
DEBUG : received data PDU: {"type":"Buffer","data":[54,56,82]}
Serial-Source: 1,3,2,0,54,56,82
UnitID: 1
FC: 3
16BitBlocksToRead: 2
16BitBlock1-readLE: payload -> 54
16BitBlock2-readLE: CRC
[1,3,2,0] and [54,56,82] should be: [1,3,2,0,54,56,82]
[1] and [3,2,0,54,56,82] should be: [1,3,2,0,54,56,82]
[1] and [3,2,0,54] and [56,82] should be: [1,3,2,0,54,56,82]
[1,3,2] and [0,54] and [56,82] should be: [1,3,2,0,54,56,82]
[1,3,2,0,54,56] and [82] should be: [1,3,2,0,54,56,82]
UnitID (1), FC (1), ByteCount, Value (2), CRC (2)
If the serial raise often an exception on read:
2 Oct 22:38:37 - [red] Uncaught Exception:
2 Oct 22:38:37 - RangeError: index out of range -> ReadHoldingRegisters.js - Line 20
There seems to be an issue with writing multiple coils. I have tried it using jsmodbus client as well as another application.
Server always crashes with jsmodbus client, no matter number of coils.
With QModMaster application server crashes when number of coils exceeds 7.
Example code: https://github.com/bam-ftw/jsmodbus-write-multiple-coils-error
Hello:
First of all I want to tank you for develop this module, its so clear an easy to use
On the example in the read me are miss the close tokens for the function "});" but the real question is if the the "readHoldingRegister" function is implemented because I take a look in the library code and i could not find it.
client.readHoldingRegister(0, 10, function (reps, err) {
// resp will look like { fc: 3, byteCount: 20, register: [ values 0 - 10 ] }
console.log(err, resp);
This gets my attention because you put it in example and when I run the example get an error with that problem.
Thanks a lot in advance
C:\node server>node mod.js
C:\node server\node_modules\socket.io\node_modules\socket.io-client\node_modules
\engine.io-client\lib\transports\polling.js:23
var xhr = new XMLHttpRequest({ xdomain: false });
^
TypeError: object is not a function
at C:\node server\node_modules\socket.io\node_modules\socket.io-client\node_
modules\engine.io-client\lib\transports\polling.js:23:13
at Object. (C:\node server\node_modules\socket.io\node_modules\so
cket.io-client\node_modules\engine.io-client\lib\transports\polling.js:25:3)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (C:\node server\node_modules\socket.io\node_modules\so
cket.io-client\node_modules\engine.io-client\lib\transports\polling-xhr.js:6:15)
at Module._compile (module.js:460:26)
C:\node server>
The reason I ask I am looking into adding automation to a project I am working on. The application already has a node interface. All values are logged to SQLite. I need to decide between:
1 is the preferred option as it reduces the points of failure. It does requires a solid ModbusRTU implementation and the text for the project is Modbus TCP (no mention of Serial) and the serial-client code was only added a month ago.
The questions I have are:
const modbus = require('jsmodbus')
const client = modbus.client.tcp.complete({
host: 'JWLE-C45',
port: 502,
autoReconnect: true,
reconnectTimeout: 1000,
timeout: 5000,
unitId: 0
})
client.on('connect', () => {
client.writeSingleCoil(1, true).then(console.log).fail(console.log)
client.readCoils(1, 1).then(console.log).fail(console.log)
setTimeout(() => client.close(), 100)
})
client.on('error', console.log)
client.connect()
{ fc: 5, outputAddress: 1, outputValue: true }
{ fc: 1,
byteCount: 1,
coils: [ true, false, false, false, false, false, false, false ] }
I write into first coil value "true", and then return value with readCoils(1, 1). Returned value contains 8 values. Is this correct? Or only one value shod be returned.
Sorry, if this is stupid question.
Great library. Thank you.
This is not an issue really. I am trying to use your library to respond with illegal address error if the client request a modbus address that does not exist in the database. For example, the client makes a readHoldingRegistersRequest for modbus address 40001. I look up that address and find there is no tags tied to that address. How would I use your modbus server to respond with that error?
Thanks.
Using the latest release with the supplied test code I found that WriteMultipleCoils examples are not working...
client.writeMultipleCoils(3, [1, 0, 1, 0, 1, 1]).then(function (resp) {
console.log(resp);
}).fail(console.log);
client.writeMultipleCoils(3, new Buffer([0x2B]), 6).then(function (resp) {
console.log(resp);
}).fail(console.log);
These are copied from source
Regards
Using node-red-contrib-modbus which is based on "node-modbus" I have no chance today to send any serial request to an address other than 1. So whatever I do on the serial line I see always a value 0x01 as first byte sent to the serial line.
I went to the source code and in the current onSend function...
var onSend = function (pdu) {
var pkt = Put()
.word8(1)
.put(pdu),
buf = pkt.buffer();
... I see that the first byte is set to value 1 always. This shall be change to enable the possibility to sent to different slave addresses other than 1.
watch Modbus RTU spec here http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
I have been using jsModbus module for more than year in my smart home installation. It works perfectly and I would like to thank you very much for great job.
I am working on another project where I need to access modbus devices over Modbus RTU/ASCII. I haver RS-485 to USB adaptor and I curious is it possible to use/adapt your module to use it with serial port?
Due to common firewall issues then i propose to separate connection establishment from modbus. A client such as an IoT device may handle connection establishment to a cloud server, after a bit of chit chat device authentication and such) then the socket may be used for modbus by the node.js server which is now a client.
Are you sure that this module Util is required here?
https://github.com/Cloud-Automation/node-modbus/blob/master/src/modbus-client-core.js#L1
I cannot find any place, where it will be used.
It seems that there is a memory leak in jsmodbus module.
I have 16 modbus devices connected via TCP. Each device has 8 registers.
I wrote a simple test that reads all registers of all devices every 5 seconds.
For 40 minutes the heap grew from 36 to 436 Mb. See the picture attached.
Test application is attached.
After createTCPClient, can I close the connection(socket)?
Hi,
it seems like you changed your promise library from Q to bluebird. Unfortunately bluebird doesn't support the promise.then(successhandler).fail(failurehandler) syntax, which is used in the examples.
Updateing my code to promise.then(successhandler, failurehandler) solved my issues.
Kind regards,
Valentin
Hi,
can you show to me how to use your Modbus TCC module on web site?
With the following patch in file "modbus-serial-client.js" data can be received from a server after polling for data
var onData = function (pdu) {
this.log.debug('received data');
this.emit('data', pdu.slice(1));
The point is that every Modbus RTU response includes as first byte the slave address mirrored.
Before the patch the whole PDU as received has been handed over to the emitter. With the patch the PDU without the first byte is handed over.
I solved that problem with handling more than 1 holding registers separating the connection moment and modbus function moment.
But I have multiple connection failure (ip adresses offline), I think would receive connection refused message for every oflline IP adress, but it doesn't happens. For example, if I have 10 offline IPs, for some connections, I receive 'connection refused', then my system blocking waiting for the connection errors, then it comes as 'connection timeout'. But it take at least 20 seconds, doesnt matter how many IPs are offline (I didnt try with more than 30 IPs).
I think it's not the best way, but I did a tcp probe with the module tcp-ping (https://github.com/apaszke/tcp-ping) and then, if it checks the host is not available, it fired your onSocketError function. It's really faster than wait for the timeout event.
In modbus-client-tcp.js, I changed:
var TcpPing = require('tcp-ping')
//on the connect() function
// socket stuffs
var host = this.host;
var port = this.port;
TcpPing.probe(host, port, function (err, available) {
if (!available) return onSocketError(err);
socket.connect(port,host);
});
Is this probe covenient?
Hi,
your package.json states that a node Version >= 0.6 is required. It seems like your a using some features only present in newer versions of nodejs. Yesterday we ran into the following error message:
"TypeError: Buffer.allocUnsafe is not a function". (jsmodbus/src/handler/client/ReadHoldingRegisters.js:49)
Updateing our node Version from 4.x.x to 6.9.1 solved the issue.
Please update the package.json file with the correct minimum nodejs version.
Kind regards,
Valentin
I know this isn't the right project, but it appears the modbus-tool project is no longer available or maybe private now?
Either way I installed modbus-tool via NPM (https://www.npmjs.com/package/modbus-tool) while running node via nvm and attempted to run the executable, but received the following error:
[user@server ~]$ modbus-tool --help
bash: /path/to/home/dir/.nvm/v0.10.35/bin/modbus-tool: /usr/local/bin/node: bad interpreter: No such file or directory
This is due to the fact that node is not installed in /usr/local/bin/node, while the script appears to be hard-coded as such.
Changing the first line of the script to following corrects this, since it will use the appropriately loaded node from the environment
[user@server ~]$ head -n 1 /path/to/home/dir/.nvm/v0.10.35/lib/node_modules/modbus-tool/bin/modbus-tool
#! /usr/bin/env node
How about writing multiple coils?
C:\node server>node mod.js
module.js:338
throw err;
^
Error: Cannot find module 'xmlhttprequest'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (C:\node server\node_modules\socket.io\node_modules\so
cket.io-client\node_modules\engine.io-client\lib\transports\index.js:5:22)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
C:\node server>
Hi,
is it possible to set the Start bits and parity, please?
May with stampit ?
I am desperately looking for a library that supports the Modbus RTU over TCP Protocoll.
That means using Modbus RTU Protocol and send it over TCP.
See explanation here: http://www.simplymodbus.ca/TCP.htm
Actually your module are great and isn't really an issue.
I need to read multiple IP adresses and then, for each one, do a readHoldingRegisters and save results/errors in an array, like this:
var results = [ ];
for(var i in ips){
//connect to this IP
//on connect, readHoldingRegisters from this device and push the values
results.push(registers);
//on error, push other value, say, { }
results.push({ })
}
//finally return all reads
return callback(results);
How can I do this?
There is a async issue with the jsmodbus.js createTCPServer() call (line 91).
var server = serialServerModule.create(
tcpServer,
handler.Server.RequestHandler,
handler.Server.ResponseHandler);
// async - server is unknown as the cb is executed before the create() call completed.
cb(null, server);
The code will fail if the server create() with port 502.
The serrver code
modbus.createTCPServer(mbport, mbServer, function(err, modbusServer) {
// addHandler
modbusServer.addHandler(4, rirHandler);
modbusServer.addHandler(5, writeCoilHandler);
// log output
console.log('MBServer is running');
});
The createTCPServer() callbback with invalid 'modbusServer'
modbusServer.addHandler(4, rirHandler);
^
TypeError: Cannot read property 'addHandler' of undefined
Hello, and congratulation for your code. I've just a question about a supposed memory leak.
I try to read holding register all 2000 ms with the code below (i read 50 objects)
var readHoldingRegister = function (objectId,startAddress, objectLength,writeAdresseOffset,writeObjectLength) {
var startAddressObject = parseInt(startAddress) + parseInt(objectId)*parseInt(objectLength);
var writeAddressForObject = parseInt(startAddress) + parseInt(writeAdresseOffset) + (parseInt(writeObjectLength) * parseInt(objectId));intv = setInterval(function () { if(isModbusConnected) { loggerProdModBus.debug("___"); loggerProdModBus.debug("Call read holding register %s",objectId); var pRead = clientProxyModBus.readHoldingRegisters(startAddressObject, objectLength); var pWrite = clientProxyModBus.readHoldingRegisters(writeAddressForObject, writeObjectLength) Promise.all([pRead, pWrite]).then(function(values) { if(values.length === 2) parserModBus.ParseModBusRegister(objectId,values[0].register,startAddressObject,values[1].register,writeAddressForObject); else loggerProdModBus.error('Promise all not returning expected result. Result :',values) }).catch(function(err) { loggerProdModBus.error('Error with ModBus Server and reading readHoldingRegister',err) }); } }, pause);
};
But after few minutes, the memory used reach 512 Mb and stop. There is a solution to clear memory once the job is done?
Thanks
François
Hi,
I think that the register number is doubled compared to the real number:
my server :
var serverModbus = modbus.server.tcp.complete({ 'logEnabled' : false,
'port' : CONF_portAutomate,
'hostname' : CONF_ipAutomate,
'responseDelay' : 10 });
serverModbus.on('readHoldingRegistersRequest', function (byteStart, quantity) {
console.log('readHoldingRegistersRequest (' + byteStart + ', ' + quantity + ')');
});
serverModbus.on('preWriteSingleRegisterRequest', function (byteAddress, value) {
console.log('write single register (' + byteAddress + ', ' + value + ')');
});
my client :
// Ecrit de type holding - registre n° 16
client.writeSingleRegister(16, parseInt(data, 2)).then(function (resp) {}).fail();
// Registre n°20 - lecture de 1 registre - Fonction n°3 (holding)
client.readHoldingRegisters(20, 1).then(function (resp) {}).fail();
And the result:
readHoldingRegistersRequest (40, 1)
write single register (32, 2)
instead of:
readHoldingRegistersRequest (20, 1)
write single register (16, 2)
Hello! Very good package.
I tried TCP server and found out, that there is no discrete inputs.
Both files server/ReadDiscreteInputs.js and server/ReadInputRegisters.js are addressing this.getInput().
I can make pull request for it if you want.
Another extension would be: events for connecting and disconnecting of masters. I can make a pull request for this too.
Greetings,
bluefox
Hi,
I use this great library on my raspberry, but with the passage on the next version, i can't install this.
The errors messages :
> [email protected] install /home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport
> node-pre-gyp install --fallback-to-build
make: Entering directory '/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build'
CXX(target) Release/obj.target/serialport/src/serialport.o
In file included from ../src/./serialport.h:7:0,
from ../src/serialport.cpp:1:
../node_modules/nan/nan.h:328:47: error: 'REPLACE_INVALID_UTF8' is not a member of 'v8::String'
static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
^
serialport.target.mk:84: recipe for target 'Release/obj.target/serialport/src/serialport.o' failed
make: *** [Release/obj.target/serialport/src/serialport.o] Error 1
make: Leaving directory '/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build'
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/share/node-gyp/lib/build.js:267:23)
gyp ERR! stack at ChildProcess.emit (events.js:98:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:809:12)
gyp ERR! System Linux 4.4.13-v7+
gyp ERR! command "nodejs" "/usr/bin/node-gyp" "build" "--fallback-to-build" "--module=/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build/Release/serialport.node" "--module_name=serialport" "--module_path=/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build/Release"
gyp ERR! cwd /home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport
gyp ERR! node -v v0.10.29
gyp ERR! node-gyp -v v0.12.2
gyp ERR! not ok
node-pre-gyp ERR! build error
node-pre-gyp ERR! stack Error: Failed to execute 'node-gyp build --fallback-to-build --module=/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build/Release/serialport.node --module_name=serialport --module_path=/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build/Release' (1)
node-pre-gyp ERR! stack at ChildProcess.<anonymous> (/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack at ChildProcess.emit (events.js:98:17)
node-pre-gyp ERR! stack at maybeClose (child_process.js:755:16)
node-pre-gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:822:5)
node-pre-gyp ERR! System Linux 4.4.13-v7+
node-pre-gyp ERR! command "node" "/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! cwd /home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport
node-pre-gyp ERR! node -v v0.10.29
node-pre-gyp ERR! node-pre-gyp -v v0.6.26
node-pre-gyp ERR! not ok
Failed to execute 'node-gyp build --fallback-to-build --module=/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build/Release/serialport.node --module_name=serialport --module_path=/home/pi/NodeJS/N3-PorteAuto/v4/node_modules/jsmodbus/node_modules/serialport/build/Release' (1)
npm WARN This failure might be due to the use of legacy binary "node"
npm WARN For further explanations, please read
/usr/share/doc/nodejs/README.Debian
npm ERR! [email protected] install: `node-pre-gyp install --fallback-to-build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is most likely a problem with the serial port package
npm ERR! not with nam itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-pre-gyp install --fallback-to-build
npm ERR! You can get their info via:
npm ERR! npm owner ls serial port
npm ERR! There is likely additional logging output above.
npm ERR! System Linux 4.4.13-v7+
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "update"
npm ERR! cwd /home/pi/NodeJS/N3-PorteAuto/v4
npm ERR! node -v v0.10.29
npm ERR! npm -v 1.4.21
npm ERR! code ELIFECYCLE
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/pi/NodeJS/N3-PorteAuto/v4/npm-debug.log
npm ERR! not ok code 0
```,
I am not sure if this is an issue at all and I already found a workaround.
I connect to a number of modbus devices using async.forEach:
async.forEach(addresses, function(address, iterate_callback){
...
var client = modbus.createTCPClient(port, host, item, function(err){
...
return iterate();});
The callbacks are called reporting on successful connections. Here it's necessary to say couple of words about my configuration - I have a number of modbus devices connected via modbus RS485-to-TCP gateway. If all devices are connected via RS485 to the gateway - everything works fine, but if some devices are not connected to RS485 I got the following issue - the callback for createTCPClient is called second time and I get exception in async module "the callback is already called" (or something).
As I said I already found a workaround - I just use some flags to avoid the calling iterate() callback the second time. Still it was a surprise for me as I didn't expect this callback fired more than once.
-ap
I have been working on a project by this awesome jsmodbus, but when I enable the AutoReconnect,
program will do the reconnect high-frequency, even raise the CPU utility to 100 %.
So I want to know is there any function I can call to set the reconnect time?
Thanks
Hi,
we have stumbled upon the following issue. When reading coils, the LSB of the answer is required to equal the start address specified in the command. See the following quote from the spec:
The LSB of the first data byte contains the output addressed in the query. The other coils follow toward the high order end of this byte, and from low order to high order in subsequent bytes.
(from http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf Chapter 6)
However, the current server implementation seems to align the coils on a fixed "grid" starting at multiples of address 8.
So e.g. when calling readCoils(5,1)
(and assuming that the value at address 5
is true
) the expected result would be:
[true, false, false, false, false, false, false, false] // 00000001
but the actual result currently is
[false, false, false, false, false, true, false, false] // 00100000
I figure the issue is the following line https://github.com/Cloud-Automation/node-modbus/blob/master/src/handler/server/ReadCoils.js#L55
val += mem.readUInt8(Math.floor(i / 8)) & Math.pow(2, i % 8);
which should probably be something like
if(mem.readUInt8(Math.floor(i / 8)) & Math.pow(2, i % 8)) {
val += 1 << ( j % 8)
}
d'accord? :-) or am I missing something? I can create a PR.
PS: that is the same for discrete inputs.
Hi,
I am trying to use readDiscreteInput function. I took code from example readDiscreteInput.js, but it returned an error:
{ errorCode: 130, exceptionCode: 1, message: 'ILLEGAL FUNCTION' }
Kind regards,
Alex
Hi everybody,
since there were some undetected API changes on Version 1.2.6 I rolled back the changes to 1.2.5. Whenever you checkout [email protected] you get [email protected].
All improvements since 1.2.5 are going to be in Version 2.0.0. See Pull Request #92 for more Informations.
Hi @BauchBeinePoe I unfortunately just realized that I have made some small mistakes in my Put() --> Buffer conversions that where not caught by the existing tests.
Luckily we have some deep integration tests in our platform and we just stumbled over those :) I am currently going through the code again and started to push fixes to the fix-byte-bugs branch: https://github.com/Cloud-Automation/node-modbus/tree/fix-byte-bugs
I'll issue the PR when I am done. Just so you know, probably pull the most recent version back from npm for now. sorry!
If I loose connection, is it possible to reconnect without the node script being stopped and restarted?
I tried this without success:
// create a modbus client
var ErreurModbus = 0;
var client = modbus.createTCPClient(CONF_portAutomate, CONF_ipAutomate, function (err) {
if (err) {
ErreurModbus = 1;
io.sockets.emit('displayErreurModbus', ErreurModbus); // tous
}
});
/*Un client se connecte*/
io.sockets.on('connection', function (socket) {
/* Clique sur le bouton Reset Server*/
socket.on('setResetServer',function(){
ErreurModbus = 0;
client.reconnect();
io.sockets.emit('displayErreurModbus', ErreurModbus); // tous
})
});
Is there any way to set a timeout period?
Well, here I am again, thanks for your atention.
So, I need to read from de 40001 to 40344 holding register, and I have understood that , to do this, I need to call readHoldingRegisters three times.
But the interval doesn't make sense for me. After some time testing the reads, I could read it make the follow call:
//after client configurations
client.on('connect', function () {
var reads = [
client.readHoldingRegisters(0, 127), //40001 to 40127
client.readHoldingRegisters(127, 255), //40128 to 40254
client.readHoldingRegisters(254, 346) //40255 to 40344
];
Promise
.all(reads)
.then(function (data) {
console.log(data);
}).error(function (err) {
console.log(err);
}).finally(function () {
client.close();
});
});
I tried to use Simply Modbus TCP Client 7.1.2 to simulate the calls, but it doesn't work well, so I don't know if it's a modbus protocol problem, just a bug in the module or just I didn't understand the protocol... what can it be?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.