Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
376d26e
Handle removal of last remaining schedule
bouwew Jul 15, 2025
1221160
Adapt to HA Select required formats
bouwew Jul 15, 2025
584c41c
Update for legacy Anna too
bouwew Jul 15, 2025
bd09300
Update manual_fixtures script
bouwew Jul 15, 2025
8ffafa8
Improve using initial values
bouwew Jul 15, 2025
45a1665
Update related amount of entity_items
bouwew Jul 15, 2025
2dd3a32
Update typing of select_schedule
bouwew Jul 15, 2025
f5cdd2b
Scripture cleanup
bouwew Jul 15, 2025
fcd01fa
Save updated fixtures
bouwew Jul 15, 2025
bb40c77
Update other select_* typing
bouwew Jul 15, 2025
07b6329
Improve data["select_dhw_mode"]
bouwew Jul 16, 2025
43f8245
Improve logic for select_regulation/gateway_mode
bouwew Jul 16, 2025
e0074a3
Add extra guarding for gateway
bouwew Jul 16, 2025
4e5d72b
Re-adapt _get_regulation_mode()
bouwew Jul 16, 2025
840ff5c
Fix userdata jsons: older firmware has no regulation_mode allowed keys
bouwew Jul 16, 2025
3d1ce65
Update related entity_items asserts
bouwew Jul 16, 2025
72e6e77
One more correction
bouwew Jul 16, 2025
37d0bd4
Also re-adapt _get_gateway_mode()
bouwew Jul 16, 2025
e6e6b27
Save updated fixtures
bouwew Jul 16, 2025
3ce925f
Revert some select_related typing updates, not required
bouwew Jul 16, 2025
5f0d779
Implement SonarQube suggestion, add explanatory comment
bouwew Jul 16, 2025
ca330d1
Bump to v1.7.8a2 test-version
bouwew Jul 16, 2025
d359f28
Bump to v1.7.8 release-version, update CHANGELOG
bouwew Jul 16, 2025
a3297f3
Improve comment
bouwew Jul 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Changelog

## Ongoing / 1.7.8a0+1
## v1.7.8

- Chores move module publishing on (test)pypi to Trusted Publishing (and using uv) - released as alpha 1.7.8a0+1 to demonstrate functionality
- Implement fixes related to the select-platform-data provided to the HA Core integrations, part of solving pw-beta issue [#897](https://github.com/plugwise/plugwise-beta/issues/897)
- Chores move module publishing on (test)pypi to Trusted Publishing (and using uv)

## v1.7.7

Expand Down
8 changes: 8 additions & 0 deletions fixtures/adam_jip/data.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
{
"06aecb3d00354375924f50c47af36bd2": {
"active_preset": "no_frost",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Slaapkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 24.2
},
Expand All @@ -24,12 +26,14 @@
},
"13228dab8ce04617af318a2888b3c548": {
"active_preset": "home",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Woonkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 27.4
},
Expand Down Expand Up @@ -237,12 +241,14 @@
},
"d27aede973b54be484f6842d1b2802ad": {
"active_preset": "home",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Kinderkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 30.0
},
Expand Down Expand Up @@ -284,12 +290,14 @@
},
"d58fec52899f4f1c92e4f8fad6d8c48c": {
"active_preset": "home",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Logeerkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 30.0
},
Expand Down
1 change: 0 additions & 1 deletion fixtures/adam_multiple_devices_per_zone/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,6 @@
"warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."
}
},
"select_regulation_mode": "heating",
"sensors": {
"outdoor_temperature": 7.81
},
Expand Down
1 change: 0 additions & 1 deletion fixtures/adam_plus_anna/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
"error": "There is no OpenTherm communication with the boiler."
}
},
"select_regulation_mode": "heating",
"sensors": {
"outdoor_temperature": 11.9
},
Expand Down
1 change: 0 additions & 1 deletion fixtures/adam_zone_per_device/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@
"warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."
}
},
"select_regulation_mode": "heating",
"sensors": {
"outdoor_temperature": 7.69
},
Expand Down
2 changes: 2 additions & 0 deletions fixtures/legacy_anna/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
},
"0d266432d64443e283b5d708ae98b455": {
"active_preset": "home",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "heating",
"dev_class": "thermostat",
Expand All @@ -44,6 +45,7 @@
"model": "ThermoTouch",
"name": "Anna",
"preset_modes": ["away", "vacation", "asleep", "home", "no_frost"],
"select_schedule": null,
"sensors": {
"illuminance": 150.8,
"setpoint": 20.5,
Expand Down
8 changes: 8 additions & 0 deletions fixtures/m_adam_jip/data.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{
"06aecb3d00354375924f50c47af36bd2": {
"active_preset": "no_frost",
"available_schedules": [],
"climate_mode": "off",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Slaapkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 24.2
},
Expand All @@ -23,12 +25,14 @@
},
"13228dab8ce04617af318a2888b3c548": {
"active_preset": "home",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Woonkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 27.4
},
Expand Down Expand Up @@ -236,12 +240,14 @@
},
"d27aede973b54be484f6842d1b2802ad": {
"active_preset": "home",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Kinderkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 30.0
},
Expand Down Expand Up @@ -283,12 +289,14 @@
},
"d58fec52899f4f1c92e4f8fad6d8c48c": {
"active_preset": "home",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Logeerkamer",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 30.0
},
Expand Down
3 changes: 2 additions & 1 deletion fixtures/m_adam_multiple_devices_per_zone/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,14 @@
},
"446ac08dd04d4eff8ac57489757b7314": {
"active_preset": "no_frost",
"available_schedules": [],
"climate_mode": "heat",
"control_state": "idle",
"dev_class": "climate",
"model": "ThermoZone",
"name": "Garage",
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
"select_schedule": null,
"sensors": {
"temperature": 15.6
},
Expand Down Expand Up @@ -587,7 +589,6 @@
"warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."
}
},
"select_regulation_mode": "heating",
"sensors": {
"outdoor_temperature": 7.81
},
Expand Down
2 changes: 1 addition & 1 deletion plugwise/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ class GwEntityData(TypedDict, total=False):
preset_modes: list[str] | None
# Schedules:
available_schedules: list[str]
select_schedule: str
select_schedule: str | None

