Merge branch 'extract-entity-picture' into dev

Conflicts:
	homeassistant/components/sensor/steam_online.py
This commit is contained in:
Paulus Schoutsen 2016-02-24 22:00:58 -08:00
commit 57ac6cd76f
7 changed files with 67 additions and 45 deletions

View File

@ -15,7 +15,6 @@ from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.components import bloomsky from homeassistant.components import bloomsky
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_PICTURE,
HTTP_NOT_FOUND, HTTP_NOT_FOUND,
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
) )
@ -132,6 +131,11 @@ class Camera(Entity):
"""No need to poll cameras.""" """No need to poll cameras."""
return False return False
@property
def entity_picture(self):
"""Return a link to the camera feed as entity picture."""
return ENTITY_IMAGE_URL.format(self.entity_id)
@property @property
# pylint: disable=no-self-use # pylint: disable=no-self-use
def is_recording(self): def is_recording(self):
@ -195,9 +199,7 @@ class Camera(Entity):
@property @property
def state_attributes(self): def state_attributes(self):
"""Camera state attributes.""" """Camera state attributes."""
attr = { attr = {}
ATTR_ENTITY_PICTURE: ENTITY_IMAGE_URL.format(self.entity_id),
}
if self.model: if self.model:
attr['model_name'] = self.model attr['model_name'] = self.model

View File

@ -25,7 +25,7 @@ import homeassistant.util.dt as dt_util
from homeassistant.helpers.event import track_utc_time_change from homeassistant.helpers.event import track_utc_time_change
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_PICTURE, ATTR_GPS_ACCURACY, ATTR_LATITUDE, ATTR_LONGITUDE, ATTR_GPS_ACCURACY, ATTR_LATITUDE, ATTR_LONGITUDE,
DEVICE_DEFAULT_NAME, STATE_HOME, STATE_NOT_HOME) DEVICE_DEFAULT_NAME, STATE_HOME, STATE_NOT_HOME)
DOMAIN = "device_tracker" DOMAIN = "device_tracker"
@ -297,14 +297,16 @@ class Device(Entity):
""" State of the device. """ """ State of the device. """
return self._state return self._state
@property
def entity_picture(self):
"""Picture of the device."""
return self.config_picture
@property @property
def state_attributes(self): def state_attributes(self):
""" Device state attributes. """ """ Device state attributes. """
attr = {} attr = {}
if self.config_picture:
attr[ATTR_ENTITY_PICTURE] = self.config_picture
if self.gps: if self.gps:
attr[ATTR_LATITUDE] = self.gps[0] attr[ATTR_LATITUDE] = self.gps[0]
attr[ATTR_LONGITUDE] = self.gps[1] attr[ATTR_LONGITUDE] = self.gps[1]

View File

@ -15,7 +15,7 @@ from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.const import ( from homeassistant.const import (
STATE_OFF, STATE_UNKNOWN, STATE_PLAYING, STATE_IDLE, STATE_OFF, STATE_UNKNOWN, STATE_PLAYING, STATE_IDLE,
ATTR_ENTITY_ID, ATTR_ENTITY_PICTURE, SERVICE_TURN_OFF, SERVICE_TURN_ON, ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON,
SERVICE_VOLUME_UP, SERVICE_VOLUME_DOWN, SERVICE_VOLUME_SET, SERVICE_VOLUME_UP, SERVICE_VOLUME_DOWN, SERVICE_VOLUME_SET,
SERVICE_VOLUME_MUTE, SERVICE_TOGGLE, SERVICE_VOLUME_MUTE, SERVICE_TOGGLE,
SERVICE_MEDIA_PLAY_PAUSE, SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PAUSE, SERVICE_MEDIA_PLAY_PAUSE, SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PAUSE,
@ -525,6 +525,11 @@ class MediaPlayerDevice(Entity):
else: else:
self.media_play() self.media_play()
@property
def entity_picture(self):
"""Return image of the media playing."""
return None if self.state == STATE_OFF else self.media_image_url
@property @property
def state_attributes(self): def state_attributes(self):
""" Return the state attributes. """ """ Return the state attributes. """
@ -538,7 +543,4 @@ class MediaPlayerDevice(Entity):
in ATTR_TO_PROPERTY if getattr(self, attr) is not None in ATTR_TO_PROPERTY if getattr(self, attr) is not None
} }
if self.media_image_url:
state_attr[ATTR_ENTITY_PICTURE] = self.media_image_url
return state_attr return state_attr

