Per chi si fosse perso le puntate precedenti: Parte prima, Parte seconda, Parte terza, Parte Quarta, Parte quinta, Parte sesta
Ed eccoci qui al cuore del sistema. Perché lasciato per ultimo? Così abbiamo tutti i pezzetti di contorno per farlo funzionare.
Torniamo alle specifiche. Il sistema va controllato via DM, ogni DM un comando, ad ogni comando un’azione, dopo l’esecuzione dell’azione il sistema risponderà con cosa ha fatto. Se il comando non è riconosciuto un DM manderà la lista di tutti i comandi utilizzabili.
Ecco i comandi che ho implementato:
- motionon: se il sistema non è attivo lo attiva, se è già attivo lo comunica
- motionoff: se il sistema è attivo lo spegne, se non è attivo lo comunica
- motionstatus: risponde con lo stato del sistema (attivo o no)
- click: scatta un’istantanea, come quella oraria, e la twitta
- cancellatutto: abilita la rimozione di tutti i tweet
- ippubblico: voglio sapere che indirizzo IP pubblico ha il router
Ecco il codice del file “cerca_dm.py”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | #!/usr/bin/env python2.7 import tweepy import sys import datetime import time import string import subprocess import os import requests import json # qualche costante file_di_log = "/home/pi/tweepy/controllo_movimento.log" # file di log del sistema di controllo file_semaforo_cancella = "/home/pi/tweepy/cancella_tutti_tweet" #file creato per autorizzare la cancellazione dei tweet utente_dm = "iltuoutente" # utente a cui mandare i DM (magari poi saranno gestibili diversi utenti) # Autenticazione su Twitter consumer_key = 'xxx' consumer_secret = 'xxx' access_token = 'xxx' access_token_secret = 'xxx' auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) # apro il file di log in append log = open (file_di_log, "a") # memorizzo il timestamp attuale (cosi' lo metto nei tweet ed evito il blocco dei doppioni) ts = time.time() st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') # recupero l'ultimo DM ricevuto dm_comando = api.direct_messages(count=1) # memorizzo una stringa vuota in ultimo_dm, nel caso in cui non si trovino DM ultimo_dm = " " # imposto id_ultimo_dm a zero, se non si trovano DM, lo uso per non mandare DM a fine pagina id_ultimo_dm = 0 # memorizzo il testo del tweet recuperato for directmessage in dm_comando: # converto la stringa tutta in minuscolo, per non avere problemi con le iniziali maiuscole dei vari client ultimo_dm = directmessage.text.lower() id_ultimo_dm = directmessage.id luogo_ultimo_dm = directmessage.sender.location data_ultimo_dm = directmessage.created_at # scrivo il log della richiesta log.write(st + " - DM di comando: " + ultimo_dm + " (" + str(id_ultimo_dm) + ") - da " + luogo_ultimo_dm + " \n") # elimino il DM api.destroy_direct_message(id_ultimo_dm) log.write(st + " - cancellato il DM di comando con id " + str(id_ultimo_dm) + " \n") # controllo se il processo 'motion' e' attivo o no processname = 'motion' tmp = os.popen("ps -Af").read() proccount = tmp.count(processname) # l'ultimo DM contiene l'ashtag motionoff? (voglio spegnere il sistema) if string.find(ultimo_dm, "motionoff") != -1: # se il processo 'motion' e' attivo lo uccido e avviso che e' disattivato if proccount != 0: os.system("pkill motion") log.write(st + " - Ucciso motion" + " \n") api.send_direct_message(utente_dm,text="Motion disattivato - " + st) else: api.send_direct_message(utente_dm,text="Motion era gia' disattivato - " + st) # l'ultimo DM contiene l'ashtag motionon? (voglio accendere il sistema) elif string.find(ultimo_dm, "motionon") != -1: # se il processo 'motion' non e' attivo lo avvio e avviso che e' attivato if proccount == 0: os.system("/home/pi/motion-mmal/motion") log.write(st + " - avviato motion \n") api.send_direct_message(utente_dm,text="Motion attivato - " + st) else: api.send_direct_message(utente_dm,text="Motion era gia' attivo - " + st) # l'ultimo DM contiene l'ashtag motionstatus? (voglio sapere se il sistema e' attivo o no) elif string.find(ultimo_dm, "motionstatus") != -1: # se il processo non c'e' twitto che e' disattivato if proccount == 0: api.send_direct_message(utente_dm,text="Stato motion: NON ATTIVO - " + st) log.write(st + " - controllo stato motion: NON attivo \n") # se il processo c'e' twitto che e' attivo else: api.send_direct_message(utente_dm,text="Stato motion: ATTIVO - " + st) log.write(st + " - controllo statio motion: attivo \n") # l'ultimo DM contiene il comando cancellatutto? (voglio cancellare tutti i tweet dell'account) elif string.find(ultimo_dm, "cancellatutto") != -1: #creo il file di semaforo semaforo = open (file_semaforo_cancella, "a") semaforo.write("cancella") log.write(st + " - creato il semaforo per la cancellazione\n") api.send_direct_message(utente_dm,text="Procedura rimozione tweet impostata, esecuzione entro 1h - " + st) # l'ultimo DM contiene il comando ippubblico (voglio sapere qual e' l'indirizzo IP pubblico) elif string.find(ultimo_dm, "ippubblico") != -1: req = requests.get("http://httpbin.org/ip") if req.status_code == 200: text = json.loads(req.text) ip = text['origin'] api.send_direct_message(utente_dm,text="Indirizzo IP pubblico: " + ip + " - " + st) log.write(st + " - IP pubblico di questo momento " + ip + " \n") # l'ultimo DM contiene il comando click (voglio scattare una foto) elif string.find(ultimo_dm, "click") != -1: # se motion e' attivo la videocamera e' impegnata, devo quindi prima spegnerlo if proccount != 0: os.system("pkill motion") log.write(st + " - ucciso motion per foto \n") time.sleep(5) os.system("raspistill -w 1600 -h 1200 -t 1 -o /home/pi/Pictures/SingoloClick.jpg") log.write(st + " - scattata la foto \n") time.sleep(15) os.system("/home/pi/motion-mmal/motion") log.write(st + " - avviato motion dopo foto \n") else: os.system("raspistill -w 1600 -h 1200 -t 1 -o /home/pi/Pictures/SingoloClick.jpg") log.write(st + " - scattata la foto con motion non attivo \n") api.update_with_media("/home/pi/Pictures/SingoloClick.jpg", utente_dm + " Istantanea del " + st) log.write(st + " - mandato tweet con istantanea \n") os.system("rm /home/pi/Pictures/SingoloClick.jpg") log.write(st + " - rimossa istantanea \n") #se nessun comando e' stato riconosciuto else: if id_ultimo_dm != 0: api.send_direct_message(utente_dm,text="Comandi utilizzabili: motionon, motionstatus, motionoff, cancellatutto, ippubblico, click - " + st) log.write(st + " - comando non riconosciuto: " + ultimo_dm + " \n") # chiudo il file di log log.close() |
Tutti commenti sono nel codice, la procedura è semplice, cerco nell’ultimo DM ricevuto il comando, se lo trovo eseguo l’azione, rimuovo l’ultimo DM ricevuto per non eseguire continuamente l’ultima azione richiesta. Per ogni azione eseguita viene registrata una riga nel file di log, compresi i dati del DM ricevuto e la posizione geografica del mittente (se abilitata dal client da cui si sta mandando il DM)
Questo programma va eseguito ogni minuto, si deve mettere di nuovo mano al crontab aggiungendo
1 2 | #controllo di motion tramite DM di twitter (una volta ogni minuto) */1 * * * * python /home/pi/tweepy/cerca_dm.py >/dev/null 2>&1 |
Attenzione che Twitter ha una frequenza massima di interrogazioni su DM, se dovete fare prove a mano lanciando il programma dalla riga di comando, interrompete il servizio del crontab o commentate quest’ultima riga anteponendo il “#” al comando. Se non lo fate vi troverete bloccati per superamento del limite di interrogazioni.
Concludendo
Ce l’abbiamo fatta! abbiamo un sistema di controllo di una zona fatto completamente da noi, completamente personalizzabile e gestibile da twitter! Ovviamente il codice è un po’ scritto da me, un po’ scopiazzato qua e là per Internet, potrebbero esserci errori e sicuramente potrebbe essere ottimizzato, vale la regola della licenza GNU, viene fornito così com’è e non potrò mai essere ritenuto responsabile di eventuali danni che questo progetto potrebbe arrecarvi.
Ovviamente se avete idee, miglioramenti, correzione di errori, sarò lieto di ascoltarli ed eventualmente implementarli tra le pagine del blog e sul dispositivo che ho a casa.
Altre idee?
Ho pubblicato questa guida per condividerla con chi è alle prime armi con il Raspberry (come me), ma sopratutto perché magari i lettori potrebbero proporre modifiche, aggiunte, nuove funzioni, tutto allo scopo di migliorare il progetto.
Problemi riscontrati ed evoluzioni
Il progetto non è esente da difetti e sicuramente potrebbe avere evoluzioni interessanti, magari ci farò altri post, man mano che mi vengono idee. Ovviamente se avete qualche idea non fatevi problemi a postarla qui sotto nei commenti!
Ecco qui alcuni pensieri che ho fatto
- Salvare tutti i file in un disco collegato via USB, per non consumare la scheda SD e poter tenere un archivio
- Fare in modo di avere un server web per poter accedere dall’esterno all’archivio delle immagini
- Utilizzare il GPIO del Raspberry per attivare un qualche dispositivo esterno in caso di rilevazione di movimento
E qui alcuni problemi che mi sono passati per le mani
- Pare che la WiFi, dopo che non accedo via SSH per un po’ di tempo, smetta di funzionare per metà, tutto il sistema funziona, ma non riesco più a collegarmici. Non so se è colpa del router, indago
- La videocamera è eccellente di giorno, ma pessima di notte, serve quella IR con illuminatore apposito (dovrei riuscire a procurarmelo prima delle vacanze)
- Ci sono ancora troppi falsi movimenti rilevati, devo trovare un modo per filtrarli
- Il LED rosso della videocamera resta acceso durante lo stato attivo, è da coprire con un pezzo di nastro nero
- Se va via la corrente ed il vs router è in po’ troppo lento ad avere la connessione è necessario ritardare l’invio del DM di riattivazione al reboot. Comunque ogni tanto lo perdo
- Qualcosa non torna con il comando “pkill” per ammazzare motion, ogni tanto il processo non viene terminato, pertanto ne parte un altro e così via a catena. Questo riempie RAM, CPU e pianta il sistema che va riavviato. Ci sto lavorando
Ed infine… ecco un banalissimo avatar che ho impostato sul mio account Twitter per il controllo, l’uovo era davvero brutto…
Complimenti per la guida, molto utile. Volevo farti una domanda. Sai se è possibile fare lo zoom in tempo reale? Quello che vorrei fare è zoommare la parte interessata e scattare una foto.
Grazie 10000000000
Ciao
Grazie!
Che io sappia no, con una videocamera con il motore puoi gestire i due assi, non ho visto nella documentazione lo zoom
Complimenti per il lavoro svolto.
è possibile collegare più di una telecamera ? Se sì, hai già avuto esperienze di questo tipo e che modifiche sono necessarie.
grazie 1000.
Ciao Francesco,
con più telecamere non ho mai provato, ma so che Motion lo gestisce (IP e USB), devi fare un file di configurazione per ognuna con un file principale per le opzioni in comune.
Su Raspberry non so se ce la fai, con solo una la CPU è parecchio sotto stress, magari con la nuova scheda Pi 2 B
Ciao Francesco,
volevo chiederti come mai quando eseguo questo ultimo file, mi esegue sempre l’ultimo DM inviato, pur avendolo eliminato (credo) con “api.destroy_direct_message(id_ultimo_dm)”
Grazie e complimenti!
Ciao Vincenzo,
per capire se hai rimosso il DM puoi mettere un try e capire se c’è un’eccezione durante l’operazione, oppure puoi memorizzare in un file l’ID in modo che quando lo controlli, se l’ID che becchi è lo stesso di prima non fai alcuna elaborazione.
Spero di essere stato di aiuto! 🙂
Ciao Francesco, ottimo lavoro, sto realizzando anche io un sistema di sorveglianza così, sapresti come fare su una ip cam che espone solo un protocollo rtsp motion non lo supporta
Ciao Luca, io ho usato una IP camera di Foscam, cercando un po’ di documentazione ho trovato il link esatto per andare a prendere lo streaming video, secondo me c’è anche nella tua (ma sicuramente Google può darti una risposta più precisa)
Ciao Francesco, Google non riesce ad aiutarmi e credo che non ha un indirizzo x stream HTTP la ipCam si chiama ONVIF JA-B1080 c’è solo lo stream RTSP ma troppo pesante x raspberry pi 2 B, occupa solo lui quasi il 100% della CPU, stavo pensando a farlo funzionare con protocollo FTP ma non so come, puoi aiutarmi? ho la porta 21 aperta, conosco l’ip ma non conosco l’indirizzo FTP://
Ciao Luca,
a me Google ha detto questo: http://ubuntuforums.org/showthread.php?t=2228419 puoi provare a partire da lì, ma se la CPU del Raspberry non ce la fa c’è ben poco da fare, se non cambiare scheda
Ciao Francesco, ho scoperto questa guida dopo aver fatto i primi passi con Motion.
Complimenti.
Ti vorrei chiedere qualcosa
1)
[code]on_[evento]
on_event_end rm /home/pi/Pictures/*.jpg
on_picture_save python /home/pi/tweepy/tweet.py %f [/code]
se volessi che memorizzi queste immagini e basta devo togliere il comando rm alla seconda linea?
2) se volessi memorizzare il filmato che si ha dopo il movimento percepito dalla webcam, che cosa dovrei impostare?
3) quando tu scrivi queste cose non capisco che devo fare:
“”
Bene, abbiamo il file configurato. Ma dove lo mettiamo? Il file si deve chiamare “motion.conf” e deve stare nella cartella “/home/pi/.motion”. Commentate le righe relative agli eventi “on_[qualcosa]” anteponendo un “;” o un “#”, e impostate l’opzione “daemon” a “off”, salvate il file ed eseguite il programma “/home/pi/motion-mmal/motion”
“”
il file motion.conf a me è nella cartella /etc/motion
Perchè lo devo spostare?
Ciao Vittorio,
vediamo se riesco a rispondere ai tuoi quesiti!
1. Sì, se togli il comando rm lui non cancella tutti i JPG dalla cartella dove salva le immagini
2. per il filmato la procedura è complessa, devi compilare e installare il modulo FFMPEG (aspettati parecchio tempo di compilazione) poi devi andare a lavorare con i parametri della sezione “FFMPEG related options” nel file di configurazione
3. l’ho spostato perché ho sbattuto parecchio il naso su questa cosa, se lo lasciavo nella /etc/motion qualcosa non funzionava, poi, non ricordo bene dove, ho trovato indicazione di spostarlo lì
Spero di essere stato di aiuto
Grazie dei complimenti 🙂
Ciao Francesco
grazie per la risposta.
Hai mai configurato motion per l’utilizzo di due webcam? io ci sto sopra da un po’ e non ci riesco. Potresti controllare i miei file di configurazione?
Ciao Vittorio,
il mio tempo non mi permette di controllare il codice altrui, mi spiace. Posso dirti che via USB non l’ho mai usata, ma ne ho una attiva via IP, nel mio file di configurazione, per accedere ho queste impostazioni
netcam_url value http://[indirizzo_IP_camera]/videostream.cgi
netcam_userpass [utente]:[password]
La mia era una Foscam, per avere il link dello streaming di altre camere devi cercare sulla documentazione della camera che usi tu
Ciao Francesco, scusa il ritardo della risposta.
Ci sono riuscito alla fine a mettere due webcam in funzione, anche se ora devo mettere qualche impostazioni per far salvare le foto o i video. Intanto se mi collego dal cell riesco a vedere entrambe le webcam in real-time.
Se vuoi, ti posso mandare in qualche modo la mia guida per settare due webcam
Quindi per quanto riguarda le webcam ip, quelle due che hai postato sono le uniche impostazioni da settare?
quando dici utente e password io che ci devo mettere?
immagina che non ho creato nessun altro utente, e che lavoro in /home/pi.
Ciao Vittorio,
sono contento che tua sia riuscito! Ma quindi attivi motion su 2 videocamere contemporaneamente sul Raspberry? E il processore tiene? Il mio, con solo una è già molto carico.
Per il salvataggio delle immagini ti consiglio di usare un HD esterno, la memoria SD si usura con tante scritture. Se vuoi un repository esterno puoi fare un FTP ogni tanto o usare iSync che permette di usare Google Drive ul raspberry.
Come credenziali devi mettere quelle che usi per collegarti alla camera IP, quando al usi
Ciao Francesco, ti rispondo sempre tardi perchè non mi arriva nessuna notifica via mail nonostante spunto ogni volta le due caselle qui sotto…..e me ne dimentico.
Per quanto riguarda il processore, e la temperatura, non vedo grossi problemi: ho installato un programma che mi permette tramite internet di monitorare sia il lavoro della CPU che la sua temperatura. Ho visto che c’è ampio margine: potrei utilizzare almeno altre due webcam. Quale è una temperatura preoccupante per il raspberry?
Vorrei fare il repository esterno con FTP, ma non ne sono in grado. Se hai una guida, ne sarei felice. Cosa è iSync??
forse allora non ho camere IP: non metto nulla per vederle: vado per esempio su mozilla e metto l’indirizzo ip del raspberry che ho settato e poi ” :porta_della_webcam “
Ciao Vittorio,
per depositare le immagini su un server FTP ti serve un PC sempre acceso con un programma che faccia da server FTP, puoi usare vsftp su Linux o Filezilla Server su Windows. Al termine di un evento, invece di fare “rm [nomefile]” puoi invocare uno script FTP che faccia l’upload della foto per poi cancellarla dal raspberry.
Non credo che la scheda patisca il surriscaldamento, è progettata bene, per surriscardarla devi iniziare a fare operazioni di overclock, ma vendono dei dissipatori da montare sul chip nel caso in cui tu lo voglia fare. La mia CPU, se faccio un “top” con motion attivo su una sola camera è al 60-70%, tu usi una Pi o una Pi2?
Mi spiace per le mail, è una cosa con cui sto combattendo da mesi, alcune partono, altre no…
Ciao Francesco
ora come ora vorrei capire come e dove mettere il percorso, dove salvare le immagini e le riprese con motion. (Non so se lo avevi scritto in questa guida, ora non ricordo).
Quello del server, ci sto ragionando e ricercando guide semplici in giro
Io ho una scehda raspberry con 1 gb di ram. Mi sembra che sia la Pi2.
Oggi mi è arrivata l’email di come passare con un nuovo portatile da win7 a win 8
ciao ciao
Ciao Vittorio,
queste attività sono di uno spettro più ampio rispetto a Raspberry, dovresti studiarti come funziona linux in generale, i mount su dischi esterni o come fare un server FTP. Buon Lavoro!
Complimenti per questa guida, molto completa ed esauriente.
Leggendo questo articolo mi è venuta un’idea… per attivare un illuminatore IR si potrebbe usare anche un GPIO che lo accenda ad una certa ora oppure che legga lo stato di un crepuscolare collegato su un altro gpio
Grazie Daniele!
Io ho risolto con un illuminatore IR trovato in una fiera con sensore crepuscolare integrato, quando diventa buio lui accende il fascio IR. Tra alimentatore e illuminatore credo di aver speso circa 20€ (ma si tratta di un po’ di tempo fa, non ricordo esattamente la spesa)
Per il tuo progetto c’è una parte interessante di studio di elettronica.
1. il GPIO non ha la corrente nè la tensione sufficiente per accendere un illuminatore almeno decente, devi giocare con un relè o un transistor
2. il crepuscolare è analogico, il GPIO del raspberry è solo digitale, devi fare un circuito in mezzo che converta la soglia minima di luce in 1 o 0
Magari ti ho dato lo spunto per elaborare un tuo sistema automatizzato
Ciao!
Ciao, non so se qualcuno legga attivamente questa (VALIDA) guida, ma la soluzione più semplice che ho trovato negli anni è MotionEye (https://github.com/ccrisan/motioneye/wiki e http://www.howtoembed.com/projects/raspberry-pi/95-motioneye-with-raspberry-pi).
Interfaccia, web, regolare aggiornamento, lavora con le USB cam e alcuni tipi di ipcam. Permette di caricare via email e via google drive, dropbox, i file video e foto. Funziona davvero bene.
Ciao Enrico,
grazie del tuo contributo, trovo motionEye davvero interessante!
Ha solo il difetto che per poterlo gestire devi aprire una porta dall’esterno verso il Raspberry PI, la soluzione con Telegram non apre porte verso l’esterno, ma è oggettivamente un po’ più scomoda 🙂 la proverò sicuramente!
Ciao!
Ciao Francesco sono Mario, il ragazzo che aveva chiesto il tuo aiuto per la versione evoluta con Telegram ! Se ti può interessare ho trovato un modo per evitare di utilizzare il nastro adesivo nero sul led rosso della camera basta eseguire da terminale:
sudo nano /boot/config.txt ed aggiungere al fine del file di configurazione
disable_camera_led=1 .
Spero possa essere utile a qualcuno. Saluti!
Ciao Mario,
grazie! avevo provato, ma pare che a seconda del modello di telecamera, questa funzione non sia “ascoltata” dal sistema, infatti con il mio non funziona, se ha te ha funzionato, meglio, è una cosa fastidiosa a volte 🙂
bel lavoro,
stavo pensando ad un modo piu “automatico” per attivare e disattivare la videosorveglianza.
che ne pensi, ammesso che sia fattibile, far verificare al raspi se nella lan sono connessi altri dispositivi esempio smatphone e nel caso positivo non serve la video sorveglianza perche significa che siamo in casa….. e viceversa. immagino che dovremo filtrare altre eventuali device che potremmo avere in casa.
Ciao Andrea,
grazie del commento e dei complimenti! Avevo già pensato a questa cosa, ma i cellulari (iPhone soprattutto), quando sono in standby disattivano la connettività WiFi e per le notifiche usano il 3G, quindi l’ho esclusa dopo un test di mezz’ora. Se hai un dispositivo che porti sempre con te e che sai che mantiene la wifi sempre attiva basta che tu imposti una reservation sul DHCP del tuo router in modo che assegni sempre lo stesso indirizzo al dispositivo e che regolarmente fai un PING su quell’IP, se è in rete allora disattivi l’antifurto.
Ci sono due problemi:
1- attento al delay di connettività, magari la tua WiFi si prende poco oltre la porta di casa e quindi rischi di entrare prima che il dispositivo venga trovato in rete
2- devi essere assolutamente certo che la tua rete sia inaccessibile e che nessun altro abbia quell’IP, se no va tutto a pallino.
Ciao!