proposed solution to limiting emails
Posted: Mon Dec 10, 2007 4:28 pm
I believe I've devised a very simple way to limit the number of email alerts by simply adding an additional clause to the filter query. My solution is far from perfect, but I think it provides a reasonable solution for the extreme simplicity of implementation.
Allow me to describe a bit of my thought process. Knowing that all events and alarm frames have a database record with a column for StartTime, I realized that I could easily write a query to return the number of events within a specified time period. In turn, that makes it pretty easy to limit the events that are returned by a filter query that sends emails.
For starters, it should be somewhat obvious to anyone who knows SQL that the query immediately below will return the count of events that have alarmed and have been emailed within the past 10 minutes (MySQL’s “INTERVAL” keyword makes this quite easy and readable):
To limit the filter query that returns events to be emailed, we just need to compare the count of events to some number. In the query below, I’m appending my “SELECT count(*)” to the default filter query to say that I don’t want more than 5 emails about alarms within the past 10 minutes.
For what it’s worth, I do include a limitation on the StartTime (December 7th in the sample above) within my email filter query, mostly because that column is indexed so it makes the query a lot faster. I also wouldn’t want ZoneMinder to suddenly send me a mass of emails for old events anyway. If you use a StartTime condition like I do, you need to consider how it might impact the subquery which we’ve just added. Mostly, just make sure the window of times is larger than that of the subquery.
To add this solution/approach as a core feature of the product, I believe ZoneMinder only needs to ask the user for two additional configuration options. The first is the number of events (5 in my example) and the second is the time interval (10 minutes in my example). We could assume the interval is only specified in minutes, such that both options could be simple numeric values (rather than letting the user specify the interval is seconds or hours).
For now, anyone can hard-code this restriction into zm_filter.pl just before the sort column is appended to the query with a line such as:
Having said all this, I should offer a bit of explanation for why I say this is far from perfect. An AutoEmail filter doesn’t run immediately after an alarm event is generated, and the execution of the filter query can pick up multiple events to be emailed which are more than the specified maximum. Think of this example. Assume no alarm events have been sent within the specified interval, and assume that the background filters execute once every minute. Within a one-minute period, it is possible to generate 10 separate alarm events. The next time the filter runs, the “select count(*)” part of the query won’t find any alarm events that have been emailed, so all 10 events will then be emailed. The use of Mocord dramatically affects the whole situation, and the pre and post event settings also impact the number of separate events when running Modetect.
The count(*) query can be expanded to join to the Frames table if people want more precision, but I haven’t thought through how that would exactly work since emails are generated and flagged at the level of the Events table.
So as I said, this isn’t perfect, but it’s easy and seems to handle a large number of the situations that users probably wish to cover.
Allow me to describe a bit of my thought process. Knowing that all events and alarm frames have a database record with a column for StartTime, I realized that I could easily write a query to return the number of events within a specified time period. In turn, that makes it pretty easy to limit the events that are returned by a filter query that sends emails.
For starters, it should be somewhat obvious to anyone who knows SQL that the query immediately below will return the count of events that have alarmed and have been emailed within the past 10 minutes (MySQL’s “INTERVAL” keyword makes this quite easy and readable):
Code: Select all
SELECT count(*) FROM Events as E2
WHERE E2.StartTime >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)
and E2.AlarmFrames >= 1 and E2.Emailed = 1
Code: Select all
select E.Id,E.MonitorId, …
from Events as E inner join Monitors as M on M.Id = E.MonitorId
where not isnull(E.EndTime)
and ( E.Archived = 0
and E.StartTime >= '2007-12-07 20:48:53'
and E.AlarmFrames >= 1 ) and ( E.Emailed = 1 )
and 5 >= (SELECT count(*) FROM Events as E2
WHERE E2.StartTime >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)
and E2.AlarmFrames >= 1 and E2.Emailed = 1 )
order by E.StartTime asc
To add this solution/approach as a core feature of the product, I believe ZoneMinder only needs to ask the user for two additional configuration options. The first is the number of events (5 in my example) and the second is the time interval (10 minutes in my example). We could assume the interval is only specified in minutes, such that both options could be simple numeric values (rather than letting the user specify the interval is seconds or hours).
For now, anyone can hard-code this restriction into zm_filter.pl just before the sort column is appended to the query with a line such as:
Code: Select all
If ($filter_data->{AutoEmail})
{
sql .= “and 5 <= (SELECT count(*) … )”
}
The count(*) query can be expanded to join to the Frames table if people want more precision, but I haven’t thought through how that would exactly work since emails are generated and flagged at the level of the Events table.
So as I said, this isn’t perfect, but it’s easy and seems to handle a large number of the situations that users probably wish to cover.