View File

@ -5,7 +5,7 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.steam_online/ https://home-assistant.io/components/sensor.steam_online/
""" """
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.const import (ATTR_ENTITY_PICTURE, CONF_API_KEY) from homeassistant.const import CONF_API_KEY
ICON = 'mdi:steam' ICON = 'mdi:steam'
@ -59,11 +59,9 @@ class SteamSensor(Entity):
}.get(self._profile.status, 'Offline') }.get(self._profile.status, 'Offline')
@property @property
def device_state_attributes(self): def entity_picture(self):
"""Return the state attributes.""" """Avatar of the account."""
return { return self._profile.avatar_medium
ATTR_ENTITY_PICTURE: self._profile.avatar_medium
}
@property @property
def icon(self): def icon(self):

View File

@ -4,7 +4,6 @@ Support for the Twitch stream status.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.twitch/ https://home-assistant.io/components/sensor.twitch/
""" """
from homeassistant.const import ATTR_ENTITY_PICTURE
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
STATE_STREAMING = 'streaming' STATE_STREAMING = 'streaming'
@ -51,6 +50,11 @@ class TwitchSensor(Entity):
"""State of the sensor.""" """State of the sensor."""
return self._state return self._state
@property
def entity_picture(self):
"""Preview of current game."""
return self._preview
# pylint: disable=no-member # pylint: disable=no-member
def update(self): def update(self):
"""Update device state.""" """Update device state."""
@ -62,6 +66,7 @@ class TwitchSensor(Entity):
self._preview = stream.get('preview').get('small') self._preview = stream.get('preview').get('small')
self._state = STATE_STREAMING self._state = STATE_STREAMING
else: else:
self._preview = None
self._state = STATE_OFFLINE self._state = STATE_OFFLINE
@property @property
@ -71,7 +76,6 @@ class TwitchSensor(Entity):
return { return {
ATTR_GAME: self._game, ATTR_GAME: self._game,
ATTR_TITLE: self._title, ATTR_TITLE: self._title,
ATTR_ENTITY_PICTURE: self._preview
} }
@property @property

View File

