Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Versions from 0.40 and up

## Ongoing

- Implement Core PR [#159626](https://github.com/home-assistant/core/pull/159626) via PR [#994](https://github.com/plugwise/plugwise-beta/pull/994)

## v0.62.2

- Bump plugwise to [v1.11.2](https://github.com/plugwise/python-plugwise/releases/tag/v1.11.2)
Expand Down
7 changes: 5 additions & 2 deletions custom_components/plugwise/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@
CONF_HOMEKIT_EMULATION, # pw-beta option
CONF_REFRESH_INTERVAL, # pw-beta option
DEFAULT_PORT,
DEFAULT_SCAN_INTERVAL, # pw-beta option
DEFAULT_UPDATE_INTERVAL,
DEFAULT_USERNAME,
DOMAIN,
FLOW_SMILE,
FLOW_STRETCH,
INIT,
P1_UPDATE_INTERVAL,
SMILE,
SMILE_OPEN_THERM,
SMILE_THERMO,
Expand Down Expand Up @@ -317,7 +318,9 @@ def __init__(self, config_entry: ConfigEntry) -> None:
self.options = deepcopy(dict(config_entry.options))

def _create_options_schema(self, coordinator: PlugwiseDataUpdateCoordinator) -> vol.Schema:
interval = DEFAULT_SCAN_INTERVAL[coordinator.api.smile.type] # pw-beta options
interval = DEFAULT_UPDATE_INTERVAL
if coordinator.api.smile.type == "power":
interval = P1_UPDATE_INTERVAL
schema = {
vol.Optional(
CONF_SCAN_INTERVAL,
Expand Down
7 changes: 2 additions & 5 deletions custom_components/plugwise/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,10 @@

# Default directives
DEFAULT_PORT: Final[int] = 80
DEFAULT_SCAN_INTERVAL: Final[dict[str, timedelta]] = {
"power": timedelta(seconds=10),
"stretch": timedelta(seconds=60),
"thermostat": timedelta(seconds=60),
}
DEFAULT_TIMEOUT: Final[int] = 30
DEFAULT_UPDATE_INTERVAL: Final = timedelta(seconds=60)
DEFAULT_USERNAME: Final = "smile"
P1_UPDATE_INTERVAL: Final = timedelta(seconds=10)

# --- Const for Plugwise Smile and Stretch
PLATFORMS: Final[list[str]] = [
Expand Down
18 changes: 11 additions & 7 deletions custom_components/plugwise/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from packaging.version import Version

from .const import DEFAULT_SCAN_INTERVAL, DEV_CLASS, DOMAIN, LOGGER, SWITCH_GROUPS
from .const import (
DEFAULT_UPDATE_INTERVAL,
DEV_CLASS,
DOMAIN,
LOGGER,
P1_UPDATE_INTERVAL,
SWITCH_GROUPS,
)

type PlugwiseConfigEntry = ConfigEntry[PlugwiseDataUpdateCoordinator]

Expand All @@ -49,7 +56,6 @@ def __init__(
hass: HomeAssistant,
cooldown: float,
config_entry: PlugwiseConfigEntry,
update_interval: timedelta = timedelta(seconds=60),
) -> None: # pw-beta cooldown
"""Initialize the coordinator."""
super().__init__(
Expand All @@ -59,7 +65,7 @@ def __init__(
name=DOMAIN,
# Core directly updates from const's DEFAULT_SCAN_INTERVAL
# Upstream check correct progress for adjusting
update_interval=update_interval,
update_interval=DEFAULT_UPDATE_INTERVAL,
# Don't refresh immediately, give the device time to process
# the change in state before we query it.
request_refresh_debouncer=Debouncer(
Expand All @@ -80,7 +86,6 @@ def __init__(
self._current_devices = set()
self._stored_devices = set()
self.new_devices = set()
self.update_interval = update_interval

async def _connect(self) -> None:
"""Connect to the Plugwise Smile.
Expand All @@ -90,9 +95,8 @@ async def _connect(self) -> None:
version = await self.api.connect()
self._connected = isinstance(version, Version)
if self._connected:
self.update_interval = DEFAULT_SCAN_INTERVAL.get(
self.api.smile.type, timedelta(seconds=60)
) # pw-beta options scan-interval
if self.api.smile.type == "power":
self.update_interval = P1_UPDATE_INTERVAL
if (custom_time := self.config_entry.options.get(CONF_SCAN_INTERVAL)) is not None:
self.update_interval = timedelta(
seconds=int(custom_time)
Expand Down
59 changes: 55 additions & 4 deletions tests/components/plugwise/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
import pytest

from freezegun.api import FrozenDateTimeFactory
from homeassistant.components.plugwise.const import DOMAIN
from homeassistant.components.plugwise.const import (
DEFAULT_UPDATE_INTERVAL,
DOMAIN,
P1_UPDATE_INTERVAL,
)
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import (
CONF_HOST,
Expand All @@ -27,7 +31,6 @@
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.setup import async_setup_component

from tests.common import MockConfigEntry, async_fire_time_changed

Expand Down Expand Up @@ -154,7 +157,7 @@ async def test_device_in_dr(
) -> None:
"""Test Gateway device registry data."""
mock_config_entry.add_to_hass(hass)
assert await async_setup_component(hass, DOMAIN, {})
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()

device_entry = device_registry.async_get_device(
Expand Down Expand Up @@ -279,7 +282,7 @@ async def test_update_device(
data = mock_smile_adam_heat_cool.async_update.return_value

mock_config_entry.add_to_hass(hass)
assert await async_setup_component(hass, DOMAIN, {})
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()

assert (
Expand Down Expand Up @@ -375,6 +378,54 @@ async def test_delete_removed_device(
assert "14df5c4dc8cb4ba69f9d1ac0eaf7c5c6" not in item_list


@pytest.mark.parametrize("chosen_env", ["m_adam_heating"], indirect=True)
@pytest.mark.parametrize("cooling_present", [False], indirect=True)
async def test_update_interval_adam(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_smile_adam_heat_cool: MagicMock,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test Adam update interval."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()

assert mock_config_entry.state is ConfigEntryState.LOADED
assert mock_smile_adam_heat_cool.async_update.call_count == 1

freezer.tick(DEFAULT_UPDATE_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()

assert mock_smile_adam_heat_cool.async_update.call_count == 2


@pytest.mark.parametrize("chosen_env", ["p1v4_442_single"], indirect=True)
@pytest.mark.parametrize(
"gateway_id", ["a455b61e52394b2db5081ce025a430f3"], indirect=True
)
async def test_update_interval_p1(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_smile_p1: MagicMock,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test Smile P1 update interval."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()

assert mock_config_entry.state is ConfigEntryState.LOADED
assert mock_smile_p1.async_update.call_count == 1

freezer.tick(P1_UPDATE_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()

assert mock_smile_p1.async_update.call_count == 2


#### pw-beta only ####
@pytest.mark.parametrize("chosen_env", ["m_anna_heatpump_cooling"], indirect=True)
@pytest.mark.parametrize("cooling_present", [True], indirect=True)
Expand Down
Loading