diff --git a/canopen/pdo/__init__.py b/canopen/pdo/__init__.py index 533309f8..a746e7a4 100644 --- a/canopen/pdo/__init__.py +++ b/canopen/pdo/__init__.py @@ -1,4 +1,5 @@ import logging +from typing import Union from canopen import node from canopen.pdo.base import PdoBase, PdoMap, PdoMaps, PdoVariable @@ -30,11 +31,18 @@ def __init__(self, node, rpdo, tpdo): self.tx = tpdo.map self.map = {} - # the object 0x1A00 equals to key '1' so we remove 1 from the key for key, value in self.rx.items(): - self.map[0x1A00 + (key - 1)] = value + self.map[0x1400 + (key - 1)] = value for key, value in self.tx.items(): - self.map[0x1600 + (key - 1)] = value + self.map[0x1800 + (key - 1)] = value + + def __getitem__(self, key: Union[int, str]): + if isinstance(key, int): + if 0x1600 <= key <= 0x1600 + 511: + key = 0x1800 + (key - 0x1600) + elif 0x1A00 <= key <= 0x1A00 + 511: + key = 0x1400 + (key - 0x1A00) + return super().__getitem__(key) class RPDO(PdoBase): diff --git a/canopen/pdo/base.py b/canopen/pdo/base.py index 216fc550..84349255 100644 --- a/canopen/pdo/base.py +++ b/canopen/pdo/base.py @@ -45,8 +45,7 @@ def __getitem__(self, key: Union[int, str]): raise KeyError("PDO index zero requested for 1-based sequence") if ( 0 < key <= 512 # By PDO Index - or 0x1600 <= key <= 0x17FF # By RPDO ID (512) - or 0x1A00 <= key <= 0x1BFF # By TPDO ID (512) + or 0x1400 <= key <= 0x1BFF # By record ID ): return self.map[key] for pdo_map in self.map.values(): @@ -154,6 +153,8 @@ def __init__(self, com_offset, map_offset, pdo_node: PdoBase, cob_base=None): :param pdo_node: :param cob_base: """ + self.com_offset = com_offset + self.map_offset = map_offset self.maps: dict[int, PdoMap] = {} for map_no in range(512): if com_offset + map_no in pdo_node.node.object_dictionary: @@ -167,6 +168,10 @@ def __init__(self, com_offset, map_offset, pdo_node: PdoBase, cob_base=None): self.maps[map_no + 1] = new_map def __getitem__(self, key: int) -> PdoMap: + if self.com_offset <= key <= self.com_offset + 511: + return self.maps[key - self.com_offset + 1] + if self.map_offset <= key <= self.map_offset + 511: + return self.maps[key - self.map_offset + 1] return self.maps[key] def __iter__(self) -> Iterator[int]: diff --git a/test/test_pdo.py b/test/test_pdo.py index 9eb6fb2f..2822ab65 100644 --- a/test/test_pdo.py +++ b/test/test_pdo.py @@ -76,6 +76,28 @@ def test_pdo_getitem(self): self.assertRaises(KeyError, lambda: node.pdo[0x1BFF]) self.assertRaises(KeyError, lambda: node.tpdo[0x1BFF]) + def test_pdo_getitem_communication_records(self): + # Test PDO access by communication parameter record indices + node = self.node + rpdo_comm = node.rpdo[0x1400] + self.assertIsInstance(rpdo_comm, canopen.pdo.PdoMap) + self.assertIs(rpdo_comm, node.rpdo[1]) + tpdo_comm = node.tpdo[0x1800] + self.assertIsInstance(tpdo_comm, canopen.pdo.PdoMap) + self.assertIs(tpdo_comm, node.tpdo[1]) + + # Test generic PDO with RPDO + pdo_rpdo_comm = node.pdo[0x1400] + self.assertIsInstance(pdo_rpdo_comm, canopen.pdo.PdoMap) + + # Test generic PDO with TPDO + pdo_tpdo_comm = node.pdo[0x1800] + self.assertIsInstance(pdo_tpdo_comm, canopen.pdo.PdoMap) + + # Verify the returned objects are the same as mapping record access + self.assertIs(node.rpdo[0x1400], node.rpdo[0x1600]) + self.assertIs(node.tpdo[0x1800], node.tpdo[0x1A00]) + def test_pdo_maps_iterate(self): node = self.node self.assertEqual(len(node.pdo), sum(1 for _ in node.pdo))