From 390bcb1bed9c7f211e1ec230fa168fc4c2517b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 19 Jan 2020 18:17:56 +0100 Subject: [PATCH 01/15] Add salt component --- homeassistant/components/salt/__init__.py | 1 + .../components/salt/device_tracker.py | 83 +++++++++++++++++++ homeassistant/components/salt/manifest.json | 11 +++ 3 files changed, 95 insertions(+) create mode 100644 homeassistant/components/salt/__init__.py create mode 100644 homeassistant/components/salt/device_tracker.py create mode 100644 homeassistant/components/salt/manifest.json diff --git a/homeassistant/components/salt/__init__.py b/homeassistant/components/salt/__init__.py new file mode 100644 index 00000000000000..29c371ece5222f --- /dev/null +++ b/homeassistant/components/salt/__init__.py @@ -0,0 +1 @@ +"""The salt component.""" diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py new file mode 100644 index 00000000000000..16803eff07fa9a --- /dev/null +++ b/homeassistant/components/salt/device_tracker.py @@ -0,0 +1,83 @@ +"""Support for Salt Fiber Box routers.""" +import logging + +from saltbox import SaltBox +import voluptuous as vol + +from homeassistant.components.device_tracker import ( + DOMAIN, + PLATFORM_SCHEMA, + DeviceScanner, +) +from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME +import homeassistant.helpers.config_validation as cv + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_IP = "192.168.1.1" +DEFAULT_USERNAME = "admin" + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( + { + vol.Optional(CONF_HOST, default=DEFAULT_IP): cv.string, + vol.Optional(CONF_USERNAME, default=DEFAULT_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + } +) + + +def get_scanner(hass, config): + """Return the Salt device scanner.""" + scanner = SaltDeviceScanner(config[DOMAIN]) + return scanner if scanner.success_init else None + + +class SaltDeviceScanner(DeviceScanner): + """This class queries a Salt Fiber Box router.""" + + def __init__(self, config): + """Initialize the scanner.""" + host = config[CONF_HOST] + username = config[CONF_USERNAME] + password = config[CONF_PASSWORD] + self.saltbox = SaltBox(f"http://{host}", username, password) + self.online_clients = [] + + # Test the router is accessible. + data = self.get_salt_data() + self.success_init = data is not None + + def scan_devices(self): + """Scan for new devices and return a list with found device IDs.""" + self._update_info() + return [client["mac"] for client in self.online_clients] + + def get_device_name(self, device): + """Return the name of the given device or None if we don't know.""" + if not self.online_clients: + return None + for client in self.online_clients: + if client["mac"] == device: + return client["name"] + return None + + def _update_info(self): + """Pull the current information from the Salt router.""" + if not self.success_init: + return False + + _LOGGER.info("Loading data from Salt Fiber Box") + data = self.get_salt_data() + if not data: + return False + + self.online_clients = data + return True + + def get_salt_data(self): + """Retrieve data from Salt router and return parsed result.""" + try: + return self.saltbox.get_online_clients() + except: # noqa: E722 # pylint: disable=bare-except + _LOGGER.info("Could not get data from Salt Fiber Box") + return self.online_clients diff --git a/homeassistant/components/salt/manifest.json b/homeassistant/components/salt/manifest.json new file mode 100644 index 00000000000000..c103346305f317 --- /dev/null +++ b/homeassistant/components/salt/manifest.json @@ -0,0 +1,11 @@ +{ + "domain": "salt", + "name": "Salt Fiber Box", + "documentation": "https://www.home-assistant.io/integrations/salt", + "requirements": ["saltbox==0.1.2"], + "ssdp": [], + "zeroconf": [], + "homekit": {}, + "dependencies": [], + "codeowners": ["@bjornorri"] +} From c9e86d54d005ed13a2bce0f0fcb027dc444ba9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 19 Jan 2020 18:21:14 +0100 Subject: [PATCH 02/15] Update files from development checklist --- .coveragerc | 1 + CODEOWNERS | 1 + requirements_all.txt | 3 +++ 3 files changed, 5 insertions(+) diff --git a/.coveragerc b/.coveragerc index 91f99fe84d4984..ea08f5cdf350b7 100644 --- a/.coveragerc +++ b/.coveragerc @@ -603,6 +603,7 @@ omit = homeassistant/components/russound_rnet/media_player.py homeassistant/components/sabnzbd/* homeassistant/components/saj/sensor.py + homeassistant/components/salt/device_tracker.py homeassistant/components/satel_integra/* homeassistant/components/scrape/sensor.py homeassistant/components/scsgate/* diff --git a/CODEOWNERS b/CODEOWNERS index 52bd64dffede96..4f9f9ad8ae0570 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -280,6 +280,7 @@ homeassistant/components/rmvtransport/* @cgtobi homeassistant/components/roomba/* @pschmitt homeassistant/components/safe_mode/* @home-assistant/core homeassistant/components/saj/* @fredericvl +homeassistant/components/salt/* @bjornorri homeassistant/components/samsungtv/* @escoand homeassistant/components/scene/* @home-assistant/core homeassistant/components/scrape/* @fabaff diff --git a/requirements_all.txt b/requirements_all.txt index cc3b6d733c9436..3ab19777fcb551 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1779,6 +1779,9 @@ russound_rio==0.1.7 # homeassistant.components.yamaha rxv==0.6.0 +# homeassistant.components.salt +saltbox==0.1.2 + # homeassistant.components.samsungtv samsungctl[websocket]==0.7.1 From 05563bc219abb8219fa771aa6c69c63297513458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri?= Date: Sun, 2 Feb 2020 10:35:15 +0100 Subject: [PATCH 03/15] Use warning log level when data cannot be retrieved Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com> --- homeassistant/components/salt/device_tracker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index 16803eff07fa9a..673e3059ae06aa 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -79,5 +79,5 @@ def get_salt_data(self): try: return self.saltbox.get_online_clients() except: # noqa: E722 # pylint: disable=bare-except - _LOGGER.info("Could not get data from Salt Fiber Box") + _LOGGER.warning("Could not get data from Salt Fiber Box") return self.online_clients From 288a9537877ee1843ba35acfa680879df9ebac50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 09:41:51 +0000 Subject: [PATCH 04/15] Remove empty fields from manifest.json --- homeassistant/components/salt/manifest.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/homeassistant/components/salt/manifest.json b/homeassistant/components/salt/manifest.json index c103346305f317..24b2d079f08ce6 100644 --- a/homeassistant/components/salt/manifest.json +++ b/homeassistant/components/salt/manifest.json @@ -3,9 +3,6 @@ "name": "Salt Fiber Box", "documentation": "https://www.home-assistant.io/integrations/salt", "requirements": ["saltbox==0.1.2"], - "ssdp": [], - "zeroconf": [], - "homekit": {}, "dependencies": [], "codeowners": ["@bjornorri"] } From dca9fc8cfaf656102c3761db175d9186d1423c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 10:10:32 +0000 Subject: [PATCH 05/15] Remove default arguments for host and username --- homeassistant/components/salt/device_tracker.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index 673e3059ae06aa..df26efa6d4510e 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -14,13 +14,10 @@ _LOGGER = logging.getLogger(__name__) -DEFAULT_IP = "192.168.1.1" -DEFAULT_USERNAME = "admin" - PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { - vol.Optional(CONF_HOST, default=DEFAULT_IP): cv.string, - vol.Optional(CONF_USERNAME, default=DEFAULT_USERNAME): cv.string, + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_PASSWORD): cv.string, } ) From b9526410f4d5e9f0d0abf17ed739b070b4b9870e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 13:01:50 +0100 Subject: [PATCH 06/15] Bump saltbox library version --- homeassistant/components/salt/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/salt/manifest.json b/homeassistant/components/salt/manifest.json index 24b2d079f08ce6..25ebdc38d1b77e 100644 --- a/homeassistant/components/salt/manifest.json +++ b/homeassistant/components/salt/manifest.json @@ -2,7 +2,7 @@ "domain": "salt", "name": "Salt Fiber Box", "documentation": "https://www.home-assistant.io/integrations/salt", - "requirements": ["saltbox==0.1.2"], + "requirements": ["saltbox==0.1.3"], "dependencies": [], "codeowners": ["@bjornorri"] } From fc3ada9404dc5b8b1951c23a7979994f0f17e9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 13:47:37 +0100 Subject: [PATCH 07/15] Refactor and improve error handling --- .../components/salt/device_tracker.py | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index df26efa6d4510e..bf4c70c879a5e6 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -2,6 +2,7 @@ import logging from saltbox import SaltBox +from saltbox import RouterLoginException, RouterNotReachableException import voluptuous as vol from homeassistant.components.device_tracker import ( @@ -26,7 +27,10 @@ def get_scanner(hass, config): """Return the Salt device scanner.""" scanner = SaltDeviceScanner(config[DOMAIN]) - return scanner if scanner.success_init else None + + # Test whether the router is accessible. + data = scanner.get_salt_data() + return scanner if data is not None else None class SaltDeviceScanner(DeviceScanner): @@ -40,10 +44,6 @@ def __init__(self, config): self.saltbox = SaltBox(f"http://{host}", username, password) self.online_clients = [] - # Test the router is accessible. - data = self.get_salt_data() - self.success_init = data is not None - def scan_devices(self): """Scan for new devices and return a list with found device IDs.""" self._update_info() @@ -58,23 +58,15 @@ def get_device_name(self, device): return client["name"] return None - def _update_info(self): - """Pull the current information from the Salt router.""" - if not self.success_init: - return False - - _LOGGER.info("Loading data from Salt Fiber Box") - data = self.get_salt_data() - if not data: - return False - - self.online_clients = data - return True - def get_salt_data(self): """Retrieve data from Salt router and return parsed result.""" try: return self.saltbox.get_online_clients() - except: # noqa: E722 # pylint: disable=bare-except - _LOGGER.warning("Could not get data from Salt Fiber Box") - return self.online_clients + except (RouterLoginException, RouterNotReachableException) as e: + _LOGGER.warning(e) + return [] + + def _update_info(self): + """Pull the current information from the Salt router.""" + _LOGGER.info("Loading data from Salt Fiber Box") + self.online_clients = self.get_salt_data() From 08f839fe8c3639daacf08115e26d124d3a14c5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 13:53:34 +0100 Subject: [PATCH 08/15] Dev checklist --- homeassistant/components/salt/manifest.json | 12 ++++++------ requirements_all.txt | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/salt/manifest.json b/homeassistant/components/salt/manifest.json index 25ebdc38d1b77e..019fdf9ae5f453 100644 --- a/homeassistant/components/salt/manifest.json +++ b/homeassistant/components/salt/manifest.json @@ -1,8 +1,8 @@ { - "domain": "salt", - "name": "Salt Fiber Box", - "documentation": "https://www.home-assistant.io/integrations/salt", - "requirements": ["saltbox==0.1.3"], - "dependencies": [], - "codeowners": ["@bjornorri"] + "domain": "salt", + "name": "Salt Fiber Box", + "documentation": "https://www.home-assistant.io/integrations/salt", + "requirements": ["saltbox==0.1.3"], + "dependencies": [], + "codeowners": ["@bjornorri"] } diff --git a/requirements_all.txt b/requirements_all.txt index 3ab19777fcb551..a7bb7b034a239a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1780,7 +1780,7 @@ russound_rio==0.1.7 rxv==0.6.0 # homeassistant.components.salt -saltbox==0.1.2 +saltbox==0.1.3 # homeassistant.components.samsungtv samsungctl[websocket]==0.7.1 From 3f9c1bd5f18b1801a58b4a227cb0fb6d0fbd48ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 14:02:25 +0100 Subject: [PATCH 09/15] Fix linting errors --- homeassistant/components/salt/device_tracker.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index bf4c70c879a5e6..20e44efae4202c 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -1,8 +1,7 @@ """Support for Salt Fiber Box routers.""" import logging -from saltbox import SaltBox -from saltbox import RouterLoginException, RouterNotReachableException +from saltbox import RouterLoginException, RouterNotReachableException, SaltBox import voluptuous as vol from homeassistant.components.device_tracker import ( @@ -62,8 +61,8 @@ def get_salt_data(self): """Retrieve data from Salt router and return parsed result.""" try: return self.saltbox.get_online_clients() - except (RouterLoginException, RouterNotReachableException) as e: - _LOGGER.warning(e) + except (RouterLoginException, RouterNotReachableException) as error: + _LOGGER.warning(error) return [] def _update_info(self): From 5a69b16f05e8788fdbcb69b085aea12f2829c40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 15:02:12 +0100 Subject: [PATCH 10/15] Check for None and return empty list --- homeassistant/components/salt/device_tracker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index 20e44efae4202c..574adba1d01c6d 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -60,7 +60,8 @@ def get_device_name(self, device): def get_salt_data(self): """Retrieve data from Salt router and return parsed result.""" try: - return self.saltbox.get_online_clients() + clients = self.saltbox.get_online_clients() + return clients if clients is not None else [] except (RouterLoginException, RouterNotReachableException) as error: _LOGGER.warning(error) return [] From 4627b965614d01a52b69a27a96572e347e9ac024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 15:03:31 +0100 Subject: [PATCH 11/15] Log on debug level instead of info --- homeassistant/components/salt/device_tracker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index 574adba1d01c6d..c0517a1a19f1e1 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -68,5 +68,5 @@ def get_salt_data(self): def _update_info(self): """Pull the current information from the Salt router.""" - _LOGGER.info("Loading data from Salt Fiber Box") + _LOGGER.debug("Loading data from Salt Fiber Box") self.online_clients = self.get_salt_data() From f7825f5b09c4859a7bcdb7a95758967341fb9199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 15:10:13 +0100 Subject: [PATCH 12/15] More compact None checks --- homeassistant/components/salt/device_tracker.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index c0517a1a19f1e1..33c8076592250f 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -29,8 +29,7 @@ def get_scanner(hass, config): # Test whether the router is accessible. data = scanner.get_salt_data() - return scanner if data is not None else None - + return scanner if data else None class SaltDeviceScanner(DeviceScanner): """This class queries a Salt Fiber Box router.""" @@ -61,7 +60,7 @@ def get_salt_data(self): """Retrieve data from Salt router and return parsed result.""" try: clients = self.saltbox.get_online_clients() - return clients if clients is not None else [] + return clients if clients else [] except (RouterLoginException, RouterNotReachableException) as error: _LOGGER.warning(error) return [] From c4f43fe1609decee80f9d2e6f39effcc8a164096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 15:11:28 +0100 Subject: [PATCH 13/15] Remove redundant None check --- homeassistant/components/salt/device_tracker.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index 33c8076592250f..31224eba06288b 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -31,6 +31,7 @@ def get_scanner(hass, config): data = scanner.get_salt_data() return scanner if data else None + class SaltDeviceScanner(DeviceScanner): """This class queries a Salt Fiber Box router.""" @@ -49,8 +50,6 @@ def scan_devices(self): def get_device_name(self, device): """Return the name of the given device or None if we don't know.""" - if not self.online_clients: - return None for client in self.online_clients: if client["mac"] == device: return client["name"] From e3dda840a5c6ae7af00196be61baaa904428ccfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 15:36:04 +0100 Subject: [PATCH 14/15] Return None on exception but store as empty list --- homeassistant/components/salt/device_tracker.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index 31224eba06288b..41271683a111c9 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -29,7 +29,7 @@ def get_scanner(hass, config): # Test whether the router is accessible. data = scanner.get_salt_data() - return scanner if data else None + return scanner if data is not None else None class SaltDeviceScanner(DeviceScanner): @@ -59,12 +59,13 @@ def get_salt_data(self): """Retrieve data from Salt router and return parsed result.""" try: clients = self.saltbox.get_online_clients() - return clients if clients else [] + return clients except (RouterLoginException, RouterNotReachableException) as error: _LOGGER.warning(error) - return [] + return None def _update_info(self): """Pull the current information from the Salt router.""" _LOGGER.debug("Loading data from Salt Fiber Box") - self.online_clients = self.get_salt_data() + data = self.get_salt_data() + self.online_clients = data if data else [] From 3017fa49322c8c8ce510ea51ca167486bf00276d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Orri=20S=C3=A6mundsson?= Date: Sun, 2 Feb 2020 15:45:42 +0100 Subject: [PATCH 15/15] More compact syntax --- homeassistant/components/salt/device_tracker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/salt/device_tracker.py b/homeassistant/components/salt/device_tracker.py index 41271683a111c9..7c03403622a8d4 100644 --- a/homeassistant/components/salt/device_tracker.py +++ b/homeassistant/components/salt/device_tracker.py @@ -68,4 +68,4 @@ def _update_info(self): """Pull the current information from the Salt router.""" _LOGGER.debug("Loading data from Salt Fiber Box") data = self.get_salt_data() - self.online_clients = data if data else [] + self.online_clients = data or []