Arlo: dialogare con il sistema tramite Python

| |

Anticipato nell’articolo dedicato allo sviluppo “from-scratch” del dialogo tra sistema tado° e casa tramite Python, era inevitabile arrivare a rompere quanto fatto tramite Bash anche per Arlo e portarlo su Python, rendendolo di fatto un “add-on” del primo script. Rimane così la logica di funzionamento e i comandi di Arm/Disarm del sistema verranno chiamati direttamente dallo script relativo al controllo di tado° quando non ci sono più dispositivi conosciuti connessi alla rete di casa. Vediamo insieme come (anche perché Netgear non l’ha resa proprio semplice a causa della MFA obbligatoria).

Arlo: dialogare con il sistema tramite Python

Prima di partire

Vorrei mantenere la stessa logica usata nell’articolo dedicato al controllo tado°, ti mostro lo script e ti racconto a cosa devi fare attenzione. Ci sarà anche un paragrafo dedicato alla creazione / configurazione di account Google (consiglio: separato da quello che usi di solito e dedicato al solo controllo della tua basestation Arlo, condivisa dal proprietario di casa) e allo sviluppo di un progetto “finto” per permettere l’accesso in sola lettura a una casella di posta Gmail. Insomma: c’è carne al fuoco. Per qualsiasi dubbio puoi certamente fare riferimento all’area commenti, tutto ciò è dovuto – come segnalato in apertura articolo – alla necessaria autenticazione MFA imposta da Netgear per accedere il sistema Arlo da sito web (my.arlo.com).

Io resto a disposizione per qualsiasi tuo dubbio in merito, l’area commenti è lì che ti aspetta.

Lo script in Python

Trattandolo come “add-on” dello script di tado°, posso permettermi di saltare la parte relativa al controllo dei dispositivi riconosciuti e andare dritto al sodo in base al parametro passando da riga di comando allo script. Chi lo passa – ovviamente – è proprio lo script Python del controllo tado° (a meno di volerlo tu lanciare manualmente):

from dotenv import load_dotenv, find_dotenv
from arlo import Arlo
import datetime
import requests
import base64
import os
import sys

load_dotenv(find_dotenv())
ARLO_USERNAME = os.environ.get("ARLO_USERNAME")
ARLO_PASSWORD = os.environ.get("ARLO_PASSWORD")
BOT_TOKEN = os.environ.get("BOT_TOKEN")
CHAT_ID = os.environ.get("CHAT_ID")

MSG_ARLO_ARM = "Arlo ARMATO. Rilevo i movimenti in casa 🔒 (%s)" % datetime.datetime.now().strftime("%d/%m/%Y alle %H:%M:%S") # https://stackoverflow.com/a/7999977
MSG_ARLO_DISARM = "Arlo DISARMATO. Smetto di rilevare i movimenti in casa 🔓 (%s)" % datetime.datetime.now().strftime("%d/%m/%Y alle %H:%M:%S")

def getMode(basestation):
    modes = arlo.GetModesV2()
    return modes[0].get('activeModes')[0]

def sendtotelegram(token,chatid,message):
    url = "https://api.telegram.org/bot%s/sendMessage?chat_id=%s&text=%s" % (token, chatid, message)
    response = requests.post(url)
    return response

try:
    if ARLO_USERNAME is None or ARLO_PASSWORD is None:
        print("Environment variables have not been loaded!")
        sys.exit(1)

    arlo = Arlo(ARLO_USERNAME, ARLO_PASSWORD, '/home/pi/Scripts/Arlo/gmail.credentials')
    basestations = arlo.GetDevices('basestation')
    systemstatus = getMode(basestations[0])
    basemode = str(sys.argv[1])
    if basemode == "Arm":
        if systemstatus == "mode0":
            sendtotelegram(BOT_TOKEN,CHAT_ID,MSG_ARLO_ARM)
            arlo.Arm(basestations[0]) # Arm Arlo
    if basemode == "Disarm":
        if systemstatus == "mode1":
            sendtotelegram(BOT_TOKEN,CHAT_ID,MSG_ARLO_DISARM)
            arlo.Disarm(basestations[0]) # Disarm Arlo

