ndokter / dsmr_parser

Library to parse Dutch Smart Meter Requirements (DSMR) telegrams.
MIT License
110 stars 64 forks source link

EQUIPMENT IDENTIFIER is wrong for Fluvius meters when other mbus devices are present #133

Closed ejpalacios closed 12 months ago

ejpalacios commented 1 year ago

Problem

When other devices are present via the WMBus, the signature for the EQUIPMENT_IDENTIFIER will match not only the ID of the meter but also the IDs of the MBus devices.

Cause

The parser will try to add every match to the telegram (telegram.add(obis_reference, dsmr_object)), overwriting in each attempt the previously mapped EQUIPMENT_IDENTIFIER. Eventually, only the last match which will be set as ID. See objects.py line 33.

Why does the test pass?

If one try to access the field as telegram[obis.EQUIPMENT_IDENTIFIER] the correct ID is captured. This is because the "raw" obis references are only saved for their first occurrence. See objects.py lines 42-43.

This last type of access is used in test_parse_fluvius.py line 36, which passes:

assert result[obis.EQUIPMENT_IDENTIFIER].value == '3153414733313031303231363035' # works

However, if the field is access with the mapping, it will not work:

assert result.EQUIPMENT_IDENTIFIER.value == '3153414733313031303231363035' # won´t work

Proposed fix

The easiest fix would be to change the telegram specification for the Fluvius meter in telegram_specifications.py line 148 from

obis.EQUIPMENT_IDENTIFIER: CosemParser(ValueParser(str)),

to

obis.BELGIUM_EQUIPMENT_IDENTIFIER: CosemParser(ValueParser(str)),
ndokter commented 1 year ago

I am aware of this problem. There is now support for multiple mbus devices:

https://github.com/ndokter/dsmr_parser#telegram-object

# All Mbus device readings like gas meters and water meters can be retrieved as follows. This
# returns a list of MbusDevice objects:
mbus_devices = telegram.MBUS_DEVICES

# A specific MbusDevice based on the channel it's connected to, can be retrieved as follows:
mbus_device = telegram.get_mbus_device_by_channel(1)
print(mbus_device.DEVICE_TYPE.value)  # 3
print(mbus_device.EQUIPMENT_IDENTIFIER_GAS.value)  # '4730303339303031393336393930363139'
print(mbus_device.HOURLY_GAS_METER_READING.value)  # Decimal('246.138')

I wonder if your fix by hardcoding the mbus channel will break implementations for other

ejpalacios commented 1 year ago

The problem is not related to IDs of the mbus devices or channels but only with the ID of the main electricity meter. When one or more mbus devices are present, the pattern

EQUIPMENT_IDENTIFIER = r'^\d-\d:96\.1\.1.+?\r\n'

matches not only the ID of the electricity meter

# ID of the Meter which should be in EQUIPMENT_IDENTIFIER
    '0-0:96.1.1(3153414733313031303231363035)\r\n'
    ...

but also the IDs other mbus devices, which overwrite its value.

# ID of MBUS device 1
    '0-1:96.1.1(37464C4F32313139303333373333)\r\n'
    ...
# ID of MBUS device 2 (actual value in EQUIPMENT_IDENTIFIER)
    '0-2:96.1.1(3853414731323334353637383930)\r\n'

Changing the telegram specification to match

BELGIUM_EQUIPMENT_IDENTIFIER = r'^\d-0:96\.1\.1.+?\r\n'

fixes the problem as it captures only the ID of the electricity meter, but indeed it means the Fluvius profile will not use the EQUIPMENT_IDENTIFIER field but rather the BELGIUM_EQUIPMENT_IDENTIFIER.

The issue can be reproduced with the script below.

from dsmr_parser.parsers import TelegramParser
from dsmr_parser import telegram_specifications
from test.example_telegrams import TELEGRAM_FLUVIUS_V171

parser = TelegramParser(telegram_specifications.BELGIUM_FLUVIUS)
result = parser.parse(TELEGRAM_FLUVIUS_V171)
print("elec meter ID: ", result.EQUIPMENT_IDENTIFIER)
print("mbus channel 2 meter ID: ", result.BELGIUM_MBUS2_EQUIPMENT_IDENTIFIER)

The output shows that EQUIPMENT_IDENTIFIER is wrong and was overwritten with the ID of the last mbus device.

# elec meter ID should be 3153414733313031303231363035
elec meter ID:  3853414731323334353637383930    [None]
mbus channel 2 meter ID:  3853414731323334353637383930  [None]
ndokter commented 1 year ago

I understand now, thank you for explaining. We only need to fix the issue with the pipeline before being able to merge

ndokter commented 12 months ago

Thank you for your work! I've released it in v1.2.4