Custom event och subflows med Home Assistant och Node-Red – Del 2

I förra inlägget gick vi igenom hur man kastar custom events till Home Assistant (och Node-Red). Nu ska vi se till att snygga till detta och göra egna noder med hjälp av subflows.

Tillägg: Halvvägs igenom denna del inser jag hur långt detta kommer bli. Jag får dela upp detta i två delar. Denna del hanterar subflow för att kasta event och nästa del hanterar subflow för att fånga event.

Som vanligt: Vill du inte lära dig något utan bara kopiera kod så finns detta längst ner i inlägget.

OBS! Detta är en artikel som ursprungligen var publicerad på frosenlind.se den 12 december 2020.
Länkar i inlägget som hänvisar till gamla sidan kommer inte att fungera!

Målbild

När vi är klara vill vi:

  • Kasta event till Home Assistans event buss genom en nod
  • Skicka med data till eventet på ett enkelt sätt
  • Fånga vårt event med en nod
  • Kunna använda vår medskickade data på ett enkelt sätt
Kasta ett custom event från egen nod med extra data i Node-Red
Hämta ett custom event med egen nod i Node-Red

Genomförande

Det första vi vill göra är att bestämma vad slutmålet ska vara, min erfarenhet säger mig följande.

  1. custom_event är det vi lyssnar på, alltså behöver vi inte kunna specificera detta på varje nod. Det vi bygger förutsätter att det är custom_events vi skickar.
  2. Vi vill skicka med ett event-id, detta kommer vi använda för att skilja ur vad det är vi vill göra.
  3. Ofta finns kommer man till tillfällen då man vill ha någon form av subgruppering/sortering. Detta hade vi kunnat skicka med som data payload, men eftersom detta händer ganska ofta så väljer jag att lägga till ett sub id.
  4. Slutligen vill vi kunna skicka med godtycklig data, detta gör vi med ett json objekt.

Skapa subflow för att kasta event

Det första vi måste göra är skapa ett subflow som vi kan använda när vi ska kasta våra event. Vi gör detta i huvudmenyn -> Subflows -> Create subflow

Skapa ett nytt subflow

Denna nod vill vi kunna använda i en sekvens för att sedan bygga vidare annan logik, därför måste vi se till att denna har en input och en output. Du justerar detta i ovankant i subflow-vyn.

Node-Red, Edit subflow input/output

Vad vi vill göra nu är:

  1. Sätta variabler som vi behöver
  2. Skicka variablerna till en fire event-nod
  3. Kasta vårt event

Klicka på edit properties, längst ner i fliken Environment Variables står det add, lägg till tre variabler och ge dem egenskaper enligt tabellen nedan.

Node-Red, Edit subflow properties
NameLabelDefault valueInput type
CUSTOM_EVENT_IDEvent IDstring
CUSTOM_EVENT_SUB_IDSub IDstring
DATAData{}JSON
Node-Red, subflow Variables

Till våra Event ID och Sub ID variabler väljer vi input type string och inget default value. Till Data där vi alltid vill att vi skickar JSON väljer vi JSON som input type och default value {}. Ni kan även välja lämplig ikon till era variabler.

I UI Preview kan ni se hur det kommer se ut!

Skicka våra variabler

Nu har vi skapat de tre variabler vi behöver använda för att kunna skapa vår sekvens.

Dra in en change-nod och en fire event-nod. Koppla sedan ihop dem i ordningen:
Input->change->fire event->output

Node-Red, subflow

Vi börjar lite bakifrån och konstaterar att: om man skickar in ett meddelande till fire event-noden som heter payload.data så kommer dessa slås ihop med det vi eventuellt skriver i konfigurationen av noden.

If the incoming message has a payload.data that is an object or parsable into an object these properties will be merged with any config values set.

//Dokumentation

Vad det egentligen betyder är att vi inte kommer behöva skriva något i Data delen av konfigurationen av fire event-noden utan vi skickar in det vi behöver, för detta har vi change-noden.

