stlehmann / pyads

Python wrapper for TwinCAT ADS
MIT License
264 stars 96 forks source link

Type detection of enumerations #263

Open dgl-cw opened 3 years ago

dgl-cw commented 3 years ago

Automatic type detection on an enum fails, as the symbol_type returned by ADSIGRP_SYM_INFOBYNAMEEX (in adsGetSymbolInfo) is the name of the enum itself (e.g. E_something) instead of the underlying integer type.

Some testing showed that SAdsSymbolEntry.dataType i.e. the adsDataType of symbol matches the underlying type of the enum e.g. ADST_INT16 for INT and ADST_UINT16 for UINT. I found this explanation why dataType is not used normally https://github.com/stlehmann/pyads/blob/fd78232c1e14c9ba6e3fea8332403b93dbf03d87/pyads/symbol.py#L176-L179 But it could be used in addition to the symbol_type to detect unknown type names.

stlehmann commented 3 years ago

@dgl-cw thanks for bringing this up. Could you elaborate what the exact problem is that arises from this? E.g. will there be an error when reading/writing a value?

dgl-cw commented 3 years ago

When trying to get the symbol, it misidentifies the type as String and procedes to raise an uncought UnicodeDecodeError when trying to decode that non-string. It's maybe just a get_symbol issue.

  File "main.py", line 64, in _get_symbol
    symbol = self.plc.get_symbol(name, *args, **kwargs)
  File "venv\lib\site-packages\pyads\ads.py", line 763, in get_symbol
    return AdsSymbol(self, name, index_group, index_offset, plc_datatype,
  File "venv\lib\site-packages\pyads\symbol.py", line 141, in __init__
    self._create_symbol_from_info()  # Perform remote lookup
  File "venv\lib\site-packages\pyads\symbol.py", line 166, in _create_symbol_from_info
    if info.comment:
  File "venv\lib\site-packages\pyads\structs.py", line 348, in comment
    return self._get_string(
  File "venv\lib\site-packages\pyads\structs.py", line 332, in _get_string
    return bytes(self.stringBuffer[offset:(offset + length)]) \
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 2: invalid start byte
stlehmann commented 3 years ago

And the variable is declared as this?:

enum_var: ENUM_TYPE;

and you try to create a symbol like this?

sym = plc.get_symbol("GVL.enum_var")
dgl-cw commented 3 years ago

Yes, exactly.