8000 [nrf52, zigbee] zigbee binary_sensor, switch and time by tomaszduda23 · Pull Request #7340 · esphome/esphome · GitHub
[go: up one dir, main page]

Skip to content

[nrf52, zigbee] zigbee binary_sensor, switch and time #7340

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 32 commits into
base: dev
Choose a base branch
from

Conversation

tomaszduda23
Copy link
Contributor
@tomaszduda23 tomaszduda23 commented Aug 22, 2024

What does this implement/fix?

Note: for adafruit bootloader check:

bootloader: adafruit_nrf52_sd140_v6 # for nice nano

This requires #7049. It adds zigbee switch and binary_sensor. Tested with zigbee2mqtt 1.40.0. Up to 8 components is supported due to endpoint limit on nrf52840. Endpoints could be reused but it requires extra implementation. Entities names are auto discovered by home assistant.

zigbee_demo.mp4

Related items:

Specification:
https://csa-iot.org/wp-content/uploads/2022/01/07-5123-08-Zigbee-Cluster-Library-1.pdf

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Other

Related issue or feature (if applicable): fixes
esphome/feature-requests#1397

Pull request in esphome-docs with documentation (if applicable): esphome/esphome-docs#

Test Environment

  • ESP32
  • ESP32 IDF
  • ESP8266
  • RP2040
  • BK72xx
  • RTL87xx
  • nrf52840

Example entry for config.yaml:

Alternative config: #7340 (comment)

---
# based on adafruit bootloader
external_components:
  - source: github://pr#7049
    components: [ logger, nrf52, time, zephyr ]
    refresh: always
  - source: github://pr#7340
    components: [ zigbee_ctx, zigbee ]
    refresh: always

nrf52:
  board: adafruit_itsybitsy_nrf52840
  bootloader: adafruit_nrf52_sd140_v6 # for nice nano

esphome:
  name: nrf52-test-nrf

logger:
  level: DEBUG

switch:
  - platform: zigbee
    output: output_template
    id: zigbee_switch_1
  - platform: zigbee
    output: output_template
    id: zigbee_switch_2

output:
  - platform: template
    id: output_template
    type: binary
    write_action:
      - binary_sensor.zigbee.publish:
          id: zigbee_binary_sensor_1
          state: ON
      - binary_sensor.zigbee.publish:
          id: zigbee_binary_sensor_1
          state: OFF
  - platform: template
    id: output_factory
    type: binary
    write_action:
      - zigbee.factory_reset

binary_sensor:
  - platform: zigbee
    id: zigbee_binary_sensor_1
  - platform: zigbee
    id: zigbee_binary_sensor_2
    lambda: return true;

zigbee:
  on_join:
    - switch.zigbee.publish:
        id: zigbee_switch_1
        state: OFF
    - switch.zigbee.publish:
        id: zigbee_switch_1
        state: ON

time:
  - platform: zigbee
    id: test_time
---
# based on mcuboot bootloader
external_components:
  - source: github://pr#7049
    components: [ logger, nrf52, time, zephyr ]
    refresh: always
  - source: github://pr#7340
    components: [ zigbee_ctx, zigbee ]
    refresh: always

nrf52:
  board: adafruit_feather_nrf52840

esphome:
  name: nrf52-test-nrf

logger:
  level: DEBUG

switch:
  - platform: zigbee
    output: output_template
    id: zigbee_switch_1
  - platform: zigbee
    output: output_template
    id: zigbee_switch_2

output:
  - platform: template
    id: output_template
    type: binary
    write_action:
      - binary_sensor.zigbee.publish:
          id: zigbee_binary_sensor_1
          state: ON
      - binary_sensor.zigbee.publish:
          id: zigbee_binary_sensor_1
          state: OFF
  - platform: template
    id: output_factory
    type: binary
    write_action:
      - zigbee.factory_reset

binary_sensor:
  - platform: zigbee
    id: zigbee_binary_sensor_1
  - platform: zigbee
    id: zigbee_binary_sensor_2
    lambda: return true;

