Skip to content

Commit f469fb1

Browse files
authored
Merge pull request #750 from plugwise/impl-126896
Downstreaming Core PR #126896
2 parents 5131b30 + 8bcf0ae commit f469fb1

File tree

7 files changed

+42
-35
lines changed

7 files changed

+42
-35
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
## Versions from 0.40 and up
44

5-
## Ongoing
5+
## v0.54.1
66

7+
- Fix typing error
8+
- Downstream Core PR #126896
79
- Optimize test code, improve docstrings and add comments
810

911
## v0.54.0

custom_components/plugwise/climate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import Any
5+
from typing import Any, cast
66

77
from homeassistant.components.climate import (
88
ATTR_HVAC_MODE,
@@ -238,7 +238,7 @@ def hvac_action(self) -> HVACAction: # pw-beta add to Core
238238

239239
# Adam provides the hvac_action for each thermostat
240240
if (control_state := self.device.get(CONTROL_STATE)) in (HVACAction.COOLING, HVACAction.HEATING, HVACAction.PREHEATING):
241-
return control_state
241+
return cast(HVACAction, control_state)
242242
if control_state == HVACMode.OFF:
243243
return HVACAction.IDLE
244244

custom_components/plugwise/config_flow.py

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import Any
5+
from typing import Any, Self
66

77
from plugwise import Smile
88
from plugwise.exceptions import (
@@ -46,16 +46,13 @@
4646
ANNA_WITH_ADAM,
4747
CONF_HOMEKIT_EMULATION, # pw-beta option
4848
CONF_REFRESH_INTERVAL, # pw-beta option
49-
CONTEXT,
5049
DEFAULT_PORT,
5150
DEFAULT_SCAN_INTERVAL, # pw-beta option
5251
DEFAULT_USERNAME,
5352
DOMAIN,
54-
FLOW_ID,
5553
FLOW_SMILE,
5654
FLOW_STRETCH,
5755
INIT,
58-
PRODUCT,
5956
SMILE,
6057
SMILE_OPEN_THERM,
6158
SMILE_THERMO,
@@ -130,6 +127,7 @@ class PlugwiseConfigFlow(ConfigFlow, domain=DOMAIN):
130127
MINOR_VERSION = 1
131128

132129
discovery_info: ZeroconfServiceInfo | None = None
130+
product: str = "Unknown Smile"
133131
_username: str = DEFAULT_USERNAME
134132

135133
async def async_step_zeroconf(
@@ -138,8 +136,8 @@ async def async_step_zeroconf(
138136
"""Prepare configuration for a discovered Plugwise Smile."""
139137
self.discovery_info = discovery_info
140138
_properties = discovery_info.properties
141-
_product = _properties.get(PRODUCT, "Unknown Smile")
142139
_version = _properties.get(VERSION, "n/a")
140+
self.product = _product = _properties.get("product", "Unknown Smile")
143141
unique_id = discovery_info.hostname.split(".")[0].split("-")[0]
144142
if DEFAULT_USERNAME not in unique_id:
145143
self._username = STRETCH_USERNAME
@@ -173,36 +171,32 @@ async def async_step_zeroconf(
173171
# If we have discovered an Adam or Anna, both might be on the network.
174172
# In that case, we need to cancel the Anna flow, as the Adam should
175173
# be added.
176-
for flow in self._async_in_progress():
177-
# This is an Anna, and there is already an Adam flow in progress
178-
if (
179-
_product == SMILE_THERMO
180-
and CONTEXT in flow
181-
and flow[CONTEXT].get(PRODUCT) == SMILE_OPEN_THERM
182-
):
183-
return self.async_abort(reason=ANNA_WITH_ADAM)
184-
185-
# This is an Adam, and there is already an Anna flow in progress
186-
if (
187-
_product == SMILE_OPEN_THERM
188-
and CONTEXT in flow
189-
and flow[CONTEXT].get(PRODUCT) == SMILE_THERMO
190-
and FLOW_ID in flow
191-
):
192-
self.hass.config_entries.flow.async_abort(flow[FLOW_ID])
174+
if self.hass.config_entries.flow.async_has_matching_flow(self):
175+
return self.async_abort(reason="anna_with_adam")
193176

194177
_name = f"{ZEROCONF_MAP.get(_product, _product)} v{_version}"
195178
self.context.update(
196179
{
197180
TITLE_PLACEHOLDERS: {CONF_NAME: _name},
198181
ATTR_CONFIGURATION_URL: (
199182
f"http://{discovery_info.host}:{discovery_info.port}"
200-
),
201-
PRODUCT: _product,
183+
)
202184
}
203185
)
204186
return await self.async_step_user()
205187

188+
def is_matching(self, other_flow: Self) -> bool:
189+
"""Return True if other_flow is matching this flow."""
190+
# This is an Anna, and there is already an Adam flow in progress
191+
if self.product == SMILE_THERMO and other_flow.product == SMILE_OPEN_THERM:
192+
return True
193+
194+
# This is an Adam, and there is already an Anna flow in progress
195+
if self.product == SMILE_OPEN_THERM and other_flow.product == SMILE_THERMO:
196+
self.hass.config_entries.flow.async_abort(other_flow.flow_id)
197+
198+
return False
199+
206200
async def async_step_user(
207201
self, user_input: dict[str, Any] | None = None
208202
) -> ConfigFlowResult:

custom_components/plugwise/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
"iot_class": "local_polling",
99
"loggers": ["plugwise"],
1010
"requirements": ["plugwise==1.5.0"],
11-
"version": "0.54.0",
11+
"version": "0.54.1",
1212
"zeroconf": ["_plugwise._tcp.local."]
1313
}

hacs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
"sensor",
1010
"switch"
1111
],
12-
"homeassistant": "2024.8.0",
12+
"homeassistant": "2024.11.0",
1313
"render_readme": true
1414
}

tests/components/plugwise/test_config_flow.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ async def test_zeroconf_abort_anna_with_adam(hass: HomeAssistant) -> None:
254254
assert result.get("type") == FlowResultType.FORM
255255
assert result.get("step_id") == "user"
256256

257-
flows_in_progress = hass.config_entries.flow.async_progress()
257+
flows_in_progress = hass.config_entries.flow._handler_progress_index[DOMAIN]
258258
assert len(flows_in_progress) == 1
259-
assert flows_in_progress[0]["context"]["product"] == "smile_thermo"
259+
assert list(flows_in_progress)[0].product == "smile_thermo"
260260

261261
# Discover Adam, Anna should be aborted and no longer present
262262
result2 = await hass.config_entries.flow.async_init(
@@ -268,9 +268,9 @@ async def test_zeroconf_abort_anna_with_adam(hass: HomeAssistant) -> None:
268268
assert result2.get("type") == FlowResultType.FORM
269269
assert result2.get("step_id") == "user"
270270

271-
flows_in_progress = hass.config_entries.flow.async_progress()
271+
flows_in_progress = hass.config_entries.flow._handler_progress_index[DOMAIN]
272272
assert len(flows_in_progress) == 1
273-
assert flows_in_progress[0]["context"]["product"] == "smile_open_therm"
273+
assert list(flows_in_progress)[0].product == "smile_open_therm"
274274

275275
# Discover Anna again, Anna should be aborted directly
276276
result3 = await hass.config_entries.flow.async_init(
@@ -282,9 +282,9 @@ async def test_zeroconf_abort_anna_with_adam(hass: HomeAssistant) -> None:
282282
assert result3.get("reason") == "anna_with_adam"
283283

284284
# Adam should still be there
285-
flows_in_progress = hass.config_entries.flow.async_progress()
285+
flows_in_progress = hass.config_entries.flow._handler_progress_index[DOMAIN]
286286
assert len(flows_in_progress) == 1
287-
assert flows_in_progress[0]["context"]["product"] == "smile_open_therm"
287+
assert list(flows_in_progress)[0].product == "smile_open_therm"
288288

289289

290290
async def test_zercoconf_discovery_update_configuration(

tests/ruff.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This extend our general Ruff rules specifically for tests
2+
extend = "../pyproject.toml"
3+
4+
[lint]
5+
6+
extend-ignore = [
7+
"B904", # Use raise from to specify exception cause
8+
"N815", # Variable {name} in class scope should not be mixedCase
9+
"RUF018", # Avoid assignment expressions in assert statements
10+
"SLF001", # Private member accessed: Tests do often test internals a lot
11+
]

0 commit comments

Comments
 (0)