Skip to content

Commit dd5cfa2

Browse files
committed
add switch-fan profile
1 parent 6a4aab5 commit dd5cfa2

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: switch-fan
2+
components:
3+
- id: main
4+
capabilities:
5+
- id: switch
6+
version: 1
7+
- id: fanMode
8+
version: 1
9+
- id: fanSpeedPercent
10+
version: 1
11+
- id: firmwareUpdate
12+
version: 1
13+
- id: refresh
14+
version: 1
15+
categories:
16+
- name: Switch

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,13 @@ function DeviceConfiguration.match_profile(driver, device)
180180
if switch_utils.tbl_contains(server_onoff_ep_ids, default_endpoint_id) then
181181
updated_profile = SwitchDeviceConfiguration.assign_profile_for_onoff_ep(device, default_endpoint_id)
182182
local generic_profile = function(s) return string.find(updated_profile or "", s, 1, true) end
183-
if generic_profile("plug-binary") or generic_profile("plug-level") then
183+
if (generic_profile("plug-binary") or generic_profile("light-binary")) and #device:get_endpoints(clusters.FanControl.ID) > 0 then
184+
updated_profile = "switch-fan"
185+
elseif generic_profile("light-color-level") and #device:get_endpoints(clusters.FanControl.ID) > 0 then
186+
updated_profile = "light-color-level-fan"
187+
elseif generic_profile("light-level") and #device:get_endpoints(clusters.OccupancySensing.ID) > 0 then
188+
updated_profile = "light-level-motion"
189+
elseif generic_profile("plug-binary") or generic_profile("plug-level") then
184190
if switch_utils.check_switch_category_vendor_overrides(device) then
185191
updated_profile = string.gsub(updated_profile, "plug", "switch")
186192
else
@@ -189,10 +195,6 @@ function DeviceConfiguration.match_profile(driver, device)
189195
if #embedded_cluster_utils.get_endpoints(device, clusters.ElectricalEnergyMeasurement.ID) > 0 then electrical_tags = electrical_tags .. "-energy-powerConsumption" end
190196
if electrical_tags ~= "" then updated_profile = string.gsub(updated_profile, "-binary", "") .. electrical_tags end
191197
end
192-
elseif generic_profile("light-color-level") and #device:get_endpoints(clusters.FanControl.ID) > 0 then
193-
updated_profile = "light-color-level-fan"
194-
elseif generic_profile("light-level") and #device:get_endpoints(clusters.OccupancySensing.ID) > 0 then
195-
updated_profile = "light-level-motion"
196198
elseif generic_profile("light-level-colorTemperature") or generic_profile("light-color-level") then
197199
-- ignore attempts to dynamically profile light-level-colorTemperature and light-color-level devices for now, since
198200
-- these may lose fingerprinted Kelvin ranges when dynamically profiled.

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

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,44 @@ local mock_device = test.mock_device.build_test_matter_device({
5454
}
5555
})
5656

57+
local mock_device_switch = test.mock_device.build_test_matter_device({
58+
label = "Matter Switch",
59+
profile = t_utils.get_profile_definition("switch-fan.yml"),
60+
manufacturer_info = {
61+
vendor_id = 0x0000,
62+
product_id = 0x0000,
63+
},
64+
endpoints = {
65+
{
66+
endpoint_id = 0,
67+
clusters = {
68+
{cluster_id = clusters.Basic.ID, cluster_type = "SERVER"},
69+
},
70+
device_types = {
71+
{device_type_id = 0x0016, device_type_revision = 1} -- RootNode
72+
}
73+
},
74+
{
75+
endpoint_id = mock_device_ep1,
76+
clusters = {
77+
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
78+
},
79+
device_types = {
80+
{device_type_id = 0x010A, device_type_revision = 2} -- On Off Plugin Unit
81+
}
82+
},
83+
{
84+
endpoint_id = mock_device_ep2,
85+
clusters = {
86+
{cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 15},
87+
},
88+
device_types = {
89+
{device_type_id = 0x002B, device_type_revision = 1,} -- Fan
90+
}
91+
}
92+
}
93+
})
94+
5795
local CLUSTER_SUBSCRIBE_LIST ={
5896
clusters.OnOff.attributes.OnOff,
5997
clusters.LevelControl.attributes.CurrentLevel,
@@ -72,6 +110,13 @@ local CLUSTER_SUBSCRIBE_LIST ={
72110
clusters.FanControl.attributes.PercentCurrent,
73111
}
74112

113+
local SWITCH_CLUSTER_SUBSCRIBE_LIST ={
114+
clusters.OnOff.attributes.OnOff,
115+
clusters.FanControl.attributes.FanModeSequence,
116+
clusters.FanControl.attributes.FanMode,
117+
clusters.FanControl.attributes.PercentCurrent,
118+
}
119+
75120
local function test_init()
76121
test.disable_startup_messages()
77122
test.mock_device.add_test_device(mock_device)
@@ -95,6 +140,31 @@ end
95140

96141
test.set_test_init_function(test_init)
97142

143+
local function test_init_switch()
144+
test.disable_startup_messages()
145+
test.mock_device.add_test_device(mock_device_switch)
146+
local subscribe_request = SWITCH_CLUSTER_SUBSCRIBE_LIST[1]:subscribe(mock_device_switch)
147+
for i, clus in ipairs(SWITCH_CLUSTER_SUBSCRIBE_LIST) do
148+
if i > 1 then subscribe_request:merge(clus:subscribe(mock_device_switch)) end
149+
end
150+
151+
test.socket.device_lifecycle:__queue_receive({ mock_device_switch.id, "added" })
152+
test.socket.matter:__expect_send({mock_device_switch.id, subscribe_request})
153+
154+
test.socket.device_lifecycle:__queue_receive({ mock_device_switch.id, "init" })
155+
test.socket.matter:__expect_send({mock_device_switch.id, subscribe_request})
156+
157+
test.socket.device_lifecycle:__queue_receive({ mock_device_switch.id, "doConfigure" })
158+
mock_device_switch:expect_metadata_update({ profile = "switch-fan" })
159+
mock_device_switch:expect_metadata_update({ provisioning_state = "PROVISIONED" })
160+
end
161+
162+
test.register_message_test(
163+
"On Off Plug In Unit + Fan should profile as switch-fan",
164+
{},
165+
{ test_init = test_init_switch }
166+
)
167+
98168
test.register_coroutine_test(
99169
"Switch capability should send the appropriate commands", function()
100170
test.socket.capability:__queue_receive(

0 commit comments

Comments
 (0)