Zigbee to ESP32c6

Hello everyone,

I’m a newbie in the world of the Xiao ESP32C6 and programming.

To avoid bothering you too much with my newbie issues, I turned to AI to help me write some code that might work. Well… what a struggle! Nine times out of ten, it either doesn’t work or doesn’t do what I want.

That said, I did manage to come up with the following code:

#ifndef ZIGBEE_MODE_ED
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
#endif

#include "Zigbee.h"

/* Zigbee relay configuration */
#define RELAY_COUNT 3
const uint8_t relays[RELAY_COUNT] = {21, 22, 23}; // GPIOs pour les relais
uint8_t button = BOOT_PIN;

ZigbeeLight* zbRelays[RELAY_COUNT];

/********************* Relais control functions **************************/
void setRelay(int index, bool value) {
    if (index >= 0 && index < RELAY_COUNT) {
        digitalWrite(relays[index], value);
        delay(500); // Maintien du relais activé pendant 500 ms
        digitalWrite(relays[index], LOW); // Désactivation du relais
    }
}

void relayCallback0(bool value) { setRelay(0, value); }
void relayCallback1(bool value) { setRelay(1, value); }
void relayCallback2(bool value) { setRelay(2, value); }

/********************* Arduino functions **************************/
void setup() {
    Serial.begin(115200);

    // Init relais et les éteindre
    for (int i = 0; i < RELAY_COUNT; i++) {
        pinMode(relays[i], OUTPUT);
        digitalWrite(relays[i], LOW);
    }

    // Init bouton pour reset usine
    pinMode(button, INPUT_PULLUP);

    // Allocation dynamique des objets ZigbeeLight
    for (int i = 0; i < RELAY_COUNT; i++) {
        zbRelays[i] = new ZigbeeLight(10 + i);
        String modelName = "ZBRelay" + String(i+1);
        zbRelays[i]->setManufacturerAndModel("MonFabricant", modelName.c_str());
    }

    zbRelays[0]->onLightChange(relayCallback0);
    zbRelays[1]->onLightChange(relayCallback1);
    zbRelays[2]->onLightChange(relayCallback2);

    // Ajout des endpoints Zigbee
    for (int i = 0; i < RELAY_COUNT; i++) {
        Serial.printf("Adding ZigbeeRelay%d endpoint to Zigbee Core\n", i + 1);
        Zigbee.addEndpoint(zbRelays[i]);
    }

    // Démarrage du Zigbee
    if (!Zigbee.begin()) {
        Serial.println("Zigbee failed to start!");
        Serial.println("Rebooting...");
        ESP.restart();
    }
    Serial.println("Connecting to network");
    while (!Zigbee.connected()) {
        Serial.print(".");
        delay(100);
    }
    Serial.println();
}

void loop() {
    // Vérification du bouton pour le reset usine
    if (digitalRead(button) == LOW) {  // Bouton pressé
        delay(100);
        int startTime = millis();
        while (digitalRead(button) == LOW) {
            delay(50);
            if ((millis() - startTime) > 3000) {
                Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
                delay(1000);
                Zigbee.factoryReset();
            }
        }
    }
    delay(100);
}

It’s supposed to activate relays for 250 ms.
I have no idea if the code is properly written — I based it on a light control example because I couldn’t get anything working with switch examples.

Do you have any suggestions?

The next step is to figure out how to get relay state feedback into Home Assistant and Zigbee2MQTT (which I can’t seem to set up) along with an image and manufacturer info supported by Z2M.

If anyone can help, I’d really appreciate it!

Thanks!