Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How to implement Matter door_lock endpoint #11765

Open
Assignees
Labels
Area: MatterIssues and Feature Request about Matter Protocol Type: Feature requestFeature request for Arduino ESP32 Type: QuestionOnly question
@0xbacaba

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=1 Cluster=0x0000_0101 Command=0x0000_0001 status 0x01 (no additional context)
I (41099) set_lock false
E (47131) chip[DMG]: Endpoint=1 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

Labels

Area: MatterIssues and Feature Request about Matter Protocol Type: Feature requestFeature request for Arduino ESP32 Type: QuestionOnly question

Type

No type

Projects

No projects

Milestone

No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      AltStyle によって変換されたページ (->オリジナル) /