You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2024/03/07 10:32:20 UTC

(plc4x) 01/01: fix(plc4py/umas): Start to add write support

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

hutcheb pushed a commit to branch feat/plc4py/umas_write_support
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit a5d746dad7fc8ddca2b2215f5194434ea2ce6960
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Thu Mar 7 11:32:00 2024 +0100

    fix(plc4py/umas): Start to add write support
---
 .../python/PythonLanguageTemplateHelper.java       |  11 +-
 .../src/main/resources/protocols/umas/umas.mspec   |  23 +++-
 sandbox/plc4py/plc4py/drivers/umas/UmasDevice.py   |  10 +-
 .../plc4py/plc4py/drivers/umas/UmasVariables.py    |  20 ++--
 .../plc4py/protocols/umas/readwrite/UmasPDUItem.py |  18 ++++
 .../umas/readwrite/UmasPDUReadVariableRequest.py   |  10 +-
 ...leRequest.py => UmasPDUWriteVariableRequest.py} |  40 +++----
 .../umas/readwrite/UmasPDUWriteVariableResponse.py | 118 +++++++++++++++++++++
 ...eference.py => VariableReadRequestReference.py} |  24 ++---
 ...ference.py => VariableWriteRequestReference.py} |  53 ++++++---
 10 files changed, 255 insertions(+), 72 deletions(-)

diff --git a/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java b/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
index 8c17d4e21c..4d97f75700 100644
--- a/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
+++ b/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
@@ -768,9 +768,10 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
             Term b = ternaryTerm.getB();
             Term c = ternaryTerm.getC();
             String castExpressionForTypeReference = getCastExpressionForTypeReference(fieldType);
-            String inlineIf = "utils.InlineIf(" + toExpression(field, new DefaultBooleanTypeReference(), a, parserArguments, serializerArguments, serialize, false) + ", " +
-                "func() any {return " + castExpressionForTypeReference + "(" + toExpression(field, fieldType, b, parserArguments, serializerArguments, serialize, false) + ")}, " +
-                "func() any {return " + castExpressionForTypeReference + "(" + toExpression(field, fieldType, c, parserArguments, serializerArguments, serialize, false) + ")})";
+            String inlineIf = castExpressionForTypeReference + "(" + toExpression(field, fieldType, b, parserArguments, serializerArguments, serialize, false) + ") if " +
+                toExpression(field, new DefaultBooleanTypeReference(), a, parserArguments, serializerArguments, serialize, false) + " else " +
+                castExpressionForTypeReference + "(" + toExpression(field, fieldType, c, parserArguments, serializerArguments, serialize, false) + ")";
+            
             if (fieldType != null) {
                 if (fieldType instanceof ByteOrderTypeReference) {
                     return tracer.dive("byteordertypereference") + "(" + inlineIf + ").(binary.ByteOrder)";
@@ -778,7 +779,7 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
                 if (fieldType.isNonSimpleTypeReference()) {
                     return tracer.dive("nonsimpletypereference") + castExpressionForTypeReference + "(" + inlineIf + ")";
                 }
-                return tracer + inlineIf + ".(" + castExpressionForTypeReference + ")";
+                return tracer + inlineIf;
             }
             return tracer + inlineIf;
         } else {
@@ -1289,7 +1290,7 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
 
     private String toOptionalVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean suppressPointerAccess, Tracer tracer) {
         tracer = tracer.dive("optional fields");
-        return tracer + "(" + (suppressPointerAccess || (typeReference != null && typeReference.isComplexTypeReference()) ? "" : "*") + variableLiteral.getName() + ")" +
+        return tracer + "(" + (suppressPointerAccess || (typeReference != null && typeReference.isComplexTypeReference()) ? "" : "") + camelCaseToSnakeCase(variableLiteral.getName()) + ")" +
             variableLiteral.getChild().map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true))).orElse("");
     }
 
