fix: add event-id latch to linked monitor score detection

Linked monitor alarm detection was purely point-in-time: it only
returned a score when the linked monitor's state was exactly ALARM at
the instant of the check. If the linked monitor's entire alarm cycle
(ALARM -> ALERT -> IDLE) occurred between two analysis cycles of the
checking monitor, the alarm was missed entirely.

Add a latch using last_event_id: if the linked monitor's event id has
changed since the last check, a new event started and we return a
score even if the ALARM state has already passed. Also remove dead
code in hasAlarmed() where last_event_id was updated after an early
return.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Isaac ConnorandClaude Opus 4.6 committed 2026-03-14 20:40:26 -04:00
1 parent f017c72498
commit 4356a6dea8
1 file changed
+13 -2
+13 -2
View File
@@ -218,6 +218,19 @@ int Monitor::MonitorLink::score() {
Debug(1, "Checking zone %u, zone_index is %d, score is %d", zone_id, zone_index, zone_scores[zone_index]);
return zone_scores[zone_index];
}
// Latch: detect if a new event started since we last checked.
// This catches alarms even if the linked monitor transitioned through
// ALARM -> ALERT -> IDLE between our analysis cycles.
if (shared_data->last_event_id != last_event_id) {
Debug(1, "New event %" PRIu64 " on linked monitor (was %" PRIu64 "), last_frame_score %d",
shared_data->last_event_id, last_event_id, shared_data->last_frame_score);
last_event_id = shared_data->last_event_id;
// Return last_frame_score if still available, otherwise minimum of 1
// to ensure the alarm is not silently missed
return shared_data->last_frame_score > 0 ? shared_data->last_frame_score : 1;
}
if (shared_data->state == ALARM) {
Debug(1, "Checking all zones score is %d", shared_data->last_frame_score);
return shared_data->last_frame_score;
@@ -228,6 +241,4 @@ int Monitor::MonitorLink::score() {
bool Monitor::MonitorLink::hasAlarmed() {
return this->score() > 0;
last_event_id = shared_data->last_event_id;
return false;
}