Skip to content

Commit

Permalink
Sort endpoints before initializing switch (#1657)
Browse files Browse the repository at this point in the history
Sort endpoints before initializing switch
  • Loading branch information
nickolas-deboom authored Sep 30, 2024
1 parent b2893b0 commit 9a008a5
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 1 deletion.
2 changes: 2 additions & 0 deletions drivers/SmartThings/matter-switch/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ end
local function initialize_switch(driver, device)
local switch_eps = device:get_endpoints(clusters.OnOff.ID)
local button_eps = device:get_endpoints(clusters.Switch.ID, {feature_bitmap=clusters.Switch.types.Feature.MOMENTARY_SWITCH})
table.sort(switch_eps)
table.sort(button_eps)

local profile_name = nil

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,75 @@ local mock_device = test.mock_device.build_test_matter_device({
}
})

local child1_ep_non_sequential = 50
local child2_ep_non_sequential = 30
local child3_ep_non_sequential = 40

local mock_device_parent_child_endpoints_non_sequential = test.mock_device.build_test_matter_device({
label = "Matter Switch",
profile = t_utils.get_profile_definition("light-level-colorTemperature.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 = parent_ep,
clusters = {
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
},
device_types = {
{device_type_id = 0x0100, device_type_revision = 2} -- On/Off Light
}
},
{
endpoint_id = child1_ep_non_sequential,
clusters = {
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
{cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER", feature_map = 2}
},
device_types = {
{device_type_id = 0x0100, device_type_revision = 2}, -- On/Off Light
{device_type_id = 0x0101, device_type_revision = 2} -- Dimmable Light
}
},
{
endpoint_id = child2_ep_non_sequential,
clusters = {
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
{cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER", feature_map = 2},
{cluster_id = clusters.ColorControl.ID, cluster_type = "BOTH", feature_map = 30},
},
device_types = {
{device_type_id = 0x010D, device_type_revision = 2} -- Extended Color Light
}
},
{
endpoint_id = child3_ep_non_sequential,
clusters = {
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
{cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER", feature_map = 2},
{cluster_id = clusters.ColorControl.ID, cluster_type = "BOTH", feature_map = 30},
},
device_types = {
{device_type_id = 0x010D, device_type_revision = 2} -- Extended Color Light
}
},
}
})

local child_profiles = {
[child1_ep] = t_utils.get_profile_definition("light-level.yml"),
[child2_ep] = t_utils.get_profile_definition("light-color-level.yml")
[child2_ep] = t_utils.get_profile_definition("light-color-level.yml"),
}

local mock_children = {}
Expand Down Expand Up @@ -138,6 +204,77 @@ local function test_init()
})
end

local child_profiles_non_sequential = {
[child1_ep_non_sequential] = t_utils.get_profile_definition("light-level.yml"),
[child2_ep_non_sequential] = t_utils.get_profile_definition("light-color-level.yml"),
[child3_ep_non_sequential] = t_utils.get_profile_definition("light-color-level.yml"),
}

local mock_children_non_sequential = {}
for i, endpoint in ipairs(mock_device_parent_child_endpoints_non_sequential.endpoints) do
if endpoint.endpoint_id ~= parent_ep and endpoint.endpoint_id ~= 0 then
local child_data = {
profile = child_profiles_non_sequential[endpoint.endpoint_id],
device_network_id = string.format("%s:%d", mock_device_parent_child_endpoints_non_sequential.id, endpoint.endpoint_id),
parent_device_id = mock_device_parent_child_endpoints_non_sequential.id,
parent_assigned_child_key = string.format("%d", endpoint.endpoint_id)
}
mock_children_non_sequential[endpoint.endpoint_id] = test.mock_device.build_test_child_device(child_data)
end
end

local function test_init_parent_child_endpoints_non_sequential()
local cluster_subscribe_list = {
clusters.OnOff.attributes.OnOff,
clusters.LevelControl.attributes.CurrentLevel,
clusters.LevelControl.attributes.MaxLevel,
clusters.LevelControl.attributes.MinLevel,
clusters.ColorControl.attributes.ColorTemperatureMireds,
clusters.ColorControl.attributes.ColorTempPhysicalMaxMireds,
clusters.ColorControl.attributes.ColorTempPhysicalMinMireds,
clusters.ColorControl.attributes.CurrentHue,
clusters.ColorControl.attributes.CurrentSaturation,
clusters.ColorControl.attributes.CurrentX,
clusters.ColorControl.attributes.CurrentY
}
local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_parent_child_endpoints_non_sequential)
for i, cluster in ipairs(cluster_subscribe_list) do
if i > 1 then
subscribe_request:merge(cluster:subscribe(mock_device_parent_child_endpoints_non_sequential))
end
end
test.socket.matter:__expect_send({mock_device_parent_child_endpoints_non_sequential.id, subscribe_request})

test.mock_device.add_test_device(mock_device_parent_child_endpoints_non_sequential)
for _, child in pairs(mock_children_non_sequential) do
test.mock_device.add_test_device(child)
end

mock_device_parent_child_endpoints_non_sequential:expect_device_create({
type = "EDGE_CHILD",
label = "Matter Switch 2",
profile = "light-color-level",
parent_device_id = mock_device_parent_child_endpoints_non_sequential.id,
parent_assigned_child_key = string.format("%d", child2_ep_non_sequential)
})

mock_device_parent_child_endpoints_non_sequential:expect_device_create({
type = "EDGE_CHILD",
label = "Matter Switch 3",
profile = "light-color-level",
parent_device_id = mock_device_parent_child_endpoints_non_sequential.id,
parent_assigned_child_key = string.format("%d", child3_ep_non_sequential)
})

mock_device_parent_child_endpoints_non_sequential:expect_device_create({
type = "EDGE_CHILD",
label = "Matter Switch 4",
profile = "light-level",
parent_device_id = mock_device_parent_child_endpoints_non_sequential.id,
parent_assigned_child_key = string.format("%d", child1_ep_non_sequential)
})
end

test.set_test_init_function(test_init)

test.register_message_test(
Expand Down Expand Up @@ -494,4 +631,11 @@ test.register_message_test(
}
)

test.register_coroutine_test(
"Test child devices are created in order of their endpoints",
function()
end,
{ test_init = test_init_parent_child_endpoints_non_sequential }
)

test.run_registered_tests()

0 comments on commit 9a008a5

Please sign in to comment.