Skip to content

Add BinaryOutputCluster switch support - #467

Merged
puddly merged 11 commits into
zigpy:devfrom
oddlama:add-binary-output-cluster-switch
Jun 25, 2025
Merged

Add BinaryOutputCluster switch support#467
puddly merged 11 commits into
zigpy:devfrom
oddlama:add-binary-output-cluster-switch

Conversation

@oddlama

@oddlama oddlama commented Jun 17, 2025

Copy link
Copy Markdown
Contributor

This PR adds support for BinaryOutputCluster as a switch. Currently, binary output clusters are correctly set up but not exposed into home assistant at all. Created switches look like this:

image

@oddlama
oddlama force-pushed the add-binary-output-cluster-switch branch from c3f2e6c to e76d70b Compare June 17, 2025 20:08
@puddly

puddly commented Jun 17, 2025

Copy link
Copy Markdown
Contributor

Thanks for making a PR for this feature!

For something that'll be used by DIY devices, I think it would be best to gate this behind the presence of a description attribute like we do for the BinaryInput cluster, like so:

    def _is_supported(self) -> bool:
        if self._cluster_handler.description is None:
            return False

        return super()._is_supported()

This should get all of the failing entity unit tests passing as well.

@oddlama
oddlama force-pushed the add-binary-output-cluster-switch branch from 1fe0aed to ed91294 Compare June 18, 2025 18:48
@oddlama

oddlama commented Jun 18, 2025

Copy link
Copy Markdown
Contributor Author

Thanks for making a PR for this feature!

For something that'll be used by DIY devices, I think it would be best to gate this behind the presence of a description attribute like we do for the BinaryInput cluster, like so:

Good point! I've added your suggested code.

@TheJulianJES TheJulianJES changed the title Adds support for BinaryOutputCluster as a switch Add BinaryOutputCluster switch support Jun 24, 2025
Comment thread zha/application/platforms/switch.py Outdated
@codecov

codecov Bot commented Jun 25, 2025

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.90%. Comparing base (a2de928) to head (cd19266).
Report is 8 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #467      +/-   ##
==========================================
+ Coverage   96.88%   96.90%   +0.02%     
==========================================
  Files          63       63              
  Lines       10361    10409      +48     
==========================================
+ Hits        10038    10087      +49     
+ Misses        323      322       -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.

Comment thread zha/application/platforms/switch.py Outdated

@TheJulianJES TheJulianJES left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

~~Also noticed that the async_update implementation (for polling with homeassistant.update_entity service call) seems to be missing. Already the case for the OnOff variant. Only the ConfigurableAttributeSwitch has it (for config entities).

Just a reminder to add this when we also add it for OnOff. It's not that crucial, but we should still implement it in the future.~~

EDIT: Never mind, it's enough to implement async_update in the cluster handler and we magically call it from PlatformEntity if implemented:

async def async_update(self) -> None:
"""Retrieve latest state."""
self.debug("polling current state")
tasks = [
cluster_handler.async_update()
for cluster_handler in self.cluster_handlers.values()
if hasattr(cluster_handler, "async_update")
]

Comment on lines +185 to +187
if self._binary_output_cluster_handler.present_value is None:
return False
return bool(self._binary_output_cluster_handler.present_value)

@TheJulianJES TheJulianJES Jun 25, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Now that we use bool(.present_value), we should be able to remove the present_value is None check, since that will return False. That also fixes the coverage issue 😄

@puddly puddly Jun 25, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

True. I was keeping it around for future review because I'm not sure if I agree with this behavior in general, it seems like unavailable would be a better state?

@TheJulianJES TheJulianJES Jun 25, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I also thought about that. It makes sense for sensors and so on (and I think we unfortunately have this same behavior for binary sensors), but I'm not sure how this behaves with switches. Can you still turn on/off a switch if it's unavailable in HA?

Like, if it's an issue that present_value or on_off or whatever just wasn't read properly during pairing OR if there's some buggy device that just [makes zigpy] return None until the value was written once, do we really want to block doing that? (Assuming unavailable switch in HA means we can't turn on or off).

@TheJulianJES TheJulianJES left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since async_update is apparently already supported, since we magically call that method in the cluster handler from the base PlatformEntity here, mind also copying the async_update part from one of the OnOff switch tests to get coverage for that in the cluster handler (if you're not already working on that 😄)?

Otherwise, this looks good now.

@TheJulianJES TheJulianJES left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice!

@puddly
puddly merged commit 1ed3b8d into zigpy:dev Jun 25, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants