Al momento stai visualizzando Impostare lo stato di un’entità in Home Assistant [aggiornato]

Impostare lo stato di un’entità in Home Assistant [aggiornato]

  • Autore dell'articolo:
  • Categoria dell'articolo:Home Assistant
  • Commenti dell'articolo:15 commenti
  • Ultima modifica dell'articolo:10 Gennaio 2022

Dopo un po’ di esperienza configurando automazioni a molti insorge l’esigenza di impostare lo stato di un’entità in Home Assistant.

Può essere utile per impostare lo stato di un’entità di tipo device_tracker in base alla rete WiFi collegata allo smartphone, per forzare uno stato di un’entità da un’automazione, per creare un’entità provvisoria in cui memorizzare lo stato precedente o per simulare qualcosa.

Per qualunque fine ci serva ci scontreremo presto con il fatto che non è possibile impostare lo stato o l’attributo di un’entità in modo nativo in Home Assistant, men che meno creare una nuova entità da un’automazione o uno script. Ma fortunatamente la soluzione è piuttosto semplice.

Se ti interessa sapere come fare continue a leggere e sarai in grado di farlo!

Abilitare gli script Python

Come prima cosa dovremo abilitare la possibilità di creare degli script scritti in linguaggio Python nella nostra configurazione di Home Assistant.

Farlo è molto semplice, basta inserire la seguente riga nel nostro configuration.yaml o in un package:

python_script:

Sarà inoltre necessario creare la cartella python_scripts all’interno della nostra cartella config.
In tale cartella si potrà quindi creare un file .py per ogni script python che vorremo utilizzare.

Se poi vorremo documentare i parametri dei nostri script, come faremmo con uno script scritto in yaml (ad esempio vedi il mio script multinotify), basterà creare un file services.yaml nella cartella python_scripts appena creata, nel quale inserire la definizione di ogni script con la descrizione ed i campi, senza il corpo dello script. Fate attenzione che il nome delle definizioni nel file services.yaml devono corrispondere ai nomi dei file .py, che sono anche i nomi dei servizi da richiamare per eseguire tali script.

Per ulteriori indicazioni fare riferimento alla guida ufficiale.

Creare lo script set_state per impostare lo stato di un’entità in Home Assistant

ATTENZIONE! Ho aggiornato lo script al 10/01/2022 (lo riconosci anche dal nome del file che termina con …-v2.zip) con una nuova versione, compatibile con la precedente ma che supporta, in più, la creazione di nuove entità. Se avevi già installato tale script assicurati che la tua versione sia uguale a quella che trovi ora!

Per creare lo script set_state scarica lo zip di seguito e scompattane il contenuto nella cartella config/python_scripts.

In alternativa puoi fare copia/incolla creando i seguenti due file sempre nella cartella config/python_scripts:

set_state.py

#==================================================================================================
#  python_scripts/set_state.py 
#  modified from - https://community.home-assistant.io/t/how-to-manually-set-state-value-of-sensor/43975/37
#==================================================================================================

#--------------------------------------------------------------------------------------------------
# Set the state or other attributes for the entity specified in the Automation Action
#--------------------------------------------------------------------------------------------------

inputEntity = data.get('entity_id')
if inputEntity is None:
    logger.warning("===== entity_id is required if you want to set something.")
else:    
    inputStateObject = hass.states.get(inputEntity)
    if inputStateObject is None and not data.get('allow_create'):
        logger.warning("===== unknown entity_id: %s", inputEntity)
    else:
        if not inputStateObject is None:
            inputState = inputStateObject.state
            inputAttributesObject = inputStateObject.attributes.copy()
        else:
            inputAttributesObject = {}
    
        for item in data:
            newAttribute = data.get(item)
            logger.debug("===== item = {0}; value = {1}".format(item,newAttribute))
            if item == 'entity_id':
                continue            # already handled
            elif item == 'allow_create':
                continue            # already handled
            elif item == 'state':
                inputState = newAttribute
            else:
                inputAttributesObject[item] = newAttribute
            
        hass.states.set(inputEntity, inputState, inputAttributesObject)

services.yaml

# set_state.py
set_state:
  description: "Imposta lo stato e/o gli attributi di una entità ai valori desiderati"
  fields:
    entity_id:
      description: "Nome completo dell'entità da aggiornare"
      example: device_tracker.mio_tracker
    state:
      description: "Nuovo valore dello stato dell'entità (opzionale)"
      example: not_home
    allow_create:
      description: "Specifica se permettere di creare nuove entità (default=false, così se si sbaglia a scrivere non vengono create entità errate)"
      example: false
    other:
      description: "Qualunque altro valore verrà impostato negli attributi dell'entità. Se l'attributo non esiste verrà creato."

Al termine riavviare il core di Home Assistant da Impostazioni -> Controlli del server -> Gestione del server -> RIAVVIARE.

Come utilizzare lo script set_state per Impostare lo stato di un’entità in Home Assistant

Home Assistant creerà un servizio per ogni file .py presente nella cartella python_scripts con nome python_script.NOME_FILE. Pertanto, per il file set_state.py, avremo il servizio python_script.set_state.

Per richiamarlo basterà utilizzare questa sintassi all’interno di una lista di azioni (automazioni o script):

- service: python_script.set_state
  data:
    entity_id: device_tracker.mio_smartphone
    state: home

Tramite il codice sopra riportato lo stato dell’entità device_tracker.mio_smartphone sarà impostato a home.

Abbiamo anche la possibilità di impostare gli attributi di un’entità, semplicemente specificando come parametri ulteriori i nomi degli attributi da impostare.

Per esempio possiamo impostare lo stato e la sorgente tramite l’attributo source_type con questo codice:

- service: python_script.set_state
  data:
    entity_id: device_tracker.mio_smartphone
    state: home
    source_type: wifi

Solo se stai usando la versione aggiornata al 10/01/2022 (il file zip si chiama …v2.zip) puoi anche creare una entità ex novo. Questo può essere estremamente utile per creare on the fly da un’automazione o uno script un backup di una entità per poter ripristinarla dopo qualcosa.

- service: python_script.set_state
  data:
    entity_id: tmp.nuova_entita
    state: {{states('sensor.sensore_da_backuppare')}}
    allow_create: true

Tramite il codice sopra verrà creata (se non esiste) o aggiornata l’entità tmp.nuova_entità impostandone lo stato al valore dell’entità sensor.sensore_da_backuppare.

Attenzione! Ricorda che l’entità creata non è permanente e al primo riavvio di Home Assistant non esisterà più.

Per fare delle prove ti potrebbe essere utile usare Strumenti per sviluppatori -> Servizi nel seguente modo (la descrizione dei parametri nella parte inferiore è presente grazie al file services.yaml):

Conclusione

Questa non era per niente complicata eh? Una volta tanto… Ora puoi impostare lo stato e gli attributi di entità a piacimento o creare nuove entità (che ricorda: saranno eliminate al riavvio di Home Assistant!)

Tieni in considerazione che è un po’ aggirare il sistema in quanto Home Assistant non prevede questa possibilità.

Ciononostante set_state è una possibilità molto utile e potente, usala con responsabilità… 🙂

Henrik Sozzi

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

