Files
esp-matter/examples/light_network_prov/main/app_driver.cpp
T

218 lines
7.6 KiB
C++

/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_log.h>
#include <stdlib.h>
#include <string.h>
#include <esp_matter.h>
#include <esp_rmaker_utils.h>
#include "bsp/esp-bsp.h"
#include <app_priv.h>
using namespace chip::app::Clusters;
using namespace esp_matter;
static const char *TAG = "app_driver";
extern uint16_t light_endpoint_id;
/* Do any conversions/remapping for the actual value here */
esp_err_t app_driver_light_set_power(led_indicator_handle_t handle, bool val)
{
#if CONFIG_BSP_LEDS_NUM > 0
esp_err_t err = ESP_OK;
if (val) {
err = led_indicator_start(handle, BSP_LED_ON);
} else {
err = led_indicator_start(handle, BSP_LED_OFF);
}
return err;
#else
ESP_LOGI(TAG, "LED set power: %d", val);
return ESP_OK;
#endif
}
esp_err_t app_driver_light_set_brightness(led_indicator_handle_t handle, int val)
{
#if CONFIG_BSP_LEDS_NUM > 0
return led_indicator_set_brightness(handle, val);
#else
ESP_LOGI(TAG, "LED set brightness: %d", val);
return ESP_OK;
#endif
}
esp_err_t app_driver_light_set_hue(led_indicator_handle_t handle, int val)
{
#if CONFIG_BSP_LEDS_NUM > 0
led_indicator_ihsv_t hsv;
hsv.value = led_indicator_get_hsv(handle);
hsv.h = val;
return led_indicator_set_hsv(handle, hsv.value);
#else
ESP_LOGI(TAG, "LED set hue: %d", val);
return ESP_OK;
#endif
}
esp_err_t app_driver_light_set_saturation(led_indicator_handle_t handle, int val)
{
#if CONFIG_BSP_LEDS_NUM > 0
led_indicator_ihsv_t hsv;
hsv.value = led_indicator_get_hsv(handle);
hsv.s = val;
return led_indicator_set_hsv(handle, hsv.value);
#else
ESP_LOGI(TAG, "LED set saturation: %d", val);
return ESP_OK;
#endif
}
esp_err_t app_driver_light_set_temperature(led_indicator_handle_t handle, int val)
{
#if CONFIG_BSP_LEDS_NUM > 0
return led_indicator_set_color_temperature(handle, val);
#else
ESP_LOGI(TAG, "LED set temperature: %ld", val);
return ESP_OK;
#endif
}
static void app_driver_button_toggle_cb(void *arg, void *data)
{
ESP_LOGI(TAG, "Toggle button pressed");
uint16_t endpoint_id = light_endpoint_id;
uint32_t cluster_id = OnOff::Id;
uint32_t attribute_id = OnOff::Attributes::OnOff::Id;
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
attribute::get_val(attribute, &val);
val.val.b = !val.val.b;
attribute::update(endpoint_id, cluster_id, attribute_id, &val);
}
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
uint32_t attribute_id, esp_matter_attr_val_t *val)
{
esp_err_t err = ESP_OK;
if (endpoint_id == light_endpoint_id) {
led_indicator_handle_t handle = (led_indicator_handle_t)driver_handle;
if (cluster_id == OnOff::Id) {
if (attribute_id == OnOff::Attributes::OnOff::Id) {
err = app_driver_light_set_power(handle, val->val.b);
}
} else if (cluster_id == LevelControl::Id) {
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
err = app_driver_light_set_brightness(handle, val->val.u8);
}
} else if (cluster_id == ColorControl::Id) {
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
err = app_driver_light_set_hue(handle, val->val.u16);
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
err = app_driver_light_set_saturation(handle, val->val.u16);
} else if (attribute_id == ColorControl::Attributes::ColorTemperatureMireds::Id) {
err = app_driver_light_set_temperature(handle, val->val.u16);
}
}
}
return err;
}
esp_err_t app_driver_light_set_defaults(uint16_t endpoint_id)
{
esp_err_t err = ESP_OK;
void *priv_data = endpoint::get_priv_data(endpoint_id);
led_indicator_handle_t handle = (led_indicator_handle_t)priv_data;
attribute_t *attribute = NULL;
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
/* Setting brightness */
attribute = attribute::get(endpoint_id, LevelControl::Id, LevelControl::Attributes::CurrentLevel::Id);
attribute::get_val(attribute, &val);
err |= app_driver_light_set_brightness(handle, val.val.u8);
/* Setting color */
attribute = attribute::get(endpoint_id, ColorControl::Id, ColorControl::Attributes::ColorMode::Id);
attribute::get_val(attribute, &val);
if (val.val.u8 == (uint8_t)ColorControl::ColorMode::kCurrentHueAndCurrentSaturation) {
/* Setting hue */
attribute = attribute::get(endpoint_id, ColorControl::Id, ColorControl::Attributes::CurrentHue::Id);
attribute::get_val(attribute, &val);
err |= app_driver_light_set_hue(handle, val.val.u16);
/* Setting saturation */
attribute = attribute::get(endpoint_id, ColorControl::Id, ColorControl::Attributes::CurrentSaturation::Id);
attribute::get_val(attribute, &val);
err |= app_driver_light_set_saturation(handle, val.val.u16);
} else if (val.val.u8 == (uint8_t)ColorControl::ColorMode::kColorTemperature) {
/* Setting temperature */
attribute = attribute::get(endpoint_id, ColorControl::Id, ColorControl::Attributes::ColorTemperatureMireds::Id);
attribute::get_val(attribute, &val);
err |= app_driver_light_set_temperature(handle, val.val.u16);
} else {
ESP_LOGE(TAG, "Color mode not supported");
}
/* Setting power */
attribute = attribute::get(endpoint_id, OnOff::Id, OnOff::Attributes::OnOff::Id);
attribute::get_val(attribute, &val);
err |= app_driver_light_set_power(handle, val.val.b);
return err;
}
app_driver_handle_t app_driver_light_init()
{
#if CONFIG_BSP_LEDS_NUM > 0
/* Initialize led */
led_indicator_handle_t leds[CONFIG_BSP_LEDS_NUM];
ESP_ERROR_CHECK(bsp_led_indicator_create(leds, NULL, CONFIG_BSP_LEDS_NUM));
led_indicator_set_hsv(leds[0], SET_HSV(DEFAULT_HUE, DEFAULT_SATURATION, DEFAULT_BRIGHTNESS));
return (app_driver_handle_t)leds[0];
#else
return NULL;
#endif
}
static bool perform_factory_reset = false;
static void button_factory_reset_pressed_cb(void *arg, void *data)
{
if (!perform_factory_reset) {
ESP_LOGI(TAG, "Factory reset triggered. Release the button to start factory reset.");
perform_factory_reset = true;
}
}
static void button_factory_reset_released_cb(void *arg, void *data)
{
if (perform_factory_reset) {
ESP_LOGI(TAG, "Starting factory reset");
// Do RainMaker factory reset immediately and wait for 10 seconds
// so that the device can finish Matter factory reset.
esp_rmaker_factory_reset(0, 10);
esp_matter::factory_reset();
perform_factory_reset = false;
}
}
app_driver_handle_t app_driver_button_init()
{
/* Initialize button */
button_handle_t btns[BSP_BUTTON_NUM];
ESP_ERROR_CHECK(bsp_iot_button_create(btns, NULL, BSP_BUTTON_NUM));
ESP_ERROR_CHECK(iot_button_register_cb(btns[0], BUTTON_PRESS_DOWN, NULL, app_driver_button_toggle_cb, NULL));
ESP_ERROR_CHECK(iot_button_register_cb(btns[0], BUTTON_LONG_PRESS_HOLD, NULL, button_factory_reset_pressed_cb, NULL));
ESP_ERROR_CHECK(iot_button_register_cb(btns[0], BUTTON_PRESS_UP, NULL, button_factory_reset_released_cb, NULL));
return (app_driver_handle_t)btns[0];
}