diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index 7eb69d08724..752f40a0ead 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -408,7 +408,8 @@ class GoogleEntity: state = self.state domain = state.domain - features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + attributes = state.attributes + features = attributes.get(ATTR_SUPPORTED_FEATURES, 0) if not isinstance(features, int): _LOGGER.warning( @@ -423,7 +424,7 @@ class GoogleEntity: self._traits = [ Trait(self.hass, state, self.config) for Trait in trait.TRAITS - if Trait.supported(domain, features, device_class) + if Trait.supported(domain, features, device_class, attributes) ] return self._traits diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index 384c5bfd0ae..3bfce41ae2b 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -212,10 +212,11 @@ class BrightnessTrait(_Trait): commands = [COMMAND_BRIGHTNESS_ABSOLUTE] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, attributes): """Test if state is supported.""" + color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) if domain == light.DOMAIN: - return features & light.SUPPORT_BRIGHTNESS + return any(mode in color_modes for mode in light.COLOR_MODES_BRIGHTNESS) return False @@ -267,7 +268,7 @@ class CameraStreamTrait(_Trait): stream_info = None @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == camera.DOMAIN: return features & camera.SUPPORT_STREAM @@ -308,7 +309,7 @@ class OnOffTrait(_Trait): commands = [COMMAND_ONOFF] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" return domain in ( group.DOMAIN, @@ -362,23 +363,26 @@ class ColorSettingTrait(_Trait): commands = [COMMAND_COLOR_ABSOLUTE] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, attributes): """Test if state is supported.""" if domain != light.DOMAIN: return False - return features & light.SUPPORT_COLOR_TEMP or features & light.SUPPORT_COLOR + color_modes = attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) + return light.COLOR_MODE_COLOR_TEMP in color_modes or any( + mode in color_modes for mode in light.COLOR_MODES_COLOR + ) def sync_attributes(self): """Return color temperature attributes for a sync request.""" attrs = self.state.attributes - features = attrs.get(ATTR_SUPPORTED_FEATURES, 0) + color_modes = attrs.get(light.ATTR_SUPPORTED_COLOR_MODES, []) response = {} - if features & light.SUPPORT_COLOR: + if any(mode in color_modes for mode in light.COLOR_MODES_COLOR): response["colorModel"] = "hsv" - if features & light.SUPPORT_COLOR_TEMP: + if light.COLOR_MODE_COLOR_TEMP in color_modes: # Max Kelvin is Min Mireds K = 1000000 / mireds # Min Kelvin is Max Mireds K = 1000000 / mireds response["colorTemperatureRange"] = { @@ -394,10 +398,10 @@ class ColorSettingTrait(_Trait): def query_attributes(self): """Return color temperature query attributes.""" - features = self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + color_modes = self.state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) color = {} - if features & light.SUPPORT_COLOR: + if any(mode in color_modes for mode in light.COLOR_MODES_COLOR): color_hs = self.state.attributes.get(light.ATTR_HS_COLOR) brightness = self.state.attributes.get(light.ATTR_BRIGHTNESS, 1) if color_hs is not None: @@ -407,7 +411,7 @@ class ColorSettingTrait(_Trait): "value": brightness / 255, } - if features & light.SUPPORT_COLOR_TEMP: + if light.COLOR_MODE_COLOR_TEMP in color_modes: temp = self.state.attributes.get(light.ATTR_COLOR_TEMP) # Some faulty integrations might put 0 in here, raising exception. if temp == 0: @@ -495,7 +499,7 @@ class SceneTrait(_Trait): commands = [COMMAND_ACTIVATE_SCENE] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" return domain in (scene.DOMAIN, script.DOMAIN) @@ -531,7 +535,7 @@ class DockTrait(_Trait): commands = [COMMAND_DOCK] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" return domain == vacuum.DOMAIN @@ -565,7 +569,7 @@ class StartStopTrait(_Trait): commands = [COMMAND_STARTSTOP, COMMAND_PAUSEUNPAUSE] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == vacuum.DOMAIN: return True @@ -709,7 +713,7 @@ class TemperatureSettingTrait(_Trait): google_to_preset = {value: key for key, value in preset_to_google.items()} @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == climate.DOMAIN: return True @@ -976,7 +980,7 @@ class HumiditySettingTrait(_Trait): commands = [COMMAND_SET_HUMIDITY] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == humidifier.DOMAIN: return True @@ -1059,7 +1063,7 @@ class LockUnlockTrait(_Trait): commands = [COMMAND_LOCKUNLOCK] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" return domain == lock.DOMAIN @@ -1120,7 +1124,7 @@ class ArmDisArmTrait(_Trait): } @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" return domain == alarm_control_panel.DOMAIN @@ -1236,7 +1240,7 @@ class FanSpeedTrait(_Trait): } @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == fan.DOMAIN: return features & fan.SUPPORT_SET_SPEED @@ -1349,7 +1353,7 @@ class ModesTrait(_Trait): } @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == input_select.DOMAIN: return True @@ -1518,7 +1522,7 @@ class InputSelectorTrait(_Trait): SYNONYMS = {} @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == media_player.DOMAIN and ( features & media_player.SUPPORT_SELECT_SOURCE @@ -1591,7 +1595,7 @@ class OpenCloseTrait(_Trait): commands = [COMMAND_OPENCLOSE, COMMAND_OPENCLOSE_RELATIVE] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == cover.DOMAIN: return True @@ -1727,7 +1731,7 @@ class VolumeTrait(_Trait): commands = [COMMAND_SET_VOLUME, COMMAND_VOLUME_RELATIVE, COMMAND_MUTE] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if trait is supported.""" if domain == media_player.DOMAIN: return features & ( @@ -1915,7 +1919,7 @@ class TransportControlTrait(_Trait): ] @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" if domain == media_player.DOMAIN: for feature in MEDIA_COMMAND_SUPPORT_MAPPING.values(): @@ -2034,7 +2038,7 @@ class MediaStateTrait(_Trait): } @staticmethod - def supported(domain, features, device_class): + def supported(domain, features, device_class, _): """Test if state is supported.""" return domain == media_player.DOMAIN diff --git a/tests/components/google_assistant/test_smart_home.py b/tests/components/google_assistant/test_smart_home.py index 9531602ef0c..0dfa9e2a5e9 100644 --- a/tests/components/google_assistant/test_smart_home.py +++ b/tests/components/google_assistant/test_smart_home.py @@ -1171,7 +1171,7 @@ async def test_sync_message_recovery(hass, caplog): "on", { "min_mireds": "badvalue", - "supported_features": hass.components.light.SUPPORT_COLOR_TEMP, + "supported_color_modes": ["color_temp"], }, ) @@ -1220,7 +1220,7 @@ async def test_query_recover(hass, caplog): "light.good", "on", { - "supported_features": hass.components.light.SUPPORT_BRIGHTNESS, + "supported_color_modes": ["brightness"], "brightness": 50, }, ) @@ -1228,7 +1228,7 @@ async def test_query_recover(hass, caplog): "light.bad", "on", { - "supported_features": hass.components.light.SUPPORT_BRIGHTNESS, + "supported_color_modes": ["brightness"], "brightness": "shoe", }, ) diff --git a/tests/components/google_assistant/test_trait.py b/tests/components/google_assistant/test_trait.py index fd62d225aac..1d70027024a 100644 --- a/tests/components/google_assistant/test_trait.py +++ b/tests/components/google_assistant/test_trait.py @@ -70,10 +70,15 @@ PIN_DATA = helpers.RequestData( ) -async def test_brightness_light(hass): +@pytest.mark.parametrize( + "supported_color_modes", [["brightness"], ["hs"], ["color_temp"]] +) +async def test_brightness_light(hass, supported_color_modes): """Test brightness trait support for light domain.""" assert helpers.get_google_type(light.DOMAIN, None) is not None - assert trait.BrightnessTrait.supported(light.DOMAIN, light.SUPPORT_BRIGHTNESS, None) + assert trait.BrightnessTrait.supported( + light.DOMAIN, 0, None, {"supported_color_modes": supported_color_modes} + ) trt = trait.BrightnessTrait( hass, @@ -111,7 +116,9 @@ async def test_camera_stream(hass): {"external_url": "https://example.com"}, ) assert helpers.get_google_type(camera.DOMAIN, None) is not None - assert trait.CameraStreamTrait.supported(camera.DOMAIN, camera.SUPPORT_STREAM, None) + assert trait.CameraStreamTrait.supported( + camera.DOMAIN, camera.SUPPORT_STREAM, None, None + ) trt = trait.CameraStreamTrait( hass, State("camera.bla", camera.STATE_IDLE, {}), BASIC_CONFIG @@ -140,7 +147,7 @@ async def test_camera_stream(hass): async def test_onoff_group(hass): """Test OnOff trait support for group domain.""" assert helpers.get_google_type(group.DOMAIN, None) is not None - assert trait.OnOffTrait.supported(group.DOMAIN, 0, None) + assert trait.OnOffTrait.supported(group.DOMAIN, 0, None, None) trt_on = trait.OnOffTrait(hass, State("group.bla", STATE_ON), BASIC_CONFIG) @@ -166,7 +173,7 @@ async def test_onoff_group(hass): async def test_onoff_input_boolean(hass): """Test OnOff trait support for input_boolean domain.""" assert helpers.get_google_type(input_boolean.DOMAIN, None) is not None - assert trait.OnOffTrait.supported(input_boolean.DOMAIN, 0, None) + assert trait.OnOffTrait.supported(input_boolean.DOMAIN, 0, None, None) trt_on = trait.OnOffTrait(hass, State("input_boolean.bla", STATE_ON), BASIC_CONFIG) @@ -194,7 +201,7 @@ async def test_onoff_input_boolean(hass): async def test_onoff_switch(hass): """Test OnOff trait support for switch domain.""" assert helpers.get_google_type(switch.DOMAIN, None) is not None - assert trait.OnOffTrait.supported(switch.DOMAIN, 0, None) + assert trait.OnOffTrait.supported(switch.DOMAIN, 0, None, None) trt_on = trait.OnOffTrait(hass, State("switch.bla", STATE_ON), BASIC_CONFIG) @@ -225,7 +232,7 @@ async def test_onoff_switch(hass): async def test_onoff_fan(hass): """Test OnOff trait support for fan domain.""" assert helpers.get_google_type(fan.DOMAIN, None) is not None - assert trait.OnOffTrait.supported(fan.DOMAIN, 0, None) + assert trait.OnOffTrait.supported(fan.DOMAIN, 0, None, None) trt_on = trait.OnOffTrait(hass, State("fan.bla", STATE_ON), BASIC_CONFIG) @@ -250,7 +257,7 @@ async def test_onoff_fan(hass): async def test_onoff_light(hass): """Test OnOff trait support for light domain.""" assert helpers.get_google_type(light.DOMAIN, None) is not None - assert trait.OnOffTrait.supported(light.DOMAIN, 0, None) + assert trait.OnOffTrait.supported(light.DOMAIN, 0, None, None) trt_on = trait.OnOffTrait(hass, State("light.bla", STATE_ON), BASIC_CONFIG) @@ -276,7 +283,7 @@ async def test_onoff_light(hass): async def test_onoff_media_player(hass): """Test OnOff trait support for media_player domain.""" assert helpers.get_google_type(media_player.DOMAIN, None) is not None - assert trait.OnOffTrait.supported(media_player.DOMAIN, 0, None) + assert trait.OnOffTrait.supported(media_player.DOMAIN, 0, None, None) trt_on = trait.OnOffTrait(hass, State("media_player.bla", STATE_ON), BASIC_CONFIG) @@ -303,7 +310,7 @@ async def test_onoff_media_player(hass): async def test_onoff_humidifier(hass): """Test OnOff trait support for humidifier domain.""" assert helpers.get_google_type(humidifier.DOMAIN, None) is not None - assert trait.OnOffTrait.supported(humidifier.DOMAIN, 0, None) + assert trait.OnOffTrait.supported(humidifier.DOMAIN, 0, None, None) trt_on = trait.OnOffTrait(hass, State("humidifier.bla", STATE_ON), BASIC_CONFIG) @@ -330,7 +337,7 @@ async def test_onoff_humidifier(hass): async def test_dock_vacuum(hass): """Test dock trait support for vacuum domain.""" assert helpers.get_google_type(vacuum.DOMAIN, None) is not None - assert trait.DockTrait.supported(vacuum.DOMAIN, 0, None) + assert trait.DockTrait.supported(vacuum.DOMAIN, 0, None, None) trt = trait.DockTrait(hass, State("vacuum.bla", vacuum.STATE_IDLE), BASIC_CONFIG) @@ -347,7 +354,7 @@ async def test_dock_vacuum(hass): async def test_startstop_vacuum(hass): """Test startStop trait support for vacuum domain.""" assert helpers.get_google_type(vacuum.DOMAIN, None) is not None - assert trait.StartStopTrait.supported(vacuum.DOMAIN, 0, None) + assert trait.StartStopTrait.supported(vacuum.DOMAIN, 0, None, None) trt = trait.StartStopTrait( hass, @@ -387,7 +394,7 @@ async def test_startstop_vacuum(hass): async def test_startstop_cover(hass): """Test startStop trait support for cover domain.""" assert helpers.get_google_type(cover.DOMAIN, None) is not None - assert trait.StartStopTrait.supported(cover.DOMAIN, cover.SUPPORT_STOP, None) + assert trait.StartStopTrait.supported(cover.DOMAIN, cover.SUPPORT_STOP, None, None) state = State( "cover.bla", @@ -447,11 +454,14 @@ async def test_startstop_cover_assumed(hass): assert stop_calls[0].data == {ATTR_ENTITY_ID: "cover.bla"} -async def test_color_setting_color_light(hass): +@pytest.mark.parametrize("supported_color_modes", [["hs"], ["rgb"], ["xy"]]) +async def test_color_setting_color_light(hass, supported_color_modes): """Test ColorSpectrum trait support for light domain.""" assert helpers.get_google_type(light.DOMAIN, None) is not None - assert not trait.ColorSettingTrait.supported(light.DOMAIN, 0, None) - assert trait.ColorSettingTrait.supported(light.DOMAIN, light.SUPPORT_COLOR, None) + assert not trait.ColorSettingTrait.supported(light.DOMAIN, 0, None, {}) + assert trait.ColorSettingTrait.supported( + light.DOMAIN, 0, None, {"supported_color_modes": supported_color_modes} + ) trt = trait.ColorSettingTrait( hass, @@ -461,7 +471,7 @@ async def test_color_setting_color_light(hass): { light.ATTR_HS_COLOR: (20, 94), light.ATTR_BRIGHTNESS: 200, - ATTR_SUPPORTED_FEATURES: light.SUPPORT_COLOR, + "supported_color_modes": supported_color_modes, }, ), BASIC_CONFIG, @@ -507,9 +517,9 @@ async def test_color_setting_color_light(hass): async def test_color_setting_temperature_light(hass): """Test ColorTemperature trait support for light domain.""" assert helpers.get_google_type(light.DOMAIN, None) is not None - assert not trait.ColorSettingTrait.supported(light.DOMAIN, 0, None) + assert not trait.ColorSettingTrait.supported(light.DOMAIN, 0, None, {}) assert trait.ColorSettingTrait.supported( - light.DOMAIN, light.SUPPORT_COLOR_TEMP, None + light.DOMAIN, 0, None, {"supported_color_modes": ["color_temp"]} ) trt = trait.ColorSettingTrait( @@ -521,7 +531,7 @@ async def test_color_setting_temperature_light(hass): light.ATTR_MIN_MIREDS: 200, light.ATTR_COLOR_TEMP: 300, light.ATTR_MAX_MIREDS: 500, - ATTR_SUPPORTED_FEATURES: light.SUPPORT_COLOR_TEMP, + "supported_color_modes": ["color_temp"], }, ), BASIC_CONFIG, @@ -560,9 +570,9 @@ async def test_color_setting_temperature_light(hass): async def test_color_light_temperature_light_bad_temp(hass): """Test ColorTemperature trait support for light domain.""" assert helpers.get_google_type(light.DOMAIN, None) is not None - assert not trait.ColorSettingTrait.supported(light.DOMAIN, 0, None) + assert not trait.ColorSettingTrait.supported(light.DOMAIN, 0, None, {}) assert trait.ColorSettingTrait.supported( - light.DOMAIN, light.SUPPORT_COLOR_TEMP, None + light.DOMAIN, 0, None, {"supported_color_modes": ["color_temp"]} ) trt = trait.ColorSettingTrait( @@ -585,7 +595,7 @@ async def test_color_light_temperature_light_bad_temp(hass): async def test_light_modes(hass): """Test Light Mode trait.""" assert helpers.get_google_type(light.DOMAIN, None) is not None - assert trait.ModesTrait.supported(light.DOMAIN, light.SUPPORT_EFFECT, None) + assert trait.ModesTrait.supported(light.DOMAIN, light.SUPPORT_EFFECT, None, None) trt = trait.ModesTrait( hass, @@ -653,7 +663,7 @@ async def test_light_modes(hass): async def test_scene_scene(hass): """Test Scene trait support for scene domain.""" assert helpers.get_google_type(scene.DOMAIN, None) is not None - assert trait.SceneTrait.supported(scene.DOMAIN, 0, None) + assert trait.SceneTrait.supported(scene.DOMAIN, 0, None, None) trt = trait.SceneTrait(hass, State("scene.bla", scene.STATE), BASIC_CONFIG) assert trt.sync_attributes() == {} @@ -669,7 +679,7 @@ async def test_scene_scene(hass): async def test_scene_script(hass): """Test Scene trait support for script domain.""" assert helpers.get_google_type(script.DOMAIN, None) is not None - assert trait.SceneTrait.supported(script.DOMAIN, 0, None) + assert trait.SceneTrait.supported(script.DOMAIN, 0, None, None) trt = trait.SceneTrait(hass, State("script.bla", STATE_OFF), BASIC_CONFIG) assert trt.sync_attributes() == {} @@ -689,7 +699,7 @@ async def test_scene_script(hass): async def test_temperature_setting_climate_onoff(hass): """Test TemperatureSetting trait support for climate domain - range.""" assert helpers.get_google_type(climate.DOMAIN, None) is not None - assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None) + assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None, None) hass.config.units.temperature_unit = TEMP_FAHRENHEIT @@ -734,7 +744,7 @@ async def test_temperature_setting_climate_onoff(hass): async def test_temperature_setting_climate_no_modes(hass): """Test TemperatureSetting trait support for climate domain not supporting any modes.""" assert helpers.get_google_type(climate.DOMAIN, None) is not None - assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None) + assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None, None) hass.config.units.temperature_unit = TEMP_CELSIUS @@ -760,7 +770,7 @@ async def test_temperature_setting_climate_no_modes(hass): async def test_temperature_setting_climate_range(hass): """Test TemperatureSetting trait support for climate domain - range.""" assert helpers.get_google_type(climate.DOMAIN, None) is not None - assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None) + assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None, None) hass.config.units.temperature_unit = TEMP_FAHRENHEIT @@ -842,7 +852,7 @@ async def test_temperature_setting_climate_range(hass): async def test_temperature_setting_climate_setpoint(hass): """Test TemperatureSetting trait support for climate domain - setpoint.""" assert helpers.get_google_type(climate.DOMAIN, None) is not None - assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None) + assert trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0, None, None) hass.config.units.temperature_unit = TEMP_CELSIUS @@ -947,7 +957,7 @@ async def test_temperature_setting_climate_setpoint_auto(hass): async def test_humidity_setting_humidifier_setpoint(hass): """Test HumiditySetting trait support for humidifier domain - setpoint.""" assert helpers.get_google_type(humidifier.DOMAIN, None) is not None - assert trait.HumiditySettingTrait.supported(humidifier.DOMAIN, 0, None) + assert trait.HumiditySettingTrait.supported(humidifier.DOMAIN, 0, None, None) trt = trait.HumiditySettingTrait( hass, @@ -983,7 +993,7 @@ async def test_humidity_setting_humidifier_setpoint(hass): async def test_lock_unlock_lock(hass): """Test LockUnlock trait locking support for lock domain.""" assert helpers.get_google_type(lock.DOMAIN, None) is not None - assert trait.LockUnlockTrait.supported(lock.DOMAIN, lock.SUPPORT_OPEN, None) + assert trait.LockUnlockTrait.supported(lock.DOMAIN, lock.SUPPORT_OPEN, None, None) assert trait.LockUnlockTrait.might_2fa(lock.DOMAIN, lock.SUPPORT_OPEN, None) trt = trait.LockUnlockTrait( @@ -1007,7 +1017,7 @@ async def test_lock_unlock_lock(hass): async def test_lock_unlock_unlock(hass): """Test LockUnlock trait unlocking support for lock domain.""" assert helpers.get_google_type(lock.DOMAIN, None) is not None - assert trait.LockUnlockTrait.supported(lock.DOMAIN, lock.SUPPORT_OPEN, None) + assert trait.LockUnlockTrait.supported(lock.DOMAIN, lock.SUPPORT_OPEN, None, None) trt = trait.LockUnlockTrait( hass, State("lock.front_door", lock.STATE_LOCKED), PIN_CONFIG @@ -1067,7 +1077,7 @@ async def test_lock_unlock_unlock(hass): async def test_arm_disarm_arm_away(hass): """Test ArmDisarm trait Arming support for alarm_control_panel domain.""" assert helpers.get_google_type(alarm_control_panel.DOMAIN, None) is not None - assert trait.ArmDisArmTrait.supported(alarm_control_panel.DOMAIN, 0, None) + assert trait.ArmDisArmTrait.supported(alarm_control_panel.DOMAIN, 0, None, None) assert trait.ArmDisArmTrait.might_2fa(alarm_control_panel.DOMAIN, 0, None) trt = trait.ArmDisArmTrait( @@ -1230,7 +1240,7 @@ async def test_arm_disarm_arm_away(hass): async def test_arm_disarm_disarm(hass): """Test ArmDisarm trait Disarming support for alarm_control_panel domain.""" assert helpers.get_google_type(alarm_control_panel.DOMAIN, None) is not None - assert trait.ArmDisArmTrait.supported(alarm_control_panel.DOMAIN, 0, None) + assert trait.ArmDisArmTrait.supported(alarm_control_panel.DOMAIN, 0, None, None) assert trait.ArmDisArmTrait.might_2fa(alarm_control_panel.DOMAIN, 0, None) trt = trait.ArmDisArmTrait( @@ -1376,7 +1386,7 @@ async def test_arm_disarm_disarm(hass): async def test_fan_speed(hass): """Test FanSpeed trait speed control support for fan domain.""" assert helpers.get_google_type(fan.DOMAIN, None) is not None - assert trait.FanSpeedTrait.supported(fan.DOMAIN, fan.SUPPORT_SET_SPEED, None) + assert trait.FanSpeedTrait.supported(fan.DOMAIN, fan.SUPPORT_SET_SPEED, None, None) trt = trait.FanSpeedTrait( hass, @@ -1468,7 +1478,9 @@ async def test_fan_speed(hass): async def test_climate_fan_speed(hass): """Test FanSpeed trait speed control support for climate domain.""" assert helpers.get_google_type(climate.DOMAIN, None) is not None - assert trait.FanSpeedTrait.supported(climate.DOMAIN, climate.SUPPORT_FAN_MODE, None) + assert trait.FanSpeedTrait.supported( + climate.DOMAIN, climate.SUPPORT_FAN_MODE, None, None + ) trt = trait.FanSpeedTrait( hass, @@ -1529,7 +1541,7 @@ async def test_inputselector(hass): """Test input selector trait.""" assert helpers.get_google_type(media_player.DOMAIN, None) is not None assert trait.InputSelectorTrait.supported( - media_player.DOMAIN, media_player.SUPPORT_SELECT_SOURCE, None + media_player.DOMAIN, media_player.SUPPORT_SELECT_SOURCE, None, None ) trt = trait.InputSelectorTrait( @@ -1686,7 +1698,7 @@ async def test_inputselector_nextprev_invalid(hass, sources, source): async def test_modes_input_select(hass): """Test Input Select Mode trait.""" assert helpers.get_google_type(input_select.DOMAIN, None) is not None - assert trait.ModesTrait.supported(input_select.DOMAIN, None, None) + assert trait.ModesTrait.supported(input_select.DOMAIN, None, None, None) trt = trait.ModesTrait( hass, @@ -1762,7 +1774,9 @@ async def test_modes_input_select(hass): async def test_modes_humidifier(hass): """Test Humidifier Mode trait.""" assert helpers.get_google_type(humidifier.DOMAIN, None) is not None - assert trait.ModesTrait.supported(humidifier.DOMAIN, humidifier.SUPPORT_MODES, None) + assert trait.ModesTrait.supported( + humidifier.DOMAIN, humidifier.SUPPORT_MODES, None, None + ) trt = trait.ModesTrait( hass, @@ -1840,7 +1854,7 @@ async def test_sound_modes(hass): """Test Mode trait.""" assert helpers.get_google_type(media_player.DOMAIN, None) is not None assert trait.ModesTrait.supported( - media_player.DOMAIN, media_player.SUPPORT_SELECT_SOUND_MODE, None + media_player.DOMAIN, media_player.SUPPORT_SELECT_SOUND_MODE, None, None ) trt = trait.ModesTrait( @@ -1914,7 +1928,7 @@ async def test_openclose_cover(hass): """Test OpenClose trait support for cover domain.""" assert helpers.get_google_type(cover.DOMAIN, None) is not None assert trait.OpenCloseTrait.supported( - cover.DOMAIN, cover.SUPPORT_SET_POSITION, None + cover.DOMAIN, cover.SUPPORT_SET_POSITION, None, None ) trt = trait.OpenCloseTrait( @@ -1951,7 +1965,7 @@ async def test_openclose_cover_unknown_state(hass): """Test OpenClose trait support for cover domain with unknown state.""" assert helpers.get_google_type(cover.DOMAIN, None) is not None assert trait.OpenCloseTrait.supported( - cover.DOMAIN, cover.SUPPORT_SET_POSITION, None + cover.DOMAIN, cover.SUPPORT_SET_POSITION, None, None ) # No state @@ -1981,7 +1995,7 @@ async def test_openclose_cover_assumed_state(hass): """Test OpenClose trait support for cover domain.""" assert helpers.get_google_type(cover.DOMAIN, None) is not None assert trait.OpenCloseTrait.supported( - cover.DOMAIN, cover.SUPPORT_SET_POSITION, None + cover.DOMAIN, cover.SUPPORT_SET_POSITION, None, None ) trt = trait.OpenCloseTrait( @@ -2010,7 +2024,7 @@ async def test_openclose_cover_assumed_state(hass): async def test_openclose_cover_query_only(hass): """Test OpenClose trait support for cover domain.""" assert helpers.get_google_type(cover.DOMAIN, None) is not None - assert trait.OpenCloseTrait.supported(cover.DOMAIN, 0, None) + assert trait.OpenCloseTrait.supported(cover.DOMAIN, 0, None, None) state = State( "cover.bla", @@ -2034,7 +2048,7 @@ async def test_openclose_cover_no_position(hass): """Test OpenClose trait support for cover domain.""" assert helpers.get_google_type(cover.DOMAIN, None) is not None assert trait.OpenCloseTrait.supported( - cover.DOMAIN, cover.SUPPORT_OPEN | cover.SUPPORT_CLOSE, None + cover.DOMAIN, cover.SUPPORT_OPEN | cover.SUPPORT_CLOSE, None, None ) state = State( @@ -2091,7 +2105,7 @@ async def test_openclose_cover_secure(hass, device_class): """Test OpenClose trait support for cover domain.""" assert helpers.get_google_type(cover.DOMAIN, device_class) is not None assert trait.OpenCloseTrait.supported( - cover.DOMAIN, cover.SUPPORT_SET_POSITION, device_class + cover.DOMAIN, cover.SUPPORT_SET_POSITION, device_class, None ) assert trait.OpenCloseTrait.might_2fa( cover.DOMAIN, cover.SUPPORT_SET_POSITION, device_class @@ -2158,7 +2172,7 @@ async def test_openclose_cover_secure(hass, device_class): async def test_openclose_binary_sensor(hass, device_class): """Test OpenClose trait support for binary_sensor domain.""" assert helpers.get_google_type(binary_sensor.DOMAIN, device_class) is not None - assert trait.OpenCloseTrait.supported(binary_sensor.DOMAIN, 0, device_class) + assert trait.OpenCloseTrait.supported(binary_sensor.DOMAIN, 0, device_class, None) trt = trait.OpenCloseTrait( hass, @@ -2191,9 +2205,7 @@ async def test_volume_media_player(hass): """Test volume trait support for media player domain.""" assert helpers.get_google_type(media_player.DOMAIN, None) is not None assert trait.VolumeTrait.supported( - media_player.DOMAIN, - media_player.SUPPORT_VOLUME_SET, - None, + media_player.DOMAIN, media_player.SUPPORT_VOLUME_SET, None, None ) trt = trait.VolumeTrait( @@ -2244,9 +2256,7 @@ async def test_volume_media_player(hass): async def test_volume_media_player_relative(hass): """Test volume trait support for relative-volume-only media players.""" assert trait.VolumeTrait.supported( - media_player.DOMAIN, - media_player.SUPPORT_VOLUME_STEP, - None, + media_player.DOMAIN, media_player.SUPPORT_VOLUME_STEP, None, None ) trt = trait.VolumeTrait( hass, @@ -2314,6 +2324,7 @@ async def test_media_player_mute(hass): media_player.DOMAIN, media_player.SUPPORT_VOLUME_STEP | media_player.SUPPORT_VOLUME_MUTE, None, + None, ) trt = trait.VolumeTrait( hass, @@ -2376,10 +2387,10 @@ async def test_temperature_setting_sensor(hass): is not None ) assert not trait.TemperatureSettingTrait.supported( - sensor.DOMAIN, 0, sensor.DEVICE_CLASS_HUMIDITY + sensor.DOMAIN, 0, sensor.DEVICE_CLASS_HUMIDITY, None ) assert trait.TemperatureSettingTrait.supported( - sensor.DOMAIN, 0, sensor.DEVICE_CLASS_TEMPERATURE + sensor.DOMAIN, 0, sensor.DEVICE_CLASS_TEMPERATURE, None ) @@ -2422,10 +2433,10 @@ async def test_humidity_setting_sensor(hass): helpers.get_google_type(sensor.DOMAIN, sensor.DEVICE_CLASS_HUMIDITY) is not None ) assert not trait.HumiditySettingTrait.supported( - sensor.DOMAIN, 0, sensor.DEVICE_CLASS_TEMPERATURE + sensor.DOMAIN, 0, sensor.DEVICE_CLASS_TEMPERATURE, None ) assert trait.HumiditySettingTrait.supported( - sensor.DOMAIN, 0, sensor.DEVICE_CLASS_HUMIDITY + sensor.DOMAIN, 0, sensor.DEVICE_CLASS_HUMIDITY, None ) @@ -2456,7 +2467,9 @@ async def test_transport_control(hass): assert helpers.get_google_type(media_player.DOMAIN, None) is not None for feature in trait.MEDIA_COMMAND_SUPPORT_MAPPING.values(): - assert trait.TransportControlTrait.supported(media_player.DOMAIN, feature, None) + assert trait.TransportControlTrait.supported( + media_player.DOMAIN, feature, None, None + ) now = datetime(2020, 1, 1) @@ -2586,7 +2599,7 @@ async def test_media_state(hass, state): assert helpers.get_google_type(media_player.DOMAIN, None) is not None assert trait.TransportControlTrait.supported( - media_player.DOMAIN, media_player.SUPPORT_PLAY, None + media_player.DOMAIN, media_player.SUPPORT_PLAY, None, None ) trt = trait.MediaStateTrait(