0.0.1 • Published 2 months ago

modbus-tcp-secure v0.0.1

Weekly downloads
-
License
GPL-3.0
Repository
-
Last release
2 months ago

modbus-tcp-secure

Installation

npm install modbus-tcp-secure

Usage

The classes ModbusServer and ModbusClient can be imported from modbus-tcp-secure and contain the needed method to operate either a Slave or a Master device.
For convenience the enums AccessMode and ModbusFunctionCode can be imported also.

Methods

ModbusServer

ModbusServer contains different methods for configuring the behaviour of the slave device. All properties, registers or coils in read or write mode, need to be configured before being available.

  • Registers (params are explained in jsDoc):
    • .addRegisters(...)
    • .getRegisters(...)
    • .setRegisters(...)
    • .deleteRegisters(...)
  • Coils (params are explained in jsDoc):
    • .addCoils(...)
    • .getCoils(...)
    • .setCoils(...)
    • .deleteCoils(...)
  • Settings:
    • .setModbusId(number): Set new value (1-247) to the modbus ID used to address this slave. Default is 1.
    • .enableFillRegisters()/ .disableFillRegisters(): Updates fillRegisters property. If fillRegisters are deactivated, the slave will answer with an exception when requesting for example 3 registers starting at address 3, if register 4 is not defined. If fillRegisters are activated the missing value will be filled with NaN(0xFFFF).
    • .enableFunctionCode(ModbusFunctionCode)/ .disableFunctionCode(ModbusFunctionCode): Adds/Removes a function code from the available function codes for this slave. Registers have to be added manually. If a function code with defined registers is disabled, the configured registers are lost. Can be used to prevent write access slave-wide. Possible Exceptions:
  • IllegalFunction: For the requested function code, no register / coil is defined
  • IllegalDataAddress: Requested function code is available, but no register / coil is defined for the requested register address
  • IllegalDataValue: The given write value does not fit the intended use

ModbusClient

The ModbusClient class provides methods for requesting data from or writing data to a slave.
A request needs to be called with communication parameters like modbusID, startRegister, registerCount and also data if register values should be written.
The requests are sent asynchronously and should be awaited to access the response.

  • Reading Registers / Coils

    • .readCoils(...): Function Code 1 (0x01), reading coil registers. Each can have a value of 0 or 1
    • .readDiscretes(...): Function Code 2 (0x02), reading discrete registers. Each can have a value of 0 or 1
    • .readHoldingRegisters(...): Function Code 3 (0x03), reading holding registers. Each register can contain 16-bit of data.
      To offer bigger values like 32-bit floats, multiple registers can be used to represent a single value.
    • .readDiscretes(...): Function Code 4 (0x04), reading input registers. Each register can contain 16-bit of data.
      To offer bigger values like 32-bit floats, multiple registers can be used to represent a single value.
  • Writing Registers / Coils

    • .writeSingleCoil(...): Function Code 5 (0x05), write single coil register. Accepts one boolean value as data.
    • .writeSingleRegister(...): Function Code 6 (0x06), write single register. Accepts 16-bit value as Buffer as data.
    • .writeMultipleCoils(...): Function Code 15 (0x0F), write multiple coil registers. Accepts values as Buffer containing one coil value 0;1 per byte.
    • .writeMultipleRegister(...): Function Code 16 (0x10), write multiple registers. Accepts values as Buffer containing multiples of 16-bit.

Configuration

The ModbusServer and the ModbusClient constructor expect the following parameters:

  • Host: IP-Address / Hostname
  • Port: TCP Port to be used. Well known Modbus port is 502
  • Options: TLSOptions object that should contain the following:
    • key: fs.readFileSync(KEY_PATH)
    • cert: fs.readFileSync(CERT_PATH)
    • ca: [fs.readFileSync(CERT_PATH)]
    • rejectUnauthorized: true (while this is not mandatory, it's highly recommended since otherwise the authentication is not enforced)

KEY_PATH: The path for the public key.
CERT_PATH: The path for the certificate.

Key and certificate creation

You can find an explanation how to create a self-signed certificate and key here.

For a successful self-signed certificate it is necessary to use a san.cnf like this:

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext

[dn]
C=DE                     # Your country code
ST=Bavaria               # Your state
L=Augsburg               # Your state
O=no_organisation        # Your organisation
OU=no_unit               # Your organisation unit
emailAddress=no_email    # Your email address
CN = localhost           # Common name of your Server/Client

[req_ext]
subjectAltName = @alt_names

[alt_names]
IP.1 = 127.0.0.1

Command to create the key and cert file from the san.cnf

openssl req -new -x509 -nodes -out public-cert.pem -keyout private-key.pem -config san.cnf -extensions req_ext

Self-signed certificates should only be used in local networks and not when communicating via Internet

Server / Client Structure

The ModbusServer class is a representation of a ModbusSlave device. Its main tasks are:

  • Answering reading request of coils and registers
  • Accepting write commands and values
  • Responding with the suitable Modbus error code for invalid messages

The ModbusClient class is a representation of a ModbusMaster device. While it's possible in ModbusTCP that one slave is polled/controlled by more than one master device, it's highly recommended using only one master per slave. The main tasks are:

  • Polling values from a slave
  • Sending commands or setpoints

Recommended layout with 1 master

+--- System -------------------------------+
|                 +--------+               |
|                 | Master |               |
|                 +--------+               |
|                     |                    |
|                     |                    |
|     --------------------------------     |
|     |               |              |     |
|     |               |              |     |
| +--------+     +--------+     +--------+ |
| | Slave1 |     | Slave2 |     | Slave3 | |
| +--------+     +--------+     +--------+ |
+------------------------------------------+

Recommended layout with 2 masters

+--- System -------------------------------------------------------------------------+
|                +---------+                               +---------+               |
|                | Master1 |                               | Master2 |               |
|                +---------+                               +---------+               |
|                     |                                         |                    |
|                     |                                         |                    |
|     --------------------------------          --------------------------------     |
|     |               |              |          |               |              |     |
|     |               |              |          |               |              |     |
| +--------+     +--------+     +--------+  +--------+     +--------+     +--------+ |
| | Slave1 |     | Slave2 |     | Slave3 |  | Slave4 |     | Slave5 |     | Slave6 | |
| +--------+     +--------+     +--------+  +--------+     +--------+     +--------+ |
+------------------------------------------------------------------------------------+

License

This module is licensed under GNU GPLv3.
For explicit information see the LICENSE file.

0.0.1

2 months ago