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
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.
- 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.
- Vi vill skicka med ett event-id, detta kommer vi använda för att skilja ur vad det är vi vill göra.
- 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.
- 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.
Vad vi vill göra nu är:
- Sätta variabler som vi behöver
- Skicka variablerna till en fire event-nod
- 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.
Name | Label | Default value | Input type |
---|---|---|---|
CUSTOM_EVENT_ID | Event ID | string | |
CUSTOM_EVENT_SUB_ID | Sub ID | string | |
DATA | Data | {} | JSON |
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
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
//Dokumentationpayload.data
that is an object or parsable into an object these properties will be merged with any config values set.
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:
- Spara eventuell data som kommer till noden och skicka den vidare
- Tömma payload.data så vi inte skickar felaktig data till fire event-noden
- Spara ner våra Environment Variables i vårt payload message.
Regel | msg | to msg |
---|---|---|
1.Set | throughput | payload |
2.Delete | payload | |
3.Set | payload.data | $DATA |
4.Set | payload.data.event_id | $CUSTOM_EVENT_ID |
5.Set | payload.data.sub_id | $CUSTOM_EVENT_SUB_ID |
Vad vi nu gör är att (förenklat):
- Sparar ner hela inkommande payloaden till en ny variabel som vi kallar throughput
- Tar bort all information som finns i payloaden
- Sätter variabeln payload.data till det som vi skriver in i vårt subflow under variabeln $DATA
- Sätter variabeln payload.data.event_id till det som vi skriver in i vårt subflow under variabeln $CUSTOM_EVENT_ID
- 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
Vårt subflow borde nu se ut som följande:
Vi testar och kontrollerar
Skapa en inject-nod och konfigurera enligt bilden. Dvs. skicka in en payload med texten ”Detta är en text”
Dra in en debug-nod och ändra Output till complete msg object
Dra in ditt subflow och koppla ihop enligt Inject -> subflow -> debug
Konfigurera också ditt subflow med ett Event ID, Sub ID och någon data.
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.
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