Disable / Enable Cameras that are not responding script

If you've made a patch to quick fix a bug or to add a new feature not yet in the main tree then post it here so others can try it out.
Post Reply
User avatar
snake
Posts: 337
Joined: Sat May 21, 2016 2:20 am

Disable / Enable Cameras that are not responding script

Post by snake »

NOTE: Please read full post, and edits at the bottom.

In my setup which uses Foscam 9805s and ZM 1.29, they occasionally drop out and do not return. Whether cameras dropout is brand dependent. I was able to get better results by extending the zmwatch timeout in options, but dropouts continued. I'm not sure what the underlying fault is. However, overall zmwatch is failing to revive certain monitors. This has been discussed in other threads (viewtopic.php?f=36&t=25626&hilit=loosing+wlan)

I made a bash script that queries the API for a list of events from monitors in the last 15 minutes, and if certain monitor IDs don't show in the list, you can have the API fully disable, then re-enable the camera.

From https://notabug.org/monitor/ZM_Scripts

Code: Select all

#!/bin/bash
# add -x to debug

# the script will do the following:
# Auth to ZM API
# Get list of monitors with events in the last eleven minutes
# Restart any monitors that have 0 events in the last eleven minutes (any that don't appear in the list)
# requires logger (but can edit that out if not available), thats it.
# tested in devuan jessie

# find in the logs by searching for zmrestart

# change these variables for your setup
USERNAME="username"
PASSWORD="username"

# requires email setup on ZM. See wiki.zoneminder.com/SMS_Notifications
EMAIL="emailaddress"

# function for the camera. If you have varying functions you
# will need to implement on your own
# I use runstates that reset everything every so often, so I'm just going to mocord/record any dropped cameras
# Case sensitive
FUNCTION="Mocord"

# script must have write access to these files, and directory which its run in
EVENTSFILE="/root/lasthourevents.log"
PARSEFILE="/root/lasthour2.log"
SERVERLOCATION="localhost"
COOKIE="/root/cookies.txt"

# we look for these IDs in the json results, and in this order. Edit to include your monitor numbers.
# omit monitors that you don't want searched for. Do not need to be in order.
# Find monitorIds in Mysql: use zm; select ID from Monitors;
CAMERAMONITORIDSTOCHECK=(1 2 3 4 5)
ARRAYLENGTH=${#CAMERAMONITORIDSTOCHECK[@]}




# dont need to change these
MONITORNUMBER=0
COUNTER=0
ERRORFOUND=0
x=0


# auth to zm
curl -d "username=$USERNAME&password=$PASSWORD&action=login&view=console" -c $COOKIE  $SERVERLOCATION/zm/index.php

# this returns number of events in the 15 minutes for all cameras that have events. if events are zero, nothing is returned for
# that monitor.
# can be adjusted. 1%20hour is equivalent to 1 hour (%20 is space..?). can also use minutes, days, etc.
# see: https://github.com/ZoneMinder/ZoneMinder/blob/master/web/api/app/Controller/EventsController.php#L259
curl -b $COOKIE "$SERVERLOCATION/zm/api/events/consoleEvents/15%20minute.json" -o $EVENTSFILE



# get all events
# for cut you can use '"' or  \"
# cut is neat
grep -Po ^[^:]*  $EVENTSFILE | tail -n +3 | head -n -2 | cut -d \" -f 2 > $PARSEFILE

for (( i=0; i<$ARRAYLENGTH; i++ ))
do
	grep  ^${CAMERAMONITORIDSTOCHECK[i]}$ $PARSEFILE

		# if not found, grep returns error / value of one
		# if return code is error/false
		# if $? == 1
		if [ $? == 1 ]
			then
			# restartcamera

			echo "RESTARTING CAMERA ${CAMERAMONITORIDSTOCHECK[i]}"


			curl -b $COOKIE -XPOST $SERVERLOCATION/zm/api/monitors/${CAMERAMONITORIDSTOCHECK[i]}.json -d "Monitor[Function]=None&Monitor[Enabled]=0"

	                logger "camera ${CAMERAMONITORIDSTOCHECK[i]} has been disabled by zmrestart bashloop."

        	        # wait a little while (say 30 seconds)
			# required
                	sleep 30

	                # enable designated camera again
        	        curl -b $COOKIE -XPOST $SERVERLOCATION/zm/api/monitors/${CAMERAMONITORIDSTOCHECK[i]}.json -d "Monitor[Function]=$FUNCTION&Monitor[Enabled]=1"

	                logger "camera ${CAMERAMONITORIDSTOCHECK[i]} has been enabled by the zmrestart bashloop."

        	        # email notification (if email is setup)
                	echo "${CAMERAMONITORIDSTOCHECK[i]} has been restart on a zm server" | mutt -s "zmcamerarestart mon ${CAMERAMONITORIDSTOCHECK[i]}." $EMAIL

	                (( ERRORFOUND++ ))

		fi


done

logger "zmrestart bash loop has completed."
If you have multiple camera modes (modect,mocord) you can run multiple scripts, or edit this.

Run it in a cron job, every couple of minutes.

EDIT: Please see the repo for the latest code. I tweaked this to not email more than 7 times in one day. Without it, the inbox fills up if a camera is truly down.

This script works with Mocord, or Record cameras.

EDIT#2: MAX_RESTART_DELAY is the option used by zmwatch.pl.

EDIT#3: I've given up on the script, for simplicity sake, and now instead use modect on offending cameras. Modect seems to have less issues.
Post Reply