mercoledì 20 marzo 2013

Un sistema di "video sorveglianza" fatto in casa

Un sistema di "video sorveglianza" fatto in casa (con linux ovviamente).


L'esperimento riportato è un esempio molto alla buona, non ottimizzato o su cui sarebbe possbile lavorare tantissimo per apportare migliorie in quasi tutti i passaggi, è stato realizzato per spirito di curiosità ed  apprendimento, spirito che permette alle persone umili di crescere.

Materiale necessario :

connessione ad internet

1 o più portatile / eeepc / rasberry / mini pc collegati in wifi o rete ad internet

1 o più webcam

un sito internet pubblico con accesso ftp ed almeno 300 mega di spazio.

Come obiettivo ci poniamo quello di scattare una foto ogni 10 secondi, di creare una miniatura al minuto e di pubblicare sul sito l'elenco delle miniature in maniera tale da tenere sott'occhio eventuali movimenti all'interno della casa.

primo passo : scattare una foto con la webcam :


dopo qualche ricerca mi è venuto in aiuto vlc http://www.videolan.org/ un player altamente maneggevole.

se usiamo ubuntu possiamo scrivere sudo apt-get install vlc

vlc -I dummy v4l2:///dev/video0 --video-filter scene --no-audio --scene-path /home/utente/webcam --scene-prefix foto --scene-format jpg vlc://quit --run-time=1

vediamo di capire almeno le basi:

/dev/video0                   questa è la mia webcam
--scene-path /home/utente/webcam    percorso in cui salva l'immagine
--scene-prefix foto             nome con cui inizia il file
--scene-format jpg            formato con cui salva le foto ( potrebbe sare anche png ma occuperebbero + spazio )
--run-time=1                            quanto tempo deve stare accesa la webcam ( 1 secondo )

a conti fatti questo comando ci scatta una foto dalla webcam e la mette in formato jpg nella cartella /home/utente/webcam

secondo passo : rinomimare la foto e creare una miniatura :


per rinominare la foto useremo la data e l'ora di sistema inclusi i secondi, partendo dall'anno, quindi:

data=$(date +"%y%m%d%H%M%S")
crea una variabile d'ambiente chiamata $data contenente annoMeseGiornoOraMinutiSecondi es: 20130320095800

copia:
cp /home/utente/webcam/foto00001.jpg /home/utente/webcam/storico/foto$data.jpg

creazione miniatura :

convert -thumbnail x40 /home/utente/webcam/storico/foto$data.jpg /home/utente/webcam/storico/thumb/foto$data.jpg

dove x40 indica la grandezza della miniatura, più è piccolo questo valore più piccola sarà la miniatura

terzo passo : caricare le foto su un server ftp



# nome o indirizzo del server ftp :
HOST='nomenostrohost.ftp'
# nome utente per la connessione :
USER='nomeutente'
# password per la connessione
PASSWD='password'
# cartella da cui prelevare il file da caricare
FILE1='/home/utente/webcam/storico/'
# cartella da cui caricare il file della miniatura da caricare
FILE2='/home/utente/webcam/storico/thumb'
# cartella destinazione dell'immagine sul server
DIRE1='wbcm'
# cartella di destinazione delle miniature sul server
DIRE2='thumb'

# processo di uoload ftp :
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
cd $DIRE1
lcd $FILE1
put foto$data.jpg
cd $DIRE2
lcd $FILE2
put foto$data.jpg
quit
END_SCRIPT


quarto passo : automazione ogni 10 secondi :

basta creare 6 job che devono essere lanciati ogni minuto, e che attendono qualche secondo prima di partire, ad esempio, volendo creare il primo script, ovvero quello che parte ogni minuto e che crea la miniatura, si aggiungono alle righe che abbiamo individuato sopra :


