Skip to content

Commit 5326437

Browse files
authored
Merge pull request #759 from plugwise/pw-1.5.0
Make timeout an internal backend parameter.
2 parents 8f0134a + 183bd97 commit 5326437

File tree

9 files changed

+38
-93
lines changed

9 files changed

+38
-93
lines changed

CHANGELOG.md

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

33
## Versions from 0.40 and up
44

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

7-
- Link to plugwise [v1.4.4](https://github.com/plugwise/python-plugwise/releases/tag/v1.4.4) and adapt.
7+
- Link to plugwise [v1.5.0](https://github.com/plugwise/python-plugwise/releases/tag/v1.5.0) and adapt:
8+
- Remove the connection-timeout function added in v0.53.3, not accepted in Core
9+
- Remove the need to pass a connection-timeout value to the backend library, as suggested by a Core dev
10+
- Link to plugwise [v1.4.4](https://github.com/plugwise/python-plugwise/releases/tag/v1.4.4) and adapt
811
- Fix coordinator connection-method: don't use defaults
912

1013
## v0.53.5

custom_components/plugwise/__init__.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
SERVICE_DELETE, # pw-beta delete_notifications
2525
)
2626
from .coordinator import PlugwiseDataUpdateCoordinator
27-
from .util import get_timeout_for_version
2827

2928
type PlugwiseConfigEntry = ConfigEntry[PlugwiseDataUpdateCoordinator]
3029

@@ -46,7 +45,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: PlugwiseConfigEntry) ->
4645
await coordinator.async_config_entry_first_refresh()
4746

4847
await async_migrate_sensor_entities(hass, coordinator)
49-
await async_migrate_plugwise_entry(hass, coordinator, entry)
5048

5149
entry.runtime_data = coordinator
5250

@@ -146,23 +144,23 @@ async def async_migrate_sensor_entities(
146144
# Upstream remove LOGGER debug
147145
ent_reg.async_update_entity(entity_id, new_unique_id=new_unique_id)
148146

149-
async def async_migrate_plugwise_entry(
150-
hass: HomeAssistant,
151-
coordinator: PlugwiseDataUpdateCoordinator,
152-
entry: ConfigEntry
153-
) -> bool:
154-
"""Migrate to new config entry."""
155-
if entry.version == 1 and entry.minor_version < 2:
147+
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
148+
"""Migrate back to v1.1 config entry."""
149+
if entry.version > 1:
150+
# This means the user has downgraded from a future version
151+
return False
152+
153+
if entry.version == 1 and entry.minor_version == 2:
156154
new_data = {**entry.data}
157-
new_data[CONF_TIMEOUT] = get_timeout_for_version(str(coordinator.api.smile_version))
155+
new_data.pop(CONF_TIMEOUT)
158156
hass.config_entries.async_update_entry(
159-
entry, data=new_data, minor_version=2, version=1
157+
entry, data=new_data, minor_version=1, version=1
160158
)
161-
LOGGER.debug(
162-
"Migration to version %s.%s successful",
163-
entry.version,
164-
entry.minor_version,
165-
)
166-
return True
167159

168-
return False
160+
LOGGER.debug(
161+
"Migration to version %s.%s successful",
162+
entry.version,
163+
entry.minor_version,
164+
)
165+
166+
return True

custom_components/plugwise/config_flow.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
CONF_PASSWORD,
3535
CONF_PORT,
3636
CONF_SCAN_INTERVAL,
37-
CONF_TIMEOUT,
3837
CONF_USERNAME,
3938
)
4039

@@ -50,7 +49,6 @@
5049
CONTEXT,
5150
DEFAULT_PORT,
5251
DEFAULT_SCAN_INTERVAL, # pw-beta option
53-
DEFAULT_TIMEOUT,
5452
DEFAULT_USERNAME,
5553
DOMAIN,
5654
FLOW_ID,
@@ -71,7 +69,6 @@
7169

7270
# Upstream
7371
from .coordinator import PlugwiseDataUpdateCoordinator
74-
from .util import get_timeout_for_version
7572

7673
type PlugwiseConfigEntry = ConfigEntry[PlugwiseDataUpdateCoordinator]
7774

@@ -119,7 +116,6 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> Smile:
119116
host=data[CONF_HOST],
120117
password=data[CONF_PASSWORD],
121118
port=data[CONF_PORT],
122-
timeout=data[CONF_TIMEOUT],
123119
username=data[CONF_USERNAME],
124120
websession=websession,
125121
)
@@ -131,10 +127,9 @@ class PlugwiseConfigFlow(ConfigFlow, domain=DOMAIN):
131127
"""Handle a config flow for Plugwise Smile."""
132128

133129
VERSION = 1
134-
MINOR_VERSION = 2
130+
MINOR_VERSION = 1
135131

136132
discovery_info: ZeroconfServiceInfo | None = None
137-
_timeout: int = DEFAULT_TIMEOUT
138133
_username: str = DEFAULT_USERNAME
139134

