Eurotronic Spirit Z-Wave - external temperature sensor

I was checking zwave specification and found a message structure:


so in our case 15.12 C report to the target node should look like:

Multilevel Sensor 0x31
Command = SENSOR_MULTILEVEL_REPORT 0x03
Sensor Type(air temp) 0x01
precision  0x02
Scale (celsius) 0x00
size (2 bytes) 0x02  #not sure about size
value 0x0E 0x0C or 0x44bd0000 #not sure how to convert temperature to the right value

I couldnā€™t find how to feed this line to OZWaveJS

I have some plans about migration of installations with Spirit, but not now.
Where you can put a look?
Itā€™s a my template for this task (sorry, my template, for me, i donā€™t want to export flow for some reasons)

NodeRED used for authomatization, HomeAssistant as device holder and dashboard constructor, Zwavejs2mqtt - as Z-Wave server (For HA - it a ZwaveJS), with node-red-contrib-home-assistant-websocket (set of nodes to interop with HA)

  1. Manual. zwave-js - Z-Wave driver written entirely in JavaScript/TypeScript
    Looks like prec. and length calculated by Zwavejs2mqtt

  2. Simplest way to send anything to anything - MQTT
    How-to:


    Where blue nodes - you HA sensors. No matter, Zigbee, WiFi, or virtual.
    Hexagon - can be tunet to activate, when value changed, (i) - get value
    Gray node - timer
    Green - debug output
    Orange node - format you request. function.
    can be:

var nodeid=100500; // place actual id here
var sensortype=1;
var scale=2;
var value=msg.payload; // data from you sensor. if precesion not 2, you can reformat it


msg.payload={"args":[{"nodeId":nodeid,"commandClass":0x31,"endpoint":0},"set",[sensortype,scale,value]]};

return msg;

purple - MQTT output.
Topic is:

<YOU PREFIX FROM SETUP>/_CLIENTS/ZWAVE_GATEWAY-<NAME FROM SETUP>/api/sendCommand/set

default prefix - zwave, default name - Zwavejs2Mqtt
If ou want to chec output - use MQTT input with same topic, without ā€œsetā€.
You can use some kind of MQTT explorers, to checkout what happened in real time.
If dry run Ok, remove debug nodes and connect formatted output to MQTT ā€œsendā€.
and relax :grinning:

It can be constructed in 5 min.
And it is not an ONLY way.
You can use MQTT integration for HA and manipulate topics directly, from HA, tou can use other API.

1 Like

Thanks, I feel like Iā€™m almost there, but not yet.
In the topic, last command is not set, but sendReport. I had every update in zwave2mqtt logged with error when it was set.

<YOU PREFIX FROM SETUP>/_CLIENTS/ZWAVE_GATEWAY-<NAME FROM SETUP>/api/sendCommand/sendReport

What Iā€™m getting now is

2021-11-21 18:14:57.607 INFO MQTT: Message received on zwave/_CLIENTS/ZWAVE_GATEWAY-Mosquitto/api/sendCommand/sendReport: '{"args":[{"nodeId":3,"commandClass":49,"endpoint":0},"set",[1,2,22.5]]}'

And it clearly doesnā€™t work. Temperature reported still internal, and when external is 23C, internal 18C, setpoint to 22C - valve opens to 80%, so it still uses internal temperature for adjusting.
I tried sending 22.5 as string with 2 decimals, and still same issue.

2021-11-21 18:36:17.597 INFO MQTT: Message received on zwave/_CLIENTS/ZWAVE_GATEWAY-Mosquitto/api/sendCommand/sendReport: '{"args":[{"nodeId":3,"commandClass":49,"endpoint":0},"set",[1,2,"22.80"]]}'

NodeId is 3 because other commands on this TRV mention this number

2021-11-21 18:37:47.412 INFO ZWAVE: Node 3: value updated: 67-0-setpoint-1 22 => 22

Do you have any ideas what could I check or what I am missing?

Update 1:
Now I saw that it might be /set thoughā€¦ so with topic /set I have the following in the logs:


