ESP32-C6 - Hat schon jemand Erfahrungen mit Selbstbau-Zigbee?

Begonnen von Beta-User, 16 April 2025, 10:38:19

Vorheriges Thema - Nächstes Thema

TomLee

#15
Zitat von: betateilchen am 17 April 2025, 16:39:03Mit dem C6 habe ich schon einige der Zigbee-Beispiel-sketches, die in der Arduino IDE mitgeliefert werden, ausprobiert und sie haben alle auf Anhieb funktioniert.


---



Mit einem ESP32 C6 Super Mini funzt das Zigbee_Color_Dimmable_Light bei mir auch auf Anhieb.
Hast Du eine Konverter-Datei erstellt, das dein Device "Unterstützt" (Reiter Über->Unterstützungsstatus) wird?
Mit der aktuellen Arduino IDE 2.3.6 und der Bibliothekversion esp32 3.2.0 steht da bei mir ohne zutun "Nicht unterstützt (how_to_add_support)".

Mein Gedanke war ein HIGH/LOW auszuwerten, weder mit Zigbee_Color_Dimmer_Switch, Zigbee_Occupancy_Sensor oder Zigbee_On_Off_Switch war mir das heute nach meinen ersten Gehversuchen gelungen.
Bin erstmal ratlos.

edit:
Lösung: Macht man keinen Neustart von z2m nach dem neu flashen eines anderen Sketches, wird das Device immer als Zigbee_Model des zuvor gelöschten Device erkannt.


TomLee

Den Zigbee_Occupancy_Sensor.ino Sketch hab mir leicht angepasst:

#ifndef ZIGBEE_MODE_ZCZR
#error "Zigbee router mode is not selected in Tools->Zigbee mode"
#endif

#include "Zigbee.h"

/* Zigbee occupancy sensor configuration */
#define OCCUPANCY_SENSOR_ENDPOINT_NUMBER 10
uint8_t button = BOOT_PIN;
uint8_t sensor_pin = 4;  // GPIO4
ZigbeeOccupancySensor zbOccupancySensor = ZigbeeOccupancySensor(OCCUPANCY_SENSOR_ENDPOINT_NUMBER);

void setup() {
  Serial.begin(115200);

  // Init Button + Sensor
  pinMode(button, INPUT_PULLUP);     // BOOT-Taste mit internem Pullup
  pinMode(sensor_pin, INPUT_PULLUP); // GPIO4 mit internem Pullup

  // Geräteinformationen
  zbOccupancySensor.setManufacturerAndModel("ESP32-C6", "DIY-LD2410B");
  // determine powersource
  zbOccupancySensor.setPowerSource(ZB_POWER_SOURCE_MAINS);

  // Endpoint registrieren
  Zigbee.addEndpoint(&zbOccupancySensor);

  Serial.println("Starte Zigbee im Router-Modus...");
  if (!Zigbee.begin(ZIGBEE_ROUTER)) {
    Serial.println("Zigbee konnte nicht gestartet werden!");
    ESP.restart();
  }

  // Netzwerk 180 Sekunden nach Boot offen lassen
  Zigbee.setRebootOpenNetwork(180);

  Serial.println("Warte auf Netzwerkverbindung...");
  while (!Zigbee.connected()) {
    Serial.print(".");
    delay(100);
  }
  Serial.println("\nVerbunden als Router.");
}

void loop() {
  static bool occupancy = false;

  // GPIO4 → LOW = Bewegung, HIGH = keine Bewegung
  if (digitalRead(sensor_pin) == LOW && !occupancy) {
    zbOccupancySensor.setOccupancy(true);
    zbOccupancySensor.report();
    Serial.println("Bewegung erkannt → occupancy = true");
    occupancy = true;
  } else if (digitalRead(sensor_pin) == HIGH && occupancy) {
    zbOccupancySensor.setOccupancy(false);
    zbOccupancySensor.report();
    Serial.println("Keine Bewegung → occupancy = false");
    occupancy = false;
  }

  // Factory Reset bei langem Tastendruck
  if (digitalRead(button) == LOW) {
    delay(100);  // Entprellung
    int startTime = millis();
    while (digitalRead(button) == LOW) {
      delay(50);
      if ((millis() - startTime) > 3000) {
        Serial.println("Factory Reset in 1 Sekunde...");
        delay(1000);
        Zigbee.factoryReset();
      }
    }
  }

  delay(100);
}

