You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2022/09/02 07:22:54 UTC

[plc4x] branch develop updated: chore(plc4j/api): Refactored the PlcBrowseItem to have more properties (name, readable, writable, subscribable, children) and changed the dataType from String to PlcValueType.

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 6ff68d49a chore(plc4j/api): Refactored the PlcBrowseItem to have more properties (name, readable, writable, subscribable, children) and changed the dataType from String to PlcValueType.
6ff68d49a is described below

commit 6ff68d49ae236f22887dd8eece28c6fca2ad4c10
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Sep 2 09:22:45 2022 +0200

    chore(plc4j/api): Refactored the PlcBrowseItem to have more properties (name, readable, writable, subscribable, children) and changed the dataType from String to PlcValueType.
---
 .../plc4x/java/api/messages/PlcBrowseItem.java     | 31 ++++++++++-
 .../plc4x/java/ads/protocol/AdsProtocolLogic.java  | 41 +++++++++++---
 .../HelloPlc4xDiscoverAndBrowse.java               |  2 +-
 .../java/spi/messages/DefaultPlcBrowseItem.java    | 62 ++++++++++++++++++++--
 4 files changed, 123 insertions(+), 13 deletions(-)

diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcBrowseItem.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcBrowseItem.java
index 817390c60..e81b136ec 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcBrowseItem.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcBrowseItem.java
@@ -18,6 +18,10 @@
  */
 package org.apache.plc4x.java.api.messages;
 
+import org.apache.plc4x.java.api.types.PlcValueType;
+
+import java.util.List;
+
 public interface PlcBrowseItem {
 
     /**
@@ -25,9 +29,34 @@ public interface PlcBrowseItem {
      */
     String getAddress();
 
+    /**
+     * @return returns a textual description of this item
+     */
+    String getName();
+
     /**
      * @return returns the data-type of this item
      */
-    String getDataType();
+    PlcValueType getPlcValueType();
+
+    /**
+     * @return returns 'true' if we can read this variable.
+     */
+    boolean isReadable();
+
+    /**
+     * @return returns 'true' if we can write to this variable.
+     */
+    boolean isWritable();
+
+    /**
+     * @return returns 'true' if we can subscribe this variable.
+     */
+    boolean isSubscribable();
+
+    /**
+     * @return returns any children this item might have
+     */
+    List<PlcBrowseItem> getChildren();
 
 }
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
index 8a8bf8989..23336149b 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
@@ -316,36 +316,46 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         CompletableFuture<PlcBrowseResponse> future = new CompletableFuture<>();
         List<PlcBrowseItem> values = new ArrayList<>(symbolTable.size());
         for (AdsSymbolTableEntry symbol : symbolTable.values()) {
-            // Add the type itself.
-            values.add(new DefaultPlcBrowseItem(symbol.getName(), symbol.getDataTypeName()));
+            // Get the datatype of this entry.
             AdsDataTypeTableEntry dataType = dataTypeTable.get(symbol.getDataTypeName());
             if (dataType == null) {
                 System.out.printf("couldn't find datatype: %s%n", symbol.getDataTypeName());
                 continue;
             }
-            // Recursively add all children of the current datatype.
-            values.addAll(getBrowseItems(symbol.getName(), symbol.getGroup(), symbol.getOffset(), dataType));
+            String itemName = (symbol.getComment() == null || symbol.getComment().isEmpty()) ? symbol.getName() : symbol.getComment();
+            // Convert the plc value type from the ADS specific one to the PLC4X global one.
+            org.apache.plc4x.java.api.types.PlcValueType plc4xPlcValueType = org.apache.plc4x.java.api.types.PlcValueType.valueOf(getPlcValueTypeForAdsDataType(dataType).toString());
+
+            // If this type has children, add entries for its children.
+            List<PlcBrowseItem> children = getBrowseItems(symbol.getName(), symbol.getGroup(), symbol.getOffset(), !symbol.getFlagReadOnly(), dataType);
+            // Add the type itself.
+            values.add(new DefaultPlcBrowseItem(symbol.getName(), itemName, plc4xPlcValueType, true, !symbol.getFlagReadOnly(), true, children));
         }
         DefaultPlcBrowseResponse response = new DefaultPlcBrowseResponse(browseRequest, PlcResponseCode.OK, values);
         future.complete(response);
         return future;
     }
 
