Skip to content

Commit 436a56a

Browse files
committed
Initial implementation of opcua binding.
Signed-off-by: Łukasz Dywicki <[email protected]>
1 parent dd9a926 commit 436a56a

File tree

21 files changed

+1351
-1
lines changed

21 files changed

+1351
-1
lines changed

Diff for: bundles/org.connectorio.addons.binding.opcua/pom.xml

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
- Copyright (C) 2022-2022 ConnectorIO Sp. z o.o.
4+
-
5+
- Licensed under the Apache License, Version 2.0 (the "License");
6+
- you may not use this file except in compliance with the License.
7+
- You may obtain a copy of the License at
8+
-
9+
- http://www.apache.org/licenses/LICENSE-2.0
10+
-
11+
- Unless required by applicable law or agreed to in writing, software
12+
- distributed under the License is distributed on an "AS IS" BASIS,
13+
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
- See the License for the specific language governing permissions and
15+
- limitations under the License.
16+
-
17+
- SPDX-License-Identifier: Apache-2.0
18+
-->
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20+
21+
<modelVersion>4.0.0</modelVersion>
22+
23+
<parent>
24+
<groupId>org.connectorio.addons</groupId>
25+
<artifactId>bundles</artifactId>
26+
<version>3.0.0-SNAPSHOT</version>
27+
</parent>
28+
29+
<artifactId>org.connectorio.addons.binding.opcua</artifactId>
30+
<packaging>bundle</packaging>
31+
32+
<name>ConnectorIO - Addons - Binding - OPC UA</name>
33+
<description>OPC UA binding.</description>
34+
35+
<dependencies>
36+
<dependency>
37+
<groupId>org.connectorio.addons</groupId>
38+
<artifactId>org.connectorio.addons.binding</artifactId>
39+
</dependency>
40+
41+
<dependency>
42+
<groupId>org.eclipse.milo</groupId>
43+
<artifactId>stack-client</artifactId>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.eclipse.milo</groupId>
47+
<artifactId>sdk-client</artifactId>
48+
</dependency>
49+
50+
<dependency>
51+
<groupId>org.connectorio.addons</groupId>
52+
<artifactId>org.connectorio.units</artifactId>
53+
</dependency>
54+
<dependency>
55+
<groupId>org.connectorio.addons</groupId>
56+
<artifactId>org.connectorio.units.si</artifactId>
57+
</dependency>
58+
59+
<dependency>
60+
<groupId>org.openhab.core.bundles</groupId>
61+
<artifactId>org.openhab.core</artifactId>
62+
</dependency>
63+
<dependency>
64+
<groupId>org.openhab.core.bundles</groupId>
65+
<artifactId>org.openhab.core.auth.oauth2client</artifactId>
66+
</dependency>
67+
<dependency>
68+
<groupId>org.openhab.core.bundles</groupId>
69+
<artifactId>org.openhab.core.io.net</artifactId>
70+
</dependency>
71+
<dependency>
72+
<groupId>org.openhab.core.bundles</groupId>
73+
<artifactId>org.openhab.core.storage.json</artifactId>
74+
</dependency>
75+
<dependency>
76+
<groupId>org.openhab.core.bundles</groupId>
77+
<artifactId>org.openhab.core.thing</artifactId>
78+
</dependency>
79+
80+
<dependency>
81+
<groupId>org.osgi</groupId>
82+
<artifactId>org.osgi.service.component.annotations</artifactId>
83+
</dependency>
84+
<dependency>
85+
<groupId>org.openhab.core.bundles</groupId>
86+
<artifactId>org.openhab.core.config.discovery</artifactId>
87+
</dependency>
88+
89+
<dependency>
90+
<groupId>org.connectorio.addons</groupId>
91+
<artifactId>org.connectorio.addons.binding.test</artifactId>
92+
</dependency>
93+
<dependency>
94+
<groupId>org.slf4j</groupId>
95+
<artifactId>slf4j-api</artifactId>
96+
</dependency>
97+
98+
<dependency>
99+
<groupId>org.junit.jupiter</groupId>
100+
<artifactId>junit-jupiter-api</artifactId>
101+
<scope>test</scope>
102+
</dependency>
103+
<dependency>
104+
<groupId>org.assertj</groupId>
105+
<artifactId>assertj-core</artifactId>
106+
<scope>test</scope>
107+
</dependency>
108+
<dependency>
109+
<groupId>org.mockito</groupId>
110+
<artifactId>mockito-junit-jupiter</artifactId>
111+
</dependency>
112+
</dependencies>
113+
114+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2022-2022 ConnectorIO Sp. z o.o.
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+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
package org.connectorio.addons.binding.opcua;
19+
20+
import java.util.Arrays;
21+
import java.util.HashSet;
22+
import java.util.Set;
23+
import org.connectorio.addons.binding.BaseBindingConstants;
24+
import org.openhab.core.thing.ThingTypeUID;
25+
26+
public interface OpcUaBindingConstants extends BaseBindingConstants {
27+
28+
String BINDING_ID = BaseBindingConstants.identifier("opcua");
29+
30+
// well..
31+
ThingTypeUID SERVER_THING_TYPE = new ThingTypeUID(BINDING_ID, "server");
32+
33+
ThingTypeUID CLIENT_THING_TYPE = new ThingTypeUID(BINDING_ID, "client");
34+
ThingTypeUID OBJECT_THING_TYPE = new ThingTypeUID(BINDING_ID, "node");
35+
36+
Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(
37+
SERVER_THING_TYPE,
38+
CLIENT_THING_TYPE,
39+
OBJECT_THING_TYPE
40+
));
41+
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package org.connectorio.addons.binding.opcua.internal;
2+
3+
import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
4+
import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.toList;
5+
6+
import java.util.Arrays;
7+
import java.util.List;
8+
import java.util.concurrent.CompletableFuture;
9+
import java.util.concurrent.ExecutionException;
10+
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
11+
import org.eclipse.milo.opcua.sdk.client.api.UaClient;
12+
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
13+
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder;
14+
import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;
15+
import org.eclipse.milo.opcua.sdk.client.api.identity.SignedIdentityToken;
16+
import org.eclipse.milo.opcua.sdk.client.nodes.UaNode;
17+
import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
18+
import org.eclipse.milo.opcua.stack.client.UaStackClient;
19+
import org.eclipse.milo.opcua.stack.client.UaStackClientConfigBuilder;
20+
import org.eclipse.milo.opcua.stack.core.Identifiers;
21+
import org.eclipse.milo.opcua.stack.core.NamespaceTable;
22+
import org.eclipse.milo.opcua.stack.core.UaException;
23+
import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString;
24+
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
25+
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
26+
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
27+
import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection;
28+
import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask;
29+
import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass;
30+
import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription;
31+
import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult;
32+
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
33+
import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription;
34+
import org.slf4j.Logger;
35+
import org.slf4j.LoggerFactory;
36+
37+
public class Main {
38+
39+
private static Logger logger = LoggerFactory.getLogger(Main.class);
40+
41+
public static void main(String[] args) throws Exception {
42+
OpcUaClientConfigBuilder cfg = new OpcUaClientConfigBuilder();
43+
44+
List<EndpointDescription> descriptions = DiscoveryClient.getEndpoints(
45+
"opc.tcp://localhost:4840").get();
46+
47+
for (EndpointDescription description : descriptions) {
48+
System.out.println(description.getEndpointUrl() + " " + Arrays.toString(description.getUserIdentityTokens()));
49+
}
50+
51+
OpcUaClientConfig config = OpcUaClientConfig.builder()
52+
.setApplicationName(LocalizedText.english("eclipse milo opc-ua client of the apache PLC4X:PLC4J project"))
53+
.setApplicationUri("urn:eclipse:milo:plc4x:client")
54+
.setEndpoint(descriptions.get(0))
55+
// .setIdentityProvider(new IdentityProvider() {
56+
// @Override
57+
// public SignedIdentityToken getIdentityToken(EndpointDescription endpointDescription, ByteString byteString) throws Exception {
58+
// return null;
59+
// }
60+
// })
61+
.setRequestTimeout(UInteger.valueOf(100))
62+
.build();
63+
64+
OpcUaClient client = OpcUaClient.create(config);
65+
UaClient uaClient = client.connect().get();
66+
67+
// start browsing at root folder
68+
//browseNode("", client, Identifiers.RootFolder);
69+
browseNode2("", client, Identifiers.ObjectsFolder);
70+
71+
}
72+
73+
74+
private static void browseNode(String indent, OpcUaClient client, NodeId browseRoot) {
75+
BrowseDescription browse = new BrowseDescription(
76+
browseRoot,
77+
BrowseDirection.Forward,
78+
Identifiers.References,
79+
true,
80+
uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue() | NodeClass.View.getValue()),
81+
uint(BrowseResultMask.All.getValue())
82+
);
83+
84+
try {
85+
BrowseResult browseResult = client.browse(browse).get();
86+
87+
List<ReferenceDescription> references = toList(browseResult.getReferences());
88+
89+
for (ReferenceDescription rd : references) {
90+
System.out.println(indent + " Node=" + rd.getBrowseName().getName() + " " + rd.getDisplayName().getText());
91+
92+
// recursively browse to children
93+
rd.getNodeId().toNodeId(client.getNamespaceTable())
94+
.ifPresent(nodeId -> browseNode(indent + " ", client, nodeId));
95+
}
96+
} catch (InterruptedException | ExecutionException e) {
97+
logger.error("Browsing nodeId={} failed: {}", browseRoot, e.getMessage(), e);
98+
}
99+
}
100+
101+
private static void browseNode2(String indent, OpcUaClient client, NodeId browseRoot) {
102+
try {
103+
List<? extends UaNode> nodes = client.getAddressSpace().browseNodes(browseRoot);
104+
105+
for (UaNode node : nodes) {
106+
System.out.println(indent + " Node=" + node.getBrowseName().getName() + " " + node.getDisplayName().getText() + " " + node.getNodeId());
107+
108+
// recursively browse to children
109+
browseNode2(indent + " ", client, node.getNodeId());
110+
}
111+
} catch (UaException e) {
112+
logger.error("Browsing nodeId={} failed: {}", browseRoot, e.getMessage(), e);
113+
}
114+
}
115+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (C) 2022-2022 ConnectorIO Sp. z o.o.
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+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
package org.connectorio.addons.binding.opcua.internal.config;
19+
20+
import org.connectorio.addons.binding.config.Configuration;
21+
22+
public class ClientConfig implements Configuration {
23+
24+
public String host;
25+
public int port = 4848;
26+
27+
public String username;
28+
public String password;
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) 2022-2022 ConnectorIO Sp. z o.o.
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+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
package org.connectorio.addons.binding.opcua.internal.config;
19+
20+
import org.connectorio.addons.binding.config.Configuration;
21+
22+
public class NodeConfig implements Configuration {
23+
24+
public int ns;
25+
public IdentifierType identifierType;
26+
public String identifier;
27+
28+
public enum IdentifierType {
29+
i, s, g, b;
30+
}
31+
32+
}

0 commit comments

Comments
 (0)