Con Blink succede sempre la stessa cosa: si disarma il sistema per entrare in casa senza farsi riprendere, o per passare un pomeriggio in giardino, e poi ci si dimentica di riarmarlo. Lo si scopre la sera, o il giorno dopo, quando le telecamere sono rimaste spente tutto il tempo.
L'obiettivo di questa guida è togliere la memoria dall'equazione:
- riarmo automatico dopo un numero di minuti scelto da chi usa il sistema;
- comandi da WhatsApp, per armare, disarmare o rimandare il riarmo senza aprire l'app;
- un avviso a ogni disarmo e riarmo, con chi l'ha fatto, e uno se l'armamento non riesce.
Parto dalle telecamere già in Home Assistant, come nella guida Telecamere Blink in Home Assistant. Per la parte WhatsApp servono il gateway con l'elenco dei mittenti autorizzati e i ruoli Admin e Utente con le categorie; senza, il riarmo automatico e la dashboard funzionano lo stesso.
🧠 Come ragiona Blink in Home Assistant
Prima di scrivere una riga di YAML conviene avere chiaro cosa si arma.
- Si arma il sistema, non la telecamera. Il sistema è il modulo di sincronizzazione, e in Home Assistant è un'entità alarm_control_panel, per esempio
alarm_control_panel.blink_casa. È esattamente quello che fa il pulsante dell'app: arma o disarma tutte le telecamere del modulo insieme. - Le telecamere hanno un interruttore «rilevamento del movimento», ma da solo non basta: una telecamera registra solo se il suo sistema è armato. Per questa guida conta solo lo stato del sistema.
- Considera solo i sistemi con telecamere. Ogni entità
cameradi Blink ha l'attributosync_module, con il nome del modulo a cui appartiene. Ricavando l'elenco dei sistemi da lì, un vecchio modulo vuoto o offline rimasto nell'account non entra nei conti e non genera un errore a ogni tentativo di armarlo.
⏱️ Il limite da conoscere: Blink si aggiorna ogni 5 minuti
- L'integrazione Blink interroga il cloud ogni 5 minuti, e l'intervallo non si cambia.
- Un disarmo fatto dall'app Blink arriva in Home Assistant fino a 5 minuti dopo, e il conteggio dei minuti del riarmo parte da quando Home Assistant lo vede, non da quando hai premuto il pulsante.
- Il «da quando» è il
last_changeddell'entità: dopo un riavvio di Home Assistant riparte da zero, quindi un sistema disarmato riceve di nuovo tutti i minuti di attesa. - I comandi dati da Home Assistant (dashboard, WhatsApp, riarmo automatico) invece si vedono subito, perché l'integrazione rilegge lo stato appena eseguito il comando.
🎛️ Le entità di configurazione
Tutto quello che l'utente può cambiare sta in pochi helper, così si modifica dalla dashboard o da WhatsApp senza toccare il YAML.
| Helper | A cosa serve |
|---|---|
input_boolean.blink_riarmo_auto | Riarmo automatico acceso o spento |
input_number.blink_riarmo_minuti | Dopo quanti minuti riarmare; 0 vuol dire subito, al primo controllo |
input_text.blink_riarmo_programmato | Riarmo una tantum, per esempio «disarma per 60 minuti»: contiene l'ora del riarmo e vale anche con l'automatico spento |
input_text.blink_ultimo_comando | L'ultimo comando dato da Home Assistant, nel formato azione|chi|ora: serve per scrivere chi ha armato o disarmato |
input_boolean.blink_errore_in_corso | Acceso durante una serie di errori, per non ripetere l'avviso a ogni tentativo |
input_text.blink_ultimo_errore | Il motivo dell'ultimo errore, da mostrare in dashboard |
input_boolean:
blink_riarmo_auto:
name: Blink riarmo automatico
icon: mdi:shield-refresh
blink_errore_in_corso:
name: Blink errore in corso
input_number:
blink_riarmo_minuti:
name: Blink riarma dopo (minuti)
min: 0
max: 240
step: 5
mode: box
unit_of_measurement: min
input_text:
blink_riarmo_programmato:
name: Blink riarmo programmato
max: 40
blink_ultimo_comando:
name: Blink ultimo comando
max: 255
blink_ultimo_errore:
name: Blink ultimo errore
max: 255
📊 Il sensore con l'elenco dei sistemi
Un template sensor raccoglie in un attributo tutto quello che serve sui sistemi: stato, da quando, stato del modulo, numero di telecamere e ora del prossimo riarmo. Le automazioni e i comandi WhatsApp leggono da qui, invece di ripetere gli stessi calcoli in tre posti.
template:
- sensor:
- name: Blink sistemi
unique_id: blink_sistemi
state: "{{ this.attributes.sistemi | default([]) | count }}"
attributes:
sistemi: >-
{% set camere = integration_entities('blink') | select('match', 'camera\.') | list %}
{% set moduli = camere | map('state_attr', 'sync_module') | reject('none') | unique | list %}
{% set auto = is_state('input_boolean.blink_riarmo_auto', 'on') %}
{% set minuti = states('input_number.blink_riarmo_minuti') | float(0) | int %}
{% set prog = as_datetime(states('input_text.blink_riarmo_programmato')) %}
{% set ns = namespace(l=[]) %}
{% for m in moduli %}
{% set p = 'alarm_control_panel.blink_' ~ (m | slugify) %}
{% set da = states[p].last_changed if states[p] is not none else none %}
{% set riarmo = '' %}
{% if is_state(p, 'disarmed') %}
{% if prog is not none %}{% set riarmo = (prog | as_local).isoformat() %}
{% elif auto and da is not none %}{% set riarmo = ((da + timedelta(minutes=minuti)) | as_local).isoformat() %}
{% endif %}
{% endif %}
{% set ns.l = ns.l + [{
'entity': p, 'nome': m, 'stato': states(p),
'da': da.isoformat() if da is not none else '',
'modulo': state_attr(p, 'status') | string,
'camere': camere | map('state_attr', 'sync_module') | select('eq', m) | list | count,
'riarmo': riarmo }] %}
{% endfor %}
{{ ns.l }}
Il nome dell'entità del sistema si ricava dal nome del modulo: il modulo «CASA» diventa alarm_control_panel.blink_casa. Se hai rinominato le entità, sostituisci quella riga con una mappa fissa modulo → entità. Il riarmo programmato, se c'è, vince sull'automatico: chi scrive «disarma per 60 minuti» vuole 60 minuti, non i 30 dell'impostazione generale.
Per la dashboard serve anche un valore unico, l'ora del prossimo riarmo, ed è un secondo sensore:
- name: Blink prossimo riarmo
unique_id: blink_prossimo_riarmo
device_class: timestamp
state: >-
{% set l = state_attr('sensor.blink_sistemi', 'sistemi') or [] %}
{% set orari = l | selectattr('stato', 'eq', 'disarmed') | map(attribute='riarmo') | reject('eq', '') | sort | list %}
{{ orari[0] if orari | count > 0 else none }}
🪞 Perché un sensore a parte e non lo stato del primo
- Verrebbe naturale mettere il prossimo riarmo nello stato di
sensor.blink_sistemi, calcolandolo dathis.attributes.sistemi. - Ma in un template sensor
thisè lo stato precedente dell'entità: lo stato verrebbe calcolato sugli attributi del giro prima, e la dashboard mostrerebbe un orario in ritardo di un aggiornamento (per esempio ancora vuoto subito dopo un disarmo). - Il secondo sensore legge l'attributo già aggiornato del primo e si ricalcola quando il primo cambia: il valore è sempre quello giusto. Lo stato del primo, il numero di sistemi, invece non cambia quasi mai, e lì il ritardo non conta.
🔁 L'automazione di riarmo
Parte ogni minuto, cerca i sistemi disarmati con il riarmo scaduto e li passa allo script che arma. Non riprova più di una volta ogni 5 minuti: se il modulo è offline, martellare il cloud Blink ogni minuto non lo fa tornare online prima.
automation:
- id: blink_riarmo_automatico
alias: Blink - riarmo automatico
mode: single
triggers:
- trigger: time_pattern
minutes: "/1"
variables:
scaduti: >-
{% set l = state_attr('sensor.blink_sistemi', 'sistemi') or [] %}
{% set ns = namespace(e=[]) %}
{% for s in l if s.stato == 'disarmed' and s.riarmo != '' and as_datetime(s.riarmo) <= now() %}
{% set ns.e = ns.e + [s.entity] %}
{% endfor %}
{{ ns.e }}
conditions:
- "{{ scaduti | count > 0 }}"
# al massimo un tentativo ogni 5 minuti
- >-
{% set t = state_attr('script.blink_arma', 'last_triggered') %}
{{ t is none or now() - t > timedelta(minutes=5) }}
actions:
- action: input_text.set_value
target:
entity_id: input_text.blink_ultimo_comando
data:
value: "arma|riarmo automatico|{{ now().isoformat() }}"
- action: script.blink_arma
data:
sistemi: "{{ scaduti }}"
Il controllo dei 5 minuti usa il last_triggered dello script, che Home Assistant tiene già: nessun helper in più. E sta direttamente nella condizione, non in una variabile, perché nelle variables la data diventerebbe un testo e la sottrazione con now() darebbe errore.
🔒 Lo script che arma e verifica
Chiamare alarm_arm_away non basta: il comando può partire e Blink non confermare, perché il modulo è offline o il cloud non risponde. Lo script quindi arma, aspetta la conferma, e se non arriva capisce perché.
- Chiama
alarm_control_panel.alarm_arm_awayconcontinue_on_error: true, così un errore del cloud non ferma lo script. - Aspetta con
wait_templatefino a 45 secondi che tutti i sistemi sianoarmed_away. - Se non arriva, forza una rilettura con
homeassistant.update_entity(senza aspettare il giro dei 5 minuti) e aspetta altri 30 secondi. - Se ancora niente, ricava il motivo e lo salva.
- Manda l'avviso d'errore solo se non è già in corso una serie di errori.
script:
blink_arma:
alias: Blink - arma
mode: single
max_exceeded: silent
fields:
sistemi:
description: Elenco dei sistemi da armare (vuoto = tutti)
sequence:
- variables:
lista: >-
{% set tutti = (state_attr('sensor.blink_sistemi', 'sistemi') or []) | map(attribute='entity') | list %}
{{ sistemi if sistemi is defined and sistemi | count > 0 else tutti }}
- action: alarm_control_panel.alarm_arm_away
continue_on_error: true
target:
entity_id: "{{ lista }}"
- wait_template: "{{ lista | reject('is_state', 'armed_away') | list | count == 0 }}"
timeout: "00:00:45"
- if: "{{ not wait.completed }}"
then:
- action: homeassistant.update_entity
continue_on_error: true
target:
entity_id: "{{ lista }}"
- wait_template: "{{ lista | reject('is_state', 'armed_away') | list | count == 0 }}"
timeout: "00:00:30"
- variables:
mancanti: "{{ lista | reject('is_state', 'armed_away') | list }}"
- if: "{{ mancanti | count > 0 }}"
then:
- variables:
motivo: >-
{% set p = mancanti[0] %}
{% if states(p) in ['unavailable', 'unknown'] %}integrazione non disponibile
{% elif (state_attr(p, 'status') | string | lower) == 'offline' %}modulo offline
{% else %}Blink non ha confermato{% endif %}
- action: input_text.set_value
target:
entity_id: input_text.blink_ultimo_errore
data:
value: "{{ motivo | trim }} ({{ now().strftime('%H:%M') }})"
- if: "{{ is_state('input_boolean.blink_errore_in_corso', 'off') }}"
then:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.blink_errore_in_corso
- action: script.avviso_categoria
data:
categoria: telecamere
testo: |-
*⚠️ BLINK NON ARMATO*
━━━━━━━━━━━━━━
Motivo: {{ motivo | trim }}
_Riprovo ogni 5 minuti, ti avviso quando riesce_
script.avviso_categoria sta per lo script che già manda un messaggio agli Admin e agli Utenti iscritti a una categoria, quello della guida sui ruoli. Lo script non spegne l'errore quando l'armamento riesce: lo fa l'automazione degli avvisi qui sotto, che così può scrivere «errore risolto» nel messaggio di riarmo.
🔔 Un avviso a ogni cambio di stato
L'avviso non parte dai comandi ma dal cambio di stato del sistema, quindi arriva qualunque sia la fonte: WhatsApp, riarmo automatico, dashboard o app Blink. Tre regole:
- Ignorare i passaggi da e verso
unavailable. A ogni riavvio di Home Assistant, o quando il cloud Blink non risponde, il sistema passa daunavailableaarmed_away: senza questo filtro arriverebbe un falso «Blink riarmato» ogni volta. - Scrivere chi è stato, in quest'ordine: il comando registrato in
blink_ultimo_comandonegli ultimi 3 minuti, se è la stessa azione (WhatsApp con il nome, oppure riarmo automatico); poi ilcontext.user_iddel nuovo stato, che c'è quando il comando arriva dalla dashboard di Home Assistant; altrimenti «app Blink o altra fonte». - Dire cosa succede dopo: l'avviso di disarmo dice a che ora avverrà il riarmo, o che il riarmo automatico è spento; quello di riarmo dice da quanto il sistema era disarmato.
automation:
- id: blink_avviso_stato
alias: Blink - avviso cambio stato
mode: queued
triggers:
- trigger: state
entity_id: alarm_control_panel.blink_casa
conditions:
- "{{ trigger.from_state is not none and trigger.to_state is not none }}"
- "{{ trigger.from_state.state not in ['unavailable', 'unknown'] }}"
- "{{ trigger.to_state.state in ['armed_away', 'disarmed'] }}"
variables:
armato: "{{ trigger.to_state.state == 'armed_away' }}"
sistema: "{{ trigger.to_state.name }}"
chi: >-
{% set c = states('input_text.blink_ultimo_comando').split('|') %}
{% set azione = 'arma' if trigger.to_state.state == 'armed_away' else 'disarma' %}
{% set quando = as_datetime(c[2]) if c | count == 3 else none %}
{% set uid = trigger.to_state.context.user_id %}
{% if quando is not none and c[0] == azione and now() - quando < timedelta(minutes=3) %}{{ c[1] }}
{% elif uid %}dashboard ({{ states.person | selectattr('attributes.user_id', 'eq', uid) | map(attribute='name') | first | default('utente di Home Assistant') }})
{% else %}app Blink o altra fonte{% endif %}
durata: >-
{% set m = ((now() - trigger.from_state.last_changed).total_seconds() / 60) | int %}
{{ m ~ ' min' if m < 60 else (m // 60) ~ ' h ' ~ (m % 60) ~ ' min' }}
riarmo: >-
{% set prog = as_datetime(states('input_text.blink_riarmo_programmato')) %}
{% if prog is not none %}alle {{ (prog | as_local).strftime('%H:%M') }}
{% elif is_state('input_boolean.blink_riarmo_auto', 'on') %}alle {{ ((trigger.to_state.last_changed + timedelta(minutes=states('input_number.blink_riarmo_minuti') | float(0))) | as_local).strftime('%H:%M') }}
{% else %}spento{% endif %}
risolto: "{{ is_state('input_boolean.blink_errore_in_corso', 'on') }}"
actions:
- if: "{{ armato }}"
then:
- action: script.avviso_categoria
data:
categoria: telecamere
testo: |-
*🔒 BLINK RIARMATO*
━━━━━━━━━━━━━━
📹 Sistema: {{ sistema }}
👤 Da: {{ chi | trim }}
⏱️ Era disarmato da {{ durata | trim }}{% if risolto %}
✅ Errore risolto{% endif %}
- action: input_boolean.turn_off
target:
entity_id: input_boolean.blink_errore_in_corso
- action: input_text.set_value
target:
entity_id: input_text.blink_riarmo_programmato
data:
value: ""
else:
- action: script.avviso_categoria
data:
categoria: telecamere
testo: |-
*🔓 BLINK DISARMATO*
━━━━━━━━━━━━━━
📹 Sistema: {{ sistema }}
👤 Da: {{ chi | trim }}
🔁 Riarmo: {{ riarmo | trim }}
_Scrivi blink arma per riarmarlo prima_
Due dettagli. L'ora del riarmo nell'avviso è calcolata qui dentro e non letta da sensor.blink_prossimo_riarmo: il sensore si aggiorna sullo stesso cambio di stato, e non c'è garanzia che lo faccia prima dell'automazione. E al riarmo il riarmo programmato si svuota, così una vecchia ora non resta lì a valere per il disarmo successivo.
Su WhatsApp l'avviso di riarmo cita il messaggio del disarmo, così nella chat si vede a colpo d'occhio quale disarmo è stato chiuso. Serve un gateway che restituisca l'id del messaggio inviato e accetti un messaggio in risposta: si salva l'id dell'avviso di disarmo in un helper di testo e lo si passa all'avviso di riarmo. Se il tuo gateway non lo permette, il resto funziona uguale.
Esempio: disarmo da WhatsApp, riarmo automatico dopo 30 minuti e un errore
💬 I comandi WhatsApp
| Messaggio | Cosa fa | Chi può |
|---|---|---|
blink | Stato di ogni sistema, da quando, prossimo riarmo | Admin e Utenti con Telecamere |
blink arma | Arma tutti i sistemi | Admin e Utenti con Telecamere |
blink disarma | Disarma; il riarmo segue l'impostazione automatica | Admin e Utenti con Telecamere |
blink disarma 60 | Disarma e riarma fra 60 minuti, anche con l'automatico spento | Admin e Utenti con Telecamere |
blink auto on · blink auto off | Accende o spegne il riarmo automatico | Solo Admin |
blink minuti 30 | Imposta dopo quanti minuti riarmare | Solo Admin |
I permessi seguono la stessa logica degli altri comandi di casa. I comandi base appartengono alla categoria 📹 Telecamere: li usano gli Admin e gli Utenti che hanno quella categoria accesa. Le impostazioni (auto e minuti) cambiano il comportamento per tutti, quindi sono solo per gli Admin. E aiuto mostra a ognuno solo i comandi che può usare: un Utente con Telecamere vede le righe di Blink senza auto e minuti, un Utente senza la categoria non le vede affatto.
Esempio: un Utente con la categoria Telecamere chiede lo stato e prova a cambiare i minuti
Gli avvisi seguono la stessa logica: arrivano agli Admin e agli Utenti iscritti a Telecamere, ed è per questo che tutti passano da script.avviso_categoria con categoria: telecamere.
L'automazione che riceve il webhook del gateway calcola già ruolo e nome del mittente per gli altri comandi. Per Blink controlla il permesso sulla categoria e passa ruolo e nome allo script, che parte con script.turn_on per non tenere il webhook in attesa:
- conditions: "{{ (testo | string | lower | trim).split(' ')[0] == 'blink' }}"
sequence:
- if: "{{ not (ruolo == 'admin' or 'telecamere' in categorie) }}"
then:
- action: script.whatsapp_rispondi
data:
chat: "{{ chat }}"
testo: |-
*🔒 COMANDO NON DISPONIBILE*
━━━━━━━━━━━━━━
Il tuo profilo non comprende le telecamere.
else:
- action: script.turn_on
target:
entity_id: script.blink_comando
data:
variables:
testo: "{{ testo }}"
chat: "{{ chat }}"
nome: "{{ nome }}"
admin: "{{ ruolo == 'admin' }}"
E lo script dei comandi, ridotto ai rami principali. script.whatsapp_rispondi sta per lo script con cui già rispondi a una chat:
script:
blink_comando:
alias: Blink - comando WhatsApp
mode: queued
fields:
testo: {}
chat: {}
nome: {}
admin: {}
sequence:
- variables:
parole: "{{ (testo | string | lower | trim).split()[1:] }}"
azione: "{{ parole[0] if parole | count > 0 else 'stato' }}"
valore: "{{ parole[1] if parole | count > 1 else '' }}"
is_admin: "{{ admin | string | lower in ['true', '1', 'on'] }}"
sistemi: "{{ (state_attr('sensor.blink_sistemi', 'sistemi') or []) | map(attribute='entity') | list }}"
- choose:
# PRIMA il controllo dei permessi, poi i rami che eseguono
- conditions: "{{ azione in ['auto', 'minuti'] and not is_admin }}"
sequence:
- action: script.whatsapp_rispondi
data:
chat: "{{ chat }}"
testo: |-
*🔒 COMANDO RISERVATO*
━━━━━━━━━━━━━━
Le impostazioni del riarmo sono riservate agli Admin.
- conditions: "{{ azione == 'arma' }}"
sequence:
- action: input_text.set_value
target:
entity_id: input_text.blink_ultimo_comando
data:
value: "arma|WhatsApp ({{ nome }})|{{ now().isoformat() }}"
- action: script.blink_arma
data:
sistemi: "{{ sistemi }}"
- conditions: "{{ azione == 'disarma' }}"
sequence:
# prima il riarmo programmato, poi il disarmo: l'avviso lo legge subito
- action: input_text.set_value
target:
entity_id: input_text.blink_riarmo_programmato
data:
value: >-
{{ (now() + timedelta(minutes=valore | string | int)).isoformat()
if (valore | string).isdigit() else '' }}
- action: input_text.set_value
target:
entity_id: input_text.blink_ultimo_comando
data:
value: "disarma|WhatsApp ({{ nome }})|{{ now().isoformat() }}"
- action: alarm_control_panel.alarm_disarm
continue_on_error: true
target:
entity_id: "{{ sistemi }}"
- conditions: "{{ azione == 'auto' and (valore | string) in ['on', 'off'] }}"
sequence:
- action: "input_boolean.turn_{{ valore }}"
target:
entity_id: input_boolean.blink_riarmo_auto
- action: script.whatsapp_rispondi
data:
chat: "{{ chat }}"
testo: |-
*🔁 RIARMO AUTOMATICO*
━━━━━━━━━━━━━━
{{ '🟢 Acceso' if (valore | string) == 'on' else '⚫ Spento' }}
- conditions: "{{ azione == 'minuti' and (valore | string).isdigit() }}"
sequence:
- action: input_number.set_value
target:
entity_id: input_number.blink_riarmo_minuti
data:
value: "{{ valore | string | int }}"
- action: script.whatsapp_rispondi
data:
chat: "{{ chat }}"
testo: |-
*🔁 RIARMO AUTOMATICO*
━━━━━━━━━━━━━━
⏱️ Riarmo dopo {{ valore }} minuti
A blink arma e blink disarma lo script non risponde con un messaggio suo: la conferma è l'avviso 🔒 o 🔓 che arriva a tutti, mittente compreso, e dice anche chi è stato. Il ramo dello stato (solo blink) legge sensor.blink_sistemi e scrive una riga per sistema, come nel mockup sopra.
🖥️ La dashboard
Una scheda sola per usare e configurare il riarmo: stato, sistema, interruttore del riarmo, minuti, prossimo riarmo, ultimo errore e un pulsante per armare subito. I minuti compaiono solo con il riarmo acceso, l'ultimo errore solo se c'è un errore in corso: due righe conditional della scheda entità.
Esempio: la scheda con il riarmo acceso e nessun errore in corso
type: entities
title: 📹 Blink
entities:
- entity: alarm_control_panel.blink_casa
name: Stato
- type: attribute
entity: alarm_control_panel.blink_casa
attribute: status
name: Modulo CASA
- entity: input_boolean.blink_riarmo_auto
name: Riarmo automatico
- type: conditional
conditions:
- entity: input_boolean.blink_riarmo_auto
state: "on"
row:
entity: input_number.blink_riarmo_minuti
name: Riarma dopo (minuti)
- entity: sensor.blink_prossimo_riarmo
name: Prossimo riarmo
format: time
- type: conditional
conditions:
- entity: input_boolean.blink_errore_in_corso
state: "on"
row:
entity: input_text.blink_ultimo_errore
name: Ultimo errore
- type: button
name: Arma adesso
icon: mdi:shield-lock
action_name: ARMA
tap_action:
action: perform-action
perform_action: script.blink_arma
Il pulsante chiama lo script senza dati, quindi arma tutti i sistemi; nell'avviso comparirà «dashboard» con il nome della persona, grazie al context.user_id. La scelta dei canali di ogni avviso (WhatsApp, app, email) non sta qui ma in una vista a parte, la stessa degli altri avvisi di casa, come nella guida sui messaggi su WhatsApp, email e app: questa scheda resta corta e si usa al volo.
🪤 Le trappole dei template
Gli script sono quasi tutti template Jinja, e tre trappole fanno perdere più tempo di tutto il resto.
1. Nelle variables il testo cambia tipo
Home Assistant converte il risultato di un template nelle variables nel suo tipo «naturale»: «1» diventa il numero 1, «true» diventa il booleano True. Un confronto con un testo allora non è mai vero, e i metodi dei testi danno errore.
# con "blink minuti 30" valore è il numero 30
# Sbagliato: isdigit() su un numero ferma lo script
- conditions: "{{ valore.isdigit() }}"
# Sbagliato: 30 non è uguale a '30'
- conditions: "{{ valore == '30' }}"
# Giusto: | string nel punto in cui lo usi
- conditions: "{{ (valore | string).isdigit() }}"
- conditions: "{{ (valore | string) == '30' }}"
2. Il booleano che arriva come testo
L'automazione passa admin: "{{ ruolo == 'admin' }}", cioè True o False. Ma a seconda di come viene chiamato, lo script può riceverlo come booleano o come testo «True», «true», «on». {{ not admin }} su un testo non vuoto è sempre falso, quindi un Utente risulterebbe Admin. Va normalizzato una volta, all'inizio:
- variables:
# Sbagliato: "False" come testo è vero
# is_admin: "{{ admin }}"
is_admin: "{{ admin | string | lower in ['true', '1', 'on'] }}"
3. Nel choose vince la prima condizione vera
Un choose esegue il primo ramo con la condizione vera e ignora gli altri. Se il ramo «comando riservato agli Admin» sta dopo il ramo che esegue blink minuti, un Utente cambia i minuti e il controllo non viene mai raggiunto. Il controllo dei permessi va sempre per primo, come nello script sopra:
- choose:
# 1. prima il rifiuto
- conditions: "{{ azione in ['auto', 'minuti'] and not is_admin }}"
sequence: [...]
# 2. poi i rami che eseguono
- conditions: "{{ azione == 'minuti' and (valore | string).isdigit() }}"
sequence: [...]
🧪 Come provarlo
- Accendi il riarmo automatico e metti i minuti a 5, dalla dashboard o con
blink auto oneblink minuti 5. - Scrivi
blink disarma: deve arrivare l'avviso 🔓 con il tuo nome e l'ora del riarmo, 5 minuti più tardi. - Scrivi
blink: lo stato deve dire «disarmato da» e la stessa ora di riarmo. - Aspetta: entro un minuto dall'ora indicata arriva l'avviso 🔒 «riarmo automatico», con «era disarmato da 5 min».
- Prova
blink disarma 10con l'automatico spento: il riarmo deve arrivare comunque, dopo 10 minuti. - Disarma dall'app Blink: l'avviso arriva fino a 5 minuti dopo e dice «app Blink o altra fonte».
- Dal numero di un Utente con Telecamere prova
blink minuti 15: deve rispondere «comando riservato». - Rimetti i minuti che vuoi davvero.
✅ Checklist finale
- I sistemi in
sensor.blink_sistemisono solo quelli con telecamere, e i nomi delle entità corrispondono. - Con 0 minuti il riarmo avviene al primo controllo dopo il disarmo, cioè entro un minuto da quando Home Assistant lo vede.
- Un riavvio di Home Assistant non manda avvisi di riarmo falsi.
- Con il modulo offline arriva un solo avviso ⚠️, e al primo armamento riuscito il 🔒 dice «errore risolto».
- Gli avvisi arrivano agli Admin e agli Utenti con Telecamere, e a nessun altro.
- L'
aiutodi un Utente non mostraautoeminuti. - Il riarmo programmato si svuota dopo il riarmo.
💡 Idee per estenderlo
- Armare solo di notte: una condizione d'orario nell'automazione di riarmo, o un secondo valore di minuti per le ore notturne.
- Disarmare quando il telefono arriva a casa: un'automazione sulla zona casa dell'entità
personche disarma e scrive «arrivo a casa» inblink_ultimo_comando, così l'avviso dice anche perché. - Un riepilogo serale: a un'ora fissa un messaggio con lo stato di ogni sistema e quante volte è stato disarmato durante il giorno, utile per accorgersi di un sistema rimasto spento.