From aa9673b208506e8df4fa5e47e13d7d6b3b8f2107 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 13 Jan 2015 08:25:17 -0800 Subject: [PATCH 01/10] Device Tracker sets up group auto attribute proper --- homeassistant/components/device_tracker/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index 3da9054be8d..04cea3e047b 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -111,7 +111,8 @@ class DeviceTracker(object): """ Triggers update of the device states. """ self.update_devices(now) - dev_group = group.Group(hass, GROUP_NAME_ALL_DEVICES) + dev_group = group.Group( + hass, GROUP_NAME_ALL_DEVICES, user_defined=False) # pylint: disable=unused-argument def reload_known_devices_service(service): From ce9de1b7d235f218fe21549609121af38bcb40c6 Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 01:14:47 +0000 Subject: [PATCH 02/10] Add initial support for wink sensors. Refactor wink API fetching into a generic 'get_devices' function. --- homeassistant/external/wink/pywink.py | 173 ++++++++++++++++++++------ 1 file changed, 138 insertions(+), 35 deletions(-) diff --git a/homeassistant/external/wink/pywink.py b/homeassistant/external/wink/pywink.py index 7d44050f55c..1b01a9b9a89 100644 --- a/homeassistant/external/wink/pywink.py +++ b/homeassistant/external/wink/pywink.py @@ -10,6 +10,134 @@ baseUrl = "https://winkapi.quirky.com" headers = {} +class wink_sensor_pod(object): + """ represents a wink.py sensor + json_obj holds the json stat at init (and if there is a refresh it's updated + it's the native format for this objects methods + and looks like so: +{ + "data": { + "last_event": { + "brightness_occurred_at": None, + "loudness_occurred_at": None, + "vibration_occurred_at": None + }, + "model_name": "Tripper", + "capabilities": { + "sensor_types": [ + { + "field": "opened", + "type": "boolean" + }, + { + "field": "battery", + "type": "percentage" + } + ] + }, + "manufacturer_device_model": "quirky_ge_tripper", + "location": "", + "radio_type": "zigbee", + "manufacturer_device_id": None, + "gang_id": None, + "sensor_pod_id": "37614", + "subscription": { + }, + "units": { + }, + "upc_id": "184", + "hidden_at": None, + "last_reading": { + "battery_voltage_threshold_2": 0, + "opened": False, + "battery_alarm_mask": 0, + "opened_updated_at": 1421697092.7347496, + "battery_voltage_min_threshold_updated_at": 1421697092.7347229, + "battery_voltage_min_threshold": 0, + "connection": None, + "battery_voltage": 25, + "battery_voltage_threshold_1": 25, + "connection_updated_at": None, + "battery_voltage_threshold_3": 0, + "battery_voltage_updated_at": 1421697092.7347066, + "battery_voltage_threshold_1_updated_at": 1421697092.7347302, + "battery_voltage_threshold_3_updated_at": 1421697092.7347434, + "battery_voltage_threshold_2_updated_at": 1421697092.7347374, + "battery": 1.0, + "battery_updated_at": 1421697092.7347553, + "battery_alarm_mask_updated_at": 1421697092.734716 + }, + "triggers": [ + ], + "name": "MasterBathroom", + "lat_lng": [ + 37.550773, + -122.279182 + ], + "uuid": "a2cb868a-dda3-4211-ab73-fc08087aeed7", + "locale": "en_us", + "device_manufacturer": "quirky_ge", + "created_at": 1421523277, + "local_id": "2", + "hub_id": "88264" + }, +} + + """ + def __init__(self, aJSonObj, objectprefix="sensor_pods"): + self.jsonState = aJSonObj + self.objectprefix = objectprefix + # Tuple (desired state, time) + self._last_call = (0, None) + + def __str__(self): + return "%s %s %s" % (self.name(), self.deviceId(), self.state()) + + def __repr__(self): + return "" % (self.name(), self.deviceId(), self.state()) + + @property + def _last_reading(self): + return self.jsonState.get('last_reading') or {} + + def name(self): + return self.jsonState.get('name', "Unknown Name") + + def state(self): + # Optimistic approach to setState: + # Within 15 seconds of a call to setState we assume it worked. + if self._recent_state_set(): + return self._last_call[1] + + return self._last_reading.get('opened', False) + + def deviceId(self): + return self.jsonState.get('sensor_pod_id', self.name()) + + def refresh_state_at_hub(self): + """ + Tell hub to query latest status from device and upload to Wink. + PS: Not sure if this even works.. + """ + urlString = baseUrl + "/%s/%s/refresh" % (self.objectprefix, self.deviceId()) + requests.get(urlString, headers=headers) + + def updateState(self): + """ Update state with latest info from Wink API. """ + urlString = baseUrl + "/%s/%s" % (self.objectprefix, self.deviceId()) + arequest = requests.get(urlString, headers=headers) + self._updateStateFromResponse(arequest.json()) + + def _updateStateFromResponse(self, response_json): + """ + :param response_json: the json obj returned from query + :return: + """ + self.jsonState = response_json.get('data') + + def _recent_state_set(self): + return time.time() - self._last_call[0] < 15 + class wink_binary_switch(object): """ represents a wink.py switch json_obj holds the json stat at init (and if there is a refresh it's updated @@ -248,53 +376,28 @@ class wink_bulb(wink_binary_switch): self.name(), self.deviceId(), self.state()) -def get_bulbs_and_switches(): +def get_devices(filter, constructor): arequestUrl = baseUrl + "/users/me/wink_devices" j = requests.get(arequestUrl, headers=headers).json() items = j.get('data') - switches = [] + devices = [] for item in items: - id = item.get('light_bulb_id') - if id != None: - switches.append(wink_bulb(item)) - id = item.get('binary_switch_id') - if id != None: - switches.append(wink_binary_switch(item)) - - return switches + id = item.get(filter) + if id is not None: + devices.append(constructor(item)) + return devices def get_bulbs(): - arequestUrl = baseUrl + "/users/me/wink_devices" - j = requests.get(arequestUrl, headers=headers).json() - - items = j.get('data') - - switches = [] - for item in items: - id = item.get('light_bulb_id') - if id is not None: - switches.append(wink_bulb(item)) - - return switches - + return get_devices('light_bulb_id', wink_bulb) def get_switches(): - arequestUrl = baseUrl + "/users/me/wink_devices" - j = requests.get(arequestUrl, headers=headers).json() - - items = j.get('data') - - switches = [] - for item in items: - id = item.get('binary_switch_id') - if id is not None: - switches.append(wink_binary_switch(item)) - - return switches + return get_devices('binary_switch_id', wink_binary_switch) +def get_sensors(): + return get_devices('sensor_pod_id', wink_sensor_pod) def set_bearer_token(token): global headers From 7fbd36ccad06c2d54ce34d6e0a31cd96d6ab69a0 Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 01:16:04 +0000 Subject: [PATCH 03/10] Add a new sensor component Hook up to scan sensor_pod_id's from Wink and report their status. --- homeassistant/components/sensor/__init__.py | 89 +++++++++++++++++++++ homeassistant/components/sensor/wink.py | 35 ++++++++ homeassistant/components/wink.py | 33 +++++++- homeassistant/const.py | 2 + 4 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 homeassistant/components/sensor/__init__.py create mode 100644 homeassistant/components/sensor/wink.py diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py new file mode 100644 index 00000000000..925e3bf9bec --- /dev/null +++ b/homeassistant/components/sensor/__init__.py @@ -0,0 +1,89 @@ +""" +homeassistant.components.sensor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Component to interface with various sensors that can be monitored. +""" +import logging +from datetime import timedelta + +from homeassistant.loader import get_component +import homeassistant.util as util +from homeassistant.const import ( + STATE_OPEN, ATTR_ENTITY_ID) +from homeassistant.helpers import ( + extract_entity_ids, platform_devices_from_config) +from homeassistant.components import group, discovery, wink + +DOMAIN = 'sensor' +DEPENDENCIES = [] + +GROUP_NAME_ALL_SENSORS = 'all_sensors' +ENTITY_ID_ALL_SENSORS = group.ENTITY_ID_FORMAT.format( + GROUP_NAME_ALL_SENSORS) + +ENTITY_ID_FORMAT = DOMAIN + '.{}' + +MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) + +# Maps discovered services to their platforms +DISCOVERY_PLATFORMS = { + wink.DISCOVER_SENSORS: 'wink', +} + +_LOGGER = logging.getLogger(__name__) + + +def is_on(hass, entity_id=None): + """ Returns if the sensor is open based on the statemachine. """ + entity_id = entity_id or ENTITY_ID_ALL_SENSORS + + return hass.states.is_state(entity_id, STATE_OPEN) + +def setup(hass, config): + """ Track states and offer events for sensors. """ + logger = logging.getLogger(__name__) + + sensors = platform_devices_from_config( + config, DOMAIN, hass, ENTITY_ID_FORMAT, logger) + + # pylint: disable=unused-argument + @util.Throttle(MIN_TIME_BETWEEN_SCANS) + def update_states(now): + """ Update states of all sensors. """ + if sensors: + logger.info("Updating sensors states") + + for sensor in sensors.values(): + sensor.update_ha_state(hass, True) + + update_states(None) + + # Track all sensors in a group + sensor_group = group.Group( + hass, GROUP_NAME_ALL_SENSORS, sensors.keys(), False) + + def sensor_discovered(service, info): + """ Called when a sensor is discovered. """ + platform = get_component("{}.{}".format( + DOMAIN, DISCOVERY_PLATFORMS[service])) + + discovered = platform.devices_discovered(hass, config, info) + + for sensor in discovered: + if sensor is not None and sensor not in sensors.values(): + sensor.entity_id = util.ensure_unique_string( + ENTITY_ID_FORMAT.format(util.slugify(sensor.name)), + sensors.keys()) + + sensors[sensor.entity_id] = sensor + + sensor.update_ha_state(hass) + + sensor_group.update_tracked_entity_ids(sensors.keys()) + + discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), sensor_discovered) + + # Update state every 30 seconds + hass.track_time_change(update_states, second=[0, 30]) + + return True diff --git a/homeassistant/components/sensor/wink.py b/homeassistant/components/sensor/wink.py new file mode 100644 index 00000000000..99303d3ef56 --- /dev/null +++ b/homeassistant/components/sensor/wink.py @@ -0,0 +1,35 @@ +""" Support for Wink sensors. """ +import logging + +# pylint: disable=no-name-in-module, import-error +import homeassistant.external.wink.pywink as pywink + +from homeassistant.components.wink import WinkSensorDevice +from homeassistant.const import CONF_ACCESS_TOKEN + + +# pylint: disable=unused-argument +def get_devices(hass, config): + """ Find and return Wink sensors. """ + token = config.get(CONF_ACCESS_TOKEN) + + if token is None: + logging.getLogger(__name__).error( + "Missing wink access_token - " + "get one at https://winkbearertoken.appspot.com/") + return [] + + pywink.set_bearer_token(token) + + return get_sensors() + + +# pylint: disable=unused-argument +def devices_discovered(hass, config, info): + """ Called when a device is discovered. """ + return get_sensors() + + +def get_sensors(): + """ Returns the Wink sensors. """ + return [WinkSensorDevice(sensor) for sensor in pywink.get_sensors()] diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index d049d1ecc26..dba73dc1dae 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -8,7 +8,7 @@ import homeassistant.external.wink.pywink as pywink from homeassistant import bootstrap from homeassistant.loader import get_component -from homeassistant.helpers import validate_config, ToggleDevice +from homeassistant.helpers import validate_config, ToggleDevice, Device from homeassistant.const import ( EVENT_PLATFORM_DISCOVERED, CONF_ACCESS_TOKEN, ATTR_SERVICE, ATTR_DISCOVERED, ATTR_FRIENDLY_NAME) @@ -18,7 +18,7 @@ DEPENDENCIES = [] DISCOVER_LIGHTS = "wink.lights" DISCOVER_SWITCHES = "wink.switches" - +DISCOVER_SENSORS = "wink.sensors" def setup(hass, config): """ Sets up the Wink component. """ @@ -32,7 +32,8 @@ def setup(hass, config): # Load components for the devices in the Wink that we support for component_name, func_exists, discovery_type in ( ('light', pywink.get_bulbs, DISCOVER_LIGHTS), - ('switch', pywink.get_switches, DISCOVER_SWITCHES)): + ('switch', pywink.get_switches, DISCOVER_SWITCHES), + ('sensor', pywink.get_sensors, DISCOVER_SENSORS)): if func_exists(): component = get_component(component_name) @@ -49,6 +50,32 @@ def setup(hass, config): return True +class WinkSensorDevice(Device): + """ represents a wink sensor within home assistant. """ + + def __init__(self, wink): + self.wink = wink + + @property + def unique_id(self): + """ Returns the id of this wink switch """ + return "{}.{}".format(self.__class__, self.wink.deviceId()) + + @property + def name(self): + """ Returns the name of the sensor if any. """ + return self.wink.name() + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + return { + ATTR_FRIENDLY_NAME: self.wink.name() + } + + def update(self): + """ Update state of the sensor. """ + self.wink.updateState() class WinkToggleDevice(ToggleDevice): """ represents a WeMo switch within home assistant. """ diff --git a/homeassistant/const.py b/homeassistant/const.py index 39089ae84cb..31c575b96c7 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -35,6 +35,8 @@ STATE_OFF = 'off' STATE_HOME = 'home' STATE_NOT_HOME = 'not_home' STATE_UNKNOWN = "unknown" +STATE_OPEN = 'open' +STATE_CLOSED = 'closed' # #### STATE AND EVENT ATTRIBUTES #### # Contains current time for a TIME_CHANGED event From 454bea4237e79357948b5ef5f106f3e3eef4ec9f Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 02:57:50 +0000 Subject: [PATCH 04/10] Reduce the timer interval to make sensors useful --- homeassistant/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/__init__.py b/homeassistant/__init__.py index 0ed4b2b2fd2..1556547b643 100644 --- a/homeassistant/__init__.py +++ b/homeassistant/__init__.py @@ -27,7 +27,7 @@ import homeassistant.util as util DOMAIN = "homeassistant" # How often time_changed event should fire -TIMER_INTERVAL = 10 # seconds +TIMER_INTERVAL = 3 # seconds # How long we wait for the result of a service call SERVICE_CALL_LIMIT = 10 # seconds From 80c2d81f41dc22afd344d92ff755c4a5818e4a2c Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 02:58:08 +0000 Subject: [PATCH 05/10] Fire the sensor timer more often, and fix a typo --- homeassistant/components/sensor/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 925e3bf9bec..dec5edc59aa 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -9,7 +9,7 @@ from datetime import timedelta from homeassistant.loader import get_component import homeassistant.util as util from homeassistant.const import ( - STATE_OPEN, ATTR_ENTITY_ID) + STATE_OPEN, STATE_CLOSED, ATTR_ENTITY_ID) from homeassistant.helpers import ( extract_entity_ids, platform_devices_from_config) from homeassistant.components import group, discovery, wink @@ -51,7 +51,7 @@ def setup(hass, config): def update_states(now): """ Update states of all sensors. """ if sensors: - logger.info("Updating sensors states") + logger.info("Updating sensor states") for sensor in sensors.values(): sensor.update_ha_state(hass, True) @@ -83,7 +83,6 @@ def setup(hass, config): discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), sensor_discovered) - # Update state every 30 seconds - hass.track_time_change(update_states, second=[0, 30]) + hass.track_time_change(update_states) return True From 78f7c3cbead7b51e868762d3256404e89c28ba3b Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 02:58:21 +0000 Subject: [PATCH 06/10] Implement state for the sensor device --- homeassistant/components/wink.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index dba73dc1dae..da15bed6dd5 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -11,6 +11,7 @@ from homeassistant.loader import get_component from homeassistant.helpers import validate_config, ToggleDevice, Device from homeassistant.const import ( EVENT_PLATFORM_DISCOVERED, CONF_ACCESS_TOKEN, + STATE_OPEN, STATE_CLOSED, ATTR_SERVICE, ATTR_DISCOVERED, ATTR_FRIENDLY_NAME) DOMAIN = "wink" @@ -56,6 +57,11 @@ class WinkSensorDevice(Device): def __init__(self, wink): self.wink = wink + @property + def state(self): + """ Returns the state. """ + return STATE_OPEN if self.is_open else STATE_CLOSED + @property def unique_id(self): """ Returns the id of this wink switch """ @@ -77,6 +83,11 @@ class WinkSensorDevice(Device): """ Update state of the sensor. """ self.wink.updateState() + @property + def is_open(self): + """ True if door is open. """ + return self.wink.state() + class WinkToggleDevice(ToggleDevice): """ represents a WeMo switch within home assistant. """ From 15012688f21afda1b4d2586a1b0495c84fb0de09 Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 02:58:40 +0000 Subject: [PATCH 07/10] Remove switch state delay --- homeassistant/external/wink/pywink.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/homeassistant/external/wink/pywink.py b/homeassistant/external/wink/pywink.py index 1b01a9b9a89..72a3353a77c 100644 --- a/homeassistant/external/wink/pywink.py +++ b/homeassistant/external/wink/pywink.py @@ -87,8 +87,6 @@ class wink_sensor_pod(object): def __init__(self, aJSonObj, objectprefix="sensor_pods"): self.jsonState = aJSonObj self.objectprefix = objectprefix - # Tuple (desired state, time) - self._last_call = (0, None) def __str__(self): return "%s %s %s" % (self.name(), self.deviceId(), self.state()) @@ -104,11 +102,6 @@ class wink_sensor_pod(object): return self.jsonState.get('name', "Unknown Name") def state(self): - # Optimistic approach to setState: - # Within 15 seconds of a call to setState we assume it worked. - if self._recent_state_set(): - return self._last_call[1] - return self._last_reading.get('opened', False) def deviceId(self): @@ -135,9 +128,6 @@ class wink_sensor_pod(object): """ self.jsonState = response_json.get('data') - def _recent_state_set(self): - return time.time() - self._last_call[0] < 15 - class wink_binary_switch(object): """ represents a wink.py switch json_obj holds the json stat at init (and if there is a refresh it's updated From a7315684c405f2511508225604312f34f336b573 Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 04:00:31 +0000 Subject: [PATCH 08/10] Reduce the threshold on the sensor changes, and rename it for easier debugging --- homeassistant/components/sensor/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index dec5edc59aa..a33676ae415 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -23,7 +23,7 @@ ENTITY_ID_ALL_SENSORS = group.ENTITY_ID_FORMAT.format( ENTITY_ID_FORMAT = DOMAIN + '.{}' -MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) +MIN_TIME_BETWEEN_SCANS = timedelta(seconds=1) # Maps discovered services to their platforms DISCOVERY_PLATFORMS = { @@ -48,7 +48,7 @@ def setup(hass, config): # pylint: disable=unused-argument @util.Throttle(MIN_TIME_BETWEEN_SCANS) - def update_states(now): + def update_sensor_states(now): """ Update states of all sensors. """ if sensors: logger.info("Updating sensor states") @@ -56,7 +56,7 @@ def setup(hass, config): for sensor in sensors.values(): sensor.update_ha_state(hass, True) - update_states(None) + update_sensor_states(None) # Track all sensors in a group sensor_group = group.Group( @@ -83,6 +83,6 @@ def setup(hass, config): discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), sensor_discovered) - hass.track_time_change(update_states) + hass.track_time_change(update_sensor_states) return True From a287bb5da0a8a2f932450029f1165f36d7fc0401 Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 04:23:31 +0000 Subject: [PATCH 09/10] Updates to resolve flake8 errors --- homeassistant/components/sensor/__init__.py | 5 +++-- homeassistant/components/wink.py | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index a33676ae415..2ed732289b6 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -9,9 +9,9 @@ from datetime import timedelta from homeassistant.loader import get_component import homeassistant.util as util from homeassistant.const import ( - STATE_OPEN, STATE_CLOSED, ATTR_ENTITY_ID) + STATE_OPEN) from homeassistant.helpers import ( - extract_entity_ids, platform_devices_from_config) + platform_devices_from_config) from homeassistant.components import group, discovery, wink DOMAIN = 'sensor' @@ -39,6 +39,7 @@ def is_on(hass, entity_id=None): return hass.states.is_state(entity_id, STATE_OPEN) + def setup(hass, config): """ Track states and offer events for sensors. """ logger = logging.getLogger(__name__) diff --git a/homeassistant/components/wink.py b/homeassistant/components/wink.py index da15bed6dd5..20b3e0b75f9 100644 --- a/homeassistant/components/wink.py +++ b/homeassistant/components/wink.py @@ -21,6 +21,7 @@ DISCOVER_LIGHTS = "wink.lights" DISCOVER_SWITCHES = "wink.switches" DISCOVER_SENSORS = "wink.sensors" + def setup(hass, config): """ Sets up the Wink component. """ logger = logging.getLogger(__name__) @@ -51,6 +52,7 @@ def setup(hass, config): return True + class WinkSensorDevice(Device): """ represents a wink sensor within home assistant. """ @@ -88,6 +90,7 @@ class WinkSensorDevice(Device): """ True if door is open. """ return self.wink.state() + class WinkToggleDevice(ToggleDevice): """ represents a WeMo switch within home assistant. """ From abfaca3bfbad93675bd23e3d056a184b77e01f93 Mon Sep 17 00:00:00 2001 From: Geoff Norton Date: Tue, 20 Jan 2015 04:55:12 +0000 Subject: [PATCH 10/10] Update sensor icon for now --- .../http/www_static/polymer/components/domain-icon.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/homeassistant/components/http/www_static/polymer/components/domain-icon.html b/homeassistant/components/http/www_static/polymer/components/domain-icon.html index a35bbfaacaa..1980be11d8c 100644 --- a/homeassistant/components/http/www_static/polymer/components/domain-icon.html +++ b/homeassistant/components/http/www_static/polymer/components/domain-icon.html @@ -59,6 +59,9 @@ case "thermostat": return "homeassistant:thermostat"; + case "sensor": + return "visibility"; + default: return "bookmark-outline"; }