Skip to content

Commit de15c71

Browse files
committed
add fixed W RGBW profile
1 parent 0e13a71 commit de15c71

File tree

8 files changed

+457
-332
lines changed

8 files changed

+457
-332
lines changed

drivers/SmartThings/matter-switch/fingerprints.yml

Lines changed: 321 additions & 321 deletions
Large diffs are not rendered by default.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: light-color-level-noTemp
2+
components:
3+
- id: main
4+
capabilities:
5+
- id: switch
6+
version: 1
7+
- id: switchLevel
8+
version: 1
9+
config:
10+
values:
11+
- key: "level.value"
12+
range: [1, 100]
13+
- id: colorControl
14+
version: 1
15+
- id: firmwareUpdate
16+
version: 1
17+
- id: refresh
18+
version: 1
19+
categories:
20+
- name: Light

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ function SwitchDeviceConfiguration.assign_profile_for_onoff_ep(device, server_on
2929

3030
local generic_profile = fields.device_type_profile_map[primary_dt_id]
3131

32+
-- remove colorTemperature capability from profile if device doesn't support it
33+
if generic_profile == "light-color-level" and
34+
not switch_utils.find_cluster_on_ep(ep_info, clusters.ColorControl.ID, {feature_bitmap=clusters.ColorControl.types.Feature.COLOR_TEMPERATURE}) then
35+
generic_profile = "light-color-level-noTemp"
36+
end
37+
3238
local static_electrical_tags = switch_utils.get_field_for_endpoint(device, fields.ELECTRICAL_TAGS, server_onoff_ep_id)
3339
if static_electrical_tags ~= nil then
3440
-- profiles like 'light-binary' and 'plug-binary' should drop the '-binary' and become 'light-power', 'plug-energy-powerConsumption', etc.
@@ -194,13 +200,13 @@ function DeviceConfiguration.match_profile(driver, device)
194200
updated_profile = "light-color-level-fan"
195201
elseif generic_profile("light-level") and #device:get_endpoints(clusters.OccupancySensing.ID) > 0 then
196202
updated_profile = "light-level-motion"
197-
elseif generic_profile("plug-binary") or generic_profile("plug-level") then
198-
if switch_utils.check_switch_category_vendor_overrides(device) then
199-
updated_profile = string.gsub(updated_profile, "plug", "switch")
200-
end
201-
elseif generic_profile("light-level-colorTemperature") or generic_profile("light-color-level") then
202-
-- ignore attempts to dynamically profile light-level-colorTemperature and light-color-level devices for now, since
203-
-- these may lose fingerprinted Kelvin ranges when dynamically profiled.
203+
elseif switch_utils.check_switch_category_vendor_overrides(device) then
204+
-- check whether the overwrite should be over "plug" or "light" based on the current profile
205+
local overwrite_category = string.find(updated_profile, "plug") and "plug" or "light"
206+
updated_profile = string.gsub(updated_profile, overwrite_category, "switch")
207+
elseif switch_utils.check_deprecated_color_temperature_profile_vendor_overrides(device) then
208+
-- ignore attempts to dynamically profile certain devices containing the colorTemperature capability
209+
-- for now, since these may lose fingerprinted Kelvin ranges when dynamically profiled.
204210
return
205211
end
206212
end

drivers/SmartThings/matter-switch/src/switch_utils/fields.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ SwitchFields.vendor_overrides = {
118118
},
119119
}
120120

