eip

EtherNet/IP client for reading data files from Allen-Bradley style PLCs.

The eip object speaks EtherNet/IP in both directions:

  • Clienteip.connect() / eip.read() read PLC data files. Files are addressed by a type prefix and number — F, O, I, S, B, T, R, N depending on type (e.g. "F103" for float file 103). Returned data is a packed binary buffer parsed with the bin reader functions.
  • Servereip.handle() answers incoming EtherNet/IP read and write requests from a PLC, letting the device appear as a data file the PLC polls and commands directly.

Functions

eip.connect()

eip.connect(ip) → number

Connects to a PLC over EtherNet/IP.

Arguments

NameTypeRequiredDefaultDescription
ip string yes PLC IP address, e.g. "192.168.168.1".

Returns

number 0 = connected, otherwise an error code.

Example

if(eip.connect("192.168.168.1") === 0){
  // read files ...
  eip.disconnect();
} else {
  print("PLC Connection Failed");
}

eip.read()

eip.read(file, offset, bytes) → { status, data }

Reads bytes from a PLC data file.

Reads bytes starting at element offset of the addressed file. Parse the returned buffer with string.seek() and string.read().

Arguments

NameTypeRequiredDefaultDescription
file string yes File address with type prefix (F,O,I,S,B,T,R,N) + number, e.g. "F103".
offset number yes Starting element offset within the file.
bytes number yes Number of bytes to read, e.g. 4*4 for four 32-bit floats.

Returns

object { status, data } — status 0 = success; data is a bin buffer.

Example

let res = eip.read("F103", 1, 4*4); // four 4-byte floats

if(res.status === 0){
  res.data.seek(0); // Position our cursor at the start of the data
  let plc = {
    flow:      res.data.read("F32ABCD"),
    pressure:  res.data.read(), // No format specified, use the last specified format
    pumpSpeed: res.data.read(),
    temp:      res.data.read(),
    lastUpdated: now()
  };
  print(string(plc));
} else {
  print("PLC Read Failed");
}

eip.handle()

eip.handle(handler)

Answers incoming EtherNet/IP read and write requests from a PLC.

Registers a handler for EtherNet/IP requests arriving at the device. The request object provides:

Field Meaning
req.file The requested file address (e.g. "F103").
req.bytes Read requests: the byte length of the requested data.
req.data Write requests: a bin buffer with the written data. Absent on reads.

Write requests (req.data present): parse the buffer with req.data.seek() / req.data.read() and apply the values — e.g. unpack a PLC status word into individual io flags with bit masks.

Read requests: build a response with bin.alloc() and the buffer write methods (including the "BIT" format for packing status bits), then return the buffer.

Arguments

NameTypeRequiredDefaultDescription
handler function yes Callback function(req){ … } — return a bin buffer to answer read requests.

Example

eip.handle(function(req){          // handle incoming EtherNet/IP requests
  if(req.data){                    // write request
    req.data.seek(0);
    let status = req.data.read("U16AB");
    io.PALL = {
      feedEnable:  status & 1,
      masterAlarm: (status & (1<<5)) > 0,
      flowAvailable: req.data.read("U16AB") / 0.2777778
    };
  } else {                         // read request — build and return a reply
    let buff = bin.alloc(100);
    buff.write("BIT", [0, io.p304.running, io.p303.running, 0,0,0,0,0, 0,0,0,0,0,0,0,0]);
    buff.write("U16AB", [151.2 * 0.2777778, io.clearwellLevel701.inst * 10]);
    return buff;
  }
});

eip.disconnect()

eip.disconnect()

Ends the EtherNet/IP connection.

Example

eip.disconnect();