Skip to content

Commit

Permalink
Merge pull request #17 from msp1974/dev
Browse files Browse the repository at this point in the history
v1.5.17
  • Loading branch information
msp1974 authored Oct 19, 2024
2 parents bae9b08 + a079ed7 commit e8b6fc1
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 74 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Drayton Wiser Hub API Async v1.5.16
# Drayton Wiser Hub API Async v1.5.17

This repository contains a simple API which queries the Drayton Wiser Heating sysystem used in the UK.

Expand Down Expand Up @@ -52,6 +52,11 @@ Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/b

## Changelog

### v1.5.17

* Fixed error setting opentherm endpoint for fw above 4.32.46
* Added support for CFMT devices

### v1.5.16

* Added support for v2 opentherm endpoint for fw above 4.32.46
Expand Down
2 changes: 1 addition & 1 deletion aioWiserHeatAPI/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
name = "aioWiserHeatAPI"
__all__ = ["wiserAPI", "wiserDiscovery"]

__VERSION__ = "1.5.16"
__VERSION__ = "1.5.17"

_LOGGER = logging.getLogger(__name__)
15 changes: 12 additions & 3 deletions aioWiserHeatAPI/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class _WiserDeviceTypeEnum(enum.Enum):
SmokeAlarmDevice = "SmokeAlarmDevice"
WindowDoorSensor = "BinarySensor"
BoilerInterface = "BoilerInterface"
CFMT = "HeatingActuator"


PRODUCT_TYPE_CONFIG = {
Expand Down Expand Up @@ -134,6 +135,13 @@ class _WiserDeviceTypeEnum(enum.Enum):
"endpoint": WISERBOILERINTERFACE,
"device_id_field": "DeviceId",
},
"CFMT": {
"class": _WiserHeatingActuator,
"collection": _WiserHeatingActuatorCollection,
"endpoint": WISERHEATINGACTUATOR,
"heating": True,
"has_v2_equipment": True,
},
}


Expand Down Expand Up @@ -197,9 +205,10 @@ def _build(self):

# If heating device add room id
if device_config.get("heating"):
device_info[0]["RoomId"] = self._get_temp_device_room_id(
self._domain_data, device.get("id")
)
if not device.get("RoomId"):
device_info[0]["RoomId"] = self._get_temp_device_room_id(
self._domain_data, device.get("id")
)

# If schedule device add schedule
if device_config.get("schedule_type"):
Expand Down
102 changes: 70 additions & 32 deletions aioWiserHeatAPI/helpers/opentherm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .temp import _WiserTemperatureFunctions as tf


class _WiserOpenThermBoilerParameters(object):
class _WiserOpenThermBoilerParameters:
"""Data structure for Opentherm Boiler Parameters data"""

def __init__(self, data: dict):
Expand All @@ -19,9 +19,7 @@ def ch_max_setpoint_transfer_enable(self) -> bool:

@property
def ch_setpoint(self) -> bool:
return tf._from_wiser_temp(
self._data.get("maxChSetpoint", None), "current"
)
return tf._from_wiser_temp(self._data.get("maxChSetpoint", None), "current")

@property
def ch_setpoint_lower_bound(self) -> bool:
Expand All @@ -45,9 +43,7 @@ def hw_setpoint_transfer_enable(self) -> bool:

@property
def hw_setpoint(self) -> bool:
return tf._from_wiser_temp(
self._data.get("dhwSetpoint", None), "current"
)
return tf._from_wiser_temp(self._data.get("dhwSetpoint", None), "current")

@property
def hw_setpoint_lower_bound(self) -> bool:
Expand All @@ -66,7 +62,7 @@ def json_data(self) -> dict:
return self._data


class _WiserOpenThermOperationalData(object):
class _WiserOpenThermOperationalData:
"""Data structure for Opentherm Boiler Parameters data"""

def __init__(self, data):
Expand Down Expand Up @@ -99,9 +95,7 @@ def hw_flow_rate(self) -> str:
@property
def hw_temperature(self) -> str:
"""Get Dhw1Temperature"""
return tf._from_wiser_temp(
self._data.get("Dhw1Temperature", None), "current"
)
return tf._from_wiser_temp(self._data.get("Dhw1Temperature", None), "current")

@property
def relative_modulation_level(self) -> int:
Expand All @@ -120,6 +114,58 @@ def json_data(self) -> dict:
return self._data


class _WiserOpenThermExtendedDiagnostics:
"""Data structure for Opentherm extended diagnostics."""

def __init__(self, data: dict[str, int | str]):
self._data = data

@property
def unsuccessful_burner_starts(self) -> int:
"""Get unsuccessfulBurnerStarts"""
return self._data.get("unsuccessfulBurnerStarts", 0)

@property
def number_flame_signal_too_low(self) -> int:
"""Get numberFlameSignalTooLow"""
return self._data.get("numberFlameSignalTooLow", 0)

@property
def oem_specific_service_code(self) -> int:
"""Get oemSpecificServiceCode"""
return self._data.get("oemSpecificServiceCode", 0)

@property
def successful_burner_starts(self) -> int:
"""Get successfulBurnerStarts"""
return self._data.get("successfulBurnerStarts", 0)

@property
def ch_pump_starts(self) -> int:
"""Get chPumpStarts"""
return self._data.get("chPumpStarts", 0)

@property
def dhw_pump_or_valve_starts(self) -> int:
"""Get dhwPumpOrValveStarts"""
return self._data.get("dhwPumpOrValveStarts", 0)

