npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

scouting-modbus-reader

v0.0.2

Published

Routine to communicate with Modbus-TCP including symbol lookup, etc, for PLCs

Downloads

3

Readme

modbusReader

modbusReader is a library that provides communication with PLCs and controllers using MODBUS/TCP or MODBUS RTU over TCP. It supports various tag formats for reading and writing data, including coils, input status, input register, holding register, etc. It supports the default slave ID of 1, but you can specify a different slave ID if necessary. modbusReader can be installed via npm by running npm install modbusReader. To use it, you can require the library and use it to initiate a connection, set a translation callback, add items to be read or written, and write values to those items.

Tag format supports the following:

TAG1=00001SLAVE2	// Leading zeros optional, 1-based "coils". Read/write.  Always writes with "force multiple coils" FC15, never uses the single.  

TAG1=00001,100   		// Array of coils from slave 1 (formerly 255).  Read/write.  

TAG1=10001   			// Input status.  Read-only.  

TAG1=10001,100  		// Input status array.  Read-only.  

TAG1=30001   			// Input register.  Read-only.  

TAG1=30001,100  		// Input register array.  Read-only.  

TAG1=30001:REAL,100 	// Input register array as REAL.  Read-only.  Assumes skip registers, like first is 30001, next is 30003, etc.  
TAG1=30001:WSREAL,100 	// Input register array as word-swapped REAL.  Read-only.  Assumes skip registers, like first is 30001, next is 30003,etc.  

TAG1=30001:DINT			// Input register as DINT

TAG1=30001:WSDINT		// Input register as word-swapped DINT

TAG1=30001:DWORD		// Input register as unsigned DINT

TAG1=30001:WSDWORD		// Input register as word-swapped unsigned DINT

TAG1=30001.0,15			// First Input register split into bits (read-only)

TAG1=40001   			// Holding register.  Read-only.  

TAG1=40001,100  		// Holding register array.  Read-only.  

TAG1=40001:REAL,100 	// Holding register array as REAL.  Assumes skip registers, like first is 40001, next is 40003, etc.  

TAG1=40001:WSREAL,100 	// Holding register array as word-swapped REAL.  Assumes skip registers, like first is 40001, next is 40003, etc.  

TAG1=40001:DINTSLAVE2	// Holding register as DINT, from slave 1

TAG1=40001:WSDINTSLAVE2	// Holding register as word-swapped DINT, from slave 1

TAG1=40001:DWORD		// Holding register as unsigned DINT

TAG1=40001:WSDWORD		// Holding register as word-swapped unsigned DINT

TAG1=40001.3			// Holding register bit (IMPORTANT NOTE: read-only - can't write individual bits of 4000x registers)

TAG1=RD90				// Holding register 40091 as double integer

TAG1=R190				// Holding register 40191 as integer

Installation:

npm install modbusReader

Example usage:

var modbusReader = require('modbusReader');
var conn = new modbusReader();
var doneReading = false;
var doneWriting = false;

conn.initiateConnection({port: 502, host: '192.168.8.199', defaultID: 1, RTU: false}, connected); // defaultID defaults to 1 and RTU defaults to false but shown here for illustration

function connected(err) {
	if (typeof(err) !== "undefined") {
		// We have an error.  Maybe the PLC is not reachable.  
		console.log(err);
		process.exit();
	}
	conn.setTranslationCB(tagLookup);
	conn.addItems(['TEST1']);
//	conn.addItems(['TEST1', 'TEST4']);
//	conn.removeItems(['TEST2', 'TEST3']);  // Demo.  
//	conn.writeItems(['TEST5', 'TEST6'], [ 867.5309, 9 ], valuesWritten);  // You can write an array of items.  
//	conn.writeItems('TEST7', [ 666, 777 ], valuesWritten);  // You can write a single array item too.  
	conn.readAllItems(valuesReady);	
}

function valuesReady(anythingBad) {
	if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
	console.log("Value is " + conn.findItem('TEST1').value + " quality is " + conn.findItem('TEST1').quality);
	doneReading = true;
	if (doneWriting) { process.exit(); }
}

function valuesWritten(anythingBad) {
	if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); }
	console.log("Done writing.");
	doneWriting = true;
	if (doneReading) { process.exit(); }
}

// This is a very simple "tag lookup" callback function that would eventually be replaced with either a database findOne(), or a large array in memory.  
// Note that the return value is a controller absolute address and datatype specifier.  
// If you want to use absolute addresses only, you can do that too.  
function tagLookup(tag) {
	switch (tag) {
case 'TEST1':
	return "030SLAVE1";
	case 'TEST2':
		return '40100.0SLAVE1';
	case 'TEST3':
		return '40101.1SLAVE1';	
	case 'TEST4':
		return '30001.1SLAVE1';		
	case 'TEST5':
		return '00008SLAVE1';		
	case 'TEST6':
		return '00003,20SLAVE1';
	case 'TEST7':
		return '00001,3000SLAVE1';
	case 'TEST8':
		return '40001:DINTSLAVE1';
	case 'TEST9':
		return '40001:DINT,400SLAVE1';
	case 'TEST10':
		return '30001.0,16SLAVE1';	
	default:
		return undefined;
	}
}