diff --git a/readme.md b/readme.md index 6b88596..501a2b1 100644 --- a/readme.md +++ b/readme.md @@ -290,7 +290,7 @@ devices: ### Example devices configuration -One energy meter is connected to the serial port. The serial meter reports OSIB ``0100000009ff`` +One energy meter is connected to the serial port. The serial meter reports OBIS ``0100000009ff`` as ``11111111111111111111``. For this device diff --git a/requirements.txt b/requirements.txt index 7a7ed83..2cbd607 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ # Testing pytest >= 7.1, < 8 pre-commit >= 2, < 3 -pytest-asyncio >= 0.18.2, < 0.19 +pytest-asyncio >= 0.19, < 0.20 diff --git a/requirements_setup.txt b/requirements_setup.txt index 3a85f84..8f1b4f7 100644 --- a/requirements_setup.txt +++ b/requirements_setup.txt @@ -1,5 +1,5 @@ asyncio-mqtt == 0.12.1 pyserial-asyncio == 0.6 easyconfig == 0.2.4 -pydantic >= 1.9, <2.0 -smllib == 1.1 +pydantic >= 1.10, <2.0 +smllib == 1.2 diff --git a/src/sml2mqtt/__version__.py b/src/sml2mqtt/__version__.py index 58d478a..3f262a6 100644 --- a/src/sml2mqtt/__version__.py +++ b/src/sml2mqtt/__version__.py @@ -1 +1 @@ -__version__ = '1.2.0' +__version__ = '1.2.1' diff --git a/src/sml2mqtt/config/config.py b/src/sml2mqtt/config/config.py index 377338b..2403252 100644 --- a/src/sml2mqtt/config/config.py +++ b/src/sml2mqtt/config/config.py @@ -28,6 +28,10 @@ class GeneralSettings(BaseModel): False, description='Report the device id even though it does never change', alias='report device id', in_file=False ) + device_id_obis: str = Field( + '', description='Additional OBIS field for the serial number, default is 0100000009ff', + alias='device id obis', in_file=False + ) class Settings(AppBaseModel): diff --git a/src/sml2mqtt/device/sml_device.py b/src/sml2mqtt/device/sml_device.py index a1d30e6..d2d9188 100644 --- a/src/sml2mqtt/device/sml_device.py +++ b/src/sml2mqtt/device/sml_device.py @@ -72,8 +72,9 @@ def set_status(self, new_status: DeviceStatus) -> bool: shutdown(AllDevicesFailed) return True - def process_device_id(self, serial: str): + def set_device_id(self, serial: str): assert isinstance(serial, str) + assert not self.device_id_set self.device_id = serial self.device_id_set = True @@ -94,6 +95,26 @@ def process_device_id(self, serial: str): if cfg.skip is not None: self.skip_values.update(cfg.skip) + def select_device_id(self, frame_values: Dict[str, SmlListEntry]): + obis_ids = ['0100000009ff'] + if CONFIG.general.device_id_obis: + obis_ids.append(CONFIG.general.device_id_obis) + + for obis_id in obis_ids: + entry = frame_values.pop(obis_id, None) + if entry is not None: + if not CONFIG.general.report_device_id: + self.skip_values.add(obis_id) + self.set_device_id(entry.get_value()) + break + else: + self.set_device_id(self.device_url) + + # remove additionally skipped frames + # this gets filled in set_device_id, so we have to do it afterwards! + for name in self.skip_values: + frame_values.pop(name, None) + def serial_data_timeout(self): if self.set_status(DeviceStatus.MSG_TIMEOUT): self.stream.clear() @@ -181,17 +202,7 @@ async def process_frame(self, frame: SmlFrame): # We overwrite the device_id url (default) with the serial number if the device reports it # Otherwise we still do the config lookup so the user can configure the mqtt topics if not self.device_id_set: - entry = frame_values.pop('0100000009ff', None) - if entry is not None: - if not CONFIG.general.report_device_id: - self.skip_values.add('0100000009ff') - self.process_device_id(entry.get_value()) - else: - self.process_device_id(self.device_url) - - # remove additionally skipped frames - for name in self.skip_values: - frame_values.pop(name, None) + self.select_device_id(frame_values) # Process all values for obis_value in frame_values.values(): diff --git a/tests/device/frames/test_frame_1.py b/tests/device/frames/test_frame_1.py index d19e7a3..5b63215 100644 --- a/tests/device/frames/test_frame_1.py +++ b/tests/device/frames/test_frame_1.py @@ -44,7 +44,7 @@ async def test_frame_no_id(device: Device, no_serial, caplog, sml_frame_1: SmlFr abort_on_error: 0 message_body client_id : None - sever_id : 0a0149534b0005020de2 + server_id : 0a0149534b0005020de2 list_name : 0100620affff act_sensor_time : 1815342 val_list: @@ -81,7 +81,7 @@ async def test_frame_no_id(device: Device, no_serial, caplog, sml_frame_1: SmlFr scaler : -1 value : 0 value_signature: None - -> 0.0Wh + -> 0.0Wh (Wirkenergie Total) obis : 0100100700ff (1-0:16.7.0*255) status : None diff --git a/tests/device/test_data.py b/tests/device/test_data.py index cb97303..045a899 100644 --- a/tests/device/test_data.py +++ b/tests/device/test_data.py @@ -52,7 +52,7 @@ async def test_serial_data(device: Device, no_serial, caplog, sml_data_1: bytes, abort_on_error: 0 message_body client_id : None - sever_id : 00000000000000000000 + server_id : 00000000000000000000 list_name : None act_sensor_time : 3064820 val_list: @@ -109,7 +109,7 @@ async def test_serial_data(device: Device, no_serial, caplog, sml_data_1: bytes, scaler : -5 value : 219800000 value_signature: None - -> 2198.0Wh + -> 2198.0Wh (Wirkenergie Total) obis : 0100100700ff (1-0:16.7.0*255) status : None