zigbee:
  on_join:
    - switch.zigbee.publish:
        id: zigbee_switch_1
        state: OFF
    - switch.zigbee.publish:
        id: zigbee_switch_1
        state: ON

time:
  - platform: zigbee
    id: test_time

Checklist:

  • The code change is tested and works locally.
  • Tests have been added to verify that the new code works (under tests/ folder).

If user exposed functionality or configuration variables are added/changed:

@probot-esphome
Copy link

Hey there @tomaszduda23,
Thanks for submitting this pull request! Can you add yourself as a codeowner for this integration? This way we can notify you if a bug report for this integration is reported.
In __init__.py of the integration, please add:

CODEOWNERS = ["@tomaszduda23"]

And run script/build_codeowners.py

(message by NeedsCodeownersLabel)

@codecov-commenter
Copy link
codecov-commenter commented Aug 22, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 59.94%. Comparing base (5b3d61b) to head (c96d576).
Report is 69 commits behind head on dev.

Additional details and impacted files
@@           Coverage Diff           @@
##              dev    #7340   +/-   ##
=======================================
  Coverage   59.94%   59.94%           
=======================================
  Files          50       50           
  Lines       10293    10294    +1     
  Branches     1381     1381           
=======================================
+ Hits         6170     6171    +1     
  Misses       3762     3762           
  Partials      361      361           

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

@tomaszduda23 tomaszduda23 mentioned this pull request Aug 22, 2024
56 tasks
@randybb
Copy link
randybb commented Aug 22, 2024

Nice! And what about ZHA? Will it work by default?

@tomaszduda23
Copy link
Contributor Author

It implements binaryinput/binaryoutput from https://csa-iot.org/wp-content/uploads/2022/01/07-5123-08-Zigbee-Cluster-Library-1.pdf. It might work. I've not tested it with ZHA.
I was surprised that it doesn't work with zigbee2mqtt by default since it uses standard clusters (unless I'm missing something).

@tomaszduda23
Copy link
Contributor Author

@randybb
Copy link
randybb commented Aug 22, 2024

I have ZHA and many Xiaomi/Aqara zigbee sensors. Have bunch of unused nrf5240 modules, just have no clue how to setup this whole nrf52 thing. Probably I have to wait until it is fully merged...

@Hedda
Copy link
Hedda commented Aug 27, 2024

@tomaszduda23 are you following this related "zigbee_esphome" (Zigbee component) project by @luar123 for ESPHome here?

@Hedda
Copy link
Hedda commented Aug 27, 2024

Oh, and i addition to that, FYI, be aware Espressif developer P-R-O-C-H-Y is now working on a new Zigbee Wrapper library with a simpler API in Arduino (for arduino-esp32) and he wrote that other developers can post additional feature request related to that in the same issue there for tracking. Maybe you could make use of the same Zigbee API?

@tomaszduda23
Copy link
Contributor Author

https://github.com/luar123/zigbee_esphome/

I've seen that. You can do more with it. It seems to be lower level implementation since it requires defining clusters in yaml. My goal was to make it easy to use. Most users don't want to understand what is the difference between cluster, attribute etc.

Maybe you could make use of the same Zigbee API?

Looking on provided examples Espressif API looks different from Nordic. From user point of view it could be the same. c++ implementation would have to be done twice.

@Hedda
Copy link
Hedda commented Aug 27, 2024

It implements binaryinput/binaryoutput from https://csa-iot.org/wp-content/uploads/2022/01/07-5123-08-Zigbee-Cluster-Library-1.pdf. It might work. I've not tested it with ZHA.

FYI, while ZHA does expose much by default I believe that the ZHA integration does not expose all that zigpy supports, especially not for binary sensors, but instead generally only exposes the bare essentials for each supported platform in order to try to not overwhelmn the end user, however if something is not exposed then you can expand the sensors that it exposes by default in the main zha library which contain their Zigbee Gateway implementation, check out:

and

If most of it is exposed there then it is possible to finetune device quirks by writting a custom ZHA Device Handler using the unique device signature to identify specific devices:

