zwave-js / zwave-js-ui

Full featured Z-Wave Control Panel UI and MQTT gateway. Built using Nodejs, and Vue/Vuetify
https://zwave-js.github.io/zwave-js-ui
MIT License
923 stars 197 forks source link

[feature request] add an API to execute arbitrary Z-Wave commands #336

Closed carldebilly closed 3 years ago

carldebilly commented 3 years ago

Introduction

I have a bunch of Stelpro Ki thermostats that I installed few years ago when I was using SmartThings. Those thermostats were always working great.

The feature: display outdoor temperature

The have a feature to show outdoor temperature that works well with SmartThings the code for that is here.

The failure

I switched to Home Assistant (which is using OpenZWave) and I never found how to use this feature.

Specs

On SmartThings, it's using the sensorMultilevelV3.sensorMultilevelReport to send this information to the device.

spec sheet on z-wave alliance:

Outdoor Temperature

When connected to a Z-Wave network, the thermostat may display the outdoor temperature provided by an external sensor.
When available, the outdoor temperature is displayed instead of the set point, providing that the outdoor temperature display setting is set to on.
If no temperature is received within a 4 hours timeframe, the outdoor temperature will disappear and the set point will be displayed.
In order to display the outdoor temperature, an external sensor needs to be part of the Z-Wave network. It may be a physical sensor or a weather station app.
Refer to your Z-Wave hub controller instructions manual to find how to associate both devices. On some Z-Wave hub controllers, an app may be used to provide the outdoor temperature.

The hope

Is it possible to code something like this using zwavejs/zwavejs2mqtt ? I'm not afraid to code it (I did the exact same feature for the zigbee version of this thermostat on the Zigbee2Mqtt project).

I'll need some guidance...

robertsLando commented 3 years ago

@carldebilly I don't get this, did you tried to see if it works? What error do you see? Is zwavejs2mqtt creating a climate?

carldebilly commented 3 years ago

@robertsLando I can see and operate the climate device, that's not the problem.

What I don't know how - maybe it juste missing guidance - is how to "push" the external outdoor temperature to my thermostat.

robertsLando commented 3 years ago

What I don't know how - maybe it juste missing guidance - is how to "push" the external outdoor temperature to my thermostat.

You can do this from the UI control panel, or via mqtt. Check docs: https://zwave-js.github.io/zwavejs2mqtt/#/guide/mqtt

carldebilly commented 3 years ago

I see.. but here's what I see in the UI for this device:

Sections

image

Thermostat Mode

In the Thermostat Mode I can see a manufacturerData field... but setting it to something doesn't seem to produce what I want (nothing appears on the device by setting a temperature like 10.5) image

How can I know which field to use and the format of the data to send?

For the Manufacturer Specific section, everything is read-only: image

@robertsLando

robertsLando commented 3 years ago

@carldebilly If your goal is to set the setpoint you should use the thermostat setpoint CC. ANyway when you say "How can I know which field to use and the format of the data to send" do you mean the MQTT format? If so follow docs: https://zwave-js.github.io/zwavejs2mqtt/#/guide/mqtt

carldebilly commented 3 years ago

@robertsLando I think I wasn't clear enough. I don't want to operate the thermostat - this already works well, that's not the problem. image

What I want, is to PUSH the outdoor temperature (EXT) to the thermostat. As I described in previously, there's a manufacturer endpoint for that and I want to know how I can use zwavejs2mqtt to push that information for display on the thermostat. That's not the thermostat setpoint.

robertsLando commented 3 years ago

@carldebilly Do you see the configuration CC? If not Ithink that device hasn't a valid configuration in the database, could you print here here the device Id?

carldebilly commented 3 years ago

@robertsLando I'm not sure if that's what you want... here's an export of the json for that device... image

569-1-1 (0x0239-0x0001-0x0001)

node_4.zip

Seems to be that device: https://github.com/zwave-js/node-zwave-js/blob/master/packages/config/config/devices/0x0239/stzw402.json

robertsLando commented 3 years ago

@zwave-js-bot import config from ozw with device id 0x0239-0x0001-0x0001

AlCalzone commented 3 years ago

@robertsLando what needs to happen here is to send a Multilevel Sensor Report to the device like @carldebilly wrote in the first post. It is already possible to do that in zwave-js, but you'll need to expose an API in zwavejs2mqtt for that.

Maybe it could be done similar to what I do in ioBroker.zwave2: https://github.com/AlCalzone/ioBroker.zwave2/blob/master/docs/en/sendCommand.md Basically, you need to specify the node ID, Command Class Name, API method name and the API method args. Reference implementation (which takes the object from the example) here: https://github.com/AlCalzone/ioBroker.zwave2/blob/d399cd1be91e8717b0508b0132f5f8dc57184c54/src/main.ts#L1286-L1377

You'd then need to invoke this method to send a temperature report: https://github.com/zwave-js/node-zwave-js/blob/c695ee81cb2b1d3cf15e3db1cc14b1e41a911cc0/packages/zwave-js/src/lib/commandclass/MultilevelSensorCC.ts#L149

robertsLando commented 3 years ago

@carldebilly You can try with https://github.com/zwave-js/zwavejs2mqtt/pull/360

carldebilly commented 3 years ago

I'll try this weekend...

robertsLando commented 3 years ago

@carldebilly Check the PR for more information. In your case the command to send will be sendReport and the args [sensorType, scale, value] like described here: https://github.com/zwave-js/node-zwave-js/blob/c695ee81cb2b1d3cf15e3db1cc14b1e41a911cc0/packages/zwave-js/src/lib/commandclass/MultilevelSensorCC.ts#L149

@AlCalzone how does he can identify the correct values to use as sensorType and scale ?

AlCalzone commented 3 years ago

sensor types are the first level keys here (treat as numbers!): https://github.com/zwave-js/node-zwave-js/blob/master/packages/config/config/sensorTypes.json scales are the second level keys (or for the named scales the keys here https://github.com/zwave-js/node-zwave-js/blob/master/packages/config/config/scales.json)

robertsLando commented 3 years ago

Ok so the args could be in this case [1, 0, <value>] (air temperature, celsius, the value).

Topic: zwavejs/_CLIENTS/ZWAVE_GATEWAY-<yourName>/api/sendCommand/set

Payload:

{ "args": [
  {
    "nodeId": 4,
    "commandClass": 49,
    "endpoint": 0,
    "property": "Air temperature"
  }, 
  "sendReport",
  [1, 0, <value>]
  ]
}

@AlCalzone I'm not sure about the property of the valueid as the user said he want to send it to the outdor temperature sensor

AlCalzone commented 3 years ago

Should be the correct one. Maybe another endpoint, but that must be mentioned in the manual in that case.

robertsLando commented 3 years ago

@carldebilly Ok so try with the example I showed you with endpoint 1-2-3 until you see the desired outcome :)

carldebilly commented 3 years ago

It worked on the very first try! Thanks good work!

image (not a real external temperature, BTW)