Skip to content

Commit 88ab36b

Browse files
committed
a simple IEC-62056-21 impl
1 parent 325c59d commit 88ab36b

File tree

2 files changed

+47
-35
lines changed

2 files changed

+47
-35
lines changed

custom_components/tibber_local/__init__.py

+46-34
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def should_poll(self) -> bool:
201201
class IntBasedObisCode:
202202
# This is for sure a VERY STUPID Python class - but I am a NOOB - would be cool, if someone could teach me
203203
# how I could fast convert my number array to the required format...
204-
def __init__(self, obis_src: list):
204+
def __init__(self, obis_src: list, do_log_output: bool):
205205
try:
206206
_a = int(obis_src[1])
207207
_b = int(obis_src[2])
@@ -214,8 +214,9 @@ def __init__(self, obis_src: list):
214214
# self.obis_short = f'{_c}.{_d}.{_e}'
215215
self.obis_hex = f'{self.get_as_two_digit_hex(_a)}{self.get_as_two_digit_hex(_b)}{self.get_as_two_digit_hex(_c)}{self.get_as_two_digit_hex(_d)}{self.get_as_two_digit_hex(_e)}{self.get_as_two_digit_hex(_f)}'
216216
except Exception as e:
217-
_LOGGER.warning(
218-
f"could not parse a value as int from list {obis_src} - Please check the position of your Tibber Pulse reading head (you might need to rotate it few degrees anti clock wise) - Exception: {e}")
217+
if (do_log_output):
218+
_LOGGER.warning(
219+
f"could not parse a value as int from list {obis_src} - Please check the position of your Tibber Pulse reading head (you might need to rotate it few degrees anti clock wise) - Exception: {e}")
219220

220221
@staticmethod
221222
def get_as_two_digit_hex(input: int) -> str:
@@ -254,6 +255,10 @@ async def detect_com_mode(self):
254255
await self._check_modes_internal(MODE_99_PLAINTEXT, MODE_3_SML_1_04)
255256
elif self._com_mode == MODE_0_AutoScanMode:
256257
await self._check_modes_internal(MODE_3_SML_1_04, MODE_99_PLAINTEXT)
258+
elif self._com_mode == MODE_1_IEC_62056_21:
259+
# https://github.com/marq24/ha-tibber-pulse-local/issues/29
260+
# looks like we can parse 'IEC_62056_21' as plaintext?!
261+
await self._check_modes_internal(MODE_99_PLAINTEXT, MODE_3_SML_1_04)
257262

258263
# finally raise value error if not implemented yet!
259264
if self._com_mode not in ENUM_IMPLEMENTATIONS:
@@ -308,8 +313,6 @@ async def read_tibber_local(self, mode: int, retry: bool, log_payload: bool = Fa
308313
if res.status == 200:
309314
if mode == MODE_3_SML_1_04:
310315
await self.read_sml(await res.read(), retry, log_payload)
311-
#elif mode == MODE_1_IEC_62056_21:
312-
# await self.read_ice62056(await res.read(), retry, log_payload)
313316
elif mode == MODE_99_PLAINTEXT:
314317
await self.read_plaintext(await res.text(), retry, log_payload)
315318
else:
@@ -330,41 +333,50 @@ async def read_plaintext(self, plaintext: str, retry: bool, log_payload: bool):
330333
plaintext = plaintext.replace(' ', '\r')
331334

332335
for a_line in plaintext.splitlines():
336+
try:
337+
# a patch for invalid reading?!
338+
# a_line = a_line.replace('."55*', '.255*')
339+
340+
# obis pattern is 'a-b:c.d.e*f'
341+
parts = re.split('(.*?)-(.*?):(.*?)\\.(.*?)\\.(.*?)\\*(.*?)\\((.*?)\\)', a_line)
342+
if len(parts) == 9:
343+
int_obc = IntBasedObisCode(parts, not self.ignore_parse_errors)
344+
value = parts[7]
345+
unit = None
346+
if '*' in value:
347+
val_with_unit = value.split("*")
348+
if '.' in val_with_unit[0]:
349+
value = float(val_with_unit[0])
350+
else:
351+
value = int(val_with_unit[0])
333352

334-
# a patch for invalid reading?!
335-
# a_line = a_line.replace('."55*', '.255*')
336-
337-
# obis pattern is 'a-b:c.d.e*f'
338-
parts = re.split('(.*?)-(.*?):(.*?)\\.(.*?)\\.(.*?)\\*(.*?)\\((.*?)\\)', a_line)
339-
if len(parts) == 9:
340-
int_obc = IntBasedObisCode(parts)
341-
value = parts[7]
342-
unit = None
343-
if '*' in value:
344-
val_with_unit = value.split("*")
345-
if '.' in val_with_unit[0]:
346-
value = float(val_with_unit[0])
347353
# converting any "kilo" unit to base unit...
348354
# so kWh will be converted to Wh - or kV will be V
349355
if val_with_unit[1].lower()[0] == 'k':
350356
value = value * 1000;
351357
val_with_unit[1] = val_with_unit[1][1:]
352-
unit = self.find_unit_int_from_string(val_with_unit[1])
353-
354-
# creating finally the "right" object from the parsed information
355-
entry = SmlListEntry()
356-
entry.obis = ObisCode(int_obc.obis_hex)
357-
entry.value = value
358-
entry.unit = unit
359-
temp_obis_values.append(entry)
360-
else:
361-
if parts[0] == '!':
362-
break;
363-
elif parts[0][0] != '/':
364-
if not self.ignore_parse_errors:
365-
_LOGGER.debug(f'unknown entry: {parts[0]} (line: {a_line})')
366-
# else:
367-
# print('ignore '+ parts[0])
358+
359+
unit = self.find_unit_int_from_string(val_with_unit[1])
360+
361+
# creating finally the "right" object from the parsed information
362+
if hasattr(int_obc, "obis_hex"):
363+
entry = SmlListEntry()
364+
entry.obis = ObisCode(int_obc.obis_hex)
365+
entry.value = value
366+
entry.unit = unit
367+
temp_obis_values.append(entry)
368+
else:
369+
if parts[0] == '!':
370+
break;
371+
elif len(parts[0]) > 0 and parts[0][0] != '/':
372+
if not self.ignore_parse_errors:
373+
_LOGGER.debug(f'unknown entry: {parts[0]} (line: {a_line})')
374+
#else:
375+
# print('ignore '+ parts[0])
376+
377+
except Exception as e:
378+
if not self.ignore_parse_errors:
379+
_LOGGER.info(f"{e}")
368380

369381
if len(temp_obis_values) > 0:
370382
self._obis_values = {}

custom_components/tibber_local/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
"iot_class": "local_polling",
1111
"issue_tracker": "https://github.com/marq24/ha-tibber-pulse-local/issues",
1212
"requirements": ["smllib==1.4"],
13-
"version": "2024.6.2"
13+
"version": "2024.6.3"
1414
}

0 commit comments

Comments
 (0)