feat: Adiciona suporte para dispositivo combo (relé + sensor de temperatura/umidade) e driver para sensor ultrassônico JSN-SR04T

This commit is contained in:
2026-01-17 00:34:24 +00:00
parent fcecd9d273
commit 5c063ff367
32 changed files with 467 additions and 9 deletions
Regular → Executable
+141
View File
@@ -15,6 +15,11 @@
#include "dht11_driver.h"
#endif
#ifdef DEVICE_TYPE_COMBO_RELAY_SENSOR
#include "switch_driver.h"
#include "dht11_driver.h"
#endif
#if FEATURE_LED_INDICATOR
#include "led_indicator.h"
#endif
@@ -289,6 +294,140 @@ static const device_type_t motion_sensor_device = {
};
#endif /* DEVICE_TYPE_MOTION_SENSOR */
/* ========================= DISPOSITIVO COMBO (RELÉ + SENSOR) ========================= */
#ifdef DEVICE_TYPE_COMBO_RELAY_SENSOR
static TaskHandle_t combo_sensor_task_handle = NULL;
/* Task para ler sensor DHT11 periodicamente */
static void combo_sensor_task(void *pvParameters)
{
dht11_reading_t reading;
TickType_t last_wake_time = xTaskGetTickCount();
while (1) {
vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(SENSOR_UPDATE_INTERVAL));
esp_err_t ret = dht11_read(&reading);
if (ret == ESP_OK && reading.valid) {
int16_t temp_zigbee = (int16_t)(reading.temperature * 100);
uint16_t humidity_zigbee = (uint16_t)(reading.humidity * 100);
esp_zb_lock_acquire(portMAX_DELAY);
esp_zb_zcl_set_attribute_val(
HA_ONOFF_SWITCH_ENDPOINT,
ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,
ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID,
&temp_zigbee,
false
);
esp_zb_zcl_set_attribute_val(
HA_ONOFF_SWITCH_ENDPOINT,
ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT,
ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
ESP_ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID,
&humidity_zigbee,
false
);
esp_zb_lock_release();
ESP_LOGI(TAG, "Sensor updated - Temp: %.1f°C (%d), Humidity: %.1f%% (%u)",
reading.temperature, temp_zigbee, reading.humidity, humidity_zigbee);
} else {
ESP_LOGW(TAG, "Failed to read DHT11: %s", esp_err_to_name(ret));
}
}
}
static esp_zb_cluster_list_t* combo_create_clusters(void)
{
esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
/* Clusters básicos */
esp_zb_cluster_list_add_basic_cluster(cluster_list, device_create_basic_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_identify_cluster(cluster_list, device_create_identify_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
/* Cluster de controle do relé */
esp_zb_cluster_list_add_on_off_cluster(cluster_list, device_create_onoff_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
/* Clusters de sensores */
esp_zb_cluster_list_add_temperature_meas_cluster(cluster_list, device_create_temperature_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_humidity_meas_cluster(cluster_list, device_create_humidity_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
return cluster_list;
}
static esp_err_t combo_attribute_handler(const esp_zb_zcl_set_attr_value_message_t *message)
{
/* Handler de comandos on/off para o relé */
if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF &&
message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID) {
bool on_off = message->attribute.data.value ? *(bool *)message->attribute.data.value : 0;
ESP_LOGI(TAG, "Relay command received: %s", on_off ? "ON" : "OFF");
relay_set_state(on_off);
#if FEATURE_LED_INDICATOR
led_indicator_set_state(on_off ? LED_RELAY_ON : LED_RELAY_OFF);
#endif
return ESP_OK;
}
return ESP_ERR_NOT_FOUND;
}
static void combo_hardware_init(void)
{
ESP_LOGI(TAG, "Initializing combo device (Relay + DHT11 sensor)");
/* Inicializa relé */
relay_driver_init();
/* Inicializa DHT11 */
esp_err_t ret = dht11_init(GPIO_SENSOR_DHT11);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize DHT11: %s", esp_err_to_name(ret));
return;
}
/* Cria task para leitura do sensor */
xTaskCreate(
combo_sensor_task,
"combo_sensor",
4096,
NULL,
5,
&combo_sensor_task_handle
);
ESP_LOGI(TAG, "Combo device initialized - Relay: GPIO %d, DHT11: GPIO %d",
GPIO_OUTPUT_RELAY, GPIO_SENSOR_DHT11);
}
static void combo_update_state(void)
{
/* Atualização feita pela task periódica */
}
static const device_type_t combo_relay_sensor_device = {
.name = "Zigbee Relay + Temperature/Humidity Sensor",
.device_id = ESP_ZB_HA_ON_OFF_OUTPUT_DEVICE_ID,
.endpoint = HA_ONOFF_SWITCH_ENDPOINT,
.create_clusters = combo_create_clusters,
.attribute_handler = combo_attribute_handler,
.hardware_init = combo_hardware_init,
.update_state = combo_update_state,
};
#endif /* DEVICE_TYPE_COMBO_RELAY_SENSOR */
/* ========================= SELETOR DE DISPOSITIVO ========================= */
const device_type_t* device_get_config(void)
@@ -301,6 +440,8 @@ const device_type_t* device_get_config(void)
return &door_sensor_device;
#elif defined(DEVICE_TYPE_MOTION_SENSOR)
return &motion_sensor_device;
#elif defined(DEVICE_TYPE_COMBO_RELAY_SENSOR)
return &combo_relay_sensor_device;
#else
#error "Nenhum tipo de dispositivo definido!"
return NULL;