Al momento stai visualizzando Multinotify: il package per le notifiche su Alexa e App

Multinotify: il package per le notifiche su Alexa e App

  • Autore dell'articolo:
  • Categoria dell'articolo:Home Assistant
  • Commenti dell'articolo:39 commenti
  • Ultima modifica dell'articolo:21 Gennaio 2022

Richiami spesso dalle tue automazioni notifiche su Alexa e su App? Ti piacerebbe poter scrivere una volta sola il testo della notifica, che la maggior parte delle volte è identica tra app ed Alexa? Ti piacerebbe che Alexa avesse un volume per le notifiche separato da quello impostato sui device?
Questo e molto altro con il package multinotify!

Lo script è nato originalmente perchè nelle mie automazioni richiamavo molto frequentemente sia notifiche sui dispositivi Alexa che su una o più app companion e trovavo scomodo dover richiamare sempre i servizi con le loro sintassi e duplicare il testo della notifica ogni volta.

Poi l’idea di simulare un volume specifico per le notifiche, che Alexa non ha. Per esempio se stai ascoltando la musica di sottofondo con volume 3 ed arriva una notifica farai molta fatica a capirne il contenuto. Da qui l’idea di alzare il volume prima della riproduzione della notifica e ripristinarlo al termine della stessa.

E’ stata anche una buona palestra per imparare diversi concetti avanzati, iniziando dall’articolo che ne è nato, ancora attuale, che spiegava come creare script con parametri opzionali.

In questo articolo, oltre a mettere a disposizione l’ultima versione del package multinotify, ne spiegherò anche in dettaglio come utilizzarlo ed i principi di funzionamento interni, per chi fosse interessato ad approfondire i concetti più avanzati.

Se l’argomento “notifiche” in Home Assistant ti interessa non aspettare oltre e prosegui la lettura!

Caratteristiche del package multinotify

Di seguito quel che lo script Multinotify può fare per te:

  • Notifica ad Alexa e/o app companion potendo specificare una sola volta il testo della notifica
  • Volume della notifica su Alexa specificabile e separato dal volume corrente, che verrà ripristinato al termine della riproduzione
  • Attesa che Alexa termini la pronuncia della notifica. In questo modo le azioni seguenti saranno eseguite a notifica completata. Ad esempio puoi pronunciare “…ora ti alzo le tapparelle” e al termine viene eseguita l’azione.
  • Per Alexa potrai specificare a scelta: una singola entità, un gruppo di entità, un gruppo multistanza interno di Alexa, un elenco di entità o l’entità speciale ovunque.
  • Se stavi ascoltando la musica multinotify la metterà in pausa per te prima della notifica e ripresa al suo termine (idea di Massimiliano Albani: grazie!)
  • Definizione orario in cui Alexa pronuncia le notifiche. Al di fuori dell’orario Alexa non parlerà (a meno che non si forzi la pronuncia con il relativo parametro)
  • Mitigati alcuni problemi di Alexa Media Player impostando un volume all’avvio e aggiornando automaticamente il volume impostato di volta in volta, utile per quando il websocket si disconnette.
  • Al momento le notifiche app non sono compatibili con iPhone.

Installazione e configurazione di multinotify

Installare il package è semplicissimo. Ma prima di tutto verifichiamo che i requisiti siano soddisfatti.

Requisiti

  • Se intendi utilizzare Alexa devi aver installato e configurato Alexa Media Player,
  • Se intendi utilizzare le notifiche dell’app companion devi averne installata e collegata almeno una,
  • Devi aver installato lo script python set_state.
    ATTENZIONE: di script con questo nome ne esistono molte varianti. E’ fondamentale che tu abbia lo script riportato nel mio articolo aggiornato per l’occasione che permette la creazione di entità.

Installazione del package multinotify

Premendo il pulsante sopra scaricherai un file zip contenente il package all’ultima versione.

In tale file zip estrai il file multinotify.yaml ed incollalo nella tua cartella dei packages di Home Assistant.

Se non sai cosa sono i packages fai riferimento a questa sezione della documentazione che spiega come utilizzarli oppure al capitolo “I packages” dell’articolo di Vito Antonucci
Il package è presente nel mio repository GitHub. Se vuoi correggere, implementare nuove feature o segnalare un problema utilizza GitHub 🙂

Configurazione del package multinotify

Ora non resta che configurarlo aprendolo con il tuo editor di testo preferito. La sezione da modificare si trova all’inizio del file, dopo le descrizioni iniziali. Ci sono commenti auto esplicativi ma vediamo di seguito cosa modificare:

group:
  # Gruppo contenente tutti i device Echo presenti (necessario per utilizzare media_player.ovunque come target di multinotify)
  all_alexa:
    name: Tutti i device Echo
    entities:
      # TODO: modificare l'elenco delle entità del gruppo con i propri dispositivi Alexa
      - media_player.pian_terreno
      - media_player.primo_piano
      - media_player.mansarda

Questo è un gruppo fondamentale se si desidera utilizzare l’entità speciale media_player.ovunque (ma non solo!) in quanto lo script utilizza il gruppo per sapere quali dispositivi Alexa hai.
Inserisci quindi tutti i media_player di Alexa Media Player al posto dei tre indicati come esempio.

  # TODO: Definire un gruppo per ogni gruppo interno di Alexa. Per esempio al gruppo media_player.miogruppo dovrà corrispondere
  #       il gruppo group.miogruppo contenente gli stessi dispositivi. Rimuovere l'esempio piani_superiori.
  piani_superiori:
    name: Device Echo dei piani superiori
    entities:
      - media_player.primo_piano
      - media_player.mansarda

Questo è un gruppo esemplificativo di un gruppo interno ad Alexa. Per ogni gruppo altoparlanti – musica multistanza creato dall’app Alexa, infatti, sarà necessario creare un gruppo con stesso nome contenente i dispositivi Alexa di cui è composto, visto che l’integrazione Alexa Media Player non dà modo di accedere a questa informazione.
Se hai più gruppi altoparlanti – musica multistanza configurati in Alexa crea un gruppo per ognuno di essi in questa sezione.

notify:
  # Gruppo notify.all_devices da utilizzare in multinotify per inviare una notifica a tutte le app
  - name: all_devices
    platform: group
    services:
      # TODO: modificare l'elenco dei servizi con i propri servizi di invio notifica alle app Home Assistant Companion collegate
      - service: mobile_app_tel_henrik
      - service: mobile_app_smartphone_antonella

In questa sezione creiamo un servizio di notifica di gruppo che permetterà di specificare l’invio di una notifica a tutte le app senza necessità di elencarle ogni volta che si richiama multinotify. Basterà invece utilizzare notify.all_devices per inviare la notifica a tutte le app.
Se lo desideri è possibile creare altri gruppi (ripeti il blocco a partire da “-name: all_devices” cambiandone nome e servizi contenuti) se hai tante app e desideri creare dei gruppi nominati.

Finito! Sei ora pronto per utilizzare multinotify per il tuo sistema!
Riavvia Home Assistant e prosegui la lettura.

Sintassi dello script multinotify

Come tutti gli script per richiamare multinotify si possono usare due sintassi: service: script.multinotify oppure script.turn_on. La differenza tra i due è che con la prima Home Assistant attende il termine dell’esecuzione dello script, prima di continuare l’esecuzione con l’istruzione successiva. Essendo che una peculiarità di multinotify è che attende il termine della pronuncia da parte di Alexa è consigliato richiamarlo tramite script.multinotify.

Con la seconda sintassi, invece, Home Assistant avvia lo script e prosegue immediatamente con l’istruzione successiva del chiamante.

I parametri vengono dichiarati tutti all’interno di data: e sono i seguenti (separati per categoria):

