-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Open
Labels
Area: MatterIssues and Feature Request about Matter ProtocolIssues and Feature Request about Matter ProtocolType: Feature requestFeature request for Arduino ESP32Feature request for Arduino ESP32Type: QuestionOnly questionOnly question
Description
Board
ESP32 Dev Module
Device Description
DevKit V1
Hardware Configuration
Version
v3.3.0
Type
Question
IDE Name
neovim + arduino-cli
Operating System
Arch Linux
Flash frequency
40MHz
PSRAM enabled
no
Upload speed
921600
Description
I'm trying to setup a door_lock endpoint in a similar way as the builtin OnOffLight. The device is correctly advertised, but whenever i flip the switch, it just flips back on its own.
The lock and unlock command callbacks are called correctly, MatterDoorLock::attributeChangeCB
is not called.
Any help would be greatly appreciated!
Sketch
// MatterTest.ino:
#include <Matter.h>
#include <WiFi.h>
#include "MatterDoorLock.h"
MatterDoorLock doorLock;
bool set_lock(bool state) {
Serial.print("lock set: ");
Serial.println(state ? "on" : "off");
return true;
}
void setup() {
Serial.begin(115200);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
Serial.print(WiFi.status());
delay(500);
}
Serial.print("\nConnected as ");
Serial.println(WiFi.localIP());
doorLock.onChange(set_lock);
doorLock.begin(true);
Matter.begin();
if (!Matter.isDeviceCommissioned()) {
Serial.println("");
Serial.println("Matter Node is not commissioned yet.");
Serial.println("Initiate the device discovery in your Matter environment.");
Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
}
}
// MatterDoorLock.h
#pragma once
#include <sdkconfig.h>
#include <Matter.h>
#include <MatterEndPoint.h>
#include <app/clusters/door-lock-server/door-lock-delegate.h>
#include <core/CHIPError.h>
using EndPointCB = std::function<bool(bool)>;
class MatterDoorLock : public MatterEndPoint, public ArduinoMatter {
protected:
bool started = false;
bool lockedState = false;
EndPointCB _onChangeCB = NULL;
public:
MatterDoorLock();
~MatterDoorLock();
bool begin(bool initialLocked = false);
void end();
bool set_lock(bool new_state);
bool toggle();
bool isLocked();
void onChange(EndPointCB cb) { _onChangeCB = cb; }
bool attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val);
};
// MatterDoorLock.cpp
#include <sdkconfig.h>
#include <Matter.h>
#include <app/server/Server.h>
#include <app/clusters/door-lock-server/door-lock-server.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include "MatterDoorLock.h"
#include "esp_matter.h"
#include "esp_matter_attribute_utils.h"
#include "esp_matter_command.h"
#include "esp_matter_core.h"
#define log(level, format, ...) Serial.printf(level " (%d) " format "\n", millis(), ##__VA_ARGS__)
#define log_v(format, ...) log("V", format, ##__VA_ARGS__)
#define log_d(format, ...) log("D", format, ##__VA_ARGS__)
#define log_i(format, ...) log("I", format, ##__VA_ARGS__)
#define log_e(format, ...) log("E", format, ##__VA_ARGS__)
using namespace esp_matter;
using namespace esp_matter::endpoint;
using namespace chip::app::Clusters;
MatterDoorLock::MatterDoorLock() {}
MatterDoorLock::~MatterDoorLock() {
end();
}
bool MatterDoorLock::begin(bool initialLocked) {
ArduinoMatter::_init();
if (getEndPointId() != 0) {
log_e("Matter Door Lock with Endpoint Id %d device already exists.", getEndPointId());
return false;
}
lockedState = initialLocked;
door_lock::config_t lock_config;
lock_config.door_lock.lock_state = initialLocked;
lock_config.door_lock.actuator_enabled = true;
endpoint_t *endpoint = door_lock::create(node::get(), &lock_config, ENDPOINT_FLAG_NONE, (void *)this);
if (endpoint == nullptr) {
log_e("Failed to create Door Lock endpoint");
return false;
}
setEndPointId(endpoint::get_id(endpoint));
cluster_t *lock_cluster = cluster::create(endpoint, DoorLock::Id, CLUSTER_FLAG_NONE);
if(lock_cluster == nullptr) {
log_e("Failed to create Door Lock cluster");
return false;
}
command_t *unlock_command = cluster::door_lock::command::create_unlock_door(lock_cluster);
command_t *lock_command = cluster::door_lock::command::create_lock_door(lock_cluster);
if(unlock_command == nullptr || lock_command == nullptr) {
log_e("Failed to create Door Lock commands");
return false;
}
command::set_user_callback(unlock_command, [](const ConcreteCommandPath &path, TLVReader &data, void *context) {
auto self = (MatterDoorLock *) context;
self->set_lock(false);
return ESP_OK;
});
command::set_user_callback(lock_command, [](const ConcreteCommandPath &path, TLVReader &data, void *context) {
auto self = (MatterDoorLock *) context;
self->set_lock(true);
return ESP_OK;
});
log_i("Door Lock created with endpoint_id %d", getEndPointId());
started = true;
return true;
}
void MatterDoorLock::end() {
started = false;
}
bool MatterDoorLock::attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val) {
log_d("attributeChangeCB: %d, %d, %d", endpoint_id, cluster_id, attribute_id);
if (!started) {
log_e("Matter Door Lock device not started");
return false;
}
if (endpoint_id == getEndPointId() && cluster_id == DoorLock::Id && attribute_id == DoorLock::Attributes::LockState::Id) {
log_d("Door Lock state changed to %d", val->val.b);
if (_onChangeCB) _onChangeCB(val->val.b);
lockedState = val->val.b;
}
return true;
}
bool MatterDoorLock::set_lock(bool new_state) {
log_i("set_lock %s", new_state ? "true" : "false");
if (!started) return false;
if (lockedState == new_state) return true; // no change
lockedState = new_state;
esp_matter_attr_val_t val = esp_matter_bool(new_state);
updateAttributeVal(DoorLock::Id, DoorLock::Attributes::LockState::Id, &val);
return true;
}
bool MatterDoorLock::toggle() {
return set_lock(!isLocked());
}
bool MatterDoorLock::isLocked() {
return lockedState;
}
// Makefile
PORT := /dev/ttyUSB0
BAUDRATE := 115200
all: compile upload monitor
compile:
arduino-cli compile --build-property build.partitions=min_spiffs --build-property upload.maximum_size=1966080
upload:
arduino-cli upload -p $(PORT)
monitor:
arduino-cli monitor -c $(BAUDRATE) -p $(PORT)
Debug Message
I (1670) Door Lock created with endpoint_id 1
E (1685) chip[DMG]: Endpoint 0, Cluster 0x0000_0031 not found in IncreaseClusterDataVersion!
E (1686) chip[DMG]: Endpoint 0, Cluster 0x0000_0031 not found in IncreaseClusterDataVersion!
E (6476) mdns: mdns_service_remove_for_host(6677): Service doesn't exist
I (39167) set_lock false
E (45197) chip[DMG]: Endpoint=2 Cluster=0x0000_0101 Command=0x0000_0001 status 0x01 (no additional context)
I (41099) set_lock false
E (47131) chip[DMG]: Endpoint=2 Cluster=0x0000_0101 Command=0x0000_0001 status 0x01 (no additional context)
Other Steps to Reproduce
I've tried the same structure to replicate an OnOffLight endpoint and that has worked flawlessly. Didn't even create a cluster etc.
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.
Metadata
Metadata
Assignees
Labels
Area: MatterIssues and Feature Request about Matter ProtocolIssues and Feature Request about Matter ProtocolType: Feature requestFeature request for Arduino ESP32Feature request for Arduino ESP32Type: QuestionOnly questionOnly question