Skip to content

Commit

Permalink
Feature/implement schedules (#13863)
Browse files Browse the repository at this point in the history
* Add method definitions for weekday schedule

* Use correct types for door lock schedule attributes

* Implement SetWeekDay schedule command and add argument tests for it

* Implement GetWeekDay schedule command and add argument tests for it

* Use optional instead of presentIf in door-lock-cluster.xml

* Add ability to externally get number of supported users and schedules for door lock

* Support multiple endpoints on the door lock example app

* Implement storage for week day schedules in the door lock example app

* Implement command to clear the week day door lock schedules
- Also support feature checks
- Fix compiler warnings

* Enable year-day schedule stuff in the zap configs

* Add placeholder implementation of Year Days schedules

* Implement year day schedules in the cluster

* Add Doxygen comments for door lock cluster

* Fix code review notes

* Update auto-generated files
  • Loading branch information
Morozov-5F authored and pull[bot] committed Sep 28, 2023
1 parent f3c7a1a commit 3043217
Show file tree
Hide file tree
Showing 52 changed files with 10,152 additions and 445 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1159,9 +1159,9 @@ server cluster DoorLock = 257 {
readonly attribute int16u numberOfTotalUsersSupported = 17;
readonly attribute int16u numberOfPINUsersSupported = 18;
readonly attribute int16u numberOfRFIDUsersSupported = 19;
readonly attribute int16u numberOfWeekDaySchedulesSupportedPerUser = 20;
readonly attribute int16u numberOfYearDaySchedulesSupportedPerUser = 21;
readonly attribute int16u numberOfHolidaySchedulesSupported = 22;
readonly attribute int8u numberOfWeekDaySchedulesSupportedPerUser = 20;
readonly attribute int8u numberOfYearDaySchedulesSupportedPerUser = 21;
readonly attribute int8u numberOfHolidaySchedulesSupported = 22;
readonly attribute int8u maxPINCodeLength = 23;
readonly attribute int8u minPINCodeLength = 24;
readonly attribute int8u maxRFIDCodeLength = 25;
Expand Down
1 change: 1 addition & 0 deletions examples/chip-tool/templates/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ function getTests()
const DoorLock = [
'DL_UsersAndCredentials',
'DL_LockUnlock',
'DL_Schedules',
];

const Groups = [
Expand Down
64 changes: 64 additions & 0 deletions examples/door-lock-app/door-lock-common/door-lock-app.matter
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ server cluster DoorLock = 257 {
readonly attribute int16u numberOfTotalUsersSupported = 17;
readonly attribute int16u numberOfPINUsersSupported = 18;
readonly attribute int16u numberOfRFIDUsersSupported = 19;
readonly attribute int8u numberOfWeekDaySchedulesSupportedPerUser = 20;
readonly attribute int8u numberOfYearDaySchedulesSupportedPerUser = 21;
readonly attribute int8u maxPINCodeLength = 23;
readonly attribute int8u minPINCodeLength = 24;
readonly attribute int8u maxRFIDCodeLength = 25;
Expand All @@ -527,6 +529,16 @@ server cluster DoorLock = 257 {
INT16U userIndex = 0;
}

request struct ClearWeekDayScheduleRequest {
INT8U weekDayIndex = 0;
INT16U userIndex = 1;
}

request struct ClearYearDayScheduleRequest {
INT8U yearDayIndex = 0;
INT16U userIndex = 1;
}

request struct GetCredentialStatusRequest {
DlCredential credential = 0;
}
Expand All @@ -535,6 +547,16 @@ server cluster DoorLock = 257 {
INT16U userIndex = 0;
}

request struct GetWeekDayScheduleRequest {
INT8U weekDayIndex = 0;
INT16U userIndex = 1;
}

request struct GetYearDayScheduleRequest {
INT8U yearDayIndex = 0;
INT16U userIndex = 1;
}

request struct LockDoorRequest {
optional OCTET_STRING pinCode = 0;
}
Expand All @@ -558,6 +580,23 @@ server cluster DoorLock = 257 {
nullable DlCredentialRule credentialRule = 6;
}

request struct SetWeekDayScheduleRequest {
INT8U weekDayIndex = 0;
INT16U userIndex = 1;
DlDaysMaskMap daysMask = 2;
INT8U startHour = 3;
INT8U startMinute = 4;
INT8U endHour = 5;
INT8U endMinute = 6;
}

request struct SetYearDayScheduleRequest {
INT8U yearDayIndex = 0;
INT16U userIndex = 1;
epoch_s localStartTime = 2;
epoch_s localEndTime = 3;
}

request struct UnlockDoorRequest {
optional OCTET_STRING pinCode = 0;
}
Expand All @@ -581,6 +620,25 @@ server cluster DoorLock = 257 {
nullable INT16U nextUserIndex = 9;
}

response struct GetWeekDayScheduleResponse {
INT8U weekDayIndex = 0;
INT16U userIndex = 1;
DlStatus status = 2;
optional DlDaysMaskMap daysMask = 3;
optional INT8U startHour = 4;
optional INT8U startMinute = 5;
optional INT8U endHour = 6;
optional INT8U endMinute = 7;
}

response struct GetYearDayScheduleResponse {
INT8U yearDayIndex = 0;
INT16U userIndex = 1;
DlStatus status = 2;
optional epoch_s localStartTime = 3;
optional epoch_s localEndTime = 4;
}

response struct SetCredentialResponse {
DlStatus status = 0;
nullable INT16U userIndex = 1;
Expand All @@ -589,11 +647,17 @@ server cluster DoorLock = 257 {

command ClearCredential(ClearCredentialRequest): DefaultSuccess = 38;
command ClearUser(ClearUserRequest): DefaultSuccess = 29;
command ClearWeekDaySchedule(ClearWeekDayScheduleRequest): DefaultSuccess = 13;
command ClearYearDaySchedule(ClearYearDayScheduleRequest): DefaultSuccess = 16;
command GetCredentialStatus(GetCredentialStatusRequest): GetCredentialStatusResponse = 36;
command GetUser(GetUserRequest): GetUserResponse = 27;
command GetWeekDaySchedule(GetWeekDayScheduleRequest): GetWeekDayScheduleResponse = 12;
command GetYearDaySchedule(GetYearDayScheduleRequest): GetYearDayScheduleResponse = 15;
command LockDoor(LockDoorRequest): DefaultSuccess = 0;
command SetCredential(SetCredentialRequest): SetCredentialResponse = 34;
command SetUser(SetUserRequest): DefaultSuccess = 26;
command SetWeekDaySchedule(SetWeekDayScheduleRequest): DefaultSuccess = 11;
command SetYearDaySchedule(SetYearDayScheduleRequest): DefaultSuccess = 14;
command UnlockDoor(UnlockDoorRequest): DefaultSuccess = 1;
}

Expand Down
74 changes: 69 additions & 5 deletions examples/door-lock-app/door-lock-common/door-lock-app.zap
Original file line number Diff line number Diff line change
Expand Up @@ -6076,6 +6076,54 @@
"incoming": 1,
"outgoing": 1
},
{
"name": "SetWeekDaySchedule",
"code": 11,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "GetWeekDaySchedule",
"code": 12,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "ClearWeekDaySchedule",
"code": 13,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "SetYearDaySchedule",
"code": 14,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "GetYearDaySchedule",
"code": 15,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "ClearYearDaySchedule",
"code": 16,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "SetUser",
"code": 26,
Expand Down Expand Up @@ -6151,6 +6199,22 @@
"side": "server",
"enabled": 1,
"commands": [
{
"name": "GetWeekDayScheduleResponse",
"code": 12,
"mfgCode": null,
"source": "server",
"incoming": 0,
"outgoing": 1
},
{
"name": "GetYearDayScheduleResponse",
"code": 15,
"mfgCode": null,
"source": "server",
"incoming": 0,
"outgoing": 1
},
{
"name": "GetUserResponse",
"code": 28,
Expand Down Expand Up @@ -6347,11 +6411,11 @@
"code": 20,
"mfgCode": null,
"side": "server",
"included": 0,
"included": 1,
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0",
"defaultValue": "10",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -6362,11 +6426,11 @@
"code": 21,
"mfgCode": null,
"side": "server",
"included": 0,
"included": 1,
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0",
"defaultValue": "10",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand Down Expand Up @@ -6876,7 +6940,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0x103",
"defaultValue": "0x113",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand Down
1 change: 1 addition & 0 deletions examples/door-lock-app/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import("//build_overrides/chip.gni")
executable("chip-door-lock-app") {
sources = [
"main.cpp",
"src/LockEndpoint.cpp",
"src/LockManager.cpp",
]

Expand Down
112 changes: 112 additions & 0 deletions examples/door-lock-app/linux/include/LockEndpoint.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <app/clusters/door-lock-server/door-lock-server.h>
#include <vector>

struct LockUserInfo;
struct LockCredentialInfo;
struct WeekDaysScheduleInfo;
struct YearDayScheduleInfo;

static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 20;

class LockEndpoint
{
public:
LockEndpoint(chip::EndpointId endpointId, uint16_t numberOfLockUsersSupported, uint16_t numberOfCredentialsSupported,
uint8_t weekDaySchedulesPerUser, uint8_t yearDaySchedulesPerUser) :
mEndpointId(endpointId),
mLockState(DlLockState::kLocked), mLockUsers(numberOfLockUsersSupported),
mLockCredentials(numberOfCredentialsSupported + 1),
mWeekDaySchedules(numberOfLockUsersSupported, std::vector<WeekDaysScheduleInfo>(weekDaySchedulesPerUser)),
mYearDaySchedules(numberOfLockUsersSupported, std::vector<YearDayScheduleInfo>(numberOfLockUsersSupported))
{}

inline chip::EndpointId GetEndpointId() { return mEndpointId; }

bool Lock(const Optional<chip::ByteSpan> & pin);
bool Unlock(const Optional<chip::ByteSpan> & pin);

bool GetUser(uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const;
bool SetUser(uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, const chip::CharSpan & userName,
uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule,
const DlCredential * credentials, size_t totalCredentials);

bool GetCredential(uint16_t credentialIndex, DlCredentialType credentialType,
EmberAfPluginDoorLockCredentialInfo & credential) const;

bool SetCredential(uint16_t credentialIndex, DlCredentialStatus credentialStatus, DlCredentialType credentialType,
const chip::ByteSpan & credentialData);

DlStatus GetSchedule(uint8_t weekDayIndex, uint16_t userIndex, EmberAfPluginDoorLockWeekDaySchedule & schedule);
DlStatus GetSchedule(uint8_t yearDayIndex, uint16_t userIndex, EmberAfPluginDoorLockYearDaySchedule & schedule);
DlStatus SetSchedule(uint8_t weekDayIndex, uint16_t userIndex, DlScheduleStatus status, DlDaysMaskMap daysMask,
uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute);
DlStatus SetSchedule(uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, uint32_t localStartTime,
uint32_t localEndTime);

private:
bool setLockState(DlLockState lockState, const Optional<chip::ByteSpan> & pin);
const char * lockStateToString(DlLockState lockState) const;

chip::EndpointId mEndpointId;
DlLockState mLockState;

// This is very naive implementation of users/credentials/schedules database and by no means the best practice. Proper storage
// of those items is out of scope of this example.
std::vector<LockUserInfo> mLockUsers;
std::vector<LockCredentialInfo> mLockCredentials;
std::vector<std::vector<WeekDaysScheduleInfo>> mWeekDaySchedules;
std::vector<std::vector<YearDayScheduleInfo>> mYearDaySchedules;
};

struct LockUserInfo
{
char userName[DOOR_LOCK_USER_NAME_BUFFER_SIZE];
DlCredential credentials[DOOR_LOCK_MAX_CREDENTIALS_PER_USER];
size_t totalCredentials;
uint32_t userUniqueId;
DlUserStatus userStatus;
DlUserType userType;
DlCredentialRule credentialRule;
chip::FabricIndex createdBy;
chip::FabricIndex lastModifiedBy;
};

struct LockCredentialInfo
{
DlCredentialStatus status;
DlCredentialType credentialType;
uint8_t credentialData[DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE];
size_t credentialDataSize;
};

struct WeekDaysScheduleInfo
{
DlScheduleStatus status;
EmberAfPluginDoorLockWeekDaySchedule schedule;
};

struct YearDayScheduleInfo
{
DlScheduleStatus status;
EmberAfPluginDoorLockYearDaySchedule schedule;
};
Loading

0 comments on commit 3043217

Please sign in to comment.