I change-noden kommer vi behöva sätta upp fem regler, reglerna körs i den ordningsföljd de kommer och det är därför viktigt vilken ordning vi lägger dem i.

Vi gör några antaganden.

  • Denna nod (subflowet) kommer inte komma först i en sekvens, därför vet vi inte vad det är för input till noden.
  • Eventuell input till noden kanske vi behöver senare i en sekvens, vi vill därför skicka den vidare.
  • Eftersom vi inte vet vad som kommer som input måste vi hantera det så det inte skickas till fire event-noden.

Så vad vi måste göra är att:

Node-Red, change
  1. Spara eventuell data som kommer till noden och skicka den vidare
  2. Tömma payload.data så vi inte skickar felaktig data till fire event-noden
  3. Spara ner våra Environment Variables i vårt payload message.
Regelmsgto msg
1.Setthroughputpayload
2.Deletepayload
3.Setpayload.data$DATA
4.Setpayload.data.event_id$CUSTOM_EVENT_ID
5.Setpayload.data.sub_id$CUSTOM_EVENT_SUB_ID
Table, Node-Red, Set change node

Vad vi nu gör är att (förenklat):

  1. Sparar ner hela inkommande payloaden till en ny variabel som vi kallar throughput
  2. Tar bort all information som finns i payloaden
  3. Sätter variabeln payload.data till det som vi skriver in i vårt subflow under variabeln $DATA
  4. Sätter variabeln payload.data.event_id till det som vi skriver in i vårt subflow under variabeln $CUSTOM_EVENT_ID
  5. Sätter variabeln payload.data.sub_id till det som vi skriver in i vårt subflow under variabeln $CUSTOM_EVENT_SUB_ID

Är du osäker på ovan kan det vara värt att läsa denna korta text: https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html

Trigga vårt event

Eftersom vi nu skickar in all data vi behöver till vår fire event-nod är det inte så mycket vi måste göra här. Ge den ett lämpligt namn (typ ”trigger custom event”) och i Event: anger ni custom_event

Node_red, fire custom event

Vårt subflow borde nu se ut som följande:

Node-Red, Subflow

Vi testar och kontrollerar

Skapa en inject-nod och konfigurera enligt bilden. Dvs. skicka in en payload med texten ”Detta är en text”

Node-Red, Inject

Dra in en debug-nod och ändra Output till complete msg object

Node-Red, Debug

Dra in ditt subflow och koppla ihop enligt Inject -> subflow -> debug

Node-Red, subflow sekvens

Konfigurera också ditt subflow med ett Event ID, Sub ID och någon data.

Node-Red, subflow configuration

Jag förväntar mig nu följande svar i debugnoden:

  • En variabel throughput som innehåller texten som vi skicka in i vårt subflow i en payload variabel. Dvs. texten har flyttates från payload till throughput.
  • Ett payload-object som innehåller variabeln event_type:custom_event
    Enligt dokumentationen för fire event-nodens output.
  • Ett payload-objekt som innehåller dictonaryn data, data innehåller därefter tre variabler, event_id, sub_id och mydata.

Vi testar. Tryck på inject-noden.

Node-Red, debug

Nästan alla rätt…

throughput: ”Detta är en text”
Stämmer!

event: ”custom_event”
Enligt dokumentationen ska den heta event_type. Men informationen kommer fram och stämmer.

data: ”{”mydata”:”information is king”,”event_id”:”My test event”,”sub_id”:”My sub ID”}”
Stämmer! Precis vad vi förväntade oss.

Sammanfattning

  • Vi skapar ett subflow med en input och en output
  • Vi sparar undan inkommande data i en annan variabel som även lämnar vårt subflow för att kunna användas senare
  • Vi sparar vår konfiguration i payload.data för att skicka detta med eventet
  • Vi triggar vårt event med en fire event-nod

Allt paketerat i en snygg nod.

Länk till kod på gist: https://gist.github.com/frosenlind/c3bf7c98fe8a1dbb7245ccef5a8db60b

Leave a Reply