From 36a663adeb88664800ccffb3d676688861547af3 Mon Sep 17 00:00:00 2001 From: stephanerosi Date: Mon, 16 Apr 2018 08:20:58 +0200 Subject: [PATCH] Add extra attributes for device scanner, Nmap and Unifi (IP, SSID, etc.) (#13673) * Start of development * Add extra attributes from unifi scanner * Store IP of the device in the state attributes with nmap * Allow not defining get_extra_attributes method in derived classes --- .../components/device_tracker/__init__.py | 23 ++++++++++++++++++- .../components/device_tracker/nmap_tracker.py | 11 +++++++++ .../components/device_tracker/unifi.py | 6 +++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index 45f0e51a214..b24f7784faf 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -605,6 +605,17 @@ class DeviceScanner(object): """ return self.hass.async_add_job(self.get_device_name, device) + def get_extra_attributes(self, device: str) -> dict: + """Get the extra attributes of a device.""" + raise NotImplementedError() + + def async_get_extra_attributes(self, device: str) -> Any: + """Get the extra attributes of a device. + + This method must be run in the event loop and returns a coroutine. + """ + return self.hass.async_add_job(self.get_extra_attributes, device) + def load_config(path: str, hass: HomeAssistantType, consider_home: timedelta): """Load devices from YAML configuration file.""" @@ -690,10 +701,20 @@ def async_setup_scanner_platform(hass: HomeAssistantType, config: ConfigType, host_name = yield from scanner.async_get_device_name(mac) seen.add(mac) + try: + extra_attributes = (yield from + scanner.async_get_extra_attributes(mac)) + except NotImplementedError: + extra_attributes = dict() + kwargs = { 'mac': mac, 'host_name': host_name, - 'source_type': SOURCE_TYPE_ROUTER + 'source_type': SOURCE_TYPE_ROUTER, + 'attributes': { + 'scanner': scanner.__class__.__name__, + **extra_attributes + } } zone_home = hass.states.get(zone.ENTITY_ID_HOME) diff --git a/homeassistant/components/device_tracker/nmap_tracker.py b/homeassistant/components/device_tracker/nmap_tracker.py index 23cb7ea8f9d..f62f53fe5fc 100644 --- a/homeassistant/components/device_tracker/nmap_tracker.py +++ b/homeassistant/components/device_tracker/nmap_tracker.py @@ -80,6 +80,8 @@ class NmapDeviceScanner(DeviceScanner): """Scan for new devices and return a list with found device IDs.""" self._update_info() + _LOGGER.debug("Nmap last results %s", self.last_results) + return [device.mac for device in self.last_results] def get_device_name(self, device): @@ -91,6 +93,15 @@ class NmapDeviceScanner(DeviceScanner): return filter_named[0] return None + def get_extra_attributes(self, device): + """Return the IP pf the given device.""" + filter_ip = [result.ip for result in self.last_results + if result.mac == device] + + if filter_ip: + return {'ip': filter_ip[0]} + return None + def _update_info(self): """Scan the network for devices. diff --git a/homeassistant/components/device_tracker/unifi.py b/homeassistant/components/device_tracker/unifi.py index d8a52aaaeb4..b7efe65dd01 100644 --- a/homeassistant/components/device_tracker/unifi.py +++ b/homeassistant/components/device_tracker/unifi.py @@ -122,3 +122,9 @@ class UnifiScanner(DeviceScanner): name = client.get('name') or client.get('hostname') _LOGGER.debug("Device mac %s name %s", device, name) return name + + def get_extra_attributes(self, device): + """Return the extra attributes of the device.""" + client = self._clients.get(device, {}) + _LOGGER.debug("Device mac %s attributes %s", device, client) + return client