climate_mode: str
# Extra for Adam Master Thermostats
Expand Down
4 changes: 3 additions & 1 deletion plugwise/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,13 @@ def _climate_data(
data["active_preset"] = self._preset(loc_id)

# Schedule
data["available_schedules"] = []
data["select_schedule"] = None
self._count += 2
avail_schedules, sel_schedule = self._schedules(loc_id)
if avail_schedules != [NONE]:
data["available_schedules"] = avail_schedules
data["select_schedule"] = sel_schedule
self._count += 2

# Set HA climate HVACMode: auto, heat, heat_cool, cool and off
data["climate_mode"] = "auto"
Expand Down
17 changes: 10 additions & 7 deletions plugwise/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ def _appliance_measurements(
case "elga_status_code":
data["elga_status_code"] = int(appl_p_loc.text)
case "select_dhw_mode":
data["select_dhw_mode"] = appl_p_loc.text
if self._dhw_allowed_modes:
data["select_dhw_mode"] = appl_p_loc.text

common_match_cases(measurement, attrs, appl_p_loc, data)

Expand Down Expand Up @@ -522,7 +523,7 @@ def _get_actuator_mode(

Collect the requested gateway mode.
"""
if not (self.check_name(ADAM) and entity_id == self._gateway_id):
if not (entity_id == self._gateway_id and self.check_name(ADAM)):
return None

if (search := search_actuator_functionalities(appliance, key)) is not None:
Expand All @@ -535,29 +536,31 @@ def _get_regulation_mode(
) -> None:
"""Helper-function for _get_measurement_data().

Adam: collect the gateway regulation_mode.
Adam gateway: collect the gateway regulation_mode.
"""
if (
mode := self._get_actuator_mode(
appliance, entity_id, "regulation_mode_control_functionality"
)
) is not None:
data["select_regulation_mode"] = mode
self._count += 1
# Below line needs to be here to set the boolean for both older and recent Adam firmware versions
self._cooling_enabled = mode == "cooling"
if self._reg_allowed_modes:
data["select_regulation_mode"] = mode
self._count += 1

def _get_gateway_mode(
self, appliance: etree.Element, entity_id: str, data: GwEntityData
) -> None:
"""Helper-function for _get_measurement_data().

Adam: collect the gateway mode.
Adam gateway: collect the gateway mode.
"""
if (
mode := self._get_actuator_mode(
appliance, entity_id, "gateway_mode_control_functionality"
)
) is not None:
) is not None and self._gw_allowed_modes:
data["select_gateway_mode"] = mode
self._count += 1

Expand Down
4 changes: 3 additions & 1 deletion plugwise/legacy/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ def _climate_data(self, entity: GwEntityData, data: GwEntityData) -> None:
data["active_preset"] = self._preset()

# Schedule
data["available_schedules"] = []
data["select_schedule"] = None
self._count += 2
avail_schedules, sel_schedule = self._schedules()
if avail_schedules != [NONE]:
data["available_schedules"] = avail_schedules
data["select_schedule"] = sel_schedule
self._count += 2

# Set HA climate HVACMode: auto, heat
data["climate_mode"] = "auto"
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.7.8a1"
version = "1.7.8"
license = "MIT"
description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
readme = "README.md"
Expand Down
8 changes: 2 additions & 6 deletions scripts/manual_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,8 @@ def json_writer(manual_name: str, output: dict) -> None:
adam_multiple_devices_per_zone = base.copy()

# Change schedule to not present for "446ac08dd04d4eff8ac57489757b7314"
adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"].pop(
"available_schedules"
)
adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"].pop(
"select_schedule"
)
adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"]["available_schedules"] = []
adam_multiple_devices_per_zone["446ac08dd04d4eff8ac57489757b7314"]["select_schedule"] = None

json_writer("m_adam_multiple_devices_per_zone", adam_multiple_devices_per_zone)

Expand Down
1 change: 0 additions & 1 deletion tests/data/adam/adam_multiple_devices_per_zone.json
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,6 @@
"model": "Gateway",
"model_id": "smile_open_therm",
"name": "Adam",
"select_regulation_mode": "heating",
"sensors": {
"outdoor_temperature": 7.81
},
Expand Down
1 change: 0 additions & 1 deletion tests/data/adam/adam_plus_anna.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@
"model": "Gateway",
"model_id": "smile_open_therm",
"name": "Adam",
"select_regulation_mode": "heating",
"sensors": {
"outdoor_temperature": 11.9
},
Expand Down
1 change: 0 additions & 1 deletion tests/data/adam/adam_zone_per_device.json
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,6 @@
"model": "Gateway",
"model_id": "smile_open_therm",
"name": "Adam",
"select_regulation_mode": "heating",
"sensors": {
"outdoor_temperature": 7.69
},
Expand Down
8 changes: 4 additions & 4 deletions tests/test_adam.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ async def test_connect_adam_zone_per_device(self):
assert api._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE
assert api._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA
assert api._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA
assert self.entity_items == 370
assert self.entity_items == 369

assert "af82e4ccf9c548528166d38e560662a4" in self.notifications
await api.delete_notification()
Expand Down Expand Up @@ -295,7 +295,7 @@ async def test_connect_adam_multiple_devices_per_zone(self):
assert api._last_active["82fa13f017d240daa0d0ea1775420f24"] == CV_JESSIE
assert api._last_active["08963fec7c53423ca5680aa4cb502c63"] == BADKAMER_SCHEMA
assert api._last_active["446ac08dd04d4eff8ac57489757b7314"] == BADKAMER_SCHEMA
assert self.entity_items == 375
assert self.entity_items == 374

assert "af82e4ccf9c548528166d38e560662a4" in self.notifications

Expand Down Expand Up @@ -389,7 +389,7 @@ async def test_connect_adam_plus_anna(self):
await self.device_test(api, "2020-03-22 00:00:01", testdata)
assert api.gateway_id == "b128b4bbbd1f47e9bf4d756e8fb5ee94"
assert api._last_active["009490cc2f674ce6b576863fbb64f867"] == "Weekschema"
assert self.entity_items == 81
assert self.entity_items == 80
assert "6fb89e35caeb4b1cb275184895202d84" in self.notifications

result = await self.tinker_thermostat(
Expand Down Expand Up @@ -433,7 +433,7 @@ async def test_adam_plus_jip(self):
assert api._last_active["06aecb3d00354375924f50c47af36bd2"] is None
assert api._last_active["d27aede973b54be484f6842d1b2802ad"] is None
assert api._last_active["13228dab8ce04617af318a2888b3c548"] is None
assert self.entity_items == 245
assert self.entity_items == 253

# Negative test
result = await self.tinker_thermostat(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_legacy_anna.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async def test_connect_legacy_anna(self):

await self.device_test(api, "2020-03-22 00:00:01", testdata)
assert api.gateway_id == "0000aaaa0000aaaa0000aaaa0000aa00"
assert self.entity_items == 41
assert self.entity_items == 43
assert not api.reboot

result = await self.tinker_legacy_thermostat(api, schedule_on=False)
Expand Down
Loading