Files
esp32-zigbee/ARCHITECTURE.md
T

9.1 KiB
Raw Blame History

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

  1. Implementar sensor de temperatura:

    • Adicionar driver I2C para AHT20/SHT30
    • Criar task de leitura periódica
    • Reportar valores via Zigbee
  2. Implementar sensor de porta:

    • Configurar GPIO com interrupção para reed switch
    • Implementar IAS Zone enrollment
    • Reportar mudanças de estado
  3. Adicionar OTA:

    • Habilitar FEATURE_OTA_UPDATE
    • Implementar cluster OTA
    • Testar atualização via ZHA

📖 Referências

📄 Licença

Baseado em exemplos ESP-IDF (LicenseRef-Included)