121+
--- A table of vendorIDs and corresponding productIDs indicating devices that require
122+
--- a non-default Category, specifically "Switch". These overrides are applied during device
123+
--- onboarding to ensure an accurate display in the SmartThings app.
121124
SwitchFields.switch_category_vendor_overrides = {
122125
[0x1432] = -- Elko
123126
{0x1000},
@@ -143,6 +146,34 @@ SwitchFields.switch_category_vendor_overrides = {
143146
{0xEEE2, 0xAB08, 0xAB31, 0xAB04, 0xAB01, 0xAB43, 0xAB02, 0xAB03, 0xAB05}
144147
}
145148

149+
--- Devices that were certified with profiles defining non-default min/max ColorTemperature values for the driver.
150+
--- These profiles have since been deprecated in favor of having devices report their own min/max values, but to ensure
151+
--- backwards compatibility, we override these devices with their current fingerprint at present.
152+
SwitchFields.deprecated_color_temperature_profile_vendor_overrides = {
153+
[0x115a] = -- Nanoleaf
154+
{0x0035, 0x0036, 0x0041, 0x0043, 0x0044, 0x0711, 0x0047, 0x0048, 0x0049, 0x004B},
155+
[0x1160] = -- Sengled
156+
{0x9002},
157+
[0x147F] = -- U-Tec
158+
{0x0002},
159+
[0x1339] = -- GE
160+
{0x00B1, 0x0083, 0x00B6, 0x00B5, 0x00AF, 0x00B4, 0x00AE, 0x002C, 0x0029, 0x002A,
161+
0x002B, 0x0089, 0x002E, 0x0062, 0x00AB, 0x0061, 0x0068, 0x006E, 0x007B, 0x006D,
162+
0x006B, 0x00AD, 0x0069, 0x0065, 0x0015, 0x006C, 0x0016},
163+
[0x1168] = -- AiDot
164+
{0x03F4, 0x03F3, 0x03F2, 0x0405, 0x03ec, 0x03eb, 0x03ea, 0x03e8, 0x03f8, 0x03F5,
165+
0x1000, 0x03EE, 0x03ED, 0x03EF, 0x03f9, 0x03FB, 0x03FC},
166+
[0x115F] = -- Aqara
167+
{0x1802, 0x1806},
168+
[0x1423] = -- Lifx
169+
{0x00A1, 0x00A2, 0x00A8, 0x00A9, 0x00AB, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B2,
170+
0x00B3, 0x00B4, 0x00B9, 0x00C9, 0x00DB, 0x00DC, 0x00D5, 0x00D7, 0x00D9, 0x0077},
171+
[0x1312] = -- Yeelight
172+
{0x0001},
173+
[0x1407] = -- ThirdReality
174+
{0x1088}
175+
}
176+
146177
--- stores a table of endpoints that support the Electrical Sensor device type, used during profiling
147178
--- in AvailableEndpoints and PartsList handlers for SET and TREE PowerTopology features, respectively
148179
SwitchFields.ELECTRICAL_SENSOR_EPS = "__electrical_sensor_eps"

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ function utils.check_switch_category_vendor_overrides(device)
103103
end
104104
end
105105

106+
function utils.check_deprecated_color_temperature_profile_vendor_overrides(device)
107+
for _, product_id in ipairs(fields.deprecated_color_temperature_profile_vendor_overrides[device.manufacturer_info.vendor_id] or {}) do
108+
if device.manufacturer_info.product_id == product_id then
109+
return true
110+
end
111+
end
112+
end
113+
106114
--- device_type_supports_button_switch_combination helper function used to check
107115
--- whether the device type for an endpoint is currently supported by a profile for
108116
--- combination button/switch devices.

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

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,29 @@ local mock_device_extended_color = test.mock_device.build_test_matter_device({
112112
}
113113
})
114114

115+
local mock_device_extended_color_no_temp = test.mock_device.build_test_matter_device({
116+
profile = t_utils.get_profile_definition("light-color-level.yml"),
117+
manufacturer_info = {
118+
vendor_id = 0x0000,
119+
product_id = 0x0000,
120+
},
121+
endpoints = {
122+
{
123+
endpoint_id = 1,
124+
clusters = {
125+
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
126+
{cluster_id = clusters.ColorControl.ID, cluster_type = "BOTH", feature_map = 14},
127+
{cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER", feature_map = 2}
128+
},
129+
device_types = {
130+
{device_type_id = 0x0100, device_type_revision = 1}, -- On/Off Light
131+
{device_type_id = 0x0101, device_type_revision = 1}, -- Dimmable Light
132+
{device_type_id = 0x010D, device_type_revision = 1}, -- Extended Color Light
133+
}
134+
}
135+
}
136+
})
137+
115138
local cluster_subscribe_list = {
116139
clusters.OnOff.attributes.OnOff,
117140
clusters.LevelControl.attributes.CurrentLevel,
@@ -216,6 +239,7 @@ local function test_init_color_temp()
216239
mock_device_color_temp.id,
217240
clusters.ColorControl.attributes.Options:write(mock_device_color_temp, 1, clusters.ColorControl.types.OptionsBitmap.EXECUTE_IF_OFF)
218241
})
242+
mock_device_color_temp:expect_metadata_update({ profile = "light-level-colorTemperature" })
219243
mock_device_color_temp:expect_metadata_update({ provisioning_state = "PROVISIONED" })
220244
test.socket.matter:__expect_send({mock_device_color_temp.id, subscribe_request})
221245
end
@@ -243,22 +267,58 @@ local function test_init_extended_color()
243267
mock_device_extended_color.id,
244268
clusters.ColorControl.attributes.Options:write(mock_device_extended_color, 1, clusters.ColorControl.types.OptionsBitmap.EXECUTE_IF_OFF)
245269
})
270+
mock_device_extended_color:expect_metadata_update({ profile = "light-color-level" })
246271
mock_device_extended_color:expect_metadata_update({ provisioning_state = "PROVISIONED" })
247272
test.socket.matter:__expect_send({mock_device_extended_color.id, subscribe_request})
248273
end
249274

