ZoneMinder Setup
The ZoneMinder wiki has instructions for creating different "run states" which can be turned on/off from the command line. Since my setup is not complicated, I simply used the default "start" and "stop" run states. It also covers scheduling these run state changes, but the cron entries are static. We need times to change dynamically for sunrise/sunset.
Sunwait
"Sunwait is a small C program for calculating sunrise and sunset, as well as civil, nautical, and astronomical twilights . . . The feature that makes this program slightly unique is that it can be set to wait specific event (such as 5 minutes before sunrise), then exit. This makes it useful for 'cron' jobs or 'scheduled tasks' when you want something to happen relative to sunrise, sunset, or some other astronomical event."
So basically, we will use Cron to schedule Sunwait to "wait" until sunrise/sunset, and then run our command/script.
Download: http://www.risacher.org/sunwait/
Extract / build / move to bin
tar -xvf sunwait-20041208.tar.gz
cd sunwait-20041208
make
(ignore compilation errors, should be ok)
sudo cp sunwait /usr/bin
Cron
Add su crontab entries. Those below start at 01:00 and 13:00, plenty of time before sunrise and sunset. The important thing is that they are scheduled before the earliest sunrise/sunset.
sudo crontab -e
(select default editor)
0 01 * * * /script/location/zm-sun.sh sunrise
0 13 * * * /script/location/zm-sun.sh sunset
Main script
The script checks the current run state, changes it based on the command line argument, and does some basic logging. This example starts ZoneMinder 30 minutes before sunrise and stops it 30 minutes after sundown.
zm-sun.sh
#!/bin/bash
# script to start / stop ZoneMinder based on sunrise / sunset
#
# usage:
# zm-sun.sh sunrise
# zm-sun.sh sunset
s=`zmpkg.pl status`
if [[ "$1" == "sunrise" ]]
then
if [[ "$s" == "stopped" ]]
then
sunwait sun up -00:30:00 38.794433N, 77.069450W ; zmpkg.pl start
s=`zmpkg.pl status`
else
s="already running"
fi
elif [[ "$1" == "sunset" ]]
then
if [[ "$s" == "running" ]]
then
sunwait sun down +00:30:00 38.794433N, 77.069450W ; zmpkg.pl stop
s=`zmpkg.pl status`
else
s="already stopped"
fi
fi
echo [`date`] Zoneminder $s, $1 >> /script/location/sunwait.log
exit
Make sure to enable execute permissions on the script
chmod +x zm-sun.sh
Enjoy
Very nice! Thank you! Do you have any more tweaks for ZoneMinder? Yours, 3esmit.
ReplyDeleteGlad it was helpful, that's all I have for now :)
DeleteHow would I switch from a Daytime Run Sate to a NightTime runstate?
ReplyDeleteAll you should need to do is edit the main script and swap a things around in the code. Give this a try:
Delete#!/bin/bash
# script to start / stop ZoneMinder based on sunrise / sunset
#
# usage:
# zm-sun.sh sunrise
# zm-sun.sh sunset
s=`zmpkg.pl status`
if [[ "$1" == "sunrise" ]]
then
if [[ "$s" == "running" ]]
then
sunwait sun up -00:30:00 38.794433N, 77.069450W ; zmpkg.pl stop
s=`zmpkg.pl status`
else
s="already stopped"
fi
elif [[ "$1" == "sunset" ]]
then
if [[ "$s" == "stopped" ]]
then
sunwait sun down +00:30:00 38.794433N, 77.069450W ; zmpkg.pl start
s=`zmpkg.pl status`
else
s="already running"
fi
fi
echo [`date`] Zoneminder $s, $1 >> /script/location/sunwait.log
exit
Thanks. This is what I currently have running:
ReplyDelete#!/bin/bash
# script to start / stop ZoneMinder based on sunrise / sunset
#
# usage:
# zm-sun.sh sunrise
# zm-sun.sh sunset
s=`zmpkg.pl status`
if [[ "$1" == "sunrise" ]]
then
# if [[ "$s" == "stopped" ]]
# then
sunwait sun up -00:30:00 30.115223N, 97.483887W ; zmpkg.pl Daytime
s=`zmpkg.pl status`
# else
# s="already running"
# fi
elif [[ "$1" == "sunset" ]]
then
# if [[ "$s" == "running" ]]
# then
sunwait sun down +00:30:00 30.115223N, 97.483887W ; zmpkg.pl NightTime
s=`zmpkg.pl status`
# else
# s="already stopped"
# fi
fi
echo [`date`] Zoneminder $s, $1 >> /var/log/zm/zm-sunwait.log
exit
It seems to be working. What are you checking for stop status in your script?
After a server reboot, zoneminder starts by default. So, sometimes it might be running when it's supposed to be off, or visa versa. So, the next time the script runs, it would unnecessarily be turning zoneminder to the state it's already in. The only time it might actually matter is when it was already running, and the service is re-started, but even then I did not test it to see if there is any interruption...
DeleteThanks for this. Had to change the sunwait command as it has changed over the years. Note the space between Lat/Lon and offset is now "towards noon", so "-00:30:00" is both before sunrise, and after sunset.
ReplyDeletesunwait wait rise offset -00:30:00 38.794433N 77.069450W;
sunwait wait set offset -00:30:00 38.794433N 77.069450W;
Thanks again,