-
Notifications
You must be signed in to change notification settings - Fork 7.6k
/
Copy pathZigbeeDimmableLight.cpp
108 lines (92 loc) · 4.96 KB
/
ZigbeeDimmableLight.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "ZigbeeDimmableLight.h"
#if CONFIG_ZB_ENABLED
#include "esp_zigbee_cluster.h"
ZigbeeDimmableLight::ZigbeeDimmableLight(uint8_t endpoint) : ZigbeeEP(endpoint) {
_device_id = ESP_ZB_HA_DIMMABLE_LIGHT_DEVICE_ID;
zigbee_dimmable_light_cfg_t light_cfg = ZIGBEE_DEFAULT_DIMMABLE_LIGHT_CONFIG();
_cluster_list = zigbee_dimmable_light_clusters_create(&light_cfg);
_ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_DIMMABLE_LIGHT_DEVICE_ID, .app_device_version = 0};
// set default values
_current_state = false;
_current_level = 255;
}
// set attribute method -> method overridden in child class
void ZigbeeDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) {
// check the data and call right method
if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) {
if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) {
if (_current_state != *(bool *)message->attribute.data.value) {
_current_state = *(bool *)message->attribute.data.value;
lightChanged();
}
return;
} else {
log_w("Received message ignored. Attribute ID: %d not supported for On/Off Light", message->attribute.id);
}
} else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL) {
if (message->attribute.id == ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) {
if (_current_level != *(uint8_t *)message->attribute.data.value) {
_current_level = *(uint8_t *)message->attribute.data.value;
lightChanged();
}
return;
} else {
log_w("Received message ignored. Attribute ID: %d not supported for Level Control", message->attribute.id);
// TODO: implement more attributes -> includes/zcl/esp_zigbee_zcl_level.h
}
} else {
log_w("Received message ignored. Cluster ID: %d not supported for dimmable Light", message->info.cluster);
}
}
void ZigbeeDimmableLight::lightChanged() {
if (_on_light_change) {
_on_light_change(_current_state, _current_level);
}
}
bool ZigbeeDimmableLight::setLight(bool state, uint8_t level) {
// Update all attributes
_current_state = state;
_current_level = level;
lightChanged();
log_v("Updating on/off light state to %d", state);
/* Update light clusters */
esp_zb_lock_acquire(portMAX_DELAY);
// set on/off state
esp_zb_zcl_status_t ret_state = esp_zb_zcl_set_attribute_val(
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID, &_current_state, false
);
// set level
esp_zb_zcl_status_t ret_level = esp_zb_zcl_set_attribute_val(
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID, &_current_level, false
);
esp_zb_lock_release();
if (ret_state != ESP_ZB_ZCL_STATUS_SUCCESS || ret_level != ESP_ZB_ZCL_STATUS_SUCCESS) {
log_e("Failed to set light state(0x%x) or level(0x%x)", ret_state, ret_level);
return false;
}
return true;
}
bool ZigbeeDimmableLight::setLightState(bool state) {
return setLight(state, _current_level);
}
bool ZigbeeDimmableLight::setLightLevel(uint8_t level) {
return setLight(_current_state, level);
}
esp_zb_cluster_list_t *ZigbeeDimmableLight::zigbee_dimmable_light_clusters_create(zigbee_dimmable_light_cfg_t *light_cfg) {
esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_basic_cluster_create(&light_cfg->basic_cfg);
esp_zb_attribute_list_t *esp_zb_identify_cluster = esp_zb_identify_cluster_create(&light_cfg->identify_cfg);
esp_zb_attribute_list_t *esp_zb_groups_cluster = esp_zb_groups_cluster_create(&light_cfg->groups_cfg);
esp_zb_attribute_list_t *esp_zb_scenes_cluster = esp_zb_scenes_cluster_create(&light_cfg->scenes_cfg);
esp_zb_attribute_list_t *esp_zb_on_off_cluster = esp_zb_on_off_cluster_create(&light_cfg->on_off_cfg);
esp_zb_attribute_list_t *esp_zb_level_cluster = esp_zb_level_cluster_create(&light_cfg->level_cfg);
// ------------------------------ Create cluster list ------------------------------
esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_identify_cluster(esp_zb_cluster_list, esp_zb_identify_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_groups_cluster(esp_zb_cluster_list, esp_zb_groups_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_scenes_cluster(esp_zb_cluster_list, esp_zb_scenes_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_on_off_cluster(esp_zb_cluster_list, esp_zb_on_off_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_level_cluster(esp_zb_cluster_list, esp_zb_level_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
return esp_zb_cluster_list;
}
#endif // SOC_IEEE802154_SUPPORTED