(Optionale) Konverter-Datei:
import * as m from 'zigbee-herdsman-converters/lib/modernExtend';

export default {
    zigbeeModel: ['DIY-LD2410B'],
    model: 'DIY-LD2410B',
    vendor: 'ESP32-C6',
    description: 'Automatically definition',
    extend: [m.occupancy()],
    meta: {},
};

Im seriellen Monitor sehe ich das die Ereignisse nur einmal gesendet werden:
Bewegung erkannt → occupancy = true
Keine Bewegung → occupancy = false

in z2m ist im Debug-Log nur folgendes zu sehen:
[2025-06-12 12:47:31] z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{"linkquality":183,"occupancy":true}'
[2025-06-12 12:47:31] z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{"linkquality":207,"occupancy":false}'

in FHEM kommen die Ereignisse aber immer doppelt an:
12:47:31.867 zigbee_pi zigbee2mqtt/bridge/logging {"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":183,\"occupancy\":true}'"}
12:47:31.892 zigbee_pi zigbee2mqtt/0x543204fffe3d996c {"linkquality":183,"occupancy":true}
12:47:31.932 zigbee_pi zigbee2mqtt/0x543204fffe3d996c {"linkquality":183,"occupancy":true}
12:47:31.970 zigbee_pi zigbee2mqtt/bridge/logging {"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":207,\"occupancy\":false}'"}
12:47:31.989 zigbee_pi zigbee2mqtt/0x543204fffe3d996c {"linkquality":207,"occupancy":false}
12:47:32.016 zigbee_pi zigbee2mqtt/0x543204fffe3d996c {"linkquality":207,"occupancy":false}

Ist in dem Thema irgendwer soweit drin das er mir sagen kann warum die Events in FHEM doppelt ankommen?
Mein Gedanke war das z2m da was falsch interpretiert, darum hab ich eine Konverter-Datei erstellt. Damit wird das Device auch supported, aber es bleibt beim gleichen Verhalten mit den doppelten Events.

TomLee

Offensichtlich beschränkt sich meine Frage auf einen kleinen Kreis hier.

Auch nur Gedanken zu dem Thema wären hilfreich.

betateilchen

Zitat von: TomLee am 13 Juni 2025, 21:39:03Auch nur Gedanken zu dem Thema wären hilfreich.

Meine Vermutung ist (aufgrund des Zeitversatzes), dass die doppelten Nachrichten im Umfeld Deiner mqtt-Konfiguration bzw. FHEM/z2m erzeugt werden. Beispielsweise könnten die Nachrichten beim mqtt-Server ankommen, der sie dann selbst wieder per publish an andere clients weiterschickt. Damit wird quasi ein "Echo" erzeugt.

Bei mir kommen keine doppelten Nachrichten in FHEM an.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

ZitatBei mir kommen keine doppelten Nachrichten in FHEM an.

Mit Zigbee2MQTT version 2.4.0?

TomLee

ZitatMeine Vermutung ist (aufgrund des Zeitversatzes), dass die doppelten Nachrichten im Umfeld Deiner mqtt-Konfiguration bzw. FHEM/z2m erzeugt werden. Beispielsweise könnten die Nachrichten beim mqtt-Server ankommen, der sie dann selbst wieder per publish an andere clients weiterschickt. Damit wird quasi ein "Echo" erzeugt.

Danke.

Interessanter Ansatz, weil genau so was mag ich nicht ausschliessen.
Ich schau mir das mit verbose 5 am MQTT2_Server die Tage mal an, ob das wirklich der Fall sein sollte.


betateilchen

Zitat von: TomLee am 13 Juni 2025, 22:20:17
ZitatBei mir kommen keine doppelten Nachrichten in FHEM an.

