Make scan interval user configurable

This commit is contained in:
Laurence Presland 2024-04-16 21:39:34 +10:00
parent 8c61537d9a
commit e256c35bb7
5 changed files with 39 additions and 18 deletions

View file

@ -41,10 +41,11 @@ def prepare_device(
api: SwitchBotAPI, api: SwitchBotAPI,
device: Device | Remote, device: Device | Remote,
coordinators_by_id: dict[str, SwitchBotCoordinator], coordinators_by_id: dict[str, SwitchBotCoordinator],
config: ConfigEntry,
) -> tuple[Device | Remote, SwitchBotCoordinator]: ) -> tuple[Device | Remote, SwitchBotCoordinator]:
"""Instantiate coordinator and adds to list for gathering.""" """Instantiate coordinator and adds to list for gathering."""
coordinator = coordinators_by_id.setdefault( coordinator = coordinators_by_id.setdefault(
device.device_id, SwitchBotCoordinator(hass, api, device) device.device_id, SwitchBotCoordinator(hass, api, device, config)
) )
return (device, coordinator) return (device, coordinator)
@ -55,6 +56,7 @@ def make_device_data(
api: SwitchBotAPI, api: SwitchBotAPI,
devices: list[Device | Remote], devices: list[Device | Remote],
coordinators_by_id: dict[str, SwitchBotCoordinator], coordinators_by_id: dict[str, SwitchBotCoordinator],
config: ConfigEntry,
) -> SwitchbotDevices: ) -> SwitchbotDevices:
"""Make device data.""" """Make device data."""
devices_data = SwitchbotDevices() devices_data = SwitchbotDevices()
@ -63,7 +65,7 @@ def make_device_data(
"Air Conditioner" "Air Conditioner"
): ):
devices_data.climates.append( devices_data.climates.append(
prepare_device(hass, api, device, coordinators_by_id) prepare_device(hass, api, device, coordinators_by_id, config)
) )
if ( if (
isinstance(device, Device) isinstance(device, Device)
@ -71,11 +73,11 @@ def make_device_data(
or isinstance(device, Remote) or isinstance(device, Remote)
): ):
devices_data.switches.append( devices_data.switches.append(
prepare_device(hass, api, device, coordinators_by_id) prepare_device(hass, api, device, coordinators_by_id, config)
) )
if isinstance(device, Device) and device.device_type == "MeterPlus": if isinstance(device, Device) and device.device_type == "MeterPlus":
devices_data.sensors.append( devices_data.sensors.append(
prepare_device(hass, api, device, coordinators_by_id) prepare_device(hass, api, device, coordinators_by_id, config)
) )
return devices_data return devices_data
@ -99,7 +101,8 @@ async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
coordinators_by_id: dict[str, SwitchBotCoordinator] = {} coordinators_by_id: dict[str, SwitchBotCoordinator] = {}
hass.data.setdefault(DOMAIN, {}) hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][config.entry_id] = SwitchbotCloudData( hass.data[DOMAIN][config.entry_id] = SwitchbotCloudData(
api=api, devices=make_device_data(hass, api, devices, coordinators_by_id) api=api,
devices=make_device_data(hass, api, devices, coordinators_by_id, config),
) )
await hass.config_entries.async_forward_entry_setups(config, PLATFORMS) await hass.config_entries.async_forward_entry_setups(config, PLATFORMS)
await gather( await gather(

View file

@ -7,9 +7,10 @@ from switchbot_api import CannotConnect, InvalidAuth, SwitchBotAPI
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_API_KEY, CONF_API_TOKEN from homeassistant.const import CONF_API_KEY, CONF_API_TOKEN, CONF_SCAN_INTERVAL
from homeassistant.helpers import config_validation as cv
from .const import DOMAIN, ENTRY_TITLE from .const import DEFAULT_SCAN_INTERVAL_SECONDS, DOMAIN, ENTRY_TITLE
_LOGGER = getLogger(__name__) _LOGGER = getLogger(__name__)
@ -17,6 +18,9 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
{ {
vol.Required(CONF_API_TOKEN): str, vol.Required(CONF_API_TOKEN): str,
vol.Required(CONF_API_KEY): str, vol.Required(CONF_API_KEY): str,
vol.Required(
CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL_SECONDS
): cv.positive_int,
} }
) )
@ -25,6 +29,7 @@ class SwitchBotCloudConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for SwitchBot via API.""" """Handle a config flow for SwitchBot via API."""
VERSION = 1 VERSION = 1
MINOR_VERSION = 2
async def async_step_user( async def async_step_user(
self, user_input: dict[str, Any] | None = None self, user_input: dict[str, Any] | None = None
@ -51,5 +56,7 @@ class SwitchBotCloudConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_create_entry(title=ENTRY_TITLE, data=user_input) return self.async_create_entry(title=ENTRY_TITLE, data=user_input)
return self.async_show_form( return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors step_id="user",
data_schema=STEP_USER_DATA_SCHEMA,
errors=errors,
) )

View file

@ -1,13 +1,12 @@
"""Constants for the SwitchBot Cloud integration.""" """Constants for the SwitchBot Cloud integration."""
from datetime import timedelta
from typing import Final from typing import Final
DOMAIN: Final = "switchbot_cloud" DOMAIN: Final = "switchbot_cloud"
ENTRY_TITLE = "SwitchBot Cloud" ENTRY_TITLE = "SwitchBot Cloud"
DEFAULT_SCAN_INTERVAL = timedelta(seconds=600)
DEVICE_SCAN_INTERVAL = {"MeterPlus": timedelta(seconds=60)}
SENSOR_KIND_TEMPERATURE = 'temperature' DEFAULT_SCAN_INTERVAL_SECONDS = 600
SENSOR_KIND_HUMIDITY = 'humidity'
SENSOR_KIND_BATTERY = 'battery' SENSOR_KIND_TEMPERATURE = "temperature"
SENSOR_KIND_HUMIDITY = "humidity"
SENSOR_KIND_BATTERY = "battery"

View file

@ -1,15 +1,18 @@
"""SwitchBot Cloud coordinator.""" """SwitchBot Cloud coordinator."""
from asyncio import timeout from asyncio import timeout
from datetime import timedelta
from logging import getLogger from logging import getLogger
from typing import Any from typing import Any
from switchbot_api import CannotConnect, Device, Remote, SwitchBotAPI from switchbot_api import CannotConnect, Device, Remote, SwitchBotAPI
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_SCAN_INTERVAL
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DEFAULT_SCAN_INTERVAL, DEVICE_SCAN_INTERVAL, DOMAIN from .const import DEFAULT_SCAN_INTERVAL_SECONDS, DOMAIN
_LOGGER = getLogger(__name__) _LOGGER = getLogger(__name__)
@ -23,14 +26,22 @@ class SwitchBotCoordinator(DataUpdateCoordinator[Status]):
_device_id: str _device_id: str
def __init__( def __init__(
self, hass: HomeAssistant, api: SwitchBotAPI, device: Device | Remote self,
hass: HomeAssistant,
api: SwitchBotAPI,
device: Device | Remote,
config: ConfigEntry,
) -> None: ) -> None:
"""Initialize SwitchBot Cloud.""" """Initialize SwitchBot Cloud."""
super().__init__( super().__init__(
hass, hass,
_LOGGER, _LOGGER,
name=DOMAIN, name=DOMAIN,
update_interval=DEVICE_SCAN_INTERVAL.get(device.device_type, DEFAULT_SCAN_INTERVAL), update_interval=timedelta(
seconds=config.data.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL_SECONDS
)
),
) )
self._api = api self._api = api
self._device_id = device.device_id self._device_id = device.device_id

View file

@ -4,7 +4,8 @@
"user": { "user": {
"data": { "data": {
"api_token": "[%key:common::config_flow::data::api_token%]", "api_token": "[%key:common::config_flow::data::api_token%]",
"api_key": "[%key:common::config_flow::data::api_key%]" "api_key": "[%key:common::config_flow::data::api_key%]",
"scan_interval": "Scan interval (seconds)"
} }
} }
}, },