Node.JS library for communication to Siemens S7 PLCs
NodeS7 is a library that allows communication to S7-300/400/1200/1500 PLCs using the Siemens S7 Ethernet protocol RFC1006.
This software is not affiliated with Siemens in any way, nor am I. S7-300, S7-400, S7-1200 and S7-1500 are trademarks of Siemens AG.
Fully test everything you do. In situations where writing to a random area of memory within the PLC could cost you money, back up your data and test this really well. If this could injure someone or worse, consider other software.
Using npm:
npm install nodes7Using yarn:
yarn add nodes7It is optimized in three ways - It sorts a large number of items being requested from the PLC and decides what overall data areas to request, then it groups multiple small requests together in a single packet or number of packets up to the maximum length the PLC supports, then it sends multiple packets at once, for maximum speed. So a request for 100 different bits, all close (but not necessarily completely contiguous) will be grouped in one single request to the PLC, with no additional direction from the user.
NodeS7 manages reconnects for you. So if the connection is lost because the PLC 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.
NodeS7 is written entirely in Javascript, so no compiler installation is necessary on Windows, and deployment on other platforms (ARM, etc) should be no problem.
S7-1200 and S7-1500 CPU access requires access using "Slot 1" and you must disable optimized block access (in TIA portal) for the blocks you are using. In addition, you must "Enable GET/PUT Access" in the 1200/1500 controller in TIA Portal. Doing so opens up the controller for other access by other applications as well, so be aware of the security implications of doing this.
This has been tested on direct connections to newer PROFINET CPUs and Helmholz NetLINK PRO COMPACT and IBH units. (Note with these gateways you often have to specify the MPI address as the slot number) It is reported to work with other CPU/CP combinations as well, although not all S7-200 datatypes are supported. S7 routing is not supported.
Logo 0BA8 PLCs are supported although you should set your local and remote TSAP to match your project, and your addresses have to be specified differently. DB1,INT0 should get VM0. DB1,INT1118 should get AM1.
conn = new nodes7; (or similar) then add conn.doNotOptimize = true; to ensure this isn't done, and don't try to request these items using array notation as this implies optimization, request REAL0 then REAL1 etc. doNotOptimize is now also supported as a connection parameter.Credit to the S7 Wireshark dissector plugin for help understanding why things were not working. (http://sourceforge.net/projects/s7commwireshark/)
…
Connects to a PLC.
Options
| Property | type | default |
|---|---|---|
| rack | number | 0 |
| slot | number | 2 |
| port | number | 102 |
| host | string | 192.168.8.106 |
| timeout | number | 5000 |
| localTSAP | hex | undefined |
| remoteTSAP | hex | undefined |
callback(err)
err
err is either an error object, or undefined on successful connection.
Disconnects from a PLC. This simply terminates the TCP connection.
callback()
The callback is called upon completion of the close.
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:
``
The DT type is the well-known DATE_AND_TIME type of S7-300/400 PLCs, a 8-byte-wide field with BCD-encoded parts
The DTZ type is the same as the DT, but it expects that the timestamp is in UTC in the PLC (usually NOT the case)
The DTL type is the one seen on newer S7-1200/1500 PLCs, is 12-byte long and encodes the timestamp differently than the older DATE_AND_TIME
The DTLZ type is also the same as the DTL, but expecting the timestamp in UTC in the PLC
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.
Adds items to the internal read polling list.
items can be a string or an array of strings.
If items includes the value _COMMERR it will return current communication status.
Removes items to the internal read polling list.
items can be a string or an array of strings.
If items is not defined then all items are removed.
Writes items to the PLC using the corresponding values and calls callback when done.
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.
items can be a string or an array of strings.
If items is a single string, values should then be a single item.
If items is an array of strings, values must also be an array of values.
callback(err)
err a boolean indicating if ANY of the items have "bad quality".
Reads the internal polling list and calls callback when done.
callback(err, values)
err a boolean indicating if ANY of the items have "bad quality". values an object containing the values being read as keys and their value (from the PLC) as the value.
No open issues yet, or sync has not completed.