except Exception as e:
    print(e)

Le variabili usate

Il file .env è sempre tuo amico, ne ho creato uno nella cartella in cui risiede il necessario al funzionamento dello script Python di controllo Arlo. Il file è strutturato banalmente in questa maniera:

ARLO_USER=user@contoso.com
ARLO_PASSWORD=MySuperSecretPassword
BOT_TOKEN=MyTelegramBotToken
CHAT_ID=-000000000
  • ARLO_USER*: è l’utente con il quale sei registrato su my.arlo.com.
  • ARLO_PASSWORD*: devo seriamente specificarlo?
  • BOT_TOKEN: ho voluto mantenere l’uso dell’alert inviato su Telegram, quindi questa variabile contiene il token che mi permette di lavorare con il bot di casa.
  • CHAT_ID: completa quanto detto poco sopra. L’ID del gruppo / utente con cui far comunicare il bot Telegram in caso di alert.

Tutti i parametri con * vicino sono obbligatori, gli altri puoi ignorarli se modifichi un pelo lo script anche in questo caso, ti spiego come tra poco.

All’interno dello script Python trovi anche le due variabili relative ai messaggi da spedire via Telegram (MSG_ARLO_ARM e MSG_ARLO_DISARM), puoi ritoccarli secondo tua preferenza, occhio solo a non toccare le variabili richiamate.

Librerie usate

Per lo specifico compito ho usato la libreria arlo di Jeffrey Walter, disponibile sia su GitHub (github.com/jeffreydwalter/arlo) che su pypi.org (pypi.org/project/arlo), installabile quindi tramite Pip. I requisiti necessari sono raccolti anche stavolta all’interno di un file requirements.txt che puoi quindi richiamare facilmente tramite pip install -r requirements.txt:

certifi==2020.12.5
chardet==4.0.0
idna==2.10
python-dotenv==0.16.0
requests==2.25.1
urllib3==1.26.5
PySocks==1.7.1
arlo==1.2.59
cachetools==5.0.0
google==api==core==2.5.0
google==api==python==client==2.39.0
google==auth==2.6.0
google==auth==httplib2==0.1.0
google==auth==oauthlib==0.5.0
googleapis==common==protos==1.55.0
httplib2==0.20.4
monotonic==1.6
oauthlib==3.2.0
pickle==mixin==1.0.2
protobuf==3.19.4
pyasn1==0.4.8
pyasn1==modules==0.2.8
pyparsing==3.0.7
requests==oauthlib==1.3.1
rsa==4.8
six==1.16.0
sseclient==0.0.22
uritemplate==4.1.1
urllib3==1.24

Considera che – installando la libreria arlo – questa richiamerà a bordo anche tutte le altre dopo di lei, quindi nel file poco sopra mi sarei potuto idealmente fermare a arlo==1.2.59.

Chi, cosa, come

La documentazione della libreria non è ben organizzata con Read the Docs ma è comunque disponibile su GitHub all’indirizzo github.com/jeffreydwalter/arlo/tree/master/docs. Una connessione di test si ottiene con queste poche righe di codice:

arlo = Arlo(ARLO_USERNAME, ARLO_PASSWORD, 'gmail.credentials')
basestations = arlo.GetDevices('basestation')
print(basestations[0])

Quel gmail.credentials è un file che dovrà trovarsi a portata dello script Python poiché Netgear ha reso obbligatoria l’autenticazione ai servizi Arlo tramite MFA. L’idea è quella di accedere una casella di posta Gmail in sola lettura, abilitare l’autenticazione MFA di Arlo per inviare il codice via email alla casella sotto monitor e quindi riuscire a recuperare il codice in autonomia e proseguire così nell’uso dello script. Il file gmail.credentials viene generato tramite un altro script Python di cui ti parlo nel prossimo paragrafo e che necessiterà di un progetto creato su Google Developers ad-hoc.

