From 516850481d64201c79fdcb6a94dc6d6134772cb0 Mon Sep 17 00:00:00 2001 From: Nigel Dokter Date: Mon, 13 Feb 2023 21:47:59 +0100 Subject: [PATCH] issue-51-telegram removed Telegram.__getattr__ and refactored __iter__ as well --- dsmr_parser/objects.py | 39 +++++++++------------------------------ test/test_telegram.py | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/dsmr_parser/objects.py b/dsmr_parser/objects.py index 465bd88..aa40a4c 100644 --- a/dsmr_parser/objects.py +++ b/dsmr_parser/objects.py @@ -2,10 +2,11 @@ from collections import defaultdict from decimal import Decimal from operator import attrgetter -import dsmr_parser.obis_name_mapping import datetime import json +from dsmr_parser import obis_name_mapping + class Telegram(object): """ @@ -23,16 +24,11 @@ class Telegram(object): self._telegram_data = defaultdict(list) self._mbus_channel_devices = {} - # Reverse name mapping and attribute related: - self._obis_name_mapping = dsmr_parser.obis_name_mapping.EN - self._reverse_obis_name_mapping = dsmr_parser.obis_name_mapping.REVERSE_EN - self._item_names = [] - def add(self, obis_reference, dsmr_object): self._telegram_data[obis_reference].append(dsmr_object) # Update name mapping used to get value by attribute. Example: telegram.P1_MESSAGE_HEADER - self._item_names.append(self._obis_name_mapping[obis_reference]) + setattr(self, obis_name_mapping.EN[obis_reference], dsmr_object) # Group Mbus related values into a MbusDevice object. # TODO MaxDemandParser (BELGIUM_MAXIMUM_DEMAND_13_MONTHS) returns a list @@ -65,13 +61,6 @@ class Telegram(object): def get_mbus_device_by_channel(self, channel_id): return self._mbus_channel_devices.get(channel_id) - def __getattr__(self, name): - """ will only get called for undefined attributes """ - obis_reference = self._reverse_obis_name_mapping[name] - value = self._telegram_data[obis_reference][0] - setattr(self, name, value) - return value - def __getitem__(self, obis_reference): """ Get value by key. Example: telegram[obis_references.P1_MESSAGE_HEADER] @@ -89,9 +78,11 @@ class Telegram(object): return len(self._telegram_data) def __iter__(self): - for attr in self._item_names: - value = getattr(self, attr) - yield attr, value + for obis_reference, values in self._telegram_data.items(): + reverse_obis_name = obis_name_mapping.EN[obis_reference] + value = values[0] # TODO might be considered legacy behavior? + + yield reverse_obis_name, value def __str__(self): output = "" @@ -330,20 +321,8 @@ class MbusDevice: self.channel_id = channel_id self._telegram_data = {} - # OBIS name mapping related used by __getattr__ - self._obis_name_mapping = dsmr_parser.obis_name_mapping.EN - self._reverse_obis_name_mapping = dsmr_parser.obis_name_mapping.REVERSE_EN - self._item_names = [] - def add(self, obis_reference, dsmr_object): self._telegram_data[obis_reference] = dsmr_object # Update name mapping used to get value by attribute. Example: device.HOURLY_GAS_METER_READING - self._item_names.append(self._obis_name_mapping[obis_reference]) - - def __getattr__(self, name): - """ will only get called for undefined attributes """ - obis_reference = self._reverse_obis_name_mapping[name] - value = self._telegram_data[obis_reference] - setattr(self, name, value) - return value + setattr(self, obis_name_mapping.EN[obis_reference], dsmr_object) diff --git a/test/test_telegram.py b/test/test_telegram.py index 20c79be..c33332d 100644 --- a/test/test_telegram.py +++ b/test/test_telegram.py @@ -2,13 +2,13 @@ import unittest import datetime import pytz -from dsmr_parser import telegram_specifications +from dsmr_parser import telegram_specifications, obis_references from dsmr_parser import obis_name_mapping from dsmr_parser.objects import CosemObject from dsmr_parser.objects import MBusObject from dsmr_parser.objects import ProfileGenericObject from dsmr_parser.parsers import TelegramParser -from test.example_telegrams import TELEGRAM_V4_2, TELEGRAM_V5_TWO_MBUS +from test.example_telegrams import TELEGRAM_V4_2, TELEGRAM_V5_TWO_MBUS, TELEGRAM_V5 from decimal import Decimal @@ -326,6 +326,17 @@ class TelegramTest(unittest.TestCase): self.assertEqual(len(telegram), 35) + def test_iter(self): + parser = TelegramParser(telegram_specifications.V5) + telegram = parser.parse(TELEGRAM_V5) + + for obis_reference, dsmr_object in telegram: + break + + # Verify that the iterator works for at least on evalue + self.assertEqual(obis_reference, obis_name_mapping.EN[obis_references.P1_MESSAGE_HEADER]) + self.assertEqual(dsmr_object.value, '50') + def test_get_mbus_devices(self): parser = TelegramParser(telegram_specifications.V5) telegram = parser.parse(TELEGRAM_V5_TWO_MBUS)