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/10/01 09:39:48 UTC
(plc4x) branch develop updated: feat(plc4py): Made the reading of the data types more robust
This is an automated email from the ASF dual-hosted git repository.
hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new e1741cda8b feat(plc4py): Made the reading of the data types more robust
e1741cda8b is described below
commit e1741cda8b4c2e437c226813d29d29844e5a3b83
Author: hutcheb <be...@gmail.com>
AuthorDate: Tue Oct 1 17:38:57 2024 +0800
feat(plc4py): Made the reading of the data types more robust
---
plc4py/plc4py/drivers/umas/UmasConnection.py | 6 +++---
plc4py/plc4py/drivers/umas/UmasDevice.py | 15 +++++++++------
plc4py/plc4py/drivers/umas/UmasVariables.py | 21 ++++++++++++++++++---
.../UmasPDUReadUnlocatedVariableNamesRequest.py | 6 +++---
plc4py/plc4py/spi/messages/PlcBrowser.py | 6 ++----
.../src/main/resources/protocols/umas/umas.mspec | 2 +-
6 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/plc4py/plc4py/drivers/umas/UmasConnection.py b/plc4py/plc4py/drivers/umas/UmasConnection.py
index 5fb02fe914..4257b3c3d2 100644
--- a/plc4py/plc4py/drivers/umas/UmasConnection.py
+++ b/plc4py/plc4py/drivers/umas/UmasConnection.py
@@ -121,7 +121,7 @@ class UmasConnection(PlcConnection, DefaultPlcReader, DefaultPlcBrowser):
"""
return DefaultBrowseRequestBuilder()
- def execute(self, request: PlcRequest) -> Awaitable[PlcResponse]:
+ async def execute(self, request: PlcRequest) -> PlcResponse:
"""
Executes a PlcRequest as long as it's already connected
:param request: Plc Request to execute
@@ -131,10 +131,10 @@ class UmasConnection(PlcConnection, DefaultPlcReader, DefaultPlcBrowser):
return self._default_failed_request(PlcResponseCode.NOT_CONNECTED)
if isinstance(request, PlcReadRequest):
- return self._read(request)
+ return await self._read(request)
if isinstance(request, PlcBrowseRequest):
- return self._browse(request)
+ return await self._browse(request)
return self._default_failed_request(PlcResponseCode.NOT_CONNECTED)
diff --git a/plc4py/plc4py/drivers/umas/UmasDevice.py b/plc4py/plc4py/drivers/umas/UmasDevice.py
index 5e8d5c710c..828886999e 100644
--- a/plc4py/plc4py/drivers/umas/UmasDevice.py
+++ b/plc4py/plc4py/drivers/umas/UmasDevice.py
@@ -131,15 +131,16 @@ class UmasDevice:
await self._send_read_memory_block(transport, loop)
offset = 0x0000
first_message = True
- data_types: List[UmasDatatypeReference] = {}
+ data_types: List[UmasDatatypeReference] = []
while offset != 0x0000 or first_message:
first_message = False
(
offset,
- data_types,
+ temp_data_types,
) = await self._send_unlocated_variable_datatype_request(
transport, loop, offset
)
+ data_types.extend(temp_data_types)
data_type_children: Dict[str, List[UmasUDTDefinition]] = {}
for data_type in data_types:
if data_type.class_identifier == 2:
@@ -169,9 +170,11 @@ class UmasDevice:
) -> Dict[str, UmasVariable]:
return_dict = {}
for kea, tag in tags.items():
- return_dict[kea] = UmasVariableBuilder(
+ temp_variable = UmasVariableBuilder(
kea, tag, data_types, data_type_children
).build()
+ if temp_variable is not None:
+ return_dict[kea] = temp_variable
return return_dict
async def _send_plc_ident(self, transport: Transport, loop: AbstractEventLoop):
@@ -267,9 +270,9 @@ class UmasDevice:
request_pdu = UmasPDUReadUnlocatedVariableNamesRequestBuilder(
record_type=0xDD03,
- block_no=0x0000,
+ block_no=offset,
index=self.index,
- offset=offset,
+ offset=0x0000,
hardware_id=self.hardware_id,
).build(0, 0)
@@ -288,7 +291,7 @@ class UmasDevice:
bytearray(data_type_response.block), ByteOrder.LITTLE_ENDIAN
)
basic_info = UmasPDUReadDatatypeNamesResponse.static_parse(read_buffer)
- return basic_info.next_address, basic_info.records
+ return basic_info.range, basic_info.records
async def _send_unlocated_variable_datatype_format_request(
self,
diff --git a/plc4py/plc4py/drivers/umas/UmasVariables.py b/plc4py/plc4py/drivers/umas/UmasVariables.py
index 6e2d3a0422..823e7dda88 100644
--- a/plc4py/plc4py/drivers/umas/UmasVariables.py
+++ b/plc4py/plc4py/drivers/umas/UmasVariables.py
@@ -147,7 +147,7 @@ class UmasVariableBuilder:
def build(self) -> UmasVariable:
variable: UmasVariable = None
_ARRAY_REGEX: str = (
- r"^ARRAY\[(?P<start_number>[0-9]*)..(?P<end_number>[0-9]*)\] OF (?P<data_type>[a-zA-z0-9]*)"
+ r"^ARRAY\[(?P<start_number>[0-9]*)..(?P<end_number>[0-9]*)\] OF (?P<data_type>[a-zA-z0-9_]*)"
)
_ARRAY_COMPILED: Pattern[AnyStr] = re.compile(_ARRAY_REGEX)
@@ -192,10 +192,25 @@ class UmasVariableBuilder:
)
elif data_type_reference.class_identifier == 4:
match = _ARRAY_COMPILED.match(data_type_reference.value)
- data_type = UmasDataType[match.group("data_type")]
+ data_type = None
+ if hasattr(UmasDataType, match.group("data_type")):
+ data_type = UmasDataType[match.group("data_type")].value
+ else:
+ for child_data_type_reference in self.data_type_references:
+ if (
+ match.group("data_type")
+ == child_data_type_reference.value
+ ):
+ data_type = child_data_type_reference.data_type
+ break
+ if data_type is None:
+ raise NotImplementedError(
+ "Unable to read structures of UDT's"
+ )
+
variable = UmasArrayVariable(
self.tag_reference.value,
- data_type.value,
+ data_type,
self.block,
self.tag_reference.offset + self.offset,
int(match.group("start_number")),
diff --git a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py
index 2a31ba96a5..8996d19a44 100644
--- a/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py
+++ b/plc4py/plc4py/protocols/umas/readwrite/UmasPDUReadUnlocatedVariableNamesRequest.py
@@ -71,7 +71,7 @@ class UmasPDUReadUnlocatedVariableNamesRequest(UmasPDUItem):
)
# Const Field (blank)
- write_buffer.write_unsigned_short(self.BLANK, logical_name="blank")
+ write_buffer.write_unsigned_byte(self.BLANK, logical_name="blank")
write_buffer.pop_context("UmasPDUReadUnlocatedVariableNamesRequest")
@@ -98,7 +98,7 @@ class UmasPDUReadUnlocatedVariableNamesRequest(UmasPDUItem):
length_in_bits += 16
# Const Field (blank)
- length_in_bits += 16
+ length_in_bits += 8
return length_in_bits
@@ -153,7 +153,7 @@ class UmasPDUReadUnlocatedVariableNamesRequest(UmasPDUItem):
byte_length=byte_length,
)
- BLANK: int = read_buffer.read_unsigned_short(
+ BLANK: int = read_buffer.read_unsigned_byte(
logical_name="blank",
byte_order=ByteOrder.LITTLE_ENDIAN,
umas_request_function_key=umas_request_function_key,
diff --git a/plc4py/plc4py/spi/messages/PlcBrowser.py b/plc4py/plc4py/spi/messages/PlcBrowser.py
index 4cfcf174cb..6b948c5d8d 100644
--- a/plc4py/plc4py/spi/messages/PlcBrowser.py
+++ b/plc4py/plc4py/spi/messages/PlcBrowser.py
@@ -68,11 +68,9 @@ class DefaultPlcBrowser(PlcBrowser):
)
# Return the response
return response
- except Exception:
- # If an error occurs during the execution of the browse request, return a response with
- # the INTERNAL_ERROR code. This exception is very general and probably should be replaced.
+ except Exception as e:
# TODO:- This exception is very general and probably should be replaced
- return PlcBrowseResponse(PlcResponseCode.INTERNAL_ERROR, {})
+ raise e
def is_browse_supported(self) -> bool:
"""
diff --git a/protocols/umas/src/main/resources/protocols/umas/umas.mspec b/protocols/umas/src/main/resources/protocols/umas/umas.mspec
index 1acd559403..08d611a86d 100644
--- a/protocols/umas/src/main/resources/protocols/umas/umas.mspec
+++ b/protocols/umas/src/main/resources/protocols/umas/umas.mspec
@@ -97,7 +97,7 @@
[simple uint 32 hardwareId]
[simple uint 16 blockNo]
[simple uint 16 offset]
- [const uint 16 blank 0x00]
+ [const uint 8 blank 0x00]
]
['0xFD' UmasPDUErrorResponse
[array uint 8 block count 'byteLength - 2']