This is an automated email from the ASF dual-hosted git repository. cdutz pushed a commit to branch feature/cdutz/connection-cache-and-scraper-ng in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 433a1007be2c7838bab0285b175617780c82f15c Author: Christofer Dutz <[email protected]> AuthorDate: Wed Jan 11 15:45:17 2023 +0100 feat(plc4j/examples): Added a new example, using the ADS protocol to read device telemetry from the PLC using MDP --- plc4j/examples/hello-ads-telemetry/pom.xml | 73 +++++++++++++++++ .../helloads/telemetry/HelloAdsTelemetry.java | 94 ++++++++++++++++++++++ .../src/main/resources/logback.xml | 34 ++++++++ plc4j/examples/pom.xml | 1 + 4 files changed, 202 insertions(+) diff --git a/plc4j/examples/hello-ads-telemetry/pom.xml b/plc4j/examples/hello-ads-telemetry/pom.xml new file mode 100644 index 0000000000..dd2c6ff967 --- /dev/null +++ b/plc4j/examples/hello-ads-telemetry/pom.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + --> +<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/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.plc4x.examples</groupId> + <artifactId>plc4j-examples</artifactId> + <version>0.11.0-SNAPSHOT</version> + </parent> + + <artifactId>plc4j-examples-hello-ads-telemetry</artifactId> + <name>PLC4J: Examples: Hello-ADS telemetry</name> + <description>Hello world application using PLC4X to read ADS device telemetry.</description> + + <properties> + <app.main.class>org.apache.plc4x.java.examples.helloads.telemetry.HelloAdsTelemetry</app.main.class> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.plc4x</groupId> + <artifactId>plc4j-api</artifactId> + <version>0.11.0-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>log4j-over-slf4j</artifactId> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <configuration> + <usedDependencies combine.children="append"> + <usedDependency>org.slf4j:log4j-over-slf4j</usedDependency> + </usedDependencies> + </configuration> + </plugin> + </plugins> + </build> + +</project> \ No newline at end of file diff --git a/plc4j/examples/hello-ads-telemetry/src/main/java/org/apache/plc4x/java/examples/helloads/telemetry/HelloAdsTelemetry.java b/plc4j/examples/hello-ads-telemetry/src/main/java/org/apache/plc4x/java/examples/helloads/telemetry/HelloAdsTelemetry.java new file mode 100644 index 0000000000..783591d6ce --- /dev/null +++ b/plc4j/examples/hello-ads-telemetry/src/main/java/org/apache/plc4x/java/examples/helloads/telemetry/HelloAdsTelemetry.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.plc4x.java.examples.helloads.telemetry; + +import org.apache.plc4x.java.PlcDriverManager; +import org.apache.plc4x.java.api.PlcConnection; +import org.apache.plc4x.java.api.messages.PlcReadResponse; +import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +public class HelloAdsTelemetry { + + private static final Logger logger = LoggerFactory.getLogger(HelloAdsTelemetry.class); + public static void main(String[] args) { + if(args.length != 2) { + logger.error("Usage: HelloAdsTelemetry {ip-address of PLC} {local ip-address}"); + System.exit(1); + } + + String remoteIp = args[0]; + String localIp = args[1]; + try (PlcConnection connection = new PlcDriverManager().getConnection(String.format("ads:tcp://%s?targetAmsNetId=%s.1.1&targetAmsPort=10000&sourceAmsNetId=%s.1.1&sourceAmsPort=65534&load-symbol-and-data-type-tables=false", remoteIp, remoteIp, localIp))) { + // Load the number of modules: + int numModules = connection.readRequestBuilder().addTagAddress("numberOfModules", "0x0000F302/0xF0200000:UINT").build().execute().get().getInteger("numberOfModules"); + + // Load the mdp type and index for each module + // NOTE: We need to do this without using multi-item-requests as it seems that this part of the system doesn't support this. + Map<Integer, Integer> moduleTypeIdMap = new HashMap<>(); + for(int i = 1; i < numModules; i++) { + String name = "module-" + i; + String address = String.format("0x0000F302/0xF020%04X:UDINT", i); + PlcReadResponse plcReadResponse = connection.readRequestBuilder().addTagAddress(name, address).build().execute().get(); + if (plcReadResponse.getResponseCode(name) == PlcResponseCode.OK) { + int value = plcReadResponse.getInteger(name); + int mdpType = ((value & 0xFFFF0000) >> 16); + int mdpId = value & 0x0000FFFF; + logger.info("Module {} has mdp type {} and mdp id {}", i, mdpType, mdpId); + moduleTypeIdMap.put(mdpType, mdpId); + } + } + + // Read the ADS Version information. + if(moduleTypeIdMap.containsKey(0x00000008)) { + Integer mdpId = moduleTypeIdMap.get(0x00000008); + int addrAdsTypeMain = (mdpId << 20) | 0x80010001; + int addrAdsTypeMinor = (mdpId << 20) | 0x80010002; + int addrAdsTypeBuild = (mdpId << 20) | 0x80010003; + int twinCatMainVersion = connection.readRequestBuilder().addTagAddress("value", String.format("0x0000F302/0x%8X:UINT", addrAdsTypeMain)).build().execute().get().getInteger("value"); + int twinCatMinorVersion = connection.readRequestBuilder().addTagAddress("value", String.format("0x0000F302/0x%8X:UINT", addrAdsTypeMinor)).build().execute().get().getInteger("value"); + int twinCatBuildVersion = connection.readRequestBuilder().addTagAddress("value", String.format("0x0000F302/0x%8X:UINT", addrAdsTypeBuild)).build().execute().get().getInteger("value"); + logger.info("TwinCat Version: {}.{}.{}", twinCatMainVersion, twinCatMinorVersion, twinCatBuildVersion); + } + // Read the CPU Frequency and Utilization. + if(moduleTypeIdMap.containsKey(0x0000000B)) { + Integer mdpId = moduleTypeIdMap.get(0x0000000B); + int addrCpuFrequency = (mdpId << 20) | 0x80010001; + int addrCpuUsage = (mdpId << 20) | 0x80010002; + int cpuFrequency = connection.readRequestBuilder().addTagAddress("value", String.format("0x0000F302/0x%8X:UDINT", addrCpuFrequency)).build().execute().get().getInteger("value"); + int cpuUsage = connection.readRequestBuilder().addTagAddress("value", String.format("0x0000F302/0x%8X:UINT", addrCpuUsage)).build().execute().get().getInteger("value"); + logger.info("CPU: Frequency: {}MHz Usage: {}%", cpuFrequency, cpuUsage); + } + // Read the Memory usage. + if(moduleTypeIdMap.containsKey(0x0000000C)) { + Integer mdpId = moduleTypeIdMap.get(0x0000000C); + int addrMemoryUsage = (mdpId << 20) | 0x80010002; + int memoryUsage = connection.readRequestBuilder().addTagAddress("value", String.format("0x0000F302/0x%8X:UDINT", addrMemoryUsage)).build().execute().get().getInteger("value"); + logger.info("Memory: Available: {}MB", memoryUsage / (1024 * 1024)); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/plc4j/examples/hello-ads-telemetry/src/main/resources/logback.xml b/plc4j/examples/hello-ads-telemetry/src/main/resources/logback.xml new file mode 100644 index 0000000000..eee180ec73 --- /dev/null +++ b/plc4j/examples/hello-ads-telemetry/src/main/resources/logback.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + --> +<configuration xmlns="http://ch.qos.logback/xml/ns/logback" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd"> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + </appender> + + <root level="info"> + <appender-ref ref="STDOUT" /> + </root> + +</configuration> \ No newline at end of file diff --git a/plc4j/examples/pom.xml b/plc4j/examples/pom.xml index 2447ca392d..61dc602d36 100644 --- a/plc4j/examples/pom.xml +++ b/plc4j/examples/pom.xml @@ -39,6 +39,7 @@ </properties> <modules> + <module>hello-ads-telemetry</module> <module>hello-cloud-azure</module> <module>hello-cloud-google</module> <module>hello-discovery</module>
