Open AliceJoby opened 1 month ago
Thanks for this, there defo seems to be a bug here, effects both symbol reading and read_by_name, whether you pass type in or not, although if you do pass type in then you seem to only get back the first index of the array but decoded correctly, if you don't pass the type in you get back an array of c_char_Array_20 objects.
looks linked / duplicate of #356 @AliceJoby there is a workaround in #356 if you need it while i fix the issue
@RobertoRoos fancy taking a look at this? looks like #410 may have a simlar fix?
Yeah, I'm having a look now.
I can reproduce this with the plc code:
VAR_GLOBAL
// Sizes according to `SIZEOF()`:
list_of_strings : ARRAY[0..9] OF STRING; // 810
END_VAR
and Python code:
with Connection(ams_net_id="127.0.0.1.1.1", ams_net_port=851) as plc:
list_of_strings = plc.read_by_name("GVL_Example.list_of_strings")
for item in list_of_strings:
txt = item.value.decode()
print(txt)
If there's an array of strings in the PLC, pyads will miss reading the extra byte needed for strings and won't be able to read past the first item in the array. Ex. PLC has Array [0..10] of STRING(20) pyads will parse the datatype from the PLC and determine the datatype to be pyads.symbol.c_char_Array_20_Array_10, which is correct. However, when determining the number of bytes needed to be read and reading the array, only 20 bytes will be read of the first array. Strings have an extra byte that need to be read. As a result, the last byte of the first item will become the first byte of the second item in the array, messing up the decoding.
If I put a breakpoint at https://github.com/stlehmann/pyads/blob/master/pyads/structs.py#L332 and modify the PLC datatype to be Array [0..10] of STRING(21), then the array will be read correctly.