From 3dc0976cf61f8ef1ba3a8ceb95611ecaf24ace84 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Sun, 22 Feb 2026 19:07:41 +0100 Subject: [PATCH 1/3] chore: Added a test for my S7-1500 opcua setup and did some minor tweaks to support reading and writing most types on this PLC. --- .../plc4x/java/opcua/OpcuaPlcDriver.java | 7 - .../opcua/protocol/OpcuaProtocolLogic.java | 51 ++-- .../ManualOpcUaS71500NewFWDriverTest.java | 149 ++++++++++ .../spi/values/DefaultPlcValueHandler.java | 18 +- .../spi/values/LegacyPlcValueHandler.java | 264 ------------------ 5 files changed, 187 insertions(+), 302 deletions(-) create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java delete mode 100644 plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/LegacyPlcValueHandler.java diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java index a1200481b73..6043a3ba0f6 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java @@ -29,8 +29,6 @@ import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; -import org.apache.plc4x.java.spi.values.LegacyPlcValueHandler; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.util.Collections; import java.util.List; @@ -64,11 +62,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected PlcValueHandler getValueHandler() { - return new LegacyPlcValueHandler(); - } - @Override protected boolean canRead() { return true; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java index 41d8c94cd70..6b804959dbd 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java @@ -22,6 +22,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.time.*; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import org.apache.plc4x.java.api.authentication.PlcAuthentication; @@ -50,7 +51,6 @@ import org.apache.plc4x.java.spi.configuration.HasConfiguration; import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; -import org.apache.plc4x.java.spi.generation.Message; import org.apache.plc4x.java.spi.messages.*; import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; @@ -59,17 +59,12 @@ import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager.RequestTransaction; -import org.apache.plc4x.java.spi.values.LegacyPlcValueHandler; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcList; -import org.apache.plc4x.java.spi.values.PlcSTRING; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.math.BigInteger; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; @@ -319,44 +314,44 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = array[i] != 0; } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantSByte) { byte[] array = ((VariantSByte) variant).getValue(); - value = LegacyPlcValueHandler.of(tag, array); + value = DefaultPlcValueHandler.of(tag, array); } else if (variant instanceof VariantByte) { List array = ((VariantByte) variant).getValue(); Short[] tmpValue = array.toArray(new Short[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantInt16) { List array = ((VariantInt16) variant).getValue(); Short[] tmpValue = array.toArray(new Short[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantUInt16) { List array = ((VariantUInt16) variant).getValue(); Integer[] tmpValue = array.toArray(new Integer[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantInt32) { List array = ((VariantInt32) variant).getValue(); Integer[] tmpValue = array.toArray(new Integer[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantUInt32) { List array = ((VariantUInt32) variant).getValue(); Long[] tmpValue = array.toArray(new Long[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantInt64) { List array = ((VariantInt64) variant).getValue(); Long[] tmpValue = array.toArray(new Long[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantUInt64) { - value = LegacyPlcValueHandler.of(((VariantUInt64) variant).getValue()); + value = DefaultPlcValueHandler.of(tag, ((VariantUInt64) variant).getValue()); } else if (variant instanceof VariantFloat) { List array = ((VariantFloat) variant).getValue(); Float[] tmpValue = array.toArray(new Float[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantDouble) { List array = ((VariantDouble) variant).getValue(); Double[] tmpValue = array.toArray(new Double[0]); - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantString) { int length = ((VariantString) variant).getValue().size(); List stringArray = ((VariantString) variant).getValue(); @@ -364,7 +359,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = stringArray.get(i).getStringValue(); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantDateTime) { List array = ((VariantDateTime) variant).getValue(); int length = array.size(); @@ -372,7 +367,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = LocalDateTime.ofInstant(Instant.ofEpochMilli(getDateTime(array.get(i))), ZoneOffset.UTC); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantGuid) { List array = ((VariantGuid) variant).getValue(); int length = array.size(); @@ -391,7 +386,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { } tmpValue[i] = Long.toHexString(array.get(i).getData1()) + "-" + Integer.toHexString(array.get(i).getData2()) + "-" + Integer.toHexString(array.get(i).getData3()) + "-" + Integer.toHexString(data4) + "-" + Long.toHexString(data5); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantXmlElement) { int length = ((VariantXmlElement) variant).getValue().size(); List strings = ((VariantXmlElement) variant).getValue(); @@ -399,7 +394,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).getStringValue(); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantLocalizedText) { int length = ((VariantLocalizedText) variant).getValue().size(); List strings = ((VariantLocalizedText) variant).getValue(); @@ -409,7 +404,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { tmpValue[i] += strings.get(i).getLocaleSpecified() ? strings.get(i).getLocale().getStringValue() + "|" : ""; tmpValue[i] += strings.get(i).getTextSpecified() ? strings.get(i).getText().getStringValue() : ""; } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantQualifiedName) { int length = ((VariantQualifiedName) variant).getValue().size(); List strings = ((VariantQualifiedName) variant).getValue(); @@ -417,7 +412,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = "ns=" + strings.get(i).getNamespaceIndex() + ";s=" + strings.get(i).getName().getStringValue(); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantExtensionObject) { int length = ((VariantExtensionObject) variant).getValue().size(); List strings = ((VariantExtensionObject) variant).getValue(); @@ -425,7 +420,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).toString(); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantNodeId) { int length = ((VariantNodeId) variant).getValue().size(); List strings = ((VariantNodeId) variant).getValue(); @@ -433,7 +428,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).toString(); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantStatusCode) { int length = ((VariantStatusCode) variant).getValue().size(); List strings = ((VariantStatusCode) variant).getValue(); @@ -441,7 +436,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).toString(); } - value = LegacyPlcValueHandler.of(tmpValue); + value = DefaultPlcValueHandler.of(tag, tmpValue); } else if (variant instanceof VariantByteString) { PlcList plcList = new PlcList(); List array = ((VariantByteString) variant).getValue(); @@ -451,7 +446,7 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { for (int i = 0; i < length; i++) { tmpValue[i] = byteStringArray.getValue().get(i); } - plcList.add(LegacyPlcValueHandler.of(tmpValue)); + plcList.add(DefaultPlcValueHandler.of(tag, tmpValue)); } value = plcList; } diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java new file mode 100644 index 00000000000..9b7050b0384 --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java @@ -0,0 +1,149 @@ +/* + * 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.opcua; + +import org.apache.plc4x.java.spi.values.*; +import org.apache.plc4x.test.manual.ManualTest; + +import java.math.BigDecimal; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; + +public class ManualOpcUaS71500NewFWDriverTest extends ManualTest { + + public ManualOpcUaS71500NewFWDriverTest(String connectionString) { + super(connectionString, true, true, true, true, 100); + } + + public static void main(String[] args) throws Exception { + boolean testArrays = false; + ManualOpcUaS71500NewFWDriverTest test = new ManualOpcUaS71500NewFWDriverTest("opcua://192.168.24.66:4840"); + test.addTestCase(/*"g_b1",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_b1\";BOOL", new PlcBOOL(true)); + test.addTestCase(/*"g_b8",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_b8\";BYTE", new PlcBYTE(0xAB)); + test.addTestCase(/*"g_s8",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_s8\";SINT", new PlcSINT(-12)); + test.addTestCase(/*"g_u8",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_u8\";USINT", new PlcUSINT(250)); + // TODO: Getting "INVALID_ADDRESS", as WORD is not part of OpcuaDataType +// test.addTestCase(/*"g_b16",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_b16\";WORD", new PlcWORD(0xBEEF)); + test.addTestCase(/*"g_s16",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_s16\";INT", new PlcINT(-1234)); + test.addTestCase(/*"g_u16",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_u16\";UINT", new PlcUINT(54321)); + // TODO: Getting "INVALID_ADDRESS", as DWORD is not part of OpcuaDataType +// test.addTestCase(/*"g_b32",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_b32\";DWORD", new PlcDWORD(0xDEADBEEFL)); + test.addTestCase(/*"g_s32",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_s32\";DINT", new PlcDINT(-12345678)); + test.addTestCase(/*"g_u32",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_u32\";UDINT", new PlcUDINT(305419896)); + // TODO: Getting "INVALID_ADDRESS", as LWORD is not part of OpcuaDataType +// test.addTestCase(/*"g_b64",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_b64\";LWORD", new PlcLWORD(0x0123_4567_89AB_CDEFL)); + test.addTestCase(/*"g_s64",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_s64\";LINT", new PlcLINT(-9223372036854770000L)); + // TODO: This seems to write different values to the plc. +// test.addTestCase(/*"g_u64",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_u64\";ULINT", new PlcULINT(new BigDecimal("18446744073709551000"))); + test.addTestCase(/*"g_r32",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_r32\";REAL", new PlcREAL(3.14159)); + test.addTestCase(/*"g_r64",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_r64\";LREAL", new PlcLREAL(2.71828182845905)); + // TODO: Writing of TIME doesn't seem to be supported. +// test.addTestCase(/*"g_tim",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_tim\";TIME", new PlcTIME(2500)); // Is returned as Int32 + // TODO: IEC 61131-3 date types use 1990-01-01 as epoch, PlcDATE etc. use Unix epoch (1970-01-01). +// test.addTestCase(/*"g_dat",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_dat\";DATE", new PlcDATE(LocalDate.of(2025, 11, 12))); // Is returned as UInt16 + // TODO: S7/IEC value is milliseconds since midnight +// test.addTestCase(/*"g_timoday",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_timoday\";TIME_OF_DAY", new PlcTIME_OF_DAY(LocalTime.of(14, 33, 21, 250000000))); // Is returned as UInt32 + // TODO: Getting a class cast exception here +// test.addTestCase(/*"g_dattim",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_dattim\";DATE_AND_TIME", new PlcDATE_AND_LTIME(LocalDateTime.of(2025, 11, 12, 14, 33, 21, 500_000_000))); + + test.addTestCase(/*"g_str",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_str\";STRING", new PlcSTRING("Hello PLC4X")); + // TODO: Getting "INVALID_ADDRESS", as WSTRING is not part of OpcuaDataType +// test.addTestCase(/*"g_wstr",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_wstr\";WSTRING", new PlcWSTRING("Grüße von PLC4X")); + if(testArrays) { + test.addTestCase(/*"g_arrBool",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrBool\"", new PlcList(List.of( + new PlcBOOL(true), new PlcBOOL(false), new PlcBOOL(true), new PlcBOOL(true), + new PlcBOOL(false), new PlcBOOL(false), new PlcBOOL(true), new PlcBOOL(false)) + )); + test.addTestCase(/*"g_arrByte",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrByte\"", new PlcList(List.of( + new PlcBYTE(0xDE), new PlcBYTE(0xAD), new PlcBYTE(0xBE), new PlcBYTE(0xEF), + new PlcBYTE(0x12), new PlcBYTE(0x34), new PlcBYTE(0x56), new PlcBYTE(0x78)) + )); + test.addTestCase(/*"g_arrInt",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrInt\"", new PlcList(List.of( + new PlcINT(-3), new PlcINT(-1), new PlcINT(0), new PlcINT(1), new PlcINT(3)) + )); + test.addTestCase(/*"g_arrUInt",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrUInt\"", new PlcList(List.of( + new PlcUINT(1), new PlcUINT(10), new PlcUINT(100), new PlcUINT(1000), new PlcUINT(10000)) + )); + test.addTestCase(/*"g_arrDInt",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrDInt\"", new PlcList(List.of( + new PlcDINT(-1000), new PlcDINT(0), new PlcDINT(1000), new PlcDINT(2000000)) + )); + test.addTestCase(/*"g_arrUDInt",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrUDInt\"", new PlcList(List.of( + new PlcUDINT(0), new PlcUDINT(1), new PlcUDINT(0xFFFF), new PlcUDINT(0x12345678)) + )); + test.addTestCase(/*"g_arrLReal",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrLReal\"", new PlcList(List.of( + new PlcLREAL(1.5), new PlcLREAL(-2.0), new PlcLREAL(0.125)) + )); + test.addTestCase(/*"g_arrTime",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrTime\";TIME", new PlcList(List.of( + new PlcTIME(Duration.ofMillis(10)), new PlcTIME(Duration.ofSeconds(1)), new PlcTIME(Duration.ofSeconds(10))) + )); + test.addTestCase(/*"g_arrString",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrString\"", new PlcList(List.of( + new PlcSTRING("alpha"), new PlcSTRING("beta"), new PlcSTRING("gamma")) + )); + test.addTestCase(/*"g_arrWString",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_arrWString\"", new PlcList(List.of( + new PlcWSTRING("Äpfel"), new PlcWSTRING("Öl")) + )); + test.addTestCase(/*"g_matI16_2x3",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_matI16_2x3\"", new PlcList(List.of( + new PlcList(List.of( + new PlcINT(10), new PlcINT(11), new PlcINT(12) + )), + new PlcList(List.of( + new PlcINT(-10), new PlcINT(-11), new PlcINT(-12) + ))) + )); + test.addTestCase(/*"g_matR32_3x2",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_matR32_3x2\"", new PlcList(List.of( + new PlcList(List.of( + new PlcREAL(1.0), new PlcREAL(1.5) + )), + new PlcList(List.of( + new PlcREAL(2.0), new PlcREAL(2.5) + )), + new PlcList(List.of( + new PlcREAL(3.0), new PlcREAL(3.5) + ))) + )); + test.addTestCase(/*"g_cubeU16_2x2x2",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_cubeU16_2x2x2\"", new PlcList(List.of( + new PlcList(List.of( + new PlcList(List.of( + new PlcUINT(1), new PlcUINT(2) + )), + new PlcList(List.of( + new PlcUINT(3), new PlcUINT(4) + )) + )), + new PlcList(List.of( + new PlcList(List.of( + new PlcUINT(5), new PlcUINT(6) + )), + new PlcList(List.of( + new PlcUINT(7), new PlcUINT(8) + )) + ))) + )); + } + + long start = System.currentTimeMillis(); + test.run(); + long end = System.currentTimeMillis(); + System.out.printf("Finished in %d ms", end - start); + } + +} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandler.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandler.java index 1cd73fdbc63..125cb18c9d8 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandler.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandler.java @@ -26,6 +26,7 @@ import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.api.value.PlcValue; +import java.lang.reflect.Array; import java.math.BigInteger; import java.time.Duration; import java.time.LocalDate; @@ -82,7 +83,7 @@ public static PlcValue of(PlcTag tag, Object[] values) { } private static PlcValue ofElements(PlcValueType type, List arrayInfos, Object[] values) { - ArrayInfo arrayInfo = arrayInfos.get(0); + ArrayInfo arrayInfo = arrayInfos.getFirst(); if(values.length == 1) { if(values[0] instanceof Object[]) { @@ -91,8 +92,7 @@ private static PlcValue ofElements(PlcValueType type, List arrayInfos values = ((Collection) values[0]).toArray(); } else if(values[0] instanceof PlcList) { values = ((PlcList) values[0]).getList().toArray(); - } else if(values[0] instanceof PlcRawByteArray) { - PlcRawByteArray plcRawByteArray = (PlcRawByteArray) values[0]; + } else if(values[0] instanceof PlcRawByteArray plcRawByteArray) { if(plcRawByteArray.getRaw().length != arrayInfo.getSize()) { throw new PlcRuntimeException(String.format("Expecting %d items, but got %d", arrayInfo.getSize(), plcRawByteArray.getRaw().length)); } @@ -126,6 +126,18 @@ private static PlcValue ofElement(PlcValueType type, Object value) { if(type == null) { return of(value); } + + // If this is not a List type, and we're passing in an array or a collection with exactly one element, + // get that element instead. + if (type != PlcValueType.List) { + if(value.getClass().isArray() && (Array.getLength(value) == 1)) { + value = Array.get(value, 0); + } + else if((value instanceof Collection col) && (col.size() == 1)) { + value = col.iterator().next(); + } + } + switch (type) { case BOOL: return PlcBOOL.of(value); diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/LegacyPlcValueHandler.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/LegacyPlcValueHandler.java deleted file mode 100644 index 0343bc4434d..00000000000 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/LegacyPlcValueHandler.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * 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 - * - * http://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.spi.values; - -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; -import org.apache.plc4x.java.api.exceptions.PlcUnsupportedDataTypeException; -import org.apache.plc4x.java.api.model.PlcTag; -import org.apache.plc4x.java.api.value.PlcValue; - -import java.math.BigInteger; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.List; - -public class LegacyPlcValueHandler implements PlcValueHandler { - - public PlcValue newPlcValue(Object value) { - return of(new Object[]{value}); - } - - public PlcValue newPlcValue(Object[] values) { - return of(values); - } - - public PlcValue newPlcValue(PlcTag tag, Object value) { - return of(tag, new Object[]{value}); - } - - public PlcValue newPlcValue(PlcTag tag, Object[] values) { - return of(tag, values); - } - - public static PlcValue of(Object value) { - return of(new Object[]{value}); - } - - public static PlcValue of(List value) { - return of(value.toArray()); - } - - public static PlcValue of(Object[] values) { - if (values.length != 1) { - PlcList list = new PlcList(); - for (Object value : values) { - list.add(of(new Object[]{value})); - } - return list; - } - Object value = values[0]; - if (value instanceof Boolean) { - return PlcBOOL.of(value); - } - if (value instanceof Byte) { - return PlcSINT.of(value); - } - if (value instanceof byte[]) { - return PlcRawByteArray.of(value); - } - if (value instanceof Short) { - return PlcINT.of(value); - } - if (value instanceof Integer) { - return PlcDINT.of(value); - } - if (value instanceof Long) { - return PlcLINT.of(value); - } - if (value instanceof BigInteger) { - return PlcLINT.of(value); - } - if (value instanceof Float) { - return PlcREAL.of(value); - } - if (value instanceof Double) { - return PlcLREAL.of(value); - } - if (value instanceof Duration) { - return new PlcTIME((Duration) value); - } - if (value instanceof LocalTime) { - return new PlcTIME_OF_DAY((LocalTime) value); - } - if (value instanceof LocalDate) { - return new PlcDATE((LocalDate) value); - } - if (value instanceof LocalDateTime) { - return new PlcDATE_AND_TIME((LocalDateTime) value); - } - if (value instanceof String) { - return new PlcSTRING((String) value); - } - if (value instanceof PlcValue) { - return (PlcValue) value; - } - throw new PlcUnsupportedDataTypeException("Data Type " + value.getClass() - + " Is not supported"); - } - - - public static PlcValue of(PlcTag tag, Object value) { - return of(tag, new Object[]{value}); - } - - - public static PlcValue of(PlcTag tag, Object[] values) { - if (values.length == 1) { - Object value = values[0]; - if(tag.getPlcValueType() == null) { - // TODO: This is a hacky shortcut .. - if(value instanceof PlcValue) { - return (PlcValue) value; - } - return new PlcNull(); - } - if (value instanceof PlcValue) { - PlcValue plcValue = (PlcValue) value; - if (plcValue.getPlcValueType() == tag.getPlcValueType()) { - return (PlcValue) value; - } else { - throw new PlcRuntimeException("Expected PlcValue of type " + tag.getPlcValueType().name() + " but got " + plcValue.getPlcValueType().name()); - } - } - switch (tag.getPlcValueType()) { - case BOOL: - return PlcBOOL.of(value); - case BYTE: - if(value instanceof Short) { - return new PlcBYTE((short) value); - } else if(value instanceof Integer) { - return new PlcBYTE(((Integer) value).shortValue()); - } else if(value instanceof Long) { - return new PlcBYTE(((Long) value).shortValue()); - } else if(value instanceof BigInteger) { - return new PlcBYTE(((BigInteger) value).shortValue()); - } else if(value instanceof String) { - try { - return new PlcBYTE(Short.valueOf((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as Byte"); - } - } - throw new PlcRuntimeException("BYTE requires short"); - case SINT: - return PlcSINT.of(value); - case USINT: - return PlcUSINT.of(value); - case INT: - return PlcINT.of(value); - case UINT: - return PlcUINT.of(value); - case WORD: - if(value instanceof Short) { - return new PlcWORD((int) value); - } else if(value instanceof Integer) { - return new PlcWORD((int) value); - } else if(value instanceof Long) { - return new PlcWORD(((Long) value).intValue()); - } else if(value instanceof BigInteger) { - return new PlcWORD(((BigInteger) value).intValue()); - } else if(value instanceof String) { - try { - return new PlcWORD(Integer.valueOf((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as Integer"); - } - } - throw new PlcRuntimeException("WORD requires int"); - case DINT: - return PlcDINT.of(value); - case UDINT: - return PlcUDINT.of(value); - case DWORD: - if(value instanceof Short) { - return new PlcDWORD((long) value); - } else if(value instanceof Integer) { - return new PlcDWORD((long) value); - } else if(value instanceof Long) { - return new PlcDWORD((long) value); - } else if(value instanceof BigInteger) { - return new PlcDWORD(((BigInteger) value).longValue()); - } else if(value instanceof String) { - try { - return new PlcDWORD(Long.valueOf((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as Long"); - } - } - throw new PlcRuntimeException("DWORD requires long"); - case LINT: - return PlcLINT.of(value); - case ULINT: - return PlcULINT.of(value); - case LWORD: - if(value instanceof Short) { - return new PlcLWORD(BigInteger.valueOf((long) value)); - } else if(value instanceof Integer) { - return new PlcLWORD(BigInteger.valueOf((long) value)); - } else if(value instanceof Long) { - return new PlcLWORD(BigInteger.valueOf((long) value)); - } else if(value instanceof BigInteger) { - return new PlcLWORD((BigInteger) value); - } else if(value instanceof String) { - try { - return new PlcLWORD(new BigInteger((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as BigInteger"); - } - } - throw new PlcRuntimeException("LWORD requires BigInteger"); - case REAL: - return PlcREAL.of(value); - case LREAL: - return PlcLREAL.of(value); - case CHAR: - return PlcCHAR.of(value); - case WCHAR: - return PlcWCHAR.of(value); - case STRING: - return PlcSTRING.of(value); - case WSTRING: - return PlcWSTRING.of(value); - case TIME: - return PlcTIME.of(value); - case DATE: - return PlcDATE.of(value); - case TIME_OF_DAY: - return PlcTIME_OF_DAY.of(value); - case DATE_AND_TIME: - return PlcDATE_AND_TIME.of(value); - default: - return customDataType(new Object[]{value}); - } - } else { - PlcList list = new PlcList(); - for (Object value : values) { - list.add(of(tag, new Object[]{value})); - } - return list; - } - } - - public static PlcValue customDataType(Object[] values) { - return of(values); - } -} From 4f19acf12a2a15b625e2c7e20ed000ae1a350377 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Sun, 22 Feb 2026 19:26:13 +0100 Subject: [PATCH 2/3] chore: Fixed the build --- plc4go/assets/testing/protocols/opcua/DriverTestsuite.xml | 4 ++-- plc4j/drivers/opcua/pom.xml | 1 + .../src/test/resources/protocols/opcua/DriverTestsuite.xml | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plc4go/assets/testing/protocols/opcua/DriverTestsuite.xml b/plc4go/assets/testing/protocols/opcua/DriverTestsuite.xml index 84fd77de48d..8427357d446 100644 --- a/plc4go/assets/testing/protocols/opcua/DriverTestsuite.xml +++ b/plc4go/assets/testing/protocols/opcua/DriverTestsuite.xml @@ -1338,7 +1338,7 @@ time -
ns=0;i=2258
+
ns=0;i=2258;DATE_AND_TIME
@@ -1681,7 +1681,7 @@ ns=0;i=2258 Value - NULL + DATE_AND_TIME diff --git a/plc4j/drivers/opcua/pom.xml b/plc4j/drivers/opcua/pom.xml index df242d86b4e..1369766cf2e 100644 --- a/plc4j/drivers/opcua/pom.xml +++ b/plc4j/drivers/opcua/pom.xml @@ -110,6 +110,7 @@ org.jacoco jacoco-maven-plugin + false org/eclipse/**/* diff --git a/protocols/opcua/src/test/resources/protocols/opcua/DriverTestsuite.xml b/protocols/opcua/src/test/resources/protocols/opcua/DriverTestsuite.xml index 84fd77de48d..8427357d446 100644 --- a/protocols/opcua/src/test/resources/protocols/opcua/DriverTestsuite.xml +++ b/protocols/opcua/src/test/resources/protocols/opcua/DriverTestsuite.xml @@ -1338,7 +1338,7 @@ time -
ns=0;i=2258
+
ns=0;i=2258;DATE_AND_TIME
@@ -1681,7 +1681,7 @@ ns=0;i=2258 Value - NULL + DATE_AND_TIME From 44a9064c66af72581c88b0afcf0244cb2077602a Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Mon, 23 Feb 2026 08:51:08 +0100 Subject: [PATCH 3/3] chore: Ported the initial fix for the reading of arrays. --- .../plc4x/java/opcua/readwrite/Variant.java | 16 +- .../java/opcua/readwrite/VariantBoolean.java | 4 +- .../java/opcua/readwrite/VariantByte.java | 4 +- .../opcua/readwrite/VariantByteString.java | 4 +- .../opcua/readwrite/VariantDataValue.java | 4 +- .../java/opcua/readwrite/VariantDateTime.java | 4 +- .../readwrite/VariantDiagnosticInfo.java | 4 +- .../java/opcua/readwrite/VariantDouble.java | 4 +- .../readwrite/VariantExpandedNodeId.java | 4 +- .../readwrite/VariantExtensionObject.java | 4 +- .../java/opcua/readwrite/VariantFloat.java | 4 +- .../java/opcua/readwrite/VariantGuid.java | 4 +- .../java/opcua/readwrite/VariantInt16.java | 4 +- .../java/opcua/readwrite/VariantInt32.java | 4 +- .../java/opcua/readwrite/VariantInt64.java | 4 +- .../opcua/readwrite/VariantLocalizedText.java | 4 +- .../java/opcua/readwrite/VariantNodeId.java | 4 +- .../java/opcua/readwrite/VariantNull.java | 4 +- .../opcua/readwrite/VariantQualifiedName.java | 4 +- .../java/opcua/readwrite/VariantSByte.java | 4 +- .../opcua/readwrite/VariantStatusCode.java | 4 +- .../java/opcua/readwrite/VariantString.java | 4 +- .../java/opcua/readwrite/VariantUInt16.java | 4 +- .../java/opcua/readwrite/VariantUInt32.java | 4 +- .../java/opcua/readwrite/VariantUInt64.java | 4 +- .../java/opcua/readwrite/VariantVariant.java | 4 +- .../opcua/readwrite/VariantXmlElement.java | 4 +- .../opcua/protocol/OpcuaProtocolLogic.java | 293 +++++++++++++----- .../ManualOpcUaS71500NewFWDriverTest.java | 2 +- .../protocols/opcua/opc-manual.mspec | 4 +- protocols/opcua/src/main/xslt/opc-manual.xsl | 4 +- 31 files changed, 272 insertions(+), 151 deletions(-) diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/Variant.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/Variant.java index 14397b3060d..58e46699439 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/Variant.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/Variant.java @@ -44,13 +44,13 @@ public abstract class Variant implements Message { protected final boolean arrayLengthSpecified; protected final boolean arrayDimensionsSpecified; protected final Integer noOfArrayDimensions; - protected final List arrayDimensions; + protected final List arrayDimensions; public Variant( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { super(); this.arrayLengthSpecified = arrayLengthSpecified; this.arrayDimensionsSpecified = arrayDimensionsSpecified; @@ -70,7 +70,7 @@ public Integer getNoOfArrayDimensions() { return noOfArrayDimensions; } - public List getArrayDimensions() { + public List getArrayDimensions() { return arrayDimensions; } @@ -99,7 +99,7 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { writeOptionalField("noOfArrayDimensions", noOfArrayDimensions, writeSignedInt(writeBuffer, 32)); // Array Field (arrayDimensions) - writeSimpleTypeArrayField("arrayDimensions", arrayDimensions, writeBoolean(writeBuffer)); + writeSimpleTypeArrayField("arrayDimensions", arrayDimensions, writeSignedInt(writeBuffer, 32)); writeBuffer.popContext("Variant"); } @@ -133,7 +133,7 @@ public int getLengthInBits() { // Array field if (arrayDimensions != null) { - lengthInBits += 1 * arrayDimensions.size(); + lengthInBits += 32 * arrayDimensions.size(); } return lengthInBits; @@ -222,10 +222,10 @@ public static Variant staticParse(ReadBuffer readBuffer) throws ParseException { readOptionalField( "noOfArrayDimensions", readSignedInt(readBuffer, 32), arrayDimensionsSpecified); - List arrayDimensions = + List arrayDimensions = readCountArrayField( "arrayDimensions", - readBoolean(readBuffer), + readSignedInt(readBuffer, 32), (((noOfArrayDimensions) == (null)) ? 0 : noOfArrayDimensions)); readBuffer.closeContext("Variant"); @@ -241,7 +241,7 @@ Variant build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions); + List arrayDimensions); } @Override diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantBoolean.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantBoolean.java index 452894bc4d1..a89d6439686 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantBoolean.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantBoolean.java @@ -50,7 +50,7 @@ public VariantBoolean( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, byte[] value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -136,7 +136,7 @@ public VariantBoolean build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantBoolean variantBoolean = new VariantBoolean( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByte.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByte.java index d4bb68dfe94..0d488d2aa3e 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByte.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByte.java @@ -50,7 +50,7 @@ public VariantByte( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -138,7 +138,7 @@ public VariantByte build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantByte variantByte = new VariantByte( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByteString.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByteString.java index 7c5478e068b..f9b2af6a1b0 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByteString.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantByteString.java @@ -50,7 +50,7 @@ public VariantByteString( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantByteString build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantByteString variantByteString = new VariantByteString( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDataValue.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDataValue.java index 424128db2a4..7ee036082ab 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDataValue.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDataValue.java @@ -50,7 +50,7 @@ public VariantDataValue( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantDataValue build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantDataValue variantDataValue = new VariantDataValue( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDateTime.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDateTime.java index 68feac13707..603b8da10f5 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDateTime.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDateTime.java @@ -50,7 +50,7 @@ public VariantDateTime( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -136,7 +136,7 @@ public VariantDateTime build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantDateTime variantDateTime = new VariantDateTime( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDiagnosticInfo.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDiagnosticInfo.java index 3d4cc55c091..eeebd81b3bd 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDiagnosticInfo.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDiagnosticInfo.java @@ -50,7 +50,7 @@ public VariantDiagnosticInfo( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantDiagnosticInfo build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantDiagnosticInfo variantDiagnosticInfo = new VariantDiagnosticInfo( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDouble.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDouble.java index 6c7f9f33a2b..1acb34c9382 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDouble.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantDouble.java @@ -50,7 +50,7 @@ public VariantDouble( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -136,7 +136,7 @@ public VariantDouble build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantDouble variantDouble = new VariantDouble( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExpandedNodeId.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExpandedNodeId.java index 5b4db90d26e..0ac9caaa763 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExpandedNodeId.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExpandedNodeId.java @@ -50,7 +50,7 @@ public VariantExpandedNodeId( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantExpandedNodeId build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantExpandedNodeId variantExpandedNodeId = new VariantExpandedNodeId( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExtensionObject.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExtensionObject.java index b30622ff806..b914e79d5bb 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExtensionObject.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantExtensionObject.java @@ -50,7 +50,7 @@ public VariantExtensionObject( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -143,7 +143,7 @@ public VariantExtensionObject build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantExtensionObject variantExtensionObject = new VariantExtensionObject( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantFloat.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantFloat.java index 186aaed2a0c..4f8b1b76942 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantFloat.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantFloat.java @@ -50,7 +50,7 @@ public VariantFloat( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -136,7 +136,7 @@ public VariantFloat build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantFloat variantFloat = new VariantFloat( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantGuid.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantGuid.java index fc85b24505a..7011f02a82c 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantGuid.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantGuid.java @@ -50,7 +50,7 @@ public VariantGuid( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantGuid build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantGuid variantGuid = new VariantGuid( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt16.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt16.java index ce6f2cd30c2..8950ea2277d 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt16.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt16.java @@ -50,7 +50,7 @@ public VariantInt16( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -138,7 +138,7 @@ public VariantInt16 build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantInt16 variantInt16 = new VariantInt16( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt32.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt32.java index 8cc8a9051fa..ace173c9fcd 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt32.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt32.java @@ -50,7 +50,7 @@ public VariantInt32( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -136,7 +136,7 @@ public VariantInt32 build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantInt32 variantInt32 = new VariantInt32( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt64.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt64.java index f5bf1d90259..b11d03c2f71 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt64.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantInt64.java @@ -50,7 +50,7 @@ public VariantInt64( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -136,7 +136,7 @@ public VariantInt64 build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantInt64 variantInt64 = new VariantInt64( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantLocalizedText.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantLocalizedText.java index e7ac52373f1..7a3706b867c 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantLocalizedText.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantLocalizedText.java @@ -50,7 +50,7 @@ public VariantLocalizedText( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantLocalizedText build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantLocalizedText variantLocalizedText = new VariantLocalizedText( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNodeId.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNodeId.java index 215174c888e..e91da66e741 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNodeId.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNodeId.java @@ -50,7 +50,7 @@ public VariantNodeId( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantNodeId build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantNodeId variantNodeId = new VariantNodeId( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNull.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNull.java index cfc5715b590..d6d77484a82 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNull.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantNull.java @@ -46,7 +46,7 @@ public VariantNull( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); } @@ -92,7 +92,7 @@ public VariantNull build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantNull variantNull = new VariantNull( arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantQualifiedName.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantQualifiedName.java index 550e91622ec..9ff7e799b73 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantQualifiedName.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantQualifiedName.java @@ -50,7 +50,7 @@ public VariantQualifiedName( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantQualifiedName build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantQualifiedName variantQualifiedName = new VariantQualifiedName( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantSByte.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantSByte.java index 9a5cdb3fa68..921899ecd39 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantSByte.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantSByte.java @@ -50,7 +50,7 @@ public VariantSByte( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, byte[] value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -136,7 +136,7 @@ public VariantSByte build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantSByte variantSByte = new VariantSByte( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantStatusCode.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantStatusCode.java index 55ae3cca886..538849d02ed 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantStatusCode.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantStatusCode.java @@ -50,7 +50,7 @@ public VariantStatusCode( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantStatusCode build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantStatusCode variantStatusCode = new VariantStatusCode( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantString.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantString.java index 31cc206039b..5a52922e828 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantString.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantString.java @@ -50,7 +50,7 @@ public VariantString( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantString build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantString variantString = new VariantString( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt16.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt16.java index 04bbc933d7c..93428581f43 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt16.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt16.java @@ -50,7 +50,7 @@ public VariantUInt16( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -138,7 +138,7 @@ public VariantUInt16 build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantUInt16 variantUInt16 = new VariantUInt16( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt32.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt32.java index c42a0c7acc0..4fd3a59060d 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt32.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt32.java @@ -50,7 +50,7 @@ public VariantUInt32( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -138,7 +138,7 @@ public VariantUInt32 build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantUInt32 variantUInt32 = new VariantUInt32( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt64.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt64.java index 054473830ce..29e5b7c1d17 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt64.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantUInt64.java @@ -51,7 +51,7 @@ public VariantUInt64( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -139,7 +139,7 @@ public VariantUInt64 build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantUInt64 variantUInt64 = new VariantUInt64( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantVariant.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantVariant.java index dd10e407d98..f5f552ca244 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantVariant.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantVariant.java @@ -50,7 +50,7 @@ public VariantVariant( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantVariant build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantVariant variantVariant = new VariantVariant( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantXmlElement.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantXmlElement.java index 4da3834ac95..7b93a5d04c5 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantXmlElement.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/VariantXmlElement.java @@ -50,7 +50,7 @@ public VariantXmlElement( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions, + List arrayDimensions, Integer arrayLength, List value) { super(arrayLengthSpecified, arrayDimensionsSpecified, noOfArrayDimensions, arrayDimensions); @@ -142,7 +142,7 @@ public VariantXmlElement build( boolean arrayLengthSpecified, boolean arrayDimensionsSpecified, Integer noOfArrayDimensions, - List arrayDimensions) { + List arrayDimensions) { VariantXmlElement variantXmlElement = new VariantXmlElement( arrayLengthSpecified, diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java index 6b804959dbd..8957e1e40fa 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java @@ -59,8 +59,7 @@ import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager.RequestTransaction; -import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; -import org.apache.plc4x.java.spi.values.PlcList; +import org.apache.plc4x.java.spi.values.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -85,6 +84,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase implements H new ExtensionObjectEncodingMask(false, false, false)); private static final long EPOCH_OFFSET = 116444736000000000L; //Offset between OPC UA epoch time and linux epoch time. + // IEC 61131-3 date types use 1990-01-01 as epoch, PlcDATE etc. use Unix epoch (1970-01-01). + private static final long IEC_DATE_EPOCH_OFFSET_DAYS = LocalDate.of(1990, 1, 1).toEpochDay(); private final Map subscriptions = new ConcurrentHashMap<>(); private final RequestTransactionManager tm = new RequestTransactionManager(); @@ -309,150 +310,270 @@ static PlcValue variantToPlcValue(PlcTag tag, Variant variant) { PlcValue value = null; if (variant instanceof VariantBoolean) { byte[] array = ((VariantBoolean) variant).getValue(); - int length = array.length; - Boolean[] tmpValue = new Boolean[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = array[i] != 0; + List values = new ArrayList<>(array.length); + for (byte b : array) { + values.add(new PlcBOOL(b != 0)); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantSByte) { byte[] array = ((VariantSByte) variant).getValue(); - value = DefaultPlcValueHandler.of(tag, array); + List values = new ArrayList<>(array.length); + for (byte b : array) { + values.add(new PlcSINT(b)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantByte) { List array = ((VariantByte) variant).getValue(); - Short[] tmpValue = array.toArray(new Short[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Short s : array) { + values.add(new PlcUSINT(s)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantInt16) { List array = ((VariantInt16) variant).getValue(); - Short[] tmpValue = array.toArray(new Short[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Short s : array) { + values.add(new PlcINT(s)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantUInt16) { List array = ((VariantUInt16) variant).getValue(); - Integer[] tmpValue = array.toArray(new Integer[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Integer i : array) { + values.add(new PlcUINT(i)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantInt32) { List array = ((VariantInt32) variant).getValue(); - Integer[] tmpValue = array.toArray(new Integer[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Integer i : array) { + values.add(new PlcDINT(i)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantUInt32) { List array = ((VariantUInt32) variant).getValue(); - Long[] tmpValue = array.toArray(new Long[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Long l : array) { + values.add(new PlcUDINT(l)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantInt64) { List array = ((VariantInt64) variant).getValue(); - Long[] tmpValue = array.toArray(new Long[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Long l : array) { + values.add(new PlcLINT(l)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantUInt64) { - value = DefaultPlcValueHandler.of(tag, ((VariantUInt64) variant).getValue()); + List array = ((VariantUInt64) variant).getValue(); + List values = new ArrayList<>(array.size()); + for (BigInteger bi : array) { + values.add(new PlcULINT(bi)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantFloat) { List array = ((VariantFloat) variant).getValue(); - Float[] tmpValue = array.toArray(new Float[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Float f : array) { + values.add(new PlcREAL(f)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantDouble) { List array = ((VariantDouble) variant).getValue(); - Double[] tmpValue = array.toArray(new Double[0]); - value = DefaultPlcValueHandler.of(tag, tmpValue); + List values = new ArrayList<>(array.size()); + for (Double d : array) { + values.add(new PlcLREAL(d)); + } + value = structurePlcValues(values, variant); } else if (variant instanceof VariantString) { - int length = ((VariantString) variant).getValue().size(); List stringArray = ((VariantString) variant).getValue(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = stringArray.get(i).getStringValue(); + List values = new ArrayList<>(stringArray.size()); + for (PascalString ps : stringArray) { + values.add(new PlcSTRING(ps.getStringValue())); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantDateTime) { List array = ((VariantDateTime) variant).getValue(); - int length = array.size(); - LocalDateTime[] tmpValue = new LocalDateTime[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = LocalDateTime.ofInstant(Instant.ofEpochMilli(getDateTime(array.get(i))), ZoneOffset.UTC); + List values = new ArrayList<>(array.size()); + for (Long l : array) { + values.add(DefaultPlcValueHandler.of(tag, LocalDateTime.ofInstant(Instant.ofEpochMilli(getDateTime(l)), ZoneOffset.UTC))); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantGuid) { List array = ((VariantGuid) variant).getValue(); - int length = array.size(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - //These two data section aren't little endian like the rest. - byte[] data4Bytes = array.get(i).getData4(); + List values = new ArrayList<>(array.size()); + for (GuidValue guidValue : array) { + //These two data sections aren't little endian like the rest. + byte[] data4Bytes = guidValue.getData4(); int data4 = 0; for (byte data4Byte : data4Bytes) { data4 = (data4 << 8) + (data4Byte & 0xff); } - byte[] data5Bytes = array.get(i).getData5(); + byte[] data5Bytes = guidValue.getData5(); long data5 = 0; for (byte data5Byte : data5Bytes) { data5 = (data5 << 8) + (data5Byte & 0xff); } - tmpValue[i] = Long.toHexString(array.get(i).getData1()) + "-" + Integer.toHexString(array.get(i).getData2()) + "-" + Integer.toHexString(array.get(i).getData3()) + "-" + Integer.toHexString(data4) + "-" + Long.toHexString(data5); + values.add(new PlcSTRING(Long.toHexString(guidValue.getData1()) + "-" + Integer.toHexString(guidValue.getData2()) + "-" + Integer.toHexString(guidValue.getData3()) + "-" + Integer.toHexString(data4) + "-" + Long.toHexString(data5))); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantXmlElement) { - int length = ((VariantXmlElement) variant).getValue().size(); List strings = ((VariantXmlElement) variant).getValue(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = strings.get(i).getStringValue(); + List values = new ArrayList<>(strings.size()); + for (PascalString ps : strings) { + values.add(new PlcSTRING(ps.getStringValue())); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantLocalizedText) { - int length = ((VariantLocalizedText) variant).getValue().size(); List strings = ((VariantLocalizedText) variant).getValue(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = ""; - tmpValue[i] += strings.get(i).getLocaleSpecified() ? strings.get(i).getLocale().getStringValue() + "|" : ""; - tmpValue[i] += strings.get(i).getTextSpecified() ? strings.get(i).getText().getStringValue() : ""; + List values = new ArrayList<>(strings.size()); + for (LocalizedText lt : strings) { + String s = ""; + s += lt.getLocaleSpecified() ? lt.getLocale().getStringValue() + "|" : ""; + s += lt.getTextSpecified() ? lt.getText().getStringValue() : ""; + values.add(new PlcSTRING(s)); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantQualifiedName) { - int length = ((VariantQualifiedName) variant).getValue().size(); List strings = ((VariantQualifiedName) variant).getValue(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = "ns=" + strings.get(i).getNamespaceIndex() + ";s=" + strings.get(i).getName().getStringValue(); + List values = new ArrayList<>(strings.size()); + for (QualifiedName qn : strings) { + values.add(new PlcSTRING("ns=" + qn.getNamespaceIndex() + ";s=" + qn.getName().getStringValue())); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantExtensionObject) { - int length = ((VariantExtensionObject) variant).getValue().size(); - List strings = ((VariantExtensionObject) variant).getValue(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = strings.get(i).toString(); + List objects = ((VariantExtensionObject) variant).getValue(); + List values = new ArrayList<>(objects.size()); + for (ExtensionObject eo : objects) { + values.add(new PlcSTRING(eo.toString())); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantNodeId) { - int length = ((VariantNodeId) variant).getValue().size(); - List strings = ((VariantNodeId) variant).getValue(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = strings.get(i).toString(); + List nodeIds = ((VariantNodeId) variant).getValue(); + List values = new ArrayList<>(nodeIds.size()); + for (NodeId nid : nodeIds) { + values.add(new PlcSTRING(nid.toString())); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantStatusCode) { - int length = ((VariantStatusCode) variant).getValue().size(); - List strings = ((VariantStatusCode) variant).getValue(); - String[] tmpValue = new String[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = strings.get(i).toString(); + List statusCodes = ((VariantStatusCode) variant).getValue(); + List values = new ArrayList<>(statusCodes.size()); + for (StatusCode sc : statusCodes) { + values.add(new PlcSTRING(sc.toString())); } - value = DefaultPlcValueHandler.of(tag, tmpValue); + value = structurePlcValues(values, variant); } else if (variant instanceof VariantByteString) { - PlcList plcList = new PlcList(); List array = ((VariantByteString) variant).getValue(); + List values = new ArrayList<>(array.size()); for (ByteStringArray byteStringArray : array) { - int length = byteStringArray.getValue().size(); - Short[] tmpValue = new Short[length]; - for (int i = 0; i < length; i++) { - tmpValue[i] = byteStringArray.getValue().get(i); - } - plcList.add(DefaultPlcValueHandler.of(tag, tmpValue)); + Short[] tmpValue = byteStringArray.getValue().toArray(new Short[0]); + values.add(DefaultPlcValueHandler.of(tag, tmpValue)); } - value = plcList; + value = structurePlcValues(values, variant); } + + // If the tag declares a specific type (via suffix like :TIME, :DATE, etc.), + // re-interpret the raw numeric value as the correct IEC 61131-3 type. + if (value != null && tag != null) { + PlcValueType targetType = tag.getPlcValueType(); + if (targetType != PlcValueType.NULL) { + value = applyTypeOverride(value, targetType); + } + } + return value; } + /** + * Recursively applies a type override to a PlcValue. + * For PlcList values, each element is converted individually. + * For scalar values, the raw numeric is re-interpreted as the target type. + */ + private static PlcValue applyTypeOverride(PlcValue value, PlcValueType targetType) { + // If the value is already a properly typed temporal value (e.g., from DTL + // conversion), skip the override to avoid corrupting it. + PlcValueType currentType = value.getPlcValueType(); + if (currentType == targetType || isTemporalType(currentType)) { + return value; + } + if (value instanceof PlcList list) { + List converted = new ArrayList<>(list.getLength()); + for (PlcValue item : list.getList()) { + converted.add(applyTypeOverride(item, targetType)); + } + return new PlcList(converted); + } + long raw = value.getLong(); + return switch (targetType) { + case TIME -> new PlcTIME(raw); + case LTIME -> new PlcLTIME(raw); + case DATE -> + // S7/IEC value is days since 1990-01-01, PlcDATE expects days since 1970-01-01 + new PlcDATE(raw + IEC_DATE_EPOCH_OFFSET_DAYS); + case LDATE -> + // PlcLDATE expects seconds since 1970-01-01 + new PlcLDATE(raw + IEC_DATE_EPOCH_OFFSET_DAYS * 86400L); + case TIME_OF_DAY -> + // S7/IEC value is milliseconds since midnight + new PlcTIME_OF_DAY(LocalTime.ofNanoOfDay(raw * 1_000_000L)); + case LTIME_OF_DAY -> new PlcLTIME_OF_DAY(raw); + case DATE_AND_TIME -> + // PlcDATE_AND_TIME expects seconds since 1970-01-01 + new PlcDATE_AND_TIME(raw + IEC_DATE_EPOCH_OFFSET_DAYS * 86400L); + case DATE_AND_LTIME -> + // PlcDATE_AND_LTIME expects nanoseconds since 1970-01-01 + new PlcDATE_AND_LTIME(raw + IEC_DATE_EPOCH_OFFSET_DAYS * 86400L * 1_000_000_000L); + case LDATE_AND_TIME -> + // PlcLDATE_AND_TIME expects milliseconds since 1970-01-01 + new PlcLDATE_AND_TIME(raw + IEC_DATE_EPOCH_OFFSET_DAYS * 86400L * 1000L); + default -> value; + }; + } + + private static boolean isTemporalType(PlcValueType type) { + return switch (type) { + case TIME, LTIME, DATE, LDATE, TIME_OF_DAY, LTIME_OF_DAY, DATE_AND_TIME, DATE_AND_LTIME, LDATE_AND_TIME -> + true; + default -> false; + }; + } + + /** + * Structures a flat list of PlcValues according to the variant's dimensionality: + * - Single value: returns the scalar PlcValue directly + * - 1D array (no array dimensions specified): returns a flat PlcList + * - Multi-dimensional array: returns nested PlcLists matching the declared dimensions + */ + private static PlcValue structurePlcValues(List values, Variant variant) { + if (values.size() == 1) { + return values.getFirst(); + } + List dimensions = variant.getArrayDimensions(); + if (dimensions == null || dimensions.isEmpty()) { + return new PlcList(values); + } + return buildMultiDimensionalList(values, dimensions); + } + + /** + * Recursively partitions a flat list of PlcValues into nested PlcLists + * according to the given dimensions. + * E.g., 6 values with dimensions [3, 2] produces a PlcList of 3 PlcLists of 2 values each. + */ + private static PlcValue buildMultiDimensionalList(List flatValues, List dimensions) { + if (dimensions.size() <= 1) { + return new PlcList(flatValues); + } + int currentDim = dimensions.getFirst(); + List remainingDims = dimensions.subList(1, dimensions.size()); + int chunkSize = flatValues.size() / currentDim; + List result = new ArrayList<>(currentDim); + for (int i = 0; i < currentDim; i++) { + result.add(buildMultiDimensionalList(flatValues.subList(i * chunkSize, (i + 1) * chunkSize), remainingDims)); + } + return new PlcList(result); + } + private static PlcResponseCode mapOpcStatusCode(long opcStatusCode, PlcResponseCode fallback) { if (!OpcuaStatusCode.isDefined(opcStatusCode)) { return PlcResponseCode.INTERNAL_ERROR; diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java index 9b7050b0384..cf4d99230fd 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcUaS71500NewFWDriverTest.java @@ -35,7 +35,7 @@ public ManualOpcUaS71500NewFWDriverTest(String connectionString) { } public static void main(String[] args) throws Exception { - boolean testArrays = false; + boolean testArrays = true; ManualOpcUaS71500NewFWDriverTest test = new ManualOpcUaS71500NewFWDriverTest("opcua://192.168.24.66:4840"); test.addTestCase(/*"g_b1",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_b1\";BOOL", new PlcBOOL(true)); test.addTestCase(/*"g_b8",*/ "ns=3;s=\"OPC_UA_DB\".\"OPC Data\".\"g_b8\";BYTE", new PlcBYTE(0xAB)); diff --git a/protocols/opcua/src/main/generated/protocols/opcua/opc-manual.mspec b/protocols/opcua/src/main/generated/protocols/opcua/opc-manual.mspec index 380da9f2b8b..30a38514c81 100644 --- a/protocols/opcua/src/main/generated/protocols/opcua/opc-manual.mspec +++ b/protocols/opcua/src/main/generated/protocols/opcua/opc-manual.mspec @@ -2735,8 +2735,8 @@ [array DiagnosticInfo value count 'arrayLength == null ? 1 : arrayLength'] ] ] - [optional int 32 noOfArrayDimensions 'arrayDimensionsSpecified'] - [array bit arrayDimensions count 'noOfArrayDimensions == null ? 0 : noOfArrayDimensions'] + [optional int 32 noOfArrayDimensions 'arrayDimensionsSpecified' ] + [array int 32 arrayDimensions count 'noOfArrayDimensions == null ? 0 : noOfArrayDimensions'] ] // node type, with two leading reserved bytes diff --git a/protocols/opcua/src/main/xslt/opc-manual.xsl b/protocols/opcua/src/main/xslt/opc-manual.xsl index c0fd1267b83..baea248bc38 100644 --- a/protocols/opcua/src/main/xslt/opc-manual.xsl +++ b/protocols/opcua/src/main/xslt/opc-manual.xsl @@ -354,8 +354,8 @@ [array DiagnosticInfo value count 'arrayLength == null ? 1 : arrayLength'] ] ] - [optional int 32 noOfArrayDimensions 'arrayDimensionsSpecified'] - [array bit arrayDimensions count 'noOfArrayDimensions == null ? 0 : noOfArrayDimensions'] + [optional int 32 noOfArrayDimensions 'arrayDimensionsSpecified' ] + [array int 32 arrayDimensions count 'noOfArrayDimensions == null ? 0 : noOfArrayDimensions'] ] // node type, with two leading reserved bytes