Return state when changing optimistic covers (#23498)

This commit is contained in:
Paulus Schoutsen 2019-04-28 12:09:20 -07:00 committed by GitHub
parent 2f45a7e3b9
commit 0f49a9cb7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 39 deletions

View file

@ -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):

View file

@ -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)