karlentwistle / ruby_home

Ruby HAP Server - HomeKit support for the Rubyist

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to update a characteristic value without having it pass through the after_update chain?

jeffmcfadden opened this issue · comments

I have a Z-Wave service running on my network, and I'm using ruby_home to bridge that to HomeKit.

To keep things in sync, I poll that z-wave service to get the current status of the various components in my house, and then update that value in ruby_home.

The problem is that sometimes the z-wave service can take a few minutes to update the value properly. So when I poll the z-wave service to the current value, then set that value via ruby_home, a command is sent back to the z-wave service, and the device gets updated, which sometimes resets the value of that device.

For example:

Bedroom light is at 100%
Open Home app on my iPhone, set Bedroom light to 50%
Command goes Home App -> Ruby Home -> Wave, and the light goes to 50%
However, the stupid z-wave service doesn't update itself immediately.
So now, my polling tool checks ZWave, which reports back that the light is still 100%
So then the polling tool updates the value to 100% in Ruby_Home, which then sends the command to that device to update to 100%, and now the light in the bedroom just went from 50% back to 100%.

What I want to do is only update the characteristic value in ruby_home/homekit, without triggering the full on_update chain.

Currently I do this:

@bridged_devices[zway_switch.id].on.value = current_status

But doing that always calls the after_update hook.

How can I set that value without calling the after_update hook?

Do I just need to use value_object.value= instead ?

@jeffmcfadden hey, 👋 thanks for sharing the example. That's quite an interesting problem and not one that I had considered at all 😅 You could indeed update the value_object directly and this would skip the after_update. I'm curious if the lights can also be controlled by some other mechanism which is why you need the ongoing polling. I'm pondering this because the issue with directly updating the value_object and not the value is in the following scenario:

  • Bedroom light is at 100%
  • Some other input device changes the bedroom light brightness
  • Bedroom light is now at 50%
  • Polling tool checks ZWave, which reports back that the light is at 50%
  • value_object is updated via RubyHome

You're not going to get realtime updates in the Home app because they depend on the broadcast being invoked. So I think the status of the brightness of the light would only change in Home if you open and close the app again to trigger a full refresh.

This might not be a concern though. Was just a side-effect that crossed my mind.

You're describing the scenario perfectly, yes!

Indeed other mechanisms can operate the lights (there's an Alexa integration, for example), which is why I need the polling, and while you're correct that the status in Home app can get out of date because of this, it's preferable to the lights bouncing all over the place :)

I'll go with value_object directly. Thanks!