ComuniAlexaApp companion
ParametroDescrizioneObbligatorioDefault
messageTesto da notificare alle app e pronunciare da Alexa (se non specificato diversamente)SI
titleTitolo della notifica inviata alle appNONotifica da casa
ParametroDescrizioneObbligatorioDefault
alexa_messageTesto che Alexa dovrà pronunciare, se differente da message. Utile se si desidera utilizzare le interiezioni così da limitarle solo alla pronuncia su Alexa e non mostrarle nelle notifiche alle app.NO=message
alexa_targetDispositivi Alexa che dovranno pronunciare il messaggio. E’ possibile specificare una singola entità media_player, un elenco di entità media_player, un gruppo di Home Assistant, un gruppo altoparlanti – musica multistanza di Alexa o entità speciale media_player.ovunqueNOnessuna
alexa_volumeVolume con cui i dispositivi Alexa coinvolti pronunceranno la notifica. Al termine il volume sarà comunque ripristinato a quello precedente di ogni dispositivo Alexa. Valori da 0.1 a 1.0NO0.6
alexa_forceSe non specificato o specificato il valore false il i dispositivi Alexa specificati riprodurranno l’annuncio solo se l’orario corrente è tra le 9:00 e le 23:00. Per pronunciare comunque il messaggio al di fuori di tali orari specificare true.NOfalse
ParametroDescrizioneObbligatorioDefault
notify_appNome del servizio da utilizzare per inviare la notifica alle app companion.NOnessuno
groupStringa identificativa del gruppo di notifiche dell’app. Le notifiche sul telefono verranno raggruppate in base a questo valore.NO=channel o “info” (se channel non è specificato)
channelStringa identificativa del canale per le notifiche all’app. Ogni canale, su Android, può avere impostazioni di notifica (compresa la suoneria) personalizzabili.NO=group o “info” (se group non è specificato)
iconNome del file (senza percorso, senza il prefisso notify_ e senza estensione) da visualizzare come icona della notifica in appNO=channel, =group o “info” se nessuno dei precedenti è definito
tagCampo tag della notifica all’app. Se impostata ogni successiva notifica con pari tag sostituirà la notifica precedente. Utile per notifiche il cui stato cambia e non ha senso mantenere i cambi stato precedenti.NOnessuno
criticalSpecifica lo stato di notifica critica per l’app. Se true l’app mostrerà la notifica appena possibile. Se false l’app mostrerà la notifica alla prima volta in cui avrà modo, ottimizzando il consumo di batteria (possono passare diversi minuti)NOtrue

Preparare le icone da utilizzare per le notifiche di multinotify

Nelle notifiche delle app è utile inserire un’icona per diversificare i diversi tipi di notifica. Multinotify, infatti, supporta l’inserimento di un’immagine nella notifica ma per farlo deve essere un file raggiungibile da internet (quindi la tua istanza di Home Assistant deve essere raggiungibile da internet, la soluzione più semplice è usando Nabu Casa).

Nella cartella config crea, se non già presente, una cartella www. All’interno di tale cartella copia i file png che devono chiamarsi notify_xxxx.png.

Ad esempio per utilizzare l’icona warning è necessario che sia presente il file config/www/notify_warning.png.

Consiglio di utilizzare icone png con trasparenza (png a 32 bit) della dimensione di 48×48 pixel.

Di seguito qualche suggerimento…

Se non sai come accedere alla casella config per inserire le immagini ti consiglio di installare l’addon Samba che trovi in Configurazioni -> Componenti aggiungitivi, backup e supervisore -> RACCOLTA DI COMPONENTI AGGIUNTIVI

Come sperimentare l’utilizzo dei vari parametri…

Tra poco vedremo vari esempi di utilizzo. Per imparare ad usare lo script multinotify per fare esperimenti in modo semplice ti consiglio, una volta installato e configurato, di provare a richiamarlo nelle sue varie modalità tramite Strumenti per sviluppatori -> Servizi, scegliere il servizio “Script: Notifica intelligente” (accessibile anche scrivendo script.multinotify) e utilizzare la modalità interfaccia utente cliccando sul seguente link:

Vai in modalità interfaccia utente

I campi dello script saranno visibili e impostabili semplicemente tramite l’interfaccia utente:

Interfaccia utente dello script multinotify
Nota bene: nella casella Alexa è possibile selezionare soltanto tra i dispositivi Alexa in quanto i selettori di Home Assistant non permettono la versatilità che ho voluto implementare in questo parametro. Se vuoi specificare un elenco o un gruppo dovrai scriverlo a mano in modalità YAML.

Potete vedere il codice YAML corrispondente semplicemente premendo il link in basso

Vai in modalità YAML

In tal modo potrai vedere il codice YAML da richiamare dalle tue automazioni / script con i parametri scelti da interfaccia utente:

Codice YAML generato da Strumenti per sviluppatori dopo aver impostato l'UI dello script multinotify

Ma bando alle ciance, vediamo qualche esempio concreto approfittando dell’occasione per mostrare diverse peculiarità dello script.

Esempi delle varie modalità di utilizzo di multinotify

Utilizzare lo script multinotify è molto semplice. Non lasciarti spaventare dai tanti parametri, quasi tutti sono opzionali!

Vediamo con una serie di esempi vari modi di utilizzo dello script.

La modalità base

Vediamo come utilizzare in modo basilare lo script con alcuni esempi:

service: script.multinotify
data:
  message: Questa è una notifica di prova
  alexa_target: media_player.ovunque
  notify_app: notify.all_devices

Con questo semplice comando verrà inviato un messaggio da ogni dispositivo Alexa della casa e ad ogni app Companion collegata contenente il messaggio specificato.
Per ogni dispositivo Alexa, solo se l’orario è compreso tra le 9:00 e le 23:00, lo script interromperà la riproduzione della musica, se il caso, imposterà il volume al 60%, riprodurrà il messaggio, attenderà il termine della pronuncia ed in seguito ripristinerà i volumi specifici di ogni dispositivo Alexa ed infine riprenderà la riproduzione della musica, se la si stava ascoltando.

Non male no? 🙂

Essendo message l’unico parametro obbligatorio possiamo usare lo script per pronunciare un messaggio solo ad Alexa o inviare una notifica solo alle app.

Se avessimo voluto, ad esempio, far riprodurre il messaggio precedente solo sui dispositivi Alexa sarebbe stato sufficiente richiamarlo così:

service: script.multinotify
data:
  message: Questa è una notifica di prova, inviata solo ad Alexa.
  alexa_target: media_player.ovunque

Varie modalità per specificare i dispositivi Alexa

Lo script è stato sviluppato per permettere la massima flessibilità nel modo in cui specificare su quali dispositivi Alexa riprodurre il messaggio. Di seguito un esempio per ogni possibilità:

Singola entità Alexa

service: script.multinotify
data:
  message: Notifica riprodotta da un solo dispositivo Alexa
  alexa_target: media_player.alexa1

Specificando l’id dell’entità di un singolo dispositivo Alexa, quest’ultimo riprodurrà il messaggio.

Elenco di entità Alexa

service: script.multinotify
data:
  message: "Notifica riprodotta dall'elenco specificato di dispositivi Alexa"
  alexa_target:
    - media_player.alexa1
    - media_player.alexa2

Specificando un elenco di id entità tutti i dispositivi specificati riprodurranno il messaggio specificato.

Gruppo Alexa di Home Assistant

service: script.multinotify
data:
  message: Notifica riprodotta da un gruppo di Alexa definito in Home Assistant.
  alexa_target: group.all_alexa

Specificando un gruppo nel parametro alexa_target, tutti i dispositivi Alexa contenuti in tale gruppo riprodurranno il messaggio.
Questo non è limitato al gruppo all_alexa ma si può usare qualunque gruppo tu voglia definire contenente dispositivi Alexa.

Gruppo altoparlanti – musica multistanza di Alexa

service: script.multinotify
data:
  message: "Notifica riprodotta da un gruppo di altoparlanti definito nell'app Alexa"
  alexa_target: media_player.gruppo_alexa1

Specificando il media_player associato ad un gruppo altoparlanti – musica multistanza di Alexa, tutti i dispositivi che ne fanno parte riprodurranno il messaggio.

Nota bene: è necessario aver impostato un gruppo con pari nome per ciascun gruppo altoparlanti – musica multistanza contenente l’elenco dei dispositivi contenuti. Vedi capitolo configurazione iniziale.