Account Google e MFA Netgear

Il paragrafo più lungo dell’articolo secondo me, è un po’ una rottura di scatole ma ti toglierà le castagne dal fuoco. Premetto: ho scelto di creare un account nuovo di Gmail. Avrei potuto usarne uno già attivo ma – seppur si tratti di uno script / libreria che va a sbirciare in sola lettura le notifiche che arrivano da Arlo, è pur sempre una porta aperta sulla mailbox magari “principale“. Creare un account Gmail gratuito porta via una manciata di minuti (mettilo già sotto autenticazione a due fattori già che ci sei, così da proteggerlo decentemente), una volta fatto tieni da parte le credenziali di accesso, ti serviranno tra un po’.

La documentazione in inglese scritta direttamente da Jeffrey Walter è disponibile all’indirizzo github.com/jeffreydwalter/arlo/blob/master/docs/ARLO_MFA.md. Io di seguito te la localizzo e ti accompagno in quanto ho fatto io. Puoi saltare a piè pari il paragrafo se segui direttamente il documento originale su GitHub.

Collegati alla console di Google Cloud e crea un nuovo progetto.

Arlo: dialogare con il sistema tramite Python 1

Spostati in API e servizi dal menu di sinistra, quindi fai clic su Libreria. Quando ti si caricherà la pagina di libreria cerca e attiva le API di Gmail:

A questo punto potrai generare delle credenziali per poter accedere le API:

Arlo: dialogare con il sistema tramite Python 4

Fino al passaggio 3 (quello relativo all’ambito) puoi inserire dati “fittizi“, decidi tu che nome dare all’applicazione e che indirizzo email associare alla stessa (io ho utilizzato il medesimo dell’account Gmail creato poco prima). Quello che ti serve sapere è che quando andrai a specificare gli ambiti ti servirà aggiungerne uno, filtrare “Gmail” nella schermata che ti si caricherà sulla destra dello schermo e attivare l’opzione .../auth/gmail.readonly. Proseguendo dovrai specificare il tipo di applicazione (Web), darle il nome (anche lo stesso che hai utilizzato prima andrà benissimo) e aggiungere come URI di reindirizzamento http://localhost:7788/. Concludi questo passaggio scaricando le credenziali JSON che Google genera al termine del percorso:

Il file che hai appena scaricato dovrà essere rinominato in google_client_credentials.json.

A questo punto potrai trasformare quel file appena rinominato in un altro file che la libreria userà per automatizzare l’accesso ai servizi di Netgear passando per la casella di posta e recuperando il codice MFA di volta in volta. Userai questo script ad-hoc, gmail_oauth.py, sviluppato e disponibile sempre nel repository GitHub di Jeffrey Walter:

import pickle

import google.oauth2.credentials
from google_auth_oauthlib.flow import InstalledAppFlow


FILENAME = 'gmail.credentials'
PORT = 7788

flow = InstalledAppFlow.from_client_secrets_file(
    'google_client_credentials.json',
    scopes=['https://www.googleapis.com/auth/gmail.readonly'])

flow.redirect_uri = 'http://localhost:{}/'.format(PORT)

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')

credentials = flow.run_local_server(host='localhost',
    port=PORT,
    authorization_prompt_message='Please visit this URL: {}'.format(authorization_url),
    success_message='The auth flow is complete; you may close this window.',
    open_browser=True)

pickle.dump(credentials, open(FILENAME, 'wb'))

Lo script Python dovrà trovarsi nella stessa cartella dove risiede il file google_client_credentials.json. Lancialo per aprire una finestra del browser in cui autenticarti con l’utente e la password dell’account Google che hai registrato a inizio di questo paragrafo e dare così le giuste autorizzazioni di accesso alla casella di posta elettronica:

