diff --git a/mstp-serial/pom.xml b/mstp-serial/pom.xml new file mode 100644 index 0000000..9cb9bbb --- /dev/null +++ b/mstp-serial/pom.xml @@ -0,0 +1,53 @@ + + + + 4.0.0 + + + org.code-house.bacnet4j + bacnet4j-wrapper + 1.3.0-SNAPSHOT + + + mstp-serial + bundle + + Code-House :: Bacnet4J Wrapper :: MSTP Serial adapter + Universal serial adapter for MSTP client. + + + + org.code_house.bacnet4j.wrapper.mstp, + * + + + org.code_house.bacnet4j.wrapper.mstp + + + + + + org.code-house.bacnet4j + mstp + + + org.opensmarthouse + purejavacomm + + + com.infiniteautomation + bacnet4j + + + + org.slf4j + slf4j-log4j12 + test + + + log4j + log4j + + + + \ No newline at end of file diff --git a/mstp-serial/src/main/java/org/code_house/bacnet4j/wrapper/mstp/serial/MstpSerialNetworkBuilder.java b/mstp-serial/src/main/java/org/code_house/bacnet4j/wrapper/mstp/serial/MstpSerialNetworkBuilder.java new file mode 100644 index 0000000..2bddfd0 --- /dev/null +++ b/mstp-serial/src/main/java/org/code_house/bacnet4j/wrapper/mstp/serial/MstpSerialNetworkBuilder.java @@ -0,0 +1,116 @@ +/* + * (C) Copyright 2023 Code-House and others. + * + * bacnet4j-wrapper is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * https://www.gnu.org/licenses/gpl-3.0.txt + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +package org.code_house.bacnet4j.wrapper.mstp.serial; + +import com.serotonin.bacnet4j.npdu.mstp.MasterNode; +import com.serotonin.bacnet4j.npdu.mstp.MstpNetwork; +import com.serotonin.bacnet4j.util.sero.SerialPortWrapper; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import org.code_house.bacnet4j.wrapper.mstp.MstpNetworkBuilder; +import purejavacomm.CommPort; +import purejavacomm.CommPortIdentifier; +import purejavacomm.SerialPort; + +public class MstpSerialNetworkBuilder extends MstpNetworkBuilder { + + private final SerialPortManager serialPortManager; + + public MstpSerialNetworkBuilder(SerialPortManager serialPortManager) { + this.serialPortManager = serialPortManager; + } + + @Override + public MstpNetwork build() throws Exception { + CommPortIdentifier identifier = serialPortManager.getIdentifier(getSerialPort()); + + MasterNode node = new MasterNode(new ManagedSerialPort(identifier, getBaud(), getDataBits(), getStopBits(), getParity()), + (byte)this.getStation(), 2); + node.setMaxInfoFrames(5); + node.setUsageTimeout(100); + return new MstpNetwork(node, 0); + } + + static class ManagedSerialPort extends SerialPortWrapper { + + private final CommPortIdentifier identifier; + private final int baud; + private final int dataBits; + private final int stopBits; + private final int parity; + private SerialPort port; + + ManagedSerialPort(CommPortIdentifier port, int baud, int dataBits, int stopBits, int parity) { + this.identifier = port; + this.baud = baud; + this.dataBits = dataBits; + this.stopBits = stopBits; + this.parity = parity; + } + + @Override + public void close() throws Exception { + if (port != null) { + port.close(); + } + } + + @Override + public void open() throws Exception { + CommPort port = identifier.open("bacnet4j-wrapper", 2000); + if (!(port instanceof SerialPort)) { + throw new IllegalStateException("Given port is not a serial port"); + } + + this.port = (SerialPort) port; + this.port.setSerialPortParams(baud, dataBits, stopBits, parity); + } + + @Override + public InputStream getInputStream() { + if (port != null) { + try { + return port.getInputStream(); + } catch (IOException e) { + throw new RuntimeException("Could not open input stream for port " + identifier.getName(), e); + } + } + return null; + } + + @Override + public OutputStream getOutputStream() { + if (port != null) { + try { + return port.getOutputStream(); + } catch (IOException e) { + throw new RuntimeException("Could not open output stream for port " + identifier.getName(), e); + } + } + return null; + } + + @Override + public String getCommPortId() { + return identifier.getName(); + } + } +} diff --git a/mstp-serial/src/main/java/org/code_house/bacnet4j/wrapper/mstp/serial/SerialPortManager.java b/mstp-serial/src/main/java/org/code_house/bacnet4j/wrapper/mstp/serial/SerialPortManager.java new file mode 100644 index 0000000..3e9e0c1 --- /dev/null +++ b/mstp-serial/src/main/java/org/code_house/bacnet4j/wrapper/mstp/serial/SerialPortManager.java @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2023 Code-House and others. + * + * bacnet4j-wrapper is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * https://www.gnu.org/licenses/gpl-3.0.txt + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +package org.code_house.bacnet4j.wrapper.mstp.serial; + +import purejavacomm.CommPortIdentifier; +import purejavacomm.NoSuchPortException; + +public class SerialPortManager { + + public CommPortIdentifier getIdentifier(String serialPort) throws NoSuchPortException { + return CommPortIdentifier.getPortIdentifier(serialPort); + } + +} diff --git a/mstp-serial/src/test/java/org/code_house/bacnet4j/wrapper/mstp/serial/MstpSerialNetworkBuilderMain.java b/mstp-serial/src/test/java/org/code_house/bacnet4j/wrapper/mstp/serial/MstpSerialNetworkBuilderMain.java new file mode 100644 index 0000000..9ba8272 --- /dev/null +++ b/mstp-serial/src/test/java/org/code_house/bacnet4j/wrapper/mstp/serial/MstpSerialNetworkBuilderMain.java @@ -0,0 +1,54 @@ +/* + * (C) Copyright 2023 Code-House and others. + * + * bacnet4j-wrapper is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * https://www.gnu.org/licenses/gpl-3.0.txt + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +package org.code_house.bacnet4j.wrapper.mstp.serial; + +import org.code_house.bacnet4j.wrapper.api.Device; +import org.code_house.bacnet4j.wrapper.api.DeviceDiscoveryListener; +import org.code_house.bacnet4j.wrapper.mstp.BacNetMstpClient; +import org.code_house.bacnet4j.wrapper.mstp.MstpNetworkBuilder; + +/** + * Test of mstp client with serial adapter based on purejavacomm. + */ +class MstpSerialNetworkBuilderMain { + + public static void main(String[] args) throws Exception { + BacNetMstpClient client = new BacNetMstpClient( + new MstpSerialNetworkBuilder(new SerialPortManager()) + .withSerialPort("/dev/ttyUSB0") + .withBaud(9600) + .withDataBits((short) 8) + .withStopBits((short) 1) + .build(), + 1339 + ); + client.listenForDevices(new DeviceDiscoveryListener() { + @Override + public void deviceDiscovered(Device device) { + System.out.println("Device discovered " + device); + } + }); + + client.start(); + System.in.read(); + client.stop();; + } + +} \ No newline at end of file diff --git a/mstp/pom.xml b/mstp/pom.xml index 677ca17..95b2846 100644 --- a/mstp/pom.xml +++ b/mstp/pom.xml @@ -17,7 +17,7 @@ - jssc;resolution:=optional, + !jssc, * @@ -30,11 +30,6 @@ org.code-house.bacnet4j api - - org.scream3r - jssc - 2.8.0 - org.slf4j diff --git a/pom.xml b/pom.xml index e8bb363..3c9cbb9 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ api ip mstp + mstp-serial assembly @@ -61,6 +62,7 @@ 6.0.0 1.0.0 1.1.0 + 1.0.5 1.7.12 1.2.17 @@ -137,6 +139,11 @@ commons-lang3 ${commons-lang3.version} + + org.opensmarthouse + purejavacomm + ${purejavacomm.version} + org.slf4j