Skip to content

Commit f73018e

Browse files
author
marq24
committed
support for 'missing' *255
1 parent a1ed828 commit f73018e

File tree

2 files changed

+25
-15
lines changed

2 files changed

+25
-15
lines changed

custom_components/tibber_local/__init__.py

+24-14
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
PLATFORMS = ["sensor"]
4040

41+
4142
def mask_map(d):
4243
for k, v in d.copy().items():
4344
if isinstance(v, dict):
@@ -52,6 +53,7 @@ def mask_map(d):
5253
d[k] = v
5354
return d
5455

56+
5557
async def async_setup(hass: HomeAssistant, config: dict):
5658
return True
5759

@@ -62,7 +64,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
6264
config_entry.data.get(CONF_SCAN_INTERVAL,
6365
DEFAULT_SCAN_INTERVAL)))
6466

65-
_LOGGER.info(f"Starting TibberLocal with interval: {SCAN_INTERVAL} - ConfigEntry: {mask_map(dict(config_entry.as_dict()))}")
67+
_LOGGER.info(
68+
f"Starting TibberLocal with interval: {SCAN_INTERVAL} - ConfigEntry: {mask_map(dict(config_entry.as_dict()))}")
6669

6770
if DOMAIN not in hass.data:
6871
value = "UNKOWN"
@@ -99,7 +102,8 @@ def __init__(self, hass: HomeAssistant, config_entry):
99102
# initial configuration phase - so we read it from the config_entry.data ONLY!
100103
com_mode = int(config_entry.data.get(CONF_MODE, MODE_3_SML_1_04))
101104

102-
self.bridge = TibberLocalBridge(host=self._host, pwd=the_pwd, websession=async_get_clientsession(hass), node_num=node_num,
105+
self.bridge = TibberLocalBridge(host=self._host, pwd=the_pwd, websession=async_get_clientsession(hass),
106+
node_num=node_num,
103107
com_mode=com_mode, options={"ignore_parse_errors": ignore_parse_errors})
104108
self.name = config_entry.title
105109
self._config_entry = config_entry
@@ -204,7 +208,10 @@ def __init__(self, obis_src: list, do_log_output: bool):
204208
_c = int(obis_src[3])
205209
_d = int(obis_src[4])
206210
_e = int(obis_src[5])
207-
_f = int(obis_src[6])
211+
if obis_src[6] is not None and len(obis_src[6]) > 0:
212+
_f = int(obis_src[6])
213+
else:
214+
_f = 255
208215

209216
# self.obis_code = f'{_a}-{_b}:{_c}.{_d}.{_e}*{_f}'
210217
# self.obis_short = f'{_c}.{_d}.{_e}'
@@ -224,9 +231,8 @@ def get_as_two_digit_hex(input: int) -> str:
224231

225232

226233
class TibberLocalBridge:
227-
228234
ONLY_DIGITS: re.Pattern = re.compile("^[0-9]+$")
229-
PLAIN_TEXT_LINE: re.Pattern = re.compile('(.*?)-(.*?):(.*?)\\.(.*?)\\.(.*?)\\*(.*?)\\((.*?)\\)')
235+
PLAIN_TEXT_LINE: re.Pattern = re.compile('(.*?)-(.*?):(.*?)\\.(.*?)\\.(.*?)(?:\\*(.*?)|)\\((.*?)\\)')
230236

231237
# _communication_mode 'MODE_3_SML_1_04' is the initial implemented mode (reading binary sml data)...
232238
# 'all' other modes have to be implemented... also it could be, that the bridge does
@@ -263,7 +269,7 @@ async def detect_com_mode(self):
263269
if self._com_mode not in ENUM_IMPLEMENTATIONS:
264270
raise ValueError(f"NOT IMPLEMENTED yet! - Mode: {self._com_mode}")
265271

266-
async def _check_modes_internal(self, mode_1:int, mode_2:int):
272+
async def _check_modes_internal(self, mode_1: int, mode_2: int):
267273
_LOGGER.debug(f"detect_com_mode is {self._com_mode}: will try to read {mode_1}")
268274
await self.read_tibber_local(mode_1, False, log_payload=True)
269275
if len(self._obis_values) > 0:
@@ -322,13 +328,13 @@ async def read_tibber_local(self, mode: int, retry: bool, log_payload: bool = Fa
322328
except Exception as exec:
323329
_LOGGER.warning(f"access to bridge failed with exception: {exec}")
324330

325-
def check_first_six_parts_for_digits(self, parts: list[str]) -> bool:
331+
def check_first_six_parts_for_digits_or_last_is_none(self, parts: list[str]) -> bool:
326332
return (self.ONLY_DIGITS.match(parts[1]) is not None and
327333
self.ONLY_DIGITS.match(parts[2]) is not None and
328334
self.ONLY_DIGITS.match(parts[3]) is not None and
329335
self.ONLY_DIGITS.match(parts[4]) is not None and
330336
self.ONLY_DIGITS.match(parts[5]) is not None and
331-
self.ONLY_DIGITS.match(parts[6]) is not None)
337+
(parts[6] is None or self.ONLY_DIGITS.match(parts[6]) is not None))
332338

333339
async def read_plaintext(self, plaintext: str, retry: bool, log_payload: bool):
334340
try:
@@ -347,7 +353,7 @@ async def read_plaintext(self, plaintext: str, retry: bool, log_payload: bool):
347353
# obis pattern is 'a-b:c.d.e*f'
348354
parts = re.split(self.PLAIN_TEXT_LINE, a_line)
349355
if len(parts) == 9:
350-
if self.check_first_six_parts_for_digits(parts):
356+
if self.check_first_six_parts_for_digits_or_last_is_none(parts):
351357
int_obc = IntBasedObisCode(parts, not self.ignore_parse_errors)
352358
value = parts[7]
353359
unit = None
@@ -382,7 +388,7 @@ async def read_plaintext(self, plaintext: str, retry: bool, log_payload: bool):
382388
elif len(parts[0]) > 0 and parts[0][0] != '/':
383389
if not self.ignore_parse_errors:
384390
_LOGGER.debug(f"unknown entry: {parts[0]} (line: '{a_line}')")
385-
#else:
391+
# else:
386392
# print('ignore '+ parts[0])
387393

388394
except Exception as e:
@@ -534,22 +540,26 @@ def attr0100020800ff_in_k(self) -> float:
534540
@property
535541
def attr0100100700ff(self) -> float:
536542
# search for SUM (0), POS (0), POS (255), NEG (0), ABS (0)
537-
return self._get_value_internal(['0100100700ff', '0100010700ff', '01000107ffff', '0100020700ff', '01000f0700ff'])
543+
return self._get_value_internal(
544+
['0100100700ff', '0100010700ff', '01000107ffff', '0100020700ff', '01000f0700ff'])
538545

539546
@property
540547
def attr0100240700ff(self) -> float:
541548
# search for SUM (0), POS (0), POS (255), NEG (0), ABS (0)
542-
return self._get_value_internal(['0100240700ff', '0100150700ff', '01001507ffff', '0100160700ff', '0100230700ff'])
549+
return self._get_value_internal(
550+
['0100240700ff', '0100150700ff', '01001507ffff', '0100160700ff', '0100230700ff'])
543551

544552
@property
545553
def attr0100380700ff(self) -> float:
546554
# search for SUM (0), POS (0), POS (255), NEG (0), ABS (0)
547-
return self._get_value_internal(['0100380700ff', '0100290700ff', '01002907ffff', '01002a0700ff', '0100370700ff'])
555+
return self._get_value_internal(
556+
['0100380700ff', '0100290700ff', '01002907ffff', '01002a0700ff', '0100370700ff'])
548557

549558
@property
550559
def attr01004c0700ff(self) -> float:
551560
# search for SUM (0), POS (0), POS (255), NEG (0), ABS (0)
552-
return self._get_value_internal(['01004c0700ff', '01003d0700ff', '01003d07ffff', '01003e0700ff', '01004b0700ff'])
561+
return self._get_value_internal(
562+
['01004c0700ff', '01003d0700ff', '01003d07ffff', '01003e0700ff', '01004b0700ff'])
553563

554564
@property
555565
def attr0100200700ff(self) -> float:

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.7.1"
13+
"version": "2024.8.0"
1414
}

0 commit comments

Comments
 (0)