Mit Zigbee2MQTT version 2.4.0?

2.4.0-dev commit: 6a8d2085
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

Wenn der MQTT2-Server was weiterschicken sollte, würde in der zweiten Spalte des Output vom Traffic-Monitor doch statt der CID, SENT stehen?

TomLee

#23
Raus scheint da wirklich was gesendet zu werden. Verstehen tu ich es aber erstmal nicht:

2025.06.14 12:51:09 5: in@127.0.0.1:37192 PUBLISH: 0(171)(1)(0)(26)zigbee2mqtt/bridge/logging{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":199,\"occupancy\":true}'"}
2025.06.14 12:51:09 4:   MQTT2_Server_127.0.0.1_37192 zigbee_pi PUBLISH zigbee2mqtt/bridge/logging:{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":199,\"occupancy\":true}'"}
2025.06.14 12:51:09 5:   MQTT2_Server_127.0.0.1_37192 zigbee_pi => zigbee2mqtt/bridge/logging:{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":199,\"occupancy\":true}'"}
2025.06.14 12:51:09 5: out@127.0.0.1:37192 PUBLISH: 0(171)(1)(0)(26)zigbee2mqtt/bridge/logging{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":199,\"occupancy\":true}'"}
2025.06.14 12:51:09 5: MQTT2_Server: dispatch autocreate=simple\000zigbee_pi\000zigbee2mqtt/bridge/logging\000{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\\"linkquality\\":199,\\"occupancy\\":true}'"}
2025.06.14 12:51:09 5: in@127.0.0.1:37192 PUBLISH: 0D(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 4:   MQTT2_Server_127.0.0.1_37192 zigbee_pi PUBLISH zigbee2mqtt/0x543204fffe3d996c:{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5:   MQTT2_Server_127.0.0.1_37192 zigbee_pi => zigbee2mqtt/0x543204fffe3d996c:{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5: out@127.0.0.1:37192 PUBLISH: 0D(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5: MQTT2_Server: dispatch autocreate=simple\000zigbee_pi\000zigbee2mqtt/0x543204fffe3d996c\000{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5: in@127.0.0.1:37192 PUBLISH: 0D(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 4:   MQTT2_Server_127.0.0.1_37192 zigbee_pi PUBLISH zigbee2mqtt/0x543204fffe3d996c:{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5:   MQTT2_Server_127.0.0.1_37192 zigbee_pi => zigbee2mqtt/0x543204fffe3d996c:{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5: out@127.0.0.1:37192 PUBLISH: 0D(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5: MQTT2_Server: dispatch autocreate=simple\000zigbee_pi\000zigbee2mqtt/0x543204fffe3d996c\000{"linkquality":199,"occupancy":true}
2025.06.14 12:51:09 5: in@127.0.0.1:37192 PUBLISH: 0(172)(1)(0)(26)zigbee2mqtt/bridge/logging{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":191,\"occupancy\":false}'"}
2025.06.14 12:51:09 4:   MQTT2_Server_127.0.0.1_37192 zigbee_pi PUBLISH zigbee2mqtt/bridge/logging:{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":191,\"occupancy\":false}'"}
2025.06.14 12:51:09 5:   MQTT2_Server_127.0.0.1_37192 zigbee_pi => zigbee2mqtt/bridge/logging:{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":191,\"occupancy\":false}'"}
2025.06.14 12:51:09 5: out@127.0.0.1:37192 PUBLISH: 0(172)(1)(0)(26)zigbee2mqtt/bridge/logging{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\"linkquality\":191,\"occupancy\":false}'"}
2025.06.14 12:51:09 5: MQTT2_Server: dispatch autocreate=simple\000zigbee_pi\000zigbee2mqtt/bridge/logging\000{"level":"info","message":"z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{\\"linkquality\\":191,\\"occupancy\\":false}'"}
2025.06.14 12:51:09 5: in@127.0.0.1:37192 PUBLISH: 0E(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 4:   MQTT2_Server_127.0.0.1_37192 zigbee_pi PUBLISH zigbee2mqtt/0x543204fffe3d996c:{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 5:   MQTT2_Server_127.0.0.1_37192 zigbee_pi => zigbee2mqtt/0x543204fffe3d996c:{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 5: out@127.0.0.1:37192 PUBLISH: 0E(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 5: MQTT2_Server: dispatch autocreate=simple\000zigbee_pi\000zigbee2mqtt/0x543204fffe3d996c\000{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 5: in@127.0.0.1:37192 PUBLISH: 0E(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 4:   MQTT2_Server_127.0.0.1_37192 zigbee_pi PUBLISH zigbee2mqtt/0x543204fffe3d996c:{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 5:   MQTT2_Server_127.0.0.1_37192 zigbee_pi => zigbee2mqtt/0x543204fffe3d996c:{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 5: out@127.0.0.1:37192 PUBLISH: 0E(0)(30)zigbee2mqtt/0x543204fffe3d996c{"linkquality":191,"occupancy":false}
2025.06.14 12:51:09 5: MQTT2_Server: dispatch autocreate=simple\000zigbee_pi\000zigbee2mqtt/0x543204fffe3d996c\000{"linkquality":191,"occupancy":false}

defmod MQTT2_Server MQTT2_SERVER 1883 global
attr MQTT2_Server ignoreRegexp shellies/[^:"]+/command|shellies/[^:"]+/command|cmnd/[^:"]+:|homeassistant/[^:"]+/config|tasmota/discovery/[^/:]+/(config|sensors)|devcontrol/[0-8]+/[0-8]+
attr MQTT2_Server respectRetain 0
attr MQTT2_Server room IOs

setstate MQTT2_Server 2025-06-14 12:54:51 lastPublish ebusd/700/Hc1ExcessTemp/get:
setstate MQTT2_Server 2025-06-14 13:00:29 nrclients 18
setstate MQTT2_Server 2025-06-12 10:10:35 state Initialized


defmod zigbee_0x543204fffe3d996c MQTT2_DEVICE zigbee_0x543204fffe3d996c
attr zigbee_0x543204fffe3d996c devStateIcon Motion..true:people_sensor Motion..false:motion_detector
attr zigbee_0x543204fffe3d996c devicetopic zigbee2mqtt/0x543204fffe3d996c
attr zigbee_0x543204fffe3d996c readingList $DEVICETOPIC:.* { json2nameValue($EVENT) }\
$DEVICETOPIC/availability:.* { json2nameValue($EVENT) }
attr zigbee_0x543204fffe3d996c room MQTT2_DEVICE
attr zigbee_0x543204fffe3d996c stateFormat Motion: occupancy
attr zigbee_0x543204fffe3d996c webCmd :

setstate zigbee_0x543204fffe3d996c Motion: false
setstate zigbee_0x543204fffe3d996c 2025-06-12 10:09:57 IODev MQTT2_Server
setstate zigbee_0x543204fffe3d996c 2025-06-14 13:00:31 associatedWith MQTT2_zigbee_bridge
setstate zigbee_0x543204fffe3d996c 2025-06-14 13:03:44 linkquality 199
setstate zigbee_0x543204fffe3d996c 2025-06-14 13:03:44 occupancy false
setstate zigbee_0x543204fffe3d996c 2025-06-14 13:00:31 state online

TomLee

#24
Im Frontend wird das Debug-Log default nicht mehr angezeigt ::)
Im Terminal sehe ich mit mosquitto_ sub und in z2m das die Ereignisse doppelt von z2m gepublisht werden.

Das ich nicht die dev-Version nutze, les ich an den Änderungen nicht raus, das es daran liegen könnte.
Kann sowas evtl. auch an der verwendeten Coordinator-Firmwareversion liegen ? Hab bei meinem Conbee 2 nie ein update gemacht. Der hat noch 0x26580700 aus 2020 drauf.

TomLee

Das Debug Log, das merkwürdigerweise zeigt dass das Ereignis zweimal von dem Sensor geschickt wird, sieht übrigens so aus:

[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DEVICE_STATE changed: 10101010
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 0 apsDataIndication: 1 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:deconz:driver: query aps data indication
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_INDICATION - sending read data request - SeqNr. 230
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DATA_INDICATION RESPONSE - seqNr. 230 srcAddr: 0x3de9 destAddr: 0x0 profile id: 0x104 cluster id: 0x406 lqi: 191
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: response payload: 08440a00001801
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 0 apsDataIndication: 1 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:controller: Received payload: clusterID=1030, address=15849, groupID=0, endpoint=10, destinationEndpoint=1, wasBroadcast=false, linkQuality=191, frame={"header":{"frameControl":{"frameType":0,"manufacturerSpecific":false,"direction":1,"disableDefaultResponse":false,"reservedBits":0},"transactionSequenceNumber":68,"commandIdentifier":10},"payload":[{"attrId":0,"dataType":24,"attrData":1}],"command":{"ID":10,"name":"report","parameters":[{"name":"attrId","type":33},{"name":"dataType","type":32},{"name":"attrData","type":1000}]}}
[2025-06-29 16:31:04] debug:    zh:controller:endpoint: ZCL command 0x543204fffe3d996c/10 msOccupancySensing.defaultRsp({"cmdId":10,"statusCode":0}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":1,"reservedBits":0,"transactionSequenceNumber":68,"writeUndiv":false})
[2025-06-29 16:31:04] debug:    zh:deconz: no response expected (68)
[2025-06-29 16:31:04] debug:    z2m: Received Zigbee message from '0x543204fffe3d996c', type 'attributeReport', cluster 'msOccupancySensing', data '{"occupancy":1}' from endpoint 10 with groupID 0
[2025-06-29 16:31:04] info:     z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{"linkquality":191,"occupancy":true}'
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_REQUEST - destAddr: 0x3de9 EP:10 SeqNr. 231 request id: 50
[2025-06-29 16:31:04] debug:    zh:deconz:driver: query aps data indication
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DATA_REQUEST RESPONSE - request id: 50 status: 0
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 0 apsDataIndication: 1 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_INDICATION - sending read data request - SeqNr. 232
[2025-06-29 16:31:04] debug:    zh:deconz:driver: query aps data indication
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_INDICATION - sending read data request - SeqNr. 233
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DEVICE_STATE changed: 10101110
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 1 apsDataIndication: 1 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DATA_INDICATION RESPONSE - seqNr. 232 srcAddr: 0x3de9 destAddr: 0x0 profile id: 0x104 cluster id: 0x406 lqi: 191
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: response payload: 08450a00001801
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 1 apsDataIndication: 0 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:controller: Received payload: clusterID=1030, address=15849, groupID=0, endpoint=10, destinationEndpoint=1, wasBroadcast=false, linkQuality=191, frame={"header":{"frameControl":{"frameType":0,"manufacturerSpecific":false,"direction":1,"disableDefaultResponse":false,"reservedBits":0},"transactionSequenceNumber":69,"commandIdentifier":10},"payload":[{"attrId":0,"dataType":24,"attrData":1}],"command":{"ID":10,"name":"report","parameters":[{"name":"attrId","type":33},{"name":"dataType","type":32},{"name":"attrData","type":1000}]}}
[2025-06-29 16:31:04] debug:    zh:controller:endpoint: ZCL command 0x543204fffe3d996c/10 msOccupancySensing.defaultRsp({"cmdId":10,"statusCode":0}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":1,"reservedBits":0,"transactionSequenceNumber":69,"writeUndiv":false})
[2025-06-29 16:31:04] debug:    zh:deconz: no response expected (69)
[2025-06-29 16:31:04] debug:    z2m: Received Zigbee message from '0x543204fffe3d996c', type 'attributeReport', cluster 'msOccupancySensing', data '{"occupancy":1}' from endpoint 10 with groupID 0
[2025-06-29 16:31:04] info:     z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x543204fffe3d996c', payload '{"linkquality":191,"occupancy":true}'
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_REQUEST - destAddr: 0x3de9 EP:10 SeqNr. 234 request id: 51
[2025-06-29 16:31:04] debug:    zh:deconz:driver: query aps data confirm
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DATA_REQUEST RESPONSE - request id: 51 status: 0
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 1 apsDataIndication: 0 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_CONFIRM - sending data state request - SeqNr. 235
[2025-06-29 16:31:04] debug:    zh:deconz:driver: query aps data confirm
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DEVICE_STATE changed: 10100110
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 1 apsDataIndication: 0 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DATA_CONFIRM RESPONSE - destAddr: 0x3de9 request id: 50 confirm status: 0
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 1 apsDataIndication: 0 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:deconz: sendZclFrameToEndpoint - message send with transSeq Nr.: 68
[2025-06-29 16:31:04] debug:    zh:deconz: false, true, false, 10000
[2025-06-29 16:31:04] debug:    zh:deconz: resolve request (68)
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_CONFIRM - sending data state request - SeqNr. 236
[2025-06-29 16:31:04] debug:    zh:deconz:driver: query aps data confirm
[2025-06-29 16:31:04] debug:    zh:deconz:frameparser: DATA_CONFIRM RESPONSE - destAddr: 0x3de9 request id: 51 confirm status: 0
[2025-06-29 16:31:04] debug:    zh:deconz:driver: networkstate: 2 apsDataConfirm: 0 apsDataIndication: 0 configChanged: 0 apsRequestFreeSlots: 1
[2025-06-29 16:31:04] debug:    zh:deconz: sendZclFrameToEndpoint - message send with transSeq Nr.: 69
[2025-06-29 16:31:04] debug:    zh:deconz: false, true, false, 10000
[2025-06-29 16:31:04] debug:    zh:deconz: resolve request (69)
[2025-06-29 16:31:04] debug:    zh:deconz:driver: DATA_CONFIRM - sending data state request - SeqNr. 237

Im seriellen Monitor seh ich immer nur eine Ausgabe. Ich verstehe es nicht.
Mit debounce 1000 und debounce_ignore linkquality/occupancy kann man die doppelten payloads verhindern, mich würd aber schon interessieren wo im Sketch dann die Ursache für das doppelte senden zu finden ist.


Udo, hast du es mit genau meinem oben gezeigten Sketch nachvollzogen oder einen eigenen verwendet?

TomLee

Nachdem ich jetzt ChatGPT auch mal mit den Debug-Ausgaben gefüttert habe, konnte dadurch jetzt endlich ein Hinweis geliefert werden:

Zitat⚠️ Analyse: Doppelte Reports im Sketch
Dein Sketch ruft im Loop bei jeder Zustandsänderung diese zwei Zeilen auf:

cpp
Kopieren
Bearbeiten
zbOccupancySensor.setOccupancy(true);
zbOccupancySensor.report();
Das ist korrekt, führt aber zu doppelten Ereignissen, weil:

setOccupancy(true) setzt intern den Attribute-Wert und sendet bereits selbst einen Report (abhängig von deiner Zigbee-Library-Implementierung).

zbOccupancySensor.report() ruft anschließend nochmals explizit ein Reporting auf.

🔍 Beleg im Log

Die zwei direkten Reports mit unterschiedlichen transactionSequenceNumbers (68, 69) zeigen:

python
Kopieren
Bearbeiten
[2025-06-29 16:31:04] ... commandIdentifier":10 ... transactionSequenceNumber":68
...
[2025-06-29 16:31:04] ... commandIdentifier":10 ... transactionSequenceNumber":69
→ Zwei Reports derselben occupancy=1 Änderung, wenige Millisekunden auseinander.

✅ Lösung: Nur einen Report auslösen
Entferne die explizite report()-Aufrufzeile, wenn setOccupancy() bereits sendet:

cpp
Kopieren
Bearbeiten
if (digitalRead(sensor_pin) == LOW && !occupancy) {
  zbOccupancySensor.setOccupancy(true);
  Serial.println("Bewegung erkannt → occupancy = true");
  occupancy = true;
} else if (digitalRead(sensor_pin) == HIGH && occupancy) {
  zbOccupancySensor.setOccupancy(false);
  Serial.println("Keine Bewegung → occupancy = false");
  occupancy = false;
}
Falls du sicherstellen möchtest, dass setOccupancy keinen automatischen Report sendet, prüfe deine ZigbeeOccupancySensor-Klassenimplementierung. Manche Libraries trennen ,,Wert setzen" und ,,Report senden", andere kombinieren es.

Beisst sich mit der Aussage von Betateilchen, aber wenn ich bspw. die Zeilen zbOccupancySensor.report(); auskommentiere, werden die Werte nur einmal geschickt.

TomLee

#27
ZitatDanke für deine Präzisierung, dass du die Zigbee Examples von Espressif (ESP-IDF Arduino Layer) nutzt. In diesem Kontext gilt:

⚠️ Verhalten der Espressif Zigbee Examples
In den Espressif Zigbee Examples (z.B. occupancy_sensor_demo), ist die Funktion:

cpp
Kopieren
Bearbeiten
setOccupancy(true);
lediglich ein Setter für den Attributwert im Cluster ohne automatisches Reporting. Sie aktualisiert den lokalen Cluster-Attributwert, damit dieser bei künftigen Read/Report-Requests korrekt gemeldet wird. Ein explizites report() ist dort weiterhin notwendig, um:

Sofort eine Meldung zu senden (attributeReport).

Den Wert im Coordinator/Bridge (z.B. Zigbee2MQTT, deCONZ) aktuell zu halten.

🧐 Warum dennoch doppelte Reports entstehen
Das doppelte Senden kann entstehen durch:

✅ a) Automatisches Reporting aufgrund der Reporting-Konfiguration

Der Coordinator (z.B. Zigbee2MQTT oder deCONZ) sendet bei Geräteanmeldung oder Periodik folgendes:

Configure Reporting Command für den Occupancy-Cluster.

Dadurch schickt das Endgerät automatisch Reports bei Attributwertänderungen, selbst ohne report() Aufruf.

✅ b) Dein Sketch ruft zusätzlich report() auf

Somit sendest du:

automatisch (wegen der Configure Reporting-Einstellung des Coordinators)

manuell mit zbOccupancySensor.report().

🔍 Bestätigung
Im Zigbee Cluster Logging siehst du pro Änderung:

makefile
Kopieren
Bearbeiten
transactionSequenceNumber: 68
...
transactionSequenceNumber: 69
Zwei unterschiedliche SequenceNumbers = zwei Reports, beide fast gleichzeitig.

✅ Lösungsansatz konkret (für Espressif Example)
Option A (empfohlen):
Lasse zbOccupancySensor.report() im Sketch weg und nutze rein die automatische Reporting-Funktion deines Coordinators. Das spart Bandbreite.

cpp
Kopieren
Bearbeiten
zbOccupancySensor.setOccupancy(true);
// zbOccupancySensor.report(); // entfernt
Option B:
Falls du immer sofort reporten willst und auf automatisches Reporting verzichten möchtest, kannst du im Coordinator die Reporting-Konfiguration deaktivieren oder minimal anpassen, damit dein manueller report() allein verwendet wird.

🔧 Prüfen in Zigbee2MQTT
In der Zigbee2MQTT Gerätekonfiguration:

yaml
Kopieren
Bearbeiten
Reporting:
  occupancy:
    min: 0
    max: 300
    change: 1
Falls du automatische Reports deaktivierst (max: 0 nicht erlaubt, stattdessen Reporting abbestellen über configureReporting entfernen), wird nur dein Sketch-Report gesendet.

📝 Zusammenfassung
✔️ Ursache: Doppelte Reports durch Kombination von:

automatischem Reporting (vom Coordinator konfiguriert)

manuellem report() im Sketch.

✔️ Lösung: Entferne entweder

zbOccupancySensor.report() im Sketch, oder

das automatische Reporting im Coordinator.

Reporting deaktivieren in den Einstellungen des Device im Frontend hilft auch, dann kann die zbOccupancySensor.report() Zeile drin bleiben.


Denke ich lasse zbOccupancySensor.report() im Sketch weg und nutze die automatische Reporting-Funktion des Coordinators.