From 960ee4891078c55fdef38c0e4228f9e0c1063d77 Mon Sep 17 00:00:00 2001 From: Peter Quiring Date: Mon, 6 Jan 2025 11:57:49 -0500 Subject: [PATCH] add plc4j s7 driver --- build.xml | 3 + get-jars.xml | 12 +++ install-jars.xml | 8 ++ src/javaforce/controls/Controller.java | 118 +++++++++++++++++---- src/javaforce/controls/ControllerType.java | 1 + src/javaforce/controls/ReadTag.java | 36 ++++--- src/javaforce/controls/WriteTag.java | 62 ++++++----- 7 files changed, 176 insertions(+), 64 deletions(-) diff --git a/build.xml b/build.xml index d4b8686ea..aa3948099 100755 --- a/build.xml +++ b/build.xml @@ -105,7 +105,10 @@ + + + diff --git a/get-jars.xml b/get-jars.xml index 681f499c3..2b71004eb 100644 --- a/get-jars.xml +++ b/get-jars.xml @@ -212,6 +212,16 @@ + + + + + + + + + + @@ -255,5 +265,7 @@ + + diff --git a/install-jars.xml b/install-jars.xml index 5d705ae3b..05a14cad7 100644 --- a/install-jars.xml +++ b/install-jars.xml @@ -168,4 +168,12 @@ + + + + + + + + diff --git a/src/javaforce/controls/Controller.java b/src/javaforce/controls/Controller.java index 3d220aa94..1274e8a55 100755 --- a/src/javaforce/controls/Controller.java +++ b/src/javaforce/controls/Controller.java @@ -11,6 +11,7 @@ import java.io.*; import java.net.*; import java.util.*; +import java.util.concurrent.*; import javaforce.*; import javaforce.controls.s7.*; @@ -21,13 +22,20 @@ import javaforce.media.*; import org.apache.plc4x.java.api.*; +import org.apache.plc4x.java.api.messages.*; +import org.apache.plc4x.java.api.model.*; +import org.apache.plc4x.java.api.types.*; +import org.apache.plc4x.java.api.value.*; public class Controller { private boolean connected; private Socket socket; private InputStream is; private OutputStream os; - private int plc; + private PlcConnection plcConn; + private PlcDriver plcDrv; + private int plcType; + private int plcSubType; private DAQmx daq; private Object lock = new Object(); //read/write lock private static Object s7_connect_lock = new Object(); @@ -56,15 +64,13 @@ public void setTimeout(int ms) { timeout = ms; } - /** Connects to a PLC. */ - - /* + /** Connects to a PLC. * - * url = "S7:host" - * url = "MODBUS:host" - * url = "AB:host" - * url = "NI:device/options" - * url = "MIC:name" (int16 data type , will use default mic) + * url = "S7://host" + * url = "MODBUS://host" + * url = "AB://host" + * url = "NI://device/options" + * url = "MIC://name" (int16 data type , %lt;default%gt; will use default mic) * */ public boolean connect(String url) { @@ -74,8 +80,26 @@ public boolean connect(String url) { JFLog.log("Controller:connect():url == null"); return false; } + if (url.contains("://")) { + //Apache PLC4J + plcType = ControllerType.PLC4J; + int idx = url.indexOf(':'); + String driver = url.substring(0, idx).toUpperCase(); + switch (driver) { + case "S7": plcSubType = ControllerType.S7; break; + case "AB": plcSubType = ControllerType.AB; break; + } + try { + plcConn = PlcDriverManager.getDefault().getConnectionManager().getConnection(url); + plcDrv = PlcDriverManager.getDefault().getDriver(driver); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } if (url.startsWith("S7:")) { - plc = ControllerType.S7; + plcType = ControllerType.S7; String host = url.substring(3); synchronized(s7_connect_lock) { try { @@ -121,7 +145,7 @@ public boolean connect(String url) { return true; } if (url.startsWith("MODBUS:")) { - plc = ControllerType.MB; + plcType = ControllerType.MB; String host = url.substring(7); try { connect(host, 502); @@ -137,7 +161,7 @@ public boolean connect(String url) { } if (url.startsWith("AB:")) { ab_context = new ABContext(); - plc = ControllerType.AB; + plcType = ControllerType.AB; String host = url.substring(3); try { connect(host, 44818); @@ -170,7 +194,7 @@ public boolean connect(String url) { return true; } if (url.startsWith("NI:")) { - plc = ControllerType.NI; + plcType = ControllerType.NI; daq = new DAQmx(); connected = daq.connect(url.substring(3)); if (!connected) { @@ -180,7 +204,7 @@ public boolean connect(String url) { return connected; } if (url.startsWith("MIC:")) { - plc = ControllerType.MIC; + plcType = ControllerType.MIC; mic = new AudioInput(); micBufferSize = (int)(44100.0 / (1000.0 / rate)); micBuffer = new short[micBufferSize]; @@ -217,7 +241,7 @@ public void setSOCKS(String host) { /** Disconnects from PLC. */ public boolean disconnect() { if (!connected) return false; - switch (plc) { + switch (plcType) { case ControllerType.S7: case ControllerType.MB: case ControllerType.AB: @@ -288,7 +312,7 @@ public boolean write(String addr, byte[] data, datatype type) { addr = addr.toUpperCase(); synchronized(lock) { if (!connected) return false; - switch (plc) { + switch (plcType) { case ControllerType.S7: { S7Data s7 = S7Packet.decodeAddress(addr); if (s7.data_type == S7Types.BIT) { @@ -428,7 +452,27 @@ public byte[] read(String addr) { addr = addr.toUpperCase(); synchronized(lock) { if (!connected) return null; - switch (plc) { + switch (plcType) { + case ControllerType.PLC4J: + try { + PlcReadRequest.Builder reader = plcConn.readRequestBuilder(); + switch (plcSubType) { + case ControllerType.S7: if (!addr.startsWith("%")) addr = "%" + addr; break; + } + //why is plcConn.parseTagAddress() @deprecated ? + PlcTag plcTag = plcDrv.prepareTag(addr); + reader.addTag("tag0", plcTag); + PlcReadResponse data = reader.build().execute().get(5000, TimeUnit.MILLISECONDS); + PlcValue value = data.getPlcValue("tag0"); + if (value != null) { + return value.getRaw(); + } else { + return empty; + } + } catch (Exception e) { + JFLog.log(e); + } + break; case ControllerType.S7: { S7Data s7 = S7Packet.decodeAddress(addr); if (s7 == null) return null; @@ -545,13 +589,45 @@ public byte[] read(String addr) { } } + private static byte[] empty = new byte[0]; + /** Reads multiple data tags from PLC. (only S7 is currently supported) */ public byte[][] read(String[] addr) { if (!connected) return null; for(int a=0;a