Zacknetic / HomebridgeMagicHome-DynamicPlatform

Homebridge Plugin for MagicHome LED controllers and light bulbs
Apache License 2.0
61 stars 11 forks source link

"Sticky" Button Behavior #55

Closed Zacknetic closed 3 years ago

Zacknetic commented 3 years ago

@isramos With the latest update, devices are showing some odd behavior including a "sticky" touch.

Expected Behavior: Clicking a device tile should immediately turn on/off the tile with no delay, even before the light has actually physically turned on/off and even before the light responds with the proper "I'm on/off". On / off is just an example though. This snappy behavior should be seen in all commands including setting hue/sat and brightness.

Observed Behavior: When clicking a device on, the icon will immediately show that device as on as intended > then off a fraction of a second later >then on again about half a second later.

While being slightly annoying, this also feels disorienting. Users may click the button multiple times thinking it is broken, amplifying the issue.

This issue is caused by returning the device's state to Homekit too after the "setHue/Sat/Brightness" function is called. The speed at which devices respond to queries about their state varies. Up to 500ms as you have noted. We should not be waiting for that response before sending another command. Some devices simply don't respond with their state at all. Instead, simply with an "OK" packet.

However, the speed at which MagicHome devices receive instructions to change color is very fast. less than 20ms. Thus a smarter "fire and forget" logic must be implemented.

The solution to this is to:

  1. always return the callback immediately.
  2. After there has been no instruction from the user in HK for ~1 second, query the device to see if the last command arrived successfully.
  3. Keep HK out of the loop! If there is a problem or discrepancy, don't let it know that. This keeps the UI snappy.
  4. Query the device until one of three things happens...
    i. the user sends another command, in which case we stop waiting for a response and go back to step 1. ii. the device returns a response in which we will do one of two things: a. if the response is identical to the command we sent, success! Exit the loop. Don't tell HK. b. if the response is incorrect (i.e. we sent r: 255, g: 0, b:0 but got back r:100, g:100, b:100) resend the command and go back to step 2. (check how many times this is repeated to prevent infinite loop) iii. the device fails to return a response after several attempts in which we continue to step 5.
  5. Homebridge has received no response from the device after multiple query attempts: flag the device as malfunctioning. This will create a little (!) icon on the tile. Additionally, create a warning in the log noting the device in question and user friendly advice.
  6. Restarting Homebridge "resets" the 'malfunctioning' flag on the device (perhaps it had lost power or the IP was changed?) and by no means should be permanent.
Zacknetic commented 3 years ago

This bug has since been squashed due to the new state machine.