Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 37 additions & 28 deletions drivers/SmartThings/matter-lock/src/new-matter-lock/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ if version.api < 10 then
clusters.DoorLock = require "DoorLock"
end

local DEVICE_TYPE_ID = {
DOOR_LOCK = 0x000A
}

local DoorLock = clusters.DoorLock
local PowerSource = clusters.PowerSource

Expand Down Expand Up @@ -209,35 +213,40 @@ local function match_profile_modular(driver, device)
local enabled_optional_component_capability_pairs = {}
local main_component_capabilities = {}
local modular_profile_name = "lock-modular"
for _, device_ep in pairs(device.endpoints) do
for _, ep_cluster in pairs(device_ep.clusters) do
if ep_cluster.cluster_id == DoorLock.ID then
local clus_has_feature = function(feature_bitmap)
return DoorLock.are_features_supported(feature_bitmap, ep_cluster.feature_map)
end
if clus_has_feature(DoorLock.types.Feature.USER) then
table.insert(main_component_capabilities, capabilities.lockUsers.ID)
end
if clus_has_feature(DoorLock.types.Feature.PIN_CREDENTIAL) then
table.insert(main_component_capabilities, capabilities.lockCredentials.ID)
end
if clus_has_feature(DoorLock.types.Feature.WEEK_DAY_ACCESS_SCHEDULES) or
clus_has_feature(DoorLock.types.Feature.YEAR_DAY_ACCESS_SCHEDULES) then
table.insert(main_component_capabilities, capabilities.lockSchedules.ID)
end
if clus_has_feature(DoorLock.types.Feature.UNBOLT) then
device:emit_event(capabilities.lock.supportedLockValues({"locked", "unlocked", "unlatched", "not fully locked"}, {visibility = {displayed = false}}))
device:emit_event(capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}}))
modular_profile_name = "lock-modular-embedded-unlatch" -- use the embedded config specified in this profile for devices supporting "unlatch"
else
device:emit_event(capabilities.lock.supportedLockValues({"locked", "unlocked", "not fully locked"}, {visibility = {displayed = false}}))
device:emit_event(capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}}))
end
if clus_has_feature(DoorLock.types.Feature.ALIRO_PROVISIONING) then
table.insert(main_component_capabilities, capabilities.lockAliro.ID)
end
break
local door_lock_ep_data
for _, ep_data in ipairs(device.endpoints) do
if ep_data.device_types[1].device_type_id == DEVICE_TYPE_ID.DOOR_LOCK then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the endpoint have multiple device types?

Copy link
Contributor Author

@hcarter-775 hcarter-775 Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per spec, application device types cannot have >1 device type on an endpoint

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, application device types cannot be supported on another endpoint as a secondary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed offline. Here's the spec wording:

9.2.1. Endpoint Requirements
[9.18] Each Simple endpoint SHALL support exactly one Application device type with the exception that, the endpoint MAY support additional device types which are subsets of the Application device type (the superset). See Section 9.2.10, “Superset Device Types” for cluster requirements of superset devices.

where the complement of simple endpoints are dynamic endpoints, which aren't used by us (now? ever?).

door_lock_ep_data = ep_data
break
end
end
for _, cluster in pairs(door_lock_ep_data.clusters) do
if cluster.cluster_id == DoorLock.ID then
local clus_has_feature = function(feature_bitmap)
return DoorLock.are_features_supported(feature_bitmap, cluster.feature_map)
end
if clus_has_feature(DoorLock.types.Feature.USER) then
table.insert(main_component_capabilities, capabilities.lockUsers.ID)
end
if clus_has_feature(DoorLock.types.Feature.PIN_CREDENTIAL) then
table.insert(main_component_capabilities, capabilities.lockCredentials.ID)
end
if clus_has_feature(DoorLock.types.Feature.WEEK_DAY_ACCESS_SCHEDULES) or
clus_has_feature(DoorLock.types.Feature.YEAR_DAY_ACCESS_SCHEDULES) then
table.insert(main_component_capabilities, capabilities.lockSchedules.ID)
end
if clus_has_feature(DoorLock.types.Feature.UNBOLT) then
device:emit_event(capabilities.lock.supportedLockValues({"locked", "unlocked", "unlatched", "not fully locked"}, {visibility = {displayed = false}}))
device:emit_event(capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}}))
modular_profile_name = "lock-modular-embedded-unlatch" -- use the embedded config specified in this profile for devices supporting "unlatch"
else
device:emit_event(capabilities.lock.supportedLockValues({"locked", "unlocked", "not fully locked"}, {visibility = {displayed = false}}))
device:emit_event(capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}}))
end
if clus_has_feature(DoorLock.types.Feature.ALIRO_PROVISIONING) then
table.insert(main_component_capabilities, capabilities.lockAliro.ID)
end
break
end
end

Expand Down
Loading