Attenzione

Se lo script dovesse darti errori di libreria non trovata, è perché forse lo stai eseguendo su una macchina diversa rispetto a dove prima hai lanciato il pip passandogli il file requirements.txt. Poco male, lancia questi due comandi e installerai così il necessario per affrontare la parte di autenticazione Google:

pip install --upgrade google-api-python-client
pip install --upgrade google_auth_oauthlib

Se invece l’errore dovesse riguardare Google e un errore 403, vorrà dire che l’applicazione non sarà ancora stata approvata da Google e non potrai quindi autorizzare l’accesso alla Gmail dell’utente registrato inizialmente. Poco male, lo si risolve andando a inserire l’indirizzo di posta elettronica Gmail tra gli utenti di test dell’applicazione:

Arlo: dialogare con il sistema tramite Python 10

A questo punto dovresti essere riuscito a terminare l’operazione e ottenere così un file gmail.credentials nella stessa cartella dello script Python appena utilizzato. Conserva quel file e butta via il resto, non ti servirà più.

Condividi la Base Station con l’account Gmail creato

Hai fatto tutto questo affinché potessi separare i mondi e condividere con l’account Gmail appena registrato la gestione della sola Base Station. Registrati su my.arlo.com con l’account Gmail nuovo e abilita l’autenticazione MFA (obbligatoria) chiedendo a Netgear di inviare i codici di autenticazione via posta elettronica.

Subito dopo – da un account My Arlo con pieni poteri – condividi la gestione della Base Station con l’account Gmail. Così facendo, l’account appena creato potrà effettivamente mandare in Arm/Disarm la Base Station via script. Inserisci le credenziali dell’account Gmail nel file .env e assicurati che lo script carichi correttamente il file gmail.credentials passandogli il giusto percorso:

arlo = Arlo(ARLO_USERNAME, ARLO_PASSWORD, '/posizione/del/tuo/gmail.credentials')

Prova la connessione come ti ho riportato un paio di paragrafi fa, stavolta dovresti riuscire e ottenere così qualche informazione sulla Base Station, bingo! :-)

Lo scopo del gioco

Risolta la questione legata alla casella di posta Gmail si passa oltre. Scopo del gioco è quindi dare la possibilità allo script tado° di attivare o disattivare anche il sistema Arlo in base al fatto che ci siano o meno dei dispositivi riconosciuti e collegati alla rete di casa (tramite il solito controllo sul MAC Address). Se tado° si imposta per andare in Away, allora è giusto che Arlo cominci a tenere d’occhio la casa e allertare in caso veda qualcosa che non va. Diversamente, si attiverà sia la modalità Home di tado° che lo stato di Disarm delle telecamere Arlo al rientro (e quindi riconnessione dei dispositivi).

Per fare ciò, mi è bastato ritoccare lo script tado.py e chiedergli di eseguire le operazioni necessarie:

if presence > 0:
        if str(homestate) == "AWAY":
            print("Found at least one device in home, set tado° to HOME")
            sendtotelegram(BOT_TOKEN,CHAT_ID,MSG_TADO_HOME)
            os.system("/usr/local/bin/python3.8 /home/pi/Scripts/Arlo/arlocam.py Disarm") # https://stackoverflow.com/a/3781869
            set_home_state(TADO_USER, TADO_PWD, TADO_TOKEN, True)
    else:
        if str(homestate) == "HOME":
            print("No devices found in home, set tado° to AWAY")
            sendtotelegram(BOT_TOKEN,CHAT_ID,MSG_TADO_AWAY)
            os.system("/usr/local/bin/python3.8 /home/pi/Scripts/Arlo/arlocam.py Arm") # https://stackoverflow.com/a/3781869
            set_home_state(TADO_USER, TADO_PWD, TADO_TOKEN, False)