https://github.com/zigpy/zha-device-handlers

PS: I think Zigbee2MQTT works very differently in that it instead does not expose anything by default so you more less always need to write a custom sevice handler which they call converters (see zigbee-herdsman-converters):

https://www.zigbee2mqtt.io/advanced/support-new-devices/01_support_new_devices.html

@tomaszduda23
Copy link
Contributor Author

I've not look into ZHA integration much. I don't have HW to setup another coordinator to test how it works. I could flash nrf52840 with coordinator firmware. The setup looks time consuming though. I hope it gets merged at some point zigpy/zigpy#394.

PS: I think Zigbee2MQTT works very differently in that it instead does not expose anything by default so you more less always need to write a custom sevice handler which they call converters (see zigbee-herdsman-converters):

There is auto generation which works e.g. with genOnOff. I might add auto discovery for other types Koenkk/zigbee2mqtt#23708.
In general genOnOff has better support. The thing which I don't like is missing description which could be used to display name of sensor in HA.

@Hedda
Copy link
Hedda commented Aug 28, 2024

I don't have HW to setup another coordinator to test how it works. I could flash nrf52840 with coordinator firmware. The setup looks time consuming though. I hope it gets merged at some point zigpy/zigpy#394.

FYI, the zigpy-zboss (ZBOSS radio library for zigpy) project which enable using ZBOSS NCP firmware as Zigbee Coordinator in zha is actually quite far along now so the setup should not be as time consuming description in the old issue you linked to, instead check out this repo:

The latest release should be fully usable:

Though because zigpy-zboss is still experimental and not yet included by default in ZHA you do however need to add it to the zha library (ZHA’s Zigbee Gateway implementation) and then manually make Home Assistant core use that patched version instead:

PS: I have keep up with that zigpy-zboss project myself and have ongoing progress summeries if interested in the longer back-story of that project here, which also contains user discussion on how to setup:

@tomaszduda23
Copy link
Contributor Author

It would be great to install experimental version by HACS. Patching core is not for average user 😄 I might take a look later on.

@tomaszduda23
Copy link
Contributor Author

If Koenkk/zigbee-herdsman-converters#7913 gets merge it would be discover without external converters.

@Hedda
Copy link
Hedda commented Aug 28, 2024

It would be great to install experimental version by HACS. Patching core is not for average user 😄 I might take a look later on.

I agree and that and other related ideas was requested and discussed in these:

@luar123
Copy link
Contributor
luar123 commented Aug 28, 2024

https://github.com/luar123/zigbee_esphome/

I've seen that. You can do more with it. It seems to be lower level implementation since it requires defining clusters in yaml. My goal was to make it easy to use. Most users don't want to understand what is the difference between cluster, attribute etc.

For me the ideal zigbee implementation would be like api or mqtt. Just define sensors/lights/etc and the translation to zigbee clusters is handled automatically. That is of course a lot of work to implement and I am lacking time and esphome knowledge to do that. So my approach is more flexible but not user friendly, whereas you are targeting a few use-cases that are easy to use. I hope that my approach will lead to a full mqtt-like implementation at some point.

Looking on provided examples Espressif API looks different from Nordic. From user point of view it could be the same. c++ implementation would have to be done twice.

Although low level apis are similar because both use zboss, details are different, so I don't think a common low level code base is easy to do. But what we should consider is that there will be multiple hardware implementations for zigbee. For example we both use zigbee as a component name.

@Hedda
Copy link
Hedda commented Aug 29, 2024

For me the ideal zigbee implementation would be like api or mqtt. Just define sensors/lights/etc and the translation to zigbee clusters is handled automatically.

That sounds like what @ffenix113 is trying to achieve with his ESPHome inspired non-esphome project (which is also for nRF52):

@tomaszduda23
Copy link
Contributor Author

For me the ideal zigbee implementation would be like api or mqtt. Just define sensors/lights/etc and the translation to zigbee clusters is handled automatically.

