Add code to fork and exec EventStartCommand and EventEndCommand

This commit is contained in:
Isaac Connor 2021-11-26 19:21:51 -05:00
parent d51eb63947
commit b626de50dc
2 changed files with 31 additions and 3 deletions

View File

@ -70,7 +70,7 @@
// It will be used whereever a Monitor dbrow is needed. WHERE conditions can be appended // It will be used whereever a Monitor dbrow is needed. WHERE conditions can be appended
std::string load_monitor_sql = std::string load_monitor_sql =
"SELECT `Id`, `Name`, `ServerId`, `StorageId`, `Type`, `Function`+0, `Enabled`, `DecodingEnabled`, " "SELECT `Id`, `Name`, `ServerId`, `StorageId`, `Type`, `Function`+0, `Enabled`, `DecodingEnabled`, "
"`LinkedMonitors`, `AnalysisFPSLimit`, `AnalysisUpdateDelay`, `MaxFPS`, `AlarmMaxFPS`," "`LinkedMonitors`, `EventStartCommand`, `EventEndCommand`, `AnalysisFPSLimit`, `AnalysisUpdateDelay`, `MaxFPS`, `AlarmMaxFPS`,"
"`Device`, `Channel`, `Format`, `V4LMultiBuffer`, `V4LCapturesPerFrame`, " // V4L Settings "`Device`, `Channel`, `Format`, `V4LMultiBuffer`, `V4LCapturesPerFrame`, " // V4L Settings
"`Protocol`, `Method`, `Options`, `User`, `Pass`, `Host`, `Port`, `Path`, `SecondPath`, `Width`, `Height`, `Colours`, `Palette`, `Orientation`+0, `Deinterlacing`, " "`Protocol`, `Method`, `Options`, `User`, `Pass`, `Host`, `Port`, `Path`, `SecondPath`, `Width`, `Height`, `Colours`, `Palette`, `Orientation`+0, `Deinterlacing`, "
"`DecoderHWAccelName`, `DecoderHWAccelDevice`, `RTSPDescribe`, " "`DecoderHWAccelName`, `DecoderHWAccelDevice`, `RTSPDescribe`, "
@ -435,7 +435,7 @@ Monitor::Monitor()
/* /*
std::string load_monitor_sql = std::string load_monitor_sql =
"SELECT Id, Name, ServerId, StorageId, Type, Function+0, Enabled, DecodingEnabled, LinkedMonitors, " "SELECT Id, Name, ServerId, StorageId, Type, Function+0, Enabled, DecodingEnabled, LinkedMonitors, `EventStartCommand`, `EventEndCommand`, "
"AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS," "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS,"
"Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings "Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings
"Protocol, Method, Options, User, Pass, Host, Port, Path, SecondPath, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, " "Protocol, Method, Options, User, Pass, Host, Port, Path, SecondPath, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, "
@ -489,6 +489,8 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
// See below after save_jpegs for a recalculation of decoding_enabled // See below after save_jpegs for a recalculation of decoding_enabled
ReloadLinkedMonitors(dbrow[col]); col++; ReloadLinkedMonitors(dbrow[col]); col++;
event_start_command = dbrow[col] ? dbrow[col] : ""; col++;
event_end_command = dbrow[col] ? dbrow[col] : ""; col++;
/* "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS," */ /* "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS," */
analysis_fps_limit = dbrow[col] ? strtod(dbrow[col], nullptr) : 0.0; col++; analysis_fps_limit = dbrow[col] ? strtod(dbrow[col], nullptr) : 0.0; col++;
@ -1994,6 +1996,12 @@ bool Monitor::Analyse() {
alarm_cause = cause+" Continuous "+alarm_cause; alarm_cause = cause+" Continuous "+alarm_cause;
strncpy(shared_data->alarm_cause, alarm_cause.c_str(), sizeof(shared_data->alarm_cause)-1); strncpy(shared_data->alarm_cause, alarm_cause.c_str(), sizeof(shared_data->alarm_cause)-1);
SetVideoWriterStartTime(event->StartTime()); SetVideoWriterStartTime(event->StartTime());
if (!event_start_command.empty()) {
if (fork() == 0) {
execlp(event_start_command.c_str(), event_start_command.c_str(), std::to_string(event->Id()).c_str(), nullptr);
Error("Error execing %s", event_start_command.c_str());
}
}
Info("%s: %03d - Opened new event %" PRIu64 ", section start", Info("%s: %03d - Opened new event %" PRIu64 ", section start",
name.c_str(), analysis_image_count, event->Id()); name.c_str(), analysis_image_count, event->Id());
@ -2084,6 +2092,13 @@ bool Monitor::Analyse() {
delete start_it; delete start_it;
start_it = nullptr; start_it = nullptr;
if (!event_start_command.empty()) {
if (fork() == 0) {
execlp(event_start_command.c_str(), event_start_command.c_str(), std::to_string(event->Id()).c_str(), nullptr);
Error("Error execing %s", event_start_command.c_str());
}
}
Info("%s: %03d - Opening new event %" PRIu64 ", alarm start", name.c_str(), analysis_image_count, event->Id()); Info("%s: %03d - Opening new event %" PRIu64 ", alarm start", name.c_str(), analysis_image_count, event->Id());
} else { } else {
shared_data->state = state = ALARM; shared_data->state = state = ALARM;
@ -2786,7 +2801,18 @@ void Monitor::closeEvent() {
Debug(1, "close event thread is not joinable"); Debug(1, "close event thread is not joinable");
} }
Debug(1, "Starting thread to close event"); Debug(1, "Starting thread to close event");
close_event_thread = std::thread([](Event *e){ delete e; }, event); close_event_thread = std::thread([](Event *e, const std::string &command){
int64_t event_id = e->Id();
delete e;
if (!command.empty()) {
if (fork() == 0) {
execlp(command.c_str(), command.c_str(), std::to_string(event_id).c_str(), nullptr);
Error("Error execing %s", command.c_str());
}
}
}, event, event_end_command);
Debug(1, "Nulling event"); Debug(1, "Nulling event");
event = nullptr; event = nullptr;
if (shared_data) video_store_data->recording = {}; if (shared_data) video_store_data->recording = {};

View File

@ -404,6 +404,8 @@ protected:
int n_linked_monitors; int n_linked_monitors;
MonitorLink **linked_monitors; MonitorLink **linked_monitors;
std::string event_start_command;
std::string event_end_command;
std::vector<Group *> groups; std::vector<Group *> groups;