Ti ho incollato il pezzo intero ma la vera modifica riguarda questo passaggio (nell’esempio di seguito analizzo la disattivazione di Arlo):

os.system("/usr/local/bin/python3.8 /home/pi/Scripts/Arlo/arlocam.py Disarm")

In pratica vado a richiamare Python (installato in /usr/local/bin) e lancio lo script di gestione Arlo passandogli come parametro il Disarm (si passa Arm in caso volessi attivare invece la videosorveglianza). Non faccio ulteriori controlli perché già ci pensa lo script di gestione tado°. L’unico controllo implementato nello script di gestione Arlo si occuperà di non sovrascrivere lo stato di attivazione / disattivazione stato nel caso in cui si trovi già nella giusta posizione (se Arm/Disarm è attivo non c’è bisogno di attivarlo/disattivarlo ancora, non credi?).

Non uso e non voglio Telegram

Non c’è problema, le variabili relative al token del bot e della chat in cui inviare gli alert sono infatti facoltative. Nello script però non ho attualmente previsto un controllo che tenga conto variabili volutamente lasciate vuote per evitare di richiamare la funzione di invio messaggio a Telegram. Se vuoi togliere di mezzo questo passaggio, ti basterà commentare le due chiamate alla funzione “sendtotelegram“, parlo di queste:

sendtotelegram(BOT_TOKEN,CHAT_ID,MSG_ARLO_ARM)
sendtotelegram(BOT_TOKEN,CHAT_ID,MSG_ARLO_DISARM)

Aggiungi un cancelletto prima (esempio: #sendtotelegram(BOT_TOKEN,CHAT_ID,MSG_ARLO_ARM)) e avrai così commentato la riga. Lo script funzionerà tranquillamente ma non proverà neanche a chiamare in causa Telegram.

In conclusione

Contrariamente all’altra volta non sarà necessario usare Crontab perché sarà lo script di tado° a “occuparsi di tutto“. Se vuoi comunque sapere quand’è l’ultima volta che lo script di Arlo ha effettuato il suo check / cambio di rotta, puoi modificarlo e aggiungere queste righe di codice prima di except Exception as e:

# Debug Crontab
with open('/home/pi/Scripts/Arlo/debug.txt', 'w') as f:
 f.write(datetime.datetime.now().strftime("%d/%m/%Y alle %H:%M:%S"))

Anche in questo caso potrebbe cambiare la posizione del file di testo da scrivere, occhio quindi a non prendere per “bibbia” cosa ti riporto io a titolo di esempio. Si potrebbe parlare di pulizia automatica della casella Gmail destinata alla sola ricezione delle email di Arlo per autenticazione MFA ma questo è altro argomento, così come il check batteria delle telecamere o l’allertarsi in caso di evento rilevato che sicuramente vorrò affrontare, ma non adesso, un passo alla volta (c’è ancora IFTTT a coprire queste esigenze).

L’articolo si conclude qui. Se vuoi – come sempre – l’area commenti è a tua totale disposizione per dubbi, ulteriori informazioni o suggerimenti riguardo possibili miglioramenti.

#StaySafe


Immagine di copertina: Etienne Girardet on Unsplash
Riconoscimenti (oltre quelli già riportati nell’articolo):
github.com/jeffreydwalter/arlo/issues/185
github.com/jeffreydwalter/arlo/wiki/Changing-Basestation-Modes-(Armed,-Disarmed,-Schedule,-etc.)

Correzioni, suggerimenti? Lascia un commento nell'apposita area qui di seguito o contattami privatamente.
Ti è piaciuto l'articolo? Offrimi un caffè! ☕ :-)

L'articolo potrebbe non essere aggiornato

Questo post è stato scritto più di 5 mesi fa, potrebbe non essere aggiornato. Per qualsiasi dubbio ti invito a lasciare un commento per chiedere ulteriori informazioni! :-)

Condividi l'articolo con i tuoi contatti:
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Commenti
Inline Feedbacks
View all comments