Return state when changing optimistic covers (#23498)
This commit is contained in:
parent
2f45a7e3b9
commit
0f49a9cb7b
2 changed files with 105 additions and 39 deletions
|
@ -1027,6 +1027,8 @@ class OpenCloseTrait(_Trait):
|
|||
COMMAND_OPENCLOSE
|
||||
]
|
||||
|
||||
override_position = None
|
||||
|
||||
@staticmethod
|
||||
def supported(domain, features, device_class):
|
||||
"""Test if state is supported."""
|
||||
|
@ -1043,20 +1045,22 @@ class OpenCloseTrait(_Trait):
|
|||
|
||||
def sync_attributes(self):
|
||||
"""Return opening direction."""
|
||||
attrs = {}
|
||||
response = {}
|
||||
if self.state.domain == binary_sensor.DOMAIN:
|
||||
attrs['queryOnlyOpenClose'] = True
|
||||
return attrs
|
||||
response['queryOnlyOpenClose'] = True
|
||||
return response
|
||||
|
||||
def query_attributes(self):
|
||||
"""Return state query attributes."""
|
||||
domain = self.state.domain
|
||||
response = {}
|
||||
|
||||
if domain == cover.DOMAIN:
|
||||
# When it's an assumed state, we will always report it as 50%
|
||||
# Google will not issue an open command if the assumed state is
|
||||
# open, even if that is currently incorrect.
|
||||
if self.override_position is not None:
|
||||
response['openPercent'] = self.override_position
|
||||
|
||||
elif domain == cover.DOMAIN:
|
||||
# When it's an assumed state, we will return that querying state
|
||||
# is not supported.
|
||||
if self.state.attributes.get(ATTR_ASSUMED_STATE):
|
||||
raise SmartHomeError(
|
||||
ERR_NOT_SUPPORTED,
|
||||
|
@ -1067,7 +1071,7 @@ class OpenCloseTrait(_Trait):
|
|||
ERR_NOT_SUPPORTED,
|
||||
'Querying state is not supported')
|
||||
|
||||
position = self.state.attributes.get(
|
||||
position = self.override_position or self.state.attributes.get(
|
||||
cover.ATTR_CURRENT_POSITION
|
||||
)
|
||||
|
||||
|
@ -1096,7 +1100,6 @@ class OpenCloseTrait(_Trait):
|
|||
):
|
||||
_verify_pin_challenge(data, challenge)
|
||||
|
||||
position = self.state.attributes.get(cover.ATTR_CURRENT_POSITION)
|
||||
if params['openPercent'] == 0:
|
||||
await self.hass.services.async_call(
|
||||
cover.DOMAIN, cover.SERVICE_CLOSE_COVER, {
|
||||
|
@ -1107,7 +1110,8 @@ class OpenCloseTrait(_Trait):
|
|||
cover.DOMAIN, cover.SERVICE_OPEN_COVER, {
|
||||
ATTR_ENTITY_ID: self.state.entity_id
|
||||
}, blocking=True, context=data.context)
|
||||
elif position is not None:
|
||||
elif (self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) &
|
||||
cover.SUPPORT_SET_POSITION):
|
||||
await self.hass.services.async_call(
|
||||
cover.DOMAIN, cover.SERVICE_SET_COVER_POSITION, {
|
||||
ATTR_ENTITY_ID: self.state.entity_id,
|
||||
|
@ -1118,6 +1122,11 @@ class OpenCloseTrait(_Trait):
|
|||
ERR_FUNCTION_NOT_SUPPORTED,
|
||||
'Setting a position is not supported')
|
||||
|
||||
if (self.state.attributes.get(ATTR_ASSUMED_STATE) or
|
||||
self.state.state == STATE_UNKNOWN):
|
||||
print("YOO")
|
||||
self.override_position = params['openPercent']
|
||||
|
||||
|
||||
@register_trait
|
||||
class VolumeTrait(_Trait):
|
||||
|
|
|
@ -1109,36 +1109,9 @@ async def test_openclose_cover(hass):
|
|||
assert trait.OpenCloseTrait.supported(cover.DOMAIN,
|
||||
cover.SUPPORT_SET_POSITION, None)
|
||||
|
||||
# No position
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', cover.STATE_OPEN, {
|
||||
}), BASIC_CONFIG)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
assert trt.query_attributes() == {
|
||||
'openPercent': 100
|
||||
}
|
||||
|
||||
# No state
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', STATE_UNKNOWN, {
|
||||
}), BASIC_CONFIG)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
|
||||
with pytest.raises(helpers.SmartHomeError):
|
||||
trt.query_attributes()
|
||||
|
||||
# Assumed state
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', cover.STATE_OPEN, {
|
||||
ATTR_ASSUMED_STATE: True,
|
||||
}), BASIC_CONFIG)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
|
||||
with pytest.raises(helpers.SmartHomeError):
|
||||
trt.query_attributes()
|
||||
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', cover.STATE_OPEN, {
|
||||
cover.ATTR_CURRENT_POSITION: 75
|
||||
cover.ATTR_CURRENT_POSITION: 75,
|
||||
ATTR_SUPPORTED_FEATURES: cover.SUPPORT_SET_POSITION,
|
||||
}), BASIC_CONFIG)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
|
@ -1158,6 +1131,89 @@ async def test_openclose_cover(hass):
|
|||
}
|
||||
|
||||
|
||||
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)
|
||||
|
||||
# No state
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', STATE_UNKNOWN, {
|
||||
}), BASIC_CONFIG)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
|
||||
with pytest.raises(helpers.SmartHomeError):
|
||||
trt.query_attributes()
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, cover.DOMAIN, cover.SERVICE_OPEN_COVER)
|
||||
await trt.execute(
|
||||
trait.COMMAND_OPENCLOSE, BASIC_DATA,
|
||||
{'openPercent': 100}, {})
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data == {
|
||||
ATTR_ENTITY_ID: 'cover.bla',
|
||||
}
|
||||
|
||||
assert trt.query_attributes() == {'openPercent': 100}
|
||||
|
||||
|
||||
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)
|
||||
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', cover.STATE_OPEN, {
|
||||
ATTR_ASSUMED_STATE: True,
|
||||
ATTR_SUPPORTED_FEATURES: cover.SUPPORT_SET_POSITION,
|
||||
}), BASIC_CONFIG)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
|
||||
with pytest.raises(helpers.SmartHomeError):
|
||||
trt.query_attributes()
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, cover.DOMAIN, cover.SERVICE_SET_COVER_POSITION)
|
||||
await trt.execute(
|
||||
trait.COMMAND_OPENCLOSE, BASIC_DATA,
|
||||
{'openPercent': 40}, {})
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data == {
|
||||
ATTR_ENTITY_ID: 'cover.bla',
|
||||
cover.ATTR_POSITION: 40
|
||||
}
|
||||
|
||||
assert trt.query_attributes() == {'openPercent': 40}
|
||||
|
||||
|
||||
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_SET_POSITION, None)
|
||||
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', cover.STATE_OPEN, {
|
||||
}), BASIC_CONFIG)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
assert trt.query_attributes() == {
|
||||
'openPercent': 100
|
||||
}
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, cover.DOMAIN, cover.SERVICE_CLOSE_COVER)
|
||||
await trt.execute(
|
||||
trait.COMMAND_OPENCLOSE, BASIC_DATA,
|
||||
{'openPercent': 0}, {})
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data == {
|
||||
ATTR_ENTITY_ID: 'cover.bla',
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('device_class', (
|
||||
cover.DEVICE_CLASS_DOOR,
|
||||
cover.DEVICE_CLASS_GARAGE,
|
||||
|
@ -1170,6 +1226,7 @@ async def test_openclose_cover_secure(hass, device_class):
|
|||
|
||||
trt = trait.OpenCloseTrait(hass, State('cover.bla', cover.STATE_OPEN, {
|
||||
ATTR_DEVICE_CLASS: device_class,
|
||||
ATTR_SUPPORTED_FEATURES: cover.SUPPORT_SET_POSITION,
|
||||
cover.ATTR_CURRENT_POSITION: 75
|
||||
}), PIN_CONFIG)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue