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

depaula_eip

v1.0.4

Published

A Node-RED DePaula's prototype node to interact with some Weidmueller FBC-Coupler by Ethernet IP Protocol

Downloads

49

Readme

depaula_eip

depaula_eip is a library that allows communication to certain Ethernet/IP remote modules UR20-FBC-EIP from Weidmueller. This is not an official implementation of Ethernet/IP. This is not affiliated with or supported by Weidmueller or Allen-Bradley in any way.

WARNING - This is BETA CODE and you need to be aware that WRONG VALUES could be written to WRONG LOCATIONS. Fully test everything you do. In situations where writing to a random area of memory could cost you money, back up your data and test this really well. If this could injure someone or worse, consider other software.

To use this on a UR20-FBC-EIP modules just need to install it and set up the variables to be read.
Try at your own risk with other combinations. Using this with another Devices, you maybe will need to use different DF1 command with different formatting. Consult the DF1 manual (google it) for more details. (The manual suggests reading is more likely to work than writing but we don't have access to a PLC and can't test it.) In any case, PLC-specific commands could certainly be added.

So if you create a variable called THEINTEGER with type INT[10] then map it to file 7 and download, you can request N7:0 to get the first element, and so on.

Note that it is currently not possible to write to bits above 15 (most-significant word) in a long integer as the depaula_eip read-modify-write command appears to not support this. You must write the entire DINT or use bits within an INT.

It is optimized in two ways - it sorts a large number of items being requested, you should define what overall data areas to request. It does not yet group multiple small requests together in a single packet, which is apparently possible. It does, however, send 2 packets at once, for speed, and this number could potentially be increased. So a request for 100 different bits, all close (but not necessarily completely contiguous) will be grouped in one single request, with no additional direction from the user. Its optimizations are not likely tuned as well as some commercial OPC servers, however.

depaula_eip manages reconnects for you. So if the connection is lost because the device is powered down or disconnected, you can continue to request data with no other action necessary. "Bad" values are returned, and eventually the connection will be automatically restored.

depaula_eip is written entirely in Javascript, so no compiler installation is necessary on Windows, and deployment on other platforms (ARM, etc) should be no problem.

This was developed using Wireshark to help with packet format. No documentation was helpful as well, such as the "DF1 manual".

To get started:

npm install depaula_eip

Example usage:

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

conn.initiateConnection({port: 44818, host: '192.168.8.106' /* , routing: [0x01,0x00,0x01,0x00] */}, connected);
// Either uncomment the routing or uncomment this next line for any device if otherwise using routing	
// First 0x01, 0x00 = 1 word in the path, second 0x01, 0x00 = Port 0x01 (backplane port of Ethernet module), 0x00 = device is in slot 0 in chassis.   

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

function valuesReady(anythingBad, values) {
	if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
	console.log(values);
// alternative syntax		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 'N7:0';				// Integer
	case 'TEST2':
		return 'B3:0/0';			// Bit
	case 'TEST3':
		return 'B3/17';				// Same as B3:1/1
	case 'TEST4':
		return 'F8:0,20';  			// Yes this is an array...  20 real numbers.  
	case 'TEST5':
		return 'F8:1';				// Single real.  
	case 'TEST6':
		return 'F8:2';				// Another single real.  
	case 'TEST7':
		return 'N7:1,2';			// A couple of integers in an array  	
	case 'TEST8':
		return 'O:5/1';				// Direct output  	
	case 'TEST9':
		return 'ST18:0';
	default:
		return undefined;
	}
}

This returns some diagnostic output as well as the following:

{ TEST1: 30724,
  TEST4: 
   [ 867530.875,
     1,
     97.0999984741211,
     2.9000000953674316,
     97,
     0,
     0,
     19,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0 ] }

API

depaula_eip.initiateConnection(params, callback)

Connects to a Device.

params should be an object with the following keys:

  • port (normally specify 44818)
  • host (address)
  • routing (array of characters specifying path length, path, etc. Most common is [0x01, 0x00, 0x01, 0x00] for routing.)

callback(err) will be executed on success or failure. err is either an error object, or undefined on successful connection.

depaula_eip.dropConnection(callback)

Disconnects from a Device.

This simply terminates the TCP connection. It does NOT do an Ethernet/IP disconnect at this time. The callback is called upon completion of the TCP close.

depaula_eip.setTranslationCB(translator)

Sets a callback for name - address translation.

This is optional - you can choose to use "addItem" etc with absolute addresses.

If you use it, translator should be a function that takes a string as an argument, and returns a string in the following format: <type specifier><file number - I assumed 1, O assumed 0, S assumed 2>:<element>[</bit> or </DN, /EN, /TT> or <.ACC, .PRE>],array length

Examples:

  • F8:30
  • F8:0,10 - array of 10 floating point numbers
  • N7:12
  • L9:1 - long integer is MicroLogix/ControlLogix/CompactLogix only
  • N7:12/1 - second bit in the word
  • B3:6/6
  • T4:6.ACC - timer accumulator - read/write
  • C5:1.PRE - counter preset - read/write
  • T4:0,20 - array of timers - will return an array of objects representing 20 timers - READ ONLY
  • R6:0.LEN - control length - read/write
  • R6:0 - control structure - will return a JS object - READ ONLY
  • ST18:0,2 - Array of strings
  • NST34:0 - String that has been copied with the COP instruction to an integer data type

Note that some values are not supported in an array - timer presets and accumulators are an example, but entire timers are fine for READ ONLY.

In the example above, an object is declared and the translator references that object. It could just as reference a file or database. In any case, it allows cleaner Javascript code to be written that refers to a name instead of an absolute address.

depaula_eip.addItems(items)

Adds items to the internal read polling list.

items can be a string or an array of strings.

depaula_eip.removeItems(items)

Removes items to the internal read polling list.

items can be a string or an array of strings.

depaula_eip.writeItems(items, values)

Writes items to the device using the corresponding values.

items can be a string or an array of strings. If items is a single string, values should then be a single item (or an array if items is an array item). If items is an array of strings, values must be an array.

You should monitor the return value - if it is non-zero, the write will not be processed as there is already one it progress, and the callback will not be called.

depaula_eip.readAllItems(callback)

Reads the internal polling list and calls callback when done.

callback(err, values) is called with two arguments - a boolean indicating if ANY of the items have "bad quality", and values, an object containing the values being read as keys and their value (from the device) as the value.

depaula_eip.findItem(item)

Returns the item object being searched for (by iterating through the array of items), or undefined if it isn't found in the item list. This allows accessing item.value and item.quality.