Cloud-Automation / node-modbus

Modbus TCP Client/Server implementation for Node.JS
471 stars 175 forks source link

SimpleServer.js example not working. #112

Closed roccomuso closed 7 years ago

roccomuso commented 7 years ago

I'm trying to create a basic modbus-tcp-server that prints random data. I'm having this issue with the SimpleServer in the examples dir:

           this.getCoils().writeUInt8(0);
                 ^

TypeError: this.getCoils is not a function

SimpleServer.js:L17

What am I missing?

stefanpoeter commented 7 years ago

The example is working without errors in my place. Can you provide some more code?

roccomuso commented 7 years ago

Removed the previous method call, this is now the whole error, I'm on node v.6.8.0:

/home/user/Desktop/PROVE/modbus-server-tcp/prova.js:26 this.on('readCoilsRequest', function (start, quantity) { ^

TypeError: this.on is not a function at null. (/home/user/Desktop/PROVE/modbus-server-tcp/prova.js:26:22) at null. (/home/user/Desktop/PROVE/modbus-server-tcp/prova.js:42:13) at Stamp (/home/user/Desktop/PROVE/modbus-server-tcp/node_modules/stampit/dist/stampit.full.js:216:41) at Object. (/home/user/Desktop/PROVE/modbus-server-tcp/prova.js:46:5) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.runMain (module.js:604:10)

This is my example script:

    var stampit = require('stampit'),
        modbus = require('jsmodbus');

    var customServer = stampit()
        .refs({
            'logEnabled'        : true,
            'port'              : 8888,
            'responseDelay'     : 10, // so we do not fry anything when someone is polling this server

            // specify coils, holding and input register here as buffer or leave it for them to be new Buffer(1024)
            coils               : Buffer.alloc(1024, 0),
            holding             : Buffer.alloc(1024, 0),
            input               : Buffer.alloc(1024, 0)
        })
        .compose(modbus.server.tcp.complete)
        .init(function () {

            var init = function () {

                // get the coils with this.getCoils() [ Buffer(1024) ]
                // get the holding register with this.getHolding() [ Buffer(1024) ]
                // get the input register with this.getInput() [ Buffer(1024) ]                

                // listen to requests 

                this.on('readCoilsRequest', function (start, quantity) {

                    // do something, this will be executed in sync before the 
                    // read coils request is executed 

                });

                // the write request have pre and post listener
                this.on('[pre][post]WriteSingleCoilRequest', function (address, value) {

                });

            }.bind(this);    

            init();

        });

    customServer();

    // you can of course always use a standard server like so

    var server = modbus.server.tcp.complete({ port : 8888 });

    // and interact with the register via the getCoils(), getHolding() and getInput() calls

    server.getHolding().writeUInt16BE(123, 1);
stefanpoeter commented 7 years ago

Remove the part beneath customServer() or you will assign port 8888 to the server and the custom server. Executed the rest and everything is still fine. I am using v6.9.4.

roccomuso commented 7 years ago

@BauchBeinePoe what do you mean? this code is in the example. Maybe it's worth make things more clear?

stefanpoeter commented 7 years ago

@roccomuso You are right, presenting an example where two server instances are using the same port can be confusing.

The customServer and the server instances both use port 8888. So when you start the example you should get a port-already-in-use-error. I don't know how windows handles this kind of situations. Remove the lines starting with var server = ... and server.getHolding()... and try again.

stefanpoeter commented 7 years ago

@roccomuso You can of course always use the error proved examples from the example folder. You find a server example under examples/tcp/SimplerServer.js.

roccomuso commented 7 years ago

@BauchBeinePoe The server example examples/tcp/SimpleServer.js gives me the same error:

            this.on('readCoilsRequest', function (start, quantity) {
                 ^

TypeError: this.on is not a function

By the way I'm not under windows, but Ubuntu. The error is not even relative to port-already-in-use. It's a TypeError. Tried also with Node v4.4.0.

stefanpoeter commented 7 years ago

Strange!

Can you modify the init function and print out the content of this

...
var init = function () {

    console.log(this);

    this.on('readCoilsRequest', function (start, quantity) { } );

}.bind(this);
...

Should look like this

{ logEnabled: true,
  port: 8888,
  responseDelay: 10,
  coils: <Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
  holding: <Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
  input: <Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
  emit: [Function],
  on: [Function],
  once: [Function],
  removeListener: [Function],
  log: 
   { error: [Function: bound ],
     warn: [Function: bound ],
     info: [Function: bound ],
     debug: [Function: bound ],
     trace: [Function: bound ] },
  logInfo: [Function: bound ],
  logError: [Function: bound ],
  logLevel: 'info',
  onData: [Function: bound ],
  setRequestHandler: [Function],
  getCoils: [Function],
  getInput: [Function],
  getHolding: [Function],
  inState: [Function],
  getState: [Function],
  setState: [Function],
  close: [Function],
  hostname: '0.0.0.0' }
roccomuso commented 7 years ago

It's a bit different than mine:

{ logEnabled: true,
  port: 8888,
  responseDelay: 10,
  coils: <Buffer ff ff ff ff 00 00 00 00 00 00 c0 03 00 00 00 00 00 1e 4f 03 00 00 00 00 58 1b 4f 03 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ff ff ... >,
  holding: <Buffer 00 00 00 00 00 00 00 00 f0 ff 47 03 00 00 00 00 b0 0d 54 8a ff 7f 00 00 00 8f 4e 03 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... >,
  input: <Buffer 58 42 a3 24 4a 7f 00 00 58 42 a3 24 4a 7f 00 00 c0 26 4f 03 00 00 00 00 c0 26 4f 03 00 00 00 00 0a 00 00 00 00 00 00 00 28 b8 4e 03 00 00 00 00 0b 00 ... >
}
stefanpoeter commented 7 years ago

Can you execute this

var modbus = require('jsmodbus');

var server = modbus.server.tcp.complete({ port : 8888 });
roccomuso commented 7 years ago

In that way the app run without exceptions.

stefanpoeter commented 7 years ago

Well then copy the code from your example in here. There must be something wrong.

stefanpoeter commented 7 years ago

@roccomuso : Any progress?

flottokarotto commented 7 years ago

I ran into the same issue

npm ERR! Linux 3.16.0-4-amd64 npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "start" npm ERR! node v6.7.0 npm ERR! npm v3.10.9

roccomuso commented 7 years ago
    var stampit = require('stampit'),
        modbus = require('jsmodbus');

    var customServer = stampit()
        .refs({
            'logEnabled'        : true,
            'port'              : 8888,
            'responseDelay'     : 10, // so we do not fry anything when someone is polling this server

            // specify coils, holding and input register here as buffer or leave it for them to be new Buffer(1024)
            coils               : new Buffer(1024),
            holding             : new Buffer(1024),
            input               : new Buffer(1024)
        })
        .compose(modbus.server.tcp.complete)
        .init(function () {

            var init = function () {          

                // listen to requests 
        console.log(this)

                this.on('readCoilsRequest', function (start, quantity) {

                    // do something, this will be executed in sync before the 
                    // read coils request is executed 

                });

                // the write request have pre and post listener
                this.on('[pre][post]WriteSingleCoilRequest', function (address, value) {

                });

            }.bind(this);    

            init();

        });

    customServer();
stefanpoeter commented 7 years ago

Let me guess, you installed the stampit module before the jsmodbus module? Stampit moved to version 3.x and this is not entirely compatible with stampit@2.x. jsmodbus depends on stampit@2.x and when you install stampit by hand it installs the latest version.

Just remove the node_modules folder, make a npm install jsmodbus and execute the Server with node SimpleServer.js.

flottokarotto commented 7 years ago

yeah, you are right! I used an outdated npm version, so i got an dependency "error". My solution was: update npm to latest version, clean up packet.json, rm -rf ,node_modules, npm install