Siri?Alexa?Google? No il mio assistente vocale si chiama Jarvis, ed è completamente personale!

Quante volte abbiamo sentito parlare degli assistenti vocali?

Che bella invenzione, facile comoda e sicuramente necessaria nel nuovo panarama tecnologico… ma, quali sono le problematiche relative a questi assistenti vocali? cosa sappiamo esattamente rispetto agli algoritmi di apprendimento automatici che sono alla base di questi sistemi o ancora meglio, che fine fanno le nostre registrazioni vocali continue (perchè questo è, registrano sempre fintantoché dalle registrazione non esce qualcosa che risveglia l’assistente es. Alexa chiama).

Interessato al mondo degli assistenti personali digitali ma evidentemente troppo propenso alla sicurezza e alla necessità di fare da me ogni singola innovazione proposta, ho deciso di realizzare Jarvis.

Si si, avete capito bene, Jarvis l’assistente di IronMan ovvero Tony Stark’s che nei vari episodi riesce sempre a capire e interpretare i comandi di Tony e avere una certa autonomia di azione.

Si Jarvis è un qualcosa di troppo avanzato, qui stiamo proponendo il figlio di Jarvis neonato ma sicuramente potrebbe essere un ottimo spunto, come tutti gli articoli di questo blog, per fare di meglio e sfruttare come base (anche l’idea) di creare qualcosa che prima non c’era o meglio non c’era del “tutto personale”.

Andiamo al sodo, dopo avervi spiegato l’idea di partenza, vi descrivo il progetto.

Cosa ho utilizzato?

  • Raspberry pi 4 con 4GB di RAM
  • Microfono USB
  • Casse esterne con classico Jack audio
  • Tanta ma tanta pazienza

Lianguaggio di programmazione Python, con due listati diversi:

  • jarvis_command.py : Esegue i comandi attraverso la lettura di una parziale parola della trascrizione del vocale fatta da jarvice_voice.py
  • Jarvis_voice.py: Trascrive semplicemente i comandi vocali su un file di testo che jarvis_command leggerà per trovare le parole di attivazione ai comandi.

Difficile? Più a farsi che a dirsi.

In sostanza l’idea è stata quella di trascrivere in un file di testo (che per comodità chiamerò command.txt) le registrazioni vocali che vengono date a Jarvis utilizzando l’IF appunto della parola Jarvis ( se la stringa Jarvis nella frase trascritta non viene letta l’assistente vocale non si attiverà) in un ciclo While infinito dove il nostro programmino attenderà sempre che venga detto qualcosa, se cosi non fosse o non viene capito riparte dall’ascolto; altrimenti se la stringa di attivazione viene riconosciuta trascriverà il testo in file (command.txt) che a sua volta verrà letto da jarvis_command.py.

Il jarvis_command.py legge in un ciclo infinito il file di testo ed estrapola la stringa ricercando al suo interno le parola che attivano le funzioni, e se trovate, effettuarà il comando definito in funzione ed attiverà un sintonizzatore vocale che leggerà il testo pre-definito per il comando dato.

es. concreto:

Jarvis accendi la luce –> command.txt –> if “accendi” in txt –> gtts.(“Ho acceso la luce”).save(“audio.mp3”) –> playsound(audio.mp3) –> funzione accendi().

Vi mostro il contenuto del file di jarvis_voice.py:

#python
import speech_recognition as sr  

r = sr.Recognizer()   
m = sr.Microphone()

while True:
    with sr.Microphone() as source:   
        r.adjust_for_ambient_noise(source)                                                                    
        print("Parla con Jarvis...")                                                                                   
        audio = r.listen(source)   
    try:
        jarvis_recog = r.recognize_google(audio, language="it-IT")
        if "Jarvis" in jarvis_recog:
            file = open("command.txt","w") 
            file.write(jarvis_recog)  
            file.close() 
            print("Hai detto: " + jarvis_recog)
        else:
            print("devi dire Jarvis per avere una risposta!")
    except sr.UnknownValueError:
        print("Non riesco a capire cosa hai detto.")
    except sr.RequestError as e:
        print("Mi dispiace non riesco a stabilire la connessione correttamente; {0}".format(e))

è facile interpretare il listato, ma vi farò un appunto su:

    jarvis_recog = r.recognize_google(audio, language="it-IT")

Perchè per trascrivere ciò chediciamo in testo, ho avuto bisogno di Google o meglio delle API di google (gratuite) utilizzate attraverso il modulo speech_recognition disponibile per python attraverso un pip install speechrecognition.

Lanciato lo script, esso attenderà che venga detta sempre qualcosa riscrivendo lo stesso file di testo con quello che viene detto, con la sola clausula che, come detto, all’interno della frase ci sia la parola Jarvis.

Vi mostro adesso il contenuto del file di jarvis_command.py:

#python
from selenium import webdriver
from pyvirtualdisplay import Display
import time,random,collections,os
from gtts import gTTS 
import subprocess


def voce(text):
    print(text)
    tts = gTTS(text=text, lang='it')
    tts.save("audio.mp3")
    subprocess.run(["omxplayer", "audio.mp3"]) //player predefinito per RaspBian
    os.remove("audio.mp3")

def ewelink_luce():
    text = "Accendo la luce in garage"
    voce(text)
    browser.find_element_by_xpath('//div[2]/div/img').click() #accendi luce

def ewelink_garage():
    text = "Apro il garage"
    voce(text)
    browser.find_element_by_xpath('//div[2]/div[2]/div/div/img').click() #apri garage

text = "Avvio sistema centrale in corso..."
voce(text)

display = Display(visible=0, size=(800, 600))
display.start()
browser = webdriver.Firefox()
browser.get('https://web.ewelink.cc') 
//mi serve per l'accesso alle API dei SONOFF. Il codice da qui è stato eliminato perchè accede alla piattaforma con le credenziali personali.

while True:
    file = open("command.txt", "r") 
    lettura = file.read() 
    if "accendi" in lettura:
        ewelink_luce()   
        file = open("command.txt","w") 
        file.write("")  
        file.close()      
    if "spegni" in lettura:
        ewelink_luce()   
        file = open("command.txt","w") 
        file.write("")  
        file.close()
    if "apri" in lettura:
        ewelink_garage()   
        file = open("command.txt","w") 
        file.write("")  
        file.close()
    if "chiudi" in lettura:
        ewelink_garage()   
        file = open("command.txt","w") 
        file.write("")  
        file.close()

Come in altri articoli del blog, vi ho già parlato di Selenium che effettua lo scraping del web o emula il funzionamento di un browser attraverso degli attivatore ovvero dei TAG che impostiamo a priori.

Questo mi è servito per accedere alle API (non preseti di EWELINK, ovvero il portale dei contatti SONOFF) per poter effettuare l’accensione e lo spegnimento del contatto LAMPADA da me impostato.

Una menzione particolare va a from gtts import gTTS, un’API sempre Google che permette di trasformare il testo in voce salvandolo poi in audio da riprodurre.

E’ ovvio che come funzione può essere implementata la qualsiasi, il funzionamento di base è lo stesso… possiamo inventarci qualsiasi cosa attraverso API o meno, ed impostare una parola di attivazione.

Il due script python si impostano all’accensione del sistema operativo RaspBian attraverso il crontab di sistema con una semplice aggiunta:

@reboot nohub python jarvis_voice.py &
@reboot nohub python jarvis_command.py &

Ancora non disponibile, metterò come consueto, un video su youtube che fa effettivamente vedere il funzionameto corretto dello stesso.

Al prossimo articolo, con Jarvis in Telegram e perchè no, Jarvis in remoto dal cellulare!!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *