diff --git a/homeassistant/components/switchbee/__init__.py b/homeassistant/components/switchbee/__init__.py index 79b2e449a14..352f191588a 100644 --- a/homeassistant/components/switchbee/__init__.py +++ b/homeassistant/components/switchbee/__init__.py @@ -2,8 +2,8 @@ from __future__ import annotations +from switchbee.api import CentralUnitPolling, CentralUnitWsRPC, is_wsrpc_api from switchbee.api.central_unit import SwitchBeeError -from switchbee.api.polling import CentralUnitPolling from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, Platform @@ -25,17 +25,27 @@ PLATFORMS: list[Platform] = [ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up SwitchBee Smart Home from a config entry.""" + hass.data.setdefault(DOMAIN, {}) central_unit = entry.data[CONF_HOST] user = entry.data[CONF_USERNAME] password = entry.data[CONF_PASSWORD] websession = async_get_clientsession(hass, verify_ssl=False) - api = CentralUnitPolling(central_unit, user, password, websession) + api: CentralUnitPolling | CentralUnitWsRPC = CentralUnitPolling( + central_unit, user, password, websession + ) + + # First try to connect and fetch the version try: await api.connect() except SwitchBeeError as exp: raise ConfigEntryNotReady("Failed to connect to the Central Unit") from exp + # Check if websocket version + if is_wsrpc_api(api): + api = CentralUnitWsRPC(central_unit, user, password, websession) + await api.connect() + coordinator = SwitchBeeCoordinator( hass, api, diff --git a/homeassistant/components/switchbee/const.py b/homeassistant/components/switchbee/const.py index 12cc5e77a63..c7792dfe645 100644 --- a/homeassistant/components/switchbee/const.py +++ b/homeassistant/components/switchbee/const.py @@ -1,4 +1,6 @@ """Constants for the SwitchBee Smart Home integration.""" +from switchbee.api import CentralUnitPolling, CentralUnitWsRPC + DOMAIN = "switchbee" -SCAN_INTERVAL_SEC = 5 +SCAN_INTERVAL_SEC = {CentralUnitWsRPC: 10, CentralUnitPolling: 5} diff --git a/homeassistant/components/switchbee/coordinator.py b/homeassistant/components/switchbee/coordinator.py index e8453afdbb8..ad9e9669ac8 100644 --- a/homeassistant/components/switchbee/coordinator.py +++ b/homeassistant/components/switchbee/coordinator.py @@ -6,11 +6,11 @@ from collections.abc import Mapping from datetime import timedelta import logging +from switchbee.api import CentralUnitPolling, CentralUnitWsRPC from switchbee.api.central_unit import SwitchBeeError -from switchbee.api.polling import CentralUnitPolling from switchbee.device import DeviceType, SwitchBeeBaseDevice -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import format_mac from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -20,15 +20,15 @@ _LOGGER = logging.getLogger(__name__) class SwitchBeeCoordinator(DataUpdateCoordinator[Mapping[int, SwitchBeeBaseDevice]]): - """Class to manage fetching Freedompro data API.""" + """Class to manage fetching SwitchBee data API.""" def __init__( self, hass: HomeAssistant, - swb_api: CentralUnitPolling, + swb_api: CentralUnitPolling | CentralUnitWsRPC, ) -> None: """Initialize.""" - self.api: CentralUnitPolling = swb_api + self.api: CentralUnitPolling | CentralUnitWsRPC = swb_api self._reconnect_counts: int = 0 self.mac_formatted: str | None = ( None if self.api.mac is None else format_mac(self.api.mac) @@ -38,9 +38,20 @@ class SwitchBeeCoordinator(DataUpdateCoordinator[Mapping[int, SwitchBeeBaseDevic hass, _LOGGER, name=DOMAIN, - update_interval=timedelta(seconds=SCAN_INTERVAL_SEC), + update_interval=timedelta(seconds=SCAN_INTERVAL_SEC[type(self.api)]), ) + # Register callback for notification WsRPC + if isinstance(self.api, CentralUnitWsRPC): + self.api.subscribe_updates(self._async_handle_update) + + @callback + def _async_handle_update(self, push_data: dict) -> None: + """Manually update data and notify listeners.""" + assert isinstance(self.api, CentralUnitWsRPC) + _LOGGER.debug("Received update: %s", push_data) + self.async_set_updated_data(self.api.devices) + async def _async_update_data(self) -> Mapping[int, SwitchBeeBaseDevice]: """Update data via library.""" diff --git a/homeassistant/components/switchbee/manifest.json b/homeassistant/components/switchbee/manifest.json index 27201e45090..659034d77ec 100644 --- a/homeassistant/components/switchbee/manifest.json +++ b/homeassistant/components/switchbee/manifest.json @@ -3,7 +3,7 @@ "name": "SwitchBee", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/switchbee", - "requirements": ["pyswitchbee==1.7.3"], + "requirements": ["pyswitchbee==1.7.19"], "codeowners": ["@jafar-atili"], - "iot_class": "local_polling" + "iot_class": "local_push" } diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json index 4507aa969a3..fdc9d12ad00 100644 --- a/homeassistant/generated/integrations.json +++ b/homeassistant/generated/integrations.json @@ -5278,7 +5278,7 @@ "name": "SwitchBee", "integration_type": "hub", "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_push" }, "switchbot": { "name": "SwitchBot", diff --git a/requirements_all.txt b/requirements_all.txt index b920cb5dfb8..b7710d0c234 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1979,7 +1979,7 @@ pystiebeleltron==0.0.1.dev2 pysuez==0.1.19 # homeassistant.components.switchbee -pyswitchbee==1.7.3 +pyswitchbee==1.7.19 # homeassistant.components.syncthru pysyncthru==0.7.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index fb2469a8c67..4b1f191f9de 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1414,7 +1414,7 @@ pyspcwebgw==0.4.0 pysqueezebox==0.6.1 # homeassistant.components.switchbee -pyswitchbee==1.7.3 +pyswitchbee==1.7.19 # homeassistant.components.syncthru pysyncthru==0.7.10