From 96edd759a8d33dea8dc2fd096ec8555808a94001 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 30 May 2015 00:52:33 -0700 Subject: [PATCH 1/2] media_player.cast: support thumbnail + title --- homeassistant/components/media_player/cast.py | 24 ++++++++++++------- requirements.txt | 4 ++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index 35d9748c663..0685b31f439 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -15,10 +15,12 @@ except ImportError: # We will throw error later pass +from homeassistant.const import ATTR_ENTITY_PICTURE + # ATTR_MEDIA_ALBUM, ATTR_MEDIA_IMAGE_URL, -# ATTR_MEDIA_TITLE, ATTR_MEDIA_ARTIST, +# ATTR_MEDIA_ARTIST, from homeassistant.components.media_player import ( - MediaPlayerDevice, STATE_NO_APP, ATTR_MEDIA_STATE, + MediaPlayerDevice, STATE_NO_APP, ATTR_MEDIA_STATE, ATTR_MEDIA_TITLE, ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_DURATION, ATTR_MEDIA_VOLUME, MEDIA_STATE_PLAYING, MEDIA_STATE_PAUSED, MEDIA_STATE_STOPPED, MEDIA_STATE_UNKNOWN) @@ -95,7 +97,8 @@ class CastDevice(MediaPlayerDevice): def state_attributes(self): """ Returns the state attributes. """ cast_status = self.cast.status - media_status = self.cast.media_status + media_controller = self.cast.media_controller + media_status = media_controller.status state_attr = { ATTR_MEDIA_STATE: self.media_state, @@ -105,12 +108,17 @@ class CastDevice(MediaPlayerDevice): if cast_status: state_attr[ATTR_MEDIA_VOLUME] = cast_status.volume_level, - if media_status: - if media_status.content_id: - state_attr[ATTR_MEDIA_CONTENT_ID] = media_status.content_id + if media_status.content_id: + state_attr[ATTR_MEDIA_CONTENT_ID] = media_status.content_id - if media_status.duration: - state_attr[ATTR_MEDIA_DURATION] = media_status.duration + if media_status.duration: + state_attr[ATTR_MEDIA_DURATION] = media_status.duration + + if media_controller.title: + state_attr[ATTR_MEDIA_TITLE] = media_controller.title + + if media_controller.thumbnail: + state_attr[ATTR_ENTITY_PICTURE] = media_controller.thumbnail return state_attr diff --git a/requirements.txt b/requirements.txt index 6d2e032af45..c1c5403be3e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ phue>=0.8 ledcontroller>=1.0.7 # media_player.cast -pychromecast>=0.6 +pychromecast>=0.6.0.3 # keyboard pyuserinput>=0.1.9 @@ -41,7 +41,7 @@ pydispatcher>=2.0.5 # isy994 PyISY>=1.0.2 -# sensor.systemmonitor +# sensor.systemmonitor psutil>=2.2.1 # pushover notifications From 3d4392ce63be9885fd7138d20c7da204511c063f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 13 Jun 2015 14:56:20 -0700 Subject: [PATCH 2/2] Refactor basic switch structure --- homeassistant/components/switch/__init__.py | 46 ++++++++++++++++++- .../components/switch/command_switch.py | 22 ++++----- homeassistant/components/switch/demo.py | 30 +++++++----- homeassistant/components/switch/wemo.py | 26 ++++++----- 4 files changed, 87 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/switch/__init__.py b/homeassistant/components/switch/__init__.py index 359839a3946..95457b66f5f 100644 --- a/homeassistant/components/switch/__init__.py +++ b/homeassistant/components/switch/__init__.py @@ -7,6 +7,7 @@ import logging from datetime import timedelta from homeassistant.helpers.entity_component import EntityComponent +from homeassistant.helpers.entity import ToggleEntity from homeassistant.const import ( STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID) @@ -33,6 +34,11 @@ DISCOVERY_PLATFORMS = { isy994.DISCOVER_SWITCHES: 'isy994', } +PROP_TO_ATTR = { + 'current_power_mwh': ATTR_CURRENT_POWER_MWH, + 'today_power_mw': ATTR_TODAY_MWH, +} + _LOGGER = logging.getLogger(__name__) @@ -74,10 +80,48 @@ def setup(hass, config): else: switch.turn_off() - switch.update_ha_state(True) + if switch.should_poll: + switch.update_ha_state(True) hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_switch_service) hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_switch_service) return True + + +class SwitchDevice(ToggleEntity): + """ Represents a switch within Home Assistant. """ + # pylint: disable=no-self-use + + @property + def current_power_mwh(self): + """ Current power usage in mwh. """ + return None + + @property + def today_power_mw(self): + """ Today total power usage in mw. """ + return None + + @property + def device_state_attributes(self): + """ Returns device specific state attributes. """ + return None + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + data = {} + + for prop, attr in PROP_TO_ATTR.items(): + value = getattr(self, prop) + if value: + data[attr] = value + + device_attr = self.device_state_attributes + + if device_attr is not None: + data.update(device_attr) + + return data diff --git a/homeassistant/components/switch/command_switch.py b/homeassistant/components/switch/command_switch.py index 291cd3af04d..7cc51a1f9b9 100644 --- a/homeassistant/components/switch/command_switch.py +++ b/homeassistant/components/switch/command_switch.py @@ -6,8 +6,7 @@ homeassistant.components.switch.command_switch Allows to configure custom shell commands to turn a switch on/off. """ import logging -from homeassistant.helpers.entity import ToggleEntity -from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME +from homeassistant.components.switch import SwitchDevice import subprocess _LOGGER = logging.getLogger(__name__) @@ -30,11 +29,11 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): add_devices_callback(devices) -class CommandSwitch(ToggleEntity): +class CommandSwitch(SwitchDevice): """ Represents a switch that can be togggled using shell commands """ def __init__(self, name, command_on, command_off): - self._name = name or DEVICE_DEFAULT_NAME - self._state = STATE_OFF + self._name = name + self._state = False self._command_on = command_on self._command_off = command_off @@ -60,22 +59,19 @@ class CommandSwitch(ToggleEntity): """ The name of the switch """ return self._name - @property - def state(self): - """ Returns the state of the switch. """ - return self._state - @property def is_on(self): """ True if device is on. """ - return self._state == STATE_ON + return self._state def turn_on(self, **kwargs): """ Turn the device on. """ if CommandSwitch._switch(self._command_on): - self._state = STATE_ON + self._state = True + self.update_ha_state() def turn_off(self, **kwargs): """ Turn the device off. """ if CommandSwitch._switch(self._command_off): - self._state = STATE_OFF + self._state = False + self.update_ha_state() diff --git a/homeassistant/components/switch/demo.py b/homeassistant/components/switch/demo.py index b54b48a1c9b..7b2f077d6a8 100644 --- a/homeassistant/components/switch/demo.py +++ b/homeassistant/components/switch/demo.py @@ -5,20 +5,20 @@ homeassistant.components.switch.demo Demo platform that has two fake switches. """ -from homeassistant.helpers.entity import ToggleEntity -from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME +from homeassistant.components.switch import SwitchDevice +from homeassistant.const import DEVICE_DEFAULT_NAME # pylint: disable=unused-argument def setup_platform(hass, config, add_devices_callback, discovery_info=None): """ Find and return demo switches. """ add_devices_callback([ - DemoSwitch('Ceiling', STATE_ON), - DemoSwitch('AC', STATE_OFF) + DemoSwitch('Ceiling', True), + DemoSwitch('AC', False) ]) -class DemoSwitch(ToggleEntity): +class DemoSwitch(SwitchDevice): """ Provides a demo switch. """ def __init__(self, name, state): self._name = name or DEVICE_DEFAULT_NAME @@ -35,19 +35,27 @@ class DemoSwitch(ToggleEntity): return self._name @property - def state(self): - """ Returns the state of the device if any. """ - return self._state + def current_power_mwh(self): + """ Current power usage in mwh. """ + if self._state: + return 100 + + @property + def today_power_mw(self): + """ Today total power usage in mw. """ + return 1500 @property def is_on(self): """ True if device is on. """ - return self._state == STATE_ON + return self._state def turn_on(self, **kwargs): """ Turn the device on. """ - self._state = STATE_ON + self._state = True + self.update_ha_state() def turn_off(self, **kwargs): """ Turn the device off. """ - self._state = STATE_OFF + self._state = False + self.update_ha_state() diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index d8be9286413..eb55e0662b7 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -6,9 +6,7 @@ Support for WeMo switches. """ import logging -from homeassistant.helpers.entity import ToggleEntity -from homeassistant.components.switch import ( - ATTR_TODAY_MWH, ATTR_CURRENT_POWER_MWH) +from homeassistant.components.switch import SwitchDevice # pylint: disable=unused-argument @@ -43,10 +41,11 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): if isinstance(switch, pywemo.Switch)]) -class WemoSwitch(ToggleEntity): +class WemoSwitch(SwitchDevice): """ Represents a WeMo switch within Home Assistant. """ def __init__(self, wemo): self.wemo = wemo + self.insight_params = None @property def unique_id(self): @@ -59,15 +58,16 @@ class WemoSwitch(ToggleEntity): return self.wemo.name @property - def state_attributes(self): - """ Returns optional state attributes. """ - if self.wemo.model.startswith('Belkin Insight'): - cur_info = self.wemo.insight_params + def current_power_mwh(self): + """ Current power usage in mwh. """ + if self.insight_params: + return self.insight_params['currentpower'] - return { - ATTR_CURRENT_POWER_MWH: cur_info['currentpower'], - ATTR_TODAY_MWH: cur_info['todaymw'] - } + @property + def today_power_mw(self): + """ Today total power usage in mw. """ + if self.insight_params: + return self.insight_params['todaymw'] @property def is_on(self): @@ -85,3 +85,5 @@ class WemoSwitch(ToggleEntity): def update(self): """ Update WeMo state. """ self.wemo.get_state(True) + if self.wemo.model.startswith('Belkin Insight'): + self.insight_params = self.wemo.insight_params