That was my idea too at the beginning. How would you like to do so? I can see two possibilities:

  1. use ZCL which is standardized but not fully supported by z2m. Probably similar thing in zha. There are also limitation e.g. genOnOff do not support description which could be used to set name.
  2. implement completely custom clusters just for esphome and add implementation to z2m and zha.
  3. Are there others possibilities?

Although low level apis are similar because both use zboss, details are different, so I don't think a common low level code base is easy to do. But what we should consider is that there will be multiple hardware implementations for zigbee. For example we both use zigbee as a component name.

Mine could be done on top of yours as long as you allow to define ZCL clusters. I was thinking about generating everything in python similar to yours but it was just easier to use things which are already defined in nrf-sdk.

@luar123
Copy link
Contributor
luar123 commented Aug 29, 2024

That was my idea too at the beginning. How would you like to do so? I can see two possibilities:
1. use ZCL which is standardized but not fully supported by z2m. Probably similar thing in zha. There are also limitation e.g. genOnOff do not support description which could be used to set name.
2. implement completely custom clusters just for esphome and add implementation to z2m and zha.
3. Are there others possibilities?

I would stick to standard ZCL clusters wherever possible and add custom clusters for not supported functions. With this also binding to other devices would work. I think it is even possible to add custom attributes to default clusters, but then you still need a converter for z2m. For z2m converters could be added upstream or esphome could generate custom files for each device.

Mine could be done on top of yours as long as you allow to define ZCL clusters. I was thinking about generating everything in python similar to yours but it was just easier to use things which are already defined in nrf-sdk.

At the moment my implementation depends on esp, I don't think there is much to share. Basically an intermediate abstraction layer would be needed. (But don't expect much development from my side, I am not working at this at the moment, just sharing ideas)

@Hedda
Copy link
Hedda commented Aug 29, 2024

That was my idea too at the beginning. How would you like to do so? I can see two possibilities:

  1. use ZCL which is standardized but not fully supported by z2m. Probably similar thing in zha. There are also limitation e.g. genOnOff do not support description which could be used to set name.
  2. implement completely custom clusters just for esphome and add implementation to z2m and zha.
  3. Are there others possibilities?

I would stick to standard ZCL clusters wherever possible and add custom clusters for not supported functions. With this also binding to other devices would work. I think it is even possible to add custom attributes to default clusters, but then you still need a converter for z2m. For z2m converters could be added upstream or esphome could generate custom files for each device.

What sounds like a good compromise would be to use standard ZCL clusters as much as possible and create a set of custom clusters for not supported functions that is standardized for ESPHome so can reuse the same converter in Zigbee2MQTT and same for ZHA Device Handler (zha-quirk) for translation without having to new converter or device handler for each new device created. Also note that ZHA recently added support for ZHA Device Handlers version 2 (ZHA-Quirks V2) architectural design which enable writing dynamic device handlers for ZHA:

@Hedda
Copy link
Hedda commented Sep 2, 2024

FYI; ZHA developers are working on AnalogInput and MultistateInput clusters for their "zha" Zigbee Gateway implementation:

@prairiesnpr do you happen to know if zha will dynamically support both BinaryInput and BinaryOutput clusters this way?

Copy link
Contributor

To use the changes from this PR as an external component, add the following to your ESPHome configuration YAML file:

external_components:
  - source: github://pr#7340
    components: [zigbee, zigbee_ctx]
    refresh: 1h

(Added by the PR bot)

@esphome esphome bot added the new-platform label Jul 17, 2025
Copy link
Contributor

To use the changes from this PR as an external component, add the following to your ESPHome configuration YAML file:

external_components:
  - source: github://pr#7340
    components: [zigbee, zigbee_ctx]
    refresh: 1h

(Added by the PR bot)

@tomaszduda23 tomaszduda23 requested a review from a team as a code owner July 17, 2025 20:07
Copy link
Contributor

To use the changes in this PR:

# Clone the repository:
git clone https://github.com/esphome/esphome
cd esphome