@ -8,8 +8,7 @@ import logging
import requests import requests
from homeassistant.const import ( from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
ATTR_ENTITY_PICTURE, CONF_LATITUDE, CONF_LONGITUDE)
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from homeassistant.util import location from homeassistant.util import location
@ -97,20 +96,21 @@ class YrSensor(Entity):
"""Returns the state of the device.""" """Returns the state of the device."""
return self._state return self._state
@property
def entity_picture(self):
"""Weather symbol if type is symbol."""
if self.type != 'symbol':
return None
return "http://api.met.no/weatherapi/weathericon/1.1/" \
"?symbol={0};content_type=image/png".format(self._state)
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Returns state attributes. """ """Returns state attributes. """
data = { return {
'about': "Weather forecast from yr.no, delivered by the" 'about': "Weather forecast from yr.no, delivered by the"
" Norwegian Meteorological Institute and the NRK" " Norwegian Meteorological Institute and the NRK"
} }
if self.type == 'symbol':
symbol_nr = self._state
data[ATTR_ENTITY_PICTURE] = \
"http://api.met.no/weatherapi/weathericon/1.1/" \
"?symbol={0};content_type=image/png".format(symbol_nr)
return data
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):

View File

@ -10,7 +10,8 @@ from collections import defaultdict
from homeassistant.const import ( from homeassistant.const import (
ATTR_ASSUMED_STATE, ATTR_FRIENDLY_NAME, ATTR_HIDDEN, ATTR_ICON, ATTR_ASSUMED_STATE, ATTR_FRIENDLY_NAME, ATTR_HIDDEN, ATTR_ICON,
ATTR_UNIT_OF_MEASUREMENT, DEVICE_DEFAULT_NAME, STATE_OFF, STATE_ON, ATTR_UNIT_OF_MEASUREMENT, DEVICE_DEFAULT_NAME, STATE_OFF, STATE_ON,
STATE_UNAVAILABLE, STATE_UNKNOWN, TEMP_CELCIUS, TEMP_FAHRENHEIT) STATE_UNAVAILABLE, STATE_UNKNOWN, TEMP_CELCIUS, TEMP_FAHRENHEIT,
ATTR_ENTITY_PICTURE)
from homeassistant.exceptions import NoEntitySpecifiedError from homeassistant.exceptions import NoEntitySpecifiedError
from homeassistant.util import ensure_unique_string, slugify from homeassistant.util import ensure_unique_string, slugify
@ -105,6 +106,11 @@ class Entity(object):
"""Return the icon to use in the frontend, if any.""" """Return the icon to use in the frontend, if any."""
return None return None
@property
def entity_picture(self):
"""Return the entity picture to use in the frontend, if any."""
return None
@property @property
def hidden(self): def hidden(self):
"""Return True if the entity should be hidden from UIs.""" """Return True if the entity should be hidden from UIs."""
@ -157,25 +163,18 @@ class Entity(object):
if device_attr is not None: if device_attr is not None:
attr.update(device_attr) attr.update(device_attr)
if ATTR_UNIT_OF_MEASUREMENT not in attr and \ self._attr_setter('unit_of_measurement', str, ATTR_UNIT_OF_MEASUREMENT,
self.unit_of_measurement is not None: attr)
attr[ATTR_UNIT_OF_MEASUREMENT] = str(self.unit_of_measurement)
if not self.available: if not self.available:
state = STATE_UNAVAILABLE state = STATE_UNAVAILABLE
attr = {} attr = {}
if self.name is not None: self._attr_setter('name', str, ATTR_FRIENDLY_NAME, attr)
attr[ATTR_FRIENDLY_NAME] = str(self.name) self._attr_setter('icon', str, ATTR_ICON, attr)
self._attr_setter('entity_picture', str, ATTR_ENTITY_PICTURE, attr)
if self.icon is not None: self._attr_setter('hidden', bool, ATTR_HIDDEN, attr)
attr[ATTR_ICON] = str(self.icon) self._attr_setter('assumed_state', bool, ATTR_ASSUMED_STATE, attr)
if self.hidden:
attr[ATTR_HIDDEN] = bool(self.hidden)
if self.assumed_state:
attr[ATTR_ASSUMED_STATE] = bool(self.assumed_state)
# overwrite properties that have been set in the config file # overwrite properties that have been set in the config file
attr.update(_OVERWRITE.get(self.entity_id, {})) attr.update(_OVERWRITE.get(self.entity_id, {}))
@ -195,6 +194,21 @@ class Entity(object):
return self.hass.states.set(self.entity_id, state, attr) return self.hass.states.set(self.entity_id, state, attr)
def _attr_setter(self, name, typ, attr, attrs):
"""Helper method to populate attributes based on properties."""
if attr in attrs:
return
value = getattr(self, name)
if not value:
return
try:
attrs[attr] = typ(value)
except (TypeError, ValueError):
pass
def __eq__(self, other): def __eq__(self, other):
return (isinstance(other, Entity) and return (isinstance(other, Entity) and
other.unique_id == self.unique_id) other.unique_id == self.unique_id)