# imposta i precorsi per i file eseguibili
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# indica il display a cui allacciare i programmi
export DISPLAY=:0.0
# cancella i file temporanei precedenti
rm -f /home/utente/webcam/*.jpg

prendiamo questi comandi ed accodiamo quelli che abbiamo visto prima per formare uno script, lo possiamo chiamare ad esempio webcam.sh

poi editiamo il crontab che ci permette di schedulare lo script ogni minuto:

crontab -e

* * * * *     /home/utente/bin/webcam.sh

quindi creiamo lo script che deve partire dopo 10 secondi e non creare la miniatura :

lo script sarà uguale a webcam.sh con dei passaggi in meno, ed una riga in più ovvero

prima di cancellare i file temporanei andiamo ad aggiungere

sleep 10

che indica al sistema di aspettare 10 secondi.

inoltre commentiamo la riga convert, la riga file2,dire2 e sotto dove pubblica il file thumb

possiamo quindi salvare questo script come webcam10.sh e cambiando i secondi di attesa
creare webcam 20,30,40,50 ...

crontab -e

* * * * *     /home/utente/bin/webcam.sh
* * * * *     /home/utente/bin/webcam10.sh
* * * * *     /home/utente/bin/webcam20.sh
* * * * *     /home/utente/bin/webcam30.sh
* * * * *     /home/utente/bin/webcam40.sh
* * * * *     /home/utente/bin/webcam50.sh

oppure potete passare una variabile allo script che indica il numero di secondi da attedere e se deve fare la miniatura....



quinto passo : visualizzazione e pulizia archivio :


sul server web adesso abbiamo in una cartella con le immagini ogni 10 secondi, ed una con le miniature ogni minuto....

dobbiamo innanzi tutto visualizzarle, e lo facciamo scrivendo poche righe di codice php

Nella pagina iniziale andiamo a mettere una piccola password per precludere al pubblico la visualizzazione , andiamo a creare una pagina per vedere le miniature, ed in fine una per pulire i file più vecchi di tot giorni, le pagine php vanno protette da un sistema di password per permettere solo al proprietario di accedere alle informazioni, ma qui si ci potrebbe dilungare troppo :


analizziamo i punti fondamentali degli script :
innanzi tutto prendiamo una funzione che ci fa l'elenco delle immagini contenute nella cartella :

questa funzione prende tutti i file che iniziano per "foto"
function elencafiles($dirname){
        $arrayfiles=Array();
        if(file_exists($dirname)){
                $handle = opendir($dirname);
                while (false !== ($file = readdir($handle))) {
                        if(is_file($dirname.$file) && substr($file,0,4)=="foto")
                               array_push($arrayfiles,$file);                      
                }
                $handle = closedir($handle);
        }
        sort($arrayfiles);
        return $arrayfiles;
}


se aggiungiamo del codice tipo

$arrayfile=array();
$arrayfile=elencafiles("./thumb/");
$size=sizeof($arrayfile);

for ($x=$size-1;$x>-1;$x--){
$minuti=substr($arrayfile[$x],12,2);
$ore=substr($arrayfile[$x],10,2);
 echo "<a href=mostra.php?name=".$arrayfile[$x]."><img src=thumb/".$arrayfile[$x
]." alt=\"$ore:$minuti\" ></a>";
if ($minuti=="00" || $minuti=="15" || $minuti=="30" || $minuti=="45")
        echo ($ore.":".$minuti."<br>");
// se 13 e 14 = 00 vai da capo ?
}


prendiamo tutte le miniature ed andiamo a capo ogni volta che i minuti sono = a 00,15,30,45 avendo 15 immagini per riga e l'orario stampato a fine riga, questo favorisce la visualizzazione, inoltre mettiamo su ogni miniatura il link all'immagine ingrandita...
Nel file mostra.php viene visualizzata l'immagine $arrayfile[$x] e vengono messi i link all'immagine successiva e quella precedente per pter navigare nel tempo di 10 secondi.
Per i dettagli sui file php non esitate a contattarmi o a commentare...

Per concludere c'e' il file delle cancellazioni, ovvero pulire l'archivio per evitare che si riempia all'infinito occupando tutto lo spazio sul server... se facciamo un file pulisci.php e poi creiamo uno script che lo lancia dal nostro pc collegato ad internet ogni giorno, potremmo risolvere il problema.


$mGiorni=1;
$mOre=3;

cancella tutti i file più vecchi di 1 giorno e 3 ore... come :
// per ogni file
$filename = $arrayfile[$x];

if ( filectime($filename) < mktime(date("H")-$mOre, date("i"),date("s"), date("m"), date("d")-$mGiorni,   date("Y")))
            // se è più vecchio cancella il file
{
echo "<br>devo cancellare $filename   : ..........";
if (    unlink($filename))
 echo "$filename e' stato cancellato:<br>";


ovviamente questa operazione va fatta per i file immagine e per la cartella delle miniature

creiamo pulisciremoto.sh
wget http://miosito/cartellafile/pulisci.php
lo aggiungiamo al crontab con cadenza giornaliera o a nostra scelta.