A program update for my popular Raspberry Pi trail cam guide.


One aspect of my home made trail cam that I am looking to improve is it's capability to record video at night. Currently, the camera only works in day light which isn't much use if you want to know what's lurking in your garden throughout the night.

While I experiment with this, I thought I'd update the current program so that users can choose a time range within the day to start recording after and stop recording before. Essentially, I don't want the camera to record anything before sunrise and after sunset since it would only record black.

Please note, this feature replies on having a real time clock as part of the trail cam to work properly. Otherwise, the Raspberry Pi might not know the correct time making this feature a bit useless!

 

from gpiozero import MotionSensor
import logging
from datetime import datetime, time as t
from subprocess import call
import picamera
import time
import os

################################################################################################################################
## User Variables - change these as necessary

# The pin number for the PIR signal
pir = MotionSensor(17)

# The duration of recording
duration = 20

# Time to start recording after and stop recording by. This prevents recording during the night if you are using a camera 
# with no infrared capability.
# The format is hour,minute in 24 hour format. E.g. 7:30am = 7,30 or 4:15pm = 16,15
start_recording_after = time(5,30)
stop_recording_by = time(20,00)

# Text to be displayed on the camera - useful if you are using more than one camera
cam_name = 'Peak Nature  - 1'


## End of user cofigurable options
################################################################################################################################

if not os.path.exists('/home/pi/trailcam_log'):
    os.makedirs('/home/pi/trailcam_log')

if not os.path.exists('/home/pi/videos'):
    os.makedirs('/home/pi/videos')

def is_time_between(begin_time, end_time, check_time=None):
    # If check time is not given, default to current UTC time
    check_time = check_time or datetime.utcnow().time()
    if begin_time < end_time:
        return check_time >= begin_time and check_time <= end_time
    else: # crosses midnight
        return check_time >= begin_time or check_time <= end_time

logfile = "/home/pi/trailcam_log/trailcam_log-"+str(datetime.now().strftime("%Y%m%d-%H%M"))+".csv"
logging.basicConfig(filename=logfile, level=logging.DEBUG,
    format='%(asctime)s %(message)s',
    datefmt='%Y-%m-%d, %H:%M:%S,')

name = cam_name if cam_name else 'Trail Cam'

# Wait an initial duration to allow PIR to settle
print('Waiting for sensor to settle')
time.sleep(10)
print('Ready')

while True:
    pir.wait_for_motion()

    # Check time falls roughly in daylight hours
    result = is_time_between(start_recording_after, stop_recording_by, datetime.now().time())

    if result:
        logging.info('Motion detected')
        print('Motion detected')
        while pir.motion_detected:
            print('Beginning capture')
            ts = '{:%Y%m%d-%H%M%S}'.format(datetime.now())
            logging.info('Beginning capture: '+ str(ts)+'.h264')
            with picamera.PiCamera() as cam:
                cam.resolution=(1024,768)
                cam.annotate_background = picamera.Color('black')

                cam.start_recording('/home/pi/video.h264')
                start = datetime.now()
                while (datetime.now() - start).seconds < duration:
                    cam.annotate_text = name+" "+datetime.now().strftime('%d-%m-%y %H:%M:%S')
                    cam.wait_recording(0.2)
                cam.stop_recording()
            time.sleep(1)
            print('Stopped recording')
            timestamp = datetime.now().strftime('%d-%m-%y_%H-%M-%S')
            input_video = "/home/pi/video.h264"

            logging.info('Attempting to save video')
            print('Attempting to save video')

            usb = call("mountpoint -q /mnt/usb", shell=True)

            if usb == 0:
                logging.info('Saving to /mnt/usb/videos/')
                print('Saving to /mnt/usb/videos/')
                output_video = "/mnt/usb/videos/{}.mp4".format(timestamp)
            else:
                logging.info('Saving to /home/pi/videos/')
                print('Saving to /home/pi/videos/')
                output_video = "/home/pi/videos/{}.mp4".format(timestamp)

            call(["MP4Box", "-add", input_video, output_video])
            print('Motion ended - sleeping for 10 secs')
            logging.info('Motion Ended')
            time.sleep(10)