Reading PDO maps from a node is a 1-indexed value. However, if the user use index 0 (which is a common expectation for many indexes), __getitem__ returns a PdoVariable instead of the expected PdoMap.
node = network.create_node(42, "mynode.eds")
node.rpdo.aread(from_od=False)
# Use correct 1 index
rpdo = node.rpdo[1] # Type returned is `PdoMap`
# Use incorrect 0 index
rpdo = node.rpdo[0] # Type returned is a `PdoVariable`
The source is due to the else in this code
|
def __getitem__(self, key): |
|
if isinstance(key, int) and (0x1A00 <= key <= 0x1BFF or # By TPDO ID (512) |
|
0x1600 <= key <= 0x17FF or # By RPDO ID (512) |
|
0 < key <= 512): # By PDO Index |
|
return self.map[key] |
|
else: |
|
for pdo_map in self.map.values(): |
|
try: |
|
return pdo_map[key] |
|
except KeyError: |
|
# ignore if one specific PDO does not have the key and try the next one |
|
continue |
|
raise KeyError(f"PDO: {key} was not found in any map") |
We just spent an hour trying to debug why the PDO didn't work before we realized the obvious mistake. I think using 0 index is such a common expectation, that I think we should give an error or clearly warn the user.
What is the intent of the the else section in L48-L53? When is this used? I could not find any tests showing how this is used. Because of the else rpdo[0] as shown above will fetch the first PdoVariable from the first PDO, but rpdo[1] will not fetch the second PdoVariable.
Reading PDO maps from a node is a 1-indexed value. However, if the user use index 0 (which is a common expectation for many indexes),
__getitem__returns aPdoVariableinstead of the expectedPdoMap.The source is due to the else in this code
canopen/canopen/pdo/base.py
Lines 42 to 54 in e840449
We just spent an hour trying to debug why the PDO didn't work before we realized the obvious mistake. I think using 0 index is such a common expectation, that I think we should give an error or clearly warn the user.
What is the intent of the the else section in L48-L53? When is this used? I could not find any tests showing how this is used. Because of the else
rpdo[0]as shown above will fetch the firstPdoVariablefrom the first PDO, butrpdo[1]will not fetch the secondPdoVariable.