-    protected List<PlcBrowseItem> getBrowseItems(String basePath, long baseGroupId, long baseOffset, AdsDataTypeTableEntry dataType) {
+    protected List<PlcBrowseItem> getBrowseItems(String basePath, long baseGroupId, long baseOffset, boolean parentWritable, AdsDataTypeTableEntry dataType) {
         if (dataType.getNumChildren() == 0) {
             return Collections.emptyList();
         }
 
         List<PlcBrowseItem> values = new ArrayList<>(dataType.getNumChildren());
         for (AdsDataTypeTableChildEntry child : dataType.getChildren()) {
-            values.add(new DefaultPlcBrowseItem(basePath + "." + child.getPropertyName(), child.getDataTypeName()));
             AdsDataTypeTableEntry childDataType = dataTypeTable.get(child.getDataTypeName());
             if (childDataType == null) {
                 System.out.printf("couldn't find datatype: %s%n", child.getDataTypeName());
                 continue;
             }
+            String itemAddress = basePath + "." + child.getPropertyName();
+            String itemName = (child.getComment() == null || child.getComment().isEmpty()) ? child.getPropertyName() : child.getComment();
+            // Convert the plc value type from the ADS specific one to the PLC4X global one.
+            org.apache.plc4x.java.api.types.PlcValueType plc4xPlcValueType = org.apache.plc4x.java.api.types.PlcValueType.valueOf(getPlcValueTypeForAdsDataType(childDataType).toString());
             // Recursively add all children of the current datatype.
-            values.addAll(getBrowseItems(child.getDataTypeName(), baseGroupId, baseOffset + child.getOffset(), childDataType));
+            List<PlcBrowseItem> children = getBrowseItems(itemAddress, baseGroupId, baseOffset + child.getOffset(), parentWritable, childDataType);
+            // Add the type itself.
+            values.add(new DefaultPlcBrowseItem(basePath + "." + child.getPropertyName(), itemName, plc4xPlcValueType, true, parentWritable, true, children));
         }
         return values;
     }
@@ -1365,6 +1375,23 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
             if (dataTypeTableEntry.getArrayDimensions() > 0) {
                 return PlcValueType.List;
             }
+            // There seem to be some data types, that have odd names, but no children
+            // So we'll check if their "simpleTypeName" matches instead.
+            if(dataTypeTableEntry.getChildren().isEmpty()) {
+                try {
+                    dataTypeName = dataTypeTableEntry.getSimpleTypeName();
+                    if (dataTypeName.startsWith("STRING(")) {
+                        dataTypeName = "STRING";
+                    } else if (dataTypeName.startsWith("WSTRING(")) {
+                        dataTypeName = "WSTRING";
+                    }
+
+                    return PlcValueType.valueOf(dataTypeName);
+                } catch (IllegalArgumentException e2) {
+                    // In this case it's something we can't handle.
+                    return PlcValueType.NULL;
+                }
+            }
             return PlcValueType.Struct;
         }
     }