2021-11-21 18:45:39.337 INFO MQTT: Message received on zwave/_CLIENTS/ZWAVE_GATEWAY-Mosquitto/api/sendCommand/set: '{"args":[{"nodeId":3,"commandClass":49,"endpoint":0},"set",[1,2,"22.80"]]}'
2021-11-21 18:45:39.342 INFO ZWAVE: Calling api sendCommand with args: [
{ nodeId: 3, commandClass: 49, endpoint: 0 },
'set',
[ 1, 2, '22.80', [length]: 3 ],
[length]: 3
]
2021-11-21 18:45:39.346 INFO ZWAVE: The command set does not exist for CC 49 sendCommand undefined
2021-11-21 18:45:39.354 INFO MQTT: Message received on zwave/_CLIENTS/ZWAVE_GATEWAY-Mosquitto/api/sendCommand: '{"success":false,"message":"The command set does not exist for CC 49","args":[{"nodeId":3,"commandClass":49,"endpoint":0},"set",[1,2,"22.80"]]}'

Update 2:
So, topic was correct, typo was in the function, in there set should have been changed to sendReport.

2021-11-21 18:49:34.982 INFO MQTT: Message received on zwave/_CLIENTS/ZWAVE_GATEWAY-Mosquitto/api/sendCommand/set: '{"args":[{"nodeId":3,"commandClass":49,"endpoint":0},"sendReport",[1,2,22.8]]}'
2021-11-21 18:49:34.987 INFO ZWAVE: Calling api sendCommand with args: [
{ nodeId: 3, commandClass: 49, endpoint: 0 },
'sendReport',
[ 1, 2, 22.8, [length]: 3 ],
[length]: 3
]
2021-11-21 18:49:36.280 INFO ZWAVE: Success zwave api call sendCommand undefined
2021-11-21 18:49:36.289 INFO MQTT: Message received on zwave/_CLIENTS/ZWAVE_GATEWAY-Mosquitto/api/sendCommand: '{"success":true,"message":"Success zwave api call","args":[{"nodeId":3,"commandClass":49,"endpoint":0},"sendReport",[1,2,22.8]]}'

This is awesome! Thank you for your help.
Now, TRV does report back me the air ambient temperature, but it uses the external temperature that I send it.
TRV 18C, external temp that I send is 22.8, setpoint to 21, and TRV is completely closed. Perfect.

To sum up:
The only thing that needs to be changed is function in nodered, item in the payload args named ā€œsetā€ should be changed to ā€œsendReportā€

msg.payload={"args":[{"nodeId":nodeid,"commandClass":0x31,"endpoint":0},"sendReport",[sensortype,scale,value]]};

First of all:
Manual here:

Server awaiting only specific topic. For basic calls - ā€œā€¦/api/sendCommand/setā€

About reporting temperature:
My Spiritā€™s reports ONLY internal sensor data, but works well.
How to test:
Set setpoint to 20C (for example) and put to Spirit fake data - 10C (it must open) and 30C (close)

P.S. Currently migration of 1st installation with Spirit from Vera to HA/Zw2mqtt/NodeRed planned within a 2 month. If you can wait, i can put here some kind of a working solution.

1 Like

Hey @Tmorfus , itā€™s all good - all working as expected now! I was wrong with topic, the issue was in the payload.
The only thing that was off was item in the payload args named ā€œsetā€ which had to be changed to ā€œsendReportā€. I made 2 updates to previous comment while looking for the solution.

msg.payload={"args":[{"nodeId":nodeid,"commandClass":0x31,"endpoint":0},"sendReport",[sensortype,scale,value]]};

Itā€™s all working perfectly for a few hours already, many thanks for detailed instructions!

Thank you @insajd , @Tmorfus ,
I was waiting for it for 3 years :slight_smile:
Now it works fine.
I use home assistant MQTT service:

alias: Bedroom sensor
description: ''
trigger:
  - platform: state
    entity_id: sensor.home_temperature
condition: []
action:
  - service: mqtt.publish
    data:
      topic: zwave/_CLIENTS/ZWAVE_GATEWAY-zwavejs2mqtt/api/sendCommand/set
      payload: >-
        { "args": [ { "nodeId": 6, "commandClass": 49, "endpoint": 0 },
        "sendReport", [ "01", "02",
        "{{states('sensor.home_temperature')}}" ]]}
  - service: input_number.set_value
    data_template:
      entity_id: input_number.bedroom_temp
      value: '{{states(''sensor.home_temperature'')}}'
mode: single

So simple :slight_smile:

3 Likes

There is another one point:
Keep it in ā€œHeatingā€ mode. This device can heat andā€¦ nothing morre, becaise itā€™s a valve :slight_smile:

