zwave-js / node-red-contrib-zwave-js

The most powerful, high performing and highly polished Z-Wave node for Node-RED based on Z-Wave JS. If you want a fully featured Z-Wave framework in your Node-RED instance, you have found it.
MIT License
47 stars 6 forks source link

Force Trigger VALUE_UPDATED for CC API #51

Closed marcus-j-davies closed 3 years ago

marcus-j-davies commented 3 years ago

some devices (seems to be those with > 1 endpoint.) don't report back the updated value.

I will work around this, by enforcing a Get (if needed), and if using the CC API

@crxporter

marcus-j-davies commented 3 years ago

Ok,

So after looking at options, I can add an optional element in the message, lets say forceUpdateOn this value will be of a property (and optionally a propertyKey) you want to trigger an update on.

The resulting message will look like.

let Message = {
    payload: {
        node: 12,
        class: "BinarySwitch",
        operation: "Set",
        endpoint: 1,
        forceUpdateOn: {
            property: "currentValue"
        },
        params: [true]
    }
}
return Message

forceUpdateOn will cause a fetch on the identified property via pollValue(), and ultimately return a VALUE_UPDATED event.

making it optional, means we don't do this for devices behaving correctly - else you will get 2 events for the same thing This actually happens with the Value API internally, hence why the updates are delivered using the UI (which uses the Value API), Obviously, one can just use the Value API if preferred.

property is the property you get in VALUE_UPDATED events normally the same with propertyKey if needed

In a nut shell - what this does, is fetch the value after setting it, if the device fails to send said updated value. it should be used for devices (or endpoints) that don't report the updated value (whereas the Value API already knows to look out for this)

crxporter commented 3 years ago

In my case I would like to send everything through the same function node, regardless if it is a "well behaved" or a "rebel" device. So what is the damage, in regards to additional Zwave traffic, in using the force update option on all binary switch commands?

Perhaps it will be better for me to use the value API in this case.

Alternate thought: What if the force update is an option in the device config? So in the UI we could check a box to always force update on that device? This way we can still use the CC API as usual but the force update happens when that box is ticked.

marcus-j-davies commented 3 years ago

You could add a condition?

let ForceUpdatesFor = [5, 32, 10, 19]
let MessageToController = msg

if (ForceUpdatesFor.includes(MessageToController.payload.node)) {
    MessageToController.payload.forceUpdateOn = {
        property: "currentValue"
    }
}

Return MessageToController

The Value API - does exactly what this will do. The Value API can be used, you just need to store the ValueID's, and reference them.

you can get them with.

let Message = {
    payload: {
        node: 2,
        class: "Unmanaged",
        operation: "GetDefinedValueIDs"
    }
}
return Message
marcus-j-davies commented 3 years ago

What if the force update is an option in the device config? So in the UI we could check a box to always force update on that device? This way we can still use the CC API as usual but the force update happens when that box is ticked.

Not bad - Will have to give it some thought, as to storing it for retrieval on restarts

The ability to set this force Flag is in my dev branch. Here and used Here

crxporter commented 3 years ago

I'm remembering that the mqtt version really had a lot of duplicated messages. I wonder if it just always does a similar thing like you are suggesting.

marcus-j-davies commented 3 years ago

It's quite possible.

A lot of devices don't follow spec, one of which is updated values should always report back with new value. The Value API has a finite waiting time, to allow chance for that update, and if it isn't received in time, will force a Get.

If you decide to stick to using Managed Mode (easier in my opinion). you can just apply that forceUpdateOn object for specific nodes as exampled.

In other news - I'm almost done with adding Controller status to the node status text.

crxporter commented 3 years ago

The Value API has a finite waiting time, to allow chance for that update, and if it isn't received in time, will force a Get.

The value api is just sounding better and better... I'm out of bed now I think I'll run through some tests on that.

marcus-j-davies commented 3 years ago

Yeah - its a good API (I don't use it myself) but the node has full support for it. It is limited however to primitive types, i.e you can't pass durations or control exotic types with it.

Binary Switches and stuff like that should be fine.

marcus-j-davies commented 3 years ago

Heres the guide.

https://github.com/zwave-js/node-red-contrib-zwave-js/blob/main/unmanaged.md

Edit: The value ID its self determines the endpoint, so all you pass is the Node, ValueID and Value. You just have to be sure, you are using the correct ValueID for the value you want to control

marcus-j-davies commented 3 years ago

forceUpdate added in 3.3.1