Bug 238 - Changes to do with the various enabled/disable/suspend/trigger modes.

git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@1720 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
stan
2005-12-22 16:46:25 +00:00
parent b3e75d77ee
commit 05c2fb5dfd
5 changed files with 827 additions and 610 deletions

View File

@@ -34,6 +34,7 @@
#define ZM_MAX_FPS 30 // The maximum frame rate we expect to handle
#define ZM_SAMPLE_RATE int(1000000/ZM_MAX_FPS) // A general nyquist sample frequency for delays etc
#define ZM_SUSPENDED_RATE int(1000000/4) // A slower rate for when disabled etc
extern char *ZM_DB_HOST, *ZM_DB_NAME, *ZM_DB_USER, *ZM_DB_PASS, *ZM_PATH_WEB;
extern void zmLoadConfig();

View File

File diff suppressed because it is too large Load Diff

View File

@@ -45,13 +45,7 @@ public:
typedef enum
{
CONTINUOUS=0,
TRIGGERED
} RunMode;
typedef enum
{
OFF=1,
NONE=1,
MONITOR,
MODECT,
RECORD,
@@ -59,20 +53,33 @@ public:
NODECT
} Function;
typedef enum { ROTATE_0=1, ROTATE_90, ROTATE_180, ROTATE_270, FLIP_HORI, FLIP_VERT } Orientation;
typedef enum
{
ROTATE_0=1,
ROTATE_90,
ROTATE_180,
ROTATE_270,
FLIP_HORI,
FLIP_VERT
} Orientation;
typedef enum { IDLE, PREALARM, ALARM, ALERT, TAPE } State;
typedef enum { ACTIVE, SUSPENDED, RESUMING } ActivityState;
typedef enum
{
IDLE,
PREALARM,
ALARM,
ALERT,
TAPE
} State;
protected:
// These are read from the DB and thereafter remain unchanged
int id;
char *name;
Function function; // What the monitor is doing
bool enabled; // Whether the monitor is enabled or asleep
unsigned int width; // Normally the same as the camera, but not if partly rotated
unsigned int height; // Normally the same as the camera, but not if partly rotated
RunMode run_mode; // Whether the monitor is running continuously or is triggered
Orientation orientation; // Whether the image has to be rotated at all
int brightness; // The statically saved brightness of the camera
int contrast; // The statically saved contrast of the camera
@@ -98,10 +105,9 @@ protected:
Image ref_image;
Purpose purpose; // What this monitor has been created to do
ActivityState activity_state;
int event_count;
int image_count;
int resume_image_count;
int ready_count;
int first_alarm_count;
int last_alarm_count;
int buffer_count;
@@ -112,6 +118,7 @@ protected:
Event *event;
time_t start_time;
time_t last_fps_time;
time_t auto_resume_time;
int shmid;
typedef struct Snapshot
@@ -122,11 +129,12 @@ protected:
Snapshot *image_buffer;
typedef enum { GET_SETTINGS=0x1, SET_SETTINGS=0x2, SUSPEND=0x4, RESUME=0x8 } Action;
typedef enum { GET_SETTINGS=0x1, SET_SETTINGS=0x2, RELOAD=0x4, SUSPEND=0x10, RESUME=0x20 } Action;
typedef struct
{
int size;
bool valid;
bool active;
State state;
int last_write_index;
int last_read_index;
@@ -158,7 +166,7 @@ protected:
Camera *camera;
public:
Monitor( int p_id, char *p_name, int p_function, Camera *p_camera, int p_orientation, char *p_event_prefix, char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, bool p_track_motion, Purpose p_purpose=QUERY, int p_n_zones=0, Zone *p_zones[]=0 );
Monitor( int p_id, char *p_name, int p_function, bool p_enabled, Camera *p_camera, int p_orientation, char *p_event_prefix, char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, bool p_track_motion, Purpose p_purpose=QUERY, int p_n_zones=0, Zone *p_zones[]=0 );
~Monitor();
void Setup();
@@ -178,10 +186,36 @@ public:
{
return( name );
}
inline Function GetFunction() const
{
return( function );
}
inline const char *EventPrefix() const
{
return( event_prefix );
}
inline bool Ready()
{
if ( function <= MONITOR )
return( false );
return( image_count > ready_count );
}
inline bool Enabled()
{
if ( function <= MONITOR )
return( false );
return( enabled );
}
inline bool Active()
{
if ( function <= MONITOR )
return( false );
return( enabled && shared_data->active );
}
unsigned int Width() const { return( width ); }
unsigned int Height() const { return( height ); }
State GetState() const;
int GetImage( int index=-1, int scale=100 ) const;
struct timeval GetTimestamp( int index=-1 ) const;
@@ -194,153 +228,36 @@ public:
void ForceAlarmOff();
void CancelForced();
TriggerState GetTriggerState() const { return( trigger_data?trigger_data->trigger_state:TRIGGER_CANCEL ); }
void Suspend();
void Resume();
inline void TimestampImage( Image *ts_image, time_t ts_time ) const
{
if ( label_format[0] )
{
static int token_count = -1;
static char label_time_text[256];
static char label_text[256];
void actionReload();
void actionEnable();
void actionDisable();
void actionSuspend();
void actionResume();
if ( token_count < 0 )
{
const char *token_ptr = label_format;
const char *token_string = "%%s";
token_count = 0;
while( token_ptr = strstr( token_ptr, token_string ) )
{
token_count++;
token_ptr += strlen(token_string);
}
}
strftime( label_time_text, sizeof(label_time_text), label_format, localtime( &ts_time ) );
switch ( token_count )
{
case 0:
{
strncpy( label_text, label_time_text, sizeof(label_text) );
break;
}
case 1:
{
snprintf( label_text, sizeof(label_text), label_time_text, name );
break;
}
case 2:
{
snprintf( label_text, sizeof(label_text), label_time_text, name, trigger_data->trigger_showtext );
break;
}
}
int actionBrightness( int p_brightness=-1 );
int actionHue( int p_hue=-1 );
int actionColour( int p_colour=-1 );
int actionContrast( int p_contrast=-1 );
ts_image->Annotate( label_text, label_coord );
}
}
int Brightness( int p_brightness=-1 );
int Hue( int p_hue=-1 );
int Colour( int p_colour=-1 );
int Contrast( int p_contrast=-1 );
bool DumpSettings( char *output, bool verbose );
void DumpZoneImage( const char *zone_string=0 );
unsigned int Width() const { return( width ); }
unsigned int Height() const { return( height ); }
inline int PreCapture()
{
return( camera->PreCapture() );
}
inline int PostCapture()
{
if ( camera->PostCapture( image ) == 0 )
{
if ( orientation != ROTATE_0 )
{
switch ( orientation )
{
case ROTATE_90 :
case ROTATE_180 :
case ROTATE_270 :
{
image.Rotate( (orientation-1)*90 );
break;
}
case FLIP_HORI :
case FLIP_VERT :
{
image.Flip( orientation==FLIP_HORI );
break;
}
}
}
int index = image_count%image_buffer_count;
if ( index == shared_data->last_read_index && function > MONITOR )
{
Warning(( "Buffer overrun at index %d, slow down capture, speed up analysis or increase ring buffer size", index ));
}
gettimeofday( image_buffer[index].timestamp, &dummy_tz );
if ( config.timestamp_on_capture )
{
TimestampImage( &image, image_buffer[index].timestamp->tv_sec );
}
image_buffer[index].image->CopyBuffer( image );
shared_data->last_write_index = index;
shared_data->last_image_time = image_buffer[index].timestamp->tv_sec;
image_count++;
if ( image_count && !(image_count%fps_report_interval) )
{
time_t now = image_buffer[index].timestamp->tv_sec;
fps = double(fps_report_interval)/(now-last_fps_time);
//Info(( "%d -> %d -> %d", fps_report_interval, now, last_fps_time ));
//Info(( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps ));
Info(( "%s: %d - Capturing at %.2lf fps", name, image_count, fps ));
last_fps_time = now;
}
if ( shared_data->action & GET_SETTINGS )
{
shared_data->brightness = camera->Brightness();
shared_data->hue = camera->Hue();
shared_data->colour = camera->Colour();
shared_data->contrast = camera->Contrast();
shared_data->action &= ~GET_SETTINGS;
}
if ( shared_data->action & SET_SETTINGS )
{
camera->Brightness( shared_data->brightness );
camera->Hue( shared_data->hue );
camera->Colour( shared_data->colour );
camera->Contrast( shared_data->contrast );
shared_data->action &= ~SET_SETTINGS;
}
return( 0 );
}
return( -1 );
}
inline bool Ready()
{
if ( function <= MONITOR )
return( false );
if ( image_count <= warmup_count )
return( false );
return( true );
}
void DumpImage( Image *dump_image ) const;
bool Analyse();
int PostCapture();
unsigned int Compare( const Image &comp_image );
bool Analyse();
void DumpImage( Image *dump_image ) const;
void TimestampImage( Image *ts_image, time_t ts_time ) const;
bool closeEvent();
void Reload();
void ReloadZones();
bool DumpSettings( char *output, bool verbose );
void DumpZoneImage( const char *zone_string=0 );
static int LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose=QUERY );
static int LoadRemoteMonitors( const char *host, const char*port, const char*path, Monitor **&monitors, Purpose purpose=QUERY );
static int LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose=QUERY );

