vigil

Security camera system built on motion and yolov7.
git clone git://code.dwrz.net/vigil
Log | Files | Refs

notify (2306B)


      1 #!/usr/bin/env bash
      2 
      3 # Devices to check -- if populated and up, no notifications are sent.
      4 readonly DEVICES=()
      5 
      6 # COCO Labels
      7 readonly LABEL_PERSON=0
      8 readonly LABEL_CAT=15
      9 
     10 # Lockfile to ensure that only one instance of the script is running.
     11 readonly LOCKFILE="/tmp/motion-notify.lock.d"
     12 
     13 # yolov7 working directory.
     14 readonly PROJECT="/tmp/yolov7"
     15 
     16 # Notification recipient.
     17 readonly RECIPIENT="${NOTIFICATION_RECIPIENT}"
     18 
     19 # rsync user and server for backups.
     20 readonly RSYNC_USER="${RSYNC_USER}"
     21 readonly RSYNC_SERVER="${RSYNC_SERVER}"
     22 
     23 acquire_lock () {
     24   while true; do
     25     if mkdir "${LOCKFILE}"; then
     26       break;
     27     fi
     28     sleep 1
     29   done
     30 }
     31 
     32 check_devices() {
     33   for device in "${DEVICES[@]}"; do
     34     if ping -c 1 -w 1 "${device}" &> "/dev/null"; then
     35       return 0
     36     fi
     37   done
     38 
     39   return 255
     40 }
     41 
     42 detect_objects() {
     43   local filepath="$1"
     44 
     45   python "${HOME}/yolov7/detect.py" \
     46 	 --exist-ok \
     47 	 --no-trace \
     48 	 --save-txt \
     49 	 --project "${PROJECT}" \
     50 	 --name "motion" \
     51 	 --weights "${HOME}/yolov7/yolov7-tiny.pt" \
     52 	 --source "${filepath}"
     53 }
     54 
     55 notify() {
     56   local name="$1"
     57 
     58   echo "${HOSTNAME} at $(date '+%Y-%m-%dT%H:%M:%S%:z')" | \
     59     mutt -a "${PROJECT}/motion/${name}.jpg" \
     60 	 -s "${HOSTNAME}: Motion Detected" \
     61 	 -- "${RECIPIENT}"
     62 }
     63 
     64 upload() {
     65   local name="$1"
     66 
     67   rsync --archive --verbose \
     68 	"${PROJECT}/motion/${name}.jpg" \
     69 	"${RSYNC_USER}@${RSYNC_SERVER}:/photo/${name}.jpg"
     70 }
     71 
     72 delete_outdated() {
     73   local filepath="$1"
     74 
     75   acquire_lock
     76 
     77   rm -f "$1"
     78   rm -f "${PROJECT}/motion/${name}.jpg"
     79   find "${HOME}/photo/" -mmin +5 -delete
     80   find "${PROJECT}/motion/" -iname "*.jpg" -mmin +5 -delete
     81   find "${PROJECT}/motion/labels/" -mmin +5 -delete
     82 
     83   release_lock
     84 }
     85 
     86 release_lock () {
     87   rmdir "${LOCKFILE}"
     88 }
     89 
     90 main() {
     91   local filepath="$1"
     92   local name
     93   name="$(basename "${filepath}" .jpg)"
     94 
     95   # If devices are present, don't notify.
     96   if (( "${#DEVICES[@]}" )); then
     97     if check_devices; then
     98       delete_outdated "${filepath}" "${name}"
     99       exit 0
    100     fi
    101   fi
    102 
    103   detect_objects "${filepath}"
    104 
    105   # Send a notification if we match any labels.
    106   labels="$(awk '{print $1}' "${PROJECT}/motion/labels/${name}.txt")"
    107   if echo "${labels}" | grep -qw "${LABEL_PERSON}\|${LABEL_CAT}"; then
    108     notify "${name}"
    109   fi
    110 
    111   upload "${name}"
    112 
    113   delete_outdated "${filepath}" "${name}"
    114 }
    115 
    116 main "$@"