La Sveglia di Iron Man 3.0: Report Videosorveglianza AI e Meteo Reale con Home Assistant
Home Assistant Guide
Scritto da Vincenzo Caputo
Vi ricordate quando, qualche anno fa, pubblicai la prima versione della Sveglia di Iron Man? Era un progetto affascinante, ma a guardarlo oggi sembra quasi "preistoria". Era uno script rigido, che leggeva dati statici e ripeteva frasi sempre uguali.
Nel tempo, però, la nostra Smart Home è maturata. Abbiamo fatto un percorso preciso:
Abbiamo imparato a rendere gli script intelligenti con l'AI (qui la guida).
Abbiamo integrato l'analisi video AI per capire cosa vedono le telecamere (qui l'articolo).
Ci siamo spinti oltre implementando anche il riconoscimento facciale per essere ancora più precisi nella distinzione dei soggetti umani (leggi qui).
Oggi uniamo tutti questi puntini per creare la Sveglia 3.0. Non più un semplice lettore di meteo, ma un vero J.A.R.V.I.S. che analizza la sicurezza notturna, incrocia i dati di una stazione meteo professionale e ci parla con un tono naturale e ironico.
Vediamo come costruirla passo dopo passo.
A proposito vi ri-segnalo il link della musica che in tanti mi chiedete per realizzare questa sveglia:
Scarica QUI.
Quando ho iniziato a mettere mani a questo progetto, l'obiettivo era quello di ottenere un report mattutino fatto da: condizioni meteo, consigli per l'abbigliamento da indossare prima di uscire e report di sicurezza notturno basato sull'analisi di eventuali movimenti rilevati dalle telecamere perimetrali della mia abitazione.
Ottenere dunque qualcosa tipo: "buongiorno, sono le 6:30, all'esterno rilevo una temperatura di 10 gradi e un umidità del 60%, il tempo è sereno quindi ti consiglio di vestirti leggero. Durante la notte le telecamere hanno rilevato un gatto camminare in giardino e uno sconosciuto che si è avvicinato all'auto in cortile."
Oppure semplicemente "la notte è trascorsa tranquilla senza alcuna rilevazione".
Le sfide tecniche non sono mancate nel configurare il tutto. Vediamo passo passo com'è andata.
1. La "Memoria a Breve Termine": Il Paradosso del Gatto
Il primo ostacolo tecnico da superare è la gestione delle notifiche di sicurezza. Se interrogo semplicemente l'ultimo stato della telecamera, rischio di cadere nel "Paradosso del Gatto".
Immaginate questo scenario notturno:
Ore 03:00: Un malintenzionato si avvicina all'auto (Evento Critico).
Ore 03:15: Un gatto randagio passa davanti al sensore (Evento Minore).
Se la sveglia leggesse solo l'ultimo evento, alle 07:00 mi direbbe: "Buongiorno, stanotte è passato un gatto". L'informazione del ladro verrebbe sovrascritta e persa. Per evitare questo, dobbiamo creare una coda di memoria (FIFO).
La Soluzione: 3 Slot di Memoria
Ho creato 3 aiutanti di testo (input_text) in Home Assistant:
input_text.log_cam_tav_1 (Evento più recente)
input_text.log_cam_tav_2
input_text.log_cam_tav_3 (Evento più vecchio)
Se avete seguito la mia guida precedente sull'Analisi AI delle telecamere, avete già un'automazione che scatta quando c'è un movimento, fa la foto e la analizza. Ora dobbiamo solo dire a quell'automazione di salvare traccia di ciò che è accaduto.
Creiamo un piccolo Script "FIFO" (First-In, First-Out) che si occupa solo di aggiornare i registri.
alias: "Sicurezza - Scrittura Log FIFO"
icon: mdi:pencil-plus-outline
mode: queued
sequence:
# 1. Sposta lo Slot 2 nel 3 (Il più vecchio viene perso)
- action: input_text.set_value
target:
entity_id: input_text.log_cam_tav_3
data:
value: "{{ states('input_text.log_cam_tav_2') }}"
# 2. Sposta lo Slot 1 nel 2
- action: input_text.set_value
target:
entity_id: input_text.log_cam_tav_2
data:
value: "{{ states('input_text.log_cam_tav_1') }}"
# 3. Scrivi il NUOVO evento nello Slot 1
# Qui registriamo l'ora e una descrizione generica.
- action: input_text.set_value
target:
entity_id: input_text.log_cam_tav_1
data:
value: "{{ now().strftime('%H:%M') }} - Rilevata Presenza (Analisi AI avviata)"
Naturalmente aggiungete l'azione che esegue questo script all'automazione delle cam che scatta una foto quando rileva un movimento (fate sempre riferimento alla precedente guida).
Il "Neuralizzatore": Reset Serale
L'altra faccia della medaglia è evitare notizie vecchie (es. il corriere delle 16:00 di ieri). Per questo, ho creato un'automazione che scatta ogni sera (o all'attivazione dell'allarme notturno) e resetta tutti gli slot a "Nessuno". Se al mattino J.A.R.V.I.S. trova del testo, siamo sicuri che sia successo stanotte.
alias: "Sicurezza: Reset Log Serale (Neuralizzatore)"
description: "Pulisce la memoria degli eventi passati per preparare il report della notte."
mode: single
trigger:
# OPZIONE 1: Orario fisso (es. prima di andare a dormire)
- platform: time
at: "21:00:00"
# OPZIONE 2: Quando si attiva l'allarme notte (Scommenta se hai l'allarme)
# - platform: state
# entity_id: alarm_control_panel.allarme_casa
# to: "armed_night"
action:
# Sovrascrive tutti e 3 gli slot con la parola chiave "Nessuno"
# NOTA: È fondamentale usare "Nessuno" perché lo script AI filtra proprio questa parola.
- service: input_text.set_value
target:
entity_id:
- input_text.log_cam_tav_1
- input_text.log_cam_tav_2
- input_text.log_cam_tav_3
data:
value: "Nessuno"
Occhio perché la parola "Nessuno" non è scelta a caso. Nel codice Jinja (che troverete più avanti nella guida) che abbiamo scritto per l'AI (reject('match', 'Nessuno')), il sistema cerca esattamente quella stringa per capire che lo slot è vuoto. Se scrivessimo "Vuoto" o "Clear", la sveglia direbbe: "Allarme rilevato: Vuoto".
2. I Sensi: La precisione del "Doppio Controllo" (Ecowitt)
Le app meteo sbagliano spesso sul "qui e ora". Per un assistente domotico evoluto, sapere se sta davvero piovendo è fondamentale.
Per la Sveglia 3.0 ho integrato una stazione meteo Ecowitt (Gateway GW2000), sfruttando una sua caratteristica unica: il doppio sensore di pioggia. (Se volete approfondire l'hardware, vi rimando alla mia video recensione completa su MissingTech: Guarda il video qui).
Naturalmente nel caso non abbiate una stazione meteo personale, la parte che segue la potete ignorare del tutto e lasciare che la sveglia prelevi i dati dalle previsioni meteo come nella vecchia versione.
Nello script usiamo due entità distinte per non sbagliare mai:
Rain Status (Binary Sensor): È un sensore "tattile". Appena sente la vibrazione della prima goccia, passa a "Bagnato". È istantaneo.
Rain Rate (Piezo Sensor): Misura l'intensità in mm/h. Ci dice se è una pioggerellina o un nubifragio.
La nostra logica vince sul cloud perché combina i due dati:
Se il Rain Rate è alto (> 8 mm/h) → Diluvio.
Se il Rain Rate è 0, ma il Rain Status è attivo → Sta iniziando a piovere o pioviggina (e l'app meteo non lo sa ancora!).
Solo se entrambi sono "asciutti", ci fidiamo del meteo cloud.
3. Il Cervello: Prompt Engineering con logica "Jinja First"
Qui è dove molti sbagliano: danno all'AI i dati grezzi e sperano che faccia i calcoli giusti. Ma le AI generative (LLM) non sono calcolatrici e spesso "allucinano".
La strategia vincente che abbiamo adottato si chiama "Jinja First". Usiamo il motore di template di Home Assistant per fare i calcoli logici e passiamo all'AI solo i fatti compiuti.
Invece di dire all'AI: "Vedi tu se piove con questi dati..." Le diciamo: "Piove (dato certo). Temperatura 7.4°C. Crea una frase ironica."
Ecco lo script definitivo che invia il prompt a Google Gemini:
alias: "Sveglia Famiglia AI 3.0 Final"
sequence:
- action: conversation.process
data:
text: >-
{# --- 1. PRE-CALCOLO LOGICA METEO (Jinja) --- #}
{# Leggiamo i sensori reali Ecowitt #}
{% set temp = states('sensor.gw2000a_outdoor_temperature') | float(0) | round(1) %}
{% set wind = states('sensor.gw2000a_wind_speed') | float(0) | round(1) %}
{% set hum = states('sensor.gw2000a_outdoor_humidity') | float(0) | round(0) %}
{# I DUE SENSORI PIOGGIA (Importante: usiamo entrambi!) #}
{% set rain_rate = states('sensor.gw2000a_piezo_rain_rate') | float(0) %}
{% set is_raining = is_state('binary_sensor.gw2000a_rain_status', 'on') %}
{# Logica decisionale deterministica #}
{% if rain_rate > 8 %}
{% set meteo_status = "Sta diluviando pesantemente." %}
{% set consiglio = "Impermeabile pesante obbligatorio." %}
{% elif rain_rate > 0 or is_raining %}
{% set meteo_status = "Sta piovendo." %}
{% set consiglio = "Prendi l'ombrello." %}
{% else %}
{# Se asciutto, usiamo il meteo cloud tradotto in italiano #}
{% set meteo_status = "Il cielo è " ~ state_translated('weather.casa') ~ " (Niente pioggia)." %}
{# Usiamo l'accento su vèstiti per correggere la pronuncia del TTS #}
{% set consiglio = "Niente ombrello, vèstiti a strati." %}
{% endif %}
{# --- 2. FILTRAGGIO SICUREZZA --- #}
{% set l1 = states('input_text.log_cam_tav_1') %}
{% set l2 = states('input_text.log_cam_tav_2') %}
{% set l3 = states('input_text.log_cam_tav_3') %}
{# Creiamo una lista escludendo i 'Nessuno' #}
{% set eventi_reali = [l1, l2, l3] | reject('match', 'Nessuno') | list %}
{% if eventi_reali | length > 0 %}
{# Uniamo tutti gli eventi trovati per non perderne nessuno #}
{% set security_status = "ATTENZIONE, RILEVATI MULTIPLI EVENTI: " ~ eventi_reali | join('. ') %}
{% else %}
{% set security_status = "Nessun evento rilevato. Notte tranquilla." %}
{% endif %}
{# --- 3. IL PROMPT PER GEMINI --- #}
Sei J.A.R.V.I.S., il maggiordomo di casa.
DATI CERTI (Usali per il report, non inventare nulla):
- Ora: {{ now().strftime('%H:%M') }}
- Meteo: {{ meteo_status }}
- Temperatura: {{ temp }} °C (Leggi anche i decimali!)
- Umidità: {{ hum }} %
- Vento: {{ wind }} km/h
- Consiglio Tecnico: {{ consiglio }}
- Report Sicurezza: {{ security_status }}
COMPITO:
Genera un messaggio vocale fluido, "British", ironico e sintetico (max 60 parole).
1. Saluta e dì l'ora.
2. Fai un report meteo citando Temperatura, Umidità e Vento se rilevanti.
3. Integra il consiglio sull'abbigliamento.
4. Concludi con la Sicurezza: se c'è allarme, ELENCA I DETTAGLI DEGLI EVENTI, altrimenti conferma la quiete.
agent_id: conversation.google_generative_ai
response_variable: gemini_response
# Output Audio TTS
- action: chime_tts.say
data:
message: "{{ gemini_response.response.speech.plain.speech }}"
# ... qui va la tua configurazione media player e suono ...
4. Il Risultato Finale
Quando la sveglia scatta, l'esperienza è completamente diversa dal solito assistente vocale. La musica si abbassa leggermente e la voce (sintetizzata, ma resa umana dal testo di Gemini) dice:
"Buongiorno. Sono le 07:30. Il cielo è sereno con una temperatura precisa di 7.4 gradi, ma con quell'umidità al 90% sentirai più freddo, quindi copriti bene. Durante la notte tutto tranquillo, tranne un gatto rilevato in giardino alle 03:15."
Abbiamo ottenuto precisione (grazie a Jinja ed Ecowitt), memoria storica (grazie alla logica FIFO) e naturalezza (grazie a Gemini). Questa è la vera domotica "intelligente".
5. L'Interfaccia: Il Pannello di Controllo J.A.R.V.I.S.
Tony Stark non modifica il codice ogni sera per cambiare l'ora della sveglia. Usa un'interfaccia olografica. Noi faremo lo stesso (o quasi) su Home Assistant Dashboard.
Per gestire il sistema, ho creato prima di tutto questi Aiutanti (Helpers) da UI:
input_datetime.orario_sveglia_jarvis: Per impostare l'ora.
input_boolean.stato_sveglia_jarvis: L'interruttore generale ON/OFF.
input_select.giorni_sveglia_jarvis: Per scegliere la frequenza (Tutti i giorni, Solo Feriali, ecc.).
Una volta creati gli aiutanti, serve una veste grafica. Vi propongo due versioni: una classica e una moderna.
Opzione A: Stile "Stark Industries" (Classico)
Questa card è solida, funzionale e usa un'immagine di testata evocativa. Permette di vedere e controllare tutto in un unico blocco.
type: vertical-stack
cards:
- type: picture
image: /local/Iron_Man_Mark_7_diag_battle_jayse_hansen.jpg # Assicuratevi di avere l'immagine nella cartella www
tap_action:
action: none
- type: entities
title: J.A.R.V.I.S. Protocol
show_header_toggle: false
entities:
- entity: input_boolean.stato_sveglia_jarvis
name: Protocollo Sveglia
icon: mdi:shield-sync
- entity: input_datetime.orario_sveglia_jarvis
name: Orario Risveglio
icon: mdi:clock-digital
- entity: input_select.giorni_sveglia_jarvis
name: Programmazione
icon: mdi:calendar-clock
# Questo pulsante lancia lo script manualmente per testare il sistema
- entity: script.sveglia_famiglia_ai_3_0_final
name: Test Manuale Sistemi
icon: mdi:play-network-outline
action_name: AVVIA
tap_action:
action: call-service
service: script.sveglia_famiglia_ai_3_0_final
Opzione B: Stile "Moderno" (Mushroom Cards)
Per chi ama il design pulito e i pulsanti grandi, questa versione richiede l'installazione di Mushroom Cards (via HACS). È molto più interattiva e visivamente appagante.
type: vertical-stack
cards:
- type: picture
image: /local/iron.jpg
tap_action:
action: none
- type: custom:mushroom-title-card
title: J.A.R.V.I.S.
subtitle: Protocollo Risveglio Famiglia
- type: horizontal-stack
cards:
- type: custom:mushroom-entity-card
entity: input_boolean.stato_sveglia_jarvis
name: Stato
layout: vertical
icon: mdi:robot-industrial
icon_color: "{{ 'red' if is_state('input_boolean.stato_sveglia_jarvis', 'on') else 'grey' }}"
tap_action:
action: toggle
- type: custom:mushroom-entity-card
entity: input_datetime.orario_sveglia_jarvis
name: Orario
layout: vertical
icon: mdi:alarm
icon_color: amber
tap_action:
action: more-info
- type: custom:mushroom-select-card
entity: input_select.giorni_sveglia_jarvis
name: Programmazione
icon: mdi:calendar-multiselect
icon_color: blue
layout: horizontal
- type: custom:mushroom-template-card
primary: Avvia Test Manuale
secondary: Analisi Meteo & Sicurezza
icon: mdi:fingerprint
icon_color: cyan
layout: horizontal
tap_action:
action: call-service
service: script.sveglia_famiglia_ai_3_0_final # Assicurati che il nome corrisponda al tuo script finale
multiline_secondary: true
fill_container: true
A questo punto abbiamo lo script e abbiamo le card, ci manca solo l'automazione che unisce il tutto.
Il Codice dell'automazione: "Trigger Sveglia con Filtro Giorni"
Per farla funzionare, assicurati che nel tuo Helper (input_select.giorni_sveglia_jarvis) le opzioni siano scritte esattamente così (o modifica il codice di conseguenza):
Tutti i giorni
Lunedì - Venerdì
Solo Weekend
Ecco il codice YAML da copiare:
alias: "Sveglia J.A.R.V.I.S. 3.0 - Logic UI"
description: "Sveglia AI che rispetta orario UI e giorni selezionati."
mode: single
triggers:
# TRIGGER DINAMICO: Scatta all'orario impostato nella dashboard
- trigger: time
at: input_datetime.orario_sveglia_jarvis
conditions:
# 1. MASTER SWITCH: Se è spento, non fa nulla
- condition: state
entity_id: input_boolean.stato_sveglia_jarvis
state: "on"
# 2. FILTRO GIORNI (Tutti, Lun-Ven, Weekend)
- condition: or
conditions:
# Caso A: Tutti i giorni
- condition: state
entity_id: input_select.giorni_sveglia_jarvis
state: "Tutti i giorni"
# Caso B: Lunedì - Venerdì
- condition: and
conditions:
- condition: state
entity_id: input_select.giorni_sveglia_jarvis
state: "Lunedì - Venerdì"
- condition: time
weekday: [mon, tue, wed, thu, fri]
# Caso C: Solo Weekend
- condition: and
conditions:
- condition: state
entity_id: input_select.giorni_sveglia_jarvis
state: "Solo Weekend"
- condition: time
weekday: [sat, sun]
actions:
# Chiama lo script AI
- action: script.sveglia_famiglia_ai_3_0_final
Questa automazione sfrutta il trigger dinamico (at: input_datetime...). È una delle funzioni più potenti di Home Assistant perché permette di cambiare l'orario di scatto da interfaccia grafica senza dover modificare il codice YAML dell'automazione.
Restiamo Connessi
Se volete ricevere una notifica istantanea ogni volta che pubblico una nuova guida o un aggiornamento su queste integrazioni AI (e altri interessanti contenuti), vi invito a iscrivervi al mio Canale Telegram ufficiale:
Iscriviti al Canale Telegram di Vincenzo Caputo
Guarda il video su MissingTech
Volete vedere (anzi, sentire!) la nuova sveglia di Iron Man 3.0 in azione? Nel video dedicato sul mio canale YouTube MissingTech, vi mostrerò il test dal vivo e una prova completa con la stupenda grafica delle nuove card! Buona visione!
Produrre e aggiornare contenuti su vincenzocaputo.com richiede molto tempo e lavoro. Se il contenuto che hai appena letto è di tuo gradimento e vuoi supportarmi, clicca uno dei link qui sotto per fare una donazione.