Entità speciale ovunque

service: script.multinotify
data:
  message: Notifica riprodotta da un solo dispositivo Alexa
  alexa_target: media_player.ovunque

L’entità speciale media_player.ovunque altro non è che un gruppo altoparlanti – musica multistanza definito nell’app Alexa per default e contiene tutti i dispositivi Alexa.

Nota bene: è necessario aver impostato il gruppo con nome all_alexa contenente l’elenco di tutti i dispositivi Alexa. Vedi capitolo configurazione iniziale.

Usando tutti i parametri

Vediamo di seguito l’esempio più complesso per richiamare lo script multinotify, utilizzando tutti i parametri presenti:

service: script.multinotify
data:
  title: "Notifica dalla cucina"
  message: "E' pronto da mangiare!"
  alexa_message: '<say-as interpret-as="interjection">hey</say-as>, è pronto da mangiare!'
  alexa_target:
    - media_player.mansarda
    - media_player.primo_piano
  alexa_volume: 0.8
  alexa_force: true
  notify_app: notify.all_devices
  group: meal-cucina
  channel: meal
  icon: meal
  tag: pronto_da_mangiare
  critical: true

Con questi parametri stiamo specificando che:

  • title: “Notifica dalla cucina”
    il titolo della notifica (visibile solo nell’app) sarà “Notifica dalla cucina”
  • message: “E’ pronto da mangiare!”
    il messaggio è “E’ pronto da mangiare!”
  • alexa_message: ‘<say-as interpret-as=”interjection”>hey</say-as>, è pronto da mangiare!’
    per Alexa il messaggio da pronunciare è diverso, così da inserire una interjection che nell’app non sarebbe leggibile
  • alexa_target:
    – media_player.mansarda
    – media_player.primo_piano

    facciamo pronunciare il messagio ai soli due dispositivi Alexa specificati
  • alexa_volume: 0.8
    l’annuncio di Alexa sarà riprodotto con volume 80% e poi sarà ripristinato il singolo volume che ogni dispositivo coinvolto aveva
  • alexa_force: true
    forziamo la riproduzione dell’annuncio Alexa anche se l’orario è al di fuori della fascia 9:00 23:00
  • notify_app: notify.all_devices
    il servizio di notifica da usare. In questo caso notify.all_devices definito ad inizio package, per inviare la notifica a tutte le app
  • group: meal-cucina
    questa notifica farà gruppo tra le notifiche di Android con tutte le notifiche aventi pari valore di questo parametro
  • channel: meal
    Il canale della notifica di Android sarà meal. Tramite la configurazione delle notifiche dell’app sarà possibile impostare una suoneria specifica per questo canale, oltre ad impostazioni come il tipo di vibrazione, il colore del led di notifica ed altro ancora.
  • icon: meal
    Visualizza nella notifica l’icona posta in config/www/notify_meal.png
  • tag: pronto_da_mangiare
    Ogni notifica successiva con questo valore di tag sostituisce la precedente eventualmente ancora presente anzi che aggiungersi come altra notifica. Questo fa sì che richiamando più volte di seguito questo script la notifica presente sarà solo una: la più recente.
  • critical: true
    Questo è già il valore di default per cui è omissibile. true significa che l’app mostrerà la notifica immediatamente.
    Le notifiche aventi invece critical: false possono arrivare dopo diversi minuti, quando l’app risveglia il telefono dallo stato di standby alla prima occasione per verificare se ci sono notifiche.

Azioni sequenziali

Le notifiche di Alexa Media Player non attendono che i dispositivi Alexa pronuncino il testo specificato per proseguire l’esecuzione delle azioni nell’automazione o script. Multinotify inserisce invece un tempo di attesa calcolato in funzione di quanto pronunciato che effettua l’attesa del tempo più simile possible al tempo impiegato da Alexa per la pronuncia. Questo rende possibile sequenze come la seguente:

- service: script.multinotify
  data:
    message: 'Buongiorno! Ora ti alzo le tapparelle!'
    alexa_target: media_player.pian_terreno
    alexa_volume: 0.5
    alexa_force: true
- service: script.tapparelle_apri

Tramite la sequenza sopra il dispositivo Alexa pian_terreno pronuncerà “Buongiorno! Ora ti alzo le tapparelle!” e solo al termine della frase verrà avviato lo script tapparelle_apri. L’effetto è ottimo 🙂

Come funziona lo script multinotify

Finora ho spiegato come installare, configurare ed utilizzare lo script. Spero però davvero che tu colga l’occasione per studiare com’è fatto il package per imparare diverse tecniche che possono diventare molto utili in diversi altri contesti.

Per questo motivo nei capitoli che seguono cercherò di descrivere le parti salienti degli script coinvolti seguendo il flusso di esecuzione, così da capire come funzionano.

Se non l’hai già letto ti consiglio la lettura del precedente articolo sulla prima versione di multinotify, che affronta il tema dei parametri degli script e dei valori di default da assegnare qualora non vengano specificati. Sebbene tale articolo faccia riferimento ad una versione di multinotify superata tutte le nozioni sono utilissime e correntemente utilizzate anche dalle versioni aggiornate: Script con parametri opzionali in Home Assistant

Flusso di funzionamento principale

L’esecuzione dello script multinotify si compone di due parti essenziali: l’invio della notifica alle app e la pronuncia dai dispositivi Alexa.

Notifica alle app

Di seguito il codice che si occupa della notifica alle app:

- alias: "Notifica App"
  choose:
  - alias: "notify_app è stato passato dal chiamante?"
    conditions: "{{ notify_app is defined }}"
    sequence:
      - service: '{{notify_app}}'
        data:
          title: "{{title | default('Notifica da casa')}}"
          message: "{{message}}"
          data:
            group: "{{group | default(channel) | default('info')}}"
            channel: "{{channel | default(group) | default('info')}}"
            tag: "{{tag | default('')}}"
            icon_url: "/local/notify_{{icon | default(channel) | default(group) | default('info')}}.png"
            ttl: "{{0 if (critical | default(true)) else 86400}}"
            priority: "{{'high' if (critical | default(true)) else 'normal'}}"

Il choose determina, tramite la condizione "{{ notify_app is defined }}", che sia stato specificato il parametro notify_app per procedere alla notifica.
In tal caso tramite service template specifichiamo quale servizio notify utilizzare. Il resto è solo una compilazione dei campi necessari, gestendone i valori di default se non specificati dal chiamante.

Notifiche ad Alexa

Il vero cuore, però, di multinotify è nella pronuncia tramite Alexa, che avviene nel blocco seguente che inizia con alias: "Notifica Alexa".

Passiamo in rassegna le varie istruzioni che seguono:

- alias: "Notifica Alexa"
  choose:
    - conditions:
        - alias: "alexa_target è stato passato dal chiamante?"
          condition: template
          value_template: "{{ alexa_target is defined }}"
        - alias: "Orario diurno oppure alexa_force = true"
          condition: or
          conditions:
            - condition: template
              value_template: "{{ alexa_force | default(false)}}"
            - condition: time
              after: '09:00:00'
              before: '23:00:00'
      sequence:
         ........

Anche in questo caso il choose valuta come prima cosa che alexa_target sia stato passato dal chiamante per procedere ed, in seguito, valuta se l’orario è diurno (9:00 – 23:00) oppure se è stato passato il parametro alexa_force: true.
Se queste condizioni sono soddisfatte proseguiamo.

