Skip to content
Open
Show file tree
Hide file tree
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
16 changes: 16 additions & 0 deletions drivers/SmartThings/matter-switch/profiles/switch-fan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: switch-fan
components:
- id: main
capabilities:
- id: switch
version: 1
- id: fanMode
version: 1
- id: fanSpeedPercent
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: Switch
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,44 @@ local mock_device = test.mock_device.build_test_matter_device({
}
})

local mock_device_switch = test.mock_device.build_test_matter_device({
label = "Matter Switch",
profile = t_utils.get_profile_definition("switch-fan.yml"),
manufacturer_info = {
vendor_id = 0x0000,
product_id = 0x0000,
},
endpoints = {
{
endpoint_id = 0,
clusters = {
{cluster_id = clusters.Basic.ID, cluster_type = "SERVER"},
},
device_types = {
{device_type_id = 0x0016, device_type_revision = 1} -- RootNode
}
},
{
endpoint_id = mock_device_ep1,
clusters = {
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
},
device_types = {
{device_type_id = 0x010A, device_type_revision = 2} -- On Off Plugin Unit
}
},
{
endpoint_id = mock_device_ep2,
clusters = {
{cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 15},
},
device_types = {
{device_type_id = 0x002B, device_type_revision = 1,} -- Fan
}
}
}
})

local CLUSTER_SUBSCRIBE_LIST ={
clusters.OnOff.attributes.OnOff,
clusters.LevelControl.attributes.CurrentLevel,
Expand All @@ -83,6 +121,13 @@ local CLUSTER_SUBSCRIBE_LIST ={
clusters.FanControl.attributes.PercentCurrent,
}

local SWITCH_CLUSTER_SUBSCRIBE_LIST ={
clusters.OnOff.attributes.OnOff,
clusters.FanControl.attributes.FanModeSequence,
clusters.FanControl.attributes.FanMode,
clusters.FanControl.attributes.PercentCurrent,
}

local function test_init()
test.disable_startup_messages()
test.mock_device.add_test_device(mock_device)
Expand All @@ -104,6 +149,31 @@ end

test.set_test_init_function(test_init)

local function test_init_switch()
test.disable_startup_messages()
test.mock_device.add_test_device(mock_device_switch)
local subscribe_request = SWITCH_CLUSTER_SUBSCRIBE_LIST[1]:subscribe(mock_device_switch)
for i, clus in ipairs(SWITCH_CLUSTER_SUBSCRIBE_LIST) do
if i > 1 then subscribe_request:merge(clus:subscribe(mock_device_switch)) end
end

test.socket.device_lifecycle:__queue_receive({ mock_device_switch.id, "added" })
test.socket.matter:__expect_send({mock_device_switch.id, subscribe_request})

test.socket.device_lifecycle:__queue_receive({ mock_device_switch.id, "init" })
test.socket.matter:__expect_send({mock_device_switch.id, subscribe_request})

test.socket.device_lifecycle:__queue_receive({ mock_device_switch.id, "doConfigure" })
mock_device_switch:expect_metadata_update({ profile = "switch-fan" })
mock_device_switch:expect_metadata_update({ provisioning_state = "PROVISIONED" })
end

test.register_message_test(
"On Off Plug In Unit + Fan should profile as switch-fan",
{},
{ test_init = test_init_switch }
)

test.register_coroutine_test(
"Switch capability should send the appropriate commands", function()
test.socket.capability:__queue_receive(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,13 @@ function DeviceConfiguration.match_profile(driver, device)
if switch_utils.tbl_contains(server_onoff_ep_ids, default_endpoint_id) then
updated_profile = SwitchDeviceConfiguration.assign_profile_for_onoff_ep(device, default_endpoint_id)
local generic_profile = function(s) return string.find(updated_profile or "", s, 1, true) end
if generic_profile("plug-binary") or generic_profile("plug-level") then
if (generic_profile("plug-binary") or generic_profile("light-binary")) and #device:get_endpoints(clusters.FanControl.ID) > 0 then
updated_profile = "switch-fan"
elseif generic_profile("light-color-level") and #device:get_endpoints(clusters.FanControl.ID) > 0 then
updated_profile = "light-color-level-fan"
elseif generic_profile("light-level") and #device:get_endpoints(clusters.OccupancySensing.ID) > 0 then
updated_profile = "light-level-motion"
elseif generic_profile("plug-binary") or generic_profile("plug-level") then
if switch_utils.check_switch_category_vendor_overrides(device) then
updated_profile = string.gsub(updated_profile, "plug", "switch")
else
Expand All @@ -186,10 +192,6 @@ function DeviceConfiguration.match_profile(driver, device)
if #embedded_cluster_utils.get_endpoints(device, clusters.ElectricalEnergyMeasurement.ID) > 0 then electrical_tags = electrical_tags .. "-energy-powerConsumption" end
if electrical_tags ~= "" then updated_profile = string.gsub(updated_profile, "-binary", "") .. electrical_tags end
end
elseif generic_profile("light-color-level") and #device:get_endpoints(clusters.FanControl.ID) > 0 then
updated_profile = "light-color-level-fan"
elseif generic_profile("light-level") and #device:get_endpoints(clusters.OccupancySensing.ID) > 0 then
updated_profile = "light-level-motion"
elseif generic_profile("light-level-colorTemperature") or generic_profile("light-color-level") then
-- ignore attempts to dynamically profile light-level-colorTemperature and light-color-level devices for now, since
-- these may lose fingerprinted Kelvin ranges when dynamically profiled.
Expand Down
Loading