Skip to content

Add Shelly Ecowitt WS90.#4708

Open
paveljandejsek wants to merge 1 commit intozigpy:devfrom
paveljandejsek:pj/add-shelly-ecowitt-ws90
Open

Add Shelly Ecowitt WS90.#4708
paveljandejsek wants to merge 1 commit intozigpy:devfrom
paveljandejsek:pj/add-shelly-ecowitt-ws90

Conversation

@paveljandejsek
Copy link

@paveljandejsek paveljandejsek commented Jan 31, 2026

Proposed change

Add support for Shelly Ecowitt WS90.

Additional information

Based on the quirk and discussion in #4558
The quirk code itself is 99% based on the work done by @DougMunford in that issue, I just added the cluster manufacturer id code, extracted couple things to constants and put this into PR. So huge kudos to Doug!!!

Device documentation: here

This is my first PR to this repo and my first ever commit to anything in Python so I apologize in advance if I messed something up 🙂
Any and all feedback is definitely welcome!

Device diagnostics

zha-79be2e9ad9b58ac907e43c7f06078f1a-Shelly Ecowitt WS90-6fda9ff7584dc159a0a84279398bdb7e.json

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
  • Device diagnostics data has been attached

Copilot AI review requested due to automatic review settings January 31, 2026 17:52
@codecov
Copy link

codecov bot commented Jan 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.34%. Comparing base (04c61bb) to head (a8b9be8).
⚠️ Report is 4 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #4708      +/-   ##
==========================================
+ Coverage   92.32%   92.34%   +0.01%     
==========================================
  Files         371      373       +2     
  Lines       12198    12228      +30     
==========================================
+ Hits        11262    11292      +30     
  Misses        936      936              

☔ 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.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for the Shelly Ecowitt WS90 weather station by implementing a V2 quirk with custom clusters for wind, UV index, and precipitation measurements. The implementation is based on community work from issue #4558 by @DougMunford and marks the first Shelly device added to this repository.

Changes:

  • Introduces Shelly manufacturer module with shared constants
  • Implements custom clusters for manufacturer-specific weather measurements (wind, UV, rain)
  • Creates Home Assistant entities for wind speed/direction, gust speed, UV index, precipitation, and rain detection
  • Adds basic tests verifying custom cluster attribute definitions

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.

File Description
zhaquirks/shelly/init.py Defines Shelly manufacturer constants following established patterns from other manufacturers
zhaquirks/shelly/ecowitt_ws90.py Implements V2 quirk with three custom clusters (0xFC01-0xFC03) exposing weather station sensors to Home Assistant
tests/test_shelly.py Provides basic test coverage verifying custom cluster attributes are properly defined

"""Wind cluster attribute definitions."""

wind_speed = foundation.ZCLAttributeDef(
id=0x0000, type=types.uint16_t, access="rp", is_manufacturer_specific=True
Copy link
Contributor

Choose a reason for hiding this comment

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

We're moving to using manufacturer_code=0xABCD (with the correct manufacturer code) for every definition. This replaces the manufacturer ID override and is_manufacturer_specific.

Can you confirm that they Shelly manufacturer code is the same as the cluster ID? That sounds strange.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah apologies, I just named it weirdly now that I am looking into it... SHELLY_MANUFACTURER_CODE would be a better name - the code is 0x1490 for all three of these clusters... I will change the naming (and also put a link to the Zigbee spec from Shelly for this devices to the description of the PR)

I will change it to manufacturer_code then, thanks for the info!

Copy link
Author

Choose a reason for hiding this comment

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

I changed it to the manufacturer_code and removed the is_manufacturer_specific and manufacturer_id_override.

I also added the link to the Shelly doc to the initial PR description in the "Additional information".

Copilot seems to be complaining about the change in the comment below: https://github.com/zigpy/zha-device-handlers/pull/4708#discussion_r2749886452#discussion_r2749886452 - can I safely ignore it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, the AI instructions haven't been updated for the above API change. You can ignore it.

@paveljandejsek paveljandejsek force-pushed the pj/add-shelly-ecowitt-ws90 branch from af7eb31 to fc1af45 Compare January 31, 2026 19:10
Copilot AI review requested due to automatic review settings January 31, 2026 19:10
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

@newash
Copy link

newash commented Feb 10, 2026

Hi,

I'm using your code as custom quirk in my HA installation but when I updated Core from 2026.1.3 -> 2026.2.1 the custom attributes stopped updating.

I asked ClaudeAI, and its suggestion fixed it for me, so I thought you'll be interested:

Your ZCLAttributeDef entries lack per-attribute manufacturer_code. The cluster-level manufacturer_code = SHELLY_MANUFACTURER_CODE was sufficient in zigpy ≤0.90.x — it was used as the default for all ZCL operations on that cluster.
zigpy 0.91.0 (shipped in ZHA 0.0.85, landed in HA 2026.2) refactored manufacturer code handling to be per-attribute/per-command on the ZCLAttributeDef itself. The cluster-level field alone no longer propagates into configure_reporting_multiple() ZCL frames or incoming Report_Attributes matching. This is confirmed by #4708 (comment):

  • zha-quirks 0.0.154: "Bump zigpy to 0.91.3 and adjust quirks", "Update read/write_attributes method signatures"
  • PR Add quirk for SONOFF SNZB-03PR2 motion sensor #4714 review comment: "We've moving from is_manufacturer_specific=True to explicit manufacturer codes per attribute/command"
  • zigpy 0.91.3: "Correctly handle manufacturer_code=None for attributes and commands" (your attributes have implicit None)

So configure_reporting fires without the manufacturer code in the ZCL frame header → device rejects/ignores it → no unsolicited reports are configured → entities stay stale. Manual "Read attributes" works because the ZHA UI reads go through a different code path that still picks up the cluster-level code.

The Fix
Add manufacturer_code=SHELLY_MANUFACTURER_CODE to every ZCLAttributeDef:

wind_speed = foundation.ZCLAttributeDef(
    id=0x0000, type=types.uint16_t, access="rp",
    manufacturer_code=SHELLY_MANUFACTURER_CODE,
)

@paveljandejsek paveljandejsek force-pushed the pj/add-shelly-ecowitt-ws90 branch from fc1af45 to fa7eee6 Compare February 10, 2026 20:55
Copilot AI review requested due to automatic review settings February 10, 2026 20:55
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@paveljandejsek
Copy link
Author

Hi,

I'm using your code as custom quirk in my HA installation but when I updated Core from 2026.1.3 -> 2026.2.1 the custom attributes stopped updating.

I asked ClaudeAI, and its suggestion fixed it for me, so I thought you'll be interested:

Your ZCLAttributeDef entries lack per-attribute manufacturer_code. The cluster-level manufacturer_code = SHELLY_MANUFACTURER_CODE was sufficient in zigpy ≤0.90.x — it was used as the default for all ZCL operations on that cluster.
zigpy 0.91.0 (shipped in ZHA 0.0.85, landed in HA 2026.2) refactored manufacturer code handling to be per-attribute/per-command on the ZCLAttributeDef itself. The cluster-level field alone no longer propagates into configure_reporting_multiple() ZCL frames or incoming Report_Attributes matching. This is confirmed by #4708 (comment):

  • zha-quirks 0.0.154: "Bump zigpy to 0.91.3 and adjust quirks", "Update read/write_attributes method signatures"
  • PR Add quirk for SONOFF SNZB-03PR2 motion sensor #4714 review comment: "We've moving from is_manufacturer_specific=True to explicit manufacturer codes per attribute/command"
  • zigpy 0.91.3: "Correctly handle manufacturer_code=None for attributes and commands" (your attributes have implicit None)

So configure_reporting fires without the manufacturer code in the ZCL frame header → device rejects/ignores it → no unsolicited reports are configured → entities stay stale. Manual "Read attributes" works because the ZHA UI reads go through a different code path that still picks up the cluster-level code.
The Fix
Add manufacturer_code=SHELLY_MANUFACTURER_CODE to every ZCLAttributeDef:

wind_speed = foundation.ZCLAttributeDef(
    id=0x0000, type=types.uint16_t, access="rp",
    manufacturer_code=SHELLY_MANUFACTURER_CODE,
)

You are absolutely right! I just checked my HA and those attributes were indeed missing after the upgrade to 2026.2...
I have amended the PR accordingly, thanks again, really appreciated 🙂

@paveljandejsek paveljandejsek force-pushed the pj/add-shelly-ecowitt-ws90 branch from 01b6031 to f7fcfc9 Compare February 11, 2026 17:01
Copilot AI review requested due to automatic review settings February 11, 2026 17:01
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@paveljandejsek paveljandejsek force-pushed the pj/add-shelly-ecowitt-ws90 branch from db4856c to a8b9be8 Compare February 12, 2026 18:30
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