Skip to content

Commit 2f0ec4e

Browse files
committed
Fix operation status calculation for binaty register values
1 parent 52dbfc8 commit 2f0ec4e

2 files changed

Lines changed: 57 additions & 35 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ To execute the example file, first run `pip install -r requirements.txt` to inst
5454
| `cooling_supply_line_temperature` | Cooling supply line temperature in Celsius |
5555
| --- | --- |
5656
| Operational status | |
57-
| `operational_status` | Operational status of the Heat Pump |
57+
| `operational_status` | Operational status of the Heat Pump or list of operational statuses (if multiple) |
5858
| `available_operational_statuses` | List of available operational statuses |
5959
| `available_operational_statuses_map` | Dictionary mapping operational status names to their values |
6060
| `operational_status_auxiliary_heater_3kw` | Auxiliary heater status for 3kw (returns `None` if unavailable) |

ThermiaOnlineAPI/model/HeatPump.py

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import sys
55
from ..utils.utils import pretty_print_except
66

7-
from typing import TYPE_CHECKING, Dict, Optional
7+
from typing import TYPE_CHECKING, Dict, List, Optional, Union
88

99
from ThermiaOnlineAPI.const import (
1010
REG_BRINE_IN,
@@ -56,10 +56,14 @@ def __init__(self, device_data: dict, api_interface: "ThermiaAPI"):
5656
self.__status = None
5757
self.__device_data = None
5858

59+
self.__device_config: Dict[str, Optional[str]] = {
60+
"operational_status_register": None,
61+
"operational_status_valueNamePrefix": None,
62+
}
63+
5964
# GROUPS
6065
self.__group_temperatures = None
6166
self.__group_operational_status = None
62-
self.__operational_status_register = None
6367
self.__group_operational_time = None
6468
self.__group_operational_operation = None
6569
self.__group_hot_water: Dict[str, Optional[int]] = {
@@ -345,39 +349,43 @@ def __get_value_by_key_and_register_name_from_operational_status(
345349
return None
346350

347351
def __get_operational_statuses_from_operational_status(self) -> Optional[Dict]:
348-
if self.__operational_status_register is not None:
349-
return self.__get_register_from_operational_status(
350-
self.__operational_status_register
352+
if self.__device_config["operational_status_register"] is not None:
353+
data = self.__get_register_from_operational_status(
354+
self.__device_config["operational_status_register"]
351355
)
356+
if data is not None:
357+
return data.get("valueNames", [])
352358

353359
# Try to get the data from the REG_OPERATIONAL_STATUS_PRIO1 register
354360
data = self.__get_register_from_operational_status(REG_OPERATIONAL_STATUS_PRIO1)
355361
if data is not None:
356-
self.__operational_status_register = REG_OPERATIONAL_STATUS_PRIO1
357-
return {
358-
"registerValues": data.get("valueNames", []),
359-
"valueNamePrefix": "REG_VALUE_STATUS_",
360-
}
362+
self.__device_config[
363+
"operational_status_register"
364+
] = REG_OPERATIONAL_STATUS_PRIO1
365+
self.__device_config[
366+
"operational_status_valueNamePrefix"
367+
] = "REG_VALUE_STATUS_"
368+
return data.get("valueNames", [])
361369

362370
# Try to get the data from the COMP_STATUS_ITEC register
363371
data = self.__get_register_from_operational_status(COMP_STATUS_ITEC)
364372
if data is not None:
365-
self.__operational_status_register = COMP_STATUS_ITEC
366-
return {
367-
"registerValues": data.get("valueNames", []),
368-
"valueNamePrefix": "COMP_VALUE_",
369-
}
373+
self.__device_config["operational_status_register"] = COMP_STATUS_ITEC
374+
self.__device_config["operational_status_valueNamePrefix"] = "COMP_VALUE_"
375+
return data.get("valueNames", [])
370376

371377
# Try to get the data from the REG_OPERATIONAL_STATUS_PRIORITY_BITMASK register
372378
data = self.__get_register_from_operational_status(
373379
REG_OPERATIONAL_STATUS_PRIORITY_BITMASK
374380
)
375381
if data is not None:
376-
self.__operational_status_register = REG_OPERATIONAL_STATUS_PRIORITY_BITMASK
377-
return {
378-
"registerValues": data.get("valueNames", []),
379-
"valueNamePrefix": "REG_VALUE_STATUS_",
380-
}
382+
self.__device_config[
383+
"operational_status_register"
384+
] = REG_OPERATIONAL_STATUS_PRIORITY_BITMASK
385+
self.__device_config[
386+
"operational_status_valueNamePrefix"
387+
] = "REG_VALUE_"
388+
return data.get("valueNames", [])
381389

382390
return None
383391

@@ -389,17 +397,13 @@ def __get_all_operational_statuses_from_operational_status(
389397
if data is None:
390398
return None
391399

392-
filtered_register_values = list(
393-
filter(lambda value: value.get("visible"), data["valueNames"])
394-
)
395-
396400
operation_modes_map = map(
397401
lambda values: {
398-
values.get("value"): values.get("name").split(data["valueNamePrefix"])[
399-
1
400-
],
402+
values.get("value"): values.get("name").split(
403+
self.__device_config["operational_status_valueNamePrefix"]
404+
)[1],
401405
},
402-
filtered_register_values,
406+
data,
403407
)
404408

405409
operation_modes_list = list(operation_modes_map)
@@ -554,15 +558,15 @@ def cooling_supply_line_temperature(self):
554558
###########################################################################
555559

556560
@property
557-
def operational_status(self):
558-
if self.__operational_status_register is None:
561+
def operational_status(self) -> Optional[Union[str, List[str]]]:
562+
if self.__device_config["operational_status_register"] is None:
559563
# Attempt to get the register from the status data
560564
self.__get_operational_statuses_from_operational_status()
561-
if self.__operational_status_register is None:
565+
if self.__device_config["operational_status_register"] is None:
562566
return None
563567

564568
data = self.__get_register_from_operational_status(
565-
self.__operational_status_register
569+
self.__device_config["operational_status_register"]
566570
)
567571

568572
if data is None:
@@ -575,11 +579,29 @@ def operational_status(self):
575579
if data is None:
576580
return None
577581

582+
data_items_list = list(data.items())
583+
578584
current_operation_mode = [
579-
name for value, name in data.items() if value == current_register_value
585+
name for value, name in data_items_list if value == current_register_value
580586
]
581587

582-
if len(current_operation_mode) != 1:
588+
if (
589+
len(current_operation_mode) != 1
590+
and current_register_value > 0
591+
and len(data_items_list) > 1
592+
):
593+
# Attempt to get multiple statuses by binary sum of the values
594+
data_items_list.sort(key=lambda x: x[0], reverse=True)
595+
list_of_current_operation_modes = []
596+
597+
for value, name in data_items_list:
598+
if value <= current_register_value:
599+
current_register_value -= value
600+
list_of_current_operation_modes.append(name)
601+
602+
if current_register_value == 0:
603+
return list_of_current_operation_modes
604+
583605
return None
584606

585607
return current_operation_mode[0]

0 commit comments

Comments
 (0)