@property
def burner_starts_during_dhw_mode(self) -> int:
"""Get burnerStartsDuringDhwMode"""
return self._data.get("burnerStartsDuringDhwMode", 0)

@property
def burner_hours(self) -> int:
"""Get burnerHours"""
return self._data.get("burnerHours", 0)

@property
def ch_pump_hours(self) -> int:
"""Get chPumpHours"""
return self._data.get("chPumpHours", 0)


class _WiserOpentherm(object):
"""Data structure for Opentherm data"""

Expand Down Expand Up @@ -160,9 +206,7 @@ def ch1_flow_enabled(self) -> bool:
@property
def ch1_flow_setpoint(self) -> float:
"""Get ch1FlowSetpoint"""
return tf._from_wiser_temp(
self._data.get("ch1FlowSetpoint", None), "current"
)
return tf._from_wiser_temp(self._data.get("ch1FlowSetpoint", None), "current")

@property
def ch2_flow_enabled(self) -> bool:
Expand All @@ -172,9 +216,7 @@ def ch2_flow_enabled(self) -> bool:
@property
def ch2_flow_setpoint(self) -> float:
"""Get ch2FlowSetpoint"""
return tf._from_wiser_temp(
self._data.get("ch2FlowSetpoint", None), "current"
)
return tf._from_wiser_temp(self._data.get("ch2FlowSetpoint", None), "current")

@property
def connection_status(self) -> str:
Expand All @@ -194,9 +236,7 @@ def hw_enabled(self) -> bool:
@property
def hw_flow_setpoint(self) -> float:
"""Get dhwFlowSetpoint"""
return tf._from_wiser_temp(
self._data.get("dhwFlowSetpoint", None), "current"
)
return tf._from_wiser_temp(self._data.get("dhwFlowSetpoint", None), "current")

@property
def operating_mode(self) -> str:
Expand All @@ -205,29 +245,29 @@ def operating_mode(self) -> str:

@property
def operational_data(self) -> _WiserOpenThermOperationalData:
return _WiserOpenThermOperationalData(
self._data.get("operationalData", {})
)
return _WiserOpenThermOperationalData(self._data.get("operationalData", {}))

@property
def boiler_parameters(self) -> _WiserOpenThermBoilerParameters:
return _WiserOpenThermBoilerParameters(
self._data.get("preDefinedRemoteBoilerParameters", {})
)

@property
def extended_diagnostics(self) -> _WiserOpenThermExtendedDiagnostics:
return _WiserOpenThermExtendedDiagnostics(
self._data.get("extendedDiagnostics", {})
)

@property
def room_setpoint(self) -> float:
"""Get roomTemperature"""
return tf._from_wiser_temp(
self._data.get("roomSetpoint", None), "current"
)
return tf._from_wiser_temp(self._data.get("roomSetpoint", None), "current")

@property
def room_temperature(self) -> float:
"""Get roomTemperature"""
return tf._from_wiser_temp(
self._data.get("roomTemperature", None), "current"
)
return tf._from_wiser_temp(self._data.get("roomTemperature", None), "current")

@property
def tracked_room_id(self) -> int:
Expand All @@ -238,9 +278,7 @@ def tracked_room_id(self) -> int:
def json_data(self) -> dict:
return self._data

async def set_opentherm_parameter(
self, endpoint: str, cmd_data: str
) -> bool:
async def set_opentherm_parameter(self, endpoint: str, cmd_data: str) -> bool:
"""Allow settign of opentherm param"""
return await self._wiser_rest_controller._do_hub_action(
WiserRestActionEnum.PATCH,
Expand Down
55 changes: 18 additions & 37 deletions aioWiserHeatAPI/helpers/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,57 +11,38 @@ class Version:

def __gt__(self, other):
if isinstance(other, Version):
return (
self.major >= other.major
and self.minor >= other.minor
and self.micro > other.micro
)
return self._version_compare(self.version, other.version) == 1

def __ge__(self, other):
if isinstance(other, Version):
return self.__eq__(other) or self.__gt__(other)

def __lt__(self, other):
if isinstance(other, Version):
return (
self.major <= other.major
and self.minor <= other.minor
and self.micro < other.micro
)
return self._version_compare(self.version, other.version) == -1

def __le__(self, other):
if isinstance(other, Version):
return self.__eq__(other) or self.__lt__(other)

def __eq__(self, other):
if isinstance(other, Version):
return (
self.major == other.major
and self.minor == other.minor
and self.micro == other.micro
)
return self._version_compare(self.version, other.version) == 0

@property
def major(self) -> int:
"""Get major version."""
try:
return self.version.split(".")[0]
except IndexError:
return None
def _version_compare(self, v1: str, v2: str) -> int:
version1 = v1.replace("-", ".").split(".")
version2 = v2.replace("-", ".").split(".")

@property
def minor(self) -> int:
"""Get minor version."""
try:
return self.version.split(".")[1]
except IndexError:
return None
length = max(len(version1), len(version2))

@property
def micro(self) -> int:
"""Get micro version."""
try:
full_micro = self.version.split(".")[2]
return full_micro.split("-")[0]
except IndexError:
return None
# Compare each component of the version strings.
for i in range(length):
v1_itm = int(version1[i]) if version1[i].isdigit() else version1[i]
v2_itm = int(version2[i]) if version2[i].isdigit() else version2[i]

if v1_itm > v2_itm:
return 1
if v1_itm < v2_itm:
return -1

return 0

0 comments on commit e8b6fc1

Please sign in to comment.