diff --git a/.coveragerc b/.coveragerc index fd314287f87..d1fc86e1010 100644 --- a/.coveragerc +++ b/.coveragerc @@ -740,7 +740,7 @@ omit = homeassistant/components/simplisafe/lock.py homeassistant/components/simulated/sensor.py homeassistant/components/sisyphus/* - homeassistant/components/sky_hub/device_tracker.py + homeassistant/components/sky_hub/* homeassistant/components/skybeacon/sensor.py homeassistant/components/skybell/* homeassistant/components/slack/notify.py diff --git a/CODEOWNERS b/CODEOWNERS index 711398ae455..58e31bd3858 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -364,6 +364,7 @@ homeassistant/components/signal_messenger/* @bbernhard homeassistant/components/simplisafe/* @bachya homeassistant/components/sinch/* @bendikrb homeassistant/components/sisyphus/* @jkeljo +homeassistant/components/sky_hub/* @rogerselwyn homeassistant/components/slide/* @ualex73 homeassistant/components/sma/* @kellerza homeassistant/components/smappee/* @bsmappee diff --git a/homeassistant/components/sky_hub/__init__.py b/homeassistant/components/sky_hub/__init__.py index a5b8969018f..9c875507c09 100644 --- a/homeassistant/components/sky_hub/__init__.py +++ b/homeassistant/components/sky_hub/__init__.py @@ -1 +1,6 @@ """The sky_hub component.""" + + +async def async_setup(hass, config): + """Set up the sky_hub component.""" + return True diff --git a/homeassistant/components/sky_hub/device_tracker.py b/homeassistant/components/sky_hub/device_tracker.py index 2537196f21d..b97331b6195 100644 --- a/homeassistant/components/sky_hub/device_tracker.py +++ b/homeassistant/components/sky_hub/device_tracker.py @@ -1,8 +1,7 @@ """Support for Sky Hub.""" import logging -import re -import requests +from pyskyqhub.skyq_hub import SkyQHub import voluptuous as vol from homeassistant.components.device_tracker import ( @@ -10,102 +9,54 @@ from homeassistant.components.device_tracker import ( PLATFORM_SCHEMA, DeviceScanner, ) -from homeassistant.const import CONF_HOST, HTTP_OK +from homeassistant.const import CONF_HOST +from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) -_MAC_REGEX = re.compile(r"(([0-9A-Fa-f]{1,2}\:){5}[0-9A-Fa-f]{1,2})") PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({vol.Optional(CONF_HOST): cv.string}) -def get_scanner(hass, config): +async def async_get_scanner(hass, config): """Return a Sky Hub scanner if successful.""" - scanner = SkyHubDeviceScanner(config[DOMAIN]) + host = config[DOMAIN].get(CONF_HOST, "192.168.1.254") + websession = async_get_clientsession(hass) + hub = SkyQHub(websession, host) - return scanner if scanner.success_init else None + _LOGGER.debug("Initialising Sky Hub") + await hub.async_connect() + if hub.success_init: + scanner = SkyHubDeviceScanner(hub) + return scanner + + return None class SkyHubDeviceScanner(DeviceScanner): """This class queries a Sky Hub router.""" - def __init__(self, config): + def __init__(self, hub): """Initialise the scanner.""" - _LOGGER.info("Initialising Sky Hub") - self.host = config.get(CONF_HOST, "192.168.1.254") + self._hub = hub self.last_results = {} - self.url = f"http://{self.host}/" - # Test the router is accessible - data = _get_skyhub_data(self.url) - self.success_init = data is not None - - def scan_devices(self): + async def async_scan_devices(self): """Scan for new devices and return a list with found device IDs.""" - self._update_info() - - return (device for device in self.last_results) - - def get_device_name(self, device): - """Return the name of the given device or None if we don't know.""" - # If not initialised and not already scanned and not found. - if device not in self.last_results: - self._update_info() - - if not self.last_results: - return None + await self._async_update_info() + return list(self.last_results) + async def async_get_device_name(self, device): + """Return the name of the given device.""" return self.last_results.get(device) - def _update_info(self): - """Ensure the information from the Sky Hub is up to date. + async def _async_update_info(self): + """Ensure the information from the Sky Hub is up to date.""" + _LOGGER.debug("Scanning") - Return boolean if scanning successful. - """ - if not self.success_init: - return False - - _LOGGER.info("Scanning") - - data = _get_skyhub_data(self.url) + data = await self._hub.async_get_skyhub_data() if not data: - _LOGGER.warning("Error scanning devices") - return False + return self.last_results = data - - return True - - -def _get_skyhub_data(url): - """Retrieve data from Sky Hub and return parsed result.""" - try: - response = requests.get(url, timeout=5) - except requests.exceptions.Timeout: - _LOGGER.exception("Connection to the router timed out") - return - if response.status_code == HTTP_OK: - return _parse_skyhub_response(response.text) - _LOGGER.error("Invalid response from Sky Hub: %s", response) - - -def _parse_skyhub_response(data_str): - """Parse the Sky Hub data format.""" - pattmatch = re.search("attach_dev = '(.*)'", data_str) - if pattmatch is None: - raise OSError( - "Error: Impossible to fetch data from Sky Hub. Try to reboot the router." - ) - patt = pattmatch.group(1) - - dev = [patt1.split(",") for patt1 in patt.split("")] - - devices = {} - for dvc in dev: - if _MAC_REGEX.match(dvc[1]): - devices[dvc[1]] = dvc[0] - else: - raise RuntimeError(f"Error: MAC address {dvc[1]} not in correct format.") - - return devices diff --git a/homeassistant/components/sky_hub/manifest.json b/homeassistant/components/sky_hub/manifest.json index b358fa76fbf..da9197899e7 100644 --- a/homeassistant/components/sky_hub/manifest.json +++ b/homeassistant/components/sky_hub/manifest.json @@ -2,5 +2,6 @@ "domain": "sky_hub", "name": "Sky Hub", "documentation": "https://www.home-assistant.io/integrations/sky_hub", - "codeowners": [] + "requirements": ["pyskyqhub==0.1.0"], + "codeowners": ["@rogerselwyn"] } diff --git a/requirements_all.txt b/requirements_all.txt index d4ac79183d0..28cb701ec65 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1607,6 +1607,9 @@ pysher==1.0.1 # homeassistant.components.signal_messenger pysignalclirestapi==0.3.4 +# homeassistant.components.sky_hub +pyskyqhub==0.1.0 + # homeassistant.components.sma pysma==0.3.5