140135
async def async_step_zeroconf(
@@ -145,7 +140,6 @@ async def async_step_zeroconf(
145140
_properties = discovery_info.properties
146141
_product = _properties.get(PRODUCT, "Unknown Smile")
147142
_version = _properties.get(VERSION, "n/a")
148-
self._timeout = get_timeout_for_version(_version)
149143
unique_id = discovery_info.hostname.split(".")[0].split("-")[0]
150144
if DEFAULT_USERNAME not in unique_id:
151145
self._username = STRETCH_USERNAME
@@ -158,7 +152,6 @@ async def async_step_zeroconf(
158152
CONF_HOST: discovery_info.host,
159153
CONF_PASSWORD: config_entry.data[CONF_PASSWORD],
160154
CONF_PORT: discovery_info.port,
161-
CONF_TIMEOUT: self._timeout,
162155
CONF_USERNAME: config_entry.data[CONF_USERNAME],
163156
},
164157
)
@@ -228,8 +221,6 @@ async def async_step_user(
228221
user_input[CONF_PORT] = self.discovery_info.port
229222
user_input[CONF_USERNAME] = self._username
230223

231-
# Ensure a timeout-value is available, required for validation
232-
user_input[CONF_TIMEOUT] = self._timeout
233224
try:
234225
api = await validate_input(self.hass, user_input)
235226
except ConnectionFailedError:

custom_components/plugwise/coordinator.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
CONF_PASSWORD,
1919
CONF_PORT,
2020
CONF_SCAN_INTERVAL, # pw-beta options
21-
CONF_TIMEOUT,
2221
CONF_USERNAME,
2322
)
2423
from homeassistant.core import HomeAssistant
@@ -29,7 +28,7 @@
2928
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
3029
from packaging.version import Version
3130

32-
from .const import DEFAULT_SCAN_INTERVAL, DEFAULT_TIMEOUT, DOMAIN, GATEWAY_ID, LOGGER
31+
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN, GATEWAY_ID, LOGGER
3332

3433

3534
class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[PlugwiseData]):
@@ -67,8 +66,6 @@ def __init__(
6766
host=self.config_entry.data[CONF_HOST],
6867
password=self.config_entry.data[CONF_PASSWORD],
6968
port=self.config_entry.data[CONF_PORT],
70-
# Needs to stay .get() for config_entry migration-testing:
71-
timeout=self.config_entry.data.get(CONF_TIMEOUT, DEFAULT_TIMEOUT),
7269
username=self.config_entry.data[CONF_USERNAME],
7370
websession=async_get_clientsession(hass, verify_ssl=False),
7471
)

custom_components/plugwise/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"integration_type": "hub",
88
"iot_class": "local_polling",
99
"loggers": ["plugwise"],
10-
"requirements": ["plugwise==1.4.4"],
11-
"version": "0.53.5",
10+
"requirements": ["plugwise==1.5.0"],
11+
"version": "0.54.0",
1212
"zeroconf": ["_plugwise._tcp.local."]
1313
}

custom_components/plugwise/util.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
from plugwise.exceptions import PlugwiseException
99

1010
from homeassistant.exceptions import HomeAssistantError
11-
from packaging import version
1211

13-
from .const import DEFAULT_TIMEOUT
1412
from .entity import PlugwiseEntity
1513

1614
# For reference:
@@ -19,17 +17,6 @@
1917
# _P = ParamSpec("_P")
2018

2119

22-
def get_timeout_for_version(version_str: str) -> int:
23-
"""Determine timeout value based on gateway version.
24-
25-
A gateway firmware version > 3.2.0 should mean a latest-generation-device, allowing for a timeout of 10s.
26-
Legacy devices require a timeout of 30s.
27-
"""
28-
if version.parse(version_str) >= version.parse("3.2.0"):
29-
return 10
30-
return DEFAULT_TIMEOUT
31-
32-
3320
def plugwise_command[_PlugwiseEntityT: PlugwiseEntity, **_P, _R](
3421
func: Callable[Concatenate[_PlugwiseEntityT, _P], Awaitable[_R]],
3522
) -> Callable[Concatenate[_PlugwiseEntityT, _P], Coroutine[Any, Any, _R]]:

tests/components/plugwise/snapshots/test_init.ambr

Lines changed: 0 additions & 27 deletions
This file was deleted.

