From 86bec750f9477ec0c4a060b6756693849ca7db46 Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Wed, 11 Oct 2023 19:32:49 +0200 Subject: [PATCH] Fix switches and buttons --- custom_components/speedport/__init__.py | 10 +- custom_components/speedport/button.py | 17 ++++ custom_components/speedport/config_flow.py | 33 +------ custom_components/speedport/device_tracker.py | 2 + custom_components/speedport/switch.py | 93 +++++++++++-------- .../speedport/translations/en.json | 3 +- 6 files changed, 88 insertions(+), 70 deletions(-) diff --git a/custom_components/speedport/__init__.py b/custom_components/speedport/__init__.py index 5856633..8df9377 100644 --- a/custom_components/speedport/__init__.py +++ b/custom_components/speedport/__init__.py @@ -3,6 +3,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant +from homeassistant.helpers import aiohttp_client from speedport import Speedport from .const import DOMAIN @@ -12,10 +13,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Speedport from a config entry.""" + session = aiohttp_client.async_get_clientsession(hass) hass.data.setdefault(DOMAIN, {}) - speedport = Speedport(entry.data["host"]) - await speedport.login(entry.data["password"]) + speedport = await Speedport( + host=entry.data["host"], password=entry.data["password"], session=session + ).create() hass.data[DOMAIN][entry.entry_id] = speedport for platform in PLATFORMS: @@ -28,6 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - hass.data[DOMAIN].pop(entry.entry_id) + speedport = hass.data[DOMAIN].pop(entry.entry_id) + await speedport.close() return unload_ok diff --git a/custom_components/speedport/button.py b/custom_components/speedport/button.py index ef75439..14b1d76 100644 --- a/custom_components/speedport/button.py +++ b/custom_components/speedport/button.py @@ -5,6 +5,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback +from speedport import Speedport from .const import DOMAIN @@ -19,6 +20,7 @@ async def async_setup_entry( [ SpeedportReconnectButton(coordinator), SpeedportRebootButton(coordinator), + SpeedportWPSButton(coordinator), ] ) @@ -51,3 +53,18 @@ def __init__(self, coordinator) -> None: async def async_press(self) -> None: """Send out a restart command.""" await self.coordinator.reboot() + + +class SpeedportWPSButton(ButtonEntity): + _attr_device_class = ButtonDeviceClass.IDENTIFY + _attr_entity_category = EntityCategory.CONFIG + _attr_name = "WPS on" + + def __init__(self, coordinator) -> None: + """Initialize the button entity.""" + self.coordinator: Speedport = coordinator + self._attr_unique_id = "speedport_wps" + + async def async_press(self) -> None: + """Send out a restart command.""" + await self.coordinator.wps_on() diff --git a/custom_components/speedport/config_flow.py b/custom_components/speedport/config_flow.py index 0d6ab58..9294383 100644 --- a/custom_components/speedport/config_flow.py +++ b/custom_components/speedport/config_flow.py @@ -16,44 +16,21 @@ _LOGGER = logging.getLogger(__name__) -# TODO adjust the data schema to the data that you need STEP_USER_DATA_SCHEMA = vol.Schema( { vol.Required("host", default="speedport.ip"): str, vol.Required("password"): str, + vol.Optional("https", default=False): bool, } ) -class PlaceholderHub: - """Placeholder class to make tests pass. - - TODO Remove this placeholder class and replace with things from your PyPI package. - """ - - def __init__(self, host: str) -> None: - """Initialize.""" - self.host = host - - async def authenticate(self, username: str, password: str) -> bool: - """Test if we can authenticate with the host.""" - return True - - async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, Any]: - """Validate the user input allows us to connect. - - Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user. - """ - # TODO validate the data can be used to set up a connection. - - # If your PyPI package is not built with async, pass your methods - # to the executor: - # await hass.async_add_executor_job( - # your_validate_func, data["username"], data["password"] - # ) + """Validate the user input allows us to connect.""" - speedport = Speedport(data["host"]) + speedport = await Speedport( + host=data["host"], password=data["password"], https=data["https"] + ).create() if not await speedport.login(data["password"]): raise InvalidAuth diff --git a/custom_components/speedport/device_tracker.py b/custom_components/speedport/device_tracker.py index 19d722b..9e917f2 100644 --- a/custom_components/speedport/device_tracker.py +++ b/custom_components/speedport/device_tracker.py @@ -51,6 +51,8 @@ def __init__(self, coordinator: SpeedportCoordinator, mac: str) -> None: super().__init__(coordinator) self._mac = mac self._device: WlanDevice = self.coordinator.data.get(mac) + self._attr_entity_registry_enabled_default = True + self._attr_entity_registry_visible_default = True @property def source_type(self) -> SourceType: diff --git a/custom_components/speedport/switch.py b/custom_components/speedport/switch.py index d3264b8..3e81804 100644 --- a/custom_components/speedport/switch.py +++ b/custom_components/speedport/switch.py @@ -3,10 +3,11 @@ import logging from typing import Any -from homeassistant.components.switch import SwitchEntity +from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback +from speedport import Speedport from .const import DOMAIN @@ -18,59 +19,75 @@ async def async_setup_entry( ) -> None: """Set up entry.""" - speedport = hass.data[DOMAIN][entry.entry_id] - async_add_entities([SpeedportWifiSwitch(speedport)]) + speedport: Speedport = hass.data[DOMAIN][entry.entry_id] + await speedport.update_status() + async_add_entities( + [ + SpeedportWifiSwitch(speedport), + SpeedportGuestWifiSwitch(speedport), + SpeedportOfficeWifiSwitch(speedport), + ] + ) class SpeedportWifiSwitch(SwitchEntity): _attr_is_on: bool | None = False - def __init__(self, speedport) -> None: - self._description = "Wi-Fi" - self._friendly_name = "Wi-Fi" - self._icon = "mdi:wifi" - self._type = "WiFiNetwork" + def __init__(self, speedport: Speedport) -> None: + self._speedport: Speedport = speedport + self._attr_icon = "mdi:wifi" + self._attr_name = speedport.wlan_ssid + self._attr_unique_id = "wifi" - self._name = f"{self._friendly_name} {self._description}" - self._unique_id = self._description + async def is_on(self) -> bool | None: + return self._speedport.wlan_active - self._is_available = True - self._speedport = speedport + async def async_turn_on(self, **kwargs: Any) -> None: + """Turn on switch.""" + await self._speedport.wifi_on() - @property - def name(self) -> str: - """Return name.""" - return self._name + async def async_turn_off(self, **kwargs: Any) -> None: + """Turn off switch.""" + await self._speedport.wifi_off() - @property - def icon(self) -> str: - """Return name.""" - return self._icon - @property - def unique_id(self) -> str: - """Return unique id.""" - return self._unique_id +class SpeedportGuestWifiSwitch(SwitchEntity): + _attr_is_on: bool | None = False - @property - def available(self) -> bool: - """Return availability.""" - return True + def __init__(self, speedport: Speedport) -> None: + self._speedport: Speedport = speedport + self._attr_icon = "mdi:wifi" + self._attr_name = speedport.wlan_guest_ssid + self._attr_unique_id = "wifi_guest" - async def async_update(self) -> None: - """Update data.""" - _LOGGER.debug("Updating '%s' (%s) switch state", self.name, self._type) - # await self._update() + async def is_on(self) -> bool | None: + return self._speedport.wlan_guest_active async def async_turn_on(self, **kwargs: Any) -> None: """Turn on switch.""" - await self._speedport.wifi_on() + await self._speedport.wifi_guest_on() async def async_turn_off(self, **kwargs: Any) -> None: """Turn off switch.""" - await self._speedport.wifi_off() + await self._speedport.wifi_guest_off() + - async def _async_handle_turn_on_off(self, turn_on: bool) -> None: - """Handle switch state change request.""" - # await self._switch(turn_on) - self._attr_is_on = turn_on +class SpeedportOfficeWifiSwitch(SwitchEntity): + _attr_is_on: bool | None = False + + def __init__(self, speedport: Speedport) -> None: + self._speedport: Speedport = speedport + self._attr_icon = "mdi:wifi" + self._attr_name = speedport.wlan_office_ssid + self._attr_unique_id = "wifi_office" + + async def is_on(self) -> bool | None: + return self._speedport.wlan_office_ssid + + async def async_turn_on(self, **kwargs: Any) -> None: + """Turn on switch.""" + await self._speedport.wifi_office_on() + + async def async_turn_off(self, **kwargs: Any) -> None: + """Turn off switch.""" + await self._speedport.wifi_office_off() diff --git a/custom_components/speedport/translations/en.json b/custom_components/speedport/translations/en.json index f9334da..e32d9b8 100644 --- a/custom_components/speedport/translations/en.json +++ b/custom_components/speedport/translations/en.json @@ -12,7 +12,8 @@ "user": { "data": { "host": "Host", - "password": "Password" + "password": "Password", + "https": "Use https connection" } } }