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
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,9 @@ function CameraDeviceConfiguration.match_profile(device)
clus_has_feature(clusters.CameraAvSettingsUserLevelManagement.types.Feature.MECHANICAL_ZOOM) then
table.insert(main_component_capabilities, capabilities.mechanicalPanTiltZoom.ID)
end
elseif ep_cluster.cluster_id == clusters.ZoneManagement.ID and has_server_cluster_type(ep_cluster) then
table.insert(main_component_capabilities, capabilities.zoneManagement.ID)
elseif ep_cluster.cluster_id == clusters.ZoneManagement.ID and has_server_cluster_type(ep_cluster) and
clusters.ZoneManagement.are_features_supported(clusters.ZoneManagement.types.Feature.USER_DEFINED, ep_cluster.feature_map) then
table.insert(main_component_capabilities, capabilities.zoneManagement.ID)
elseif ep_cluster.cluster_id == clusters.OccupancySensing.ID and has_server_cluster_type(ep_cluster) then
table.insert(main_component_capabilities, capabilities.motionSensor.ID)
elseif ep_cluster.cluster_id == clusters.WebRTCTransportProvider.ID and has_server_cluster_type(ep_cluster) then
Expand Down
180 changes: 158 additions & 22 deletions drivers/SmartThings/matter-switch/src/test/test_matter_camera.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ local mock_device = test.mock_device.build_test_matter_device({
{
cluster_id = clusters.ZoneManagement.ID,
feature_map = clusters.ZoneManagement.types.Feature.TWO_DIMENSIONAL_CARTESIAN_ZONE |
clusters.ZoneManagement.types.Feature.PER_ZONE_SENSITIVITY,
clusters.ZoneManagement.types.Feature.PER_ZONE_SENSITIVITY |
clusters.ZoneManagement.types.Feature.USER_DEFINED,
cluster_type = "SERVER"
},
{
Expand Down Expand Up @@ -120,6 +121,46 @@ local mock_device = test.mock_device.build_test_matter_device({
})

local mock_device_no_per_zone_sensitivity = test.mock_device.build_test_matter_device({
profile = t_utils.get_profile_definition("camera.yml"),
manufacturer_info = {vendor_id = 0x0000, product_id = 0x0000},
matter_version = {hardware = 1, software = 1},
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 = CAMERA_EP,
clusters = {
{
cluster_id = clusters.CameraAvStreamManagement.ID,
feature_map = clusters.CameraAvStreamManagement.types.Feature.VIDEO,
cluster_type = "SERVER"
},
{
cluster_id = clusters.ZoneManagement.ID,
feature_map = clusters.ZoneManagement.types.Feature.TWO_DIMENSIONAL_CARTESIAN_ZONE |
clusters.ZoneManagement.types.Feature.USER_DEFINED,
cluster_type = "SERVER"
},
{
cluster_id = clusters.PushAvStreamTransport.ID,
cluster_type = "SERVER"
}
},
device_types = {
{device_type_id = 0x0142, device_type_revision = 1} -- Camera
}
}
}
})

local mock_device_no_user_defined_zone = test.mock_device.build_test_matter_device({
profile = t_utils.get_profile_definition("camera.yml"),
manufacturer_info = {vendor_id = 0x0000, product_id = 0x0000},
matter_version = {hardware = 1, software = 1},
Expand Down Expand Up @@ -229,6 +270,26 @@ local function test_init_no_per_zone_sensitivity()
mock_device_no_per_zone_sensitivity:expect_metadata_update({ provisioning_state = "PROVISIONED" })
end

local subscribe_request_no_user_defined_zone
local subscribed_attributes_no_user_defined_zone = {
clusters.CameraAvStreamManagement.attributes.AttributeList,
}

local function test_init_no_user_defined_zone()
test.mock_device.add_test_device(mock_device_no_user_defined_zone)
test.socket.device_lifecycle:__queue_receive({ mock_device_no_user_defined_zone.id, "added" })
test.socket.device_lifecycle:__queue_receive({ mock_device_no_user_defined_zone.id, "init" })
subscribe_request_no_user_defined_zone = subscribed_attributes_no_user_defined_zone[1]:subscribe(mock_device_no_user_defined_zone)
subscribe_request_no_user_defined_zone:merge(cluster_base.subscribe(mock_device_no_user_defined_zone, nil, camera_fields.CameraAVSMFeatureMapAttr.cluster, camera_fields.CameraAVSMFeatureMapAttr.ID))
subscribe_request_no_user_defined_zone:merge(cluster_base.subscribe(mock_device_no_user_defined_zone, nil, camera_fields.ZoneManagementFeatureMapAttr.cluster, camera_fields.ZoneManagementFeatureMapAttr.ID))
for i, attr in ipairs(subscribed_attributes_no_user_defined_zone) do
if i > 1 then subscribe_request_no_user_defined_zone:merge(attr:subscribe(mock_device_no_user_defined_zone)) end
end
test.socket.matter:__expect_send({mock_device_no_user_defined_zone.id, subscribe_request_no_user_defined_zone})
test.socket.device_lifecycle:__queue_receive({ mock_device_no_user_defined_zone.id, "doConfigure" })
mock_device_no_user_defined_zone:expect_metadata_update({ provisioning_state = "PROVISIONED" })
end

local additional_subscribed_attributes = {
clusters.CameraAvStreamManagement.attributes.HDRModeEnabled,
clusters.CameraAvStreamManagement.attributes.ImageRotation,
Expand Down Expand Up @@ -485,6 +546,69 @@ local function update_device_profile_no_per_zone_sensitivity()
test.socket.matter:__expect_send({mock_device_no_per_zone_sensitivity.id, subscribe_request_no_per_zone_sensitivity})
end

local additional_subscribed_attributes_no_user_defined_zone = {
clusters.CameraAvStreamManagement.attributes.StatusLightBrightness,
clusters.CameraAvStreamManagement.attributes.StatusLightEnabled,
clusters.CameraAvStreamManagement.attributes.RateDistortionTradeOffPoints,
clusters.CameraAvStreamManagement.attributes.MaxEncodedPixelRate,
clusters.CameraAvStreamManagement.attributes.VideoSensorParams,
clusters.CameraAvStreamManagement.attributes.AllocatedVideoStreams,
clusters.CameraAvSettingsUserLevelManagement.attributes.DPTZStreams,
clusters.CameraAvStreamManagement.attributes.MinViewportResolution,
clusters.CameraAvStreamManagement.attributes.Viewport,
clusters.CameraAvStreamManagement.attributes.AttributeList,
clusters.OnOff.attributes.OnOff,
}

local function update_device_profile_no_user_defined_zone()
local expected_metadata = {
optional_component_capabilities = {
{
"main",
{
"videoCapture2",
"cameraViewportSettings",
"videoStreamSettings",
}
},
{
"statusLed",
{
"switch",
"mode"
}
}
},
profile = "camera"
}

test.socket.matter:__queue_receive({
mock_device_no_user_defined_zone.id,
clusters.CameraAvStreamManagement.attributes.AttributeList:build_test_report_data(mock_device_no_user_defined_zone, CAMERA_EP, {
uint32(clusters.CameraAvStreamManagement.attributes.StatusLightEnabled.ID),
uint32(clusters.CameraAvStreamManagement.attributes.StatusLightBrightness.ID)
})
})
mock_device_no_user_defined_zone:expect_metadata_update(expected_metadata)
test.wait_for_events()
local updated_device_profile = t_utils.get_profile_definition(
"camera.yml", {enabled_optional_capabilities = expected_metadata.optional_component_capabilities}
)
test.wait_for_events()
test.socket.device_lifecycle:__queue_receive(mock_device_no_user_defined_zone:generate_info_changed({ profile = updated_device_profile }))

test.socket.capability:__expect_send(
mock_device_no_user_defined_zone:generate_test_message("main", capabilities.videoStreamSettings.supportedFeatures(
{"liveStreaming", "clipRecording", "perStreamViewports"}
))
)

for _, attr in ipairs(additional_subscribed_attributes_no_user_defined_zone) do
subscribe_request_no_user_defined_zone:merge(attr:subscribe(mock_device_no_user_defined_zone))
end
test.socket.matter:__expect_send({mock_device_no_user_defined_zone.id, subscribe_request_no_user_defined_zone})
end

-- Matter Handler UTs

test.register_coroutine_test(
Expand Down Expand Up @@ -3185,49 +3309,61 @@ test.register_coroutine_test(
)

test.register_coroutine_test(
"Zone Management trigger reports should omit sensitivity when per-zone sensitivity is unsupported, even if provided by client",
"Camera profile should include zoneManagement when USER_DEFINED feature is present",
function()
update_device_profile_no_per_zone_sensitivity()
test.wait_for_events()
-- Create a trigger with
end,
{
test_init = test_init_no_per_zone_sensitivity,
min_api_version = 17
}
)

test.register_coroutine_test(
"Camera profile should not include zoneManagement when USER_DEFINED feature is missing",
function()
update_device_profile_no_user_defined_zone()
test.wait_for_events()
end,
{
test_init = test_init_no_user_defined_zone,
min_api_version = 17
}
)

test.register_coroutine_test(
"Zone Management trigger command should be ignored when zoneManagement capability is not exposed",
function()
update_device_profile_no_user_defined_zone()
test.wait_for_events()
test.socket.capability:__queue_receive({
mock_device_no_per_zone_sensitivity.id,
mock_device_no_user_defined_zone.id,
{ capability = "zoneManagement", component = "main", command = "createOrUpdateTrigger", args = {
1, 10, 3, 15, 3, 5
}}
})
test.socket.matter:__expect_send({
mock_device_no_per_zone_sensitivity.id, clusters.ZoneManagement.server.commands.CreateOrUpdateTrigger(mock_device_no_per_zone_sensitivity, CAMERA_EP, {
zone_id = 1,
initial_duration = 10,
augmentation_duration = 3,
max_duration = 15,
blind_duration = 3
})
})
test.wait_for_events()
end,
{
test_init = test_init_no_per_zone_sensitivity,
test_init = test_init_no_user_defined_zone,
min_api_version = 17
}
)

test.register_coroutine_test(
"Zone Management setSensitivity command should handle global sensitivity when per-zone sensitivity is unsupported",
"Zone Management setSensitivity command should be ignored when zoneManagement capability is not exposed",
function()
update_device_profile_no_per_zone_sensitivity()
update_device_profile_no_user_defined_zone()
test.wait_for_events()
test.socket.capability:__queue_receive({
mock_device_no_per_zone_sensitivity.id,
mock_device_no_user_defined_zone.id,
{ capability = "zoneManagement", component = "main", command = "setSensitivity", args = { 5 } }
})
test.socket.matter:__expect_send({
mock_device_no_per_zone_sensitivity.id,
clusters.ZoneManagement.attributes.Sensitivity:write(mock_device_no_per_zone_sensitivity, CAMERA_EP, 5)
})
test.wait_for_events()
end,
{
test_init = test_init_no_per_zone_sensitivity,
test_init = test_init_no_user_defined_zone,
min_api_version = 17
}
)
Expand Down
Loading