diff --git a/protocols/umas/src/main/resources/protocols/umas/umas.mspec b/protocols/umas/src/main/resources/protocols/umas/umas.mspec
index 2a8c4b500a..e724fbb8c3 100644
--- a/protocols/umas/src/main/resources/protocols/umas/umas.mspec
+++ b/protocols/umas/src/main/resources/protocols/umas/umas.mspec
@@ -84,7 +84,12 @@
         ['0x22'      UmasPDUReadVariableRequest
             [simple     uint 32        crc]
             [simple     uint 8        variableCount]
-            [array      VariableRequestReference variables count 'variableCount']
+            [array      VariableReadRequestReference variables count 'variableCount']
+        ]
+        ['0x23'      UmasPDUWriteVariableRequest
+            [simple     uint 32        crc]
+            [simple     uint 8        variableCount]
+            [array      VariableWriteRequestReference variables count 'variableCount']
         ]
         ['0x26'     UmasPDUReadUnlocatedVariableNamesRequest
             [simple     uint 16         recordType]
@@ -131,6 +136,9 @@
         ['0xFE', '0x22'     UmasPDUReadVariableResponse
             [array      uint 8          block count 'byteLength - 2']
         ]
+        ['0xFE', '0x23'     UmasPDUWriteVariableResponse
+            [array      uint 8          block count 'byteLength - 2']
+        ]
         ['0xFE', '0x26'     UmasPDUReadUnlocatedVariableResponse
             [array      uint 8          block count 'byteLength - 2']
         ]
@@ -171,7 +179,17 @@
     [array      UmasDatatypeReference         records count 'noOfRecords']
 ]
 
