Skip to content

Instantly share code, notes, and snippets.

@markwylde
Last active December 4, 2023 13:34
Show Gist options
  • Save markwylde/99459937c1fb6b8b5e9edf631ab62e5f to your computer and use it in GitHub Desktop.
Save markwylde/99459937c1fb6b8b5e9edf631ab62e5f to your computer and use it in GitHub Desktop.
ESP32-C6 ZigBee LED Blinker

The following firmware can be uploaded onto an ESP32-C6 to expose a ZigBee device.

At the bottom is the zigbee2mqtt device definition.

Firmware:

#include "esp_zigbee.h"

void setup() {
    // Initialize Zigbee stack configuration for a Zigbee end-device
    esp_zb_cfg_t zb_config = ESP_ZB_ZED_CONFIG();
    esp_zb_init(&zb_config);

    // Set device information
    uint8_t model_id[] = "MARKS-LED-BLINKER"; // Model Identifier
    uint8_t manufacturer_name[] = "MARK-WYLDE"; // Manufacturer Name

    // Create and configure the basic cluster
    esp_zb_attribute_list_t *basic_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_BASIC);
    esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, model_id);
    esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, manufacturer_name);

    // Create a Home Automation (HA) on/off light endpoint
    esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
    esp_zb_cluster_list_add_basic_cluster(cluster_list, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_ep_list_t *ep_list = esp_zb_ep_list_create();
    esp_zb_ep_list_add_ep(ep_list, cluster_list, 1 /* Endpoint ID */, ESP_ZB_AF_HA_PROFILE_ID, ESP_ZB_HA_ON_OFF_OUTPUT_DEVICE_ID);

    // Register the Zigbee device
    esp_zb_device_register(ep_list);

    // Set up GPIO for LED
    pinMode(LED_BUILTIN, OUTPUT);

    // Start Zigbee stack
    esp_zb_start();

    // Set up attribute change callback
    esp_zb_device_add_set_attr_value_cb(attr_callback);
}

void loop() {
    // Run Zigbee stack main loop iteration
    esp_zb_main_loop_iteration();
}

// Callback function to handle attribute changes
void attr_callback(uint8_t status, uint8_t endpoint, uint16_t cluster_id, uint16_t attr_id, void *new_value) {
    if (cluster_id == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF && attr_id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID) {
        uint8_t value = *(uint8_t*)new_value;
        digitalWrite(LED_BUILTIN, (bool)value);
    }
}

Driver:

name: 'Marks LED Blinker'
description: 'Control an onboard LED on the ESP32-C6 via Zigbee'
vendor: 'MARK-WYLDE'
model: 'MARKS-LED-BLINKER'
exposes:
  - type: 'switch'
    name: 'state'
    property: 'state'
    access: 7 # (read, write, and report capabilities)
    value_on: 'ON'
    value_off: 'OFF'
    value_toggle: 'TOGGLE'
fromZigbee:
  - converterId: 'on_off'
toZigbee:
  - converterId: 'on_off'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment