Set homekit alarm/sensor/switch/cover state as soon as possible (#34245)

* Set homekit alarm/sensor/switch state as soon as possible

This change is part of a multi-part effort to fix the
HomeKit event storms on startup.

Previously we would set the states after HomeKit
had started up which meant that when the controller
client connected it would request the states and get
a list of default states so all the initial states
would always be wrong. The defaults states generally went
unnoticed because we set the state of each HomeKit device
soon after which would result in an event storm in the log
that looked like the following for every client and every
device:

Sending event to client: ('192.168.x.x', 58410)
Sending event to client: ('192.168.x.x', 53399)
Sending event to client: ('192.168.x.x', 53399)

To solve this, we now set the state right away when we
create the entity in HomeKit, so it is correct on
initial sync, which avoids the event storm.  Additionally,
we now check all states values before sending an update
to HomeKit to ensure we do not send events when nothing
has changed.

* pylint

* Fix event storm in covers as well

* fix refactoring error in security system

* cover positions, now with constants
This commit is contained in:
J. Nick Koston authored and GitHub committed 2020-04-15 21:38:31 -05:00
1 parent 188f3e35fd
commit d6a47cb3e0
6 files changed
+146 -80

No files matched your search

+10 -10
View File
@@ -147,35 +147,35 @@ async def test_valve_set_state(hass, hk_driver, events):
assert acc.aid == 2
assert acc.category == 29 # Faucet
assert acc.char_active.value is False
assert acc.char_in_use.value is False
assert acc.char_active.value == 0
assert acc.char_in_use.value == 0
assert acc.char_valve_type.value == 0 # Generic Valve
hass.states.async_set(entity_id, STATE_ON)
await hass.async_block_till_done()
assert acc.char_active.value is True
assert acc.char_in_use.value is True
assert acc.char_active.value == 1
assert acc.char_in_use.value == 1
hass.states.async_set(entity_id, STATE_OFF)
await hass.async_block_till_done()
assert acc.char_active.value is False
assert acc.char_in_use.value is False
assert acc.char_active.value == 0
assert acc.char_in_use.value == 0
# Set from HomeKit
call_turn_on = async_mock_service(hass, "switch", "turn_on")
call_turn_off = async_mock_service(hass, "switch", "turn_off")
await hass.async_add_executor_job(acc.char_active.client_update_value, True)
await hass.async_add_executor_job(acc.char_active.client_update_value, 1)
await hass.async_block_till_done()
assert acc.char_in_use.value is True
assert acc.char_in_use.value == 1
assert call_turn_on
assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id
assert len(events) == 1
assert events[-1].data[ATTR_VALUE] is None
await hass.async_add_executor_job(acc.char_active.client_update_value, False)
await hass.async_add_executor_job(acc.char_active.client_update_value, 0)
await hass.async_block_till_done()
assert acc.char_in_use.value is False
assert acc.char_in_use.value == 0
assert call_turn_off
assert call_turn_off[0].data[ATTR_ENTITY_ID] == entity_id
assert len(events) == 2