9.1 KiB
9.1 KiB
Arquitetura Modular - Dispositivos Zigbee ESP32-C6
📋 Visão Geral
Este projeto foi refatorado para uma arquitetura modular flexível que permite criar facilmente diferentes tipos de dispositivos Zigbee apenas mudando uma configuração. Ideal para reutilizar código entre projetos com sensores, atuadores ou dispositivos mistos.
🎯 Tipos de Dispositivos Suportados
✅ Implementado
- DEVICE_TYPE_RELAY - Relé controlável (On/Off Light)
- GPIO 4: Saída do relé
- GPIO 9: Botão (toggle + factory reset)
- GPIO 8: LED RGB indicador
- Controle via ZHA/Zigbee2MQTT
🚧 Esqueleto Pronto (Basta Implementar Hardware)
-
DEVICE_TYPE_TEMP_SENSOR - Sensor de temperatura e umidade DHT11
- Clusters: Basic, Identify, Temperature Measurement, Humidity Measurement
- GPIO configurável para DHT11 (one-wire)
- ✅ Implementado com DHT11 - Reporta temperatura e umidade via Zigbee
-
DEVICE_TYPE_DOOR_SENSOR - Sensor de porta/janela
- Clusters: Basic, Identify, IAS Zone
- GPIO configurável para reed switch
- TODO: Implementar leitura e notificação de estado
-
DEVICE_TYPE_MOTION_SENSOR - Sensor de movimento PIR
- Clusters: Basic, Identify, Occupancy Sensing
- GPIO configurável para sensor PIR
- TODO: Implementar detecção e timeout
🔧 Como Usar
1. Selecionar Tipo de Dispositivo
Edite main/device_config.h:
/* Descomente APENAS UMA das opções */
#define DEVICE_TYPE_RELAY /* Relé controlável ✅ */
// #define DEVICE_TYPE_TEMP_SENSOR /* Sensor de temperatura */
// #define DEVICE_TYPE_DOOR_SENSOR /* Sensor de porta/janela */
// #define DEVICE_TYPE_MOTION_SENSOR /* Sensor de movimento */
2. Configurar GPIOs
No mesmo arquivo device_config.h:
/* GPIOs comuns */
#define GPIO_BUTTON_PAIRING 9 /* Botão pareamento/factory reset */
#define GPIO_LED_RGB 8 /* LED RGB indicador */
/* GPIOs específicos do dispositivo */
#ifdef DEVICE_TYPE_RELAY
#define GPIO_OUTPUT_RELAY 4 /* Relé de saída */
#define HAS_BUTTON_TOGGLE 1 /* Botão faz toggle */
#endif
#ifdef DEVICE_TYPE_TEMP_SENSOR
#define GPIO_SENSOR_I2C_SDA 6 /* I2C SDA */
#define GPIO_SENSOR_I2C_SCL 7 /* I2C SCL */
#endif
3. Habilitar/Desabilitar Features
#define FEATURE_LED_INDICATOR 1 /* LED RGB indicador */
#define FEATURE_LONG_PRESS_RESET 1 /* Factory reset 5s */
#define FEATURE_OTA_UPDATE 0 /* OTA (futuro) */
#define BUTTON_LONG_PRESS_MS 5000 /* Tempo long press */
#define LED_BRIGHTNESS_NORMAL 50 /* Brilho LED (0-255) */
4. Compilar e Gravar
idf.py build
idf.py -p /dev/ttyACM0 flash monitor
📁 Estrutura de Arquivos
main/
├── device_config.h # ⚙️ CONFIGURAÇÃO PRINCIPAL - Defina tipo e GPIOs
├── device_registry.h # 📋 Interface de abstração de dispositivos
├── device_registry.c # 🏭 Implementação de tipos de dispositivos
│
├── esp_zb_switch.h # Configuração Zigbee (rede, canal)
├── esp_zb_switch.c # Core Zigbee (agora usa device_registry)
│
├── switch_driver.h # Driver de botão e relé
├── switch_driver.c # (Condicionalmente compilado por tipo)
│
├── led_indicator.h # Driver LED RGB
├── led_indicator.c # Animações de status
├── led_strip_encoder.h # Encoder RMT customizado
├── led_strip_encoder.c # Para WS2812
🔄 Como Funciona a Arquitetura
Fluxo de Inicialização
app_main()
└─> esp_zb_task()
├─> device_get_config() // Obtém configuração ativa
├─> device->create_clusters() // Cria clusters específicos
├─> esp_zb_device_register() // Registra no Zigbee
└─> deferred_driver_init()
└─> device->hardware_init() // Inicializa hardware
Fluxo de Comandos Zigbee
ZHA/Coordinator
└─> [Comando On/Off]
└─> zb_attribute_handler()
└─> device->attribute_handler() // Handler específico
├─> relay_set_state() // (Relay)
└─> led_indicator_set_state() // Atualiza LED
➕ Como Adicionar um Novo Tipo de Dispositivo
Exemplo: Sensor de Umidade
1. Adicionar em device_config.h:
// #define DEVICE_TYPE_HUMIDITY_SENSOR
#ifdef DEVICE_TYPE_HUMIDITY_SENSOR
#define GPIO_SENSOR_I2C_SDA 6
#define GPIO_SENSOR_I2C_SCL 7
#define SENSOR_UPDATE_INTERVAL 60000
#endif
2. Implementar em device_registry.c:
#ifdef DEVICE_TYPE_HUMIDITY_SENSOR
static esp_zb_cluster_list_t* humidity_sensor_create_clusters(void)
{
esp_zb_cluster_list_t *list = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_basic_cluster(list, device_create_basic_cluster(),
ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_identify_cluster(list, device_create_identify_cluster(),
ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_humidity_meas_cluster(list,
device_create_humidity_cluster(),
ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
return list;
}
static void humidity_sensor_hardware_init(void)
{
// Inicializar I2C e sensor
ESP_LOGI(TAG, "Initializing humidity sensor");
}
static void humidity_sensor_update_state(void)
{
// Ler sensor e atualizar atributo Zigbee
// esp_zb_zcl_set_attribute_val(...);
}
static const device_type_t humidity_sensor_device = {
.name = "Zigbee Humidity Sensor",
.device_id = ESP_ZB_HA_HUMIDITY_SENSOR_DEVICE_ID,
.endpoint = HA_ONOFF_SWITCH_ENDPOINT,
.create_clusters = humidity_sensor_create_clusters,
.attribute_handler = NULL, // Sensor não recebe comandos
.hardware_init = humidity_sensor_hardware_init,
.update_state = humidity_sensor_update_state,
};
#endif
3. Adicionar ao seletor:
const device_type_t* device_get_config(void)
{
#ifdef DEVICE_TYPE_RELAY
return &relay_device;
#elif defined(DEVICE_TYPE_HUMIDITY_SENSOR)
return &humidity_sensor_device;
// ...
}
🎨 Estados do LED RGB
| Estado | Cor | Comportamento |
|---|---|---|
| OFF | Apagado | Dispositivo não iniciado |
| PAIRING | Azul Piscando | Modo pareamento (10s após boot) |
| CONNECTED | Verde | Conectado à rede Zigbee |
| DISCONNECTED | Vermelho Piscando | Desconectado da rede |
| RELAY_ON | Verde Brilhante | Relé ligado |
| RELAY_OFF | Verde Fraco | Relé desligado |
| FACTORY_RESET | Arco-íris | Reset em progresso (5s) |
🔘 Funcionalidades do Botão
- Pressão curta: Toggle do relé (apenas DEVICE_TYPE_RELAY)
- Long press 5s: Factory reset + modo pareamento
- LED RGB faz animação arco-íris
- Apaga credenciais Zigbee
- Reinicia dispositivo
🌐 Configuração Zigbee
Edite esp_zb_switch.h:
#define ESP_ZB_PRIMARY_CHANNEL_MASK ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK
/* Informações do dispositivo */
#define ESP_MANUFACTURER_NAME "\x09""ESPRESSIF"
#define ESP_MODEL_IDENTIFIER "\x0D""ZB_RELAY_V1.0"
🛠️ Configuração de Rede
/* Router configuration */
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZR_CONFIG();
- ESP_ZB_ZR_CONFIG() - Router (recomendado para dispositivos com alimentação)
- ESP_ZB_ZED_CONFIG() - End Device (economia de energia)
📊 Uso de Memória
Binary Size: ~617 KB
Flash Free: ~304 KB (33%)
Bootloader: 22.7 KB
🔍 Debugging
# Monitor serial
idf.py -p /dev/ttyACM0 monitor
# Filtrar logs específicos
idf.py -p /dev/ttyACM0 monitor | grep "DEVICE_REGISTRY"
idf.py -p /dev/ttyACM0 monitor | grep "LED_INDICATOR"
📝 Exemplos de Logs
I (1234) DEVICE_REGISTRY: Creating device: Zigbee Relay (ID: 0x0100)
I (1245) ESP_ZB_ON_OFF_SWITCH: Start Zigbee stack
I (1250) LED_INDICATOR: LED initialized on GPIO 8
I (1260) ESP_ZB_SWITCH: Relay inicializado no GPIO 4
I (12000) ESP_ZB_ON_OFF_SWITCH: Joined network successfully
I (12010) LED_INDICATOR: Setting LED state: CONNECTED
⚡ Próximos Passos
-
Implementar sensor de temperatura:
- Adicionar driver I2C para AHT20/SHT30
- Criar task de leitura periódica
- Reportar valores via Zigbee
-
Implementar sensor de porta:
- Configurar GPIO com interrupção para reed switch
- Implementar IAS Zone enrollment
- Reportar mudanças de estado
-
Adicionar OTA:
- Habilitar
FEATURE_OTA_UPDATE - Implementar cluster OTA
- Testar atualização via ZHA
- Habilitar
📖 Referências
📄 Licença
Baseado em exemplos ESP-IDF (LicenseRef-Included)