EtherNet/IP Server (PLC Handler)
Answers EtherNet/IP requests from a PLC with eip.handle(): write requests
unpack a status word into individual io flags using bit masks, and read
requests build a binary reply with bin.alloc(), the "BIT" bit-packing
format and "U16AB" registers.
eip.handle(function(req){ // handle incoming EtherNet/IP read and write requests
if(req.data){ // Is this a write request with write data?
print("EtherIP Write Request");
print("EIP File", req.file);
print("EIP Payload:", bin.toHex(req.data));
req.data.seek(0);
let status = req.data.read("U16AB");
io.PALL = {
_lu: now(),
skidInletValveD: (status & (1<<11)) > 0,
skidInletValveC: (status & (1<<10)) > 0,
skidInletValveB: (status & (1<<9)) > 0,
skidInletValveA: (status & (1<<8)) > 0,
chnMasterAlarm: (status & (1<<6)) > 0,
masterAlarm: (status & (1<<5)) > 0,
skidDAlarm: (status & (1<<4)) > 0,
skidCAlarm: (status & (1<<3)) > 0,
skidBAlarm: (status & (1<<2)) > 0,
skidAAlarm: (status & (1<<1)) > 0,
feedEnable: status & 1,
flowAvailable: req.data.read("U16AB") / 0.2777778,
skidAStatus: req.data.read(), // read using the same previously defined structure
skidBStatus: req.data.read(),
skidCStatus: req.data.read(),
};
req.data.seek(100);
io.PALL.inletTurbidity = req.data.read();
} else {
// Read request.
print("EtherIP Read Request");
print("EIP File", req.file);
print("EIP Bytes:", req.bytes); // the byte length of the requested data
let pallW = {
highClearwellAlarm: alm.v("Clearwell") >= alm.warn,
highPressAlarm: alm.fV("PALL Intake","Inlet Pressure High") > 0,
filterOutputPermission: true,
flowRequest: 151.1999 * pallProcess.pumpsRunningCount.limit(1,4) // m3/h
};
let buff = bin.alloc(100); // empty 100-byte buffer; the read/write cursor is positioned on it automatically
buff.write("BIT", [0, io.p304.running, io.p303.running, io.p302.running, io.p301.running,
pallW.highClearwellAlarm, pallW.highPressAlarm, pallW.filterOutputPermission,
0,0,0,0,0,0,0,0]); // write our statuses as bits
buff.write("U16AB", [pallW.flowRequest * 0.2777778,
io.clearwellLevel701.inst * 10]); // flow request + clearwell level as U16s
return buff; // return our binary data
}
});