Add Huawei LTE integration suspend and resume services (#30207)

Useful e.g. if accessing the router web interface from another source
such as a web browser is temporarily required.
pull/30213/head
Ville Skyttä 2019-12-25 13:43:51 +02:00 committed by Martin Hjelmare
parent a5c4508571
commit 50a87bbe18
4 changed files with 68 additions and 10 deletions

View File

@ -52,6 +52,7 @@ from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import HomeAssistantType from homeassistant.helpers.typing import HomeAssistantType
from .const import ( from .const import (
ADMIN_SERVICES,
ALL_KEYS, ALL_KEYS,
CONNECTION_TIMEOUT, CONNECTION_TIMEOUT,
DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_NAME,
@ -66,6 +67,8 @@ from .const import (
KEY_WLAN_HOST_LIST, KEY_WLAN_HOST_LIST,
SERVICE_CLEAR_TRAFFIC_STATISTICS, SERVICE_CLEAR_TRAFFIC_STATISTICS,
SERVICE_REBOOT, SERVICE_REBOOT,
SERVICE_RESUME_INTEGRATION,
SERVICE_SUSPEND_INTEGRATION,
UPDATE_OPTIONS_SIGNAL, UPDATE_OPTIONS_SIGNAL,
UPDATE_SIGNAL, UPDATE_SIGNAL,
) )
@ -137,6 +140,7 @@ class Router:
) )
unload_handlers: List[CALLBACK_TYPE] = attr.ib(init=False, factory=list) unload_handlers: List[CALLBACK_TYPE] = attr.ib(init=False, factory=list)
client: Client client: Client
suspended = attr.ib(init=False, default=False)
def __attrs_post_init__(self): def __attrs_post_init__(self):
"""Set up internal state on init.""" """Set up internal state on init."""
@ -191,6 +195,10 @@ class Router:
def update(self) -> None: def update(self) -> None:
"""Update router data.""" """Update router data."""
if self.suspended:
_LOGGER.debug("Integration suspended, not updating data")
return
self._get_data(KEY_DEVICE_INFORMATION, self.client.device.information) self._get_data(KEY_DEVICE_INFORMATION, self.client.device.information)
if self.data.get(KEY_DEVICE_INFORMATION): if self.data.get(KEY_DEVICE_INFORMATION):
# Full information includes everything in basic # Full information includes everything in basic
@ -210,15 +218,8 @@ class Router:
self.signal_update() self.signal_update()
def cleanup(self, *_) -> None: def logout(self) -> None:
"""Clean up resources.""" """Log out router session."""
self.subscriptions.clear()
for handler in self.unload_handlers:
handler()
self.unload_handlers.clear()
if not isinstance(self.connection, AuthorizedConnection): if not isinstance(self.connection, AuthorizedConnection):
return return
try: try:
@ -230,6 +231,17 @@ class Router:
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
_LOGGER.warning("Logout error", exc_info=True) _LOGGER.warning("Logout error", exc_info=True)
def cleanup(self, *_) -> None:
"""Clean up resources."""
self.subscriptions.clear()
for handler in self.unload_handlers:
handler()
self.unload_handlers.clear()
self.logout()
@attr.s @attr.s
class HuaweiLteData: class HuaweiLteData:
@ -441,15 +453,29 @@ async def async_setup(hass: HomeAssistantType, config) -> bool:
return return
if service.service == SERVICE_CLEAR_TRAFFIC_STATISTICS: if service.service == SERVICE_CLEAR_TRAFFIC_STATISTICS:
if router.suspended:
_LOGGER.debug("%s: ignored, integration suspended", service.service)
return
result = router.client.monitoring.set_clear_traffic() result = router.client.monitoring.set_clear_traffic()
_LOGGER.debug("%s: %s", service.service, result) _LOGGER.debug("%s: %s", service.service, result)
elif service.service == SERVICE_REBOOT: elif service.service == SERVICE_REBOOT:
if router.suspended:
_LOGGER.debug("%s: ignored, integration suspended", service.service)
return
result = router.client.device.reboot() result = router.client.device.reboot()
_LOGGER.debug("%s: %s", service.service, result) _LOGGER.debug("%s: %s", service.service, result)
elif service.service == SERVICE_RESUME_INTEGRATION:
# Login will be handled automatically on demand
router.suspended = False
_LOGGER.debug("%s: %s", service.service, "done")
elif service.service == SERVICE_SUSPEND_INTEGRATION:
router.logout()
router.suspended = True
_LOGGER.debug("%s: %s", service.service, "done")
else: else:
_LOGGER.error("%s: unsupported service", service.service) _LOGGER.error("%s: unsupported service", service.service)
for service in (SERVICE_CLEAR_TRAFFIC_STATISTICS, SERVICE_REBOOT): for service in ADMIN_SERVICES:
hass.helpers.service.async_register_admin_service( hass.helpers.service.async_register_admin_service(
DOMAIN, service, service_handler, schema=SERVICE_SCHEMA, DOMAIN, service, service_handler, schema=SERVICE_SCHEMA,
) )

View File

@ -15,6 +15,15 @@ CONNECTION_TIMEOUT = 10
SERVICE_CLEAR_TRAFFIC_STATISTICS = "clear_traffic_statistics" SERVICE_CLEAR_TRAFFIC_STATISTICS = "clear_traffic_statistics"
SERVICE_REBOOT = "reboot" SERVICE_REBOOT = "reboot"
SERVICE_RESUME_INTEGRATION = "resume_integration"
SERVICE_SUSPEND_INTEGRATION = "suspend_integration"
ADMIN_SERVICES = {
SERVICE_CLEAR_TRAFFIC_STATISTICS,
SERVICE_REBOOT,
SERVICE_RESUME_INTEGRATION,
SERVICE_SUSPEND_INTEGRATION,
}
KEY_DEVICE_BASIC_INFORMATION = "device_basic_information" KEY_DEVICE_BASIC_INFORMATION = "device_basic_information"
KEY_DEVICE_INFORMATION = "device_information" KEY_DEVICE_INFORMATION = "device_information"

View File

@ -44,6 +44,12 @@ class HuaweiLteSmsNotificationService(BaseNotificationService):
if not targets or not message: if not targets or not message:
return return
if self.router.suspended:
_LOGGER.debug(
"Integration suspended, not sending notification to %s", targets
)
return
try: try:
resp = self.router.client.sms.send_sms( resp = self.router.client.sms.send_sms(
phone_numbers=targets, message=message phone_numbers=targets, message=message

View File

@ -11,3 +11,20 @@ reboot:
url: url:
description: URL of router to reboot; optional when only one is configured. description: URL of router to reboot; optional when only one is configured.
example: http://192.168.100.1/ example: http://192.168.100.1/
resume_integration:
description: Resume suspended integration.
fields:
url:
description: URL of router to resume integration for; optional when only one is configured.
example: http://192.168.100.1/
suspend_integration:
description: >
Suspend integration. Suspending logs the integration out from the router, and stops accessing it.
Useful e.g. if accessing the router web interface from another source such as a web browser is temporarily required.
Invoke the resume_integration service to resume.
fields:
url:
description: URL of router to resume integration for; optional when only one is configured.
example: http://192.168.100.1/