Skip to content

Commit 9cca67f

Browse files
committed
update switch workaround handling logic
1 parent 38f240f commit 9cca67f

File tree

2 files changed

+45
-35
lines changed

2 files changed

+45
-35
lines changed

drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -587,14 +587,6 @@ local function test_init_parent_child_unsupported_device_type()
587587
test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_unsupported_device_type.id, "doConfigure" })
588588
mock_device_parent_child_unsupported_device_type:expect_metadata_update({ profile = "switch-binary" })
589589
mock_device_parent_child_unsupported_device_type:expect_metadata_update({ provisioning_state = "PROVISIONED" })
590-
591-
mock_device_parent_child_unsupported_device_type:expect_device_create({
592-
type = "EDGE_CHILD",
593-
label = "Matter Switch 2",
594-
profile = "switch-binary",
595-
parent_device_id = mock_device_parent_child_unsupported_device_type.id,
596-
parent_assigned_child_key = string.format("%d", 10)
597-
})
598590
end
599591

600592
local function test_init_light_level_motion()

drivers/SmartThings/matter-switch/src/utils/device_configuration.lua

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,30 @@ local DeviceConfiguration = {}
3131
local SwitchDeviceConfiguration = {}
3232
local ButtonDeviceConfiguration = {}
3333

34+
local function server_onoff_supported(ep_info)
35+
for _, cluster in pairs(ep_info.clusters) do
36+
if cluster.cluster_id == clusters.OnOff.ID then
37+
if cluster.cluster_type == "SERVER" or cluster.cluster_type == "BOTH" then
38+
return true
39+
else
40+
return false
41+
end
42+
end
43+
end
44+
end
45+
3446
function SwitchDeviceConfiguration.assign_profile_for_onoff_ep(device, onoff_ep_id, is_child_device)
35-
local ep = switch_utils.get_endpoint_info(device, onoff_ep_id)
36-
local primary_dt_id = switch_utils.find_max_subset_device_type(ep, fields.DEVICE_TYPE_ID.LIGHT)
37-
or (switch_utils.detect_matter_thing(device) and switch_utils.find_max_subset_device_type(ep, fields.DEVICE_TYPE_ID.SWITCH))
38-
or ep.device_types[1] and ep.device_types[1].device_type_id
47+
local ep_info = switch_utils.get_endpoint_info(device, onoff_ep_id)
48+
49+
local primary_dt_id = switch_utils.find_max_subset_device_type(ep_info, fields.DEVICE_TYPE_ID.LIGHT)
50+
or ep_info.device_types[1] and ep_info.device_types[1].device_type_id
51+
52+
-- workaround: for 'Light Switch' Device Type EPs that break spec and implement their OnOff cluster as 'server'.
53+
-- For this, check server is supported before attempting to profile a device according to a Switch device type
54+
if switch_utils.tbl_contains(fields.DEVICE_TYPE_ID.SWITCH, primary_dt_id) and server_onoff_supported(ep_info) then
55+
primary_dt_id = switch_utils.find_max_subset_device_type(ep_info, fields.DEVICE_TYPE_ID.SWITCH)
56+
end
57+
3958
local profile = fields.device_type_profile_map[primary_dt_id]
4059

4160
if is_child_device then
@@ -54,39 +73,38 @@ function SwitchDeviceConfiguration.assign_profile_for_onoff_ep(device, onoff_ep_
5473
end
5574
end
5675
end
57-
58-
-- default to "switch-binary" if no profile is found
59-
return profile or "switch-binary"
6076
end
6177

6278
return profile
6379
end
6480

65-
function SwitchDeviceConfiguration.create_child_devices(driver, device, server_onoff_ep_ids, main_endpoint_id)
66-
if #server_onoff_ep_ids == 1 and server_onoff_ep_ids[1] == main_endpoint_id then -- no children will be created
81+
function SwitchDeviceConfiguration.create_child_devices(driver, device, onoff_ep_ids, main_endpoint_id)
82+
if #onoff_ep_ids == 1 and onoff_ep_ids[1] == main_endpoint_id then -- no children will be created
6783
return
6884
end
6985

7086
local device_num = 0
71-
table.sort(server_onoff_ep_ids)
72-
for idx, ep_id in ipairs(server_onoff_ep_ids) do
87+
table.sort(onoff_ep_ids)
88+
for idx, ep_id in ipairs(onoff_ep_ids) do
7389
device_num = device_num + 1
7490
if ep_id ~= main_endpoint_id then -- don't create a child device that maps to the main endpoint
7591
local name = string.format("%s %d", device.label, device_num)
7692
local child_profile = SwitchDeviceConfiguration.assign_profile_for_onoff_ep(device, ep_id, true)
77-
driver:try_create_device(
78-
{
79-
type = "EDGE_CHILD",
80-
label = name,
81-
profile = child_profile,
82-
parent_device_id = device.id,
83-
parent_assigned_child_key = string.format("%d", ep_id),
84-
vendor_provided_label = name
85-
}
86-
)
87-
if idx == 1 and string.find(child_profile, "energy") then
88-
-- when energy management is defined in the root endpoint(0), replace it with the first switch endpoint and process it.
89-
device:set_field(fields.ENERGY_MANAGEMENT_ENDPOINT, ep_id, {persist = true})
93+
if child_profile then -- a supported child profile was found
94+
driver:try_create_device(
95+
{
96+
type = "EDGE_CHILD",
97+
label = name,
98+
profile = child_profile,
99+
parent_device_id = device.id,
100+
parent_assigned_child_key = string.format("%d", ep_id),
101+
vendor_provided_label = name
102+
}
103+
)
104+
if idx == 1 and string.find(child_profile, "energy") then
105+
-- when energy management is defined in the root endpoint(0), replace it with the first switch endpoint and process it.
106+
device:set_field(fields.ENERGY_MANAGEMENT_ENDPOINT, ep_id, {persist = true})
107+
end
90108
end
91109
end
92110
end
@@ -178,9 +196,9 @@ function DeviceConfiguration.match_profile(driver, device)
178196
end
179197
end
180198

181-
local server_onoff_ep_ids = device:get_endpoints(clusters.OnOff.ID, { cluster_type = "SERVER" })
182-
if #server_onoff_ep_ids > 0 then
183-
SwitchDeviceConfiguration.create_child_devices(driver, device, server_onoff_ep_ids, main_endpoint_id)
199+
local onoff_ep_ids = device:get_endpoints(clusters.OnOff.ID)
200+
if #onoff_ep_ids > 0 then
201+
SwitchDeviceConfiguration.create_child_devices(driver, device, onoff_ep_ids, main_endpoint_id)
184202
updated_profile = SwitchDeviceConfiguration.assign_profile_for_onoff_ep(device, main_endpoint_id)
185203
local generic_profile = function(s) return string.find(updated_profile or "", s, 1, true) end
186204

0 commit comments

Comments
 (0)