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
parent
a5c4508571
commit
50a87bbe18
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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/
|
||||||
|
|
Loading…
Reference in New Issue