-[type VariableRequestReference
+[type VariableReadRequestReference
+    [simple     uint 4           isArray]
+    [simple     uint 4           dataSizeIndex]
+    [simple     uint 16          block]
+    [const      uint 8           unknown1 0x01]
+    [simple     uint 16          baseOffset]
+    [simple     uint 8           offset]
+    [optional   uint 16          arrayLength 'isArray']
+]
+
+[type VariableWriteRequestReference
     [simple     uint 4           isArray]
     [simple     uint 4           dataSizeIndex]
     [simple     uint 16          block]
@@ -179,6 +197,7 @@
     [simple     uint 16          baseOffset]
     [simple     uint 8           offset]
     [optional   uint 16          arrayLength 'isArray']
+    [array      byte       recordData     length  'isArray == 1 ? dataSizeIndex * arrayLength : dataSizeIndex']
 ]
 
 [type UmasUnlocatedVariableReference
diff --git a/sandbox/plc4py/plc4py/drivers/umas/UmasDevice.py b/sandbox/plc4py/plc4py/drivers/umas/UmasDevice.py
index 91d67d2f07..4670922ff1 100644
--- a/sandbox/plc4py/plc4py/drivers/umas/UmasDevice.py
+++ b/sandbox/plc4py/plc4py/drivers/umas/UmasDevice.py
@@ -87,8 +87,8 @@ from plc4py.protocols.umas.readwrite.UmasPDUReadVariableResponse import (
 from plc4py.protocols.umas.readwrite.UmasUnlocatedVariableReference import (
     UmasUnlocatedVariableReference,
 )
-from plc4py.protocols.umas.readwrite.VariableRequestReference import (
-    VariableRequestReference,
+from plc4py.protocols.umas.readwrite.VariableReadRequestReference import (
+    VariableReadRequestReference,
 )
 from plc4py.spi.generation.ReadBuffer import ReadBufferByteBased
 from plc4py.spi.messages.utils.ResponseItem import ResponseItem
@@ -351,7 +351,7 @@ class UmasDevice:
     ):
         message_future = loop.create_future()
 
-        sorted_variable_list: List[VariableRequestReference] = [
+        sorted_variable_list: List[VariableReadRequestReference] = [
             variable_reference[1] for variable_reference in sorted_tags
         ]
         request_pdu = UmasPDUReadVariableRequestBuilder(
@@ -391,7 +391,7 @@ class UmasDevice:
         return response
 
     def _sort_tags_based_on_memory_address(self, request):
-        tag_list: List[List[Tuple[str, VariableRequestReference]]] = [[]]
+        tag_list: List[List[Tuple[str, VariableReadRequestReference]]] = [[]]
         current_list_index = 0
         current_list = tag_list[current_list_index]
         byte_count: int = 0
@@ -412,7 +412,7 @@ class UmasDevice:
                     variable.get_variable_reference(umas_tag.tag_name),
                 )
             )
-        sorted_tag_lists: List[List[Tuple[str, VariableRequestReference]]] = []
+        sorted_tag_lists: List[List[Tuple[str, VariableReadRequestReference]]] = []
         for request in tag_list:
             sorted_tags = sorted(
                 request,
diff --git a/sandbox/plc4py/plc4py/drivers/umas/UmasVariables.py b/sandbox/plc4py/plc4py/drivers/umas/UmasVariables.py
index 344034936c..27b90c0d6b 100644
--- a/sandbox/plc4py/plc4py/drivers/umas/UmasVariables.py
+++ b/sandbox/plc4py/plc4py/drivers/umas/UmasVariables.py
@@ -22,8 +22,8 @@ from typing import Dict, List, Pattern, AnyStr, Union
 
 from plc4py.protocols.umas.readwrite.UmasDataType import UmasDataType
 
-from plc4py.protocols.umas.readwrite.VariableRequestReference import (
-    VariableRequestReference,
+from plc4py.protocols.umas.readwrite.VariableReadRequestReference import (
+    VariableReadRequestReference,
 )
 
 from plc4py.api.exceptions.exceptions import PlcDataTypeNotFoundException
@@ -42,7 +42,7 @@ class UmasVariable:
     block_no: int
     offset: int
 
-    def get_variable_reference(self, address: str) -> VariableRequestReference:
+    def get_variable_reference(self, address: str) -> VariableReadRequestReference:
         raise NotImplementedError(
             f"UmasVariable subclass not implemented for variable {self.variable_name}"
         )
@@ -55,9 +55,9 @@ class UmasVariable:
 
 @dataclass
 class UmasElementryVariable(UmasVariable):
-    def get_variable_reference(self, address: str) -> VariableRequestReference:
+    def get_variable_reference(self, address: str) -> VariableReadRequestReference:
         if self.data_type == UmasDataType.STRING.value:
-            return VariableRequestReference(
+            return VariableReadRequestReference(
                 is_array=1,
                 data_size_index=UmasDataType(self.data_type).request_size,
                 block=self.block_no,
@@ -66,7 +66,7 @@ class UmasElementryVariable(UmasVariable):
                 array_length=16,
             )
         else:
-            return VariableRequestReference(
+            return VariableReadRequestReference(
                 is_array=0,
                 data_size_index=UmasDataType(self.data_type).request_size,
                 block=self.block_no,
@@ -83,7 +83,7 @@ class UmasElementryVariable(UmasVariable):
 class UmasCustomVariable(UmasVariable):
     children: Dict[str, UmasVariable]
 
-    def get_variable_reference(self, address: str) -> VariableRequestReference:
+    def get_variable_reference(self, address: str) -> VariableReadRequestReference:
         split_tag_address: List[str] = address.split(".")
         child_index = None
         if len(split_tag_address) > 1:
@@ -106,14 +106,14 @@ class UmasArrayVariable(UmasVariable):
     start_index: int
     end_index: int
 
-    def get_variable_reference(self, address: str) -> VariableRequestReference:
+    def get_variable_reference(self, address: str) -> VariableReadRequestReference:
         split_tag_address: List[str] = address.split(".")
         address_index = None
         if len(split_tag_address) > 1:
             address_index = int(split_tag_address[1])
         data_type_enum = UmasDataType(self.data_type)
         if address_index:
-            return VariableRequestReference(
+            return VariableReadRequestReference(
                 is_array=0,
                 data_size_index=data_type_enum.request_size,
                 block=self.block_no,
@@ -123,7 +123,7 @@ class UmasArrayVariable(UmasVariable):
                 array_length=None,
             )
         else:
-            return VariableRequestReference(
+            return VariableReadRequestReference(
                 is_array=1,
                 data_size_index=data_type_enum.request_size,
                 block=self.block_no,
diff --git a/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py
index 5ed3365996..6b33d4fbed 100644
--- a/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py
+++ b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUItem.py
@@ -202,6 +202,15 @@ class UmasPDUItem(ABC, PlcMessage):
             builder = UmasPDUReadVariableRequest.static_parse_builder(
                 read_buffer, umas_request_function_key, byte_length
             )
+        from plc4py.protocols.umas.readwrite.UmasPDUWriteVariableRequest import (
+            UmasPDUWriteVariableRequest,
+        )
+
+        if umas_function_key == int(0x23):
+
+            builder = UmasPDUWriteVariableRequest.static_parse_builder(
+                read_buffer, umas_request_function_key, byte_length
+            )
         from plc4py.protocols.umas.readwrite.UmasPDUReadUnlocatedVariableNamesRequest import (
             UmasPDUReadUnlocatedVariableNamesRequest,
         )
@@ -256,6 +265,15 @@ class UmasPDUItem(ABC, PlcMessage):
             builder = UmasPDUReadVariableResponse.static_parse_builder(
                 read_buffer, umas_request_function_key, byte_length
             )
+        from plc4py.protocols.umas.readwrite.UmasPDUWriteVariableResponse import (
+            UmasPDUWriteVariableResponse,
+        )
+
+        if umas_function_key == int(0xFE) and umas_request_function_key == int(0x23):
+
+            builder = UmasPDUWriteVariableResponse.static_parse_builder(
+                read_buffer, umas_request_function_key, byte_length
+            )
         from plc4py.protocols.umas.readwrite.UmasPDUReadUnlocatedVariableResponse import (
             UmasPDUReadUnlocatedVariableResponse,
         )
diff --git a/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
index c5fe4f7fa3..8146fdc54a 100644
--- a/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
@@ -23,8 +23,8 @@ from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.umas.readwrite.UmasPDUItem import UmasPDUItem
-from plc4py.protocols.umas.readwrite.VariableRequestReference import (
-    VariableRequestReference,
+from plc4py.protocols.umas.readwrite.VariableReadRequestReference import (
+    VariableReadRequestReference,
 )
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
@@ -39,7 +39,7 @@ import math
 class UmasPDUReadVariableRequest(UmasPDUItem):
     crc: int
     variable_count: int
-    variables: List[VariableRequestReference]
+    variables: List[VariableReadRequestReference]
     # Arguments.
     byte_length: int
     # Accessors for discriminator values.
@@ -106,7 +106,7 @@ class UmasPDUReadVariableRequest(UmasPDUItem):
 
         variables: List[Any] = read_buffer.read_array_field(
             logical_name="variables",
-            read_function=VariableRequestReference.static_parse,
+            read_function=VariableReadRequestReference.static_parse,
             count=variable_count,
             byte_order=ByteOrder.LITTLE_ENDIAN,
             umas_request_function_key=umas_request_function_key,
@@ -151,7 +151,7 @@ class UmasPDUReadVariableRequest(UmasPDUItem):
 class UmasPDUReadVariableRequestBuilder:
     crc: int
     variable_count: int
-    variables: List[VariableRequestReference]
+    variables: List[VariableReadRequestReference]
 
     def build(self, byte_length: int, pairing_key) -> UmasPDUReadVariableRequest:
         umas_pdu_read_variable_request: UmasPDUReadVariableRequest = (
diff --git a/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableRequest.py
similarity index 79%
copy from sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
copy to sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableRequest.py
index c5fe4f7fa3..b27361290e 100644
--- a/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadVariableRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableRequest.py
@@ -23,8 +23,8 @@ from plc4py.api.exceptions.exceptions import PlcRuntimeException
 from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.umas.readwrite.UmasPDUItem import UmasPDUItem
-from plc4py.protocols.umas.readwrite.VariableRequestReference import (
-    VariableRequestReference,
+from plc4py.protocols.umas.readwrite.VariableWriteRequestReference import (
+    VariableWriteRequestReference,
 )
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
@@ -36,18 +36,18 @@ import math
 
 
 @dataclass
-class UmasPDUReadVariableRequest(UmasPDUItem):
+class UmasPDUWriteVariableRequest(UmasPDUItem):
     crc: int
     variable_count: int
-    variables: List[VariableRequestReference]
+    variables: List[VariableWriteRequestReference]
     # Arguments.
     byte_length: int
     # Accessors for discriminator values.
-    umas_function_key: ClassVar[int] = 0x22
+    umas_function_key: ClassVar[int] = 0x23
     umas_request_function_key: ClassVar[int] = 0
 
     def serialize_umas_pdu_item_child(self, write_buffer: WriteBuffer):
-        write_buffer.push_context("UmasPDUReadVariableRequest")
+        write_buffer.push_context("UmasPDUWriteVariableRequest")
 
         # Simple Field (crc)
         write_buffer.write_unsigned_int(self.crc, bit_length=32, logical_name="crc")
@@ -60,14 +60,14 @@ class UmasPDUReadVariableRequest(UmasPDUItem):
         # Array Field (variables)
         write_buffer.write_complex_array(self.variables, logical_name="variables")
 
-        write_buffer.pop_context("UmasPDUReadVariableRequest")
+        write_buffer.pop_context("UmasPDUWriteVariableRequest")
 
     def length_in_bytes(self) -> int:
         return int(math.ceil(float(self.length_in_bits() / 8.0)))
 
     def length_in_bits(self) -> int:
         length_in_bits: int = super().length_in_bits()
-        _value: UmasPDUReadVariableRequest = self
+        _value: UmasPDUWriteVariableRequest = self
 
         # Simple field (crc)
         length_in_bits += 32
@@ -86,7 +86,7 @@ class UmasPDUReadVariableRequest(UmasPDUItem):
     def static_parse_builder(
         read_buffer: ReadBuffer, umas_request_function_key: int, byte_length: int
     ):
-        read_buffer.push_context("UmasPDUReadVariableRequest")
+        read_buffer.push_context("UmasPDUWriteVariableRequest")
 
         crc: int = read_buffer.read_unsigned_int(
             logical_name="crc",
@@ -106,25 +106,25 @@ class UmasPDUReadVariableRequest(UmasPDUItem):
 
         variables: List[Any] = read_buffer.read_array_field(
             logical_name="variables",
-            read_function=VariableRequestReference.static_parse,
+            read_function=VariableWriteRequestReference.static_parse,
             count=variable_count,
             byte_order=ByteOrder.LITTLE_ENDIAN,
             umas_request_function_key=umas_request_function_key,
             byte_length=byte_length,
         )
 
-        read_buffer.pop_context("UmasPDUReadVariableRequest")
+        read_buffer.pop_context("UmasPDUWriteVariableRequest")
         # Create the instance
-        return UmasPDUReadVariableRequestBuilder(crc, variable_count, variables)
+        return UmasPDUWriteVariableRequestBuilder(crc, variable_count, variables)
 
     def equals(self, o: object) -> bool:
         if self == o:
             return True
 
-        if not isinstance(o, UmasPDUReadVariableRequest):
+        if not isinstance(o, UmasPDUWriteVariableRequest):
             return False
 
-        that: UmasPDUReadVariableRequest = UmasPDUReadVariableRequest(o)
+        that: UmasPDUWriteVariableRequest = UmasPDUWriteVariableRequest(o)
         return (
             (self.crc == that.crc)
             and (self.variable_count == that.variable_count)
@@ -148,15 +148,15 @@ class UmasPDUReadVariableRequest(UmasPDUItem):
 
 
 @dataclass
-class UmasPDUReadVariableRequestBuilder:
+class UmasPDUWriteVariableRequestBuilder:
     crc: int
     variable_count: int
-    variables: List[VariableRequestReference]
+    variables: List[VariableWriteRequestReference]
 
-    def build(self, byte_length: int, pairing_key) -> UmasPDUReadVariableRequest:
-        umas_pdu_read_variable_request: UmasPDUReadVariableRequest = (
-            UmasPDUReadVariableRequest(
+    def build(self, byte_length: int, pairing_key) -> UmasPDUWriteVariableRequest:
+        umas_pdu_write_variable_request: UmasPDUWriteVariableRequest = (
+            UmasPDUWriteVariableRequest(
                 byte_length, pairing_key, self.crc, self.variable_count, self.variables
             )
         )
-        return umas_pdu_read_variable_request
+        return umas_pdu_write_variable_request
diff --git a/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableResponse.py b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableResponse.py
new file mode 100644
index 0000000000..af3020ba0b
--- /dev/null
+++ b/sandbox/plc4py/plc4py/protocols/umas/readwrite/UmasPDUWriteVariableResponse.py
@@ -0,0 +1,118 @@
+#
+# 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.
+#
+
+from dataclasses import dataclass
+
+from plc4py.api.exceptions.exceptions import PlcRuntimeException
+from plc4py.api.exceptions.exceptions import SerializationException
+from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.protocols.umas.readwrite.UmasPDUItem import UmasPDUItem
+from plc4py.spi.generation.ReadBuffer import ReadBuffer
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
+from plc4py.utils.GenericTypes import ByteOrder
+from typing import Any
+from typing import ClassVar
+from typing import List
+import math
+
+
+@dataclass
+class UmasPDUWriteVariableResponse(UmasPDUItem):
+    block: List[int]
+    # Arguments.
+    byte_length: int
+    # Accessors for discriminator values.
+    umas_function_key: ClassVar[int] = 0xFE
+    umas_request_function_key: ClassVar[int] = 0x23
+
+    def serialize_umas_pdu_item_child(self, write_buffer: WriteBuffer):
+        write_buffer.push_context("UmasPDUWriteVariableResponse")
+
+        # Array Field (block)
+        write_buffer.write_simple_array(
+            self.block, write_buffer.write_unsigned_byte, logical_name="block"
+        )
+
+        write_buffer.pop_context("UmasPDUWriteVariableResponse")
+
+    def length_in_bytes(self) -> int:
+        return int(math.ceil(float(self.length_in_bits() / 8.0)))
+
+    def length_in_bits(self) -> int:
+        length_in_bits: int = super().length_in_bits()
+        _value: UmasPDUWriteVariableResponse = self
+
+        # Array field
+        if self.block is not None:
+            length_in_bits += 8 * len(self.block)
+
+        return length_in_bits
+
+    @staticmethod
+    def static_parse_builder(
+        read_buffer: ReadBuffer, umas_request_function_key: int, byte_length: int
+    ):
+        read_buffer.push_context("UmasPDUWriteVariableResponse")
+
+        block: List[Any] = read_buffer.read_array_field(
+            logical_name="block",
+            read_function=read_buffer.read_unsigned_byte,
+            count=byte_length - int(2),
+            byte_order=ByteOrder.LITTLE_ENDIAN,
+            umas_request_function_key=umas_request_function_key,
+            byte_length=byte_length,
+        )
+
+        read_buffer.pop_context("UmasPDUWriteVariableResponse")
+        # Create the instance
+        return UmasPDUWriteVariableResponseBuilder(block)
+
+    def equals(self, o: object) -> bool:
+        if self == o:
+            return True
+
+        if not isinstance(o, UmasPDUWriteVariableResponse):
+            return False
+
+        that: UmasPDUWriteVariableResponse = UmasPDUWriteVariableResponse(o)
+        return (self.block == that.block) and super().equals(that) and True
+
+    def hash_code(self) -> int:
+        return hash(self)
+
+    def __str__(self) -> str:
+        pass
+        # write_buffer_box_based: WriteBufferBoxBased = WriteBufferBoxBased(True, True)
+        # try:
+        #    write_buffer_box_based.writeSerializable(self)
+        # except SerializationException as e:
+        #    raise PlcRuntimeException(e)
+
+        # return "\n" + str(write_buffer_box_based.get_box()) + "\n"
+
+
+@dataclass
+class UmasPDUWriteVariableResponseBuilder:
+    block: List[int]
+
+    def build(self, byte_length: int, pairing_key) -> UmasPDUWriteVariableResponse:
+        umas_pdu_write_variable_response: UmasPDUWriteVariableResponse = (
+            UmasPDUWriteVariableResponse(byte_length, pairing_key, self.block)
+        )
+        return umas_pdu_write_variable_response
diff --git a/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py b/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableReadRequestReference.py
similarity index 87%
copy from sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py
copy to sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableReadRequestReference.py
index c43fdc1ad1..e97ad81cc3 100644
--- a/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py
+++ b/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableReadRequestReference.py
@@ -28,7 +28,7 @@ import math
 
 
 @dataclass
-class VariableRequestReference:
+class VariableReadRequestReference:
     is_array: int
     data_size_index: int
     block: int
@@ -38,7 +38,7 @@ class VariableRequestReference:
     UNKNOWN1: int = 0x01
 
     def serialize(self, write_buffer: WriteBuffer):
-        write_buffer.push_context("VariableRequestReference")
+        write_buffer.push_context("VariableReadRequestReference")
 
         # Simple Field (isArray)
         write_buffer.write_unsigned_byte(
@@ -74,14 +74,14 @@ class VariableRequestReference:
                 self.array_length, logical_name="arrayLength"
             )
 
-        write_buffer.pop_context("VariableRequestReference")
+        write_buffer.pop_context("VariableReadRequestReference")
 
     def length_in_bytes(self) -> int:
         return int(math.ceil(float(self.length_in_bits() / 8.0)))
 
     def length_in_bits(self) -> int:
         length_in_bits: int = 0
-        _value: VariableRequestReference = self
+        _value: VariableReadRequestReference = self
 
         # Simple field (isArray)
         length_in_bits += 4
@@ -109,11 +109,11 @@ class VariableRequestReference:
 
     @staticmethod
     def static_parse(read_buffer: ReadBuffer, **kwargs):
-        return VariableRequestReference.static_parse_context(read_buffer)
+        return VariableReadRequestReference.static_parse_context(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
-        read_buffer.push_context("VariableRequestReference")
+        read_buffer.push_context("VariableReadRequestReference")
 
         is_array: int = read_buffer.read_unsigned_byte(
             logical_name="isArray", bit_length=4
@@ -141,23 +141,23 @@ class VariableRequestReference:
         if is_array:
             array_length = read_buffer.read_unsigned_short(logical_name="arrayLength")
 
-        read_buffer.pop_context("VariableRequestReference")
+        read_buffer.pop_context("VariableReadRequestReference")
         # Create the instance
-        _variable_request_reference: VariableRequestReference = (
-            VariableRequestReference(
+        _variable_read_request_reference: VariableReadRequestReference = (
+            VariableReadRequestReference(
                 is_array, data_size_index, block, base_offset, offset, array_length
             )
         )
-        return _variable_request_reference
+        return _variable_read_request_reference
 
     def equals(self, o: object) -> bool:
         if self == o:
             return True
 
-        if not isinstance(o, VariableRequestReference):
+        if not isinstance(o, VariableReadRequestReference):
             return False
 
-        that: VariableRequestReference = VariableRequestReference(o)
+        that: VariableReadRequestReference = VariableReadRequestReference(o)
         return (
             (self.is_array == that.is_array)
             and (self.data_size_index == that.data_size_index)
diff --git a/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py b/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableWriteRequestReference.py
similarity index 75%
rename from sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py
rename to sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableWriteRequestReference.py
index c43fdc1ad1..ebcffb656b 100644
--- a/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableRequestReference.py
+++ b/sandbox/plc4py/plc4py/protocols/umas/readwrite/VariableWriteRequestReference.py
@@ -24,21 +24,24 @@ from plc4py.api.exceptions.exceptions import SerializationException
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.spi.generation.ReadBuffer import ReadBuffer
 from plc4py.spi.generation.WriteBuffer import WriteBuffer
+from typing import Any
+from typing import List
 import math
 
 
 @dataclass
-class VariableRequestReference:
+class VariableWriteRequestReference:
     is_array: int
     data_size_index: int
     block: int
     base_offset: int
     offset: int
     array_length: int
+    record_data: List[int]
     UNKNOWN1: int = 0x01
 
     def serialize(self, write_buffer: WriteBuffer):
-        write_buffer.push_context("VariableRequestReference")
+        write_buffer.push_context("VariableWriteRequestReference")
 
         # Simple Field (isArray)
         write_buffer.write_unsigned_byte(
@@ -74,14 +77,17 @@ class VariableRequestReference:
                 self.array_length, logical_name="arrayLength"
             )
 
-        write_buffer.pop_context("VariableRequestReference")
+        # Array Field (recordData)
+        write_buffer.write_byte_array(self.record_data, logical_name="recordData")
+
+        write_buffer.pop_context("VariableWriteRequestReference")
 
     def length_in_bytes(self) -> int:
         return int(math.ceil(float(self.length_in_bits() / 8.0)))
 
     def length_in_bits(self) -> int:
         length_in_bits: int = 0
-        _value: VariableRequestReference = self
+        _value: VariableWriteRequestReference = self
 
         # Simple field (isArray)
         length_in_bits += 4
@@ -105,15 +111,19 @@ class VariableRequestReference:
         if self.is_array:
             length_in_bits += 16
 
+        # Array field
+        if self.record_data is not None:
+            length_in_bits += 8 * len(self.record_data)
+
         return length_in_bits
 
     @staticmethod
     def static_parse(read_buffer: ReadBuffer, **kwargs):
-        return VariableRequestReference.static_parse_context(read_buffer)
+        return VariableWriteRequestReference.static_parse_context(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
-        read_buffer.push_context("VariableRequestReference")
+        read_buffer.push_context("VariableWriteRequestReference")
 
         is_array: int = read_buffer.read_unsigned_byte(
             logical_name="isArray", bit_length=4
@@ -141,23 +151,39 @@ class VariableRequestReference:
         if is_array:
             array_length = read_buffer.read_unsigned_short(logical_name="arrayLength")
 
-        read_buffer.pop_context("VariableRequestReference")
+        record_data: List[Any] = read_buffer.read_array_field(
+            logical_name="recordData",
+            read_function=read_buffer.read_byte,
+            count=(
+                int(data_size_index * (array_length))
+                if bool((is_array) == ((1)))
+                else int(data_size_index)
+            ),
+        )
+
+        read_buffer.pop_context("VariableWriteRequestReference")
         # Create the instance
-        _variable_request_reference: VariableRequestReference = (
-            VariableRequestReference(
-                is_array, data_size_index, block, base_offset, offset, array_length
+        _variable_write_request_reference: VariableWriteRequestReference = (
+            VariableWriteRequestReference(
+                is_array,
+                data_size_index,
+                block,
+                base_offset,
+                offset,
+                array_length,
+                record_data,
             )
         )
-        return _variable_request_reference
+        return _variable_write_request_reference
 
     def equals(self, o: object) -> bool:
         if self == o:
             return True
 
-        if not isinstance(o, VariableRequestReference):
+        if not isinstance(o, VariableWriteRequestReference):
             return False
 
-        that: VariableRequestReference = VariableRequestReference(o)
+        that: VariableWriteRequestReference = VariableWriteRequestReference(o)
         return (
             (self.is_array == that.is_array)
             and (self.data_size_index == that.data_size_index)
@@ -165,6 +191,7 @@ class VariableRequestReference:
             and (self.base_offset == that.base_offset)
             and (self.offset == that.offset)
             and (self.array_length == that.array_length)
+            and (self.record_data == that.record_data)
             and True
         )