"Después del juego es antes del juego"
Sepp Herberger

jueves, 22 de febrero de 2018

Montemos una IP-Webcam barata - Reloaded III

Este tema es inacabable. Después de todos los posts sobre la cámara IP a partir de una cámara usb y un router ADSL casero con OpenWRT/LEDE todavía me siguen saliendo cositas y ampliaciones cada pocos meses, así que no me queda otra opción que seguir revisitando el tema. Hagamos una retrospectiva:


Ahora el problema es que, recordemos, el guardado de las imágenes de captura se realizaba en una carpeta de un servidor remoto montada por sshfs. No es infrecuente que haya algún problema de red y esa conexión quede interrumpida. No siempre es restaurada esa conexión en tiempo y forma y a veces me encuentro con que llevamos varios días desechando imágenes ya que en el mermado espacio de almacenamiento del router ADSL no se puede guardar nada.

Para evitar esto he añadido código para que cuando se detecte que se ha perdido el montaje remoto por sshfs se envíe un correo especial de aviso, para que al menos pueda ponerle remedio cuanto antes. Marco en negrita la parte con el pequeño fragmento de código nuevo (el resto es como la ha ido quedando las últimas veces):
# cat /root/controlador.sh
#!/bin/ash

log() {
  test $montado -eq 1 && echo "$1" >> /mnt/snapshot/log.txt  
}

email() {
  test $email -eq 1 && echo -e "$1" | sendmail correo.aviso@gmail.com
}

monta_sshfs() {
  sshfs -o ssh_command="ssh -i /root/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -o nonempty openwrt@192.168.0.25:/home/openwrt /mnt
}

envia_secuencia() {

   if [ -e /tmp/motion.txt ]
   then

      #Recopila todos los ficheros de /tmp/motion/txt y los envia en un correo

      ficheros=$(cat /tmp/motion.txt | tr '\n' ' ')
      rm /tmp/motion.txt

      log "Historia de capturas $ficheros"
      zip -9 /mnt/escena.zip $ficheros

      echo "Secuencia $1" > /mnt/mensaje.txt
      test $email -eq 1 && mutt -s "Evento camara" correo.aviso@gmail.com -a /mnt/escena.zip < /mnt/mensaje.txt

      rm /mnt/escena.zip
      #Si no hay acceso al almacenamiento remoto, borramos las capturas para no llenar el disco del router.

      test $montado -eq 0 && rm -rf $destino

   fi

}

#Parametro 1: start, picture, end
#Parametro 2: fecha
#Parametro 3: nombre fichero (opcional)

#Obtenemos fecha y hora por si queremos poner algun filtro sobre ella y solo avisar en determinados
#momentos

time=$(date +%s)
anio=$(date +%Y @$time)
mes=$(date +%m @$time)
dia=$(date +%d @$time)
hora=$(date +%H @$time)
minuto=$(date +%M @$time)
diasemana=$(date +%u @$time) #El 1 es lunes
destino="/mnt/snapshot/$anio-$mes-$dia"
montado=1
email=0

if [ $diasemana -ge 6 -o $hora -le 7 -o $hora -ge 17 ]  # sabado/domingo o cualquier dia antes de las 8:00 o despues de las 17:00
then
   email=1
fi

#Si existe el fichero /mnt/testigo no se ha montado directorio remoto por sshfs,
#Intentamos montarlo y otra vez y luego preguntamos de nuevo.
#Si no se ha montado nada es que no se puede guardar nada de forma permanente ya que estamos escribiendo en la
#memoria interna del router y eso se llena rapido

test -e /mnt/testigo || monta_sshfs

if test -e /mnt/testigo
then
  #No está montado el directorio remoto, no hay donde guardar las imagenes
  montado=0
  #No hay almacenamiento por dias, no vamos a guardar tanto tiempo el fichero.
  destino="/mnt/snapshot"
  #Si no se ha avisado antes se avisa por correo
  if ! test -e /tmp/avisado
  then
     touch /tmp/avisado
     echo -e "Subject: Camara sin almacenamiento\r\n\r\nSe ha perdido la conexión remota con el directorio de almacenamiento de la cámara" | sendmail correo.aviso@gmail.com
  fi
else
  #Tenemos montado el directorio remoto, borramos el testigo de aviso.
  rm -f /tmp/avisado
fi

test -d $destino || mkdir -p $destino

case $1 in

  "start")
     log "Detectado inicio de movimiento $2" 
     email "Subject: Evento camara\r\n\r\nDetectado inicio de movimiento $2"
     #El fichero motion.txt tiene dos finalidades: 1) testigo para indicar que estamos detectando movimiento 
     #                                             2) guarda los nombres de los ficheros de captura de las fotos
     touch /tmp/motion.txt
     ;;
  "picture")
     fichero=$(basename $3)
     log "Guardando imagen $2 : $destino/$fichero" 

     #Si estamos en una ráfaga de movimiento detectado, guardamos el nombre de fichero con la foto.
     test -e /tmp/motion.txt && echo "$destino/$fichero" >> /tmp/motion.txt

     #Se guarda el fichero en el almacenamiento destino
     mv "$3" "$destino/$fichero"

     #Si no está montado el almacenamiento remoto y vemos que llevamos mas de 10 imagenes en
     #movimiento tenemos que borrarlas y enviarlas ya mismo, para no saturar el espacio.
     if [ $montado -eq 0 ]
     then
        #Si estamos en una ráfaga de movimiento detectado....
        if [ -e /tmp/motion.txt ]
        then
          lineas=$(wc -l /tmp/motion.txt | cut -d" " -f1)
          test $lineas -gt 10 && envia_secuencia $2
        else
          #Si no lo estamos, es una captura *snapshot* regular sin interés, la borramos.
          rm -f "$destino/$fichero"
        fi  
     fi
     ;;
  "end") 
     log "Detectado fin de movimiento $2"
     envia_secuencia $2
     ;;
   *) log "Evento $1"
esac


#Borra fichero "sent" creado por sendmail si existe, para liberar espacio
rm -rf /root/sent
rm -rf /sent
Para evitar enviar el mensaje en cada invocación del script se usa un fichero "avisado" en /tmp/ como bandera para verificar si se ha enviado o no ese mensaje. Ese fichero se borra cuando se detecta que se ha montado el directorio remoto o al reiniciar el equipo (todo el contenido de /tmp se borra en cada reinicio).

Bueno, pues seguro que vuelve la burra al trigo pronto y estamos otra vez aquí.



Hasta siempre Forges, me has hecho reírme de mí mismo muchas veces.

No hay comentarios:

Publicar un comentario