npm promotes metadefinitions

    ethernet-ip

    1.2.5 • Public • Published

    Vue logo

    npm Gitter license Travis Coveralls github Known Vulnerabilities GitHub stars

    Node Ethernet/IP

    A simple and lightweight node based API for interfacing with Rockwell Control/CompactLogix PLCs.

    Prerequisites

    latest version of NodeJS

    Getting Started

    Install with npm

    npm install ethernet-ip --save
    

    The API

    How the heck does this thing work anyway? Great question!

    The Basics

    Getting Connected

    const { Controller } = require("ethernet-ip");
     
    const PLC = new Controller();
     
    // Controller.connect(IP_ADDR[, SLOT])
    // NOTE: SLOT = 0 (default) - 0 if CompactLogix
    PLC.connect("192.168.1.1", 0).then(() => {
        console.log(PLC.properties);
    });

    Controller.properties Object

     {
        name: String, // eg "1756-L83E/B"
        serial_number: Number, 
        slot: Number,
        time: Date, // last read controller WallClock datetime
        path: Buffer,
        version: String, // eg "30.11"
        status: Number,
        faulted: Boolean,  // will be true if any of the below are true
        minorRecoverableFault: Boolean,
        minorUnrecoverableFault: Boolean,
        majorRecoverableFault: Boolean,
        majorUnrecoverableFault: Boolean,
        io_faulted: Boolean
    }

    Set the Clock of the Controller

    NOTE Controller.prototype.readWallClock and Controller.prototype.writeWallClock are experimental features and may not be available on all controllers. 1756-L8 ControlLogix Controllers are currently the only PLCs supporting these features.

    Sync Controller WallClock to PC Datetime

    const { Controller } = require("ethernet-ip");
     
    const PLC = new Controller();
     
    PLC.connect("192.168.1.1", 0).then(async () => {
        // Accepts a JS Date Type
        // Controller.writeWallClock([Date])
        await PLC.writeWallClock(); // Defaults to 'new Date()'
    });

    Set Controller WallClock to a Specific Date

    const { Controller } = require("ethernet-ip");
     
    const PLC = new Controller();
     
    PLC.connect("192.168.1.1", 0).then(async () => {
        const partyLikeIts1999 = new Date('December 17, 1999 03:24:00');
        await PLC.writeWallClock(partyLikeIts1999); // Pass a custom Datetime
    });

    Reading Tags

    NOTE: Currently, the Tag Class only supports Atomic datatypes (SINT, INT, DINT, REAL, BOOL). Not to worry, support for STRING, ARRAY, and UDTs are in the plans and coming soon! =]

    Reading Tags Individually...

    const { Controller, Tag } = require("ethernet-ip");
     
    const PLC = new Controller();
     
    // Create Tag Instances
    const fooTag = new Tag("contTag"); // Controller Scope Tag
    const barTag = new Tag("progTag", "prog"); // Program Scope Tag in PLC Program "prog"
     
    PLC.connect("192.168.1.1", 0).then(async () => {
        await PLC.readTag(fooTag);
        await PLC.readTag(barTag);
     
        console.log(fooTag.value);
        console.log(barTag.value);
    });

    Additional Tag Name Examples ...

    const fooTag = new Tag("Program:prog.progTag"); // Alternative Syntax for Program Scope Tag in PLC Program "prog"
    const barTag = new Tag("arrayTag[0]"); // Array Element
    const bazTag = new Tag("arrayTag[0,1,2]"); // Multi Dim Array Element
    const quxTag = new Tag("integerTag.0"); // SINT, INT, or DINT Bit
    const quuxTag = new Tag("udtTag.Member1"); // UDT Tag Atomic Member
    const quuzTag = new Tag("boolArray[0]", null, BIT_STRING); // bool array tag MUST have the data type "BIT_STRING" passed in

    Reading Tags as a Group...

    const { Controller, Tag, TagGroup } = require("ethernet-ip");
     
    const PLC = new Controller();
    const group = new TagGroup();
     
    // Add some tags to group
    group.add(new Tag("contTag")); // Controller Scope Tag
    group.add(new Tag("progTag", "prog")); // Program Scope Tag in PLC Program "prog"
     
    PLC.connect("192.168.1.1", 0).then(async () => {
        await PLC.readTagGroup(group);
     
        // log the values to the console
        group.forEach(tag => {
            console.log(tag.value);
        });
    });

    Writing Tags

    NOTE: You MUST read the tags first or manually provide a valid CIP datatype. The following examples are taking the latter approach.

    Writing Tags Individually...

    const { Controller, Tag, EthernetIP } = require("ethernet-ip");
    const { DINT, BOOL } = EthernetIP.CIP.DataTypes.Types;
     
    const PLC = new Controller();
     
    // Create Tag Instances
    const fooTag = new Tag("contTag", null, DINT); // Controller Scope Tag
    const barTag = new Tag("progTag", "prog", BOOL); // Program Scope Tag in PLC Program "prog"
     
    PLC.connect("192.168.1.1", 0).then(async () => {
     
        // First way to write a new value
        fooTag.value = 75;
        await PLC.writeTag(fooTag);
     
        // Second way to write a new value
        await PLC.writeTag(barTag, true);
     
        console.log(fooTag.value);
        console.log(barTag.value);
    });

    Writing Tags as a Group...

    const { Controller, Tag, TagGroup, EthernetIP } = require("ethernet-ip");
    const { DINT, BOOL } = EthernetIP.CIP.DataTypes.Types;
     
    const PLC = new Controller();
    const group = new TagGroup();
     
    // Create Tag Instances
    const fooTag = new Tag("contTag", null, DINT); // Controller Scope Tag
    const barTag = new Tag("progTag", "prog", BOOL); // Program Scope Tag in PLC Program "prog"
     
    group.add(fooTag); // Controller Scope Tag
    group.add(barTag); // Program Scope Tag in PLC Program "prog"
     
    PLC.connect("192.168.1.1", 0).then(async () => {
        // Set new values
        fooTag.value = 75;
        barTag.value = true;
     
        // Will only write tags whose Tag.controller_tag !== Tag.value
        await PLC.writeTagGroup(group);
     
        group.forEach(tag => {
            console.log(tag.value);
        });
    });

    Lets Get Fancy

    Subscribing to Controller Tags

    const { Controller, Tag } = require("ethernet-ip");
     
    const PLC = new Controller();
     
    // Add some tags to group
    PLC.subscribe(new Tag("contTag")); // Controller Scope Tag
    PLC.subscribe(new Tag("progTag", "prog")); // Program Scope Tag in PLC Program "prog"
     
    PLC.connect("192.168.1.1", 0).then(() => {
        // Set Scan Rate of Subscription Group to 50 ms (defaults to 200 ms)
        PLC.scan_rate = 50;
     
        // Begin Scanning
        PLC.scan();
    });
     
    // Catch the Tag "Changed" and "Initialized" Events
    PLC.forEach(tag => {
        // Called on the First Successful Read from the Controller
        tag.on("Initialized", tag => {
            console.log("Initialized", tag.value);
        });
     
        // Called if Tag.controller_value changes
        tag.on("Changed", (tag, oldValue) => {
            console.log("Changed:", tag.value);
        });
    });

    Demos

    • Monitor Tags for Changes Demo

    Simple Demo

    const { Controller, Tag } = require("ethernet-ip");
     
    // Intantiate Controller
    const PLC = new Controller();
     
    // Subscribe to Tags
    PLC.subscribe(new Tag("TEST_TAG"););
    PLC.subscribe(new Tag("TEST", "Prog"););
    PLC.subscribe(new Tag("TEST_REAL", "Prog"););
    PLC.subscribe(new Tag("TEST_BOOL", "Prog"););
     
    // Connect to PLC at IP, SLOT
    PLC.connect("10.1.60.205", 5).then(() => {
        const { name } = PLC.properties;
     
        // Log Connected to Console
        console.log(`\n\nConnected to PLC ${name}...\n`);
     
        // Begin Scanning Subscription Group
        PLC.scan();
    });
     
    // Initialize Event Handlers
    PLC.forEach(tag => {
        tag.on("Changed", (tag, lastValue) => {
            console.log(`${tag.name} changed from ${lastValue} -> ${tag.value}`);
        });
    })

    Built With

    Contributers

    Related Projects

    Wanna become a contributor? Here's how!

    License

    This project is licensed under the MIT License - see the LICENCE file for details

    Install

    npm i ethernet-ip

    DownloadsWeekly Downloads

    858

    Version

    1.2.5

    License

    MIT

    Unpacked Size

    109 kB

    Total Files

    27

    Last publish

    Collaborators

    • cmseaton42