View File

@@ -58,6 +58,24 @@ void zm_term_handler( int signal )
zma_terminate = true;
}
bool zma_reload = false;
void zm_hup_handler( int signal )
{
#if HAVE_DECL_STRSIGNAL
char * error = strsignal(signal);
size_t errorStringSize = strlen(error) + strlen("Got signal (), reloading.");
char * errorString =(char *) malloc(errorStringSize + 1); // plus 1 for termination char.
(void) snprintf(errorString, errorStringSize, "Got signal (%s), reloading.", error);
Info(( (const char *)errorString ));
free(errorString);
#else /* HAVE_DECL_STRSIGNAL */
Info(( "Got HUP signal, reloading" ));
#endif /* HAVE_DECL_STRSIGNAL */
zma_reload = true;
}
void Usage()
{
fprintf( stderr, "zma -m <monitor_id>\n" );
@@ -129,7 +147,7 @@ int main( int argc, char *argv[] )
if ( monitor )
{
Info(( "Warming up" ));
Info(( "In mode %d/%d, warming up", monitor->GetFunction(), monitor->Enabled() ));
if ( config.opt_frame_server )
{
@@ -140,6 +158,11 @@ int main( int argc, char *argv[] )
sigemptyset( &block_set );
struct sigaction action, old_action;
action.sa_handler = zm_hup_handler;
action.sa_mask = block_set;
action.sa_flags = 0;
sigaction( SIGHUP, &action, &old_action );
action.sa_handler = zm_term_handler;
action.sa_mask = block_set;
action.sa_flags = 0;
@@ -157,7 +180,12 @@ int main( int argc, char *argv[] )
sigprocmask( SIG_BLOCK, &block_set, 0 );
if ( !monitor->Analyse() )
{
usleep( ZM_SAMPLE_RATE ); // Nyquist sampling rate at 30fps, wouldn't expect any more than this
usleep( monitor->Active()?ZM_SAMPLE_RATE:ZM_SUSPENDED_RATE );
}
if ( zma_reload )
{
monitor->Reload();
zma_reload = false;
}
sigprocmask( SIG_UNBLOCK, &block_set, 0 );
}

View File

@@ -58,6 +58,9 @@ void Usage( int status=-1 )
fprintf( stderr, " -a, --alarm : Force alarm in monitor, this will trigger recording until cancelled with -c\n" );
fprintf( stderr, " -n, --noalarm : Force no alarms in monitor, this will prevent alarms until cancelled with -c\n" );
fprintf( stderr, " -c, --cancel : Cancel a forced alarm/noalarm in monitor, required after being enabled with -a or -n\n" );
fprintf( stderr, " -L, --reload : Signal monitor to reload settings\n" );
fprintf( stderr, " -E, --enable : Enable detection, wake monitor up\n" );
fprintf( stderr, " -D, --disable : Disble detection, put monitor to sleep\n" );
fprintf( stderr, " -u, --suspend : Suspend detection, useful to prevent bogus alarms when panning etc\n" );
fprintf( stderr, " -r, --resume : Resume detection after a suspend\n" );
fprintf( stderr, " -U, --username <username> : When running in authenticated mode the username and\n" );
@@ -85,8 +88,11 @@ typedef enum {
CONTRAST = 0x00002000,
HUE = 0x00004000,
COLOUR = 0x00008000,
SUSPEND = 0x00010000,
RESUME = 0x00020000,
RELOAD = 0x00010000,
ENABLE = 0x00100000,
DISABLE = 0x00200000,
SUSPEND = 0x00400000,
RESUME = 0x00800000,
LIST = 0x10000000,
} Function;
@@ -108,7 +114,7 @@ bool ValidateAccess( User *user, int mon_id, int function )
if ( user->getMonitors() < User::PERM_VIEW )
allowed = false;
}
if ( function & (ALARM|NOALARM|CANCEL|SUSPEND|RESUME|BRIGHTNESS|CONTRAST|HUE|COLOUR) )
if ( function & (ALARM|NOALARM|CANCEL|RELOAD|ENABLE|DISABLE|SUSPEND|RESUME|BRIGHTNESS|CONTRAST|HUE|COLOUR) )
{
if ( user->getMonitors() < User::PERM_EDIT )
allowed = false;
@@ -150,6 +156,9 @@ int main( int argc, char *argv[] )
{"alarm", 0, 0, 'a'},
{"noalarm", 0, 0, 'n'},
{"cancel", 0, 0, 'c'},
{"reload", 0, 0, 'L'},
{"enable", 0, 0, 'E'},
{"disable", 0, 0, 'D'},
{"suspend", 0, 0, 'u'},
{"resume", 0, 0, 'r'},
{"query", 0, 0, 'q'},
@@ -179,7 +188,7 @@ int main( int argc, char *argv[] )
{
int option_index = 0;
int c = getopt_long (argc, argv, "d:m:vsurwei::S:t::fz::ancqhlB::C::H::O::U:P:A:", long_options, &option_index);
int c = getopt_long (argc, argv, "d:m:vsEDurwei::S:t::fz::ancqhlB::C::H::O::U:P:A:", long_options, &option_index);
if (c == -1)
{
break;
@@ -244,6 +253,15 @@ int main( int argc, char *argv[] )
case 'c':
function |= CANCEL;
break;
case 'L':
function |= RELOAD;
break;
case 'E':
function |= ENABLE;
break;
case 'D':
function |= DISABLE;
break;
case 'u':
function |= SUSPEND;
break;
@@ -498,17 +516,35 @@ int main( int argc, char *argv[] )
printf( "Cancelling forced alarm on/off\n" );
monitor->CancelForced();
}
if ( function & RELOAD )
{
if ( verbose )
printf( "Reloading monitor settings\n" );
monitor->actionReload();
}
if ( function & ENABLE )
{
if ( verbose )
printf( "Enabling event generation\n" );
monitor->actionEnable();
}
if ( function & DISABLE )
{
if ( verbose )
printf( "Disabling event generation\n" );
monitor->actionDisable();
}
if ( function & SUSPEND )
{
if ( verbose )
printf( "Suspending motion detection\n" );
monitor->Suspend();
printf( "Suspending event generation\n" );
monitor->actionSuspend();
}
if ( function & RESUME )
{
if ( verbose )
printf( "Resuming motion detection\n" );
monitor->Resume();
printf( "Resuming event generation\n" );
monitor->actionResume();
}
if ( function & QUERY )
{
@@ -521,17 +557,17 @@ int main( int argc, char *argv[] )
if ( verbose )
{
if ( brightness >= 0 )
printf( "New brightness: %d\n", monitor->Brightness( brightness ) );
printf( "New brightness: %d\n", monitor->actionBrightness( brightness ) );
else
printf( "Current brightness: %d\n", monitor->Brightness() );
printf( "Current brightness: %d\n", monitor->actionBrightness() );
}
else
{
if ( have_output ) printf( "%c", separator );
if ( brightness >= 0 )
printf( "%d", monitor->Brightness( brightness ) );
printf( "%d", monitor->actionBrightness( brightness ) );
else
printf( "%d", monitor->Brightness() );
printf( "%d", monitor->actionBrightness() );
have_output = true;
}
}
@@ -540,17 +576,17 @@ int main( int argc, char *argv[] )
if ( verbose )
{
if ( contrast >= 0 )
printf( "New brightness: %d\n", monitor->Contrast( contrast ) );
printf( "New brightness: %d\n", monitor->actionContrast( contrast ) );
else
printf( "Current contrast: %d\n", monitor->Contrast() );
printf( "Current contrast: %d\n", monitor->actionContrast() );
}
else
{
if ( have_output ) printf( "%c", separator );
if ( contrast >= 0 )
printf( "%d", monitor->Contrast( contrast ) );
printf( "%d", monitor->actionContrast( contrast ) );
else
printf( "%d", monitor->Contrast() );
printf( "%d", monitor->actionContrast() );
have_output = true;
}
}
@@ -559,17 +595,17 @@ int main( int argc, char *argv[] )
if ( verbose )
{
if ( hue >= 0 )
printf( "New hue: %d\n", monitor->Hue( hue ) );
printf( "New hue: %d\n", monitor->actionHue( hue ) );
else
printf( "Current hue: %d\n", monitor->Hue() );
printf( "Current hue: %d\n", monitor->actionHue() );
}
else
{
if ( have_output ) printf( "%c", separator );
if ( hue >= 0 )
printf( "%d", monitor->Hue( hue ) );
printf( "%d", monitor->actionHue( hue ) );
else
printf( "%d", monitor->Hue() );
printf( "%d", monitor->actionHue() );
have_output = true;
}
}
@@ -578,17 +614,17 @@ int main( int argc, char *argv[] )
if ( verbose )
{
if ( colour >= 0 )
printf( "New colour: %d\n", monitor->Colour( colour ) );
printf( "New colour: %d\n", monitor->actionColour( colour ) );
else
printf( "Current colour: %d\n", monitor->Colour() );
printf( "Current colour: %d\n", monitor->actionColour() );
}
else
{
if ( have_output ) printf( "%c", separator );
if ( colour >= 0 )
printf( "%d", monitor->Colour( colour ) );
printf( "%d", monitor->actionColour( colour ) );
else
printf( "%d", monitor->Colour() );
printf( "%d", monitor->actionColour() );
have_output = true;
}
}