Cloud-Automation / node-modbus

Modbus TCP Client/Server implementation for Node.JS
456 stars 169 forks source link

TypeScript Example #332

Closed cycl0ne closed 7 months ago

cycl0ne commented 8 months ago

Hi, first the example using: import Modbus from '../../..'

yes from your view ok, but i installed jsmodbus and then this wont work :-P

second: I just copy the example code and execute it:

import Modbus from 'jsmodbus'
import { Socket, SocketConnectOpts } from 'net'

const socket = new Socket()

const options: SocketConnectOpts = {
  host: '127.0.0.1',
  port: 8502
}
const client = new Modbus.client.TCP(socket)

const readStart = 0;
const readCount = 10;

socket.on('connect', function () {
  client.readHoldingRegisters(readStart, readCount)
    .then(({ metrics, request, response }) => {
      console.log('Transfer Time: ' + metrics.transferTime)
      console.log('Response Body Payload: ' + response.body.valuesAsArray)
      console.log('Response Body Payload As Buffer: ' + response.body.valuesAsBuffer)
    })
    .catch(handleErrors)
    .finally(() => socket.end())
})

socket.on('error', console.error)
socket.connect(options)

function handleErrors(err: any) {
  if (Modbus.errors.isUserRequestError(err)) {
    switch (err.err) {
      case 'OutOfSync':
      case 'Protocol':
      case 'Timeout':
      case 'ManuallyCleared':
      case 'ModbusException':
      case 'Offline':
      case 'crcMismatch':
        console.log('Error Message: ' + err.message, 'Error' + 'Modbus Error Type: ' + err.err)
        break;
    }

  } else if (Modbus.errors.isInternalException(err)) {
    console.log('Error Message: ' + err.message, 'Error' + 'Error Name: ' + err.name, err.stack)
  } else {
    console.log('Unknown Error', err);
  }
}

i get the following error:

const client = new jsmodbus_1.default.client.TCP(socket); ^ TypeError: Cannot read property 'client' of undefined at Object. (/home/pi/Python/_node/dist/app.js:13:39) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12) at internal/main/run_main_module.js:17:47

Any idea?

stefanpoeter commented 8 months ago

Hey @cycl0ne,

I am always happy for contributions if you want to correct the example.

The error looks like more of a setup problem. Seems like there is something missing when you build the javascript files. Don't see anything wrong with the code.

cycl0ne commented 7 months ago

Hmm, did a complete clean install. same error. "TypeError: Cannot read property 'client' of undefined"

Understanding Question here: I just use the example without a server on 127.0.0.1 maybe because of this, since he cant find a connection there? Shouldnt there be a sort thrown error for this?

stefanpoeter commented 7 months ago

did you checked this const client = new jsmodbus_1.default.client.TCP(socket); and const client = new Modbus.client.TCP(socket)

What is happening there?

cycl0ne commented 7 months ago

in the latest try above.. i get the error that client is undefined. but mouseover in IDE (Code-Server) says: its a const.. but executing it after ts compilation throws: undefined.

i will check the first example i used. -> Same error. the client throws an undefined error.

here my two config files:

{
  "name": "tibberts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "start": "node dist/App.js",
    "build": "cd client && npm install && npm run build",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/express": "^4.17.20",
    "@types/node": "^20.8.8",
    "typescript": "^5.2.2"
  },
  "dependencies": {
    "commander": "^11.1.0",
    "express": "^4.18.2",
    "jsmodbus": "^4.0.6",
    "tibber-api": "^5.1.9"
  }
}

and

{
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "ES2021",
    "lib": ["ES2021", "DOM"],
    "skipLibCheck": true, 
  },
  "include": ["**/*.ts"],
  "exclude": [".vscode", "node_modules", "_Retired", "/_Retired/*.ts"]
}

so no real hokuspokus here.

cycl0ne commented 7 months ago

hmm trying to locate still the error.. using your cli tool: jsmodbus, but now i get the following error:

jsmodbus fc04 192.168.1.13 225 1285

Attempting to connect to 192.168.1.13:502 at unitId 225 ... Connected [Arguments] { '0': UserRequestError { err: 'ModbusException', message: 'A Modbus Exception Occurred - See Response Body', response: ModbusTCPResponse { _id: 1, _protocol: 0, _bodyLength: 3, _unitId: 225, _body: ExceptionResponseBody { _fc: 4, _code: 3 } } } }

with qModbus (tool for windows),Loxone SmartHome and python (with the modbus module) i can read the values with this setting: ip/unit/adress.

i think i will give up on nodejs and go back to python. 🤣

stefanpoeter commented 7 months ago

Hey @cycl0ne ,

the specification states the following regarding error code 4

Screenshot_20231202-164715

cycl0ne commented 7 months ago

yes, but here again: i just use the CLI Tool: jsmodbus fc04 192.168.1.13 100 844

Output in Bash: Attempting to connect to 192.168.1.13:502 at unitId 100 ... Connected [Arguments] { '0': UserRequestError { err: 'ModbusException', message: 'A Modbus Exception Occurred - See Response Body', response: ModbusTCPResponse { _id: 1, _protocol: 0, _bodyLength: 3, _unitId: 100, _body: ExceptionResponseBody { _fc: 4, _code: 3 } } } }

here the result with qmodmaster tool: qmodbus

so i dont modify query data or anything else.. just using the cli tool.

but as i said.. maybe my intenstions using a web tech language for a machine specific thing is too much... maybe i switch back to ugly python.

stefanpoeter commented 7 months ago

Don't know what you expect, the bin/jsmodbus.js defines the parameters for a fc04 call like this

.command('fc04 <host> <unitId> <range>')

I think you need to change your command to something like

jsmodbus fc04 192.168.1.13 unitid startRegister endRegister

cycl0ne commented 7 months ago

hmm still doesnt work: jsmodbus fc04 192.168.1.13 100 844 845 same error

what i want, i want a simple api to call modbus like i do in python: c = ModbusClient(host="192.168.1.13", port=502, unit_id=100) c.read_holding_registers(844,1)

simple 2 liners. Seems this is much more complicated in js/ts than in python. so yes i will close this case and look for something more intuitive to use without such a hassle.