Skip to content

Commit

Permalink
Merge pull request #1585 from SmartThingsCommunity/main
Browse files Browse the repository at this point in the history
rolling up main to beta
  • Loading branch information
ctowns authored Aug 19, 2024
2 parents 5985405 + cb1f617 commit 1bd918b
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 1 deletion.
19 changes: 18 additions & 1 deletion drivers/SmartThings/matter-switch/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ local COLOR_TEMPERATURE_KELVIN_MIN = 1000
local COLOR_TEMPERATURE_MIRED_MAX = MIRED_KELVIN_CONVERSION_CONSTANT/COLOR_TEMPERATURE_KELVIN_MIN
local COLOR_TEMPERATURE_MIRED_MIN = MIRED_KELVIN_CONVERSION_CONSTANT/COLOR_TEMPERATURE_KELVIN_MAX
local SWITCH_LEVEL_LIGHTING_MIN = 1
local CURRENT_HUESAT_ATTR_MIN = 0
local CURRENT_HUESAT_ATTR_MAX = 254

local SWITCH_INITIALIZED = "__switch_intialized"
-- COMPONENT_TO_ENDPOINT_MAP is here only to perserve the endpoint mapping for
Expand Down Expand Up @@ -66,6 +68,11 @@ local device_type_profile_map = {
[ON_OFF_DIMMER_SWITCH_ID] = "switch-level",
[ON_OFF_COLOR_DIMMER_SWITCH_ID] = "switch-color-level",
}

local child_device_profile_overrides = {
{ vendor_id = 0x1321, product_id = 0x000D, child_profile = "switch-binary" },
}

local detect_matter_thing

local function get_field_for_endpoint(device, field, endpoint)
Expand All @@ -77,7 +84,7 @@ local function set_field_for_endpoint(device, field, endpoint, value, additional
end

local function convert_huesat_st_to_matter(val)
return math.floor((val * 0xFE) / 100.0 + 0.5)
return utils.clamp_value(math.floor((val * 0xFE) / 100.0 + 0.5), CURRENT_HUESAT_ATTR_MIN, CURRENT_HUESAT_ATTR_MAX)
end

local function mired_to_kelvin(value)
Expand Down Expand Up @@ -109,6 +116,16 @@ end

local function assign_child_profile(device, child_ep)
local profile

-- check if device has an overriden child profile that differs from the profile
-- that would match the child's device type
for _, fingerprint in ipairs(child_device_profile_overrides) do
if device.manufacturer_info.vendor_id == fingerprint.vendor_id and
device.manufacturer_info.product_id == fingerprint.product_id then
return fingerprint.child_profile
end
end

for _, ep in ipairs(device.endpoints) do
if ep.endpoint_id == child_ep then
-- Some devices report multiple device types which are a subset of
Expand Down
68 changes: 68 additions & 0 deletions drivers/SmartThings/matter-switch/src/test/test_matter_switch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,74 @@ test.register_message_test(
}
)

hue = 0xFE
sat = 0xFE
test.register_message_test(
"Set color command should clamp invalid huesat values",
{
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.ColorControl.attributes.ColorCapabilities:build_test_report_data(mock_device, 1, 0x01)
}
},
{
channel = "capability",
direction = "receive",
message = {
mock_device.id,
{ capability = "colorControl", component = "main", command = "setColor", args = { { hue = 110, saturation = 110 } } }
}
},
{
channel = "matter",
direction = "send",
message = {
mock_device.id,
clusters.ColorControl.server.commands.MoveToHueAndSaturation(mock_device, 1, hue, sat, TRANSITION_TIME, OPTIONS_MASK, OPTIONS_OVERRIDE)
}
},
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.ColorControl.server.commands.MoveToHueAndSaturation:build_test_command_response(mock_device, 1)
}
},
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.ColorControl.attributes.CurrentHue:build_test_report_data(mock_device, 1, hue)
}
},
{
channel = "capability",
direction = "send",
message = mock_device:generate_test_message("main", capabilities.colorControl.hue(100))
},
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.ColorControl.attributes.CurrentSaturation:build_test_report_data(mock_device, 1, sat)
}
},
{
channel = "capability",
direction = "send",
message = mock_device:generate_test_message("main", capabilities.colorControl.saturation(100))
}
}
)

hue = math.floor((50 * 0xFE) / 100.0 + 0.5)
sat = math.floor((50 * 0xFE) / 100.0 + 0.5)
test.register_message_test(
"Set Hue command should send MoveToHue",
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ local capabilities = require "st.capabilities"
local clusters = require "st.matter.clusters"

local child_profile = t_utils.get_profile_definition("plug-binary.yml")
local child_profile_override = t_utils.get_profile_definition("switch-binary.yml")
local parent_ep = 10
local child1_ep = 20
local child2_ep = 30
Expand Down Expand Up @@ -70,6 +71,53 @@ local mock_device = test.mock_device.build_test_matter_device({
}
})

local mock_device_child_profile_override = test.mock_device.build_test_matter_device({
label = "Matter Switch",
profile = t_utils.get_profile_definition("switch-binary.yml"),
manufacturer_info = {
vendor_id = 0x1321,
product_id = 0x000D,
},
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 = 0x010A, device_type_revision = 2} -- On/Off Plug
}
},
{
endpoint_id = child1_ep,
clusters = {
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
},
device_types = {
{device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug
}
},
{
endpoint_id = child2_ep,
clusters = {
{cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"},
},
device_types = {
{device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug
}
},
}
})

local mock_children = {}
for i, endpoint in ipairs(mock_device.endpoints) do
if endpoint.endpoint_id ~= parent_ep and endpoint.endpoint_id ~= 0 then
Expand Down Expand Up @@ -112,6 +160,47 @@ local function test_init()
})
end

local mock_children_child_profile_override = {}
for i, endpoint in ipairs(mock_device_child_profile_override.endpoints) do
if endpoint.endpoint_id ~= parent_ep and endpoint.endpoint_id ~= 0 then
local child_data = {
profile = child_profile_override,
device_network_id = string.format("%s:%d", mock_device_child_profile_override.id, endpoint.endpoint_id),
parent_device_id = mock_device_child_profile_override.id,
parent_assigned_child_key = string.format("%d", endpoint.endpoint_id)
}
mock_children_child_profile_override[endpoint.endpoint_id] = test.mock_device.build_test_child_device(child_data)
end
end
local function test_init_child_profile_override()
local cluster_subscribe_list = {
clusters.OnOff.attributes.OnOff,
}
local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_child_profile_override)
test.socket.matter:__expect_send({mock_device_child_profile_override.id, subscribe_request})

test.mock_device.add_test_device(mock_device_child_profile_override)
for _, child in pairs(mock_children_child_profile_override) do
test.mock_device.add_test_device(child)
end

mock_device:expect_device_create({
type = "EDGE_CHILD",
label = "Matter Switch 2",
profile = "switch-binary",
parent_device_id = mock_device_child_profile_override.id,
parent_assigned_child_key = string.format("%d", child1_ep)
})

mock_device:expect_device_create({
type = "EDGE_CHILD",
label = "Matter Switch 3",
profile = "switch-binary",
parent_device_id = mock_device_child_profile_override.id,
parent_assigned_child_key = string.format("%d", child2_ep)
})
end

test.set_test_init_function(test_init)

test.register_message_test(
Expand Down Expand Up @@ -228,4 +317,10 @@ test.register_coroutine_test(
end
)

test.register_coroutine_test(
"Child device profiles should be overriden for specific devices", function()
end,
{ test_init = test_init_child_profile_override }
)

test.run_registered_tests()

0 comments on commit 1bd918b

Please sign in to comment.