UNPKG

modbus-serial

Version:

A pure JavaScript implemetation of MODBUS-RTU (Serial and TCP) for NodeJS.

434 lines (372 loc) 13.2 kB
"use strict"; /** * Copyright (c) 2015, Yaacov Zamir <kobi.zamir@gmail.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ const MIN_MODBUSRTU_FRAMESZ = 5; /** * Adds connection shorthand API to a Modbus objext * * @param {ModbusRTU} Modbus the ModbusRTU object. */ const addConnctionAPI = function(Modbus) { const cl = Modbus.prototype; const open = function(obj, next) { /* the function check for a callback * if we have a callback, use it * o/w build a promise. */ if (next) { // if we have a callback, use the callback obj.open(next); } else { // o/w use a promise return new Promise(function(resolve, reject) { function cb(err) { if (err) { reject(err); } else { resolve(); } } obj.open(cb); }); } }; /** * Connect to a communication port, using SerialPort. * * @param {string} path the path to the Serial Port - required. * @param {Object} options - the serial port options - optional. * @param {Function} next the function to call next. */ cl.connectRTU = function(path, options, next) { if (options) { this._enron = options.enron; this._enronTables = options.enronTables; } // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // disable auto open, as we handle the open options.autoOpen = false; // set vmin to smallest modbus packet size options.platformOptions = { vmin: MIN_MODBUSRTU_FRAMESZ, vtime: 0 }; // create the SerialPort const SerialPort = require("serialport").SerialPort; this._port = new SerialPort(Object.assign({}, { path }, options)); // open and call next return open(this, next); }; /** * Connect to a communication port, using TcpPort. * * @param {string} ip the ip of the TCP Port - required. * @param {Object} options - the TCP port options - optional. * @param {Function} next the function to call next. */ cl.connectTCP = function(ip, options, next) { if (options) { this._enron = options.enron; this._enronTables = options.enronTables; } // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // create the TcpPort const TcpPort = require("../ports/tcpport"); if (this._timeout) { options.timeout = this._timeout; } this._port = new TcpPort(ip, options); // open and call next return open(this, next); }; /** * Setup a communication port with existing socket, using TcpPort. * * @param {string} socket the instance of the net.Socket - required. * @param {Object} options - the TCP port options - optional. * @param {Function} next the function to call next. */ cl.linkTCP = function(socket, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } options.socket = socket; // create the TcpPort const TcpPort = require("../ports/tcpport"); if (this._timeout) { options.timeout = this._timeout; } this._port = new TcpPort(options); // open and call next return open(this, next); }; /** * Connect to a communication port, using TcpRTUBufferedPort. * * @param {string} ip the ip of the TCP Port - required. * @param {Object} options - the serial tcp port options - optional. * @param {Function} next the function to call next. */ cl.connectTcpRTUBuffered = function(ip, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } const TcpRTUBufferedPort = require("../ports/tcprtubufferedport"); if (this._timeout) { options.timeout = this._timeout; } this._port = new TcpRTUBufferedPort(ip, options); // open and call next return open(this, next); }; cl.linkTcpRTUBuffered = function(socket, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } options.socket = socket; // create the TcpPort const TcpRTUBufferedPort = require("../ports/tcprtubufferedport"); if (this._timeout) { options.timeout = this._timeout; } this._port = new TcpRTUBufferedPort(options); // open and call next return open(this, next); }; /** * Connect to a communication port, using TelnetPort. * * @param {string} ip the ip of the TelnetPort - required. * @param {Object} options - the serial port options - optional. * @param {Function} next the function to call next. */ cl.connectTelnet = function(ip, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // create the TcpPort const TelnetPort = require("../ports/telnetport"); if (this._timeout) { options.timeout = this._timeout; } this._port = new TelnetPort(ip, options); // open and call next return open(this, next); }; cl.linkTelnet = function(socket, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } options.socket = socket; // create the TcpPort const TelnetPort = require("../ports/telnetport"); if (this._timeout) { options.timeout = this._timeout; } this._port = new TelnetPort(options); // open and call next return open(this, next); }; /** * Connect to a communication port, using C701 UDP-to-Serial bridge. * * @param {string} ip the ip of the TelnetPort - required. * @param {Object} options - the serial port options - optional. * @param {Function} next the function to call next. */ cl.connectC701 = function(ip, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // create the TcpPort const C701Port = require("../ports/c701port"); this._port = new C701Port(ip, options); // open and call next return open(this, next); }; /** * Connect to a communication port, using modbus-udp. * * @param {string} ip the ip of the UDP Port - required. * @param {Object} options - the serial port options - optional. * @param {Function} next the function to call next. */ cl.connectUDP = function(ip, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // create the UdpPort const UdpPort = require("../ports/udpport"); this._port = new UdpPort(ip, options); // open and call next return open(this, next); }; /** * Connect to a communication port, using Bufferd Serial port. * * @param {string} path the path to the Serial Port - required. * @param {Object} options - the serial port options - optional. * @param {Function} next the function to call next. */ cl.connectRTUBuffered = function(path, options, next) { if (options) { this._enron = options.enron; this._enronTables = options.enronTables; } // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // create the SerialPort const SerialPort = require("../ports/rtubufferedport"); this._port = new SerialPort(path, options); // set vmin to smallest modbus packet size options.platformOptions = { vmin: MIN_MODBUSRTU_FRAMESZ, vtime: 0 }; // open and call next return open(this, next); }; /** * Connect to a communication port, using ASCII Serial port. * * @param {string} path the path to the Serial Port - required. * @param {Object} options - the serial port options - optional. * @param {Function} next the function to call next. */ cl.connectAsciiSerial = function(path, options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // create the ASCII SerialPort const SerialPortAscii = require("../ports/asciiport"); this._port = new SerialPortAscii(path, options); // open and call next return open(this, next); }; /** * Connect to existing client socket. * * @param {socket} socket the socket to connect to - required. * @param {Function} next the function to call next. */ cl.connectRTUSocket = function(socket, next) { const thisModbus = this; this._port = socket; this._port.open = function(callback) { // existing socket is already connected thisModbus._port.isOpen = true; callback(); }; // open and call next return open(this, next); }; /** * Connect to existing client socket. * * @param {socket} socket the socket to connect to - required. * @param {Function} next the function to call next. */ cl.connectBle = function(options, next) { // check if we have options if (typeof next === "undefined" && typeof options === "function") { next = options; options = {}; } // check if we have options if (typeof options === "undefined") { options = {}; } // create the TcpPort const BlePort = require("../ports/bleport"); if (this._timeout) { options.timeout = this._timeout; } this._port = new BlePort(options); // open and call next return open(this, next); }; }; /** * Connection API Modbus. * * @type {addConnctionAPI} */ module.exports = addConnctionAPI;