Skip to content

feat(zigbee): Add setLight APIs to manually operate lights #10626

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

Merged
merged 2 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ ZigbeeColorDimmableLight zbColorLight = ZigbeeColorDimmableLight(ZIGBEE_LIGHT_EN

/********************* RGB LED functions **************************/
void setRGBLight(bool state, uint8_t red, uint8_t green, uint8_t blue, uint8_t level) {
if (!state) {
rgbLedWrite(LED_PIN, 0, 0, 0);
return;
}
float brightness = (float)level / 255;
rgbLedWrite(LED_PIN, red * brightness, green * brightness, blue * brightness);
}
Expand Down Expand Up @@ -98,6 +102,8 @@ void loop() {
Zigbee.factoryReset();
}
}
// Increase blightness by 50 every time the button is pressed
zbColorLight.setLightLevel(zbColorLight.getLightLevel() + 50);
Copy link
Collaborator

@SuGlider SuGlider Nov 19, 2024

Choose a reason for hiding this comment

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

How would it overflow? Maybe it is necessary to promote something to uint16_t in order to get the u8 from uint16_t & 0xFF final value?

Nervermind - overflow goes fine with 8 bits.

Copy link
Member Author

Choose a reason for hiding this comment

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

the setLightLevel parameter is uint8_t so max is 255. When it overflows, it's starting from 0 + the overflowed value.
Its like that on purpose to have it simple :)

}
delay(100);
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ void loop() {
Zigbee.factoryReset();
}
}
// Toggle light by pressing the button
zbLight.setLight(!zbLight.getLightState());
}
delay(100);
}
62 changes: 62 additions & 0 deletions libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ void ZigbeeColorDimmableLight::calculateRGB(uint16_t x, uint16_t y, uint8_t &red
blue = (uint8_t)(b * (float)255);
}

void ZigbeeColorDimmableLight::calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y) {
// Convert RGB to XYZ
float r = (float)red / 255.0f;
float g = (float)green / 255.0f;
float b = (float)blue / 255.0f;

float X, Y, Z;
RGB_TO_XYZ(r, g, b, X, Y, Z);

// Convert XYZ to xy chromaticity coordinates
float color_x = X / (X + Y + Z);
float color_y = Y / (X + Y + Z);

// Convert normalized xy to 16-bit values
x = (uint16_t)(color_x * 65535.0f);
y = (uint16_t)(color_y * 65535.0f);
}

//set attribute method -> method overridden in child class
void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) {
//check the data and call right method
Expand Down Expand Up @@ -109,4 +127,48 @@ void ZigbeeColorDimmableLight::lightChanged() {
}
}

void ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue) {
//Update all attributes
_current_state = state;
_current_level = level;
_current_red = red;
_current_green = green;
_current_blue = blue;
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_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_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
);
//set color
uint16_t color_x, color_y;
calculateXY(red, green, blue, color_x, color_y);
esp_zb_zcl_set_attribute_val(
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, &color_x, false
);
esp_zb_zcl_set_attribute_val(
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID, &color_y, false
);
esp_zb_lock_release();
}

void ZigbeeColorDimmableLight::setLightState(bool state) {
setLight(state, _current_level, _current_red, _current_green, _current_blue);
}

void ZigbeeColorDimmableLight::setLightLevel(uint8_t level) {
setLight(_current_state, level, _current_red, _current_green, _current_blue);
}

void ZigbeeColorDimmableLight::setLightColor(uint8_t red, uint8_t green, uint8_t blue) {
setLight(_current_state, _current_level, red, green, blue);
}

#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
22 changes: 22 additions & 0 deletions libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,31 @@ class ZigbeeColorDimmableLight : public ZigbeeEP {
lightChanged();
}

void setLightState(bool state);
void setLightLevel(uint8_t level);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue);
void setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue);

bool getLightState() {
return _current_state;
}
uint8_t getLightLevel() {
return _current_level;
}
uint8_t getLightRed() {
return _current_red;
}
uint8_t getLightGreen() {
return _current_green;
}
uint8_t getLightBlue() {
return _current_blue;
}

private:
void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override;
void calculateRGB(uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue);
void calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y);

uint16_t getCurrentColorX();
uint16_t getCurrentColorY();
Expand Down
13 changes: 13 additions & 0 deletions libraries/Zigbee/src/ep/ZigbeeLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,17 @@ void ZigbeeLight::lightChanged() {
}
}

void ZigbeeLight::setLight(bool state) {
_current_state = state;
lightChanged();

log_v("Updating on/off light state to %d", state);
/* Update on/off light state */
esp_zb_lock_acquire(portMAX_DELAY);
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
);
esp_zb_lock_release();
}

#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
9 changes: 8 additions & 1 deletion libraries/Zigbee/src/ep/ZigbeeLight.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ class ZigbeeLight : public ZigbeeEP {
ZigbeeLight(uint8_t endpoint);
~ZigbeeLight();

// Use tp set a cb function to be called on light change
// Use to set a cb function to be called on light change
void onLightChange(void (*callback)(bool)) {
_on_light_change = callback;
}
// Use to restore light state
void restoreLight() {
lightChanged();
}
// Use to control light state
void setLight(bool state);
// Use to get light state
bool getLightState() {
return _current_state;
}

private:
void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override;
Expand Down
Loading