Skip to content

Commit b7b4586

Browse files
committed
Matter Camera: Prevent duplicate zones in triggeredZones report
1 parent dd871ed commit b7b4586

2 files changed

Lines changed: 67 additions & 7 deletions

File tree

drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_handlers/event_handlers.lua

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,43 @@ local switch_utils = require "switch_utils.utils"
77

88
local CameraEventHandlers = {}
99

10+
local function has_triggered_zone(triggered_zones, zone_id)
11+
for _, zone in ipairs(triggered_zones or {}) do
12+
if zone.zoneId == zone_id then
13+
return true
14+
end
15+
end
16+
return false
17+
end
18+
1019
function CameraEventHandlers.zone_triggered_handler(driver, device, ib, response)
1120
local triggered_zones = device:get_field(camera_fields.TRIGGERED_ZONES) or {}
12-
if not switch_utils.tbl_contains(triggered_zones, ib.data.elements.zone.value) then
13-
table.insert(triggered_zones, {zoneId = ib.data.elements.zone.value})
21+
local zone_id = ib.data.elements.zone.value
22+
if not has_triggered_zone(triggered_zones, zone_id) then
23+
table.insert(triggered_zones, {zoneId = zone_id})
1424
device:set_field(camera_fields.TRIGGERED_ZONES, triggered_zones)
1525
device:emit_event_for_endpoint(ib, capabilities.zoneManagement.triggeredZones(triggered_zones))
1626
end
1727
end
1828

1929
function CameraEventHandlers.zone_stopped_handler(driver, device, ib, response)
2030
local triggered_zones = device:get_field(camera_fields.TRIGGERED_ZONES) or {}
21-
for i, v in pairs(triggered_zones) do
22-
if v.zoneId == ib.data.elements.zone.value then
23-
table.remove(triggered_zones, i)
24-
device:set_field(camera_fields.TRIGGERED_ZONES, triggered_zones)
25-
device:emit_event_for_endpoint(ib, capabilities.zoneManagement.triggeredZones(triggered_zones))
31+
local zone_id = ib.data.elements.zone.value
32+
local updated_triggered_zones = {}
33+
local zone_removed = false
34+
35+
for _, zone in ipairs(triggered_zones) do
36+
if zone.zoneId ~= zone_id then
37+
table.insert(updated_triggered_zones, zone)
38+
else
39+
zone_removed = true
2640
end
2741
end
42+
43+
if zone_removed then
44+
device:set_field(camera_fields.TRIGGERED_ZONES, updated_triggered_zones)
45+
device:emit_event_for_endpoint(ib, capabilities.zoneManagement.triggeredZones(updated_triggered_zones))
46+
end
2847
end
2948

3049
return CameraEventHandlers

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,47 @@ test.register_coroutine_test(
14711471
}
14721472
)
14731473

1474+
test.register_coroutine_test(
1475+
"Duplicate ZoneTriggered events should not duplicate triggeredZones state",
1476+
function()
1477+
update_device_profile()
1478+
test.wait_for_events()
1479+
1480+
test.socket.matter:__queue_receive({
1481+
mock_device.id,
1482+
clusters.ZoneManagement.events.ZoneTriggered:build_test_event_report(mock_device, CAMERA_EP, {
1483+
zone = 2,
1484+
reason = clusters.ZoneManagement.types.ZoneEventTriggeredReasonEnum.MOTION
1485+
})
1486+
})
1487+
test.socket.capability:__expect_send(
1488+
mock_device:generate_test_message("main", capabilities.zoneManagement.triggeredZones({{zoneId = 2}}))
1489+
)
1490+
1491+
test.socket.matter:__queue_receive({
1492+
mock_device.id,
1493+
clusters.ZoneManagement.events.ZoneTriggered:build_test_event_report(mock_device, CAMERA_EP, {
1494+
zone = 2,
1495+
reason = clusters.ZoneManagement.types.ZoneEventTriggeredReasonEnum.MOTION
1496+
})
1497+
})
1498+
1499+
test.socket.matter:__queue_receive({
1500+
mock_device.id,
1501+
clusters.ZoneManagement.events.ZoneStopped:build_test_event_report(mock_device, CAMERA_EP, {
1502+
zone = 2,
1503+
reason = clusters.ZoneManagement.types.ZoneEventStoppedReasonEnum.ACTION_STOPPED
1504+
})
1505+
})
1506+
test.socket.capability:__expect_send(
1507+
mock_device:generate_test_message("main", capabilities.zoneManagement.triggeredZones({}))
1508+
)
1509+
end,
1510+
{
1511+
min_api_version = 17
1512+
}
1513+
)
1514+
14741515
test.register_coroutine_test(
14751516
"Button events should generate appropriate events",
14761517
function()

0 commit comments

Comments
 (0)