ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
zigbee_esp32.h
Go to the documentation of this file.
1#pragma once
2
4#ifdef USE_ESP32
5#ifdef USE_ZIGBEE
6
7#include <map>
8#include <tuple>
9#include <atomic>
10
11#include "esp_zigbee.h"
12#include "ezbee/zha.h"
16
17#ifdef USE_BINARY_SENSOR
19#endif
20
21namespace esphome::zigbee {
22
23/* Zigbee configuration */
24static const uint16_t ED_KEEP_ALIVE = 3000; /* 3000 millisecond */
25static const uint8_t MAX_CHILDREN = 10;
26static const uint32_t EZB_PRIMARY_CHANNEL_MASK = 0x07FFF800U; /* channels 11-26 */
27
28#define EZB_DEFAULT_RADIO_CONFIG() \
29 { .radio_mode = ESP_ZIGBEE_RADIO_MODE_NATIVE, }
30
31uint8_t *get_zcl_string(const char *str, uint8_t max_size, bool use_max_size = false);
32
33class ZigbeeAttribute;
34
35class ZigbeeComponent final : public Component {
36 public:
38 void setup() override;
39 void loop() override;
40 void dump_config() override;
41
42 void set_basic_cluster(const char *model, const char *manufacturer, uint8_t power_source);
43 void add_cluster(uint8_t endpoint_id, uint16_t cluster_id, uint8_t role);
44 void create_default_cluster(uint8_t endpoint_id, uint16_t device_id);
45 bool register_device();
46
47 template<typename T>
48 void add_attr(ZigbeeAttribute *attr, uint8_t endpoint_id, uint16_t cluster_id, uint8_t role, uint16_t attr_id,
49 uint8_t max_size, T value);
50
51 template<typename T>
52 void add_attr(uint8_t endpoint_id, uint16_t cluster_id, uint8_t role, uint16_t attr_id, uint8_t max_size, T value);
53
54 static bool app_signal_handler(const ezb_app_signal_t *app_signal);
55 static void esp_zigbee_alarm_bdb_commissioning(ezb_bdb_comm_mode_mask_t mode);
56
58 esp_zigbee_lock_acquire(portMAX_DELAY);
59 esp_zigbee_factory_reset(); // triggers a reboot
60 esp_zigbee_lock_release();
61 }
62
63 template<typename F> void add_on_join_callback(F &&cb) { this->join_cb_.add(std::forward<F>(cb)); }
64
65 bool is_battery_powered() { return this->basic_cluster_data_.power_source == EZB_ZCL_BASIC_POWER_SOURCE_BATTERY; }
66 bool is_started() { return this->started; }
67 bool is_connected() { return this->connected_; }
68 std::atomic<bool> started = false;
69 std::atomic<bool> joined = false;
70 std::atomic<bool> factory_new = false;
71
72 protected:
73 struct {
74 uint8_t *model;
75 uint8_t *manufacturer;
76 uint8_t *date;
77 uint8_t power_source;
79 bool connected_ = false;
80#ifdef CONFIG_ZB_ZED
81 ezb_nwk_device_type_t device_role_ = EZB_NWK_DEVICE_TYPE_END_DEVICE;
82#else
83 ezb_nwk_device_type_t device_role_ = EZB_NWK_DEVICE_TYPE_ROUTER;
84#endif
85 void update_basic_cluster_(ezb_af_ep_desc_t ep_desc);
86 template<typename T>
87 void add_attr_(ZigbeeAttribute *attr, uint8_t endpoint_id, uint16_t cluster_id, uint8_t role, uint16_t attr_id,
88 T *value_p);
89 // attributes_ will be used during operation in zigbee callbacks to update the attribute values and trigger
90 // automations
91 // key tuple could be replaced by single 64 (48) bit int with bit fields for endpoint, cluster, role and attr_id
92 std::map<std::tuple<uint8_t, uint16_t, uint8_t, uint16_t>, ZigbeeAttribute *> attributes_;
93 ezb_af_device_desc_t dev_desc_;
95};
96
97template<typename T>
98void ZigbeeComponent::add_attr(uint8_t endpoint_id, uint16_t cluster_id, uint8_t role, uint16_t attr_id,
99 uint8_t max_size, T value) {
100 this->add_attr<T>(nullptr, endpoint_id, cluster_id, role, attr_id, max_size, value);
101}
102
103template<typename T>
104void ZigbeeComponent::add_attr(ZigbeeAttribute *attr, uint8_t endpoint_id, uint16_t cluster_id, uint8_t role,
105 uint16_t attr_id, uint8_t max_size, T value) {
106 // The size byte of the zcl_str must be set to the maximum value,
107 // even though the initial string may be shorter.
108 if constexpr (std::is_same<T, std::string>::value) {
109 auto zcl_str = get_zcl_string(value.c_str(), max_size, true);
110 add_attr_(attr, endpoint_id, cluster_id, role, attr_id, zcl_str);
111 delete[] zcl_str;
112 } else if constexpr (std::is_convertible<T, const char *>::value) {
113 auto zcl_str = get_zcl_string(value, max_size, true);
114 add_attr_(attr, endpoint_id, cluster_id, role, attr_id, zcl_str);
115 delete[] zcl_str;
116 } else {
117 add_attr_(attr, endpoint_id, cluster_id, role, attr_id, &value);
118 }
119}
120
121template<typename T>
122void ZigbeeComponent::add_attr_(ZigbeeAttribute *attr, uint8_t endpoint_id, uint16_t cluster_id, uint8_t role,
123 uint16_t attr_id, T *value_p) {
124 ezb_af_ep_desc_t ep_desc = ezb_af_device_get_endpoint_desc(this->dev_desc_, endpoint_id);
125 if (ep_desc == NULL) {
126 return;
127 }
128 ezb_zcl_cluster_desc_t cluster_desc = ezb_af_endpoint_get_cluster_desc(ep_desc, cluster_id, role);
129 if (cluster_desc == NULL) {
130 return;
131 }
132 esphome_zb_cluster_add_or_update_attr(cluster_id, cluster_desc, attr_id, value_p);
133
134 if (attr != nullptr) {
135 this->attributes_[{endpoint_id, cluster_id, role, attr_id}] = attr;
136 }
137}
138
139} // namespace esphome::zigbee
140
141#endif
142#endif
BedjetMode mode
BedJet operating mode.
CallbackManager< void(bool)> join_cb_
void create_default_cluster(uint8_t endpoint_id, uint16_t device_id)
struct esphome::zigbee::ZigbeeComponent::@200 basic_cluster_data_
std::map< std::tuple< uint8_t, uint16_t, uint8_t, uint16_t >, ZigbeeAttribute * > attributes_
void update_basic_cluster_(ezb_af_ep_desc_t ep_desc)
void add_cluster(uint8_t endpoint_id, uint16_t cluster_id, uint8_t role)
static void esp_zigbee_alarm_bdb_commissioning(ezb_bdb_comm_mode_mask_t mode)
static bool app_signal_handler(const ezb_app_signal_t *app_signal)
std::atomic< bool > factory_new
ezb_nwk_device_type_t device_role_
void set_basic_cluster(const char *model, const char *manufacturer, uint8_t power_source)
void add_attr(ZigbeeAttribute *attr, uint8_t endpoint_id, uint16_t cluster_id, uint8_t role, uint16_t attr_id, uint8_t max_size, T value)
ezb_af_device_desc_t dev_desc_
void add_attr_(ZigbeeAttribute *attr, uint8_t endpoint_id, uint16_t cluster_id, uint8_t role, uint16_t attr_id, T *value_p)
uint8_t * get_zcl_string(const char *str, uint8_t max_size, bool use_max_size)
static void uint32_t
ezb_err_t esphome_zb_cluster_add_or_update_attr(uint16_t cluster_id, ezb_zcl_cluster_desc_t cluster_desc, uint16_t attr_id, void *value_p)