mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 18:27:51 +00:00
Implemented tplink_lte components and notify service via SMS (#17111)
* Implemented tplink_lte components and notify service * Device discovery for the notify component * Improved the config schema. Small fixes * Improved login retry mechanism * Log successful connection only on retries * Removed CancelledError handlers and small fixes
This commit is contained in:
parent
922f34f72d
commit
1c3ef8be55
@ -333,6 +333,9 @@ omit =
|
|||||||
homeassistant/components/toon.py
|
homeassistant/components/toon.py
|
||||||
homeassistant/components/*/toon.py
|
homeassistant/components/*/toon.py
|
||||||
|
|
||||||
|
homeassistant/components/tplink_lte.py
|
||||||
|
homeassistant/components/*/tplink_lte.py
|
||||||
|
|
||||||
homeassistant/components/tradfri.py
|
homeassistant/components/tradfri.py
|
||||||
homeassistant/components/*/tradfri.py
|
homeassistant/components/*/tradfri.py
|
||||||
|
|
||||||
|
50
homeassistant/components/notify/tplink_lte.py
Normal file
50
homeassistant/components/notify/tplink_lte.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
"""TP-Link LTE platform for notify component.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/notify.tplink_lte/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import attr
|
||||||
|
|
||||||
|
from homeassistant.components.notify import (
|
||||||
|
ATTR_TARGET, BaseNotificationService)
|
||||||
|
|
||||||
|
from ..tplink_lte import DATA_KEY
|
||||||
|
|
||||||
|
DEPENDENCIES = ['tplink_lte']
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_get_service(hass, config, discovery_info=None):
|
||||||
|
"""Get the notification service."""
|
||||||
|
if discovery_info is None:
|
||||||
|
return
|
||||||
|
return TplinkNotifyService(hass, discovery_info)
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class TplinkNotifyService(BaseNotificationService):
|
||||||
|
"""Implementation of a notification service."""
|
||||||
|
|
||||||
|
hass = attr.ib()
|
||||||
|
config = attr.ib()
|
||||||
|
|
||||||
|
async def async_send_message(self, message="", **kwargs):
|
||||||
|
"""Send a message to a user."""
|
||||||
|
import tp_connected
|
||||||
|
modem_data = self.hass.data[DATA_KEY].get_modem_data(self.config)
|
||||||
|
if not modem_data:
|
||||||
|
_LOGGER.error("No modem available")
|
||||||
|
return
|
||||||
|
|
||||||
|
phone = self.config[ATTR_TARGET]
|
||||||
|
targets = kwargs.get(ATTR_TARGET, phone)
|
||||||
|
if targets and message:
|
||||||
|
for target in targets:
|
||||||
|
try:
|
||||||
|
await modem_data.modem.sms(target, message)
|
||||||
|
except tp_connected.Error:
|
||||||
|
_LOGGER.error("Unable to send to %s", target)
|
150
homeassistant/components/tplink_lte.py
Normal file
150
homeassistant/components/tplink_lte.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
"""
|
||||||
|
Support for TP-Link LTE modems.
|
||||||
|
|
||||||
|
For more details about this component, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/tplink_lte/
|
||||||
|
"""
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
import attr
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.notify import ATTR_TARGET
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_HOST, CONF_NAME, CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.helpers import config_validation as cv, discovery
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||||
|
|
||||||
|
REQUIREMENTS = ['tp-connected==0.0.4']
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
DOMAIN = 'tplink_lte'
|
||||||
|
DATA_KEY = 'tplink_lte'
|
||||||
|
|
||||||
|
CONF_NOTIFY = "notify"
|
||||||
|
|
||||||
|
_NOTIFY_SCHEMA = vol.All(vol.Schema({
|
||||||
|
vol.Optional(CONF_NAME): cv.string,
|
||||||
|
vol.Required(ATTR_TARGET): vol.All(cv.ensure_list, [cv.string]),
|
||||||
|
}))
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
|
DOMAIN: vol.All(cv.ensure_list, [vol.Schema({
|
||||||
|
vol.Required(CONF_HOST): cv.string,
|
||||||
|
vol.Required(CONF_PASSWORD): cv.string,
|
||||||
|
vol.Optional(CONF_NOTIFY):
|
||||||
|
vol.All(cv.ensure_list, [_NOTIFY_SCHEMA]),
|
||||||
|
})])
|
||||||
|
}, extra=vol.ALLOW_EXTRA)
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class ModemData:
|
||||||
|
"""Class for modem state."""
|
||||||
|
|
||||||
|
host = attr.ib()
|
||||||
|
modem = attr.ib()
|
||||||
|
|
||||||
|
connected = attr.ib(init=False, default=True)
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class LTEData:
|
||||||
|
"""Shared state."""
|
||||||
|
|
||||||
|
websession = attr.ib()
|
||||||
|
modem_data = attr.ib(init=False, factory=dict)
|
||||||
|
|
||||||
|
def get_modem_data(self, config):
|
||||||
|
"""Get the requested or the only modem_data value."""
|
||||||
|
if CONF_HOST in config:
|
||||||
|
return self.modem_data.get(config[CONF_HOST])
|
||||||
|
if len(self.modem_data) == 1:
|
||||||
|
return next(iter(self.modem_data.values()))
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass, config):
|
||||||
|
"""Set up TP-Link LTE component."""
|
||||||
|
if DATA_KEY not in hass.data:
|
||||||
|
websession = async_create_clientsession(
|
||||||
|
hass, cookie_jar=aiohttp.CookieJar(unsafe=True))
|
||||||
|
hass.data[DATA_KEY] = LTEData(websession)
|
||||||
|
|
||||||
|
domain_config = config.get(DOMAIN, [])
|
||||||
|
|
||||||
|
tasks = [_setup_lte(hass, conf) for conf in domain_config]
|
||||||
|
if tasks:
|
||||||
|
await asyncio.wait(tasks)
|
||||||
|
|
||||||
|
for conf in domain_config:
|
||||||
|
for notify_conf in conf.get(CONF_NOTIFY, []):
|
||||||
|
hass.async_create_task(discovery.async_load_platform(
|
||||||
|
hass, 'notify', DOMAIN, notify_conf, config))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def _setup_lte(hass, lte_config, delay=0):
|
||||||
|
"""Set up a TP-Link LTE modem."""
|
||||||
|
import tp_connected
|
||||||
|
|
||||||
|
host = lte_config[CONF_HOST]
|
||||||
|
password = lte_config[CONF_PASSWORD]
|
||||||
|
|
||||||
|
websession = hass.data[DATA_KEY].websession
|
||||||
|
modem = tp_connected.Modem(hostname=host, websession=websession)
|
||||||
|
|
||||||
|
modem_data = ModemData(host, modem)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await _login(hass, modem_data, password)
|
||||||
|
except tp_connected.Error:
|
||||||
|
retry_task = hass.loop.create_task(
|
||||||
|
_retry_login(hass, modem_data, password))
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def cleanup_retry(event):
|
||||||
|
"""Clean up retry task resources."""
|
||||||
|
if not retry_task.done():
|
||||||
|
retry_task.cancel()
|
||||||
|
|
||||||
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_retry)
|
||||||
|
|
||||||
|
|
||||||
|
async def _login(hass, modem_data, password):
|
||||||
|
"""Log in and complete setup."""
|
||||||
|
await modem_data.modem.login(password=password)
|
||||||
|
modem_data.connected = True
|
||||||
|
hass.data[DATA_KEY].modem_data[modem_data.host] = modem_data
|
||||||
|
|
||||||
|
async def cleanup(event):
|
||||||
|
"""Clean up resources."""
|
||||||
|
await modem_data.modem.logout()
|
||||||
|
|
||||||
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, cleanup)
|
||||||
|
|
||||||
|
|
||||||
|
async def _retry_login(hass, modem_data, password):
|
||||||
|
"""Sleep and retry setup."""
|
||||||
|
import tp_connected
|
||||||
|
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Could not connect to %s. Will keep trying.", modem_data.host)
|
||||||
|
|
||||||
|
modem_data.connected = False
|
||||||
|
delay = 15
|
||||||
|
|
||||||
|
while not modem_data.connected:
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await _login(hass, modem_data, password)
|
||||||
|
_LOGGER.warning("Connected to %s", modem_data.host)
|
||||||
|
except tp_connected.Error:
|
||||||
|
delay = min(2*delay, 300)
|
@ -1493,6 +1493,9 @@ toonlib==1.1.3
|
|||||||
# homeassistant.components.alarm_control_panel.totalconnect
|
# homeassistant.components.alarm_control_panel.totalconnect
|
||||||
total_connect_client==0.20
|
total_connect_client==0.20
|
||||||
|
|
||||||
|
# homeassistant.components.tplink_lte
|
||||||
|
tp-connected==0.0.4
|
||||||
|
|
||||||
# homeassistant.components.device_tracker.tplink
|
# homeassistant.components.device_tracker.tplink
|
||||||
tplink==0.2.1
|
tplink==0.2.1
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user