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

codesys-client

v0.1.1

Published

Node.js Codesys client for reading and writing PLC data using network variable lists (NVL)

Downloads

65

Readme

codesys-client

npm version GitHub License

Node.js Codesys client for reading and writing PLC data using network variable lists (NVL).

Uses my other library iec-61131-3 (MIT) to convert between Javascript and PLC variables.

Supports arbitrary length data including single variables, structs, single- and multi-dimensional arrays and so on.

Inspiration from Network Functionality in CoDeSys V2.3 (PDF) (https://forge.codesys.com/forum/en/124/genmed-Network_Functionality_V23.pdf) and EasyNetVars C# library (https://sourceforge.net/projects/easynetvars/).

Project status

This project is in early stage. Do not use this for anything critical!

Things that should work

  • Receiving (reading) any kind of variables
  • Sending (writing) any kind of variables

Things to do until releasing version 1.0.0

  • Testing more use cases
  • More error checking
  • Adding some basic end-to-end tests using Jest
  • Improving network variable list definition exporter
  • Updating EADME with more examples
  • Adding possibility to access received raw data

This to do at some point

  • Adding checksum feature (need to find out how it is calculated)
  • Adding "Use acknowledged transfer" support to makse sure write is successful

Table of contents

Installing

Install the npm package using npm command:

npm i codesys-client

Example: Receiving (reading) data

Codesys PLC side

  1. Create network variable list (sender)

    • Select UDP as network type
    • Enter desired Listidentifier number (listID in codesys-client)
    • Enable Pack variables to optimize data usage
    • Set transimission interval etc. to desired values

    image

  2. Edit UDP settings pressing Settings... button

    • Keep Port as default value 1202 or change it to something else
      • NOTE: When running soft-PLC and codesys-client on the same system, the PLC is most probably reserving default port --> you need to use different port.
      • In this example port is set to 12020 --> codesys-client needs to listen to that port.
    • Keep Broadcast Adr. as default 255.255.255.255 unless you want to send the data to a specific IP only
      • 255.255.255.255 -> data is sent to whole network

    image

  3. Accept settings and press Add

  4. Add variables to network variable list

    • You can add separate variables or encapsulate all data under one STRUCT
    • Encapsulating might be a good idea as in codesys-client you will need one "master object" to contain all data

    image

    NVL_SendTest:

    {attribute 'qualified_only'}
    VAR_GLOBAL
      DataToSend : ST_DataToSend;
    END_VAR

    ST_DataToSend:

    TYPE ST_DataToSend :
    STRUCT
      IntValue  : INT := 12345;
      RealValue	: REAL := 3.14;
      StringValue	: STRING := 'Hello from Codesys PLC';
      ArrValue	: ARRAY[0..4] OF INT := [1, 2, 3, 4, 5];
      StructValue	: ST_ChildStruct;
    END_STRUCT
    END_TYPE

    ST_ChildStruct:

    TYPE ST_ChildStruct :
    STRUCT
      StringValue2 : STRING(255) := 'Hi from child struct';
      ArrayOfArray : ARRAY[1..2] OF ARRAY[1..2] OF INT := [[1, 2,], [3, 4]];
    END_STRUCT
    END_TYPE
  5. PLC side is ready. Download program and set it to run.

Javascript/codesys-client side

  1. Install library using npm i codesys-client
  2. Add the following to file (example-receive.js for example) and then run it using node example-receive.js
const { Receiver } = require('codesys-client');
const iec = require('iec-61131-3');

const util = require('util'); //util needed only for demo purposes

//Setting up new receiver
const receiver = new Receiver({
  ListeningPort: 12020 //UDP port defined in PLC (see above)
});

//Creating IEC datatype schema
//See https://github.com/jisotalo/iec-61131-3 for more info
//Note that default values have no meaning here (just copy-pasted)
const ST_DataToSend = iec.fromString(`
  TYPE ST_DataToSend :
  STRUCT
    IntValue 	: INT := 12345;
    RealValue	: REAL := 3.14;
    StringValue	: STRING := 'Hello from Codesys PLC';
    ArrValue	: ARRAY[0..4] OF INT := [1, 2, 3, 4, 5];
    StructValue	: ST_ChildStruct;
  END_STRUCT
  END_TYPE

  TYPE ST_ChildStruct :
  STRUCT
    StringValue2 : STRING(255) := 'Hi from child struct';
    ArrayOfArray : ARRAY[1..2] OF ARRAY[1..2] OF INT := [[1, 2], [3, 4]];
  END_STRUCT
  END_TYPE
`, 'ST_DataToSend');

//Adding data handler(s)
receiver.addHandler(50, ST_DataToSend, (data) => {
  //data is now as object that matches ST_DataToSend
  //Using util.inspect to display the whole object for demo purposes
  console.log(new Date(), `- received data for listID 50:`, util.inspect(data, false, 999));
});

//Starting to listen for incoming data
receiver.listen()
  .then(res => console.log(`Listening UDP now to:`, res))
  .catch(err => console.log(`Failed to start listening. Error:`, err));

/*
Console output:

Listening UDP now to: { address: '0.0.0.0', family: 'IPv4', port: 12020 }
2022-07-27T14:41:05.332Z - received data for listID 50: {
  IntValue: 12345,
  RealValue: 3.140000104904175,
  StringValue: 'Hello from Codesys PLC',
  ArrValue: [ 1, 2, 3, 4, 5 ],
  StructValue: {    StringValue2: 'Hi from child struct',
    ArrayOfArray: [ [ 1, 2 ], [ 3, 4 ] ]
  }
}
2022-07-27T14:41:06.323Z - received data for listID 50: {
  IntValue: 12345,
  RealValue: 3.140000104904175,
  StringValue: 'Hello from Codesys PLC',
  ArrValue: [ 1, 2, 3, 4, 5 ],
  StructValue: {    StringValue2: 'Hi from child struct',
    ArrayOfArray: [ [ 1, 2 ], [ 3, 4 ] ]
  }
}
*/

Example: Sending (writing) data

The sending of the data is a little bit more complicated from codeys PLC side as the network variable list needs to be imported from .GVL file.

Creating GVL file

  1. Open web page https://jisotalo.github.io/others/nvl-file-generator.html or nvl-file-generator.html in the root directory.
  2. Enter details and copy-paste variable declaration for network variable list
    • Filename: NVL_ReceiveTest.GVL
    • List ID: 100
    • UDP port: 12023
    • Declaration:
{attribute 'qualified_only'}
VAR_GLOBAL
  DataToReceive : ST_Data;
END_VAR
  1. Press Download .GVL file and save the produced file locally somewhere (will be used in next chapter).

image

Codesys PLC side

  1. Create network variable list (receiver)

    • Set name as NVL_ReceiveTest
    • Select previously create NVL_ReceiveTest.GVL file

    image

  2. Press Add. The NVL is now added.

    image

  3. Download PLC software and set it to run mode

Javascript/codesys-client side

  1. (Install library using npm i codesys-client if not yet installed)
  2. Add the following to file (example-send.js for example)
const { Sender } = require('codesys-client');
const iec = require('iec-61131-3');

//Setting up new sender
const sender = new Sender({
  targetPort: 12023 //UDP port defined in NVL (see above)
});

//Creating IEC datatype schema
//See https://github.com/jisotalo/iec-61131-3 for more info
//Note that default values have no meaning here (just copy-pasted)
const ST_Data = iec.fromString(`
  TYPE ST_Data :
  STRUCT
    IntValue 	: INT := 12345;
    RealValue	: REAL := 3.14;
    StringValue	: STRING := 'Hello from Codesys PLC';
    ArrValue	: ARRAY[0..4] OF INT := [1, 2, 3, 4, 5];
    StructValue	: ST_ChildStruct;
  END_STRUCT
  END_TYPE

  TYPE ST_ChildStruct :
  STRUCT
    StringValue2 : STRING(255) := 'Hi from child struct';
    ArrayOfArray : ARRAY[1..2] OF ARRAY[1..2] OF INT := [[1, 2], [3, 4]];
  END_STRUCT
  END_TYPE
`, 'ST_Data');

const data = {
  IntValue: 0,
  RealValue: 12345.67,
  StringValue: 'Hello from Node.js',
  ArrValue: [99, 88, 77, 66, 55],
  StructValue: {
    StringValue2: 'Example value from Node.js',
    ArrayOfArray: [[9, 8], [7, 6]]
  }
};

setInterval(() => {
  //Updating some values to see result at PLC
  data.IntValue = new Date().getSeconds();
  data.StructValue.ArrayOfArray[0][1] = new Date().getSeconds();

  sender.send(100, ST_Data, data)
    .then(() => console.log(`Data sent!`))
    .catch(err => console.log(`Failed to send data. Error:`, err));
}, 1000);
  1. Start the script node example-send.js
  2. The values are written every 1s and the result can be seen from PLC:

image

Problems

If you have any problems, check

  • UDP ports used
  • Data type schemas (are they 1:1)
  • List IDs
  • etc.

Then double check again..

License

Licensed under MIT License so commercial use is possible. Please respect the license, linking to this page is also much appreciated.

Copyright (c) 2022 Jussi Isotalo <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.