Skip to content

Add auto close time to Sonoff SWV-BSP Smart Water Valve #3930

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: dev
Choose a base branch
from

Conversation

micz
Copy link

@micz micz commented Mar 4, 2025

I added these features to the Sonoff SWV-BSP Smart Water Valve (see #3298):

  • Water Leakage binary sensor
  • Water Shortage binary sensor
  • on_time attribute, representing the number of seconds after opening before the valve automatically closes.
  • A custom behaviour for the On command:
    1. If on_time == 0 it's a normal On command (0x01)
    2. If on_time != 0 it sends a on_with_timed_off (0x42), with the on_time numbers of seconds sets in the attribute

immagine immagine

This is my first attempt at creating a Quirk.
Any advice on whether I'm following the correct way would be appreciated.
Thank you!

Checklist

  • The changes are tested and work correctly
  • pre-commit checks pass / the code has been formatted using Black
  • Tests have been added to verify that the new code works

Copy link

codecov bot commented Mar 4, 2025

Codecov Report

❌ Patch coverage is 96.55172% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 91.19%. Comparing base (7713d81) to head (2848ec1).
⚠️ Report is 55 commits behind head on dev.

Files with missing lines Patch % Lines
zhaquirks/sonoff/swv.py 96.55% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #3930      +/-   ##
==========================================
+ Coverage   91.18%   91.19%   +0.01%     
==========================================
  Files         334      334              
  Lines       10862    10891      +29     
==========================================
+ Hits         9904     9932      +28     
- Misses        958      959       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@fgsch
Copy link
Contributor

fgsch commented Mar 7, 2025

FWIW, I have a similar PR minus the on_time in #3910.

@micz
Copy link
Author

micz commented Mar 7, 2025

Thank you @fgsch, I've updated the code.
The on_time is the feature I need as a failsafe if the Zigbee connection fails.
What do you think about it? Have you tried it?

I didn't see your PR, I'm sorry.
I saw that you changed the Cluster name, do you think it's better to change it here also?
Thank you!

@fgsch
Copy link
Contributor

fgsch commented Mar 8, 2025

Thank you @fgsch, I've updated the code.

👍

The on_time is the feature I need as a failsafe if the Zigbee connection fails. What do you think about it? Have you tried it?

I haven't tried it yet.

IIUC you are using the attribute for the automatic valve close if there is no water together with the timing irrigation command for this purpose? Is this correct?

I didn't see your PR, I'm sorry. I saw that you changed the Cluster name, do you think it's better to change it here also? Thank you!

No worries. I changed the name to match other devices. Might as well do it here but really up to you.

@micz
Copy link
Author

micz commented Mar 8, 2025

IIUC you are using the attribute for the automatic valve close if there is no water together with the timing irrigation command for this purpose? Is this correct?

I'm sorry I don't understand your question.

I added the on_time attribute to let the user decide how much time set for the auto close (0 = no autoclose).
Then, I use that attribute in the command to determine whether it needs to be changed to 0x42.

I added also the two alarms, because I found your PR #3346 that added the attributes and I read that the other PRs in ZHA needed for the attribute_converter were done, but I didn't found your last PR, so I added them here.

@fgsch
Copy link
Contributor

fgsch commented Mar 9, 2025

[..]
I'm sorry I don't understand your question.

I added the on_time attribute to let the user decide how much time set for the auto close (0 = no autoclose). Then, I use that attribute in the command to determine whether it needs to be changed to 0x42.

That attribute, 0x5011, is used to turn the valve off if there is no water for the specified amount of time (as per https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/devices/sonoff.ts#L1447).

This PR uses this attribute as a timer, which is later used with command 0x42 for timed irrigation (as per https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/devices/sonoff.ts#L329-L363).

Effectively, this is changing what 0x5011 is used for, assuming I understood correctly.
Maybe there is a better way to implement this that does not (ab)use existing attributes.

@micz
Copy link
Author

micz commented Mar 9, 2025

Now I understand.
It's my first quirk so any help in more than appreciated! 😄

My idea was to keep a single switch but let the user set a timeout and then send a 42 instead of a 01.

I found no way to add and store that value. Trying to figure it out I found that parameter, but I didn't get it was used for water shortage.
I tried to find a solution in other quirks v2, but I didn't find anything.
In z2m you could send a different command issuing a 42, but in ZHA it's different. If I got it right.

Could you point me in the right direction of adding an optional timeout in the device config?
Thank you!

@fgsch
Copy link
Contributor

fgsch commented Mar 10, 2025

[..]

Could you point me in the right direction of adding an optional timeout in the device config? Thank you!

I'm not sure. Perhaps one of the devs could help.

@TheJulianJES TheJulianJES added the needs reviewer answer An answer from a reviewer is needed (e.g. why a PR isn't acceptable in the current state). label Mar 15, 2025
@micz
Copy link
Author

micz commented Mar 24, 2025

@fgsch, are you the reviewer who needs to respond based on the label?
Thank you.

@TheJulianJES
Copy link
Collaborator

TheJulianJES commented Mar 24, 2025

No, it's a label for me (or other reviewers) that an answer/review/help is needed.
I'll come back to this when I find some time.

@micz
Copy link
Author

micz commented Mar 24, 2025

Ok, thank you.

@micz micz reopened this Apr 6, 2025
@micz
Copy link
Author

micz commented Apr 6, 2025

I've updated the PR for version 0.0.136, considering the merging of #3910.

@TheJulianJES TheJulianJES changed the title Sonoff SWV-BSP Smart Water Valve improvements Add auto close time to Sonoff SWV-BSP Smart Water Valve Apr 30, 2025
@LethalWhisper
Copy link

I've already tested your quirk with my 2 Sonoff SWV and it works perfectly fine :)

In my opinion it is ready for merge :)

I am currently trying to implement the few missing features that you may find in z2m, although it's not that useful.

Copy link
Contributor

@puddly puddly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a few code quality comments. I do have a question about this functionality as a whole, however: it looks like this PR basically adds a software-only "auto close time" configurable entity to the device and then intercepts OnOff:on commands, substituting them with OnOff:on_with_timed_off.

Since OnOff:on_with_timed_off is a standard ZCL cluster command, it feels odd to change the behavior of this one device. We should maybe instead consider implementing this as an action for all devices with OnOff cluster support? @TheJulianJES thoughts?

Comment on lines +54 to +55
cluster_id = OnOff.cluster_id
cmd_values = OnOff.commands_by_name.values()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cluster_id = OnOff.cluster_id
cmd_values = OnOff.commands_by_name.values()

kwargs["off_wait_time"] = 1
self.create_catching_task(self._turn_off_later(on_time_value))

return await self.request(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should call return await super().command(*args, **kwargs) instead, since this method is effectively proxying the call to command.

CustomSonoffCluster.AttributeDefs.on_time.id
)
if on_time_value is not None and on_time_value != 0:
command = self.server_commands[0x42] # on_with_timed_off
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
command = self.server_commands[0x42] # on_with_timed_off
command = self.ServerCommandDefs.on_with_timed_off

What does this line do? command isn't used anywhere.

self._is_manuf_specific or command.is_manufacturer_specific
):
manufacturer = self._manufacturer_id
if command_id == 0x01:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if command_id == 0x01:
if command_id == self.ServerCommandDefs.on.id:

async def _turn_off_later(self, delay):
"""We are not receiving the auto off event, so we force an update."""
await asyncio.sleep(delay + 1)
await self.endpoint.on_off.read_attributes(["on_off"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the device not report the attribute change on its own, when it turns back off?

@TheJulianJES
Copy link
Collaborator

Since OnOff:on_with_timed_off is a standard ZCL cluster command, it feels odd to change the behavior of this one device. We should maybe instead consider implementing this as an action for all devices with OnOff cluster support? @TheJulianJES thoughts?

Yeah, I don't think this implementation is optimal. If needed, this can already be done using a HA automation that sends a cluster command. homeassistant.update_entity can be called to poll the entity after the delay if it doesn't report its state.

The "on_time" (0x5011) attribute also seems to be used by the firmware to determine when the device should turn off if there's no water. See Z2M for reference: https://github.com/Koenkk/zigbee-herdsman-converters/blob/4275931105788ec04b5b671640a2c86efa97f131/src/devices/sonoff.ts#L1954-L1962
It seems like we're misusing that attribute for local storage here?

@fcrozat
Copy link

fcrozat commented Jul 17, 2025

Since OnOff:on_with_timed_off is a standard ZCL cluster command, it feels odd to change the behavior of this one device. We should maybe instead consider implementing this as an action for all devices with OnOff cluster support? @TheJulianJES thoughts?

Yeah, I don't think this implementation is optimal. If needed, this can already be done using a HA automation that sends a cluster command. homeassistant.update_entity can be called to poll the entity after the delay if it doesn't report its state.

The "on_time" (0x5011) attribute also seems to be used by the firmware to determine when the device should turn off if there's no water. See Z2M for reference: https://github.com/Koenkk/zigbee-herdsman-converters/blob/4275931105788ec04b5b671640a2c86efa97f131/src/devices/sonoff.ts#L1954-L1962 It seems like we're misusing that attribute for local storage here?

This is a different feature from the device.

https://github.com/Koenkk/zigbee-herdsman-converters/blob/4275931105788ec04b5b671640a2c86efa97f131/src/devices/sonoff.ts#L278 function is how timed / cyclic irrigation is managed by Z2M, using '0x5008' attribute

@PaulBol
Copy link

PaulBol commented Jul 17, 2025

This is a different feature from the device.

https://github.com/Koenkk/zigbee-herdsman-converters/blob/4275931105788ec04b5b671640a2c86efa97f131/src/devices/sonoff.ts#L278 function is how timed / cyclic irrigation is managed by Z2M, using '0x5008' attribute

@fcrozat I think your are referring to something else. This branch is about sending an on_with_timed_off command (0x42) with a parameter that tells the valve to close after a certain amount of time. The review questions were how to send the command and where to store this interval.

I would love to see the cyclic irrigation options implemented in ZHA as well. But that seems to be out of scope for this branch.

@fcrozat
Copy link

fcrozat commented Jul 17, 2025

Sorry, I wasn't clear enough. I wanted to expand a bit @TheJulianJES answer:

the way timed irrigation is handled on Z2M is simply through a 1 cycle of cycled irrigation (if I read the code right) and not (mis)-using "on_time" (0x5011).

@micz
Copy link
Author

micz commented Jul 17, 2025

This is my first attempt at creating a quirk, so I'm really open to help and suggestions. ☺️
What I needed was a failsafe mechanism to close the valve even if a network error occurs when the close command is sent.

Looking at z2m code, if I get it right, I saw that it's possible to send the OnOff:on_with_timed_off that will close the valve after on_time seconds.

I wanted to send this command using the already available switch if the on_time is > 0 and not using an automation to send a cluster command (that I didn't know it was possible before reading the comment here).

I checked the cyclic code in z2m, but it was too difficult to translate and test in a real case scenario.

If using the on_time in this way is incorrect, how is it possible to achieve the failsafe implementation I described?

Thank you for your support.

@micz
Copy link
Author

micz commented Jul 30, 2025

@puddly @TheJulianJES Do I have to fix the requested changes, or is it necessary to verify if this is the right approach as stated here?

@puddly
Copy link
Contributor

puddly commented Jul 30, 2025

I just realized that ZHA doesn't actually implement the HA Valve platform! I think, since this is a standard ZCL command and theoretically is supported by many other valves in a standard way, we could just globally implement this for all valves, since this functionality likely isn't useful for other device types.

@TheJulianJES thoughts?

@MattWestb
Copy link
Contributor

Have Matter implanting valve control in its cluster library ?
If yes implanting it as they have done as its a part pf the upcoming ZCL 9 then its being released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs reviewer answer An answer from a reviewer is needed (e.g. why a PR isn't acceptable in the current state).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants