├── .gitignore
├── README.md
├── build
├── generic-tcp-driver-gateway
│ └── pom.xml
└── generic-tcp-driver-module
│ ├── license.html
│ └── pom.xml
├── pom.xml
└── src
├── doc
├── fo-custom.xsl
├── header-config-en.png
├── html-custom.xsl
├── manual-frame.html
├── manual-styles.css
├── message-config-en.png
├── module-manual.xml
└── writeback-config-en.png
├── main
└── java
│ └── com
│ └── chitek
│ ├── ignition
│ └── drivers
│ │ └── generictcp
│ │ ├── AbstractGenericTcpDriver.java
│ │ ├── GenericTcpClientDriver.java
│ │ ├── GenericTcpDriver.properties
│ │ ├── GenericTcpDriver_de.properties
│ │ ├── GenericTcpServerDriver.java
│ │ ├── IGenericTcpDriverContext.java
│ │ ├── ModuleHook.java
│ │ ├── configuration
│ │ ├── GenericTcpClientDriverType.java
│ │ ├── GenericTcpServerDriverType.java
│ │ └── settings
│ │ │ ├── GenericTcpClientDriverSettings.java
│ │ │ ├── GenericTcpClientDriverSettings.properties
│ │ │ ├── GenericTcpClientDriverSettings_de.properties
│ │ │ ├── GenericTcpServerDriverSettings.java
│ │ │ ├── GenericTcpServerDriverSettings.properties
│ │ │ ├── GenericTcpServerDriverSettings_de.properties
│ │ │ └── IGenericTcpDriverSettings.java
│ │ ├── folder
│ │ ├── BrowseTree.java
│ │ ├── DeviceStatusFolder.java
│ │ ├── FolderManager.java
│ │ ├── ISubscriptionChangeListener.java
│ │ ├── IndexMessageFolder.java
│ │ ├── MessageDataWrapper.java
│ │ ├── MessageFolder.java
│ │ ├── MessageHeader.java
│ │ ├── SimpleWriteFolder.java
│ │ ├── StatusFolder.java
│ │ └── SubscriptionUpdater.java
│ │ ├── io
│ │ ├── ClientEventHandler.java
│ │ ├── IIoEventHandler.java
│ │ ├── IMessageHandler.java
│ │ ├── MessageState.java
│ │ ├── NioEventHandler.java
│ │ ├── NioServer.java
│ │ ├── NioTcpServer.java
│ │ ├── NioUdpServer.java
│ │ └── TimeoutHandler.java
│ │ ├── meta
│ │ └── config
│ │ │ ├── DriverConfig.java
│ │ │ ├── DriverSettings.java
│ │ │ ├── DriverSettingsPassive.java
│ │ │ ├── HeaderConfig.java
│ │ │ ├── HeaderTagConfig.java
│ │ │ ├── IDriverSettings.java
│ │ │ ├── MessageConfig.java
│ │ │ ├── TagConfig.java
│ │ │ ├── WritebackConfig.java
│ │ │ └── ui
│ │ │ ├── AbstractConfigUI.java
│ │ │ ├── ConfigUiTabs.html
│ │ │ ├── ConfigUiTabs.java
│ │ │ ├── HeaderConfigUI.html
│ │ │ ├── HeaderConfigUI.java
│ │ │ ├── HeaderConfigUI.properties
│ │ │ ├── HeaderConfigUI_de.properties
│ │ │ ├── MessageConfigUI.html
│ │ │ ├── MessageConfigUI.java
│ │ │ ├── MessageConfigUI.properties
│ │ │ ├── MessageConfigUI_de.properties
│ │ │ ├── SessionConfig.java
│ │ │ ├── WritebackConfigUI.html
│ │ │ ├── WritebackConfigUI.java
│ │ │ ├── WritebackConfigUI.properties
│ │ │ ├── WritebackConfigUI_de.properties
│ │ │ ├── res
│ │ │ ├── actionlinksnewarrow.gif
│ │ │ ├── close.gif
│ │ │ ├── configui.css
│ │ │ ├── help.gif
│ │ │ ├── indicator.gif
│ │ │ ├── maximize.gif
│ │ │ ├── row_delete.png
│ │ │ ├── row_down.png
│ │ │ ├── row_insert.png
│ │ │ └── row_up.png
│ │ │ ├── wicket-package.properties
│ │ │ └── wicket-package_de.properties
│ │ ├── tags
│ │ ├── ReadableArrayTag.java
│ │ ├── ReadableBoolArrayTag.java
│ │ ├── ReadableStringTag.java
│ │ ├── ReadableTcpDriverTag.java
│ │ └── WritableTag.java
│ │ ├── types
│ │ ├── BinaryDataType.java
│ │ ├── DriverState.java
│ │ ├── HeaderDataType.java
│ │ ├── MessageType.java
│ │ ├── OptionalDataType.java
│ │ ├── QueueMode.java
│ │ ├── RemoteDevice.java
│ │ ├── TagLengthType.java
│ │ └── WritebackDataType.java
│ │ └── util
│ │ ├── TestUtils.java
│ │ ├── Util.java
│ │ └── VariantByteBuffer.java
│ ├── util
│ ├── PersistentQueue.java
│ └── XMLConfigParser.java
│ └── wicket
│ ├── FeedbackTextField.java
│ ├── NonMatchStringValidator.java
│ └── listeditor
│ ├── EditorListItem.java
│ ├── EditorSubmitLink.java
│ ├── ListEditor.java
│ └── UniqueListItemValidator.java
└── test
├── java
└── com
│ └── chitek
│ ├── TestUtils
│ └── MockExecutor.java
│ └── ignition
│ └── drivers
│ └── generictcp
│ └── tests
│ ├── DriverTestSuite.java
│ ├── MockDriverContext.java
│ ├── MockExecutionManager.java
│ ├── TestUtils.java
│ ├── config
│ └── TestConfigParser.java
│ ├── folders
│ ├── FolderTestUtils.java
│ ├── MockMessageFolder.java
│ ├── MockReadItem.java
│ ├── MockSubscriptionItem.java
│ ├── MockWriteItem.java
│ ├── TestDeviceStatusFolder.java
│ ├── TestFolderManager.java
│ ├── TestMessageFolder.java
│ ├── TestSimpleWriteFolder.java
│ └── TestSubscription.java
│ └── io
│ ├── TestMessageState.java
│ ├── TestNioEventHandler.java
│ ├── TestNioServer.java
│ ├── TestNioUdpServer.java
│ └── TestTimeoutHandler.java
└── resources
├── log4j.properties
├── testHeaderConfig.xml
├── testHeaderConfigByte.xml
├── testHeaderConfigHandshake.xml
├── testHeaderConfigSimple.xml
├── testMessageConfig.xml
├── testMessageConfigPacketBased.xml
├── testMessageConfigPersistant.xml
├── testMessageConfigQueue.xml
├── testMessageConfigSimple.xml
├── testMessageConfigTypes.xml
├── testMessageConfigWithAge.xml
└── testWritebackConfig.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /.settings
2 | .project
3 | .classpath
4 | /target
5 | /build/
6 | /logs/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Generic TCP Driver
2 | ==================
3 |
4 | The generic TCP driver connects network devices that use a custom protocol to the Ignition(R) OPC-UA server. The communication protocol is configurable for each device. This driver does not poll data but expects the connected device to send messages on its own.
5 |
6 | The Generic TCP Driver module adds two new drivers to the Ignition TM OPC-UA Server:
7 | - Generic TCP Client Driver
8 | The client driver connects actively to a remote device.
9 | - Generic TCP Server Driver
10 | The server driver is as a passive listener. It opens a tcp-port on the server machine and waits for remote devices to establish a connection. Each driver instance allows multiple remote devices to connect.
--------------------------------------------------------------------------------
/build/generic-tcp-driver-gateway/pom.xml:
--------------------------------------------------------------------------------
1 |
true
if this is the active node in a redundant configuration (or if redundancy is disabled).
146 | */
147 | public boolean isActiveNode();
148 |
149 | }
150 |
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/ModuleHook.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2012-2015 C. Hiesserich
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | ******************************************************************************/
16 | package com.chitek.ignition.drivers.generictcp;
17 |
18 | import java.io.IOException;
19 | import java.net.MalformedURLException;
20 | import java.net.URL;
21 | import java.net.URLConnection;
22 | import java.util.List;
23 | import java.util.ResourceBundle;
24 |
25 | import org.apache.wicket.RuntimeConfigurationType;
26 |
27 | import com.chitek.ignition.drivers.generictcp.configuration.GenericTcpServerDriverType;
28 | import com.chitek.ignition.drivers.generictcp.configuration.GenericTcpClientDriverType;
29 | import com.chitek.ignition.drivers.generictcp.configuration.settings.GenericTcpServerDriverSettings;
30 | import com.chitek.ignition.drivers.generictcp.configuration.settings.GenericTcpClientDriverSettings;
31 | import com.google.common.collect.Lists;
32 | import com.inductiveautomation.ignition.common.BundleUtil;
33 | import com.inductiveautomation.ignition.gateway.model.GatewayContext;
34 | import com.inductiveautomation.xopc.driver.api.configuration.DriverType;
35 | import com.inductiveautomation.xopc.driver.common.AbstractDriverModuleHook;
36 |
37 | public class ModuleHook extends AbstractDriverModuleHook {
38 |
39 | public static final String BUNDLE_PREFIX = "GenericTcpDriver";
40 | private static final int expectedApiVersion = 4;
41 |
42 | private static final List10.224.1.99,Device1
device.com,Device2
23 |
24 | PacketTimeout.Name=Packet Timeout
25 | PacketTimeout.Desc=Maximum time (in milliseconds) between incoming data packets of one message.
26 |
27 | TimestampFactor.Name=Timestamp factor
28 | TimestampFactor.Desc=A multiplier for the timestamp / message age received from the device. The driver expects timestamps in milliseconds.
29 |
30 | MaxTimestamp.Name=Max. Timestamp
31 | MaxTimestamp.Desc=The maximum possible timestamp value sent by the device. This is used to detect an overflow.
32 |
33 | ReverseByteOrder.Name=Reverse byte order
34 | ReverseByteOrder.Desc=Set true to use LittleEndian (Intel) byte order instead of default BigEndian (Motorola).
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/configuration/settings/GenericTcpServerDriverSettings_de.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/configuration/settings/GenericTcpServerDriverSettings_de.properties
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/configuration/settings/IGenericTcpDriverSettings.java:
--------------------------------------------------------------------------------
1 | package com.chitek.ignition.drivers.generictcp.configuration.settings;
2 |
3 | import java.io.Serializable;
4 |
5 | import com.chitek.ignition.drivers.generictcp.meta.config.DriverConfig;
6 | import com.chitek.ignition.drivers.generictcp.meta.config.HeaderConfig;
7 | import com.chitek.ignition.drivers.generictcp.meta.config.WritebackConfig;
8 | import com.inductiveautomation.ignition.gateway.localdb.persistence.PersistentRecord;
9 |
10 | public interface IGenericTcpDriverSettings extends Serializable {
11 |
12 | /**
13 | * @return
14 | * This class, cast to a PersistentRecord.
15 | */
16 | public PersistentRecord getPersistentRecord();
17 |
18 | public byte[] getMessageConfig();
19 |
20 | public DriverConfig getParsedMessageConfig() throws Exception;
21 |
22 | public byte[] getHeaderConfig();
23 |
24 | public HeaderConfig getParsedHeaderConfig() throws Exception;
25 |
26 | public byte[] getWritebackConfig();
27 |
28 | public WritebackConfig getParsedWritebackConfig() throws Exception;
29 |
30 | public void setMessageConfig(byte[] messageConfig);
31 |
32 | public void setHeaderConfig(byte[] headerConfig);
33 |
34 | public void setWritebackConfig(byte[] writebackConfig);
35 |
36 | /**
37 | * @return
38 | * true if writeback config page should be shown
39 | */
40 | public boolean isWritebackEnabled();
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/folder/BrowseTree.java:
--------------------------------------------------------------------------------
1 | package com.chitek.ignition.drivers.generictcp.folder;
2 |
3 | import com.inductiveautomation.xopc.driver.util.TagTree;
4 |
5 | public class BrowseTree extends TagTreetrue
to accept the connection.
29 | */
30 | public abstract boolean clientConnected(InetSocketAddress remoteSocket);
31 |
32 | /**
33 | * Called when a remote client closes the connection.
34 | *
35 | * @param remoteAddress
36 | */
37 | public abstract void connectionLost(InetSocketAddress remoteAddress);
38 |
39 | public abstract void dataArrived(InetSocketAddress remoteAddress, ByteBuffer data, int bytesRead);
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/io/IMessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.chitek.ignition.drivers.generictcp.io;
2 |
3 | import java.net.InetSocketAddress;
4 |
5 | public interface IMessageHandler {
6 |
7 | /**
8 | * @param remoteSocket
9 | * @param messageId
10 | * @param messageData
11 | * The received messagetrue
if the timeout is expired
100 | */
101 | public boolean isTimeoutExpired() {
102 | if (oldestAddress==null || timeout==0) {
103 | return false;
104 | }
105 |
106 | long diff = System.nanoTime()/1000000-oldestTime;
107 | return (timeout-diff)<=0;
108 | }
109 |
110 | /**
111 | * Return the InetAddress whose timeout is about to or has expired.
112 | *
113 | * @return
114 | * The InetAddress that caused a timeout.
115 | */
116 | public SocketAddress getTimeoutAddress() {
117 | return oldestAddress;
118 | }
119 |
120 | private void updateTimeout() {
121 | long earliestTime=Long.MAX_VALUE;
122 | SocketAddress address=null;
123 | Iteratorlenw, 0xfe, 0xfe, timestamp
'
21 |
22 | noheaderitems=There are currently no tags configured for the header...
23 |
24 | # Validator messages
25 | rawValue.ParseableValidator=The input string '${input}' can not be parsed as an Integer.
26 | rawValue.RangeValidator=Value must be between ${minimum} and ${maximum}.
27 | dataType.SpecialTypesValidator=Special DataTypes must be used only once in a message.
28 | size.RangeValidator=Array size must be between ${minimum} and ${maximum}.
29 | useHeader.NoSizeTag=To use the header there must be a tag with the packet size.
30 | handshakeMsg.ByteStringValidator=Handshake can not be parsed (${error}).
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/HeaderConfigUI_de.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/HeaderConfigUI_de.properties
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/MessageConfigUI.properties:
--------------------------------------------------------------------------------
1 | # Types for Dropdowns
2 | BinaryDataType.Dummy=Dummy
3 | BinaryDataType.UByte=Unsigned Byte
4 | BinaryDataType.Byte=Signed Byte
5 | BinaryDataType.Bool8=Bool8
6 | BinaryDataType.Bool16=Bool16
7 | BinaryDataType.UInt16=UInt16
8 | BinaryDataType.Int16=Int16
9 | BinaryDataType.UInt32=UInt32
10 | BinaryDataType.Int32=Int32
11 | BinaryDataType.Float=Float
12 | BinaryDataType.String=String
13 | BinaryDataType.RawString=Raw String
14 | BinaryDataType.MessageAge=Message Age
15 |
16 | QueueMode.NONE=None
17 | QueueMode.HANDSHAKE=Handshake
18 | QueueMode.DELAYED=Delayed
19 |
20 | MessageType.FIXED_LENGTH=Fixed length
21 | MessageType.PACKET_BASED=Packet based
22 |
23 | TagLengthType.FIXED_LENGTH=Fixed
24 | TagLengthType.PACKET_BASED=From Packet
25 |
26 | selectMessageLabel=Select Message
27 |
28 | info.deleted=Message with ID {0} has been deleted.
29 | info.new=Created new message with ID {0}.
30 | info.copy=Copied message to new ID {0}.
31 | info.import=Successfully imported message with new ID {0}.
32 |
33 | words.new=New
34 |
35 | warn.noMessageId0=Message ID Type 'None' is selected, but there is no message with ID '0' defined.
36 | warn.MessageIdGT255=Message ID Type is 'Byte' but there is a message with ID > 255 defined. That message will be ignored.
37 | warn.noFileToUpload=No file was selected for upload.
38 | warn.importIdChanged=Message Id {0} in imported configuration is already in use.
39 |
40 | messageIdType.DisplayName=Type of message ID
41 | messageIdType.Description=Select Byte or Word to use multiple messages. When 'None' is selected, the driver will only use message with ID 0.
42 | messageType.DisplayName=Message type
43 | messageType.Description='Packet based' for message that may vary in length. One tag has to be configured with 'Packet Based' length. Data is read into this tag until the message end is detected by expiration of the Packet Timeout.
44 | queueMode.DisplayName=Queue Mode
45 | queueMode.Description='Handshake' and 'Delayed' modes buffer incoming messages in memory. The OPC values are updated only after an OPC client writes to the handshake tag (Handshake Mode) or after a fixed delay (Delayed Mode).
46 | usePersistance.DisplayName=Use Persistence
47 | usePersistance.Description=If true, the message queue (in Handshake or Delayed mode) will use a persistent disk storage to prevent data loss. If false, the queue will only be saved on a regular shutdown.
48 |
49 | messageLabel=Message ID
50 | idlabel=ID
51 | offsetlabel=Offset
52 | aliaslabel=Alias
53 | sizelabel=Size
54 | datatypelabel=Data Type
55 |
56 | noitems=There are currently no tags configured in this message...
57 |
58 | import.linklabel=Import Message
59 | import.error=Error importing message configuration from XML file.
60 | export.linklabel=Export Message
61 |
62 | # Validator messages
63 | UniqueMessageIdValidator=Message ID must be unique.
64 | messageId.RangeValidator=Message ID must be between ${minimum} and ${maximum}.
65 | UniqueMessageAliasValidator=Message Alias must be unique.
66 | messageAlias.PatternValidator=Alias must consist of alphanumerics and underscores.
67 | messageAlias.StringValidator.range=Alias must be between ${minimum} and ${maximum} characters long.
68 | dataType.SpecialTypesValidator=Special DataTypes must be used only once in a message.
69 | id.UniqueValueValidator=ID must be unique.
70 | id.RangeValidator=ID must be between ${minimum} and ${maximum}.
71 | size.RangeValidator=Array size must be between ${minimum} and ${maximum}.
72 | alias.UniqueValueValidator=Alias must be unique.
73 | alias.PatternValidator=Alias must consist of alphanumerics and underscores.
74 | alias.StringValidator.range=Alias must be between ${minimum} and ${maximum} characters long.
75 | alias.StringValidator.noMatch=The names of special tags "Handshake", "MessageCount", "QueueSize" and "Timestamp" must not be used as an alias.
76 | tagLengthType.OnlyOnePackedBasedValidator=There must be only one tag defined with a packet based length.
77 | error.noPacketBasedLengthTag=The message is configured to use packet base length, but there's no tag with a packet based length.
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/MessageConfigUI_de.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/MessageConfigUI_de.properties
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/SessionConfig.java:
--------------------------------------------------------------------------------
1 | package com.chitek.ignition.drivers.generictcp.meta.config.ui;
2 |
3 | import java.io.Serializable;
4 |
5 | import com.chitek.ignition.drivers.generictcp.meta.config.DriverConfig;
6 | import com.chitek.ignition.drivers.generictcp.meta.config.HeaderConfig;
7 | import com.chitek.ignition.drivers.generictcp.meta.config.WritebackConfig;
8 |
9 | /**
10 | * This class is used to store the edited configuration in the session.
11 | */
12 | public class SessionConfig implements Serializable {
13 | private static final long serialVersionUID = 1L;
14 |
15 | private DriverConfig driverConfig;
16 | private WritebackConfig writebackConfig;
17 | private HeaderConfig headerConfig;
18 |
19 | public SessionConfig(DriverConfig driverConfig, WritebackConfig writebackConfig, HeaderConfig headerConfig) {
20 | this.driverConfig = driverConfig;
21 | this.writebackConfig = writebackConfig;
22 | this.headerConfig = headerConfig;
23 | }
24 |
25 | public DriverConfig getDriverConfig() {
26 | return driverConfig;
27 | }
28 |
29 | public WritebackConfig getWritebackConfig() {
30 | return writebackConfig;
31 | }
32 |
33 | public HeaderConfig getHeaderConfig() {
34 | return headerConfig;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/WritebackConfigUI.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | lenb, 0xfe, 0xfe, id
'
16 | dataType.DisplayName=Data Type
17 | dataType.Description=Select the DataType to be used in the outgoing message.
18 | sendOnValueChange.DisplayName=Send on value change
19 | sendOnValueChange.Description=Send to device immediately if an OPC client changes the value. If false, send must be triggered explicitly with the Write tag.
20 | sendInitialValue.DisplayName=Send initial value
21 | sendInitialValue.Description=Sends an initial value after the connection has been established.
22 | initialValue.DisplayName=Initial Value
23 | initialValue.Description=The initial value to send on connect.
24 | initialValue.DataTypeValidator=Initial value can not be parsed as ${messageDataType}
25 | initialValue.RangeValidator=Initial value ist not in valid range for ${messageDataType}
26 | initialId.DisplayName=Initial ID
27 | initialId.Description=The initial ID to send on connect (if Message Id is used).
28 | initialId.RangeValidator=Initial ID value ist not in valid range for ${idDataType}
29 | prefix.ByteStringValidator=Prefix can not be parsed (${error}).
30 | prefix.IdNone=You configured 'id' to be send in the prefix, but Message ID Type is set to None
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/WritebackConfigUI_de.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/WritebackConfigUI_de.properties
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/actionlinksnewarrow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/actionlinksnewarrow.gif
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/close.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/close.gif
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/configui.css:
--------------------------------------------------------------------------------
1 | div#configcontents table.gentcpActiontable thead {
2 | border: none;
3 | }
4 |
5 | div#configcontents table.gentcpActiontable thead tr td {
6 | border: 1px solid gray;
7 | background-color: #DDD;
8 | }
9 |
10 |
11 | div#configcontents table.gentcpActiontable tbody tr td {
12 | border: 1px solid gray;
13 | vertical-align: middle;
14 | padding: 4px 6px;
15 | }
16 |
17 | /* Show message alias with dark background */
18 | div#configcontents table.gentcpActiontable tbody td.noedit {
19 | background-color: #DDD;
20 | color: #000;
21 | font-weight: bold;
22 | }
23 |
24 | /* Fixed width for Offset column */
25 | table.gentcpActiontable td.offset {
26 | width: 5ex;
27 | }
28 |
29 | /* The action links with images */
30 | div#configcontents table.gentcpActiontable td.links {
31 | padding: 0px;
32 | width: 22px;
33 | background-color: transparent;
34 | border: none;
35 | }
36 | table.gentcpActiontable td.links a {
37 | background-repeat: no-repeat;
38 | background-position: center;
39 | padding-right: 2px;
40 | padding-left: 16px;
41 | }
42 | table.gentcpActiontable td.links a:hover {
43 | border-bottom: 2px solid;
44 | }
45 | table.gentcpActiontable a.insert-link {
46 | background-image: url('row_insert.png');
47 | }
48 | table.gentcpActiontable a.delete-link {
49 | background-image: url('row_delete.png');
50 | }
51 | table.gentcpActiontable a.move-up-link {
52 | background-image: url('row_up.png');
53 | }
54 | table.gentcpActiontable a.move-down-link {
55 | background-image: url('row_down.png');
56 | }
57 | span.importlink
58 | {
59 | background: url("actionlinksnewarrow.gif") no-repeat scroll 0px center transparent;
60 | padding-left:20px;
61 | }
62 | div.ajax-indicator {
63 | position:absolute;
64 | top:0px;
65 | width: 100%;
66 | height: 100%;
67 | background-color:grey;
68 | background-image: url('indicator.gif');
69 | background-repeat: no-repeat;
70 | background-position: center center;
71 | }
72 |
73 | div#configcontents select {
74 | height: 30px;
75 | margin: 0px 0px;
76 | }
77 |
78 | div#configcontents input[type=button].gentcp_table_btn {
79 | margin-left: 5px;
80 | margin-right: 5px;
81 | padding: 0.2rem 0.3rem;
82 | float: none;
83 | }
84 |
85 | div#configcontents input, div#configcontents select {
86 | height: 30px;
87 | margin: 0px 0px;
88 | }
89 |
90 | /* The help link */
91 | div.driverhelplink {
92 | margin-bottom: 5px;
93 | float:left;
94 | }
95 | div.driverhelplink a {
96 | padding-left: 18px;
97 | background: url('help.gif') no-repeat;
98 | }
99 |
100 | /*Feedback Panel warnings has no default CSS in Ignition **************/
101 | li.feedbackPanelWARNING {
102 | display: block;
103 | list-stile: square inside;
104 | background-color: yellow;
105 | color: black;
106 | padding: 4px;
107 | margin-bottom: 5px;
108 | font-weight: bold;
109 | }
110 | span.feedbackPanelWARNING ul {
111 | margin-left: 30px;
112 | }
113 | span.feedbackPanelWARNING ul li {
114 | display: list-item;
115 | list-style: disc;
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/help.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/help.gif
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/indicator.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/indicator.gif
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/maximize.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/maximize.gif
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_delete.png
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_down.png
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_insert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_insert.png
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/res/row_up.png
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/wicket-package.properties:
--------------------------------------------------------------------------------
1 | helpUrl=../../system/moduledocs/chitek.generictcpdriver/manual-frame.html
2 | showHelp=Help
3 | showHelpTitle=Open manual in new window
4 |
5 | submit.save=Save
6 | submit.saveTitle=Save the changed configuration and restart the driver
7 | submit.new=New
8 | submit.newTitle=Create a new message
9 | submit.copy=Copy
10 | submit.copyTitle=Copy the current message
11 | submit.delete=Delete
12 | submit.deleteTitle=Delete this message
13 | submit.back=Back
14 | submit.backTitle=Return without saving
15 |
16 | deletelink.title=Delete this row
17 | insertlink.title=Insert a new row above this
18 | moveuplink.title=Move this row up
19 | movedownlink.title=Move this row down
20 | addrowlink.title=Add Row
21 |
22 | OptionalDataType.None=None
23 | OptionalDataType.UByte=Byte
24 | OptionalDataType.UInt16=Word
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/wicket-package_de.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chi-Ignition/generic-tcp-driver/ff9ad7e84273f42c34df1564568476c7b667e2a9/src/main/java/com/chitek/ignition/drivers/generictcp/meta/config/ui/wicket-package_de.properties
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/tags/ReadableArrayTag.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2012-2019 C. Hiesserich
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | ******************************************************************************/
16 | package com.chitek.ignition.drivers.generictcp.tags;
17 |
18 | import org.eclipse.milo.opcua.stack.core.util.ArrayUtil;
19 | import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
20 | import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
21 | import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
22 | import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
23 |
24 | import com.chitek.ignition.drivers.generictcp.types.BinaryDataType;
25 | import com.chitek.ignition.drivers.generictcp.util.Util;
26 |
27 | import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ushort;
28 |
29 | /**
30 | * A readable tag with an array as its value. The child tags contain the individual array elements.
31 | *
32 | * @author chi
33 | *
34 | */
35 | public class ReadableArrayTag extends ReadableTcpDriverTag {
36 |
37 | ReadableTcpDriverTag[] childTags;
38 | ReadableTcpDriverTag childRaw;
39 | protected int valueArrayLength = 0;
40 | protected int childCount = 0;
41 |
42 | public ReadableArrayTag(String address, int id, String alias, int index, BinaryDataType dataType, int arrayLength)
43 | {
44 | super(address, id, alias, index, dataType);
45 | this.value = initialValue;
46 | this.childTags = new ReadableTcpDriverTag[arrayLength];
47 | this.readSize = arrayLength / dataType.getArrayLength();
48 | // For 1-dimensional arrays, the values array length is the same as childCount
49 | this.valueArrayLength = arrayLength;
50 | }
51 |
52 | @Override
53 | public void setValue(Variant newValue, StatusCode statusCode, DateTime timestamp) {
54 |
55 | if (newValue.getValue().getClass().isArray() && ArrayUtil.getDimensions(newValue.getValue())[0] != valueArrayLength) {
56 | throw new IllegalArgumentException(
57 | String.format("SetValue in ReadableArray '%s' expects an Variant with array size %d. Argument has array size %d."
58 | ,getAddress(), valueArrayLength, ArrayUtil.getDimensions(newValue.getValue())[0] ));
59 | }
60 | this.value = new DataValue(newValue, statusCode, timestamp, timestamp);
61 |
62 | Object[] value = (Object[]) newValue.getValue();
63 |
64 | // Set values for childs
65 | // A simple for loop is used here, because it performs better with arrays than a (for x : childTags)
66 | int rawValue=0;
67 | for (int i = 0; i < childCount; i++) {
68 | Variant childValue = Util.makeVariant(value[i], this.getDataType());
69 | childTags[i].setValue(childValue, statusCode, timestamp);
70 | if ( childRaw!=null && (Boolean)value[i]) rawValue += 1<
30 | * For example, a tag with DataType Bool8 and size 3 will have the following structure:
31 | * 32 | *ReadableBoolArrayTag - Value {x0.0, x0.1, ..., x3.7} 33 | * ReadableArrayTag - Value {x0.0, x0.1, ..., x0.7} 34 | * ReadableTag - Value x0.0 35 | * ReadableTag - Value x0.1 36 | * ... 37 | * ReadableTag - Value x0.7 38 | * ReadableArrayTag - Value {x1.0, x1.1, ..., x1.7} 39 | * ReadableTag - Value x1.0 40 | * ... 41 | * ... 42 | *43 | * 44 | * @author chi 45 | * 46 | */ 47 | public class ReadableBoolArrayTag extends ReadableArrayTag { 48 | 49 | 50 | public ReadableBoolArrayTag(String address, int id, String alias, BinaryDataType dataType, int arrayLength) 51 | { 52 | super(address, id, alias, -1, dataType, arrayLength); 53 | 54 | // The 1st level tag of a 2-dimensional array contains all values in one big array 55 | this.readSize = arrayLength; 56 | this.valueArrayLength = arrayLength * dataType.getArrayLength(); 57 | } 58 | 59 | @Override 60 | public void setValue(Variant newValue, StatusCode statusCode, DateTime timestamp) { 61 | 62 | if (newValue.getValue().getClass().isArray() && ArrayUtil.getDimensions(newValue.getValue())[0] != valueArrayLength) { 63 | throw new IllegalArgumentException( 64 | String.format("SetValue in ReadableBoolArray '%s' expects an Variant with array size %d. Argument has array size %d." 65 | ,getAddress(), this.valueArrayLength, ArrayUtil.getDimensions(newValue.getValue())[0] )); 66 | } 67 | this.value = new DataValue(newValue, statusCode, timestamp, timestamp); 68 | 69 | Object[] value = (Object[]) newValue.getValue(); 70 | 71 | // Set values for childs 72 | for (int i = 0; i < childCount; i++) { 73 | 74 | // Set the correct array dimensions for the Variant 75 | int childArraySize = childTags[i].getValueArrayLength(); 76 | 77 | // Special treatment for BOOLEAN 78 | // Ignition API does not support multi-dimensional Variants, so for Boolean tags 79 | // with an array length > 1, the top level tag contains all Booleans in one big array 80 | Boolean[] rawValue = new Boolean[childArraySize]; 81 | System.arraycopy(value, i * childArraySize, rawValue, 0, childArraySize); 82 | 83 | Variant childValue = new Variant(rawValue); 84 | childTags[i].setValue(childValue, statusCode, timestamp); 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/chitek/ignition/drivers/generictcp/tags/ReadableStringTag.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2013 C. Hiesserich 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package com.chitek.ignition.drivers.generictcp.tags; 17 | 18 | import com.chitek.ignition.drivers.generictcp.types.BinaryDataType; 19 | 20 | public class ReadableStringTag extends ReadableTcpDriverTag { 21 | 22 | private int stringLength; 23 | 24 | public ReadableStringTag(String address, int id, String alias, BinaryDataType dataType, int stringLength) { 25 | super(address, id, alias, dataType); 26 | this.stringLength = stringLength; 27 | } 28 | 29 | /** 30 | * Returns the count of data to read from network. 31 | * 32 | * @return 33 | */ 34 | public int getReadSize() { 35 | return stringLength; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/chitek/ignition/drivers/generictcp/tags/ReadableTcpDriverTag.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2019 C. Hiesserich 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | package com.chitek.ignition.drivers.generictcp.tags; 17 | 18 | import org.eclipse.milo.opcua.sdk.server.nodes.UaVariableNode; 19 | import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; 20 | import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime; 21 | import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; 22 | import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; 23 | 24 | import com.chitek.ignition.drivers.generictcp.types.BinaryDataType; 25 | import com.inductiveautomation.xopc.driver.api.tags.DynamicDriverTag; 26 | 27 | /** 28 | * A simple tag that is only readable. 29 | * 30 | * @author chi 31 | * 32 | */ 33 | public class ReadableTcpDriverTag extends DynamicDriverTag { 34 | 35 | protected BinaryDataType driverDataType; 36 | protected DataValue value; 37 | private final String alias; 38 | private final int id; 39 | private final int index; 40 | protected UaVariableNode uaNode; 41 | protected int readSize; 42 | 43 | protected static final DataValue initialValue = new DataValue(StatusCode.BAD); 44 | 45 | public ReadableTcpDriverTag(String address, int id, String alias, BinaryDataType dataType) 46 | { 47 | super(address, dataType.getUADataType()); 48 | this.id = id; 49 | this.alias = alias; 50 | this.index = -1; 51 | this.driverDataType = dataType; 52 | this.value = initialValue; 53 | } 54 | 55 | /** 56 | * Constructor for indexed tags. The index is added to browseName and displayName 57 | * 58 | * @param address 59 | * @param id 60 | * @param alias 61 | * @param index 62 | * @param dataType 63 | */ 64 | public ReadableTcpDriverTag(String address, int id, String alias, int index, BinaryDataType dataType) 65 | { 66 | super(address, dataType.getUADataType()); 67 | this.id = id; 68 | this.alias = alias; 69 | this.index = index; 70 | this.driverDataType = dataType; 71 | this.value = initialValue; 72 | } 73 | 74 | public DataValue getValue() { 75 | return value; 76 | } 77 | 78 | public void setValue(StatusCode statusCode) { 79 | this.value = new DataValue(statusCode); 80 | } 81 | 82 | public void setValue(long statusCode) { 83 | this.value = new DataValue(statusCode); 84 | } 85 | 86 | public void setValue(Variant newValue, DateTime timestamp) { 87 | setValue(newValue, StatusCode.GOOD, timestamp); 88 | } 89 | 90 | public void setValue(Variant newValue, long statusCode, DateTime timestamp) { 91 | this.value = new DataValue(newValue, new StatusCode(statusCode), timestamp, this.value.getServerTime()); 92 | } 93 | 94 | public void setValue(Variant newValue, StatusCode statusCode, DateTime timestamp) { 95 | this.value = new DataValue(newValue, statusCode, timestamp, this.value.getServerTime()); 96 | } 97 | 98 | /** 99 | * Sets the value of the corresponding uaNode 100 | */ 101 | public void setUaNodeValue() { 102 | if (uaNode != null) 103 | uaNode.setValue(value); 104 | } 105 | 106 | public void setUaNode(UaVariableNode node) { 107 | this.uaNode = node; 108 | } 109 | 110 | public UaVariableNode getUaNode() { 111 | return uaNode; 112 | } 113 | 114 | public BinaryDataType getDriverDataType() { 115 | return driverDataType; 116 | } 117 | 118 | public String getDisplayName() { 119 | if (index > -1) 120 | return String.format("%s_%02d", alias, index); 121 | else 122 | return alias; 123 | } 124 | 125 | public String getBrowseName() { 126 | if (index > -1) 127 | return String.format("%s[%02d]", alias, index); 128 | else 129 | return alias; 130 | } 131 | 132 | public int getId() { 133 | return id; 134 | } 135 | 136 | /** 137 | * Returns the length of the array length of this tags OPC Value. 138 | * 139 | * @return 140 | * This values array length, or -1 if this tags value is scalar.
true
if the given BinaryDataType supports variable length.
119 | */
120 | public boolean supportsVariableLength() {
121 | return this == BinaryDataType.Dummy || this == BinaryDataType.String || this == BinaryDataType.RawString;
122 | }
123 |
124 | public static Listtrue
if the hostname has already been resolved to an InetAddress. getInetAddress() will return immediatly
48 | * in this case.
49 | */
50 | public boolean isAddressResolved() {
51 | return remoteAddress != null;
52 | }
53 |
54 | /**
55 | * Returns the configured address for this device.
56 | * @return
57 | */
58 | public InetAddress getInetAddress() {
59 | if (remoteAddress != null) {
60 | return remoteAddress;
61 | }
62 |
63 | try {
64 | InetAddress address = InetAddress.getByName(getHostname());
65 | remoteAddress = address;
66 | return remoteAddress;
67 | } catch (UnknownHostException e) {
68 | return null;
69 | }
70 | }
71 |
72 | /**
73 | * Used to store the remote socket after the device has connected to the driver.
74 | *
75 | * @param remoteSocket
76 | * The remote socket address.
77 | */
78 | public void setRemoteSocketAddress(InetSocketAddress remoteSocket) {
79 | this.remoteSocketAddress = remoteSocket;
80 | }
81 |
82 | public InetSocketAddress getRemoteSocketAddress() {
83 | return remoteSocketAddress;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/com/chitek/ignition/drivers/generictcp/types/TagLengthType.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2014 C. Hiesserich
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | ******************************************************************************/
16 | package com.chitek.ignition.drivers.generictcp.types;
17 |
18 | import java.util.Arrays;
19 | import java.util.List;
20 |
21 | public enum TagLengthType {
22 | FIXED_LENGTH, PACKET_BASED;
23 |
24 | /**
25 | * List with the options to use in a DropDownChoice
26 | *
27 | * @return
28 | */
29 | public static List