From 8fc1992e4d65038479fada4d377265a364ebd4bb Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 1 Jun 2026 16:31:25 -0400 Subject: [PATCH] fix: keep linked event open while source monitor is in ALERT state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Monitor::MonitorLink::score() previously returned 0 whenever the linked monitor's state was not ALARM, even when its event was still open in post-event countdown (ALERT). Combined with low AnalysisFPSLimit on the source monitor (a common setup for HD/sub-stream pairs where the low-res channel detects motion), state oscillates ALARM <-> ALERT around brief motion pauses inside a single event. The link signal drops to 0 in those gaps; the receiving monitor counts down its own PostEventCount and closes the linked event prematurely — typically after a few seconds, missing the remainder of a motion event that runs for minutes. Return a sentinel score of 1 while the linked monitor is in ALERT so the receiving event stays open. Do not return shared_data->last_frame_score here: latching the score itself would re-apply a stale numeric to every subsequent frame, inflating the accumulated score and biasing snapshot.jpg selection. The sentinel keeps the open-event signal alive without polluting the score channel. Real-world evidence: monitor 28 (HD, links to monitor 36 sub-stream) opened a 5.16-second linked event for a motion sequence that ran 300s with two motion bursts 134s apart, missing the entire second burst. With the latch, ALARM->ALERT transitions inside a single source event are bridged. Long IDLE gaps (separate motion bursts) remain correctly treated as separate triggers. --- src/zm_monitor_monitorlink.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/zm_monitor_monitorlink.cpp b/src/zm_monitor_monitorlink.cpp index e3c7a054f..ff0ee9878 100644 --- a/src/zm_monitor_monitorlink.cpp +++ b/src/zm_monitor_monitorlink.cpp @@ -241,6 +241,14 @@ int Monitor::MonitorLink::score() { Debug(1, "Checking all zones score is %d", shared_data->last_frame_score); return shared_data->last_frame_score; } + if (shared_data->state == ALERT) { + // Linked monitor's event is still open in its post-event window — motion + // has paused but may resume. Return a sentinel so our event stays open; + // do not latch last_frame_score, which would inflate the receiving + // monitor's accumulated score and bias snapshot.jpg selection. + Debug(1, "Linked monitor in ALERT, returning sentinel to keep event open"); + return 1; + } Debug(1, "not alarmed. %d", shared_data->state); return 0; }