From b701c7bb2e55731b7124a457df952f9506810fa6 Mon Sep 17 00:00:00 2001 From: Ben Dailey Date: Mon, 30 Sep 2024 11:40:01 -0400 Subject: [PATCH 1/6] Add unordered map to track ONVIF topic and state --- src/zm_monitor.h | 1 + src/zm_monitor_onvif.cpp | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 7ea14b0ac..833957b5e 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -338,6 +338,7 @@ class Monitor : public std::enable_shared_from_this { _wsnt__RenewResponse wsnt__RenewResponse; PullPointSubscriptionBindingProxy proxyEvent; void set_credentials(struct soap *soap); + std::unordered_map alarms; #endif public: explicit ONVIF(Monitor *parent_); diff --git a/src/zm_monitor_onvif.cpp b/src/zm_monitor_onvif.cpp index f55d3f550..50e49062b 100644 --- a/src/zm_monitor_onvif.cpp +++ b/src/zm_monitor_onvif.cpp @@ -176,11 +176,17 @@ void Monitor::ONVIF::WaitForMessage() { (msg->Message.__any.elts->next->elts->atts->next != nullptr) && (msg->Message.__any.elts->next->elts->atts->next->text != nullptr) ) { - Info("ONVIF Got Motion Alarm! %s %s", msg->Topic->__any.text, msg->Message.__any.elts->next->elts->atts->next->text); + last_topic = msg->Topic->__any.text; + last_value = msg->Message.__any.elts->next->elts->atts->next->text; + Info("ONVIF Got Motion Alarm! %s %s", last_topic.c_str(), last_value.c_str()); // Apparently simple motion events, the value is boolean, but for people detection can be things like isMotion, isPeople - if (strcmp(msg->Message.__any.elts->next->elts->atts->next->text, "false") == 0) { + if (last_value.find("false") == 0) { Info("Triggered off ONVIF"); - alarmed = false; + alarms.erase(last_topic); + if(alarms.empty()) { + Info("ONVIF Alarms count is %zu, alarmed is %s", alarms.size(), alarmed ? "true": "false"); + alarmed = false; + } if (!parent->Event_Poller_Closes_Event) { //If we get a close event, then we know to expect them. parent->Event_Poller_Closes_Event = true; Info("Setting ClosesEvent"); @@ -191,8 +197,7 @@ void Monitor::ONVIF::WaitForMessage() { if (!alarmed) { Info("Triggered Event"); alarmed = true; - last_topic = msg->Topic->__any.text; - last_value = msg->Message.__any.elts->next->elts->atts->next->text; + alarms[last_topic] = last_value; // Why sleep? std::this_thread::sleep_for(std::chrono::seconds(1)); //thread sleep } From b664d7b085ed101f300ed18999df33d9bdfd6efe Mon Sep 17 00:00:00 2001 From: Ben Dailey Date: Mon, 30 Sep 2024 11:45:40 -0400 Subject: [PATCH 2/6] Move debug for alarms count --- src/zm_monitor_onvif.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor_onvif.cpp b/src/zm_monitor_onvif.cpp index 50e49062b..018706e7e 100644 --- a/src/zm_monitor_onvif.cpp +++ b/src/zm_monitor_onvif.cpp @@ -184,7 +184,6 @@ void Monitor::ONVIF::WaitForMessage() { Info("Triggered off ONVIF"); alarms.erase(last_topic); if(alarms.empty()) { - Info("ONVIF Alarms count is %zu, alarmed is %s", alarms.size(), alarmed ? "true": "false"); alarmed = false; } if (!parent->Event_Poller_Closes_Event) { //If we get a close event, then we know to expect them. @@ -202,6 +201,7 @@ void Monitor::ONVIF::WaitForMessage() { std::this_thread::sleep_for(std::chrono::seconds(1)); //thread sleep } } + Info("ONVIF Alarms count is %zu, alarmed is %s", alarms.size(), alarmed ? "true": "false"); } else { Debug(1, "ONVIF Got a message that we couldn't parse"); if ((msg->Topic != nullptr) && (msg->Topic->__any.text != nullptr)) { From 3915007af55eb46267eeef0f0e101e73cf1976e4 Mon Sep 17 00:00:00 2001 From: Ben Dailey Date: Mon, 30 Sep 2024 12:41:34 -0400 Subject: [PATCH 3/6] Return the last active topic and value --- src/zm_monitor.h | 6 ++++-- src/zm_monitor_onvif.cpp | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 833957b5e..bb91cb7be 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -328,6 +328,8 @@ class Monitor : public std::enable_shared_from_this { bool healthy; std::string last_topic; std::string last_value; + std::string last_active_topic; + std::string last_active_value; #ifdef WITH_GSOAP struct soap *soap = nullptr; _tev__CreatePullPointSubscription request; @@ -348,8 +350,8 @@ class Monitor : public std::enable_shared_from_this { bool isAlarmed() const { return alarmed; }; void setAlarmed(bool p_alarmed) { alarmed = p_alarmed; }; bool isHealthy() const { return healthy; }; - const std::string &lastTopic() const { return last_topic; }; - const std::string &lastValue() const { return last_value; }; + const std::string &lastTopic() const { return last_active_topic; }; + const std::string &lastValue() const { return last_active_value; }; }; class AmcrestAPI { diff --git a/src/zm_monitor_onvif.cpp b/src/zm_monitor_onvif.cpp index 018706e7e..3e9f1c6e4 100644 --- a/src/zm_monitor_onvif.cpp +++ b/src/zm_monitor_onvif.cpp @@ -197,6 +197,8 @@ void Monitor::ONVIF::WaitForMessage() { Info("Triggered Event"); alarmed = true; alarms[last_topic] = last_value; + last_active_topic = last_topic; + last_active_value = last_value; // Why sleep? std::this_thread::sleep_for(std::chrono::seconds(1)); //thread sleep } From f43268b184208cab0e54aeba606c7e335688076f Mon Sep 17 00:00:00 2001 From: Ben Dailey Date: Tue, 1 Oct 2024 09:31:33 -0400 Subject: [PATCH 4/6] Only add to alarms map and set last active if not already in map. --- src/zm_monitor_onvif.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/zm_monitor_onvif.cpp b/src/zm_monitor_onvif.cpp index 3e9f1c6e4..b57459a24 100644 --- a/src/zm_monitor_onvif.cpp +++ b/src/zm_monitor_onvif.cpp @@ -192,18 +192,20 @@ void Monitor::ONVIF::WaitForMessage() { } } else { // Event Start - Info("Triggered on ONVIF"); - if (!alarmed) { - Info("Triggered Event"); - alarmed = true; + Info("Triggered Start on ONVIF"); + if (alarms.count(last_topic) == 0 ) + { alarms[last_topic] = last_value; last_active_topic = last_topic; last_active_value = last_value; + if (!alarmed) { + Info("Triggered Start Event on ONVIF"); + alarmed = true; // Why sleep? std::this_thread::sleep_for(std::chrono::seconds(1)); //thread sleep } } - Info("ONVIF Alarms count is %zu, alarmed is %s", alarms.size(), alarmed ? "true": "false"); + } } else { Debug(1, "ONVIF Got a message that we couldn't parse"); if ((msg->Topic != nullptr) && (msg->Topic->__any.text != nullptr)) { From 5c31384063f58d5ea16a6de9a48895c4b3074941 Mon Sep 17 00:00:00 2001 From: Ben Dailey Date: Tue, 1 Oct 2024 09:33:58 -0400 Subject: [PATCH 5/6] Add Debug --- src/zm_monitor_onvif.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/zm_monitor_onvif.cpp b/src/zm_monitor_onvif.cpp index b57459a24..280672697 100644 --- a/src/zm_monitor_onvif.cpp +++ b/src/zm_monitor_onvif.cpp @@ -184,6 +184,7 @@ void Monitor::ONVIF::WaitForMessage() { Info("Triggered off ONVIF"); alarms.erase(last_topic); if(alarms.empty()) { + Debug(1, "ONVIF Alarms Empty: Alarms count is %zu, alarmed is %s", alarms.size(), alarmed ? "true": "false"); alarmed = false; } if (!parent->Event_Poller_Closes_Event) { //If we get a close event, then we know to expect them. @@ -206,6 +207,7 @@ void Monitor::ONVIF::WaitForMessage() { } } } + Debug(1, "ONVIF Alarms count is %zu, alarmed is %s", alarms.size(), alarmed ? "true": "false"); } else { Debug(1, "ONVIF Got a message that we couldn't parse"); if ((msg->Topic != nullptr) && (msg->Topic->__any.text != nullptr)) { From 93f3a92996c9e368df6c1f34f4dc59fb0b2b51e8 Mon Sep 17 00:00:00 2001 From: Ben Dailey Date: Tue, 1 Oct 2024 09:34:48 -0400 Subject: [PATCH 6/6] Add alarms set cleanup and alarmed off when disconnected from ONVIF to prevent getting out of sync with camera. --- src/zm_monitor_onvif.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/zm_monitor_onvif.cpp b/src/zm_monitor_onvif.cpp index 280672697..c017ccc44 100644 --- a/src/zm_monitor_onvif.cpp +++ b/src/zm_monitor_onvif.cpp @@ -35,6 +35,11 @@ Monitor::ONVIF::~ONVIF() { #ifdef WITH_GSOAP if (soap != nullptr) { Debug(1, "Tearing Down Onvif"); + //We have lost ONVIF clear previous alarm topics + alarms.clear(); + //Set alarmed to false so we don't get stuck recording + alarmed = false; + Debug(1, "ONVIF Alarms Cleared: Alarms count is %zu, alarmed is %s", alarms.size(), alarmed ? "true": "false"); _wsnt__Unsubscribe wsnt__Unsubscribe; _wsnt__UnsubscribeResponse wsnt__UnsubscribeResponse; const char *RequestMessageID = parent->soap_wsa_compl ? soap_wsa_rand_uuid(soap) : "RequestMessageID";