tests/components/plugwise/test_config_flow.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@
4242
TEST_HOSTNAME2 = "stretchabc"
4343
TEST_PASSWORD = "test_password"
4444
TEST_PORT = 81
45-
TEST_TIMEOUT_LEGACY = 30
46-
TEST_TIMEOUT = 10
4745
TEST_USERNAME = "smile"
4846
TEST_USERNAME2 = "stretch"
4947
TEST_DISCOVERY = zeroconf.ZeroconfServiceInfo(
@@ -146,26 +144,25 @@ async def test_form(
146144
CONF_PASSWORD: TEST_PASSWORD,
147145
CONF_PORT: DEFAULT_PORT,
148146
CONF_USERNAME: TEST_USERNAME,
149-
CONF_TIMEOUT: TEST_TIMEOUT_LEGACY,
150147
}
151148

152149
assert len(mock_setup_entry.mock_calls) == 1
153150
assert len(mock_smile_config_flow.connect.mock_calls) == 1
154151

155152

156153
@pytest.mark.parametrize(
157-
("discovery", "parameters",),
154+
("discovery", "username",),
158155
[
159-
(TEST_DISCOVERY, (TEST_USERNAME, TEST_TIMEOUT)),
160-
(TEST_DISCOVERY2, (TEST_USERNAME2, TEST_TIMEOUT_LEGACY)),
156+
(TEST_DISCOVERY, TEST_USERNAME),
157+
(TEST_DISCOVERY2, TEST_USERNAME2),
161158
],
162159
)
163160
async def test_zeroconf_form(
164161
hass: HomeAssistant,
165162
mock_setup_entry: AsyncMock,
166163
mock_smile_config_flow: MagicMock,
167164
discovery: ZeroconfServiceInfo,
168-
parameters: tuple[str, str],
165+
username: str,
169166
) -> None:
170167
"""Test config flow for Smile devices."""
171168
result = await hass.config_entries.flow.async_init(
@@ -186,13 +183,11 @@ async def test_zeroconf_form(
186183

187184
assert result2.get("type") == FlowResultType.CREATE_ENTRY
188185
assert result2.get("title") == "Test Smile Name"
189-
username, timeout = parameters
190186
assert result2.get("data") == {
191187
CONF_HOST: TEST_HOST,
192188
CONF_PASSWORD: TEST_PASSWORD,
193189
CONF_PORT: DEFAULT_PORT,
194190
CONF_USERNAME: username,
195-
CONF_TIMEOUT: timeout,
196191
}
197192

198193
assert len(mock_setup_entry.mock_calls) == 1
@@ -228,7 +223,6 @@ async def test_zeroconf_stretch_form(
228223
CONF_PASSWORD: TEST_PASSWORD,
229224
CONF_PORT: DEFAULT_PORT,
230225
CONF_USERNAME: TEST_USERNAME2,
231-
CONF_TIMEOUT: TEST_TIMEOUT_LEGACY,
232226
}
233227

234228
assert len(mock_setup_entry.mock_calls) == 1
@@ -390,7 +384,6 @@ async def test_flow_errors(
390384
CONF_PASSWORD: TEST_PASSWORD,
391385
CONF_PORT: DEFAULT_PORT,
392386
CONF_USERNAME: TEST_USERNAME,
393-
CONF_TIMEOUT: TEST_TIMEOUT_LEGACY,
394387
}
395388

396389
assert len(mock_setup_entry.mock_calls) == 1
@@ -432,7 +425,7 @@ async def test_options_flow_thermo(
432425
data={
433426
CONF_HOST: TEST_HOST,
434427
CONF_PASSWORD: TEST_PASSWORD,
435-
CONF_TIMEOUT: TEST_TIMEOUT,
428+
CONF_TIMEOUT: 30,
436429
},
437430
minor_version=2,
438431
options={

tests/components/plugwise/test_init.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
CONF_MAC,
2222
CONF_PASSWORD,
2323
CONF_PORT,
24+
CONF_TIMEOUT,
2425
CONF_USERNAME,
2526
Platform,
2627
)
@@ -241,29 +242,31 @@ async def test_entry_migration(
241242
hass: HomeAssistant,
242243
mock_smile_anna_2: MagicMock,
243244
snapshot: SnapshotAssertion) -> None:
244-
"""Test config entry version 1 -> 2 migration."""
245+
"""Test config entry version 2 -> 1 migration."""
245246
entry = MockConfigEntry(
246247
domain=DOMAIN,
247248
data={
248249
CONF_HOST: "127.0.0.1",
249250
CONF_MAC: "AA:BB:CC:DD:EE:FF",
250251
CONF_PASSWORD: "test-password",
251252
CONF_PORT: 80,
253+
CONF_TIMEOUT: 30,
252254
CONF_USERNAME: "smile",
253255
},
254-
minor_version=1,
256+
minor_version=2,
255257
version=1,
256258
unique_id="smile98765",
257259
)
258260

259261
entry.runtime_data = MagicMock(api=mock_smile_anna_2)
260262
entry.add_to_hass(hass)
261-
262263
await hass.config_entries.async_setup(entry.entry_id)
263264
await hass.async_block_till_done()
264265

265-
# Assert that the migrated entry matches the expected structure
266-
assert hass.config_entries.async_get_entry(entry.entry_id) == snapshot
266+
assert entry.version == 1
267+
assert entry.minor_version == 1
268+
assert entry.data.get(CONF_TIMEOUT) is None
269+
assert entry.state is ConfigEntryState.LOADED
267270

268271

269272
async def test_update_device(

0 commit comments

Comments
 (0)