zwave-js / node-zwave-js

Z-Wave driver written entirely in JavaScript/TypeScript
https://zwave-js.github.io/node-zwave-js/
MIT License
741 stars 596 forks source link

Make dateTime valueId more intuitive #4265

Open robertsLando opened 2 years ago

robertsLando commented 2 years ago

Ref: https://github.com/zwave-js/zwavejs2mqtt/discussions/2277

stridger commented 2 years ago

I don't see how this is an enhancement. It looks like a bug to me. At the moment I don't think there is any way to set dateAndTime from the GUI, as the backend expects a Date object.

robertsLando commented 2 years ago

@AlCalzone Let you add the correct labels to this issue

AlCalzone commented 2 years ago

Honestly, I don't care about the label. The issue exists and should be worked on at some point.

stridger commented 2 years ago

Can I just add that this is not about the field becoming more intuitive, it is about making the field usable in any way at all. There is currently no way to set the times of the devices which support the 0x8b Time Parameters command class. Not via the API or in any other way apart from reinterviewing the device. Reinterviewing runs the time setting by itself, but the fact that the dateAndTime parameter requires a Date object, which cannot be serialised makes the command class API completely unusable.

AlCalzone commented 2 years ago

If you use the API in a way the doesn't require serialization, e.g. the driver function, it does work.

stridger commented 2 years ago

Fair enough. sorry for phrasing that incorrectly. I guess there is just no way to set it in home assistant, as the driver function is not exposed to Python? At least I couldn't find how to get that to work. I could of course do a full-fledged Python app importing the right ZWaveJS libraries etc, but that seems overkill to me. So if there is a simple way of using that, then please let me know. Currently all possible ways I have investigated eg via ZWaveJS2MQTT API, or via the HA API etc, all seem to require serialisation.

AlCalzone commented 2 years ago

I'm not sure what HA exposes how, but if you have access to the MQTT API, you can execute this function. Granted this seems unnecessary complicated, but should work: https://zwave-js.github.io/zwavejs2mqtt/#/guide/mqtt?id=z-wave-apis https://zwave-js.github.io/zwavejs2mqtt/#/guide/mqtt?id=api-call-examples

Set the topic <mqtt_prefix>/_CLIENTS/ZWAVE_GATEWAY-<mqtt_name>/api/driverFunction/set with the following payload:

{
    "args": [
        "const node = driver.controller.nodes.get(35); await node.commandClasses['Time Parameters'].set( new Date(2020, 3, 4, 12, 34, 56) );"
    ]
}

Replace 35 with your node ID.

The Date constructor takes the following arguments: year, month, day, hour, minute, second, (optional ms), or one of the other variants: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date Note that month is 0-based, so 3 = April.

stridger commented 2 years ago

Excellent, thank you so much. After @robertsLando gave me that hint in a separate feature request I was already doing it that way but could not get the syntax right, as I was doing it via the TimeParametersCCSet function and could not get it to work quite right. But yours seems to work perfectly (I still have to check whether it actually executes on the device, but I don't see why it shouldn't). So to set the current date and time I thus used

{
  "args": ["const node = driver.controller.nodes.get(12); await node.commandClasses['Time Parameters'].set( new Date() );"]
}

Thank you both for all your work on this and for helping me out!

amluto commented 2 months ago

I have a device which, in its interaction manual, says that I should be updating its time every 8 hours. It doesn’t seem like there’s a convenient way to do this right now.

ISTM the entire TimeParametersCC infrastructure is kind of odd. It’s very much hard-coded to set the actual current time instead of some other time:

https://github.com/zwave-js/node-zwave-js/blob/774ff77f5aaa829f723369ead8c78ad117446d6f/packages/cc/src/cc/TimeParametersCC.ts#L233

and this seems okay — does anyone really want to set an incorrect (or intentionally offset?) time? But the exposed API lets someone specify a different time, is hard to use (see this issue), and would result in the time being somewhat arbitrarily reset to the local time if the node is re-interviewed.

Would a better solution be to expose an actual API to simply send the current time and wire that up as a button that the user can click in the Z-Wave JS UI and as a service that can be easily called from a Home Assistant automation? Or even make it fully automatic — the config files for a device could specify the interval at which the time is supposed to be sent.

AlCalzone commented 2 months ago

There is such an API in node-zwave-js, which automatically detects which CCs it should use, so this is just a matter of exposing it in Z-Wave JS UI: https://zwave-js.github.io/node-zwave-js/#/api/node?id=setdateandtime

says that I should be updating its time every 8 hours

That's odd, given that the device could just send a command roughly every 8 hours to request the current time itself.

amluto commented 2 months ago

Hmm, reading the current version of the document, the lock will get Time all by itself. Maybe I was reading an older version of the document or the document for an older version of the lock or module.