FYI, I found these instructions and then modified them so that I could update the firmware on my Sonoff Smart Water Valve (SWV).
I successfully updated from 1.0.2 to 1.0.4
This article will introduce recent feature optimizations for SNZB-06P Human Presence Sensor, including: Optimization of detection duration, How to configure sensitivity and detection duration on ZHA & Z2M, How to update firmware on ZHA & Z2M...
Est. reading time: 7 minutes
### Add the following in the config file so that SonOff is enabled for update
zha:
zigpy_config:
ota:
extra_providers:
- type: sonoff
- type: z2m
### Run the command below against the device to get it to detect the firmware update.
action: zha.issue_zigbee_cluster_command
data:
ieee: ’xx:xx:xx:xx:xx:xx:xx’ #add the IEEE number for the device.
endpoint_id: 1 # Endpoint id for the OTA cluster.
cluster_type: out
command_type: client
cluster_id: 25
command: 0
params:
payload_type: 0
query_jitter: 100
Then it showed up to firmware update.
3 Likes
Updated sucessfully with your help MaikaiLife Shaun. Thank you.
Does anyone know how to get the option to deactivate the auto_close option with zha?
Tried to use zha toolkit for getting the maybe hidden attribute and set it with it, but without success. It seems it is not available with that option.
zha_toolkit_version: v1.1.27
zigpy_version: 0.80.1
zigpy_rf_version: 0.45.0
ieee_org:
- 36
- 158
- 173
- 254
- 255
- 246
- 239
- 12
ieee: <IEEE address>
command: scan_device
command_data: null
start_time: "2025-06-27T05:52:48.882372+00:00"
errors: []
params:
dir: 0
tries: 100
expect_reply: true
args: []
kwargs: {}
read_before_write: true
read_after_write: true
scan:
ieee: <IEEE address>
nwk: "0x84bd"
model: SWV
manufacturer: SONOFF
manufacturer_id: "0x4742"
endpoints:
- id: 1
device_type: "0x0002"
profile: "0x0104"
in_clusters:
"0x0000":
cluster_id: "0x0000"
title: Basic
name: basic
attributes:
"0x0000":
attribute_id: "0x0000"
attribute_name: zcl_version
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 8
"0x0001":
attribute_id: "0x0001"
attribute_name: app_version
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 16
"0x0003":
attribute_id: "0x0003"
attribute_name: hw_version
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 16
"0x0004":
attribute_id: "0x0004"
attribute_name: manufacturer
value_type:
- "0x42"
- CharacterString
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value: SONOFF
"0x0005":
attribute_id: "0x0005"
attribute_name: model
value_type:
- "0x42"
- CharacterString
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value: SWV
"0x0006":
attribute_id: "0x0006"
attribute_name: date_code
value_type:
- "0x42"
- CharacterString
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value: "20240820"
"0x0007":
attribute_id: "0x0007"
attribute_name: power_source
value_type:
- "0x30"
- enum8
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value: 3
"0x0011":
attribute_id: "0x0011"
attribute_name: physical_env
value_type:
- "0x30"
- enum8
- Discrete
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: 0
"0x4000":
attribute_id: "0x4000"
attribute_name: sw_build_id
value_type:
- "0x42"
- CharacterString
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value: 1.0.4
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 3
commands_received:
"0x00":
command_id: "0x00"
command_name: reset_fact_default
command_arguments: <class 'zigpy.zcl.foundation.reset_fact_default'>
commands_generated: {}
"0x0001":
cluster_id: "0x0001"
title: Power Configuration
name: power
attributes:
"0x0020":
attribute_id: "0x0020"
attribute_name: battery_voltage
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 51
"0x0021":
attribute_id: "0x0021"
attribute_name: battery_percentage_remaining
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 114
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
commands_received: {}
commands_generated: {}
"0x0003":
cluster_id: "0x0003"
title: Identify
name: identify
attributes:
"0x0000":
attribute_id: "0x0000"
attribute_name: identify_time
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: 0
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
commands_received:
"0x00":
command_id: "0x00"
command_name: identify
command_arguments: <class 'zigpy.zcl.foundation.identify'>
"0x01":
command_id: "0x01"
command_name: identify_query
command_arguments: <class 'zigpy.zcl.foundation.identify_query'>
commands_generated:
"0x00":
command_id: "0x00"
command_name: identify_query_response
command_args: <class 'zigpy.zcl.foundation.identify_query_response'>
"0x0006":
cluster_id: "0x0006"
title: On/Off
name: on_off
attributes:
"0x0000":
attribute_id: "0x0000"
attribute_name: on_off
value_type:
- "0x10"
- Bool
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value: 1
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
commands_received:
"0x00":
command_id: "0x00"
command_name: "off"
command_arguments: <class 'zigpy.zcl.foundation.off'>
"0x01":
command_id: "0x01"
command_name: "on"
command_arguments: <class 'zigpy.zcl.foundation.on'>
"0x02":
command_id: "0x02"
command_name: toggle
command_arguments: <class 'zigpy.zcl.foundation.toggle'>
"0x42":
command_id: "0x42"
command_name: on_with_timed_off
command_arguments: <class 'zigpy.zcl.foundation.on_with_timed_off'>
commands_generated: {}
"0x0020":
cluster_id: "0x0020"
title: Poll Control
name: poll_control
attributes:
"0x0000":
attribute_id: "0x0000"
attribute_name: checkin_interval
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: 13200
"0x0001":
attribute_id: "0x0001"
attribute_name: long_poll_interval
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 24
"0x0002":
attribute_id: "0x0002"
attribute_name: short_poll_interval
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
"0x0003":
attribute_id: "0x0003"
attribute_name: fast_poll_timeout
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: 40
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 3
commands_received:
"0x00":
command_id: "0x00"
command_name: checkin_response
command_arguments: <class 'zigpy.zcl.foundation.checkin_response'>
"0x01":
command_id: "0x01"
command_name: fast_poll_stop
command_arguments: <class 'zigpy.zcl.foundation.fast_poll_stop'>
"0x02":
command_id: "0x02"
command_name: set_long_poll_interval
command_arguments: <class 'zigpy.zcl.foundation.set_long_poll_interval'>
"0x03":
command_id: "0x03"
command_name: set_short_poll_interval
command_arguments: <class 'zigpy.zcl.foundation.set_short_poll_interval'>
commands_generated:
"0x00":
command_id: "0x00"
command_name: checkin
command_args: <class 'zigpy.zcl.foundation.checkin'>
"0x0404":
cluster_id: "0x0404"
title: Flow Measurement
name: flow
attributes:
"0x0000":
attribute_id: "0x0000"
attribute_name: measured_value
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 0
"0x0001":
attribute_id: "0x0001"
attribute_name: min_measured_value
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 0
"0x0002":
attribute_id: "0x0002"
attribute_name: max_measured_value
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 27
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
commands_received: {}
commands_generated: {}
"0x0b05":
cluster_id: "0x0b05"
title: Diagnostic
name: diagnostic
attributes:
"0x011b":
attribute_id: "0x011b"
attribute_name: average_mac_retry_per_aps_message_sent
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
"0x011c":
attribute_id: "0x011c"
attribute_name: last_message_lqi
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 100
"0x011d":
attribute_id: "0x011d"
attribute_name: last_message_rssi
value_type:
- "0x28"
- int8s
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: -75
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 3
commands_received: {}
commands_generated: {}
"0xfc11":
cluster_id: "0xfc11"
title: CustomSonoffCluster
name: null
attributes:
"0x001a":
attribute_id: "0x001a"
attribute_name: "26"
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: 0
"0x001b":
attribute_id: "0x001b"
attribute_name: "27"
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: 0
"0x5006":
attribute_id: "0x5006"
attribute_name: "20486"
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 3000
"0x5007":
attribute_id: "0x5007"
attribute_name: "20487"
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 0
"0x5008":
attribute_id: "0x5008"
attribute_name: "20488"
value_type:
- "0x42"
- CharacterString
- Discrete
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: ""
"0x5009":
attribute_id: "0x5009"
attribute_name: "20489"
value_type:
- "0x42"
- CharacterString
- Discrete
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: ""
"0x500c":
attribute_id: "0x500c"
attribute_name: water_valve_state
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 1
"0x500d":
attribute_id: "0x500d"
attribute_name: "20493"
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 1751009659
"0x500e":
attribute_id: "0x500e"
attribute_name: "20494"
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 1751007511
"0x500f":
attribute_id: "0x500f"
attribute_name: "20495"
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 0
"0x5010":
attribute_id: "0x5010"
attribute_name: "20496"
value_type:
- "0x20"
- uint8_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 0
"0x5011":
attribute_id: "0x5011"
attribute_name: "20497"
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|WRITE|REPORT
access_acl: 7
attribute_value: 30
"0xfffd":
attribute_id: "0xfffd"
attribute_name: "65533"
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 1
commands_received:
"0x00":
command_id: "0x00"
command_name: "0"
command_arguments: not_in_zcl
commands_generated: {}
"0xfc57":
cluster_id: "0xfc57"
title: Manufacturer Specific
name: manufacturer_specific
attributes: {}
commands_received: {}
commands_generated: {}
out_clusters:
"0x000a":
cluster_id: "0x000a"
title: Time
name: time
attributes:
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
commands_received: {}
commands_generated: {}
"0x0019":
cluster_id: "0x0019"
title: Ota
name: ota
attributes:
"0x0000":
attribute_id: "0x0000"
attribute_name: upgrade_server_id
value_type:
- "0xf0"
- EUI64
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value:
- 120
- 118
- 11
- 254
- 255
- 110
- 2
- 188
"0x0001":
attribute_id: "0x0001"
attribute_name: file_offset
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 4294967295
"0x0002":
attribute_id: "0x0002"
attribute_name: current_file_version
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 4100
"0x0003":
attribute_id: "0x0003"
attribute_name: current_zigbee_stack_version
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 2
"0x0004":
attribute_id: "0x0004"
attribute_name: downloaded_file_version
value_type:
- "0x23"
- uint32_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 4294967295
"0x0005":
attribute_id: "0x0005"
attribute_name: downloaded_zigbee_stack_version
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 65535
"0x0006":
attribute_id: "0x0006"
attribute_name: image_upgrade_status
value_type:
- "0x30"
- enum8
- Discrete
access: READ|REPORT
access_acl: 5
attribute_value: 0
"0x0007":
attribute_id: "0x0007"
attribute_name: manufacturer_id
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 4742
"0x0008":
attribute_id: "0x0008"
attribute_name: image_type_id
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 65535
"0xfffd":
attribute_id: "0xfffd"
attribute_name: cluster_revision
value_type:
- "0x21"
- uint16_t
- Analog
access: READ|REPORT
access_acl: 5
attribute_value: 4
commands_received: {}
commands_generated:
"0x01":
command_id: "0x01"
command_name: "1"
command_args: not_in_zcl
"0x03":
command_id: "0x03"
command_name: "3"
command_args: not_in_zcl
"0x06":
command_id: "0x06"
command_name: "6"
command_args: not_in_zcl
success: true
sol3uk
(Ben)
July 3, 2025, 3:17pm
45
Hi,
This link doesn’t appear to work anymore, do you know the config file that you’re supposed to add the code you’ve shared to?
Never mind I figured it out!
For posterity:
The config file is just the normal config.yaml. The action is a manual action run from the “Actions” tab in the “Developer Tools” section.
Dudenell
(Daniel Carr)
July 4, 2025, 9:36pm
46
Not really understanding what I’m doing wrong here, using zigbee2mqtt. Attempting to set “Irrigation Duration” ONLY.
I get this message:
z2m: Publish ‘set’ ‘cyclic_timed_irrigation’ to ‘Front Yard Irrigation’ failed: ‘Error: ZCL command 0x842712fffe178d39/1 customClusterEwelink.write({“20488”:{“value”:{“0”:10,“1”:0,“2”:0,“3”:0,“4”:0,“5”:3,“6”:132,“7”:0,“8”:0,“9”:0,“10”:0},“type”:66}}, {“timeout”:10000,“disableResponse”:false,“disableRecovery”:false,“disableDefaultResponse”:false,“direction”:0,“reservedBits”:0,“writeUndiv”:false}) failed (Status ‘INVALID_VALUE’)’
If I set the other values under Cyclic timed irrigation (which I don’t really understand the purpose of them), it ends up disappearing eventually.
I just hoping to set an overall max time on.
Chrisco93
(Christopher)
July 5, 2025, 1:26am
47
Update: looks like running command 66 doesnt bypass the 30 minutes shutoff
Here is how i am dealing with the auto off (using ZHA)
Create a number helper for how many minutes you want it to run. A script to call the zha cluster. I also added my dashboard card im using.
Helper number:
min 1, max 120 (minutes)
Type: slider
Step size 1
Unit of measurement: min
Script to call zha cluster
data:
ieee: yourieee
endpoint_id: 1
cluster_id: 6
command: 66
params:
on_off_control: []
on_time: "{{ states('input_number.deckmisteron_timeseconds') | int(0) * 60 }}"
off_wait_time: 30
command_type: server
cluster_type: in
action: zha.issue_zigbee_cluster_command
Then on my dashboard i use the following
type: entities
title: Deck
show_header_toggle: false
entities:
- type: conditional
conditions:
- entity: switch.deckmist
state: "off"
row:
entity: input_number.deckmisteron_timeseconds
name: Mist On Time
state_color: true
- type: conditional
conditions:
- entity: switch.deckmist
state: "off"
row:
type: button
name: Turn On Deck Mist
tap_action:
action: call-service
service: script.deckmister_timed_on_command
icon: mdi:sprinkler-fire
- type: conditional
conditions:
- entity: switch.deckmist
state: "on"
row:
type: button
name: Turn Off Deck Mist
tap_action:
action: call-service
service: switch.turn_off
data:
entity_id: switch.deckmist
icon: mdi:sprinkler-off
1 Like
sol3uk
(Ben)
July 5, 2025, 9:26am
48
UPDATE:
I updated the firmware to the latest version but I still do not get the “Auto Off” option that’s mentioned above. Not sure what I’m doing wrong here.
sol3uk
(Ben)
July 5, 2025, 9:31am
49
I updated the firmware via ZHA but I do not see this option. Are you able to share where you are seeing the firmware version and how you updated it?
Chrisco93
(Christopher)
July 5, 2025, 3:33pm
50
Ben,
I also still dont have any Auto Off option with ZHA. Version 0x00001004.
Instead i am using the script i posted above to control how long it runs.
Update: looks like running command 66 doesnt bypass the 30 minutes shutoff
brendan
(Brendan)
July 17, 2025, 4:25pm
51
Firmware alone doesn’t expose the options. ZHA does not have the option in it’s “quirk” or driver for the SOnOff SWV. Basically, as of today, if you are using ZHA you are sweet out of luck. If the SOnOff SWV detects no water flow, it will turn off after 30 minutes. Only Zigbee2MQTT has the option currently, or th EWELINK app.
I work around the issue using an input boolean helper and an automation that turns the valve back on if the input boolean is on and the valve closes. This does use more battery, but it’s probably your only work around in ZHA until the team update the driver or quirk for the SWV. Might be an idea if someone goes to github and requests it be added, if there is not already a request there.
navis
July 20, 2025, 4:05pm
52
Hi,
I have added an option to turn of water flow monitoring to the ZHA quirk. If you want, you can give it a try (only for version 1.0.4):
https://github.com/maga-1/zha-device-handlers/blob/c1adc09a0b67cf4b469c12fc85ef044eda460c34/zhaquirks/sonoff/swv.py
It will add a new switch to the configuration panel:
Endpoints etc. are taken from the herdsman-repo .
I hope, this might be useful, a pull request will follow.
1 Like
Hello,
Would it be possible for you to post the code for the custom quirk? The link does not work anymore for me.
Sadly the link doesn’t work anymore. Can you please correct that?
Just tried the link myself and you’re right - it gives a 404 if you click on it.
Copy and paste it in your browser and it will work though.
If that still doesn’t work, remove swv.py when pasting the link in your browser, then navigate manually to swv.py folder. I tried both methods suggested above and the both work for me.
navis
August 7, 2025, 6:17am
56
Sorry, I have deleted the branch after the pull request was finished. The quirk is now in the main repository of zha-device-handlers: https://github.com/zigpy/zha-device-handlers/blob/ae06bdcbf45f06feb784dc1ce248121df0f2e752/zhaquirks/sonoff/swv.py
I hope it will appear in a release soon.
1 Like
Here is my finding and a nice solution if you also face the issue that the valve tuns off automatically. Not 100% sure why the valve turns off…but pretty sure that the reason is rather a feature built-in into the firmware which cannot be circumvented via configuration or mqtt commands and which turns off the valve when the water flow is too low (water_shortage state).
However, here a nice trick which works for me: I created a timer (helper) which I set in the HA automation to the duration when starting the valve. Then I created this little automation which starts the valve again when the timer is still active:
alias: restart irrigation if the valve turns off unintended
description: ""
triggers:
- trigger: state
entity_id: switch.watervalvetoepfe
to: "off"
conditions:
- condition: state
entity_id: timer.toepfe_bewaesserung
state: active
actions:
- variables:
rest_s: >
{% set finish = state_attr('timer.toepfe_bewaesserung', 'finishes_at')
%} {% if finish %}
{% set delta = (as_datetime(finish) - now()).total_seconds() %}
{{ [delta, 0] | max | round(0) }}
{% else %}
0
{% endif %}
- choose:
- conditions:
- condition: template
value_template: "{{ rest_s > 30 }}"
sequence:
- delay:
hours: 0
minutes: 0
seconds: 15
milliseconds: 0
- action: mqtt.publish
data:
topic: zigbee2mqtt/WaterValveToepfe/set
payload: |
{{
{
"state": "ON",
"on_time": rest_s,
"off_wait_time": 10
} | tojson
}}
mode: single
navis
August 12, 2025, 9:16am
58
The switch for SWV appeared in HA 2025.8.0, so there should be no need for installing from git anymore.
brendan
(Brendan)
September 27, 2025, 5:26am
59
Works fine with ZHA and Zigee2MQTT No need to install any additional quirks.
As of 2025.9 ZHA also has a toggle to turn off the auto shutoff that annoyed so many. the SWV is designed for irrigation primarily, so when no water flow was detected, it sensed it as a problem and shut the valve after 30 minutes in this state. ZHA and Zigbee2MQTT both have an option to disable this function now. I have not used Zigbee2MQTT, but it works fine in ZHA natively out of the box
hi,
the link is for Sonoff motion sensor.
Where did you find the firmware for SWV ?
(or how did you modify it to update SWV ?)
thanks
The link is for illustration of instructions; the firmware is auto detected when you have the configuration applied.