Questo articolo ha 15 commenti.

  1. Gianluca

    Ciao e grazie per i tuoi utili articoli. Ti chiedo una conferma da non esperto. Ma il file “services.yaml” e’ obbligatorio inserirlo nella cartella ? O si puo anche omettere ed usare solo il primo script, “set_state” ? Da quanto ho capito, quello indicato nel file “services.yaml” lo imposta gia all’ avvio di HA. Invece usando lo script “set_state” , viene impostato esempio in un automazione. Giusto?
    Grazie

    1. Henrik Sozzi

      Ciao, il file services.yaml è opzionale (magari poi lo specifico meglio) e serve solo per documentare gli script Python ed i loro parametri (ne vedi il risultato in strumenti per sviluppatori). Se non c’è funziona tutto ugualmente ma in strumenti per sviluppatori non vedi le descrizioni, tutto lì.
      Però secondo me è sempre meglio documentare tutto per evitare che dopo mesi che hai fatto qualcosa non ti ricordi più come funzioni. Credimi, da programmatore ne so qualcosa 😁

  2. daniele calzetti

    Buonasera, a me rimanda questo errore

    Logger: homeassistant.components.automation.allarme_on_arma_at_night
    Source: components/automation/__init__.py:517
    Integration: Automazione (documentation, issues)
    First occurred: 27 giugno 2021, 18:20:41 (8 occurrences)
    Last logged: 0:07:06

    Error while executing automation automation.allarme_on_arma_at_night: Unable to find service python_script.set_state
    Error while executing automation automation.allarme_on_arma_at_night: Unable to find service python_scripts.set_state

    Ho notato che la directory è python_scripts mentre in service: python.script.set_state, ma cambiando in scripts il risultato è il medesimo.
    (la mia automazione arma l’allarme di sistema non integrato e quindi non usando il servizio contemporaneamente vorrei cambiare stato ad alarm_control_panel.home.alarm in state: arming per attivare il pannello anche in lovelace)

    1. daniele calzetti

      Stupidamente mi ero dimenticato la prima nozione dell’articolo inserire “python_script:” nel file configuration.yaml, Mi rimane la curiosità di come mai si richiama in configurazione python_script e la directory si chiama python_scripts, e sicuramente questo denota che mi mancano le basi 🙂 !!! grazie un saluto

      1. Henrik Sozzi

        Ciao, scusa ti rispondo in ritardo ma credo di averti già risposto sul gruppo Facebook 😉
        L’incongruenza che denoti è effettivamente vera. Sarebbe stato più giusto che l’attivazione si chiamasse “python_scripts:” al plurale, come d’altronde si chiama la cartella. Ma ricordiamoci sempre che Home Asssitant è open source e ci lavorando in diversi. A volte le cose non sono perfette, sono realizzate con buona volontà da tanti che lo fanno nel loro tempo libero per la gloria del progetto. E considerando quanto ha rivoluzionato ed è importante per casa mia… io gli perdono la “s” 😀

  3. daniele calzetti

    Grazie della risposta, però ti dico che nonostante l’incongruenza (cioè ho scritto in configuration.yaml python_script e la cartella l’ho chiamata python_scripts come da guida) le cose sembrano funzionare lo stesso.

    1. Henrik Sozzi

      Eh certo che funzionano 😁 È un’incongruenza “by design”, il codice di HA prevede che sia così

  4. maxbarba

    Grazie Henrik !!! mi è servito per cambiare lo stato dei sensori di presenza Aqara che rimangono on per molti secondi.
    Con la modifica hardware e il tuo articolo adesso rispondono ogni 5 secondi.

    1. Henrik Sozzi

      Ciao Maxbarba! Grazie per il feedback! Interessante… Fino ad oggi la soluzione al tempo di ON con i sensori modificati con ZHA pensavo fosse un’automazione che chiamasse il servizio zha.set_zigbee_cluster_attribute verso il sensore (come documentato su Home Assistant Community). Invece tu dopo il tempo hardware di ON cambi lo stato dell’entità… Non ci avevo pensato, sembra un’ottima soluzione! Ma quindi se dopo, ad esempio, 6 secondi, c’è altro movimento torna ancora in ON, giusto?

  5. daniele

    Buonasera Henrik, scrivo in questo post augurandoti innanzitutto Buon Natale e Buone Feste; non è proprio specifico al tema ma parlando di entità vorrei chiederti se sei in grado di fornirmi un suggerimento per passare un po’ delle feste che ci aspettano al lavoro sulla configurazione di Home Assistant. Il mio problema (come si dice dove ‘casca l’asino’) è che si è rotto un sensore e devo sostituirlo e qui viene il fattaccio a cui non avevo pensato: come faccio a inserire il nuovo sensore con lo/gli stesso/i entity_id per non dover riconfigurare tutte le automazioni e tutte le configurazioni (es. lovelance)? A volte i device hanno più entity_id (esempio: battery, binary_ etc.) e gestirle tutte insieme come si fa? Nella guida ufficiale si parla di MANUAL CUSTOMIZATION: – ricordo che alcune versioni indietro di Home Assistant c’era un menu che configurava un file custumize.yaml che ancora ritrovo, che ne pensi? Grazie un saluto.

    1. Henrik Sozzi

      Ciao Daniele, scusa il ritardo ma con le feste potrai immaginare… 😀 Intanto buone feste anche a te!
      Se utilizzi la platform device (di solito avviene se usi l’UI per fare le automazioni e usi “dispositivo”) ad ogni dispositivo viene assegnato da Home Assistant un id random non sotto il tuo controllo, per cui se elimini il vecchio device rotto e inserisci il nuovo questo avrà un nuovo id e, conseguentemente, dovrai modificare il dispositivo ovunque l’hai usato (motivo per il quale consiglio sempre di NON usare la piattaforma device…)
      Se invece usi gli entity_id, come credo, tieni presente che le integrazioni le creano con una nomenclatura ben specifica. Ad esempio gli Shelly quando aggiungi un dispositivo dal nome, per esempio, “Luce cucina” ti creano tutti gli entity_id sulla base del nome in cui al posto degli spazi ci sono gli underscore. Nell’esempio sopra avrai cose come “switch.luce_cucina”, “sensor.luce_cucina_power”, “sensor.luce_cucina_energy”, “binary_sensor.luce_cucina_overpower” e così via.
      Se hai “fatto casino” e vuoi riportare l’ordine negli entity_id (ad esempio perchè hai dato il nome allo shelly dopo averlo aggiunto ad HA) basterà rinominare il dispositivo e HA ti chiederà se vuoi rinominare le entità sulla base del nome scelto, premi RINOMINA e voilà.
      Quindi se avevi un device ordinato con le entity_id secondo questo schema basta eliminare il vecchio device e aggiungere il nuovo nominandolo come quello precedente e tutte le entità avranno nome uguale a quelle precedenti, lasciando tutte le automazioni funzionanti.
      Occhio che se aggiungi il device con il vecchio ancora integrato avrai tutte le entità che finiscono con “_2” che poi dovrai rinominare a mano.
      Altra possibilità, utile nel caso in cui il tuo vecchio device avesse entity_id non nominati in modo regolare con il device, è quella di segnarti tutti gli entity_id che usavi precedentemente, eliminare il vecchio device, integrare il nuovo e rinominare ogni entity_id con lo stesso che ti eri segnato da quello precedente.
      Per le automazioni basta che gli entity_id siano uguali e continuano a funzionare.
      Per far tutto questo non serve il customize.yaml o altro.
      Un saluto, buon lavoro sul tuo HA 🙂

  6. daniele

    Grazie Henrik come al solito accendi la luce, per questo darò il mio sostegno 2023 per il tuo blog (lunga vita al blog H.E.Tech 🙂 , mi piacerebbe che questo fosse lo spunto per un tuo nuovo articolo, perchè credemi, per novizi come il sottoscritto, non è per nulla scontato questo problema della definizione delle entità, anzi si parte usando UI e poi la vita si complica (anche se il mio home assistant è una macchina che va perfettamente e fa un sacco di cose anche così), ma in rete non mi sembra ci sia una guida chiara nel merito.

    Personalmente, guardando il mio file automation.yaml e spulciando i trigger, direi che ho creato varie automazioni con platform: device
    es:
    trigger:
    – type: opened
    platform: device
    device_id: 7ebb1052d9eb73a89c4540cd…….
    entity_id: binary_sensor.shelly_porta_..xxx

    Ma come vedi c’è sia device_id che entity_id. Significa che non funzionerà rinominando solo l’entity_id?
    E se così fosse, posso rimediare cancellando dal trigger i vari device_id lasciando solo entity_id, funzionerebbe?
    Un saluto.

    1. Henrik Sozzi

      Ciao Daniele, grazie di cuore per la donazione ancor più generosa delle precedenti, credimi è davvero apprezzata!
      Mi hai dato un bello spunto per un possibile articolo in effetti perché è vero che non c’è materiale di questo tipo, ti ringrazio e credo coglierò il suggerimento.
      So che con platform: device si possono essere sia il device_id che l’entity_id ma a dire il vero non so cosa succede se uno solo dei due diventa errato in quanto non lo uso mai e anche la pagina della documentazione a riguardo è davvero scarna…
      Il mio consiglio è di trasformare ogni trigger platform: device in platform: state sistemando la sintassi così che ti metti nella condizione giusta per non aver problemi in questi casi in futuro.
      Controlla anche nelle condizioni e nelle azioni. In queste ultime, per esempio, l’accensione di una luce diventerebbe qualcosa come:
      - alias: "Accende la luce della cucina"
      service: light.turn_on
      target:
      entity_id: light.luce_cucina

      Vedrai che se elimini ogni platform: device, organizzi tutto in package, metti ordine tra i dispositivi e i relativi entity_id e infine usi VSCode (come addon o standalone sul PC) per editare i package avrai notevole beneficio.
      PS: ho anche in mente qualcosa di più strutturato per imparare automazioni, script e creazione di sensori, passando per i template… Ma è ancora top secret, anche perché prima devo trovare il tempo…

Rispondi

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