Use homekit service callbacks for lights to resolve out of sync states#32348
Conversation
Codecov Report
@@ Coverage Diff @@
## dev #32348 +/- ##
======================================
Coverage ? 94.73%
======================================
Files ? 775
Lines ? 56191
Branches ? 0
======================================
Hits ? 53230
Misses ? 2961
Partials ? 0
Continue to review full report at Codecov.
|
|
Test failure seems unrelated. Happening in other PRs as well |
|
Nice. Sorry for the delay getting to this. I was worried if some less polished integrations might set their brightness in memory but not actually turn on, but the interface seems to be pretty clear that this should be OK. My main itch is that it feels weird to put this light specific logic in Actually that would be a cool refactor because you could coalesce the characteristics writes. E.g. if you received a scene update to hue, saturation, brightness and on you could turn that into a single call to |
|
(I.e. have an
@Jc2k Thanks for taking a look! This is a case where AccessoryDriver is providing a bit too much abstraction by only feeding in one change at a time. My first thought was to change it so you get all the characteristic changes at once from the iOS client and then consume them in batches. The downside is it adds complexity to devices on the Home Assistant side that have to consume the data. I looked for other special cases where we would want set some characteristic before a device turned on but I didn't find anything besides brightness so I ended up with this solution. I think it is worth refactoring the interface if there turn out to be more. You are more familiar with the range of devices than I am so I'll need some guidance on that. |
|
I think we are on the same wavelength re: the abstraction being not quite right. I think we can change the interface while preserving the current interface, so the other accessories don't have to change. I actually think this change could make things less complex on the HA side. Consider this bit of code here. 5 entry points that invoke I think there are other cases lurking around where this refactor would be a win for sure, even if not exactly the same as your original bug:
|
|
After digging in, I think the callbacks should go to the service instead of the characteristic. I think we could keep the existing api working and register callbacks on the service instead of the characteristic. That way we could process them all in one transaction. |
|
Might be able to do it without upstream changes 1.Remove the callbacks for lights
Read all the chars. If char == service.characteristics[...] and service.setter_callback: then for every service fire service.setter_callback with. (char_name, value) |
It would be a lot patching to make that work though so better to see if upstream can accept a patch |
|
It looks like I can actually do everything in HomeAssistant without patching HAP-python if need be by making a super class for Service. Of course it would be much cleaner to do it in HAP-python. Concept is here with a test to show how it works and then the change to HA would be something like It seems work pretty well |
|
@Jc2k Thanks for pointing me at the 5 light entry points. The per service callback seems to fit a lot better for this use case |
|
Nice! I was going to suggest doing it on the service originally (HomeKit controller is very service centred). Thought it would be hard to do with the way this integration is written, but adding a service callback is a great idea. |
|
@Jc2k. Bought a LIFX bulb to test this with and its working just as well as the native homekit control now. Thanks again for getting me down this path. If @ikalchev is ok with ikalchev/HAP-python#229 I'll get this cleaned up and ready for merge |
|
Nice! And thank you for getting stuck in with |
b0f658d to
ae52b54
Compare
c8adc6f to
faa843a
Compare
|
ci failure is unrelated and should be fixed in #33553 |
faa843a to
1088b2a
Compare
|
rebasing to get a clean ci run to be extra sure this is ok |
|
tts test flapped on this run |
Service callbacks allow us to get the on/off, brightness, etc all in one call so we remove all the complexity that was previously needed to handle the out of sync states We now get the on event and brightness event at the same time which allows us to prevent lights from flashing up to 100% before the requested brightness.
1088b2a to
a06a94a
Compare
|
3rd times a charm on running this through CI? |
|
Flapped on tts again This has had enough runs for me to be comfortable with it. Going to recheck coverage before merging though |
|
b4 after |
|
ok better |
|
Ideally this gets fixed in 0.108 since python-HAP was updated to do so. If someone thinks its too risky, please remove |
|
Really awesome to see the work done on this issue. Thanks to everyone involved, looking forward to seeing it in the main release. My wife's eyes will also thank you in the middle of the night. |
#32348) * Switch homekit lights to use service callbacks Service callbacks allow us to get the on/off, brightness, etc all in one call so we remove all the complexity that was previously needed to handle the out of sync states We now get the on event and brightness event at the same time which allows us to prevent lights from flashing up to 100% before the requested brightness. * Fix STATE_OFF -> STATE_ON,brightness:0

Proposed change
Service callbacks allow us to get the on/off, brightness, etc all in one call so we remove all the complexity that was previously needed to handle the out of sync states
We now get the on event and brightness event at the same time which allows us to prevent lights from flashing up to 100% before the requested brightness.
Type of change
Example entry for
configuration.yaml:# Example configuration.yamlAdditional information
Multiple issues #32278 and #13768 and #13695
Checklist
black --fast homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all..coveragerc.The integration reached or maintains the following Integration Quality Scale: