Implement capability attributes (#30545)

* Implement capability attributes

* Fix HeOS update order

* Fix test
This commit is contained in:
Paulus Schoutsen 2020-01-08 21:22:56 +01:00 committed by GitHub
parent 4cd83e71dd
commit ed6aef2fd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 14 deletions

View File

@ -47,7 +47,6 @@ ATTR_DIRECTION = "direction"
PROP_TO_ATTR = { PROP_TO_ATTR = {
"speed": ATTR_SPEED, "speed": ATTR_SPEED,
"speed_list": ATTR_SPEED_LIST,
"oscillating": ATTR_OSCILLATING, "oscillating": ATTR_OSCILLATING,
"current_direction": ATTR_DIRECTION, "current_direction": ATTR_DIRECTION,
} }
@ -178,6 +177,11 @@ class FanEntity(ToggleEntity):
"""Return the current direction of the fan.""" """Return the current direction of the fan."""
return None return None
@property
def capability_attributes(self):
"""Return capabilitiy attributes."""
return {ATTR_SPEED_LIST: self.speed_list}
@property @property
def state_attributes(self) -> dict: def state_attributes(self) -> dict:
"""Return optional state attributes.""" """Return optional state attributes."""

View File

@ -115,7 +115,6 @@ class HeosMediaPlayer(MediaPlayerDevice):
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Device added to hass.""" """Device added to hass."""
self._source_manager = self.hass.data[HEOS_DOMAIN][DATA_SOURCE_MANAGER]
# Update state when attributes of the player change # Update state when attributes of the player change
self._signals.append( self._signals.append(
self._player.heos.dispatcher.connect( self._player.heos.dispatcher.connect(
@ -242,6 +241,9 @@ class HeosMediaPlayer(MediaPlayerDevice):
current_support = [CONTROL_TO_SUPPORT[control] for control in controls] current_support = [CONTROL_TO_SUPPORT[control] for control in controls]
self._supported_features = reduce(ior, current_support, BASE_SUPPORTED_FEATURES) self._supported_features = reduce(ior, current_support, BASE_SUPPORTED_FEATURES)
if self._source_manager is None:
self._source_manager = self.hass.data[HEOS_DOMAIN][DATA_SOURCE_MANAGER]
async def async_will_remove_from_hass(self): async def async_will_remove_from_hass(self):
"""Disconnect the device when removed.""" """Disconnect the device when removed."""
for signal_remove in self._signals: for signal_remove in self._signals:

View File

@ -149,9 +149,7 @@ ATTR_TO_PROPERTY = [
ATTR_APP_ID, ATTR_APP_ID,
ATTR_APP_NAME, ATTR_APP_NAME,
ATTR_INPUT_SOURCE, ATTR_INPUT_SOURCE,
ATTR_INPUT_SOURCE_LIST,
ATTR_SOUND_MODE, ATTR_SOUND_MODE,
ATTR_SOUND_MODE_LIST,
ATTR_MEDIA_SHUFFLE, ATTR_MEDIA_SHUFFLE,
] ]
@ -784,6 +782,24 @@ class MediaPlayerDevice(Entity):
return ENTITY_IMAGE_URL.format(self.entity_id, self.access_token, image_hash) return ENTITY_IMAGE_URL.format(self.entity_id, self.access_token, image_hash)
@property
def capability_attributes(self):
"""Return capabilitiy attributes."""
supported_features = self.supported_features
data = {}
if supported_features & SUPPORT_SELECT_SOURCE:
source_list = self.source_list
if source_list:
data[ATTR_INPUT_SOURCE_LIST] = source_list
if supported_features & SUPPORT_SELECT_SOUND_MODE:
sound_mode_list = self.sound_mode_list
if sound_mode_list:
data[ATTR_SOUND_MODE_LIST] = sound_mode_list
return data
@property @property
def state_attributes(self): def state_attributes(self):
"""Return the state attributes.""" """Return the state attributes."""

View File

@ -246,6 +246,12 @@ class VacuumDevice(_BaseVacuum, ToggleEntity):
battery_level=self.battery_level, charging=charging battery_level=self.battery_level, charging=charging
) )
@property
def capability_attributes(self):
"""Return capabilitiy attributes."""
if self.fan_speed is not None:
return {ATTR_FAN_SPEED_LIST: self.fan_speed_list}
@property @property
def state_attributes(self): def state_attributes(self):
"""Return the state attributes of the vacuum cleaner.""" """Return the state attributes of the vacuum cleaner."""
@ -260,7 +266,6 @@ class VacuumDevice(_BaseVacuum, ToggleEntity):
if self.fan_speed is not None: if self.fan_speed is not None:
data[ATTR_FAN_SPEED] = self.fan_speed data[ATTR_FAN_SPEED] = self.fan_speed
data[ATTR_FAN_SPEED_LIST] = self.fan_speed_list
return data return data
@ -323,6 +328,12 @@ class StateVacuumDevice(_BaseVacuum):
battery_level=self.battery_level, charging=charging battery_level=self.battery_level, charging=charging
) )
@property
def capability_attributes(self):
"""Return capabilitiy attributes."""
if self.fan_speed is not None:
return {ATTR_FAN_SPEED_LIST: self.fan_speed_list}
@property @property
def state_attributes(self): def state_attributes(self):
"""Return the state attributes of the vacuum cleaner.""" """Return the state attributes of the vacuum cleaner."""

View File

@ -143,6 +143,25 @@ class WaterHeaterDevice(Entity):
return PRECISION_TENTHS return PRECISION_TENTHS
return PRECISION_WHOLE return PRECISION_WHOLE
@property
def capability_attributes(self):
"""Return capabilitiy attributes."""
supported_features = self.supported_features
data = {
ATTR_MIN_TEMP: show_temp(
self.hass, self.min_temp, self.temperature_unit, self.precision
),
ATTR_MAX_TEMP: show_temp(
self.hass, self.max_temp, self.temperature_unit, self.precision
),
}
if supported_features & SUPPORT_OPERATION_MODE:
data[ATTR_OPERATION_LIST] = self.operation_list
return data
@property @property
def state_attributes(self): def state_attributes(self):
"""Return the optional state attributes.""" """Return the optional state attributes."""
@ -153,12 +172,6 @@ class WaterHeaterDevice(Entity):
self.temperature_unit, self.temperature_unit,
self.precision, self.precision,
), ),
ATTR_MIN_TEMP: show_temp(
self.hass, self.min_temp, self.temperature_unit, self.precision
),
ATTR_MAX_TEMP: show_temp(
self.hass, self.max_temp, self.temperature_unit, self.precision
),
ATTR_TEMPERATURE: show_temp( ATTR_TEMPERATURE: show_temp(
self.hass, self.hass,
self.target_temperature, self.target_temperature,
@ -183,8 +196,6 @@ class WaterHeaterDevice(Entity):
if supported_features & SUPPORT_OPERATION_MODE: if supported_features & SUPPORT_OPERATION_MODE:
data[ATTR_OPERATION_MODE] = self.current_operation data[ATTR_OPERATION_MODE] = self.current_operation
if self.operation_list:
data[ATTR_OPERATION_LIST] = self.operation_list
if supported_features & SUPPORT_AWAY_MODE: if supported_features & SUPPORT_AWAY_MODE:
is_away = self.is_away_mode_on is_away = self.is_away_mode_on

View File

@ -31,7 +31,7 @@ class TestFanEntity(unittest.TestCase):
assert "off" == self.fan.state assert "off" == self.fan.state
assert 0 == len(self.fan.speed_list) assert 0 == len(self.fan.speed_list)
assert 0 == self.fan.supported_features assert 0 == self.fan.supported_features
assert {"speed_list": []} == self.fan.state_attributes assert {"speed_list": []} == self.fan.capability_attributes
# Test set_speed not required # Test set_speed not required
self.fan.oscillate(True) self.fan.oscillate(True)
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):