Supereg / homebridge-http-switch

Powerful http switch for Homebridge: https://github.com/homebridge/homebridge
ISC License
219 stars 36 forks source link

Caching stateful switch state locally #22

Closed onfoot closed 5 years ago

onfoot commented 5 years ago

When there are a lot of accessories, many of them http-based and running on low-power hardware like ESP8266, updating their state in Home can sometimes take a long time.

If there are http switches configured with the notification server support, their state reported to Home app could be sourced from recently known state by the plugin, not the accessory itself, since its state is known in all cases (provided the notification server settings are configured properly).

Even if there is an issue with the notification server not receiving the state changes, there'a also the pull timer already that could make sure the plugin has somewhat current state of the accessory.

I'd like the http-switch accessory to not retrieve the http accessory's state from it every time it's requested by the Home app.

If you want, I can create a PR with necessary changes and we can discuss the changes there.

Supereg commented 5 years ago

Out of curiosity. How long does it take for you to query some data from an ESP. Mine are pretty fast an capable here.

I think the best solution would be to make some sort of time based caching? So for example if the switch got not updated date for one hour (configureable) it queries the ESP 🤔 The caching time could be configurable and maybe '-1' to indicate lifetime caching

onfoot commented 5 years ago

It's not that bad for a single ESP, but I'm building up an army of them in my home, and some do non-trivial operations to return a status, i.e. my stairs lights convert CSV to RGB.

Just checked response time for my Sonoff Touch T2 from a laptop connected to wifi -- it's around 120ms, alhough when the network is busy, it can go up to 800ms. That accessory provides two switches really, and that's just a single device. Besides I have an Ikea bridge with a lot of bulbs, ESP-controlled stairs lights, a few ESP-based temperature, humidity, and motion sensors, two cameras, and I just got delivered a two-output BleBox switch for some outside lights.

It all just adds up.

And since the plugin is able to have the switch status pushed to it, it could take advantage of this and avoid the reads on every request.

Edit: And yeah, refreshing the status every once in a while would also be a nice addition.

Supereg commented 5 years ago

All in on smart home 😂 I'm thinking what would be the best way to add the cache setting. I though about adding something like a statusCache property just like the statusPattern. However I also had the idea to add the property inside of the urlObject so the config would look something like this:

{
    "statusUrl": {
        "url": "http://example.org",
        "statusCache": 1000
    }
}

I think the first would be more straight forward and simply. When looking at the bigger picture I think the second option could potentially be better. The plan is creating even more homebridge-http-* plugins which all share the same code basis and thus have a streamlined configuration. So looking at a lightbulb, which has multiple status urls for characteristics like "On", "Hue" or "Brightness", the config would be much more cleaner if the cache option would be inside the urlObject, wouldn't it?

I also though about adding some kind of option to define if the switch should query the current status when homebridge starts. In combination with a cache set to unlimited time, you could configure a switch, which queries it's initial state and then relies only on status updates via http or mqtt (or pulling if you want the inefficient way 😂). Building on the idea, with the said option you also could simply leave out the statusUrl by defining switchType="toggle" and also get a switch which only relies on status updates 🧐🤓

onfoot commented 5 years ago

I'd think the status is for the whole device, so in case of a bulb for example, there are several characteristics, and if they're requested using separate URLs (though unlikely), you'd need to define the cache time for each. Actually, you could allow exactly that - provide a url- or device-specific cache time. But for the time being, yeah, the url specific one is more than enough.

So you're thinking of enabling the plugin to return the last-known device status only when the notification server is set up and statusCache is defined?

And yeah, I'm all in on smart home ❤️, though going for automation instead of just having buttons for things to tap on my phone. :)

Supereg commented 5 years ago

I didn’t thought about combining both ideas 😅 why take the easy way when there is a much more complicated one 😂

Kind of. Basically a setup where the switch doesn’t need to ask for the current state all the time. Where changes are always published via push notifications (notification server or mqtt). The only problem would be when the switch starts up, it wouldn’t have the latest state. But that’s a whole different thing. For now I’m gonna implement the cache option.

Switches aren’t smart. Automation is. 😅 that’s a thing most people get wrong.

onfoot commented 5 years ago

Yeah, I think it's sensible to have the status url still, as the plugin would have to broadcast a status shoutout anyway so the devices ping back. And as even using the notification server requires some modification of the device firmware (I have my own, so that's not a big deal), we probably wouldn't want to leave dry those that can't do that for different reasons.

Or just adopt MQTT and drop custom notification things altogether. 😱

Supereg commented 5 years ago

Okay I rather though about adding options and not taking them 🤔 😅

Supereg commented 5 years ago

v0.5.16 is live