diff --git a/plc4j/examples/hello-world-plc4x-discover-and-browse/src/main/java/org/apache/plc4x/java/examples/helloplc4x/discoverandbrowse/HelloPlc4xDiscoverAndBrowse.java b/plc4j/examples/hello-world-plc4x-discover-and-browse/src/main/java/org/apache/plc4x/java/examples/helloplc4x/discoverandbrowse/HelloPlc4xDiscoverAndBrowse.java
index 33302f38d..6db390e06 100644
--- a/plc4j/examples/hello-world-plc4x-discover-and-browse/src/main/java/org/apache/plc4x/java/examples/helloplc4x/discoverandbrowse/HelloPlc4xDiscoverAndBrowse.java
+++ b/plc4j/examples/hello-world-plc4x-discover-and-browse/src/main/java/org/apache/plc4x/java/examples/helloplc4x/discoverandbrowse/HelloPlc4xDiscoverAndBrowse.java
@@ -52,7 +52,7 @@ public class HelloPlc4xDiscoverAndBrowse {
                                     throwable.printStackTrace();
                                 } else {
                                     for (PlcBrowseItem value : browseResponse.getValues()) {
-                                        System.out.println(String.format("%60s : %60s", value.getAddress(), value.getDataType()));
+                                        System.out.println(String.format("%60s : %60s", value.getAddress(), value.getPlcValueType().name()));
                                     }
                                 }
                             });
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java
index c29b4d828..457d8c2ee 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java
@@ -23,25 +23,46 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import org.apache.plc4x.java.api.messages.PlcBrowseItem;
 import org.apache.plc4x.java.api.messages.PlcDiscoveryItem;
+import org.apache.plc4x.java.api.types.PlcValueType;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
 import org.apache.plc4x.java.spi.utils.Serializable;
 
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 import java.util.Map;
 
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "className")
 public class DefaultPlcBrowseItem implements PlcBrowseItem, Serializable {
 
     private final String address;
-    private final String dataType;
+
+    private final String name;
+
+    private final PlcValueType dataType;
+
+    private final boolean readable;
+    private final boolean writable;
+    private final boolean subscribable;
+
+    private final List<PlcBrowseItem> children;
 
     @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
     public DefaultPlcBrowseItem(@JsonProperty("address") String address,
-                                @JsonProperty("dataType") String dataType) {
+                                @JsonProperty("name") String name,
+                                @JsonProperty("dataType") PlcValueType dataType,
+                                @JsonProperty("readable") boolean readable,
+                                @JsonProperty("writable") boolean writable,
+                                @JsonProperty("subscribable") boolean subscribable,
+                                @JsonProperty("children") List<PlcBrowseItem> children) {
         this.address = address;
+        this.name = name;
         this.dataType = dataType;
+        this.readable = readable;
+        this.writable = writable;
+        this.subscribable = subscribable;
+        this.children = children;
     }
 
     @Override
@@ -50,15 +71,48 @@ public class DefaultPlcBrowseItem implements PlcBrowseItem, Serializable {
     }
 
     @Override
-    public String getDataType() {
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public PlcValueType getPlcValueType() {
         return dataType;
     }
 
+    public boolean isReadable() {
+        return readable;
+    }
+
+    public boolean isWritable() {
+        return writable;
+    }
+
+    public boolean isSubscribable() {
+        return subscribable;
+    }
+
+    @Override
+    public List<PlcBrowseItem> getChildren() {
+        return children;
+    }
+
     @Override
     public void serialize(WriteBuffer writeBuffer) throws SerializationException {
         writeBuffer.pushContext(getClass().getSimpleName());
         writeBuffer.writeString("address", address.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), address);
-        writeBuffer.writeString("dataType", dataType.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), dataType);
+        writeBuffer.writeString("name", name.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), name);
+        // TODO: Find out how to serialize an enum.
+        //writeBuffer.writeString("dataType", dataType.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), dataType);
+        if(children != null && !children.isEmpty()) {
+            writeBuffer.pushContext("children");
+            for (PlcBrowseItem child : children) {
+                writeBuffer.pushContext("child");
+                ((DefaultPlcBrowseItem) child).serialize(writeBuffer);
+                writeBuffer.popContext("child");
+            }
+            writeBuffer.popContext("children");
+        }
         writeBuffer.popContext(getClass().getSimpleName());
     }