1.0.1 • Published 2 years ago

modbus-tcp-slave v1.0.1

Weekly downloads
-
License
GPL V3
Repository
github
Last release
2 years ago

Status GitHub Issues GitHub Pull Requests License


📝 Table of Contents

🧐 About

Nodejs implementation of Modubus TCP slave protocol

🏁 Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.

Prerequisites

  • NodeJs

Installing

Using npm:

  • npm install modbus-tcp-slave

Using yarn:

  • yarn add modbus-tcp-slave

🔧 Running the tests

Test are jest based, so

  • path_to_jest --config jest.config.js i.e.
  • ./node_modules/.bin/jest --config jest.config.js

🔧 Eslinter

You may eslint everithing using

  • node_modules/.bin/eslint --ext .js --fix -c .eslintrc.js *.js libs/ testLibs/

🎈 Usage

Using a fake PLC implementation:

const { FUNCTION_NAMES, ModbusTcpSlave, PLC } = require("./index");
const fs = require("fs");

let defaultValues = {
  ipAddress: "127.0.0.1",
  port: 502,
  unitId: 1,
};

if (fs.existsSync(__dirname + "/testData.json")) {
  defaultValues = JSON.parse(fs.readFileSync(__dirname + "/testData.json"));
}

/** @type {ModbusTcpSlave} */
let modbusTcpSlaveServer = new ModbusTcpSlave(defaultValues);

const main = async () => {
  const plc = new PLC({
    coils: new Array(10000).fill(false), // discrete outputs
    inputRegisters: new Array(10000).fill(false), // discrete inputs
    discreteInputs: new Array(10000).fill(0), // analog inputs
    holdingRegisters: new Array(10000).fill(0), // analog outputs
  });

  await modbusTcpSlaveServer.listen();

  // eslint-disable-next-line no-unused-vars
  plc.on("beforeRead", (request) => {
    console.log("beforeRead");
  });
  // eslint-disable-next-line no-unused-vars
  plc.on("afterWrite", (request) => {
    console.log("afterWrite");
    console.log(plc.memory);
  });

  modbusTcpSlaveServer.on("ERROR_FUNCION_CODE_NOT_IMPLEMENTED", (request) => {
    console.log(
      "ERRORE: ERROR_FUNCION_CODE_NOT_IMPLEMENTED: " + request.funcCode
    );
  });

  modbusTcpSlaveServer.on(FUNCTION_NAMES.WRITE_SINGLE_COIL, (request) => {
    plc.memory.coils[request.address] = request.value == 1;

    modbusTcpSlaveServer.respondToClient(request);
    plc.afterWrite(request);
  });
  modbusTcpSlaveServer.on(FUNCTION_NAMES.WRITE_SINGLE_REGISTER, (request) => {
    plc.memory.holdingRegisters[request.address] = request.value;

    modbusTcpSlaveServer.respondToClient(request);
    plc.afterWrite(request);
  });
  modbusTcpSlaveServer.on(FUNCTION_NAMES.WRITE_MULTIPLE_COILS, (request) => {
    for (let pos = 0; pos < request.value.length; pos++) {
      plc.memory.coils[request.address + pos] = request.value[pos] == 1;
    }

    modbusTcpSlaveServer.respondToClient(request);
    plc.afterWrite(request);
  });
  modbusTcpSlaveServer.on(FUNCTION_NAMES.WRITE_HOLDING_REGISTERS, (request) => {
    for (let pos = 0; pos < request.value.length; pos++) {
      plc.memory.holdingRegisters[request.address + pos] = request.value[pos];
    }

    modbusTcpSlaveServer.respondToClient(request);
    plc.afterWrite(request);
  });

  modbusTcpSlaveServer.on(FUNCTION_NAMES.READ_COILS, (request) => {
    plc.beforeRead(request);

    const value = [];
    for (let pos = 0; pos < request.value; pos++) {
      value.push(plc.memory.coils[request.address + pos]);
    }

    modbusTcpSlaveServer.respondToClient(request, value);
  });
  modbusTcpSlaveServer.on(FUNCTION_NAMES.READ_DISCRETE_INPUTS, (request) => {
    plc.beforeRead(request);

    const value = [];
    for (let pos = 0; pos < request.value; pos++) {
      value.push(plc.memory.discreteInputs[request.address + pos]);
    }

    modbusTcpSlaveServer.respondToClient(request, value);
  });
  modbusTcpSlaveServer.on(FUNCTION_NAMES.READ_HOLDING_REGISTERS, (request) => {
    plc.beforeRead(request);

    const value = [];
    for (let pos = 0; pos < request.value; pos++) {
      value.push(plc.memory.holdingRegisters[request.address + pos]);
    }

    modbusTcpSlaveServer.respondToClient(request, value);
  });
  modbusTcpSlaveServer.on(FUNCTION_NAMES.READ_INPUT_REGISTERS, (request) => {
    plc.beforeRead(request);

    const value = [];
    for (let pos = 0; pos < request.value; pos++) {
      value.push(plc.memory.inputRegisters[request.address + pos]);
    }

    modbusTcpSlaveServer.respondToClient(request, value);
  });
};
main();

⛏️ Built Using

✍️ Authors