# Checkout the PR branch:
git fetch origin pull/7340/head:nrf52_zigbee
git checkout nrf52_zigbee

# Install the development version:
script/setup

# Activate the development version:
source venv/bin/activate

Now you can run esphome as usual to test the changes in this PR.


(Added by the PR bot)

Copy link
Contributor

To use the changes in this PR:

# Clone the repository:
git clone https://github.com/esphome/esphome
cd esphome

# Checkout the PR branch:
git fetch origin pull/7340/head:nrf52_zigbee
git checkout nrf52_zigbee

# Install the development version:
script/setup

# Activate the development version:
source venv/bin/activate

Now you can run esphome as usual to test the changes in this PR.


(Added by the PR bot)

Copy link
Contributor

To use the changes in this PR:

# Clone the repository:
git clone https://github.com/esphome/esphome
cd esphome

# Checkout the PR branch:
git fetch origin pull/7340/head:nrf52_zigbee
git checkout nrf52_zigbee

# Install the development version:
script/setup

# Activate the development version:
source venv/bin/activate

Now you can run esphome as usual to test the changes in this PR.


(Added by the PR bot)

Copy link
Contributor

To use the changes in this PR:

# Clone the repository:
git clone https://github.com/esphome/esphome
cd esphome

# Checkout the PR branch:
git fetch origin pull/7340/head:nrf52_zigbee
git checkout nrf52_zigbee

# Install the development version:
script/setup

# Activate the development version:
source venv/bin/activate

Now you can run esphome as usual to test the changes in this PR.


(Added by the PR bot)

Copy link
Contributor

To use the changes in this PR:

# Clone the repository:
git clone https://github.com/esphome/esphome
cd esphome

# Checkout the PR branch:
git fetch origin pull/7340/head:nrf52_zigbee
git checkout nrf52_zigbee

# Install the development version:
script/setup

# Activate the development version:
source venv/bin/activate

Now you can run esphome as usual to test the changes in this PR.


(Added by the PR bot)

@Hedda
Copy link
Hedda commented Jul 22, 2025

@jesserockz the related PR #6075 was closed and locked by you without any comments, was that a mistake or on purpose?

@tomaszduda23
Copy link
Contributor Author

@jesserockz the related PR #6075 was closed and locked by you without any comments, was that a mistake or on purpose?

I've already opened new PR for tracking. The old one may stay closed #9736

@Hedda
Copy link
Hedda commented Jul 22, 2025

@jesserockz the related PR #6075 was closed and locked by you without any comments, was that a mistake or on purpose?

I've already opened new PR for tracking. The old one may stay closed #9736

@tomaszduda23 nice! Suggest you update the old PR with a link to the new PR for reference.

@tomaszduda23
Copy link
Contributor Author

@jesserockz the related PR #6075 was closed and locked by you without any comments, was that a mistake or on purpose?

I've already opened new PR for tracking. The old one may stay closed #9736

@tomaszduda23 nice! Suggest you update the old PR with a link to the new PR for reference.

It is closed. I cannot edit anymore.

@jesserockz
Copy link
Member

I closed it because we don't use prs to track other pr progress. Use a feature request discussion for that please.

Everytime you update such a pr, it takes up the CI runners

@Hedda
Copy link
Hedda commented Jul 24, 2025

@tomaszduda23 could nrf52/nrf52840 with this component be able to do ESPHome firmware image update via Zigbee OTA update (Zigbee OTAU provider) via Home Assistant’s ZHA integration if that is used as the Zigbee Gateway?

@tomaszduda23
Copy link
Contributor Author
tomaszduda23 commented Jul 24, 2025

@tomaszduda23 could nrf52/nrf52840 with this component be able to do ESPHome firmware image update via Zigbee OTA update (Zigbee OTAU provider) via Home Assistant’s ZHA integration if that is used as the Zigbee Gateway?

It looks interesting.
zephyr do support OTA over zigbee. I'm not going to implement it though.
BLE OTA #9859 is good enough for most cases. BLE can coexist with zigbee.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants
0