275+
local function test_init_extended_color_no_temp()
276+
test.mock_device.add_test_device(mock_device_extended_color_no_temp)
277+
local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_extended_color_no_temp)
278+
for i, cluster in ipairs(cluster_subscribe_list) do
279+
if i > 1 then
280+
subscribe_request:merge(cluster:subscribe(mock_device_extended_color_no_temp))
281+
end
282+
end
283+
test.socket.matter:__expect_send({mock_device_extended_color_no_temp.id, subscribe_request})
284+
test.socket.device_lifecycle:__queue_receive({ mock_device_extended_color_no_temp.id, "added" })
285+
286+
test.socket.device_lifecycle:__queue_receive({ mock_device_extended_color_no_temp.id, "init" })
287+
test.socket.matter:__expect_send({mock_device_extended_color_no_temp.id, subscribe_request})
288+
289+
test.socket.device_lifecycle:__queue_receive({ mock_device_extended_color_no_temp.id, "doConfigure" })
290+
test.socket.matter:__expect_send({
291+
mock_device_extended_color_no_temp.id,
292+
clusters.LevelControl.attributes.Options:write(mock_device_extended_color_no_temp, 1, clusters.LevelControl.types.OptionsBitmap.EXECUTE_IF_OFF)
293+
})
294+
test.socket.matter:__expect_send({
295+
mock_device_extended_color_no_temp.id,
296+
clusters.ColorControl.attributes.Options:write(mock_device_extended_color_no_temp, 1, clusters.ColorControl.types.OptionsBitmap.EXECUTE_IF_OFF)
297+
})
298+
mock_device_extended_color_no_temp:expect_metadata_update({ profile = "light-color-level-noTemp" })
299+
mock_device_extended_color_no_temp:expect_metadata_update({ provisioning_state = "PROVISIONED" })
300+
test.socket.matter:__expect_send({mock_device_extended_color_no_temp.id, subscribe_request})
301+
end
302+
303+
250304
test.register_message_test(
251-
"Test that Color Temperature Light device does not switch profiles",
305+
"Test that Color Temperature Light device switches profiles",
252306
{},
253307
{ test_init = test_init_color_temp }
254308
)
255309

256310
test.register_message_test(
257-
"Test that Extended Color Light device does not switch profiles",
311+
"Test that Extended Color Light device switches profiles",
258312
{},
259313
{ test_init = test_init_extended_color }
260314
)
261315

316+
test.register_message_test(
317+
"Test that Extended Color Light device without color temperature switches profiles",
318+
{},
319+
{ test_init = test_init_extended_color_no_temp }
320+
)
321+
262322
test.register_message_test(
263323
"On command should send the appropriate commands",
264324
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ local function test_init_parent_child_endpoints_non_sequential()
259259
test.socket.matter:__expect_send({unsup_mock_device.id, clusters.LevelControl.attributes.Options:write(unsup_mock_device, child2_ep_non_sequential, clusters.LevelControl.types.OptionsBitmap.EXECUTE_IF_OFF)})
260260
test.socket.matter:__expect_send({unsup_mock_device.id, clusters.ColorControl.attributes.Options:write(unsup_mock_device, child2_ep_non_sequential, clusters.ColorControl.types.OptionsBitmap.EXECUTE_IF_OFF)})
261261

262-
unsup_mock_device:expect_metadata_update({ profile = "light-binary" })
262+
unsup_mock_device:expect_metadata_update({ profile = "switch-binary" })
263263
unsup_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
264264

265265
for _, child in pairs(mock_children_non_sequential) do

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ local function test_init_parent_child_endpoints_non_sequential()
256256
test.socket.matter:__expect_send({mock_device_parent_child_endpoints_non_sequential.id, clusters.LevelControl.attributes.Options:write(mock_device_parent_child_endpoints_non_sequential, child1_ep_non_sequential, clusters.LevelControl.types.OptionsBitmap.EXECUTE_IF_OFF)})
257257
test.socket.matter:__expect_send({mock_device_parent_child_endpoints_non_sequential.id, clusters.LevelControl.attributes.Options:write(mock_device_parent_child_endpoints_non_sequential, child2_ep_non_sequential, clusters.LevelControl.types.OptionsBitmap.EXECUTE_IF_OFF)})
258258
test.socket.matter:__expect_send({mock_device_parent_child_endpoints_non_sequential.id, clusters.ColorControl.attributes.Options:write(mock_device_parent_child_endpoints_non_sequential, child2_ep_non_sequential, clusters.ColorControl.types.OptionsBitmap.EXECUTE_IF_OFF)})
259-
mock_device_parent_child_endpoints_non_sequential:expect_metadata_update({ profile = "light-binary" })
259+
mock_device_parent_child_endpoints_non_sequential:expect_metadata_update({ profile = "switch-binary" })
260260
mock_device_parent_child_endpoints_non_sequential:expect_metadata_update({ provisioning_state = "PROVISIONED" })
261261

262262
for _, child in pairs(mock_children_non_sequential) do

0 commit comments

Comments
 (0)