Open lowdef opened 1 year ago
Cause:
self._item_names = self._get_item_names()
In __init__
does not have any effect anymore, because Telegram is filled after being created. So _item_names is always [].
To do a traversal of _telegram_data_items() for every print or to_json() seems very inefficient.
We could add to the add() method:
setattr(self, _obis_name_mapping[obis_reference], value)
All the methods str(), to_json(), __get_item_names() can then work on the attributess of the Object itself:
for attr, value in self:
# do something with attr and value
__get_attr__()
we do not need anymore then, as all items are true first class object attributes.
Following works again, not going to merge as changes are happening in parallel now:
class Telegram(object):
"""
Container for parsed telegram data.
Attributes can be accessed on a telegram object by addressing by their english name, for example:
telegram.ELECTRICITY_USED_TARIFF_1
All attributes in a telegram can be iterated over, for example:
[k for k,v in telegram]
yields:
['P1_MESSAGE_HEADER', 'P1_MESSAGE_TIMESTAMP', 'EQUIPMENT_IDENTIFIER', ...]
"""
def __init__(self):
self._telegram_data = defaultdict(list)
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, value):
self._telegram_data[obis_reference].append(value)
name = self._obis_name_mapping[obis_reference]
self._item_names.append(name)
setattr(self, name, value)
def get(self, obis_reference, channel):
return next(filter(lambda x: x.channel == channel, self._telegram_data[obis_reference]))
def __getitem__(self, obis_reference):
return self._telegram_data[obis_reference][0]
def __len__(self):
return len(self._telegram_data) #TODO: its nested now
def _get_item_names(self):
return self._item_names
def __iter__(self):
for attr in self._item_names:
value = getattr(self, attr)
yield attr, value
def __str__(self):
output = ""
for attr, value in self:
output += "{}: \t {}\n".format(attr, str(value))
return output
def to_json(self):
return json.dumps(dict([[attr, json.loads(value.to_json())] for attr, value in self]))
Or as diff:
diff --git a/dsmr_parser/objects.py b/dsmr_parser/objects.py
index 15ed27e..b500f25 100644
--- a/dsmr_parser/objects.py
+++ b/dsmr_parser/objects.py
@@ -22,21 +22,17 @@ class Telegram(object):
self._telegram_data = defaultdict(list)
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 = self._get_item_names()
+ self._item_names = []
def add(self, obis_reference, value):
self._telegram_data[obis_reference].append(value)
+ name = self._obis_name_mapping[obis_reference]
+ self._item_names.append(name)
+ setattr(self, name, value)
def get(self, obis_reference, channel):
return next(filter(lambda x: x.channel == channel, self._telegram_data[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][0]
- setattr(self, name, value)
- return value
-
def __getitem__(self, obis_reference):
return self._telegram_data[obis_reference][0]
@@ -44,7 +40,7 @@ class Telegram(object):
return len(self._telegram_data) #TODO: its nested now
def _get_item_names(self):
- return [self._obis_name_mapping[k] for k, v in self._telegram_data.items()]
+ return self._item_names
def __iter__(self):
for attr in self._item_names:
Telegram to_str() and to_json() broken.
Both return empty results.