Add Huawei LTE mobile data switch support (#28188)

* Add Huawei LTE mobile data switch support

* Remove stale comment

* Do HA state updates in base entity
This commit is contained in:
Ville Skyttä 2019-10-26 13:29:36 +03:00 committed by GitHub
parent 7096826d1d
commit 2baee4ac3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 119 additions and 4 deletions

View File

@ -23,6 +23,7 @@ from url_normalize import url_normalize
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.config_entries import ConfigEntry, SOURCE_IMPORT from homeassistant.config_entries import ConfigEntry, SOURCE_IMPORT
from homeassistant.const import ( from homeassistant.const import (
CONF_PASSWORD, CONF_PASSWORD,
@ -48,6 +49,7 @@ from .const import (
KEY_DEVICE_BASIC_INFORMATION, KEY_DEVICE_BASIC_INFORMATION,
KEY_DEVICE_INFORMATION, KEY_DEVICE_INFORMATION,
KEY_DEVICE_SIGNAL, KEY_DEVICE_SIGNAL,
KEY_DIALUP_MOBILE_DATASWITCH,
KEY_MONITORING_TRAFFIC_STATISTICS, KEY_MONITORING_TRAFFIC_STATISTICS,
KEY_WLAN_HOST_LIST, KEY_WLAN_HOST_LIST,
UPDATE_OPTIONS_SIGNAL, UPDATE_OPTIONS_SIGNAL,
@ -158,6 +160,7 @@ class Router:
self.subscriptions.pop(KEY_DEVICE_BASIC_INFORMATION, None) self.subscriptions.pop(KEY_DEVICE_BASIC_INFORMATION, None)
get_data(KEY_DEVICE_BASIC_INFORMATION, self.client.device.basic_information) get_data(KEY_DEVICE_BASIC_INFORMATION, self.client.device.basic_information)
get_data(KEY_DEVICE_SIGNAL, self.client.device.signal) get_data(KEY_DEVICE_SIGNAL, self.client.device.signal)
get_data(KEY_DIALUP_MOBILE_DATASWITCH, self.client.dial_up.mobile_dataswitch)
get_data( get_data(
KEY_MONITORING_TRAFFIC_STATISTICS, self.client.monitoring.traffic_statistics KEY_MONITORING_TRAFFIC_STATISTICS, self.client.monitoring.traffic_statistics
) )
@ -273,7 +276,7 @@ async def async_setup_entry(hass: HomeAssistantType, config_entry: ConfigEntry)
router.subscriptions.clear() router.subscriptions.clear()
# Forward config entry setup to platforms # Forward config entry setup to platforms
for domain in (DEVICE_TRACKER_DOMAIN, SENSOR_DOMAIN): for domain in (DEVICE_TRACKER_DOMAIN, SENSOR_DOMAIN, SWITCH_DOMAIN):
hass.async_create_task( hass.async_create_task(
hass.config_entries.async_forward_entry_setup(config_entry, domain) hass.config_entries.async_forward_entry_setup(config_entry, domain)
) )
@ -316,7 +319,7 @@ async def async_unload_entry(
"""Unload config entry.""" """Unload config entry."""
# Forward config entry unload to platforms # Forward config entry unload to platforms
for domain in (DEVICE_TRACKER_DOMAIN, SENSOR_DOMAIN): for domain in (DEVICE_TRACKER_DOMAIN, SENSOR_DOMAIN, SWITCH_DOMAIN):
await hass.config_entries.async_forward_entry_unload(config_entry, domain) await hass.config_entries.async_forward_entry_unload(config_entry, domain)
# Forget about the router and invoke its cleanup # Forget about the router and invoke its cleanup
@ -419,7 +422,7 @@ class HuaweiLteBaseEntity(Entity):
async def _async_maybe_update(self, url: str) -> None: async def _async_maybe_update(self, url: str) -> None:
"""Update state if the update signal comes from our router.""" """Update state if the update signal comes from our router."""
if url == self.router.url: if url == self.router.url:
await self.async_update() self.async_schedule_update_ha_state(True)
async def _async_maybe_update_options(self, config_entry: ConfigEntry) -> None: async def _async_maybe_update_options(self, config_entry: ConfigEntry) -> None:
"""Update options if the update signal comes from our router.""" """Update options if the update signal comes from our router."""

View File

@ -13,6 +13,7 @@ UNIT_SECONDS = "s"
KEY_DEVICE_BASIC_INFORMATION = "device_basic_information" KEY_DEVICE_BASIC_INFORMATION = "device_basic_information"
KEY_DEVICE_INFORMATION = "device_information" KEY_DEVICE_INFORMATION = "device_information"
KEY_DEVICE_SIGNAL = "device_signal" KEY_DEVICE_SIGNAL = "device_signal"
KEY_DIALUP_MOBILE_DATASWITCH = "dialup_mobile_dataswitch"
KEY_MONITORING_TRAFFIC_STATISTICS = "monitoring_traffic_statistics" KEY_MONITORING_TRAFFIC_STATISTICS = "monitoring_traffic_statistics"
KEY_WLAN_HOST_LIST = "wlan_host_list" KEY_WLAN_HOST_LIST = "wlan_host_list"
@ -24,4 +25,6 @@ SENSOR_KEYS = {
KEY_MONITORING_TRAFFIC_STATISTICS, KEY_MONITORING_TRAFFIC_STATISTICS,
} }
ALL_KEYS = DEVICE_TRACKER_KEYS | SENSOR_KEYS SWITCH_KEYS = {KEY_DIALUP_MOBILE_DATASWITCH}
ALL_KEYS = DEVICE_TRACKER_KEYS | SENSOR_KEYS | SWITCH_KEYS

View File

@ -0,0 +1,109 @@
"""Support for Huawei LTE switches."""
import logging
from typing import Optional
import attr
from homeassistant.components.switch import (
DEVICE_CLASS_SWITCH,
DOMAIN as SWITCH_DOMAIN,
SwitchDevice,
)
from homeassistant.const import CONF_URL
from . import HuaweiLteBaseEntity
from .const import DOMAIN, KEY_DIALUP_MOBILE_DATASWITCH
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up from config entry."""
router = hass.data[DOMAIN].routers[config_entry.data[CONF_URL]]
switches = []
if router.data.get(KEY_DIALUP_MOBILE_DATASWITCH):
switches.append(HuaweiLteMobileDataSwitch(router))
async_add_entities(switches, True)
@attr.s
class HuaweiLteBaseSwitch(HuaweiLteBaseEntity, SwitchDevice):
"""Huawei LTE switch device base class."""
key: str
item: str
_raw_state: Optional[str] = attr.ib(init=False, default=None)
def _turn(self, state: bool) -> None:
raise NotImplementedError
def turn_on(self, **kwargs):
"""Turn switch on."""
self._turn(state=True)
def turn_off(self, **kwargs):
"""Turn switch off."""
self._turn(state=False)
@property
def device_class(self):
"""Return device class."""
return DEVICE_CLASS_SWITCH
async def async_added_to_hass(self):
"""Subscribe to needed data on add."""
await super().async_added_to_hass()
self.router.subscriptions[self.key].add(f"{SWITCH_DOMAIN}/{self.item}")
async def async_will_remove_from_hass(self):
"""Unsubscribe from needed data on remove."""
await super().async_will_remove_from_hass()
self.router.subscriptions[self.key].remove(f"{SWITCH_DOMAIN}/{self.item}")
async def async_update(self):
"""Update state."""
try:
value = self.router.data[self.key][self.item]
except KeyError:
_LOGGER.debug("%s[%s] not in data", self.key, self.item)
self._available = False
return
self._available = True
self._raw_state = str(value)
@attr.s
class HuaweiLteMobileDataSwitch(HuaweiLteBaseSwitch):
"""Huawei LTE mobile data switch device."""
def __attrs_post_init__(self):
"""Initialize identifiers."""
self.key = KEY_DIALUP_MOBILE_DATASWITCH
self.item = "dataswitch"
@property
def _entity_name(self) -> str:
return "Mobile data"
@property
def _device_unique_id(self) -> str:
return f"{self.key}.{self.item}"
@property
def is_on(self) -> bool:
"""Return whether the switch is on."""
return self._raw_state == "1"
def _turn(self, state: bool) -> None:
value = 1 if state else 0
self.router.client.dial_up.set_mobile_dataswitch(dataswitch=value)
self._raw_state = str(value)
self.schedule_update_ha_state()
@property
def icon(self):
"""Return switch icon."""
return "mdi:signal" if self.is_on else "mdi:signal-off"