Skip to content

Commit

Permalink
Merge pull request #661 from plugwise/test-elga_2
Browse files Browse the repository at this point in the history
Trying solution for Core issue #132479
  • Loading branch information
bouwew authored Dec 8, 2024
2 parents b42310d + 54ef0ce commit d8336a3
Show file tree
Hide file tree
Showing 16 changed files with 2,311 additions and 29 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: Latest commit

env:
CACHE_VERSION: 11
DEFAULT_PYTHON: "3.13"
DEFAULT_PYTHON: "3.13.0"
PRE_COMMIT_HOME: ~/.cache/pre-commit

on:
Expand Down Expand Up @@ -173,7 +173,7 @@ jobs:
needs: commitcheck
strategy:
matrix:
python-version: ["3.13", "3.12"]
python-version: ["3.13.0", "3.12"]
steps:
- name: Check out committed code
uses: actions/checkout@v4
Expand Down Expand Up @@ -213,7 +213,7 @@ jobs:
needs: prepare-test-cache
strategy:
matrix:
python-version: ["3.13", "3.12"]
python-version: ["3.13.0", "3.12"]

steps:
- name: Check out committed code
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v1.6.3

- Implement cooling-related fixes, trying to solve HA Core issue [#132479](https://github.com/home-assistant/core/issues/132479)

## v1.6.2

- Improve control_state processing:
Expand Down
1 change: 1 addition & 0 deletions fixtures/adam_heatpump_cooling/all_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"0ca13e8176204ca7bf6f09de59f81c83": {
"available": true,
"binary_sensors": {
"cooling_enabled": true,
"cooling_state": false,
"dhw_state": true,
"flame_state": false,
Expand Down
1 change: 1 addition & 0 deletions fixtures/adam_onoff_cooling_fake_firmware/all_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"devices": {
"0ca13e8176204ca7bf6f09de59f81c83": {
"binary_sensors": {
"cooling_enabled": true,
"cooling_state": true,
"dhw_state": true,
"flame_state": false,
Expand Down
37 changes: 19 additions & 18 deletions plugwise/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ def _get_entity_data(self, entity_id: str) -> GwEntityData:
# Switching groups data
self._entity_switching_group(entity, data)
# Adam data
self._get_adam_data(entity, data)
if self.smile(ADAM):
self._get_adam_data(entity, data)

# Thermostat data for Anna (presets, temperatures etc)
if self.smile(ANNA) and entity["dev_class"] == "thermostat":
Expand All @@ -225,26 +226,26 @@ def _get_adam_data(self, entity: GwEntityData, data: GwEntityData) -> None:
"""Helper-function for _get_entity_data().
Determine Adam heating-status for on-off heating via valves,
available regulations_modes and thermostat control_states.
available regulations_modes and thermostat control_states,
and add missing cooling_enabled when required.
"""
if self.smile(ADAM):
if entity["dev_class"] == "heater_central":
# Indicate heating_state based on valves being open in case of city-provided heating
if (
entity["dev_class"] == "heater_central"
and self._on_off_device
and isinstance(self._heating_valves(), int)
):
if self._on_off_device and isinstance(self._heating_valves(), int):
data["binary_sensors"]["heating_state"] = self._heating_valves() != 0

# Show the allowed regulation_modes and gateway_modes
if entity["dev_class"] == "gateway":
if self._reg_allowed_modes:
data["regulation_modes"] = self._reg_allowed_modes
self._count += 1
if self._gw_allowed_modes:
data["gateway_modes"] = self._gw_allowed_modes
self._count += 1

# Add cooling_enabled binary_sensor
if "binary_sensors" in data:
if "cooling_enabled" not in data["binary_sensors"] and self._cooling_present:
data["binary_sensors"]["cooling_enabled"] = self._cooling_enabled

# Show the allowed regulation_modes and gateway_modes
if entity["dev_class"] == "gateway":
if self._reg_allowed_modes:
data["regulation_modes"] = self._reg_allowed_modes
self._count += 1
if self._gw_allowed_modes:
data["gateway_modes"] = self._gw_allowed_modes
self._count += 1

def _climate_data(
self,
Expand Down
10 changes: 7 additions & 3 deletions plugwise/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,9 @@ def _update_elga_cooling(self, data: GwEntityData) -> None:
# Techneco Elga has cooling-capability
self._cooling_present = True
data["model"] = "Generic heater/cooler"
self._cooling_enabled = data["elga_status_code"] in (8, 9)
# Cooling_enabled in xml does NOT show the correct status!
# Setting it specifically:
self._cooling_enabled = data["binary_sensors"]["cooling_enabled"] = data["elga_status_code"] in (8, 9)
data["binary_sensors"]["cooling_state"] = self._cooling_active = (
data["elga_status_code"] == 8
)
Expand All @@ -812,11 +814,13 @@ def _update_elga_cooling(self, data: GwEntityData) -> None:

def _update_loria_cooling(self, data: GwEntityData) -> None:
"""Loria/Thermastage: base cooling-related on cooling_state and modulation_level."""
self._cooling_enabled = data["binary_sensors"]["cooling_state"]
# For Loria/Thermastage it's not clear if cooling_enabled in xml shows the correct status,
# setting it specifically:
self._cooling_enabled = data["binary_sensors"]["cooling_enabled"] = data["binary_sensors"]["cooling_state"]
self._cooling_active = data["sensors"]["modulation_level"] == 100
# For Loria the above does not work (pw-beta issue #301)
if "cooling_ena_switch" in data["switches"]:
self._cooling_enabled = data["switches"]["cooling_ena_switch"]
self._cooling_enabled = data["binary_sensors"]["cooling_enabled"] = data["switches"]["cooling_ena_switch"]
self._cooling_active = data["binary_sensors"]["cooling_state"]

def _cleanup_data(self, data: GwEntityData) -> None:
Expand Down
2 changes: 2 additions & 0 deletions plugwise/smile.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ async def async_update(self) -> PlugwiseData:
try:
await self.full_xml_update()
self.get_all_gateway_entities()
# Set self._cooling_enabled -required for set_temperature,
#also, check for a failed data-retrieval
if "heater_id" in self.gw_data:
heat_cooler = self.gw_entities[self.gw_data["heater_id"]]
if (
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "plugwise"
version = "1.6.2"
version = "1.6.3"
license = {file = "LICENSE"}
description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
readme = "README.md"
Expand Down
1 change: 1 addition & 0 deletions tests/data/adam/adam_heatpump_cooling.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"0ca13e8176204ca7bf6f09de59f81c83": {
"available": true,
"binary_sensors": {
"cooling_enabled": true,
"cooling_state": false,
"dhw_state": true,
"flame_state": false,
Expand Down
1 change: 1 addition & 0 deletions tests/data/adam/adam_onoff_cooling_fake_firmware.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"entities": {
"0ca13e8176204ca7bf6f09de59f81c83": {
"binary_sensors": {
"cooling_enabled": true,
"cooling_state": true,
"dhw_state": true,
"flame_state": false,
Expand Down
100 changes: 100 additions & 0 deletions tests/data/anna/anna_elga_2_cooling_UPDATED_DATA.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"entities": {
"573c152e7d4f4720878222bd75638f5b": {
"available": true,
"binary_sensors": {
"compressor_state": true,
"cooling_enabled": false,
"cooling_state": false,
"dhw_state": false,
"flame_state": true,
"heating_state": true,
"secondary_boiler_state": false
},
"dev_class": "heater_central",
"location": "d34dfe6ab90b410c98068e75de3eb631",
"maximum_boiler_temperature": {
"lower_bound": 0.0,
"resolution": 1.0,
"setpoint": 60.0,
"upper_bound": 100.0
},
"model": "Generic heater/cooler",
"name": "OpenTherm",
"sensors": {
"domestic_hot_water_setpoint": 60.0,
"intended_boiler_temperature": 0.0,
"modulation_level": 0.0,
"outdoor_air_temperature": 3.0,
"return_temperature": 23.4,
"water_pressure": 0.5,
"water_temperature": 22.8
},
"switches": {
"dhw_cm_switch": true
},
"vendor": "Techneco"
},
"ebd90df1ab334565b5895f37590ccff4": {
"active_preset": "home",
"available_schedules": [
"Thermostat schedule",
"off"
],
"climate_mode": "auto",
"dev_class": "thermostat",
"firmware": "2018-02-08T11:15:53+01:00",
"hardware": "6539-1301-5002",
"location": "d3ce834534114348be628b61b26d9220",
"model": "ThermoTouch",
"name": "Anna",
"preset_modes": [
"away",
"no_frost",
"vacation",
"home",
"asleep"
],
"select_schedule": "Thermostat schedule",
"sensors": {
"cooling_activation_outdoor_temperature": 26.0,
"cooling_deactivation_threshold": 3.0,
"illuminance": 0.5,
"setpoint_high": 30.0,
"setpoint_low": 19.5,
"temperature": 18.9
},
"temperature_offset": {
"lower_bound": -2.0,
"resolution": 0.1,
"setpoint": 0.0,
"upper_bound": 2.0
},
"thermostat": {
"lower_bound": 4.0,
"resolution": 0.1,
"setpoint_high": 30.0,
"setpoint_low": 19.5,
"upper_bound": 30.0
},
"vendor": "Plugwise"
},
"fb49af122f6e4b0f91267e1cf7666d6f": {
"binary_sensors": {
"plugwise_notification": false
},
"dev_class": "gateway",
"firmware": "4.2.1",
"hardware": "AME Smile 2.0 board",
"location": "d34dfe6ab90b410c98068e75de3eb631",
"mac_address": "C4930002FE76",
"model": "Gateway",
"model_id": "smile_thermo",
"name": "Smile Anna",
"sensors": {
"outdoor_temperature": 3.0
},
"vendor": "Plugwise"
}
}
}
2 changes: 2 additions & 0 deletions tests/test_adam.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ async def test_adam_heatpump_cooling(self):
assert smile._last_active["8cf650a4c10c44819e426bed406aec34"] == WERKDAG_SCHEMA
assert smile._last_active["5cc21042f87f4b4c94ccb5537c47a53f"] == WERKDAG_SCHEMA
assert self.entity_items == 497
assert self.cooling_present
assert self._cooling_enabled

await smile.close_connection()
await self.disconnect(server, client)
Expand Down
30 changes: 30 additions & 0 deletions tests/test_anna.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ async def test_connect_anna_heatpump_heating(self):
good_schedules=[
"standaard",
],
fail_cooling=True,
)
_LOGGER.debug(
"ERROR raised setting good schedule standaard: %s", exc.value
Expand Down Expand Up @@ -261,6 +262,7 @@ async def test_connect_anna_heatpump_cooling(self):
good_schedules=[
"standaard",
],
fail_cooling=True,
)
_LOGGER.debug(
"ERROR raised good schedule to standaard: %s", exc.value
Expand Down Expand Up @@ -407,6 +409,33 @@ async def test_connect_anna_elga_2_cooling(self):
assert self._cooling_enabled
assert self._cooling_active

result = await self.tinker_thermostat(
smile,
"d3ce834534114348be628b61b26d9220",
good_schedules=["Thermostat schedule"],
)
assert result

# Simulate a change of season: from cooling to heating after an update_interval
testdata_updated = self.load_testdata(
SMILE_TYPE, f"{self.smile_setup}_UPDATED_DATA"
)

self.smile_setup = "updated/anna_elga_2_switch_heating"
await self.device_test(
smile, "2020-04-05 00:00:01", testdata_updated, initialize=False
)
assert self.cooling_present
assert not self._cooling_enabled
assert not self._cooling_active

result = await self.tinker_thermostat(
smile,
"d3ce834534114348be628b61b26d9220",
good_schedules=["Thermostat schedule"],
)
assert result

await smile.close_connection()
await self.disconnect(server, client)

Expand Down Expand Up @@ -445,6 +474,7 @@ async def test_connect_anna_loria_heating_idle(self):
good_schedules=[
"Winter",
],
fail_cooling=True,
)
_LOGGER.debug(
"ERROR raised setting to schedule Winter: %s", exc.value
Expand Down
16 changes: 12 additions & 4 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,14 +704,20 @@ async def tinker_switch(

@pytest.mark.asyncio
async def tinker_thermostat_temp(
self, smile, loc_id, block_cooling=False, unhappy=False
self, smile, loc_id, block_cooling=False, fail_cooling=False, unhappy=False
):
"""Toggle temperature to test functionality."""
_LOGGER.info("Asserting modifying settings in location (%s):", loc_id)
tinker_temp_passed = False
test_temp = {"setpoint": 22.9}
if self.cooling_present and not block_cooling:
test_temp = {"setpoint_low": 19.5, "setpoint_high": 23.5}
if smile.smile_name == "Smile Anna":
if self._cooling_enabled:
test_temp = {"setpoint_low": 4.0, "setpoint_high": 23.0}
else:
test_temp = {"setpoint_low": 19.0, "setpoint_high": 30.0}
if fail_cooling:
test_temp = {"setpoint_low": 19.0, "setpoint_high": 23.0}
_LOGGER.info("- Adjusting temperature to %s", test_temp)
try:
await smile.set_temperature(loc_id, test_temp)
Expand Down Expand Up @@ -826,14 +832,15 @@ async def tinker_thermostat(
good_schedules=None,
single=False,
block_cooling=False,
fail_cooling=False,
unhappy=False,
):
"""Toggle various climate settings to test functionality."""
if good_schedules is None: # pragma: no cover
good_schedules = ["Weekschema"]

result_1 = await self.tinker_thermostat_temp(
smile, loc_id, block_cooling, unhappy
smile, loc_id, block_cooling, fail_cooling, unhappy
)
result_2 = await self.tinker_thermostat_preset(smile, loc_id, unhappy)
if smile._schedule_old_states != {}:
Expand All @@ -858,11 +865,12 @@ async def tinker_legacy_thermostat(
smile,
schedule_on=True,
block_cooling=False,
fail_cooling=False,
unhappy=False,
):
"""Toggle various climate settings to test functionality."""
result_1 = await self.tinker_thermostat_temp(
smile, "dummy", block_cooling, unhappy
smile, "dummy", block_cooling, fail_cooling, unhappy
)
result_2 = await self.tinker_thermostat_preset(smile, None, unhappy)
result_3 = await self.tinker_legacy_thermostat_schedule(smile, unhappy)
Expand Down
Empty file.
Loading

0 comments on commit d8336a3

Please sign in to comment.