Merge pull request #4158 from BHMSD-bdailey/ONVIFTrackTopics

Add unordered map to track ONVIF topic and state
This commit is contained in:
Isaac Connor
2024-10-01 10:26:59 -04:00
committed by GitHub
2 changed files with 30 additions and 11 deletions

View File

@@ -328,6 +328,8 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
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;
@@ -338,6 +340,7 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
_wsnt__RenewResponse wsnt__RenewResponse;
PullPointSubscriptionBindingProxy proxyEvent;
void set_credentials(struct soap *soap);
std::unordered_map<std::string, std::string> alarms;
#endif
public:
explicit ONVIF(Monitor *parent_);
@@ -347,8 +350,8 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
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 {

View File

@@ -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";
@@ -176,27 +181,38 @@ 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()) {
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.
parent->Event_Poller_Closes_Event = true;
Info("Setting ClosesEvent");
}
} else {
// Event Start
Info("Triggered on ONVIF");
if (!alarmed) {
Info("Triggered Event");
alarmed = true;
last_topic = msg->Topic->__any.text;
last_value = msg->Message.__any.elts->next->elts->atts->next->text;
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
}
}
}
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)) {