Richiamo script.multinotify_alexa_pre per ogni dispositivo Alexa
# script.multinotify_pre: salvo volume precedente, imposto volume e metto in pausa eventuale musica su tutti i dispositivi Alexa coinvolti
- variables:
    list: >
      {% set object_id = alexa_target | regex_findall('\\.(\\w+)') | first %}
      {% if not alexa_target is string %}
        {# Elenco di entità inline #}
        {{alexa_target | join(',')}}
      {% elif alexa_target.startswith('group.') %}
        {# Gruppo di Echo definito in Home Assistant #}
        {{expand(states[alexa_target]) | join(',', attribute='entity_id')}}
      {% elif alexa_target == ('media_player.ovunque') or alexa_target.endswith('media_player.everywhere') %}
        {# Tutti gli Echo contemporaneamente #}
        {{expand(states.group.all_alexa) | join(',', attribute='entity_id')}}
      {% elif alexa_target.startswith('media_player.') and states['group.' ~ object_id] != None %}
        {# Gruppo di Echo definito in Alexa (necessario un gruppo Home Assistant corrispondente con lo stesso nome!) #}
        {{expand(states['group.' ~ object_id]) | join(',', attribute='entity_id')}}
      {% elif alexa_target.startswith('media_player.') %}
        {# Singola entità Echo #}
        {{alexa_target}}
      {% endif %}
    count: "{{list.split(',') | count}}"
- repeat:
    while: "{{ repeat.index <= count }}"
    sequence:
      - variables:
          entity_id: "{{list.split(',')[repeat.index-1]}}"
      - service: script.multinotify_alexa_pre
        data:
          target: "{{entity_id}}"
          volume: "{{alexa_volume | default(0.6)}}"

Scopo di questo blocco è quello di richiamare lo script (che analizzeremo in seguito) script.multinotify_alexa_pre per ogni dispositivo Alexa coinvolto nella notifica. Per farlo, come prima cosa, compiliamo una variabile di nome list in cui, a seconda di cosa abbiamo passato se un’entità di gruppo, un gruppo altoparlanti, un elenco di entità o l’elemento ovunque, inseriamo l’elenco delle entità Alexa coinvolte, separate da virgola.
La variabile count contiene invece il numero di entità presenti nella lista (tramite il filtro count).

Preparati questi dati viene eseguito il repeat while come se fosse un ciclo foreach per tutti gli elementi Alexa presenti nella lista preparata sopra. Per simulare un foreach utilizziamo la variabile speciale repeat.index che contiene il numero di ciclo in cui si è. Attenzione che parte da 0 e non da 1 come si potrebbe essere portati a pensare (ecco perchè la condizione di fine è repeat.index <= count).

All’interno del repeat viene impostata la variabile entity_id prelevando l’elemento alla posizione di repeat.index-1 della lista compilata all’inizio e viene passata a script.multinotify_alexa_pre, insieme al volume desiderato.

Lo script multinotify_alexa_pre si occuperà di salvare il volume corrente del dispositivo, mettere in pausa l’eventuale musica salvando che era in riproduzione e infine impostare il volume specificato, più avanti vedremo nel dettaglio come lo fa.

Notifica vera e propria

A questo punto viene richiamato il servizio notify.alexa_media di Alexa Media Player per pronunciare la notifica desiderata:

# Notifica vera e propria
- variables:
    message: "{{alexa_message | default(message)}}"
- service: notify.alexa_media
  data:  
    message: "{{message}}"
    data:
      type: announce
    target: "{{alexa_target}}"
Attesa che Alexa abbia pronunciato la notifica

Una volta avviata la pronuncia questa è asincrona, ovvero restituisce il controllo immediato al chiamante mentre i dispositivi Alexa ne iniziano la pronuncia. Tramite il codice che segue (che mi è costato tanto sudore e tantissime prove empiriche con frasi di ogni tipo!!!) simuliamo il tempo necessario ad Alexa per pronunciare la frase specificata in message così da attendere mentre è in corso la pronuncia:

- delay:
    seconds: "{{(5 + (message.count(', ') + message.count('. ') + message.count('! ') + message.count('? ') + message.count(': ') + message.count('; ')) | float * 0.35 + (message | length) * 0.06) | round(default=0)}}"

La base su cui è calcolato questo tempo è la seguente:

  • 5 secondi fissi sono i tempi morti generali che mediamente Alexa impiega tra avvio e suono di inizio notifica
  • vengono contati i segni di punteggiatura (, . ! ? : 😉 che implicano un aumento del tempo di lettura pari a 0,35 secondi l’uno
  • vengono contati i caratteri della frase da pronunciare, moltiplicati per un tempo medio di 6 centesimi di secondo a carattere

Questi valori li ho ricavati facendo davvero tante prove con frasi corte, lunghe, frastagliate da punteggiatura o prive di punteggiatura. Il risultato è molto aderente al tempo impiegato da Alexa (sebbene sia simulato in quanto non c’è modo di attendere il reale termine della pronuncia).

Unica eccezione non ancora considerata cono le interiezioni come hey che impiegano meno tempo rispetto a quanto calcolato. In una versione seguente calcolerò anche questo.
Richiamo script.multinotify_alexa_post per ogni dispositivo Alexa

Al termine della notifica, similarmente a quanto abbiamo fatto prima della notifica vera e propria, richiamiamo script.multinotify_alexa_post per ogni dispositivo Alexa coinvolto:

# script.multinotify_post: ripristino volume precedente e riproduzione musica, se era in corso, su tutti i dispositivi Alexa coinvolti
- repeat:
    while: "{{ repeat.index <= count }}"
    sequence:
      - variables:
          entity_id: "{{list.split(',')[repeat.index-1]}}"
      - service: script.multinotify_alexa_post
        data:
          target: "{{entity_id}}"

Lo script multinotify_alexa_post si occuperà di ripristinare il volume precedente del dispositivo Alexa e riprendere la musica in riproduzione (se lo era prima dell’annuncio). Più avanti vedremo nel dettaglio come lo fa.

Lo script multinotify_alexa_pre

Come abbiamo visto sopra lo script multinotify_alexa_pre viene richiamato per ogni dispositivo Alexa coinvolto nell’operazione. Vediamo il codice per capirne il funzionamento:

# AD USO INTERNO. Viene chiamato per ogni entità Alexa PRIMA del messaggio di notifica
multinotify_alexa_pre:
  alias: "Gestione singola Alexa PRE"
  description: "Processa la singola Alexa nel ciclo di Multinotify prima dell'annuncio. Non è pensata per l'utilizzo da parte dell'utente"
  fields: 
    target:
      name: "Entità Alexa"
      description: "Entità singola di Alexa da processare"
    volume:
      name: "Volume da impostare"
      description: "Volume da impostare (sarà impostato 0.6 se non specificato)"
  sequence:
    - alias: "Imposto prev volume"
      service: python_script.set_state
      data:
        entity_id: "tmp.alexa_{{ target | regex_findall('\\.(\\w+)') | first }}_prev_volume"
        state: "{{state_attr(target, 'volume_level')}}"
        was_playing: "{{states[target].state == 'playing'}}"
        allow_create: true
    - alias: "Alexa era in riproduzione?"
      choose:
      - conditions: "{{states[target].state == 'playing'}}"
        sequence:
          - alias: "Metto in pausa Alexa"
            service: media_player.media_pause
            target:
              entity_id: "{{target}}"
    - alias: "Imposta volume desiderato"
      service: media_player.volume_set
      target:
        entity_id: "{{target}}"
      data:
        volume_level: "{{volume | default(0.6) | round(2)}}"
    - alias: "Workaround per aggiornare sempre volume_level di Alexa"
      service: python_script.set_state
      data:
        entity_id: "{{target}}"
        volume_level: "{{volume | default(0.6) | round(2)}}"

Lo script ha come parametri di ingresso target, contenente l’entità di Alexa da processare e volume, contenente il volume desiderato per Alexa.

Come prima cosa nella sequence lo script effettua un backup del volume creando un’entità temporanea nominata tmp.alexa_NOME_prev_volume (dove NOME è il nome dell’entità passata senza dominio). Val la pena analizzare bene questo passaggio:

- alias: "Imposto prev volume"
  service: python_script.set_state
  data:
    entity_id: "tmp.alexa_{{ target | regex_findall('\\.(\\w+)') | first }}_prev_volume"
    state: "{{state_attr(target, 'volume_level')}}"
    was_playing: "{{states[target].state == 'playing'}}"
    allow_create: true

Viene utilizzato lo script python set_state per creare o aggiornare l’entità temporanea. Questi i parametri passati a set_state:

  • entity_id. Nome dell’entità da creare. La Regex serve per estrarre dall’entity_id presente in target la sola componente del nome senza dominio. Per esempio per “media_player.mia_alexa” restituirebbe “mia_alexa”. Così viene composto il nome come tmp.alexa_NOME_prev_volume
  • state. Qui memorizziamo semplicemente l’attributo volume_level contenuto nell’entità passata in target.
  • was_playing. In questo attributo memorizziamo true se lo stato dell’entità passata in target era “playing” oppure false in caso contrario
  • allow_create. Viene usato true per specificare che se l’entità non esiste va creata.

A questo punto se il dispositivo Alexa stava riproducendo musica questa viene messa in pausa:

- alias: "Alexa era in riproduzione?"
  choose:
  - conditions: "{{states[target].state == 'playing'}}"
    sequence:
      - alias: "Metto in pausa Alexa"
        service: media_player.media_pause
        target:
          entity_id: "{{target}}"

Questo perchè alzando il volume prima dell’annuncio e abbassandolo dopo l’annuncio è impossibile sincronizzarsi con la musica, risultando in un aumento improvviso del volume della musica che risulta particolarmente sgradevole. In questo modo, invece, tutto avviene correttamente.

Ora viene impostato il volume passato da multinotify (oppure 0.6 se non era stato specificato come parametro):

    - alias: "Imposta volume desiderato"
      service: media_player.volume_set
      target:
        entity_id: "{{target}}"
      data:
        volume_level: "{{volume | default(0.6) | round(2)}}"

Infine viene forzato l’attributo volume_level dell’entità di Alexa al volume impostato, così che sia sempre corrispondente con il reale volume:

- alias: "Workaround per aggiornare sempre volume_level di Alexa"
  service: python_script.set_state
  data:
    entity_id: "{{target}}"
    volume_level: "{{volume | default(0.6) | round(2)}}"

Perchè viene fatta questa operazione? Alexa Media Player si basa su un Websocket costantemente attivo con i server Alexa che aggiorna Home Assistant con gli aggiornamenti di stato dei dispositivi Alexa. Normalmente, quindi, il volume viene aggiornato automaticamente dall’integrazione. Ma capita, purtroppo, che il websocket si disconnetta e l’integrazione non è più in grado di riattivarlo (senza un riavvio di Home Assistant…) e in tal caso il volume non si aggiorna più. Con questo workaround, invece, l’attributo sarà aggiornato sia che il websocket sia in funzione che nel caso contrario.

Avevo aperto un issue chiedendo che questa operazione avvenisse automaticamente nell’integrazione ma l’autore mi ha risposto, in modo non molto garbato, che non ha intenzione di implementarlo. Ecco perchè il workaround…
Lo script multinotify_alexa_post

Al pari dello script multinotify_alexa_pre anche questo script multinotify_alexa_post viene richiamato una volta per ogni dispositivo Alexa coinvolto ma al termine dell’esecuzione di multinotify.

  # AD USO INTERNO. Viene chiamato per ogni entità Alexa DOPO il messaggio di notifica
  multinotify_alexa_post:
    alias: "Gestione singola Alexa POST"
    description: "Processa la singola Alexa nel ciclo di Multinotify dopo l'annuncio. Non è pensata per l'utilizzo da parte dell'utente"
    fields: 
      target:
        name: "Entità Alexa"
        description: "Entità singola di Alexa da processare"
    sequence:
      - variables:
          object_id: "{{target | regex_findall('\\.(\\w+)') | first}}"
          prev_vol: "tmp.alexa_{{object_id}}_prev_volume"
          was_playing: "{{state_attr(prev_vol, 'was_playing')}}"
      - alias: "Imposta volume precedente"
        service: media_player.volume_set
        target:
          entity_id: "{{target}}"
        data:
          volume_level: "{{states(prev_vol)}}"
      - alias: "Workaround per aggiornare sempre volume_level di Alexa"
        service: python_script.set_state
        data:
          entity_id: "{{target}}"
          volume_level: "{{states(prev_vol)}}"

      - alias: "Se era in riproduzione precedentemente ripristino la riproduzione"
        choose:
        - conditions: "{{was_playing}}"
          sequence:
            - alias: "Attesa per lasciare applicare il volume ad Alexa"
              delay: 2
            - alias: "Ripristina riproduzione"
              service: media_player.media_play
              target:
                entity_id: "{{target}}"

Questo script ha come solo parametro di ingresso target contenente, come è facile intuire, l’entity_id del dispositivo Alexa.
La prima cosa che fa questo script è preparare delle variabili da usare in seguito tramite il blocco variables:

- variables:
    object_id: "{{target | regex_findall('\\.(\\w+)') | first}}"
    prev_vol: "tmp.alexa_{{object_id}}_prev_volume"
    was_playing: "{{state_attr(prev_vol, 'was_playing')}}"

In object_id viene messo il nome dell’entity_id senza dominio del dispositivo Alexa. Ad esempio per l’entità media_player.alexa1 object_id conterrà alexa1. La regex, infatti, preleva il contenuto del parametro target a partire dal carattere che segue il punto.

In prev_vol recuperiamo l’entity_id temporanea che avevamo creato dove abbiamo salvato il volume del dispositivo Alexa prima di modificarlo.

In was_playing preleviamo l’attributo was_playing dell’entità temporanea in cui abbiamo salvato se il dispositivo stava riproducendo musica.

Siamo ora pronti a ripristinare il volume precedente all’annuncio:

- alias: "Imposta volume precedente"
  service: media_player.volume_set
  target:
    entity_id: "{{target}}"
  data:
    volume_level: "{{states(prev_vol)}}"

Unica nota vediamo che qui preleviamo lo stato dell’entità il cui entity_id è memorizzato in prev_vol tramite la funzione states.

Come anche nello script precedente anche qui applichiamo il workaround per assicurarci che il volume dell’entità Alexa sia coerente con il volume che abbiamo impostato, anche se il websocket di Alexa Media Player dovesse cadere:

- alias: "Workaround per aggiornare sempre volume_level di Alexa"
  service: python_script.set_state
  data:
    entity_id: "{{target}}"
    volume_level: "{{states(prev_vol)}}"

Ultimo step è quello di riprendere la riproduzione di musica, qualora prima dell’annuncio il dispositivo lo stesse facendo:

- alias: "Se era in riproduzione precedentemente ripristino la riproduzione"
  choose:
  - conditions: "{{was_playing}}"
    sequence:
      - alias: "Attesa per lasciare applicare il volume ad Alexa"
        delay: 2
      - alias: "Ripristina riproduzione"
        service: media_player.media_play
        target:
          entity_id: "{{target}}"

Il choose esegue la sequenza solo se la variabile was_playing è true. In tal caso ci sarà una pausa di 2 secondi, per assicurarci che il cambio volume sia stato eseguito sul dispositivo, e verrà richiamato il servizio media_player.media_play sul dispositivo memorizzato in target. Questo farà riprendere la musica da dove era rimasta.

I workaround per Alexa Media Player

Nello script applico due workaround per degli annosi problemi che affliggono Alexa Media Player e che l’autore dell’integrazione non sembra intenzionato a risolvere.

Il primo lo abbiamo già visto applicato negli script multinotify_alexa_pre e multinotify_alexa_post, ovvero ogni volta che impostiamo un volume su un dispositivo Alexa richiamiamo la seguente azione per assicurarci che l’attributo volume_level dell’entità Alexa rispecchi il volume impostato anche se il websocket di aggiornamento dovesse essersi interrotto (cosa che capita piuttosto frequentemente e non viene più ripristinato fino al riavvio…):

      - alias: "Workaround per aggiornare sempre volume_level di Alexa"
        service: python_script.set_state
        data:
          entity_id: "{{target}}"
          volume_level: "{{states(prev_vol)}}"

Questo l’issue dove l’avevo segnalato all’autore si Alexa Media Player.

Il secondo è rappresentato dall’automazione in fondo al package:

automation:
  # Risolve il bug di attributo volume_level non presente all'avvio di Home Assistant
  # Ref: https://github.com/custom-components/alexa_media_player/issues/1394
  - id: 2d897264-e05c-46bd-ba23-772fbeeab7be
    alias: "Alexa - Evento - Reimposta volume all'avvio di Home Assistant"
    trigger:
      - platform: homeassistant
        event: start
    action:
      - alias: "Imposta il volume al 60%"
        service: media_player.volume_set
        target:
          entity_id: group.all_alexa
        data:
          volume_level: 0.6

Alexa Media Player, quando Home Assistant si avvia, non aggiorna lo stato del volume nelle entità Alexa, ovvero l’attributo volume_level di tali entità non viene valorizzato. Questo non permette a multinotify di conoscere il volume dei dispositivi Alexa, dopo un riavvio di Home Assistant (che come sappiamo è una cosa che capita di frequente).
Di conseguenza al riavvio di Home Assistant imposto il volume di ogni dispositivo Alexa al 60%. Questo fa si che il volume venga impostato negli attributi volume_level e permetta il regolare funzionamento successivo.

Questo l’issue in cui è stato segnalato il problema e io stesso ho dato il mio appoggio.

Conclusione

Spero di non averti annoiato a morte con questo articolo!
Il mio intento è sempre quello di prendere spunto da qualche lavoro per spiegare le tecniche usate e aiutare ad incrementare la capacità di realizzare script ed automazioni sempre più avanzati, piuttosto che la mera diffusione e utilizzo a scatola chiusa, senza capirne i principi di funzionamento.

Se poi non hai avuto tempo o voglia di andare oltre il capitolo “Come funziona lo script multinotify” spero almeno che troverai utile questo package tanto quanto lo trovo utile io! (e chissà che approfondirai il principio di funzionamento un domani)

Una cosa è certa: se sei arrivato fin qui hai tutto il diritto di darti una pacca sulla spalla!

Buone notifiche a tutti 🙂

Ti è piaciuto questo contenuto?

Se ti è stato utile l’articolo che hai letto potresti pensare di darmi una mano offrendomi qualche caffè!
Oltre ad aiutarmi a star sveglio nelle nottate di ricerche e scrittura mi daresti una mano concreta nel sostenere le spese del server web, incentivandomi a produrre altri contenuti di qualità.

Puoi usare Paypal:

Oppure Buymeacoffee:

Henrik Sozzi

Sono un analista programmatore per lavoro e per passione. Amo la domotica, la stampa 3D e la tecnologia in generale.

Questo articolo ha 39 commenti.

  1. Michelangelo

    Bellissimo package, usavo già da tempo la prima versione (modificata) con un Google Chromecast e due Google Nest mini, ora con questa è bello poter reimpostare il volume precedente.
    Mi chiedevo se metterai il supporto ufficiale anche per i Google Nest, con i limiti del caso (ho visto che la musica non viene ripristinata dopo un messaggio e non c’è l’entità media_player.ovunque), che comunque risulta gestibilissimo.
    Eventualmente sono disponibile per fare dei test!

    P.S.: quelle belle icone PNG 48×48 con trasparenza dove le hai trovate?

    1. Henrik Sozzi

      Ciao e grazie! Immagino tu sia l’utente GitHub dell’issue. Rispondo anche qui per completezza: ho appena comprato un Google Nest mini per collaudare e supportare anche Google 😜
      Ho diverse cose in programma per il multinotify in futuro, più servizi di notifica e una centralizzazione che semplificherà notevolmente l’utilizzo. Stay tuned 😉
      PS: le PNG sono prese da varie repository in rete. Alcune sono icone di Windows (r), altre sono di utenti vari e quelle piatte sono mdi icons modificate da me con un glow bianco (non che mi convincano un granché a dire il vero)

  2. Michelangelo

    Si sono stato io 😊
    Su GitHub ti ho allegato il file con le modifiche che ho apportato per farlo funzionare con i Google Nest mini (ho rimesso le entità di esempio originali).
    Non vedo l’ora di vedere gli sviluppi.
    Attendo anche l’articolo aggiornato sulla posizione delle persone, quello mi è stato davvero utile per attivare altre automazioni. 😁

    1. Henrik Sozzi

      Ah ecco 🙂 Ho visto il commento all’issue, grazie per il file! Quando mi arriverà il Google Nest Mini e avrò tempo lo implementerò in modo integrato. Sarà una bell’aggiunta agli altri servizi. Ti ringrazio per la collaborazione e per l’entusiasmo! 🙂
      Riguardo all’articolo sulla posizione devo trovare il tempo di mettermi ad aggiornarlo… Spero di riuscirci presto.

  3. Federico

    Ciao e complimenti per il tuo lavoro!! purtroppo avendo iphone non posso usare appieno le potenzialità di questo fantastico strumento! Attendo con ansia la versione compatibile con app companion ios..

    1. Henrik Sozzi

      Ciao e grazie! Si, mi sono dimenticato di avvisare di questo limite (lo farò appena riesco).
      Ma soprattutto ho intenzione di supportare anche iPhone, Google home ed altri servizi… 😉

  4. Alex

    Ciao Henrik, dopo aver installato il package, quando provo a verificare la configurazione prima del riavvio, Home Assistant mi risponde con “Package multinotify setup failed. Component script has duplicate key ‘alias'” naturalmente non ho modificato nulla sotto la riga “— NON MODIFICARE OLTRE QUESTA RIGA —”
    Puoi darmi qualche dritta?

    1. Henrik Sozzi

      Ciao, può essere che hai il multinotify vecchio in un altro package? Ho scelto di lasciare lo stesso nome quindi o tieni uno o l’altro (questo v2 è MOLTO meglio comunque e molto altro arriverà…)

      1. Alex

        TANA!!! Trovato grazie!

  5. Federico

    Domanda.. io ho automazioni con un data_template xchè contengono codice nel messaggio ( if is_state.. ecc).. in questo caso come devo comportarmi?

      1. Federico

        Scusa nn avevo notato che bastasse sostituire la voce data_template con data.. 😉 aspetto con ansia l’implementazione per le notifiche su iphone..ancora complimenti!

    1. Federico

      Ok, risolto bastava eliminare data_template e sostituirlo con data e lasciare il resto del messaggio invariato

  6. Alessio

    Ciao, complimenti per la guida. Non riesco a mergiare però il package: mi dice “Package multinotify setup failed. Component script cannot be merged. Dict expected in main config.”
    Qualche idea?

    1. Henrik Sozzi

      Ciao perdonami mi è sfuggito il tuo commento! Grazie per i complimenti 🙂 Se da quell’errore non hai configurato correttamente i package.
      In configuration.yaml devi avere il seguente codice (ammesso di avere una sottocartella “packages” contenente i package):
      homeassistant:
      packages: !include_dir_named packages

      (nei commenti non mantiene gli spazi. Ci sono due blank nella seconda riga davanti a packages:)
      Il multinotify è solo da incollare in tale cartella packages e deve funzionare.

      Fai riferimento alla doc ufficiale: https://www.home-assistant.io/docs/configuration/packages/ e/o al capitolo dell’articolo di Vito Antonucci: https://www.vitoantonucci.it/2021/03/home-assistant-costruiamo-le-fondamenta/#14

  7. Gino

    Ciao Henrik. Complimenti per questa nuova guida. Non sai quanto mi ha aiutato a migliorare le notifiche del mio sistema.

    Ho solo un quesito.
    Tutto funziona perfettamente tranne se utilizzo l’entità speciale “media_player.ovunque”.

    Mi spiego meglio, ho impostato nel gruppo all_alexa il mio unico dispositivo alexa.
    Quando richiamo lo script con target alexa uguale a media_player.ovunque, il volume viene impostato correttamente (si sente il beep) ma Alexa non pronuncia alcun messaggio e dopo qualche secondo di nuovo il beep del volume.

    Da cosa può dipendere? Potrebbe essere perchè ho un solo dispositivo nel gruppo all_alexa?
    Non è un grande problema (nel mio caso, imposto direttamente il mio dispositivo e risolvo) ma è giusto per capire

    1. Gino

      Ho dimenticato di dire che se uso come target “group.all_alexa” funziona.

    2. Henrik Sozzi

      Ciao Gino, sono contento che lo script ti sia di aiuto. Ho in programma diverse migliorie… 🙂
      L’entità media_player.ovunque è la trasposizione del gruppo Ovunque presente in Alexa. Ora mi viene il dubbio se viene creato automaticamente come ero convinto o l’avessi creato io quando ho comprato i primi Echo Dot…
      Ad ogni modo in entrambi i casi è logico che tu non ce l’abbia, avendo un solo dispositivo.
      Se vuoi predisporti per il futuro crea un “gruppo di altoparlanti” dall’app Alexa, dove metti dentro il tuo dispositivo e in futuro metterai gli altri, nominalo Ovunque e sei future proof 🙂

  8. gfkappa63

    Ciao Henrik, ancora complimenti e ancora grazie per la dettagliatissima spiegazione ed ottima soluzione.

    Avevo integrato nel precedente script la notifica su iPhone via companion app, solo icona titolo e messaggio, rinunciando a group, channel e tag:

    #————————————————————————————#
    # Sezione notifiche app mobile #
    #————————————————————————————#
    – choose:
    conditions:
    – condition: state
    entity_id: ‘input_boolean.notifiche_mobile_app_iphonegfk’
    state: ‘on’
    sequence:
    – service: notify.mobile_app_iphonegfk
    data:
    title: ‘{{ states(“sensor.assistente”) }}’
    message: “{{icon}} – {{title}} {{ now().strftime(‘%Y-%m-%d %H:%M:%S’) }} – {{message}}”

    stessa logica per Telegram e Notifiche persistenti sempre utilizzando una variabile esterna per l’attivazione (ma potrebbe essere sostituita da una variabile di script):

    #—————————————————————————————–#
    # Sezione messaggio notifica persistente #
    #—————————————————————————————–#
    – choose:
    conditions:
    – condition: state
    entity_id: ‘input_boolean.notifiche_persistenti’
    state: ‘on’
    sequence:
    – service: notify.persistent_notification
    data:
    title: ‘{{ states(“sensor.assistente”) }}’
    message: “![image](/local/notify/notify_small_{{icon | default(‘info’)}}.png) {{title}} {{ now().strftime(‘%Y-%m-%d %H:%M:%S’) }} – {{message}}”

    #—————————————————————————————–#
    # Sezione messaggio notifica telegram #
    #—————————————————————————————–#
    – choose:
    conditions:
    – condition: state
    entity_id: ‘input_boolean.notifiche_telegram_gfk’
    state: ‘on’
    sequence:
    – service: notify.telegram_gfk
    data:
    title: ‘{{ states(“sensor.assistente”) }}’
    message: “{{icon}} – {{title}} {{ now().strftime(‘%Y-%m-%d %H:%M:%S’) }} – {{message}}”

    Il mal di testa comincia con l’integrazione delle SONOS che uso al posto di Alexa, qualcosa ancora non mi torna con i servizi sonos.snapshot e restore per salvare il PRE e il POST che non hanno un comportamento lineare o perlomeno non l’ho capito fino in fondo (ma prima o poi riuscirò ad addomesticarli).

    Ancora grazie e in attesa del tuo prossimo articolo!

    1. Henrik Sozzi

      Ciao Gianfranco, ti ringrazio anche qui per la tua generosità, oltre che per le parole gentili. Come ti ho scritto su buymeacoffee è un grande stimolo per me. Non per il denaro in sè (che fa comodo per pagare l’hosting) ma per la prova tangibile che qualcuno ha apprezzato il mio lavoro 🙂
      Grazie per il codice che hai mandato, mi piacerebbe integrare questi servizi nel mio multinotify (lo stavo facendo ma ho incontrato un periodaccio al lavoro…) Particolarmente riguardo ad iphone cosa inserisci in {icon}? Del codice HTML con una img per mostrare l’icona? E’ un workaround in quanto iphone non supporta le icone delle notiifche?
      Riguardo a Sonos mi spiace ma non posso aiutarti in quanto non ho alcun dispositivo di quel tipo. Ti posso dire che anche ripristinare il volume di Alexa è una cosa scientifica ed ha richiesto parecchio sforzo per funzionare in modo affidabile (e ogni tanto Alexa Media Player perde il websocket e non funziona più bene… Chissà se prima o poi lo risolveranno) quindi… in bocca al lupo.
      Ti invito comunque a partire dalla versione su github che è la più aggiornata, magari si può collaborare e arrivare ad una versione che supporta “tutto”… 😉

      1. Henrik Sozzi

        Da ieri sera c’è su github la versione 3.1 del multinotify che aggiunge il supporto ad iphone (grazie per lo spunto) ed a Pushover.

      2. gfkappa63

        Ciao Henrik, è un piacere poter contribuire nel mio piccolo. Quando professionalità e ingegno si contaminano con la passione il risultato è sorprendente. Se poi aggiungiamo la voglia di condividere il proprio lavoro con gli altri, bè … chapeau.
        Tornando allo script in {icon} passo solo un testo, così come previsto come parametro dal tuo script, sia per iphone che per telegram a quel punto il messaggio completo inviato contiene solo testo come stringa composta da {icon} (esempio alert) – {title} (esempio SYSTEM + data e ora) – {message} (esempio Errore Backup).
        Sulle SONOS ci lavoro, devo risolvere un problema quando è attivo il join (multistanza).
        Ho però modificato un pò la logica, rispetto al tuo script che utilizza le variabili per dare massima flessibilità, ho preferito creare un pannello di configurazione dove attivo o disattivo gli speaker da usare, imposto i canali da attivare/disattivare (notifiche persistenti, telegram, iphone, ipad) e i volumi: giorno, notte o quando sono in riunione 🙂

        1. Henrik Sozzi

          Complimenti anche a te, amo vedere quando il mio lavoro ha stimolato e contaminato quello degli altri che lo rivedono secondo il loro punto di vista… E’ proprio il risultato che mi piace vedere perchè significa che non stai applicando passivamente il mio lavoro (che è pur lecito eh!) ma stai prendendo spunto e modificando per adattare il lavoro alle tue esigenze. Bellissimo, grazie di aver condiviso la tua esperienza!
          Il mio script è pensato per essere generico e più plug-and-play possibile, ovvero che l’utente medio possa “buttarlo dentro” ai propri package dovendo modificare il meno possibile. Questo porta ovviamente a tanti compromessi in virtù della genericità (e tanti sforzi… Ad esempio i for each, che ora si possono fare nativamente, creando entità temporanee per ogni dispositivo, così che ne hai uno o 100 funziona in modo dinamico).
          Chiaro che costruire intorno alle proprie esigenze è diverso e ti permette di entrare nel dettagli dei tuoi dispositivi e delle tue esigenze. Ma a quel punto diventa difficilmente trasportabile al grosso degli utenti. Questo solo per spiegare il “perchè” dei compromessi.
          Ad ogni modo i volumi differenti per fasce orarie differenti penso che entrerà anche nel mio script perchè mi è stato chiesto più di una volta. Per me non è un’esigenza ma evidentemente per tanti si.
          Ti anticipo che ci sarà anche uno script che lavorerà al di sopra di multinotify dove il tipo ed i parametri delle notifiche saranno centralizzati… Ma non voglio spoilerare troppo… 😉
          Spero di arrivare alla fine a creare qualcosa che possa contribuire ed essere utile per tutti. Sarebbe una bella soddisfazione.

  9. Francesco

    Ciao Henrik, bellissimo lavoro, ho già implementato tutto e con alexa funziona alla grande!
    Il problema però è che non riesco a farlo funzionare con le app.
    Se vado su strumenti per sviluppatori e provo ad inviare una notifica alla mia app il servizio che mi spunta è questo qui:
    service: notify.mobile_app_telefono_francesco
    Se invoco il servizio questo funziona tranquillamente e mi arriva la notifica sul cellulare.

    Quando però vado ad inserirlo in multinotify.yaml, in questo modo:

    notify:
    # Gruppo notify.all_devices da utilizzare in multinotify per inviare una notifica a tutte le app
    – name: all_devices
    platform: group
    services:
    # TODO: modificare l’elenco dei servizi con i propri servizi di invio notifica alle app Home Assistant Companion collegate
    – service: notify.mobile_app_telefono_francesco

    Dopo aver salvato, vado a convalidare la configurazione, ma mi dice che la configurazione non è valida, con questo messaggio di errore:

    Invalid config for [notify.group]: invalid slug notify.mobile_app_telefono_francesco (try notify_mobile_app_telefono_francesco) for dictionary value @ data[‘services’][0][‘service’]. Got ‘notify.mobile_app_telefono_francesco’. (See ?, line ?).

    Potresti suggerirmi da cosa dipende? Grazie Mille e buona giornata!

    1. Henrik Sozzi

      Ciao, la risposta te la sta indicando molto chiaramente l’errore nel log: nel gruppo di notify non devi indicare l’entity_id ma l’object_id ovvero non notify.mobile_app_telefono_francesco ma solo mobile_app_telefono_francesco 🙂

      1. Francesco

        scusami avevo dimenticato ad includere nel precedente commento che avevo già provato ad inserire soltanto: mobile_app_telefono_francesco
        Ma così facendo provando lo script da strumenti per sviluppatori, su “Servizio notifica app” mi restituisce:
        Non sono state trovate entità corrispondenti.

        Hai idea di come posso risolvere?
        Grazie mille ancora

        1. Henrik Sozzi

          Sono due cose che non c’entrano. La sintassi corretta (che trovi nel mio file che hai scaricato) è di inserire solo l’object_id mobile_app_telefono_francesco. E così avrai un servizio notify.all_devices funzionante (lo puoi collaudare per i fatti suoi come proveresti notify.mobile_app_telefono_francesco).
          Nel notify mi è rimasto il selettore del campo relativo al nome del servizio per l’app da usare perchè cercavo disperatamente un modo per caricare i servizi di notifica nella casella a discesa ma non c’è modo. Mi è rimasto quindi il selettore, che fa pensare che debba esserci un elenco ma è “normale” che l’elenco non ci sia, purtroppo. E’ un limite di Home Assistant. Devi invece scrivere il nome del servizio che vuoi a mano e vedrai che funziona 🙂
          Tutto sommato è una cosa minore perchè Strumenti Sviluppatore lo usi solo per fare le prove, poi dalle automazioni devi comunque scrivere il codice 🙂

  10. Calogero Castronovocalogeri

    io ho seguito la guida passo passo ho installato lo script set_state etc etc ma quando vado ad invocare lo script multinotify HA non lo trova

    1. Henrik Sozzi

      Hai attivato i packages? Hai riavviato il core? Se vai in strumenti sviluppatore in servizi non trovi il multinotify?

  11. Federico

    ciao Henrik, nella sezione di notifica all’app “notify_app:” si possono inserire dei template o solamente il dispositivo target?

    1. Henrik Sozzi

      Ciao, si si, puoi usare template in ogni parametro come credi. Questa è una modifica che c’è stata a livello generale in Home Assistant tanto tempo fa quando si è passati dai parametri speciali value_template (ed altri) a value. In tal contesto hanno abilitato la possibilità di usare template ovunque nei parametri.
      PS: ti ho eliminato il messaggio doppio. La prima volta che posti sul sito devo approvare il commento e non sempre riesco a farlo subito.
      EDIT: dimenticavo. Ti consiglio di utilizzare l’ultima versione (ver. 3.7.0 nel momento in cui scrivo) presente sul repo github. Aggiornerò l’articolo o ne creerò uno nuovo per le novità ma sul repo è tutto descritto per filo e per segno nel readme.

  12. Federico

    Tutto perfetto e funzionante!! Grande lavoro complimenti!! Ho altri due quesiti ( pensavi fosse finita eh?).. nella card di lovelace inserisco il messaggio ma nn viene riprodotto, si sente solo il suono dell’announce di alexa e basta..il secondo è questo: nella voce attachment se inserisco l’entità della videocamera mi manda un mess con lo screenshot della camera.. fin qui ok se tengo premuta la notifica mi apre la live, ok, ma mi chiedevo se fosse possibile vedere lo snapshot, perche se tappo sulla notifica mi apre home assistant e nn mi fa vedere la foto ( te lo chiedo perche nella mia vecchia automazione avevo da un lato il salvataggio dello snapshot e dall’altro, aprendo la notifica, mi apriva la foto). pensi si possa fare una cosa del genere? tap singolo apro lo snapshot; tap prolungato apro la live

  13. Michele

    Ciao Henrick. Ci siamo sentiti un po’ di mesi fa (vers. 2) per qualche problema con gli iPhone ma ora vedo che hai risolto e fatto passi giganti. Congratulazioni per il tuo grande lavoro e per continuare a sviluppare Multinotify, rendendolo sempre più completo e performante. Ho aggiornato alla 3.7 e ho notato che usando la Stack-in-card sulla dashboard, come da te previsto su GitHub, nel campo Destination, vengono visualizzate solo max 4 option dalla input_select.multinotify_dest, anche se ne ho inserite di più in “multinotify_ui.yaml”. Ho fatto diverse prove ma nulla da fare, pare che sia un limite intrinseco della Stack-in-card. Infatti usando la normale Stack-in-card fornita da Home Assistant, tutto funziona correttamente. Te lo segnalo perchè, in attesa che lo sviluppatore della “vertical-stack-in-card” risolva il problema, tu lo possa evidenziare nelle istruzioni di installazione del tuo Multinotify, facendo così risparmiare varie ore di prove e mal di testa a chi lo vorrà usare.

    1. Henrik Sozzi

      Ciao Michele, grazie per i complimenti! Si, ora iphone è un cittadino di serie A in multinotify, grazie all’aiuto dell’amico Francesco Calamita che ha testato le modifiche di volta in volta. Ora anche mia figlia, ahimè, ha un iphone quindi riesco a testarlo in casa.
      Si, a quanto pare la vertical-stack-in-card taglia il contenuto che eccede il bordo e quindi anche le caselle a discesa vengono tagliate… In realtà volevo aggiungere diverse cose a quella card tale per cui espandendosi dovrebbe diminuire il problema. Ma nel frattempo (bravo!) la soluzione potrebbe essere quella di usare la vertical-stack compresa nel core, sacrificando un po’ l’estetica.
      Le card le avevo create un po’ come “segnaposto” per facilitare le prove e quindi lo sviluppo, non pensavo potessero interessare così tanto (non solo a te…). Ci proverò a lavorare un po’ su nelle prossime versioni.
      Intanto grazie per la segnalazione!

  14. Michele

    Grazie per la veloce risposta. Vedo che non prevedi ancora l’uso di icon su piattaforma IOS perchè, giustamente come spieghi, occorrerebbe usare le SF Symbols library. IMHO, sarebbe interessante che Multinotify prevedesse anche quelle, per uniformità d’uso. Penso che interesserebbe anche ad altri. Potrei provare a trovare una soluzione da solo, ma preferisco non discostarmi dalle tue versioni per poter procedere con gli aggiornamenti, senza impazzire, quando li pubblicherai, quindi preferisco attendere la tua versione ufficiale. Buon lavoro, ancora!

    1. Henrik Sozzi

      Hai ragione. Inizialmente pensavo di simulare la cosa allegando l’immagine dell’icona PNG usata anche per Android. Ma il buon Francesco Calamita, che mi ha aiutato a debuggare su iphone, l’ha bocciato perchè espandendo la notifica faceva vedere l’icona grande e sgranata, una schifezza. Avevo pensato allora di mappare in qualche modo i simboli SF Symbols così da non doverli specificare ma è più la complicazione che il guadagno.
      Alla fine farò come immagino che tu stia suggerendo: aggiungo un parametro specifico per iphone con il simbolo da usare, così completiamo la cosa.
      Ti ringrazio per la fiducia nel non discostarti dalla versione ufficiale, mi riempie di orgoglio 🙂
      Grazie per i suggerimenti!

Rispondi

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.