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.
- Add TRV and set the zwave config parameters: [9-112-0-8] Temperature Offset to -128 (listen for external sensor)
- 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}]
-
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.
-
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…)
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
- Z-Wave t. and humid. sensor
- Zigbee Tuya air quality montor - it can flood about 0.1 degree changes without a pause, every second
- 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.
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.
I don’t own this device, so I don’t know what the device should report in response to the command. Maybe someone else who owns the device can confirm what it should do.
Also, the API doesn’t let you set the precision explicitly. If you need to force the precision, you might try writing a decimal value, like 25.00
, or maybe 25.01
(not sure if a round number gets converted). You can view the driver debug logs and see what the message being sent is and whether it set the precision or not.
I had to use a non-zero value to force a precision to be configured, because HA is converting the value to an integer. (Note I don’t have this device, sending the message is possible to any device that supports the Command Class, it just won’t respond to it.)
The service call with value 20.00
:
service: zwave_js.invoke_cc_api
data:
command_class: "49"
method_name: sendReport
parameters:
- 1
- 0
- 20.00
endpoint: "0"
target:
entity_id: sensor.4_in_1_sensor_air_temperature
In debug logs, we can see HA has already converted the value before it gets to the driver:
2022-09-11 10:19:59.345 DEBUG (MainThread) [zwave_js_server] Publishing message:
{'args': [1, 0, 20],
'command': 'endpoint.invoke_cc_api',
'commandClass': 49,
'endpoint': 0,
'messageId': 'b4d7b3b15637462ab366feb207847a90',
'methodName': 'sendReport',
'nodeId': 3}
In the driver, that results in:
2022-09-11T17:16:36.588Z SERIAL » 0x011100a901030531050101142500000000094c (19 bytes)
2022-09-11T17:16:36.589Z DRIVER » [Node 003] [REQ] [SendDataBridge]
│ source node id: 1
│ transmit options: 0x25 │ callback id: 9
└─[MultilevelSensorCCReport]
type: Air temperature
scale: Celsius
value: 20
You can see the integer value, 20
. You can also see the payload bytes:
3105010114
31 -> Command Class 49 (hex 31)
05 -> Command SENSOR_MULTILEVEL_REPORT
01 -> Sensor Type == 1 == Air Temperature
01 -> Precision = 0, Scale = 0, Size = 1 byte
14 -> Temp value 20 (hex 14)
So if the device requires precision 2, then this won’t work.
HA won’t covert 20.01
to a integer.
service: zwave_js.invoke_cc_api
data:
command_class: "49"
method_name: sendReport
parameters:
- 1
- 0
- 20.01
endpoint: "0"
target:
entity_id: sensor.4_in_1_sensor_air_temperature
2022-09-11 10:17:01.376 DEBUG (MainThread) [zwave_js_server] Publishing message:
{'args': [1, 0, 20.01],
'command': 'endpoint.invoke_cc_api', 'commandClass': 49,
'endpoint': 0, 'messageId': '37d3838495da4c17a130fe6df5fc782c',
'methodName': 'sendReport',
'nodeId': 3}
The decimal 20.01
is preserved.
Driver:
2022-09-11T17:17:07.826Z SERIAL » 0x011200a90103063105014207d125000000000ace (20 bytes)
2022-09-11T17:17:07.827Z DRIVER » [Node 003] [REQ] [SendDataBridge]
│ source node id: 1
│ transmit options: 0x25
│ callback id: 10
└─[MultilevelSensorCCReport]
type: Air temperature
scale: Celsius
value: 20.01
The payload is:
3105014207d1
31 -> Command Class 49 (hex 31)
05 -> Command SENSOR_MULTILEVEL_REPORT
01 -> Sensor Type == 1 == Air Temperature
42 -> 0b1000010 -> Precision = 2, Scale = 0, Size = 2 bytes
07d1 -> Temp value 20 (hex 14) 2001, which is 20.01 with precision 2
Looks like the driver also removes precision if it can. Driver code (using zwavejs2mqtt):
const node = driver.controller.nodes.get(3);
await node.commandClasses["Multilevel Sensor"].sendReport(1, 0, 20.00);
Results in the same payload as the HA service call, 3105010114
.
i tried 3 methods but honestly I need advices
zwave_js.set_config_parameter
zwave_js.invoke_cc_api
mqtt.publish
Temperature sensor on valve does not change after you send external temperature to it. It will still display the same temperature that it sees.
How you can test it if external temperature works is you can set a really low temperature and hear trv opens, or you can send a really high temperature and hear it closing.
The problem is using standard component for heating in HA. As it shows TRV temperature. To overcome this you can install a custom heating component for home assistant which supports merging the heating valve with an external sensor that you are sending temperature from, for example this one https://github.com/fineemb/lovelace-thermostat-card
I decided to prepare my heating system for winter and found out that my method:
to publish temperature via mqtt doesn’t work anymore, with error message:
{
"success": false,
"message": "sensorType is not a number (ZW0322)",
"args": [
{
"nodeId": 7,
"commandClass": 49,
"endpoint": 0
},
"sendReport",
[
"01",
"02",
"20.9"
]
],
"origin": {
"args": [
{
"nodeId": 7,
"commandClass": 49,
"endpoint": 0
},
"sendReport",
[
"01",
"02",
"20.9"
]
]
}
}
But I tried to publish via service: zwave_js.invoke_cc_api:
data:
command_class: "49"
method_name: sendReport
parameters:
- 1
- 2
- {{states('sensor.healthy_home_coach_temperature')}}
endpoint: "0"
target:
entity_id: sensor.thermostat_kidsroom_air_temperature
and it worked
Reading through this huge thread, i managed to set the temperature on my Eurotronics Spirit Zwave devices using an automation and the normal zwave-js integration. (no mqtt or node-red ) Problem with this setup is of course that home assistant has to be up and running for this to work. thanks everybody for the notes/research.
As everybody points out you first have to set option 8 of the device to -128. this way it will accept the external temperature measurement.
The automation can probably be improved but what it does is it waits for a change in temperature of my multisensor in the room. which is constantly rounded down to one digit after the comma. which the TVR is not accepting as shown in the excellent post of Freshcoast. therefore i chose just to substract 0.01 degrees from my sensor thereby creating a 2 digit after the comma number
For parameters, 1
is the sensor type (1 == temperature), 0
is the scale (0 == Celsius, 1 == Fahrenheit, 2== Celsuis or Fahrenheit), the third parameter is the temperature as mentioned.
alias: External Temperature Sensors TVR
description: >-
This automation sets the external temperature sensor on Eurotronic Spirit
Z-Wave
trigger:
- platform: state
entity_id:
- sensor.kitchen_multisensor_air_temperature
id: TempKitchen
- platform: state
entity_id:
- sensor.livingroom_multisensor_air_temperature
id: TempLivingRoom
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: TempKitchen
sequence:
- service: zwave_js.invoke_cc_api
data:
command_class: "49"
endpoint: "0"
method_name: sendReport
parameters: |-
[
1,
0,
{{(states("sensor.kitchen_multisensor_air_temperature") | float - 0.01 )| round(2)}},
]
target:
entity_id: climate.kitchen_radiator
- conditions:
- condition: trigger
id: TempLivingRoom
sequence:
- service: zwave_js.invoke_cc_api
data:
command_class: "49"
endpoint: "0"
method_name: sendReport
parameters: |-
[
1,
0,
{{(states("sensor.livingroom_multisensor_air_temperature") | float - 0.01 )| round(2)}},
]
target:
entity_id:
- climate.living_room_thermostatic_valve_left_window
- climate.living_room_thermostatic_valve_middle_window
- climate.living_room_thermostatic_valve_right_window
mode: single
@MSe-5-14 have you checked if it works for you this way? For example, if current setpoint is 20C, and it has open valve, send 28.55 to the TRV, does it close?
I think TRV actually needs 1 digit precision, not 2.
@freshcoast is describing the general idea how driver works, when we send 20.00 for example, in response to @Osorkon question. That actually means that I probably need to do something about 20.0 value.
Thing is, Multilevel Sensor v5 always shows internal air temperature of TRV, that’s why it’s 2 digit.
What we are sending with sendReport must contain 1 decimal, and after that, that value is nowhere to be observed in the ZWave JS UI of the TRV entity - we can only test it by trying out setpoint / sent value from automation.
Yes it works for me. when i set the temperature to 28.55 it closes the valve.
after your comment i did try some other values and you are right; it only needs 1 digit. must ahve misunderstood something
This won’t work because you are sending the parameters and the temperature value as strings, not as an integer or float. It is necessary to remove " near 01, 02 and temperature.
I’m using MQTT-Explorer to connect my MQTT server and it is pretty shows, that zwavejs2mqtt api returns that call is successful or not and error message. So it easy using it to find mistake.
Example working for me (I checked that there is no error from from api side, I will check valve working later):
- service: mqtt.publish
data:
topic: zwave/_CLIENTS/ZWAVE_GATEWAY-zwavejs2mqtt/api/sendCommand/set
payload: >-
{ "args": [ { "nodeId": 9, "commandClass": 49, "endPoint": 0 },
"sendReport", [ 1, 2,
{{states('sensor.p1bedroom_temperature_avg')}} ]]}
Ive tweaked my automation a little and this seems to work
alias: External Temperature Sensors TRV
description: >-
This automation sets the external temperature sensor on Eurotronic Spirit
Z-Wave
trigger:
- platform: state
entity_id:
- sensor.bathroom_multisensor_air_temperature
- sensor.bedroom_multisensor_air_temperature
- sensor.kitchen_multisensor_air_temperature
- sensor.livingroom_multisensor_air_temperature
- sensor.office_multisensor_air_temperature
condition: []
action:
- service: zwave_js.invoke_cc_api
data:
command_class: "49"
endpoint: "0"
method_name: sendReport
parameters:
- 1
- 0
- "{{ states(trigger.entity_id) }}"
target:
entity_id: >-
{{ expand(states.climate) | selectattr('entity_id', 'in',
area_entities(area_id(trigger.entity_id)))|map(attribute='entity_id') |
list }}
mode: single
The log shows i think that the message arrives correctly at the TRV, even if node 3 doesnt seem to be able to deliver the info. ill launch a heal network just to make sure, weird the plug is 1.5m away from the TRV.
NODE 003 = Fibaro Plug FGWPE-102
NODE 005 = Aeotec MultiSensor 6
NODE 014 = Eurotronics Spirit
2022-12-15T15:39:23.110Z SERIAL « 0x010e00040005063105012200c5cf00eb (16 bytes)
2022-12-15T15:39:23.111Z SERIAL » [ACK] (0x06)
2022-12-15T15:39:23.112Z CNTRLR [Node 005] [Multilevel Sensor] Air temperature: metadata updated [Endpoint 0]
2022-12-15T15:39:23.112Z CNTRLR [Node 005] [~] [Multilevel Sensor] Air temperature: 19.8 => 19.7 [Endpoint 0]
2022-12-15T15:39:23.113Z DRIVER « [Node 005] [REQ] [ApplicationCommand]
└─[MultilevelSensorCCReport]
type: Air temperature
scale: Celsius
value: 19.7
2022-12-15T15:39:23.127Z SERIAL » 0x011d00130e169f032600bf258a9ba346d2e27a93cd68977c0c2560a025f096 (31 bytes)
2022-12-15T15:39:23.129Z DRIVER » [Node 014] [REQ] [SendData]
│ transmit options: 0x25
│ callback id: 240
└─[Security2CCMessageEncapsulation]
│ sequence number: 38
└─[SupervisionCCGet]
│ session id: 28
│ request updates: true
└─[MultilevelSensorCCReport]
type: Air temperature
scale: Celsius
value: 19.7
2022-12-15T15:39:23.134Z SERIAL « [ACK] (0x06)
2022-12-15T15:39:23.141Z SERIAL « 0x0104011301e8 (6 bytes)
2022-12-15T15:39:23.142Z SERIAL » [ACK] (0x06)
2022-12-15T15:39:23.142Z DRIVER « [RES] [SendData]
was sent: true
2022-12-15T15:39:24.575Z SERIAL « 0x01180013f000009001ca7f7f7f7f010103030000000202030e52 (26 bytes)
2022-12-15T15:39:24.576Z SERIAL » [ACK] (0x06)
2022-12-15T15:39:24.577Z DRIVER « [REQ] [SendData]
callback id: 240
transmit status: OK, took 1440 ms
repeater node IDs: 3
routing attempts: 2
protocol & route speed: Z-Wave, 40 kbit/s
ACK RSSI: -54 dBm
ACK RSSI on repeaters: N/A
ACK channel no.: 1
TX channel no.: 1
route failed here: 3 -> 14
2022-12-15T15:39:24.656Z SERIAL « 0x01190004000e119f03c7008844ba3094626508bafe6d875bca0044 (27 bytes)
2022-12-15T15:39:24.657Z SERIAL » [ACK] (0x06)
2022-12-15T15:39:24.657Z DRIVER « [Node 014] [REQ] [ApplicationCommand]
└─[Security2CCMessageEncapsulation]
│ sequence number: 199
└─[SupervisionCCReport]
session id: 28
more updates follow: false
status: Success
duration: 0s
New season coming, and I started HA setup from scratch. Revisited this issue and found your automation to be very convenient - one for all TRVs in one. Thanks!
I recently changed the automation a little. Basically to stop too much unnecessary updates being sent over the zwave network. i now first check if the temperature has actually changed before sending the zwave command.
alias: Appartment.SetTempFromRoomSensors
description: >-
This automation sets the external temperature sensor on Eurotronic Spirit
Z-Wave
trigger:
- platform: state
entity_id:
- sensor.bathroom_multisensor_air_temperature
- sensor.bedroom_multisensor_air_temperature
- sensor.kitchen_multisensor_air_temperature
- sensor.livingroom_multisensor_air_temperature
- sensor.office_multisensor_air_temperature
condition:
- condition: template
value_template: "{{ trigger.from_state.state|float(0) != trigger.to_state.state|float(0) }}"
action:
- service: zwave_js.invoke_cc_api
data:
command_class: "49"
endpoint: "0"
method_name: sendReport
parameters:
- 1
- 0
- "{{ states(trigger.entity_id) }}"
target:
entity_id: >-
{{ expand(states.climate) | selectattr('entity_id', 'in',
area_entities(area_id(trigger.entity_id)))|map(attribute='entity_id') |
list }}
mode: queued
max: 5
Where can I find these “temperature” association group” ? I want to pair my Spirit with an Everspring ST814. This was possible with my old Homee.