@@ -31,11 +31,30 @@ local DeviceConfiguration = {}
3131local SwitchDeviceConfiguration = {}
3232local 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+
3446function 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
6379end
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