diff --git a/canopen/objectdictionary/eds.py b/canopen/objectdictionary/eds.py index cd64f604..40342d32 100644 --- a/canopen/objectdictionary/eds.py +++ b/canopen/objectdictionary/eds.py @@ -86,8 +86,11 @@ def import_eds(source, node_id): if eds.has_section("DeviceComissioning"): od.bitrate = int(eds.get("DeviceComissioning", "Baudrate")) * 1000 - od.node_id = int(eds.get("DeviceComissioning", "NodeID"), 0) - node_id = node_id or od.node_id + + if node_id is None: + if val := eds.get("DeviceComissioning", "NodeID", fallback=None): + node_id = int(val, base=0) + od.node_id = node_id for section in eds.sections(): # Match dummy definitions diff --git a/test/sample.eds b/test/sample.eds index 16d0c31a..3c1bbcf9 100644 --- a/test/sample.eds +++ b/test/sample.eds @@ -30,7 +30,7 @@ NrOfTXPDO=4 LSS_Supported=0 [DeviceComissioning] -NodeID=2 +NodeID=0x10 NodeName=Some name Baudrate=500 NetNumber=0 diff --git a/test/test_eds.py b/test/test_eds.py index 6caf0fa7..da59e0e6 100644 --- a/test/test_eds.py +++ b/test/test_eds.py @@ -4,7 +4,9 @@ from canopen.objectdictionary.eds import _signed_int_from_hex from canopen.utils import pretty_index -EDS_PATH = os.path.join(os.path.dirname(__file__), 'sample.eds') + +SAMPLE_EDS = os.path.join(os.path.dirname(__file__), 'sample.eds') +DATATYPES_EDS = os.path.join(os.path.dirname(__file__), 'datatypes.eds') class TestEDS(unittest.TestCase): @@ -48,7 +50,7 @@ class TestEDS(unittest.TestCase): } def setUp(self): - self.od = canopen.import_od(EDS_PATH, 2) + self.od = canopen.import_od(SAMPLE_EDS, 2) def test_load_nonexisting_file(self): with self.assertRaises(IOError): @@ -59,10 +61,34 @@ def test_load_unsupported_format(self): canopen.import_od(__file__) def test_load_file_object(self): - with open(EDS_PATH) as fp: + with open(SAMPLE_EDS) as fp: od = canopen.import_od(fp) self.assertTrue(len(od) > 0) + def test_load_implicit_nodeid(self): + # sample.eds has a DeviceComissioning section with NodeID set to 0x10. + od = canopen.import_od(SAMPLE_EDS) + self.assertEqual(od.node_id, 16) + + def test_load_implicit_nodeid_fallback(self): + import io + + # First, remove the NodeID option from DeviceComissioning. + with open(SAMPLE_EDS) as f: + lines = [L for L in f.readlines() if not L.startswith("NodeID=")] + with io.StringIO("".join(lines)) as buf: + buf.name = "mock.eds" + od = canopen.import_od(buf) + self.assertIsNone(od.node_id) + + # Next, try an EDS file without a DeviceComissioning section. + od = canopen.import_od(DATATYPES_EDS) + self.assertIsNone(od.node_id) + + def test_load_explicit_nodeid(self): + od = canopen.import_od(SAMPLE_EDS, node_id=3) + self.assertEqual(od.node_id, 3) + def test_variable(self): var = self.od['Producer heartbeat time'] self.assertIsInstance(var, canopen.objectdictionary.ODVariable)