Some devices, like Eurotronic Air quality monitor, can send ambient temperature data directly to Spirit, only fill Z-Wave associations.

Š£Š“Š°Ń‡Šø!

Does anyone know whether this can be made to work through zwave_js_set_value? It seems like it should work but I donā€™t know where to put sendReport`.

I donā€™t know, is it possible, or not.
Perhaps possible.
Value API and CC API, are different APIā€™s

Put a look here:
https://zwave-js.github.io/node-zwave-js/#/api/overview
https://zwave-js.github.io/node-zwave-js/#/api/valueid

Try to use notification with Miltilevel CC metadata.

I guess this conversation implies that as of Oct 2021 there is no support in HA to send custom messages over zwave_js (only to configured params), so doing it via mqtt seems like the only way, for now at least.

Support Leviton scene/zone controllers Ā· Issue #2397 Ā· zwave-js/node-zwave-js (github.com)

Pity. I will think about MQTT at some point.

After a time, migration from Vera to Home Assistant + NodeRed + ZWave2mqtt done.
Installation with Spirit.

One job:
Ambient temperature detected by Philio sensor and Air conditioning thermostat in different places. Average value saved to HA ā€œinpit_numberā€.

Second job:
When AVG temperature changed - send notification to Spirit
Spirit deals with the PID regulation of the valve by themself.
Itā€™s work. Confirmed.
image

msg.payload={"args":[{"nodeId":nodeid,"commandClass":0x31,"endpoint":0},"sendReport",[sensortype,scale,value]]};

to

zwave/_CLIENTS/ZWAVE_GATEWAY-Zwavejs2Mqtt/api/sendCommand/set
2 Likes

I made changes in my config based on your code and now Iā€™m a bit confusedā€¦ On one hand it seems to work properly (in log I can see commands being send with proper arguments to valve and after significant change in reported temperature I see that valve opening changed as well). What is confusing is that now TRV reports current temperature not as one set by external sensor, but one that it is measuring internally. So without offset being set it is way off from actual (+9C in my case).Is this the case for you as well? This makes thermostat card looks weird:


Is there any way to get this displayed correctlyā€¦ or it might indicate, that my config is not working properly?
BTW in your automation you set value of input_number.bedroom_tempā€¦ what is the use of it?

Yes itā€™s like you say - temp being reported from thermostat is kept as it and it looks very weird on standard thermostat card.
What I did is I installed custom thermostat card and it supports showing temperature of one sensor, and using climate entity of trv.

    - type: custom:thermostat-card
      title: Living Room
      entity: climate.living_room_thermostat_mode
      highlight_tap: true
      ambient_temperature: sensor.temperature_158d00023256d7
1 Like

Thanks a lot, will give it a try tonight!
EDIT: installed, tested and working perfectly!

Just to streamline the genius of those above for newbies like myself who puzzled through it.

Steps for ultimate TRV control:

For these instructions you must already have node-red installed and set up with an MQTT broker such as Mosquitto, and have the TRV set up over zwave

I am using Fibaro sensors that report to 1 decimal place, so I have to append an extra 0 to the string for the TRV to accept the external temperature. Check what your sensor accuracy is and remove the ā€œ+0ā€ from the function accordingly.

  1. Add TRV and set the zwave config parameters: [9-112-0-8] Temperature Offset to -128 (listen for external sensor)
  2. Import the following flow to node-red:
[{"id":"c6f182ddaff5874a","type":"tab","label":"Flow 2","disabled":false,"info":"","env":[]},{"id":"af5cdb71a955fae5","type":"function","z":"c6f182ddaff5874a","name":"TRV parse: sensor temp","func":"var nodeid=9; // place actual id here\nvar sensortype=1;\nvar scale=2;\nvar value=msg.payload; // data from you sensor. if precesion not 2, you can reformat it\n\nvalue= value + \"0\";\nmsg.payload={\"args\":[{\"nodeId\":nodeid,\"commandClass\":0x31,\"endpoint\":0},\"sendReport\",[sensortype,scale,value]]};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":140,"wires":[["3245c9c1262e195f","be653fcff22bf8ea"]]},{"id":"3245c9c1262e195f","type":"mqtt out","z":"c6f182ddaff5874a","name":"Send to Zwave","topic":"zwave/_CLIENTS/ZWAVE_GATEWAY-Zwavejs2Mqtt/api/sendCommand/set","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"295ddfb433d52749","x":520,"y":140,"wires":[]},{"id":"7bb61958b0a90a9a","type":"debug","z":"c6f182ddaff5874a","name":"1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":290,"y":220,"wires":[]},{"id":"d7afb9c49d74ae2a","type":"server-state-changed","z":"c6f182ddaff5874a","name":"Study temp change","server":"1b37d822.bbb668","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.motion_sensor_air_temperature_4","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":90,"y":140,"wires":[["af5cdb71a955fae5","7bb61958b0a90a9a"]]},{"id":"f3f0911a76e762bd","type":"inject","z":"c6f182ddaff5874a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"25.0","payloadType":"str","x":80,"y":220,"wires":[["af5cdb71a955fae5"]]},{"id":"be653fcff22bf8ea","type":"debug","z":"c6f182ddaff5874a","name":"2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":490,"y":200,"wires":[]},{"id":"dbf52222c8ce31b0","type":"inject","z":"c6f182ddaff5874a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10.0","payloadType":"str","x":90,"y":260,"wires":[["af5cdb71a955fae5"]]},{"id":"295ddfb433d52749","type":"mqtt-broker","name":"","broker":"mqtt://192.168.50.5","port":"1883","clientid":"Home Assist Mosquitto","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"1b37d822.bbb668","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]
  1. Change your sensor to the correct entity in the first blue node, change the nodeid in the function node to that of your TRV (zwave node id, left column in zwave2mqtt). Ensure your mqtt broker is selected in the MQTT node.

  2. If the TRV setpoint is 20 then you should hear full valve travel if you inject the ā€œtest temperaturesā€ via node-red to mimic extreme hot/cold levels.

The sensor you nominated should then feed values directly to the TRV.

(First ever post on any community boardā€¦)

2 Likes

Way to make it simple:
Use ā€œChangeā€ node inNodeRED

Parameter it:
Set msg.payload
to the value $number($formatNumber(msg.payload, ā€œ0.00ā€))

And use RBE filter with ā€œblock unless value changed greater thenā€
1, compared to last valid value
Itā€™s a way to avoid traffic and save the AA elements in TRV.

For example:
Ininstallation, source of temperature for TRV is AVG from 3 sensors

  1. Z-Wave t. and humid. sensor
  2. Zigbee Tuya air quality montor - it can flood about 0.1 degree changes without a pause, every second
  3. Z-Wave air conditioneer thermostat. (temperatire only)

Without a filter unit, it can eat AA elements within a week.

Hi, iā€™m trying your solution but temperature on my spirit doesnā€™t changeā€¦no idea?
I simply wish send the temperature from my xiaomi zigbee sensor (zigbee2mqtt) to zwave2mqtt eurotronic valve

id: '1662572485012'
alias: tempƩrature vanne salon
description: ''
trigger:
  - platform: state
    entity_id:
      - sensor.0x00158d000423a4aa_temperature
condition: []
action:
  - service: mqtt.publish
    data:
      topic: zwave/_CLIENTS/ZWAVE_GATEWAY-zwavejs2mqtt/api/sendCommand/set
      payload: >-
        { "args": [ { "nodeId": 10, "commandClass": 49, "endpoint": 0 },
        "sendReport", [ "01", "02",        
        "{{states('sensor.0x00158d000423a4aa_temperature')}}" ]]}
  - service: input_number.set_value
    data:
      value: '{{states(''sensor.0x00158d000423a4aa_temperature'')}}'
    target:
      device_id: 273607ff2806e9ad96a2f58b980955c8
mode: single

Is there also a way to set the external temperature by using the zwave_js.set_value service?

I tried this:

service: zwave_js.set_value
data:
  command_class: "49"
  endpoint: "0"
  property: Air temperature
  value: 22
target:
  entity_id: climate.heizung_kueche

But it doesnā€™t work?!

Uknown error

No, you canā€™t do that. Use the invoke_cc_api as shown here, and which is the same thing as the mqtt template above.

1 Like

Thanks.

Like this:

service: zwave_js.invoke_cc_api
data:
  command_class: "49"
  endpoint: "0"
  method_name: sendReport
  parameters:
    - 1
    - 0
    - 25
target:
  entity_id: climate.heizung_kueche

Should the schown temperature changed to the new value?
Because it doesnā€™t.