i recently started playing with ZWaveJS and noticed that my dimmers are very slow to report the correct state to the UI when turning on the light. I switched my ZWaveJS to use MQTT instead of web sockets and the issue goes away.
The logs show a 5 second delay when using web sockets, and the value is reported as 255 not 99.
When using MQTT the state is reflected instantly and the value is set to 99.
I did not find those differences discussed in the forums yet, and was wondering why web sockets is using 255 instead of 99. Could that cause the delay?
Web Sockets:
2022-04-15 20:53:33.504 INFO ZWAVE: Node 8: value updated: 38-0-targetValue 0 => 255
2022-04-15 20:53:38.660 INFO ZWAVE: Node 8: value updated: 38-0-targetValue 255 => 99
2022-04-15 20:53:38.665 INFO ZWAVE: Node 8: value updated: 38-0-duration 0s => 0s
2022-04-15 20:53:38.668 INFO ZWAVE: Node 8: value updated: 38-0-currentValue 0 => 99
MQTT:
2022-04-15 20:57:34.176 INFO MQTT: Message received on zwave/Office_Main_Light/38/0/targetValue/set: '99'
2022-04-15 20:57:34.178 INFO ZWAVE: Writing 99 to 8-38-0-targetValue
2022-04-15 20:57:34.368 INFO ZWAVE: Node 8: value updated: 38-0-currentValue 0 => 99
2022-04-15 20:57:34.373 INFO ZWAVE: Node 8: value updated: 38-0-targetValue 0 => 99
I played some more with the dimmer. When using the service “light: turn_on” without brightness, the state is updated after 5 seconds. When setting the brightness to 255, in the “light: turn_on” the state for the dimmer is showing instantly in the UI.
Is there a way to override default service behavior for all dimmers to always include brightness?
2022-04-15 21:32:39.992 INFO ZWAVE: Node 8: value updated: 38-0-currentValue 0 => 99
2022-04-15 21:32:39.996 INFO ZWAVE: Node 8: value updated: 38-0-targetValue 0 => 99
I saw a similar issue with a fan zwave switch. In that case zwavejs was cancelling the poll after set, I opened a bug report and it should be getting fixed.
Capture the zwavejs log files and post the excerpt here
I just migrated my z-wave dimmers from the Vera integration to Zwave JS with an Aeotec Z-stick 7, and now all my dimmers take 5 seconds to update on my dashboard when I turn on the light or fan from Home Assistant.
I believe the way it works is zwavejs will poll the device after 4 seconds after performing a setpoint if the device hasn’t sent the value yet. Well behaved devices should be sending it. But I have several that don’t…… It would be helpful if the 4 seconds was configurable……
What you can do as a workaround is poll it from an automation. I do this for many devices. For the variable speed fan controller I was able to trigger off of the switch state changing to the poll the level.
Later on I discovered that an automation can trigger from the service call event. I haven’t tried that since the current cludge has been reliable.
The automation delays for 500ms, then poll, then delay for another 1second and poll again just for good measure.
- id: "loft_fan_1 refresh switch state"
alias: loft_fan_1 refresh switch state
description: "Automation to refresh switch after state changes usually caused by switch control"
mode: queued
trigger:
- platform: state
entity_id: fan.loft_fan_1_level
condition: "{{ trigger.to_state.state != trigger.from_state.state }}"
action:
- service: system_log.write
data:
level: info
message: "Polling fan.loft_fan_1_level state change from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}"
logger: hvac
- service: zwave_js.refresh_value
data:
entity_id: fan.loft_fan_1_level
- delay: "00:00:01"
- service: zwave_js.refresh_value
data:
entity_id: fan.loft_fan_1_level
I wonder if your automation solves a different problem that what I’m facing.
I applied it exactly, with the exception of the entity (I changed fan.loft_fan_1_level to light.living_room_light). It still takes about 6 seconds for the status to update on my dashboard when I turn the light on, but now it also takes 6 seconds when I turn the light off. Without the automation it’s almost instantaneous when turning the light off.
This is with HomeSeer HS-WD200+ dimmers and HS-FC200+ fan controllers.
Here’s what I get in the Debug window of Zwave JS UI (formerly known as zwavejs2mqtt).
Turning light on to a specific level (updates immediately):
2022-09-28 17:41:29.827 INFO Z-WAVE: Node 2: value updated: 38-0-currentValue 0 => 43
2022-09-28 17:41:29.827 INFO Z-WAVE: Node 2: value updated: 38-0-targetValue 0 => 43
2022-09-28 17:41:34.864 INFO Z-WAVE: Node 2: value updated: 38-0-targetValue 43 => 43
2022-09-28 17:41:34.865 INFO Z-WAVE: Node 2: value updated: 38-0-duration 0s => 0s
2022-09-28 17:41:34.865 INFO Z-WAVE: Node 2: value updated: 38-0-currentValue 43 => 43
Turning light off (updates immediately):
2022-09-28 17:41:47.640 INFO Z-WAVE: Node 2: value updated: 38-0-currentValue 43 => 0
2022-09-28 17:41:47.644 INFO Z-WAVE: Node 2: value updated: 38-0-targetValue 43 => 0
2022-09-28 17:41:52.680 INFO Z-WAVE: Node 2: value updated: 38-0-targetValue 0 => 0
2022-09-28 17:41:52.681 INFO Z-WAVE: Node 2: value updated: 38-0-duration 0s => 0s
2022-09-28 17:41:52.681 INFO Z-WAVE: Node 2: value updated: 38-0-currentValue 0 => 0
Turning light on (updates after 5 seconds):
2022-09-28 17:41:59.475 INFO Z-WAVE: Node 2: value updated: 38-0-targetValue 0 => 255
2022-09-28 17:42:04.514 INFO Z-WAVE: Node 2: value updated: 38-0-targetValue 255 => 43
2022-09-28 17:42:04.515 INFO Z-WAVE: Node 2: value updated: 38-0-duration 0s => 0s
2022-09-28 17:42:04.515 INFO Z-WAVE: Node 2: value updated: 38-0-currentValue 0 => 43
In the first two cases, it looks like we’re setting the currentValue before setting the targetValue. In the third case, we don’t set the currentValue (presumably because we don’t know what the value should be) and the dashboard doesn’t get updated.
When I ran the automation suggested above, it didn’t trigger until after the currentValue was updated (after the 5 second delay in the third case).
This “issue” has been reported dozens of times in this forum and on also on GitHub for many years, over multiple drivers. Some attempts to address this in HA haven’t been accepted, and they have not been good solutions. I’d suggest either live with the UI issue, or set a specific brightness level when you turn it on to avoid it. Polling the device to avoid a temporary UI issue seems like overkill to me. If you really wanted to do that, you could try using the value updated trigger to react to the targetValue property change (to 255), instead of the entity state.
When you turn on the switch w/o a set level, the driver does not know what the expected level will be, so it doesn’t update until 5 seconds later (+ N duration). This delay is not configurable unless you run the driver yourself, and it applies globally, not per-device. The UI reverts to the previous state if it doesn’t get an update before 2 seconds. When you turn on a device with a specific level, the driver sends an immediate optimistic response, which updates the state in HA.
This automation for a fan controller works for me. After turning on the fan via HA (255 level), it waits 500 ms then refreshes the device. I used device triggers because it was too easy that way. You can convert to non-device triggers if that suits you. The delay should be personalized to account for the device ramp rate and network performance. If the refresh occurs after 2 seconds, it won’t be effective and the UI will revert. If it occurs too quickly, Z-Wave JS will cancel the 5 second refresh and you may get the wrong value back if it’s still transitioning (this was the problem with OZW).
alias: Fan Switch On Refresh
description: Quick refresh of fan switch when toggled on (last known level)
trigger:
- platform: device
device_id: b95ebbd62ac901ed77c3d5c7305f9f76
domain: zwave_js
type: zwave_js.value_updated.value
command_class: 38
property: targetValue
to: "255"
condition: []
action:
- delay:
hours: 0
minutes: 0
seconds: 0
milliseconds: 500
- device_id: b95ebbd62ac901ed77c3d5c7305f9f76
domain: zwave_js
entity_id: fan.in_wall_fan_speed_control_300s
type: refresh_value
mode: single
On more option would be to use an event trigger with the call_service event type, which is triggered whenever the UI is used to turn on/off the light. You would want to condition on the service turn_one, and probably check for no service call data (or more explicitly, no brightness value), otherwise you would poll unnecessarily. A downside is it wouldn’t trigger if you were using zwave-js-ui to turn it on (which the above handles, it even works with multiple HA instances), which probably isn’t a big deal. An upside is that this event would be triggered before the driver returns the targetValue updated event, so there’s no reliance on that message being received.
I could make it trigger on any one of my dimmers, but I couldn’t find a way to only poll the entity that changed, so I would have to use a separate automation for each dimmer (I have 5 of these so far).
I’ll play around with the call_service event trigger as well. That sounds promising, and I like to learn new things. Thanks for the advice.
That’s what I thought, but trigger.device_id was always empty. I tested with trigger.node_id and trigger.device_id and those had values, but trigger.device_id didn’t. I suppose I could poll all 5 devices, but that’s definitely overkill.