Resend unequal WO or RW objects to Miniserver on adapter restart?
Closed this issue · 2 comments
I'm using ioBroker to send changes from a few adapters (zWave, Sony TV, etc) to Loxone. Have achieved this by creating virtual inputs in Loxone and simply copying state changes (using JS script) from these other adapters to the Loxone VI objects. Mostly this works perfectly - thanks :)
But... it is possible that the Miniserver restarts (power outage, config upload, etc) and/or the Loxone adapter restarts while sensors are updating and things get out of sync.
It is possible that a JS script can set Loxone object values (in our use case - when a zWave sensor is triggered by a window opening for example) while the Loxone adapter is not connected or not even running. If this happens I notice that the value change happens in the object list but is not acknowledged. It doesn't seem to matter if the Loxone adapter is not running, or the Loxone Miniserver is offline - the change happens and is labelled unacknowledged in both cases. When the situation returns to normal (the Loxone adapter and/or Miniserver come back online) the Loxone adapter reads values of all virtual inputs from Loxone which can overwrite any previously updated value in ioBroker.
I'm sure there are any number of ways to solve this but am guessing the correct way would be to do this: as the object states are being fetched from Loxone at adapter startup/Miniserver connection, if a WO or RW object value read is not the same as any unacknowledged value in ioBroker, the Loxone adapter should instantly send the ioBroker value (the one that was previously not acknowledged) to Loxone to get things back in sync. In fact, does it really matter if the value was not acknowledged - shouldn't anything that isn't the same be updated in Loxone either way?
I do appreciate that while this would work for me, it might not be ideal for other users. This is because I want ioBroker to be the 'source of truth' for these virtual inputs. Other users might want something bi-directional. That said, that won't be the case for WO objects (only RW objects could pose an issue) and in the solution I describe above, it should be impossible for any Loxone virtual input to change as clearly that shouldn't be possible while the Miniserver is rebooting!
It's a shame there aren't timestamps on object values as then one could simply take the latest saved one. In the mean time, perhaps the Loxone adapter could have a config setting that determines if ioBroker or the Loxone miniserver should be treated as the 'source of truth' when values read are out of sync on adapter startup?
I'm happy to code this functionality if the authors agree it's a useful feature.
Thanks for your detailed feedback!
The question is: who is the master of all data. Until now I'm assuming the Miniserver is the master and I would prefer not to change this for all users as it could have huge side effects.
This is a kind of issue I'm also seeing with other adapters - you just want to have the output from one adapter to be forwarded into another adapter and that forwarding should be "enforced."
As far as I know, there is no adapter that does this (I might be wrong, the adapter list is getting huge and I haven't checked every single one).
My suggestion would be to write a separate adapter that does exactly this forwarding (take one state and forward it to another). It could even be configured on the states tab (instead of a separate adapter config dialog), similar to the linkeddevices adapter.
Currently I don't have the resources to write such an adapter, so if you have time, please feel free to start one.
What is your opinion on this?
Thanks for the feedback, and yes, this sort of makes sense.
In fact I used blocky 'bind'...
... which is this in JS:
on({id: 'sony-bravia.0.info.powerStatusActive', change: "ne"}, function (obj) {
setState('loxone.0.14a4fbe8-0147-7879-fffff62eeb38b63d.active', obj.state.val);
});
As we can see, this only keeps the destination object updated when the source changes which can lead to the situation I describe when I opened this issue.
Following what you said leads to the conclusion that the 'bind' block is actually at fault here and should be translated into the following to keep the destination value always same as the source, even if destination is changed via some other means:
on({id: 'sony-bravia.0.info.powerStatusActive', change: "ne"}, function (obj) {
setState('loxone.0.14a4fbe8-0147-7879-fffff62eeb38b63d.active', obj.state.val);
});
on({id: 'loxone.0.14a4fbe8-0147-7879-fffff62eeb38b63d.active', change: "ne"}, function (obj) {
setState(obj.id, getState('sony-bravia.0.info.powerStatusActive').val);
});
*I have assumed the setState
function is intelligent and will do nothing if the object is already the same as the value given. It does seem to work this way.