diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..d4b9a663b7 --- /dev/null +++ b/404.html @@ -0,0 +1,34 @@ + + + + + + + + + node-red-contrib-home-assistant-websocket + + + + + +

404

Looks like we've got some broken links.
Take me home
+ + + diff --git a/FAQ.html b/FAQ.html new file mode 100644 index 0000000000..6270e9dbb6 --- /dev/null +++ b/FAQ.html @@ -0,0 +1,34 @@ + + + + + + + + + FAQ | node-red-contrib-home-assistant-websocket + + + + + +

FAQ

What is what

node-red-contrib-home-assistant-websocket is a package that contains a set of nodes in Node-RED that interface with Home Assistant. It uses the Home Assistant WebSocket API to communicate with Home Assistant.

hass-node-redopen in new window is a Home Assistant custom integrationopen in new window. It extends the Home Assistant WebSocket API to allow Node-RED to do more with Home Assistant, such as creating sensors, buttons, and switches in Home Assistant from Node-RED. Typically, it is installed via HACSopen in new window but can be installed manuallyopen in new window.

Node-RED Home Assistant Community Add-onopen in new window is a Home Assistant Add-onopen in new window that runs Node-RED with the Home Assistant nodesopen in new window pre-installed.

Node-REDopen in new window is a flow-based development tool for visual programming developed originally by IBM for wiring together hardware devices, APIs, and online services as part of the Internet of Things.

Home Assistantopen in new window is an open source home automation that puts local control and privacy first.

Entities not showing in the autocomplete dropdown

  1. Make sure you have at least deployed once after adding a server config.
  2. There sometimes is a caching issue. Caching can be disabled for autocomplete results in the server config node and restarting Node-RED.

Entity could not be found in cache for entity_id: ???

If your flow runs before Node-RED has had a chance to connect to Home Assistant and retrieve the latest state information. The cache will be empty and this error is thrown.

Home Assistant Add-on users have a 5-second delay between connection attempts because of how the supervisor proxy works and the high CPU usage it can cause, Issue #76open in new window. The delay can be turned off in the server config.

Why do some of my nodes have a yellow font?

Starting with version 0.12.0 individual nodes on the workspace will now have a version number associated with them. This will allow changes to be made to the structure of nodes without affecting all nodes of that type until you edit them. Legacy nodes will have a yellow font until the node has been upgraded to the current version.

Just because the text is yellow on a node doesn’t mean you need to update it. It will continue to function just as it has and the next time you modify the node it will be upgraded then.

+ + + diff --git a/assets/404.html-5sy5zeZP.js b/assets/404.html-5sy5zeZP.js new file mode 100644 index 0000000000..7a25b17a47 --- /dev/null +++ b/assets/404.html-5sy5zeZP.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3706649a","path":"/404.html","title":"","lang":"en-US","frontmatter":{"layout":"NotFound"},"headers":[],"git":{},"filePathRelative":null}');export{t as data}; diff --git a/assets/404.html-DBjtgjki.js b/assets/404.html-DBjtgjki.js new file mode 100644 index 0000000000..62b03b6ae1 --- /dev/null +++ b/assets/404.html-DBjtgjki.js @@ -0,0 +1 @@ +import{_ as e,o as c,c as t}from"./app-DW3AHQOa.js";const _={};function o(r,n){return c(),t("div")}const a=e(_,[["render",o],["__file","404.html.vue"]]);export{a as default}; diff --git a/assets/API.html-BA2ozcqM.js b/assets/API.html-BA2ozcqM.js new file mode 100644 index 0000000000..b5307b2534 --- /dev/null +++ b/assets/API.html-BA2ozcqM.js @@ -0,0 +1 @@ +import{_ as c,r,o as h,c as n,a as e,d as t,b as a,w as s,e as d}from"./app-DW3AHQOa.js";const p={},u=e("h1",{id:"api",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#api","aria-hidden":"true"},"#"),t(" API")],-1),f=e("h2",{id:"config",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#config","aria-hidden":"true"},"#"),t(" Config")],-1),_={id:"protocol",tabindex:"-1"},m=e("a",{class:"header-anchor",href:"#protocol","aria-hidden":"true"},"#",-1),b=d('

Protocol to use to access Home Assistant API.

Method

Type of method to use to access the HTTP endpoint.

Path

',6),g=e("li",null,[t("Type: "),e("code",null,"string")],-1),y=e("p",null,"URL of the API endpoint.",-1),x=e("h3",{id:"params",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#params","aria-hidden":"true"},"#"),t(" Params")],-1),T=e("li",null,[t("Type: "),e("code",null,"Object")],-1),k=e("p",null,"A JSON object with key/value pairs that will be converted into URL parameters.",-1),v=e("h3",{id:"data",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#data","aria-hidden":"true"},"#"),t(" Data")],-1),O=e("li",null,[t("Type: "),e("code",null,"Object")],-1),A=d('

JSON Object to send for WebSocket requests and HTTP posts.

Results

Input

All properties need to be under msg.payload.

protocol

Overrides or sets the protocol property of the config.

method

Overrides or sets the method property of the config.

path

Overrides or sets the path property of the config.

data

Overrides or sets the data/params property of the config.

location

Overrides or sets the results property of the config.

locationType

Overrides or sets the results type property of the config.

Output

Value types:

References

',27),P={href:"https://developers.home-assistant.io/docs/api/rest",target:"_blank",rel:"noopener noreferrer"},w={href:"https://developers.home-assistant.io/docs/api/websocket",target:"_blank",rel:"noopener noreferrer"};function I(V,L){const l=r("Badge"),o=r("RouterLink"),i=r("ExternalLinkIcon");return h(),n("div",null,[u,f,e("h3",_,[m,t(" Protocol "),a(l,{text:"required"})]),b,e("ul",null,[g,e("li",null,[t("Accepts "),a(o,{to:"/guide/mustache-templates.html"},{default:s(()=>[t("Mustache Templates")]),_:1})])]),y,x,e("ul",null,[T,e("li",null,[t("Accepts "),a(o,{to:"/guide/mustache-templates.html"},{default:s(()=>[t("Mustache Templates")]),_:1})])]),k,v,e("ul",null,[O,e("li",null,[t("Accepts "),a(o,{to:"/guide/mustache-templates.html"},{default:s(()=>[t("Mustache Templates")]),_:1}),t(" when the data type is JSON")])]),A,e("ul",null,[e("li",null,[e("a",P,[t("http api"),a(i)])]),e("li",null,[e("a",w,[t("websocket api"),a(i)])])])])}const R=c(p,[["render",I],["__file","API.html.vue"]]);export{R as default}; diff --git a/assets/API.html-DH3PYQg3.js b/assets/API.html-DH3PYQg3.js new file mode 100644 index 0000000000..71b98bdcdb --- /dev/null +++ b/assets/API.html-DH3PYQg3.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-5104ae33","path":"/node/API.html","title":"API","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Config","slug":"config","link":"#config","children":[{"level":3,"title":"Protocol","slug":"protocol","link":"#protocol","children":[]},{"level":3,"title":"Method","slug":"method","link":"#method","children":[]},{"level":3,"title":"Path","slug":"path","link":"#path","children":[]},{"level":3,"title":"Params","slug":"params","link":"#params","children":[]},{"level":3,"title":"Data","slug":"data","link":"#data","children":[]},{"level":3,"title":"Results","slug":"results","link":"#results","children":[]}]},{"level":2,"title":"Input","slug":"input","link":"#input","children":[{"level":3,"title":"protocol","slug":"protocol-1","link":"#protocol-1","children":[]},{"level":3,"title":"method","slug":"method-1","link":"#method-1","children":[]},{"level":3,"title":"path","slug":"path-1","link":"#path-1","children":[]},{"level":3,"title":"data","slug":"data-1","link":"#data-1","children":[]},{"level":3,"title":"location","slug":"location","link":"#location","children":[]},{"level":3,"title":"locationType","slug":"locationtype","link":"#locationtype","children":[]}]},{"level":2,"title":"Output","slug":"output","link":"#output","children":[]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1662358213000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":5},{"name":"Keir Stiegler","email":"keir.stiegler@gmail.com","commits":1}]},"filePathRelative":"node/API.md"}');export{l as data}; diff --git a/assets/DocsOnly-DuK4YSKt.js b/assets/DocsOnly-DuK4YSKt.js new file mode 100644 index 0000000000..6f9ada95cb --- /dev/null +++ b/assets/DocsOnly-DuK4YSKt.js @@ -0,0 +1 @@ +import{_ as o,o as s,c,g as n}from"./app-DW3AHQOa.js";const t={},r={class:"docs-only"};function l(e,_){return s(),c("div",r,[n(e.$slots,"default")])}const d=o(t,[["render",l],["__file","DocsOnly.vue"]]);export{d as default}; diff --git a/assets/FAQ.html-BnloOyfX.js b/assets/FAQ.html-BnloOyfX.js new file mode 100644 index 0000000000..8de6646f74 --- /dev/null +++ b/assets/FAQ.html-BnloOyfX.js @@ -0,0 +1 @@ +import{_ as r,r as s,o as i,c as h,a as e,b as o,w as d,d as t}from"./app-DW3AHQOa.js";const l={},c=e("h1",{id:"faq",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#faq","aria-hidden":"true"},"#"),t(" FAQ")],-1),u=e("h2",{id:"what-is-what",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#what-is-what","aria-hidden":"true"},"#"),t(" What is what")],-1),f={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},m={href:"https://www.home-assistant.io/docs/glossary/#integration",target:"_blank",rel:"noopener noreferrer"},_={href:"https://hacs.xyz/",target:"_blank",rel:"noopener noreferrer"},p={href:"https://github.com/zachowj/hass-node-red?tab=readme-ov-file#manual",target:"_blank",rel:"noopener noreferrer"},w={href:"https://github.com/hassio-addons/addon-node-red",target:"_blank",rel:"noopener noreferrer"},b={href:"https://www.home-assistant.io/docs/glossary/#add-on",target:"_blank",rel:"noopener noreferrer"},g={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket",target:"_blank",rel:"noopener noreferrer"},y={href:"https://nodered.org",target:"_blank",rel:"noopener noreferrer"},v={href:"https://www.home-assistant.io",target:"_blank",rel:"noopener noreferrer"},k=e("h2",{id:"entities-not-showing-in-the-autocomplete-dropdown",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#entities-not-showing-in-the-autocomplete-dropdown","aria-hidden":"true"},"#"),t(" Entities not showing in the autocomplete dropdown")],-1),A=e("ol",null,[e("li",null,"Make sure you have at least deployed once after adding a server config."),e("li",null,"There sometimes is a caching issue. Caching can be disabled for autocomplete results in the server config node and restarting Node-RED.")],-1),x=e("h2",{id:"entity-could-not-be-found-in-cache-for-entity-id",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#entity-could-not-be-found-in-cache-for-entity-id","aria-hidden":"true"},"#"),t(" Entity could not be found in cache for entity_id: ???")],-1),H=e("p",null,"If your flow runs before Node-RED has had a chance to connect to Home Assistant and retrieve the latest state information. The cache will be empty and this error is thrown.",-1),E={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket/issues/76#issuecomment-453877333",target:"_blank",rel:"noopener noreferrer"},I=e("h2",{id:"why-do-some-of-my-nodes-have-a-yellow-font",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#why-do-some-of-my-nodes-have-a-yellow-font","aria-hidden":"true"},"#"),t(" Why do some of my nodes have a yellow font?")],-1),N=e("p",null,"Starting with version 0.12.0 individual nodes on the workspace will now have a version number associated with them. This will allow changes to be made to the structure of nodes without affecting all nodes of that type until you edit them. Legacy nodes will have a yellow font until the node has been upgraded to the current version.",-1),R=e("p",null,"Just because the text is yellow on a node doesn’t mean you need to update it. It will continue to function just as it has and the next time you modify the node it will be upgraded then.",-1);function D(T,C){const a=s("RouterLink"),n=s("ExternalLinkIcon");return i(),h("div",null,[c,u,e("p",null,[o(a,{to:"/"},{default:d(()=>[t("node-red-contrib-home-assistant-websocket")]),_:1}),t(" is a package that contains a set of nodes in Node-RED that interface with Home Assistant. It uses the Home Assistant WebSocket API to communicate with Home Assistant.")]),e("p",null,[e("a",f,[t("hass-node-red"),o(n)]),t(" is a Home Assistant custom "),e("a",m,[t("integration"),o(n)]),t(". It extends the Home Assistant WebSocket API to allow Node-RED to do more with Home Assistant, such as creating sensors, buttons, and switches in Home Assistant from Node-RED. Typically, it is installed via "),e("a",_,[t("HACS"),o(n)]),t(" but can be installed "),e("a",p,[t("manually"),o(n)]),t(".")]),e("p",null,[e("a",w,[t("Node-RED Home Assistant Community Add-on"),o(n)]),t(" is a Home Assistant "),e("a",b,[t("Add-on"),o(n)]),t(" that runs Node-RED with the "),e("a",g,[t("Home Assistant nodes"),o(n)]),t(" pre-installed.")]),e("p",null,[e("a",y,[t("Node-RED"),o(n)]),t(" is a flow-based development tool for visual programming developed originally by IBM for wiring together hardware devices, APIs, and online services as part of the Internet of Things.")]),e("p",null,[e("a",v,[t("Home Assistant"),o(n)]),t(" is an open source home automation that puts local control and privacy first.")]),k,A,x,H,e("p",null,[t("Home Assistant Add-on users have a 5-second delay between connection attempts because of how the supervisor proxy works and the high CPU usage it can cause, "),e("a",E,[t("Issue #76"),o(n)]),t(". The delay can be turned off in the server config.")]),I,N,R])}const z=r(l,[["render",D],["__file","FAQ.html.vue"]]);export{z as default}; diff --git a/assets/FAQ.html-DJ7cnGer.js b/assets/FAQ.html-DJ7cnGer.js new file mode 100644 index 0000000000..6eb8d0cc44 --- /dev/null +++ b/assets/FAQ.html-DJ7cnGer.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-39a2059c","path":"/FAQ.html","title":"FAQ","lang":"en-US","frontmatter":{"sidebar":"auto"},"headers":[{"level":2,"title":"What is what","slug":"what-is-what","link":"#what-is-what","children":[]},{"level":2,"title":"Entities not showing in the autocomplete dropdown","slug":"entities-not-showing-in-the-autocomplete-dropdown","link":"#entities-not-showing-in-the-autocomplete-dropdown","children":[]},{"level":2,"title":"Entity could not be found in cache for entity_id: ???","slug":"entity-could-not-be-found-in-cache-for-entity-id","link":"#entity-could-not-be-found-in-cache-for-entity-id","children":[]},{"level":2,"title":"Why do some of my nodes have a yellow font?","slug":"why-do-some-of-my-nodes-have-a-yellow-font","link":"#why-do-some-of-my-nodes-have-a-yellow-font","children":[]}],"git":{"updatedTime":1712970749000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"FAQ.md"}');export{e as data}; diff --git a/assets/InfoPanelOnly-hbUXTFuy.js b/assets/InfoPanelOnly-hbUXTFuy.js new file mode 100644 index 0000000000..2f47f5d824 --- /dev/null +++ b/assets/InfoPanelOnly-hbUXTFuy.js @@ -0,0 +1 @@ +import{_ as n}from"./app-DW3AHQOa.js";const e={};function _(r,c){return null}const o=n(e,[["render",_],["__file","InfoPanelOnly.vue"]]);export{o as default}; diff --git a/assets/Scrubber-DmfvHnqw.js b/assets/Scrubber-DmfvHnqw.js new file mode 100644 index 0000000000..40db37d170 --- /dev/null +++ b/assets/Scrubber-DmfvHnqw.js @@ -0,0 +1 @@ +import{_ as b,o as n,c as l,a,h as d,v as y,d as c,i as h,f as u,b as f,w as v,T as m}from"./app-DW3AHQOa.js";const w=["ha-api","api-call-service","api-current-state","ha-device","ha-entity","server-events","server-state-changed","ha-fire-event","ha-get-entities","api-get-history","poll-state","api-render-template","ha-select","ha-sentence","trigger-state","ha-tag","ha-time","ha-wait-until","ha-webhook","ha-zone","server","ha-device-config","ha-entity-config","ha-binary-sensor","ha-button","ha-number","ha-sensor","ha-switch","ha-text","ha-time-entity","ha-update-config"],x={data:function(){return{after:"",before:"",replaceServerId:"",serverId:"",showCopied:!1,showError:!1}},methods:{scrub:function(t){let e;try{e=JSON.parse(this.before)}catch{this.showError=!0,setTimeout(()=>{this.showError=!1},1500);return}this.showError=!1;let o=e.length;for(;o--;){const s=e[o].type;if(s==="server"){e.splice(o,1);continue}w.includes(s)&&(e[o].server=this.replaceServerId?this.serverId:""),["lat","lon","latitude","longitude"].forEach(p=>{e[o][p]&&(e[o][p]="")})}this.after=JSON.stringify(e)},copy:function(){this.$refs.copyme.select(),document.execCommand("copy"),this.showCopied=!0,setTimeout(()=>{this.showCopied=!1},1500)}},mounted(){localStorage.serverId&&(this.serverId=localStorage.serverId)},watch:{serverId(t){localStorage.serverId=t}}},I={key:0},g={key:0,class:"popup error"},S={key:0,class:"popup copied"};function C(t,e,o,s,p,i){return n(),l("div",null,[a("p",null,[a("label",null,[d(a("input",{type:"checkbox","onUpdate:modelValue":e[0]||(e[0]=r=>t.replaceServerId=r)},null,512),[[y,t.replaceServerId]]),c(" Replace Home Assistant server id ")]),t.replaceServerId?(n(),l("span",I,[c(" with "),d(a("input",{type:"text","onUpdate:modelValue":e[1]||(e[1]=r=>t.serverId=r),placeholder:"xxxxxxxx.xxxxx"},null,512),[[h,t.serverId]])])):u("v-if",!0)]),d(a("textarea",{"onUpdate:modelValue":e[2]||(e[2]=r=>t.before=r),placeholder:"paste exported Node-RED flow here"},null,512),[[h,t.before]]),a("button",{onClick:e[3]||(e[3]=(...r)=>i.scrub&&i.scrub(...r))},"Scrub"),f(m,{name:"fade"},{default:v(()=>[t.showError?(n(),l("span",g,"Invalid JSON")):u("v-if",!0)]),_:1}),d(a("textarea",{"onUpdate:modelValue":e[4]||(e[4]=r=>t.after=r),ref:"copyme"},null,512),[[h,t.after]]),a("button",{onClick:e[5]||(e[5]=(...r)=>i.copy&&i.copy(...r))},"Copy to Clipboard"),f(m,{name:"fade"},{default:v(()=>[t.showCopied?(n(),l("span",S,"Copied")):u("v-if",!0)]),_:1})])}const N=b(x,[["render",C],["__scopeId","data-v-0157be62"],["__file","Scrubber.vue"]]);export{N as default}; diff --git a/assets/action.html-CDqqIuhb.js b/assets/action.html-CDqqIuhb.js new file mode 100644 index 0000000000..8674a31249 --- /dev/null +++ b/assets/action.html-CDqqIuhb.js @@ -0,0 +1,12 @@ +import{_ as c,r as u,o as r,c as l,a as s,d as n,b as a,w as e,e as o}from"./app-DW3AHQOa.js";const i="/node-red-contrib-home-assistant-websocket/assets/call-service_06-Cdv6oWF6.png",k="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAA0CAYAAADrGG1QAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA5+SURBVHhe7Z3vcxXVHcb7P+UVM06dYdQXvigvOlMd3vhGplNGkFLrqFXagFbAYpDQ1BAgifJLKpaCithWByrT4jApTM0oFW2sFqswIgkEIQnf7nN2z+73nD177yb37r25yfPMPJO7e37v3f1+7tk99+Z7QlEURVEdKAKMoiiK6kgRYBRFUVRHigCjKIqiOlIEGEVRFNWRIsAoiqKojhQBRlEURXWkCDCKoiiqI0WAURRFUR0pAoyiKIrqSBFgFEVRVEeKAKMoiqI6UnMC2NjYmIyMjMiZM2douunGuYVzbL6K5z9NN8+NXO+lATY+Pi6jo6PSv2NQtvYelO5N78q6Z09W7meeP0MvMm/celpeHDgqwy8dmFcgQ19279kvPXsOyyN7T8rDe9+j6QXtn+x6u3Kv3vWWbNy5X/p27jaMAWvKqjTAUPG23j55bMOoPPTkeEv840cvmr9rNwi9CL1u85jsGNg9LyCGPvRHF9gDB0flnj9eoekF76UHPpc7Bz80f1vh5cPvywvb+wxryqo0wDDzaiW8YAKMBsQwE2u3MPMivOjFZECllQCDATHMxMqqFMDw6RO3DX3AVG0CjIZxO7GdszC0jduGoYucpheqAZRWAwzG7cSy13spgOEhG555+YCp2gQYDeOZGM7Bdglt45lX6CKn6YVqwKQdAMMzsbLXeymAYaUIFlT4gKnaBBgNY2EHzsF2CW3jgXboIqfphWrApB0Aw8KOstd7JQD72foJ+XXvNdk+NCkD+2JvH5yUZ6J9a6O0UJmQCTAaJsBouvUGTBoB2A8O/VeG/nlVPr5yK7mSxLzGPqSFysBtBdiW/uvyp5M35eN/T8n4xG2Znhbjb8dnon3T8vaJm/KbF68Hy/omwGiYAKPp1hswmSvAnvrrZZm4NSNnv/5OfjtyRX76ztfGeI19SEOeUNm2AGzVU+Oy68CkfPHljEzeuC0ffTItR//8nQz//oa89OoNeT16/dGFKbk+eVs+vzhtZmUoE6rLmgCjYQKMpltvwGSuADt0fkI2nf7GzLS2R9B674tJY7zGPqQhT6hsUwB26dIlOXv2rKnoyJEj8tzWQ7J+8ynp3nRafr7+sxxsAK+vL8/IN9/OyMuHbsgvNk3I2u4YbDBeY9+e127Ilau35atLMcT8erQJsMXrx5+9JE9vOWvg1dN7xJyDOBdxTuLcrFr++f/04GsGYqv2/U1+9OqnwQuepheSAZNGbyH+79q0MWAF4/WX16ZytxB/uHdUVg6fkFVD70j3wCulr/cgwFBoaGhIjh07JsePH3f8+utvysDAoAGZBQ1uG35+MYbX09uupfvhXz1/TR59xn3uhWdhgBhmYrVuJ3YywB5asVq67j8XTJurH7y/q+l1zkcDXAMDQ9G5lj//cE7i3MQ5WpVqnf9H33hT+ncNGpCFLvrW+BO5876VcufLobT567u6V0rXffvkrkBaZowtOs+7Ipu8/naoTAPu3Shdq06F0zwvXdUld/SG0+55eZ8s6Zrje+L04ZTc0bVRlvp5QkabtY5JvfQ6BlgaXcSB24b19gFcuKaORNeWf73Vu95zAAPtUODcuXNy/vz5oJEGiGEmhgUbeOaFW4OYefkQuvjVjBw8mt+PmRjK4JlY0cIOAsz1YgAYZl6AV73zD+doFTOxsuc/Lri2zcQQ8KoI5pUagblEgDcgUAHc326qYzgWQmk2xnsyx34C7Eu6Pwmm1XQd+AK4c6o3MeDSKMDqGTMvXEtzvd5zAAPpQL1QRdqYiWEWhtWGWLCBZ164RehDqAhgT26eiMpMmYUdmJH56XBZgBlY4BOa8WpZ/oRNOyfLon3L1nh57z0sD2H7icNyd1ePLNflbZoqn6b58FjTk6VFtu04/XHqm6VN/2z9PbLMA5gBWpqepTljTOvRxyUui/7i790rDjvj1Mer1cbsCzOv0DmnjXO0illY2fMfM7F2zMLMLMa+VwnEcjMDPRtIPoUvTcqZgGY/mZugm9RVcxaiZkGBvHH7Ok8eVMiTltPtqrzO2KL933/M3Q7Dr1bf8rOZbBaItKycPX6mn+l+D6TqQ4PT16hNU06lF40xZP3+uTDzj6kLXJs367Ntxz0mtj7/+NbqEwzANAtgVv5+zL4w8wpdY9pF13sOYLjviKlbqBJt5MEzMSyPxwpDLNjAcy4fQkUAQ943/vKdfHt1xtThp8OlAGYg0iMPBrfLACx6M1MoxPnvXnE5en1Zlt9rXyPN2/bb9SBh2mlktpT0Le27hWVSp4GXhlSSbvKbslnfLFCz44BxxukxBL1+63G12HjmVfb8s/fJm2nUWbb99izscINYvO0FIwRPG0yj10uidOeTuA2uNthr4Nk8qeNA7wfVfJDNyjuwgk39MQziIKrAYPqSbetgHtp2XadvHnRg1Jem6+MU2fRNbZtxqONox+SPweRTx7PeGF2771823uS46vcI76MDqWhbnQumH857WtyHXB8DBmCqBhieeZW93nB9+moYYFiIgWXyWG0YWlVYBDDkxepElC1azDEngDkuA7D8zCSGhA8w7ThN1wtraDUKMKefibO+uXlj67G6/UO5ZfdHx8mWxTFLXufqDByTVno2AOvv76/EZdtvD8D8W3EFswwdTL0grtONawCssHy6z++PF0iT7RgaMXBcIOl9bjDPb7uu2zcFndgxFGz7/nEw21FfMiBmRlrhGMzxs/vqjdGzA1k13gD0YlDaffk6neOO8vrYmPrc96WeAZhFAzDAKAQw3Fr88MKU9Axcl0c2TKR5mgawJFibNyeyC5VGABZt21kP7MAkrjdN007KNgqwEKxCdZp9qn0NrRi+yWwLY03GYICm8jl1EmCl228LwPzAVhCkbRBGUHMDpxvEjQPBUufNBXQdHPVrY6+MrjvYju4PgrJO97e16/ctN3YH1OHyMSTgApCGxqDrNenZ9ajtvg+Jkd++fwpmDowSO3B2wAe74yksX6svngGYBQ8wewsR3/MK3ULEqsS/j9yST/8zJcdP3JRNfdfl4V9GUFo/kd5C7B0Mr0Sc7SIOE4zNG2QDcIMAszb5krpNWr5e3zUBputL63TzhPqh68zAZWefXp8AX4wzBRdAj7HibzZj7WSALcZbiE4QS7bdIKw/mavA66S7Adiv082bD3Y6f/32s6Aabkfl94NyLkhr1+tbYOwOfMLlY8f9ziCGvHG54BgMwGqk17Bz/FKYucfNWkPJKWdcfNx9W0iHx54ZgCkCGL6ErH9hY7bCUnrU0XSAzXYRBxZgmEUc0SwrtIgDxsxr8JVJ+ccHU3LqzC15/NkJs4jjX59Ox4s4vKX31rMFWOx4RpbNPpoAMOv0dqVuI5Avck2AlbDTz8RZ3+L2XYD6Y8V2vEDF9hPll62Ixqz6Nd8AxkUctY3gowMTtp1AlAvSLqxCUAh9Wo8dCvLxPtuHXPsmmKvZiGorFNzNPttHPRsJbTuu17f82J1xKuhg2/TDaUvVr45Z4RhqpNeyPn4oG/c9BCB3vDWPu8mr4O29D/UAZw1QFQEM3+dqVABg0xdxzGUZ/dsnb5pf38DSeB9C1qvXxd8J27Ljupmp7ftDvIwes7KGltH7z8CcABwH+ixAx0G+HMDykHKCvWlXl3XzNwqw4IwKfQ/2LRmnzh/YZ2dtGnzzDWBcRl/LfuCJt9NAZuAVvZ82WAVglYeCV4dnE/RVHe42ygZmOSbdDbjGJsiqfd62H5RzQdpzzb6ZujNAmbSorfTYmWOlAGe21Vg0EPQx88dgykV1F6Unx9c95tYuZPV4DQhz/bf9yx93B5y67+m27lPgvQkYoCoCWLPU9GX0EEiHAqAepm7aoS8y48vI+CIzvpxctCTeGs++sPQetw4/+2JKnvtd419kNkEYJ1FiHaDjgGzTItDZW2tpWhHA/LKRvRmRBYK1MyNLyyq4zta6/ajt5TX6tmxNAiwFo7h/RXCPPd8ABvOLzMUOB+LkPIiCpAlkNlhGaf6n7OxTvt3nfVoP2LZprIDhB2DYtm/KOHkTJ8HU1ucGet2PABwDLu6bm2aX+aftpf3I+h9Dw5bJ2kY9Otg7+VbtM/U6x1S/J5H99yA1+pD2OX8snf53o782vSBvCskYUA6QvT7VgxcMUJUBmN43/MFV8xp/oVB+LaQ19YvMVqAdCtnnAvV+Smrn/vinpAAxzMRwixAzLQALxiwL+zDzAry+ujTDn5KiC82fkqLpzAaaoQ8EFRpwaQXA4Kb+lJQvVFTmx3wBMczE4h/znTKLNLDSEMZrPPPCbUPMvHbs5Y/50uUMiOEcbJfQdnuWzNOL0v4twGRGVWbW1EwDLFXfQgzV3dZ/p4LbiXgmhsUZmGlhmfxUZLzGPjzzqnXbUJsAo2ECjF5sdm9n1rgNWaEBkyoXcVy4citY97z4h5Z4FoYl9rhNCGOpPFYb8h9a0rM1AUbTrTdgUgQwLIEHgOYqAHBe/T+wKkyA0TABRtOtN2BSBLAq3XSAjYyMSPemd3OAqdoEGA1v3HranIPtEtp+ZO/J4EVO0wvVgEk7ALZ611ulr/dSABsbG5OtvQdzgKnaBBgNvzhw1JyD7RLa7tlzOHiR0/RCNWDSDoBt3Lm/9PVeCmBQ/45BeWzDaA4yVZoAo9dtHpPhlw4kZ2H7tHvPfnng4GjwQqfphWjApNUAWz78vvTt3J1cdfVVGmCjo6OyrbevpRAjwBa3Aa8dA7vbOvuyQh/6owuLEKMXiwGUVgIM8Hphe59hTVmVBtj4+LipGDMx3E7EMzEs7KjaeIBPLy7jmRduG2LmNR/gZYW+YCaG24l4JoaFHTS9kI0FFVUbz7xw2xAzLzAGrCmr0gDTwoWMh2xYKULTzTbOrfkELl88/2m6eW7kep8TwCiKoiiq3SLAKIqiqI4UAUZRFEV1pAgwiqIoqiNFgFEURVEdKQKMoiiK6kgRYBRFUVRHigCjKIqiOlAi/wesWvgb+TZM6gAAAABJRU5ErkJggg==",q="/node-red-contrib-home-assistant-websocket/assets/call-service_03-BfEbDwOv.png",d="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbUAAAArCAYAAAD/sRZaAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA2aSURBVHhe7Z39ixXXGcf7Py2+BFIEG/yxJSkohEB+sIIRtBTsj6UsKcFCrbG7Lq5790XclyRqjdrGWEs0MbEodqOYxa6NcUujtipdXLWNNuX0fs+ZM/OcM8+Zmfsyd+69Pl/4snfmvMyZOXOfz5yZc2e/o0QikUgk6hMJ1EQikUjUNxKoiUQikahvJFATiUQiUd9IoCYSiUSivpFATSQSiUR9o8JQW1paUvPz8+ry5ctisbjPje86vvO9Lolbve1mzsNMqK2srKiFhQU1Mjah3to/rbYOH1c/+s2J0v3GgT+KxeIKvaN2Ru2eOqomDs32JNzQ5onpObVn+n21c+YT9eOZT8Vt9hvjfyjdO8Y/VLtqc2qkNqFZBCblKRNqqGTv0D71ytA5tXr4i4544FcX9d8XarfEYnHF3jh2SY2OjfcU2NDW0XoQfP29BbXh+LK4BK9/5+9q3eR1/bcTfvXgJbV3eEQzKU+ZUMMIrZNAgwVqYnF3GWDDiK1XhBGaAK1cAzSdhBoMsGHElqcg1HC1g1uOPnTKtkBNLK7e62t/UT8fP672H6ip0dFRx7VaTZ05c0Y9efIkihbdI8Qt3HLkArG4fQZkOg01GLci8+4aBKGGB3R4huZDp2wL1MTi6r1nfE6dPn1a3+5ZXFx0jHVIO3z4cBQtukeIW3iGxgVicfsMwFQBNTxjQx9nKQg1zDzBpA0fOnneeuyWurPyTBufuTxZFqiJxdX6tbEL6tC7R1Mw833s2DF148aNKGJ0hxC3MImBC8Ti9hmAqQJqmDyCPs5S26D22jtfqstfP45KJ8I6pHFlOAvUxOJqjdmPGIlxIKNGnrwA02kJ1DpjAKYVqH3/6G01de2h+uvys6jnlP6MdUjjysAdgdr3xq6rk9eXo1JKPXr6rfr1+bva+GyFPMjL1UEtUBOLq3UjUMMzttnZWXXy5MnYFnbwrVu31IMHD6IoUL4Eap0xANMs1H52/oF69Ox/6sq9b9S++WX1k4/uaeMz1iENebiypUINgDpw8Z9q5ZsEXGOX7jngwue5K8kJjbwokwU3gZpYXK0bhVpRA3jXrl0r9FujZiVQ64wBmGahdnTxkfrlxX/pEdlwHWSffv1vbXzGOqQhD1e2NKj99IO/6WdmVh9/taJ+cHCRzQsjDXmsUBZ1cHkFamJxi367plZtPs2nFXBZUKMG4G7fvh1FhNZ0//59deXKFR2zTpw4oX4x+VsNtu2zf1Ibj3zFBmVxawZgWr39+I/H32oDYDA+333839Ttxx/OLKhtBz9W26c+UoNj7+o+Rl+jz9H3vpqCmtWN+/8JTgb53fXl1DrkRRkrPx1uHWqfqzUvD6jVb3JpnE+r1QNb1Jq3ubT2eu3mATXQQrDppNfu3KIGXq6ptUxabxrnRWf6OWjApuRzTZ9jA4mLfw8SN/pMDbcXAShrpGG9hczMzAwLNvjs2bMtjdwQ2KamptSpU6d0e6hP/v4DNTo+qeHGBeZ+80uD29TApln1EpO24fhNtW7TNrXuULR8aFa9EMybb8Cm1YkiuOWYtw4wQx+eqPel37/oc/Q9zgGqlqDGpVlDeI4WSoO4NIFad7j/oGb2adXOz9m0jrhkqOnzC31mR2pNbq+M2Y9Pnz7VZRCMQnBr9NkbrtIR1K5evZpqmzXSEBSfhxHb+u31/t/+GZu2YWiXAzzkfWHwZjpfQQM4rUItzxihoe/y+hfnAB2xlQo1iAOblb8eLgo1HXTjK1L7xTVAs+vjAKa/3Mn6JD+AlqyPQfjmIMnb+NWue7U8GIPBQG2Q3yYcbKdNG1Rr6H570KHbXbWzprdD6+ePmTU9FlvU6s0UaiYt6ziE9tnYPc4U7LpNm2t8v8HeMfGh5O4T3S62SY6XDfbNgDo69g2Xq9vpk3rfu5Bxz9f0BY973FLHpb4va2z9m48kF3NIa/HiqczfqWFkBohxcMOkkwsXLujt3LlzJyrBC1fouFr32+cbI7aqRmt69BT3IRkpwRgtxWkD6sUhLw0QAoxsHgdYGHnRsp+pF+t/OVA5bdg0pr5Lytn8me1kDOi0C2pW/nqM0jBC4/qUGucAHa21DWpZ8sFmRddZF4Kahg4JMs6yN1KLgmISkKNA4gRsEmj8unV5HwBh6yBLAiddNgEuqcsE5Ghbee2M0pPAZwKeDXROXViOgp2tz2+Xu59uXfG2aP4MZ+2zrdvfL7fdJF23yx4jv6y7nNpnZ9nkdUGBdUn+wtbHo/Fyug/i42ABZvctWo7b5y+b9icg85ajPkrSo+2hPNKc/W7cnXijCOCG25N+/Zy5GZYoi79coKNGnkomj2gg7VLro2UDjmhZp3m3A+myhZkFmZMeAS2GnAEa8jtgjG3yx2m6rqRdme0MGNApG2p4hla0f8Erq45ADaJgs6LlrZuCmmMTHJJAmHY66LqBxi+r8xcKEibwhLYdBx27TgemMDCddjJ5k/qYdkdBz6yj+5gY5XVQZI6ne4yynZWXPXa6bWZ76bL0GGYdTy7NHAcT6Pmy2Ge+vgyT9rLprJnt0z7kzmGSzh5TWobWFecx2zRX203sZ4bxnI0GjnYKz+EwcpucnGSBluXuh1q9L1K3BA1k3FGVu06DhZajUPMgFOcPggjQ84BJn6cF2xk2oPPcQ41OHLGi5a2L3X6MrmrZL28Iau4XPgkYWG+Dg5eHugjU2ECTuBjUAu1k8ib10X2wNvXo46DLkjqJAYBgAPXXBU3bzLSRbC9xEahF6bZM7rEz28uCmt6vIn3p7JPnIscl2LdmHXvMabp/rsC6ziyoRXb6u1EY8y4TalQAHLaDQHXkyBEWZNRdDbW66W09d6Rk+8e1gZo3soIJyLhnZ3o7oYkfHgSD5aM28KM914DOcw01fyakFV1n3ehEkSRo2i+4D7UkONlbNW5ASQKJzZsGYkFnBZq6U4HKyZ/TTqbupD66D9ZkX/LaxQXYhqBmTS82ImhxwZk4ve1AH+hRCjk+gX3C9jKhptc3GOj1tpopw/WJWVc61HRZOnJl8mW4215ojFuVdIYlftTd9bcfiTVI6uejBgYz0nKNkRUzEtPQ4kZ5UXpgpOUCjy9v7bSTSbcGdEJQww+n6ZtCGhWm9aOOyqHm24qb2m/lr4cbhZox/fJ6UGOCcxhqzQcB41AgNc6EWl47mSCW1Oftc5zfrstulwGGG7T5oFvUyfby6kmn5xzDOD+Xj/ZfqB7kCcAgZH0sG4Qat32/v/06STp73GgZ5nyIjbToPEsgz+TLcC+80LirJ4r4t/goTPKghpGcN+pKRlcclPJBlaTl3IrMqcsa8ApBDb83a1WAYuUTRXxDHNBsGsSlNfVMzfmCM1CjefVy/QSJAwaCDwkOOp0Gi8ZAlwpGZPu5UMtqJxPEaH16u6S8TiNB1U93g663j3pb9BhlO2uf7Xbo8aP5U2WddvlgcNuZ2mdn2S+bGPkaCvT6eNBjV8zuvpm2t3eiCD0fSDrSUA9zzhRxr7zQuKun9Ee3GJMRj5nMYZbNZwoODS0LF4DGGXUZ0Ni6zK1C73aisy1qD1L02Vy8HGpn2IBXCGrtUiVT+heb+PE1ylj56XDRkZoN2tY0eJngVl9vAz7NiyDjgcumu8EyKdNQAKzbbZu3nTho1e0Fncx2MgHKr4+WN1P6mfy2/rrdgG+CokmLpsLHATkMCGMbsK3d7Zq2k3QCMTfww962LNyt6fGr2+2rELQ9oz3x8SVl/OU2mB7z1fU+cfvQO27evrl94p2HHLD841x3uM/CbvTH11UKV+gIarhaR3uoK//xtR6RJX3hgMJ/rkYgBmi5IyVvdBWBKq530AOVZws9U6eBljPzMqudAQNeRaBG1x384qH+jL8Ql58KaR378TVecXWXvCbr3M2Hua/JQh4rlJXXZJVtBEQv6ImfDwNuKUAWdy9BDcJVOgIb2oLnbPKarPIN4HQCanBHXpMF46XEeIExfRM/Xl6c9UJj5PVfeuxboNaMzRU/vZJPj4DE4mLuNahRoT1VTwp5HgzYlH37kau7Y/96BrcarfAm/t3n72rTN/gjTxbMrLsXav4ttrSbudXTNmfc4hO33/6tXN+N3rLuJgvUxHkGYMqcKPLl8jO27o7/k9A/307/k1Csk38SKhb3jgVq4jwDMCGoYTo+oNSsAMVK/p9ayJgMgmdmcGgSSZYFamJxte6V2Y+cBGqdMQATglqZbglq8/Pzauvw8RR0yrZATSyu3r3wOzVOiFs7Zz5hA7G4fQZgqoDajvEPdR9nKQi1paUl9db+6RR0yrZATSyu3t32RpGiQtzaM/0+G4jF7TMAUwXUdtXmdB9nKQg1aGRsQr0ydC4FnjItUBOLu8sbxy6piUOzUVTofk1Mz6nX31tgg7G4PQZgOg21Vw9eUiO1iaiXw8qEGm4z7B3a11GwCdTE4u4xgDY6Np57ddxNQltH68FPwFaeAZlOQg1A2zs8opmUp0yo4SWiqAQjNtyKxDM2TB4p25h9JRaLq/OO2hm1e+qoHqH1EtCs0GaM2HArEs/YMHlE3F5j0kbZxjM03HLECA0sApPylAk1KpwkeECHmSdisbi/je96L8LMl8St3nYz52FhqIlEIpFI1O0SqIlEIpGobyRQE4lEIlHfSKAmEolEor6RQE0kEolEfSKl/g9Jcadr5XeaDAAAAABJRU5ErkJggg==",g="/node-red-contrib-home-assistant-websocket/assets/call-service_05-DBq2t9ez.png",y="/node-red-contrib-home-assistant-websocket/assets/call-service_02-CqOu7WiP.png",h="/node-red-contrib-home-assistant-websocket/assets/call-service_07-CDDnq17z.png",m="/node-red-contrib-home-assistant-websocket/assets/call-service_08-HfAzx-i_.png",f={},b=o('

Action Tips and Tricks

Homeassistant Domain

The homeassisant domain can be used with different domains of entities with certain services.

Here's an example of using the homeassistant domain to turn off some lights, switches, and everything that can be turned off in the laundry room in a single service call. This can save you from having to have multiple action nodes.

screenshot of a action node using homeassistant domain

Using Mustache Templates

Mustache templates can be used in the domain, service, and entity id fields. This is useful if you want to set the service based on msg.payload or any other message property.

',7),A={href:"https://flows.nodered.org/node/node-red-contrib-eztimer",target:"_blank",rel:"noopener noreferrer"},v=s("code",null,"on",-1),j=s("code",null,"off",-1),x=o('

screenshot of flow

screenshot of the action node

[{"id":"522c54b8de855062","type":"api-call-service","z":"a38123c1.2fd3f","name":"","server":"","version":4,"debugenabled":false,"domain":"homeassistant","service":"turn_{{payload}}","target":{"areaId":["75a88dfa58844f8aad752dde5bc51fc7"],"deviceId":[],"entityId":["light.front_porch","light.garage","light.kitchen"]},"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":526,"y":672,"wires":[[]]},{"id":"cca91c6fe47d7fa0","type":"eztimer","z":"a38123c1.2fd3f","name":"","debug":false,"autoname":"sunset - dawn","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"latLongSource":"manual","latLongHaZone":"","lat":"","lon":"","timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onpropertytype":"msg","onproperty":"payload","onvaluetype":"str","onvalue":"on","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"1","offtimesun":"dawn","offtimetod":"dusk","offduration":"00:01:00","offpropertytype":"msg","offproperty":"payload","offvaluetype":"str","offvalue":"off","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"resend":false,"resendInterval":"0s","mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":272,"y":672,"wires":[["522c54b8de855062"]]}]
+

Mustache templates are also accepted in the data field when their type is set to JSON.

Also see:

`,5),z=o('

Targets

The target fields allow you to target areas, devices, and/or entities. Any combination can be used when they are available, some services don't accept areas and devices.

Mustache templates and environment variables can be used inside each target list.

Data Field

TIP

It's recommended to use the JSONata expression, J: Expression, for the data field as it has several advantages over JSON.

Inserting a message property into a string

Sending a TTS message when a door is opened

screenshot of flow

screenshot of the action node

{ "message": "The " & data.attributes.friendly_name & " has been opened." }
+
[{"id":"cd1f9610a73addbc","type":"server-state-changed","z":"a38123c1.2fd3f","name":"","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor\\\\..+_door$","entityidfiltertype":"regex","outputinitially":false,"state_type":"str","haltifstate":"open","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":338,"y":560,"wires":[["4e016826f6497b79"],[]]},{"id":"4e016826f6497b79","type":"api-call-service","z":"a38123c1.2fd3f","name":"send tts","server":"","version":4,"debugenabled":false,"domain":"tts","service":"google_translate_say","target":{"areaId":[],"deviceId":[],"entityId":["all"]},"data":"{\\"message\\": \\"The \\" & data.attributes.friendly_name & \\" has been opened.\\"}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","output_location":"","output_location_type":"none","x":570,"y":560,"wires":[[]]}]
+

Getting a property value of a Home Assistant entity

There's a custom function in JSONata inside Home Assistant nodes that allows the fetching of any property of an HA entity.

Example of getting the friendly name of an entity

{ "message": "The " & $entities("binary_sensor.front_door").attributes.friendly_name & " has been opened." }
+

Example of getting friendly names of all the lights and switches with an on state

{
+     "message": "The " & $join($entities().*[state = "on" and entity_id ~> /^light|^switch/].attributes.friendly_name, ", ") & " are on.",
+     "title": "Left On"
+}
+

Doing arithmetic

`,19),w={href:"https://docs.jsonata.org/numeric-functions#number",target:"_blank",rel:"noopener noreferrer"},G=s("code",null,"$number()",-1),T=o('

$number($entities("sensor.kitchen_lux").state)

Adding 3 to the current temperature of a climate entity

screenshot of action node

{ "temperature": $entities("climate.thermostat").attributes.temperature + 3 }
+

Create a comma-delimited entity id list

Example of getting a list of lights from the get-entities node and then creating an entity id list to turn them off. The entity id field is left blank in this example as it is defined in the data field.

screenshot of flow

screenshot of action node

{ "entity_id": $join(payload.entity_id, ",") }
+
[{"id":"80c20ba2.f09cd8","type":"ha-get-entities","z":"f731b121.0463a","server":"","name":"get lights that are on","rules":[{"property":"entity_id","logic":"starts_with","value":"light.","valueType":"str"},{"property":"state","logic":"is","value":"on","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":468,"y":528,"wires":[["cafbf446.080928"]]},{"id":"cafbf446.080928","type":"api-call-service","z":"f731b121.0463a","name":"turn them off","server":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"","data":"{\\"entity_id\\": $join(payload.entity_id,\\",\\")}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":662,"y":528,"wires":[[]]},{"id":"39666758.cee048","type":"inject","z":"f731b121.0463a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":284,"y":528,"wires":[["80c20ba2.f09cd8"]]}]
+

Also see:

`,11),M={href:"https://docs.jsonata.org",target:"_blank",rel:"noopener noreferrer"},B={href:"http://try.jsonata.org",target:"_blank",rel:"noopener noreferrer"};function N(D,U){const t=u("ExternalLinkIcon"),p=u("RouterLink");return r(),l("div",null,[b,s("p",null,[n("Here's an example using "),s("a",A,[n("eztimer"),a(t)]),n(" to set the output of the node to "),v,n(" or "),j,n(". Then use that in the action node for which service to use.")]),x,s("ul",null,[s("li",null,[a(p,{to:"/guide/mustache-templates.html"},{default:e(()=>[n("Mustache Templates")]),_:1})])]),z,s("p",null,[n("Home Assistant states are represented as strings so to be able to do arithmetic on them in JSONata they will need to be cast to a number first use "),s("a",w,[G,a(t)]),n(". Most attributes of entities are in their correct state but it never hurts to be safe and cast them as a number.")]),T,s("ul",null,[s("li",null,[a(p,{to:"/node/action.html"},{default:e(()=>[n("Action node")]),_:1})]),s("li",null,[a(p,{to:"/guide/jsonata.html"},{default:e(()=>[n("JSONata Guide")]),_:1})]),s("li",null,[s("a",M,[n("https://docs.jsonata.org"),a(t)])]),s("li",null,[s("a",B,[n("http://try.jsonata.org"),a(t)])])])])}const Z=c(f,[["render",N],["__file","action.html.vue"]]);export{Z as default}; diff --git a/assets/action.html-CVd1_Ell.js b/assets/action.html-CVd1_Ell.js new file mode 100644 index 0000000000..9823e079a0 --- /dev/null +++ b/assets/action.html-CVd1_Ell.js @@ -0,0 +1,14 @@ +import{_ as r,r as n,o as c,c as h,a as e,d as t,b as a,w as o,e as u}from"./app-DW3AHQOa.js";const p={},_=e("h1",{id:"action",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#action","aria-hidden":"true"},"#"),t(" Action")],-1),f=e("p",null,[t("Sends a request to Home Assistant to perform an action e.g. "),e("code",null,"light.turn_on"),t(", "),e("code",null,"input_select.select_option"),t(", etc.")],-1),g={class:"custom-container tip"},m=e("p",{class:"custom-container-title"},"Helpful Examples",-1),b={href:"/guide/action.html",target:"_blank",rel:"noopener noreferrer"},y=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),x={id:"action-1",tabindex:"-1"},q=e("a",{class:"header-anchor",href:"#action-1","aria-hidden":"true"},"#",-1),w=e("li",null,[t("Type: "),e("code",null,"string")],-1),T=e("p",null,"Action to perform",-1),A=e("h3",{id:"floor",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#floor","aria-hidden":"true"},"#"),t(" Floor")],-1),v=e("li",null,[t("Type: "),e("code",null,"an array of floor ids")],-1),N=e("p",null,"A list of floor ids that will be used as targets for the action",-1),O=e("h3",{id:"area",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#area","aria-hidden":"true"},"#"),t(" Area")],-1),S=e("li",null,[t("Type: "),e("code",null,"an array of area ids")],-1),k=e("p",null,"A list of area ids that will be used as targets for the action",-1),M=e("p",null,[t("Custom ids can be inserted into the list by adding a "),e("code",null,"#"),t(" at the end of the id")],-1),J=e("h3",{id:"device",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#device","aria-hidden":"true"},"#"),t(" Device")],-1),C=e("li",null,[t("Type: "),e("code",null,"an array of device ids")],-1),D=e("p",null,"A list of device ids that will be used as targets for the action",-1),I=e("p",null,[t("Custom ids can be inserted into the list by adding a "),e("code",null,"#"),t(" at the end of the id")],-1),j=e("h3",{id:"entity",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#entity","aria-hidden":"true"},"#"),t(" Entity")],-1),E=e("li",null,[t("Type: "),e("code",null,"an array of entity ids")],-1),B=e("p",null,"A list of entity ids that will be used as targets for the action",-1),H=e("h3",{id:"label",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#label","aria-hidden":"true"},"#"),t(" Label")],-1),L=e("li",null,[t("Type: "),e("code",null,"an array of label ids")],-1),V=e("p",null,"A list of label ids that will be used as targets for the action",-1),R=e("h3",{id:"data",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#data","aria-hidden":"true"},"#"),t(" Data")],-1),F=e("li",null,[t("Type: "),e("code",null,"JSONata | JSON")],-1),W=u(`

JSON object to pass along.

Merge Context

If defined will attempt to merge the global and flow context variable into the config

Alternative Template Tags

Will change the tags used for the mustache template to <% and %>

Queue

Will store the first, last, or all messages received while disconnected from Home Assistant and send them once connected again

Input

All properties need to be under msg.payload.

Sample input

{
+    "action": "homeassistant.turn_on",
+    "target": {
+        "floor_id": ["first_floor"],
+        "area_id": ["kitchen"],
+        "device_id": ["8932894082930482903"],
+        "entity_id": ["light.kitchen", "switch.garage_light"],
+        "label_id": ["outdoor_lights"]
+    }
+    "data": {
+        "brightness_pct": 50
+    }
+}
+

Merging

If the incoming message has a payload property with action set it will override any config values if set.

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

If the node has a property value in its config for Merge Context then the flow and global contexts will be checked for this property which should be an object that will also be merged into the data payload.

Merge Resolution

As seen above the data property has a lot going on in the way of data merging, in the end, all of these are optional and the rightmost will win if a property exists in multiple objects

Config Data, Global Data, Flow Data, Payload Data ( payload data property always wins if provided )

action

Action to call

data

Data to send with the action

target

Targets of the action

Output

Value types:

References

`,34);function G(P,Q){const l=n("ExternalLinkIcon"),d=n("Badge"),i=n("RouterLink"),s=n("info-panel-only");return c(),h("div",null,[_,f,e("div",g,[m,e("p",null,[e("a",b,[t("Action Tips and Tricks"),a(l)])])]),y,e("h3",x,[q,t(" Action "),a(d,{text:"required"})]),e("ul",null,[w,e("li",null,[t("Accepts "),a(i,{to:"/guide/mustache-templates.html"},{default:o(()=>[t("Mustache Templates")]),_:1})])]),T,A,e("ul",null,[v,e("li",null,[t("Accepts "),a(i,{to:"/guide/mustache-templates.html"},{default:o(()=>[t("Mustache Templates")]),_:1}),t(" for ids")])]),N,O,e("ul",null,[S,e("li",null,[t("Accepts "),a(i,{to:"/guide/mustache-templates.html"},{default:o(()=>[t("Mustache Templates")]),_:1}),t(" for ids")])]),k,M,J,e("ul",null,[C,e("li",null,[t("Accepts "),a(i,{to:"/guide/mustache-templates.html"},{default:o(()=>[t("Mustache Templates")]),_:1}),t(" for ids")])]),D,I,j,e("ul",null,[E,e("li",null,[t("Accepts "),a(i,{to:"/guide/mustache-templates.html"},{default:o(()=>[t("Mustache Templates")]),_:1}),t(" for ids")])]),B,H,e("ul",null,[L,e("li",null,[t("Accepts "),a(i,{to:"/guide/mustache-templates.html"},{default:o(()=>[t("Mustache Templates")]),_:1}),t(" for ids")])]),V,R,e("ul",null,[F,e("li",null,[t("Accepts "),a(i,{to:"/guide/mustache-templates.html"},{default:o(()=>[t("Mustache Templates")]),_:1}),t(" when data type is JSON")])]),W,a(s,null,{default:o(()=>[e("p",null,[a(i,{to:"/node/action.html"},{default:o(()=>[t("External Docs")]),_:1})])]),_:1})])}const K=r(p,[["render",G],["__file","action.html.vue"]]);export{K as default}; diff --git a/assets/action.html-DFolIjbw.js b/assets/action.html-DFolIjbw.js new file mode 100644 index 0000000000..680b4c9df7 --- /dev/null +++ b/assets/action.html-DFolIjbw.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-2ab02ccf","path":"/node/action.html","title":"Action","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Action","slug":"action-1","link":"#action-1","children":[]},{"level":3,"title":"Floor","slug":"floor","link":"#floor","children":[]},{"level":3,"title":"Area","slug":"area","link":"#area","children":[]},{"level":3,"title":"Device","slug":"device","link":"#device","children":[]},{"level":3,"title":"Entity","slug":"entity","link":"#entity","children":[]},{"level":3,"title":"Label","slug":"label","link":"#label","children":[]},{"level":3,"title":"Data","slug":"data","link":"#data","children":[]},{"level":3,"title":"Merge Context","slug":"merge-context","link":"#merge-context","children":[]},{"level":3,"title":"Alternative Template Tags","slug":"alternative-template-tags","link":"#alternative-template-tags","children":[]},{"level":3,"title":"Queue","slug":"queue","link":"#queue","children":[]}]},{"level":2,"title":"Input","slug":"input","link":"#input","children":[{"level":3,"title":"action","slug":"action-2","link":"#action-2","children":[]},{"level":3,"title":"data","slug":"data-1","link":"#data-1","children":[]},{"level":3,"title":"target","slug":"target","link":"#target","children":[]}]},{"level":2,"title":"Output","slug":"output","link":"#output","children":[]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1722740908000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"node/action.md"}');export{e as data}; diff --git a/assets/action.html-DvTgX1MB.js b/assets/action.html-DvTgX1MB.js new file mode 100644 index 0000000000..bcf139dad1 --- /dev/null +++ b/assets/action.html-DvTgX1MB.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1a5d6ff7","path":"/guide/action.html","title":"Action Tips and Tricks","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Homeassistant Domain","slug":"homeassistant-domain","link":"#homeassistant-domain","children":[]},{"level":2,"title":"Using Mustache Templates","slug":"using-mustache-templates","link":"#using-mustache-templates","children":[]},{"level":2,"title":"Targets","slug":"targets","link":"#targets","children":[]},{"level":2,"title":"Data Field","slug":"data-field","link":"#data-field","children":[{"level":3,"title":"Inserting a message property into a string","slug":"inserting-a-message-property-into-a-string","link":"#inserting-a-message-property-into-a-string","children":[]},{"level":3,"title":"Getting a property value of a Home Assistant entity","slug":"getting-a-property-value-of-a-home-assistant-entity","link":"#getting-a-property-value-of-a-home-assistant-entity","children":[]},{"level":3,"title":"Doing arithmetic","slug":"doing-arithmetic","link":"#doing-arithmetic","children":[]},{"level":3,"title":"Create a comma-delimited entity id list","slug":"create-a-comma-delimited-entity-id-list","link":"#create-a-comma-delimited-entity-id-list","children":[]}]}],"git":{"updatedTime":1722740908000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"guide/action.md"}');export{e as data}; diff --git a/assets/actionable-notifications-subflow-for-android.html-BoPaXVyh.js b/assets/actionable-notifications-subflow-for-android.html-BoPaXVyh.js new file mode 100644 index 0000000000..19b87b6292 --- /dev/null +++ b/assets/actionable-notifications-subflow-for-android.html-BoPaXVyh.js @@ -0,0 +1 @@ +const o=JSON.parse('{"key":"v-6fb8d56c","path":"/cookbook/actionable-notifications-subflow-for-android.html","title":"Actionable Notifications Subflow for Android","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Demo flow","slug":"demo-flow","link":"#demo-flow","children":[]},{"level":2,"title":"Use Case 1: Get a notification when garage door is left open with ability to ignore the alert for an amount of time","slug":"use-case-1-get-a-notification-when-garage-door-is-left-open-with-ability-to-ignore-the-alert-for-an-amount-of-time","link":"#use-case-1-get-a-notification-when-garage-door-is-left-open-with-ability-to-ignore-the-alert-for-an-amount-of-time","children":[]},{"level":2,"title":"Use Case 2: Ask if vacation mode should be turned on after being away for 24 hours","slug":"use-case-2-ask-if-vacation-mode-should-be-turned-on-after-being-away-for-24-hours","link":"#use-case-2-ask-if-vacation-mode-should-be-turned-on-after-being-away-for-24-hours","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":6},{"name":"Mauricio Bonani","email":"bonanitech@gmail.com","commits":1}]},"filePathRelative":"cookbook/actionable-notifications-subflow-for-android.md"}');export{o as data}; diff --git a/assets/actionable-notifications-subflow-for-android.html-DtDChOoX.js b/assets/actionable-notifications-subflow-for-android.html-DtDChOoX.js new file mode 100644 index 0000000000..089038e359 --- /dev/null +++ b/assets/actionable-notifications-subflow-for-android.html-DtDChOoX.js @@ -0,0 +1 @@ +import{_ as u,r as o,o as c,c as r,a as s,d as n,b as a,w as l,e as p}from"./app-DW3AHQOa.js";const k="/node-red-contrib-home-assistant-websocket/assets/actionable-notifications-subflow-for-android_01-Ff8j17af.png",i="/node-red-contrib-home-assistant-websocket/assets/actionable-notifications-subflow-for-android_02-E9GuL3i2.png",q="/node-red-contrib-home-assistant-websocket/assets/actionable-notifications-subflow-for-android_03-CpQYr5Am.png",y="/node-red-contrib-home-assistant-websocket/assets/actionable-notifications-subflow-for-android_04-p0E-PxHx.png",g={},d=s("h1",{id:"actionable-notifications-subflow-for-android",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#actionable-notifications-subflow-for-android","aria-hidden":"true"},"#"),n(" Actionable Notifications Subflow for Android")],-1),m={class:"custom-container tip"},b=s("p",{class:"custom-container-title"},"Questions and Discussion",-1),f={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket/discussions/311",target:"_blank",rel:"noopener noreferrer"},v=p('

screenshot

v1.0.0 - Requires Nodejs v12

Changes

[{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"Android actionable notification v1.0.0\\n\\n[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\\n","category":"HA Actions","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1188,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1188,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1188,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"mobile_app_jason","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"meta":{},"color":"#46B1EF","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"icon":"font-awesome/fa-mobile-phone","status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"msg._originalPayload = msg.payload;\\nflow.set('latestMessage', msg);\\n\\nconst services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nconst actions = [1, 2, 3].reduce((acc, i) => {\\n    const name = `action${i}`\\n    const id = flow.get(`${name}Id`);\\n    const title = getActionProperty(i, \\"title\\") ?? env.get(`${name}Title`);\\n    const uri = getActionProperty(i, \\"uri\\") ?? env.get(`${name}Uri`);\\n    const action = uri.length ? 'URI' : title ? id : undefined;\\n\\n    acc.push({ action, title, uri });\\n\\n    return acc;\\n}, []);\\n\\nconst tag = flow.get('notificationTag');\\nconst data = mergeDeep({\\n        title: env.get('title'),\\n        message: env.get('message'),\\n        data: {\\n            tag,\\n            color: env.get(\\"color\\"),\\n            group: env.get(\\"group\\"),\\n            sticky: env.get(\\"sticky\\"),\\n            timeout: env.get(\\"timeout\\"),\\n            icon: env.get(\\"icon\\")\\n        },\\n    },    \\n    msg.actionable,    \\n    {data: {actions}},\\n);\\n\\nif(tag !== data?.data?.tag) {\\n    flow.set('notificationTag', data?.data?.tag);\\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data,\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();\\n\\nfunction getActionProperty(index, prop) {\\n    const i = index - 1;\\n\\n    return msg?.actionable?.data?.actions?.[i]?.[prop];\\n}\\n\\n/**\\n * Simple object check.\\n * @param item\\n * @returns {boolean}\\n */\\nfunction isObject(item) {\\n    return (item && typeof item === 'object' && !Array.isArray(item));\\n}\\n\\n/**\\n * Deep merge two objects.\\n * @param target\\n * @param sources\\n */\\nfunction mergeDeep(target, ...sources) {\\n    if (!sources.length) return target;\\n    const source = sources.shift();\\n\\n    if (isObject(target) && isObject(source)) {\\n        for (const key in source) {\\n            if (isObject(source[key])) {\\n                if (!target[key]) Object.assign(target, { [key]: {} });\\n                mergeDeep(target[key], source[key]);\\n            } else {\\n                Object.assign(target, { [key]: source[key] });\\n            }\\n        }\\n    }\\n\\n    return mergeDeep(target, ...sources);\\n}\\n","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\\n\\n[1,2,3].forEach(i => {\\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\\n})\\n\\n\\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","libs":[],"x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\\nconst event = msg.payload.event;\\n\\nlatestMessage.eventData = msg.payload;\\nlatestMessage.payload = latestMessage._originalPayload;\\ndelete latestMessage._originalPayload;\\ndelete latestMessage.actionable;\\n\\nif(env.get('userInfo')) {\\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\\n    latestMessage.userData = userData;\\n}\\n\\nif(msg.event_type === 'mobile_app_notification_cleared') {\\n    node.status({\\n        text: `cleared at: ${getPrettyDate()}`,\\n        shape: 'dot',\\n        fill: 'blue'\\n    });\\n    \\n    return [null, latestMessage];\\n}\\n\\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\\nnode.status({\\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\\n    shape: 'dot',\\n    fill: 'green'\\n});\\n\\nreturn latestMessage;\\n\\n\\nfunction getPrettyDate() {\\n    return new Date().toLocaleDateString('en-US', {\\n        month: 'short',\\n        day: 'numeric',\\n        hour12: false,\\n        hour: 'numeric',\\n        minute: 'numeric',\\n    });\\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","server":"","version":1,"debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/auth/list\\"}","dataType":"json","responseType":"json","outputProperties":[{"property":"userData","propertyType":"msg","value":"","valueType":"results"}],"x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","server":"","version":1,"event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\\"eventData\\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\\"eventData\\").event_type","valueType":"jsonata"}],"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            message: \\"clear_notification\\",\\n            data: {\\n                tag: flow.get('notificationTag'),\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.status({text: \\"cleared\\"});\\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","server":"","version":1,"event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\\"eventData\\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\\"eventData\\").event_type","valueType":"jsonata"}],"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","server":"","version":4,"debugenabled":false,"domain":"notify","target":{"areaId":[],"deviceId":[],"entityId":[]},"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"all","x":550,"y":80,"wires":[[]]},{"id":"8a2ecff38edf7efd","type":"subflow:6dc0247c.d7210c","z":"a38123c1.2fd3f","name":"","x":516,"y":544,"wires":[[],[],[],[]]}]\n
Old versions

v0.0.0

[{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\\n[1,2,3].forEach(i => {\\n    const name = `action${i}`\\n    const id = flow.get(`${name}Id`);\\n    const title = env.get(`${name}Title`);\\n    const uri = env.get(`${name}Uri`);\\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\\n    \\n    actions.push({\\n        action,\\n        title,\\n        uri\\n    });\\n});\\n\\nmsg._originalPayload = msg.payload;\\nflow.set('latestMessage', msg);\\n\\nconst services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            title: env.get('title'),\\n            message: env.get('message'),\\n            data: {\\n                tag: flow.get('notificationTag'),\\n                actions,\\n                color: env.get(\\"color\\"),\\n                group: env.get(\\"group\\"),\\n                sticky: env.get(\\"sticky\\"),\\n                timeout: env.get(\\"timeout\\"),\\n                icon: env.get(\\"icon\\")\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\\n\\n[1,2,3].forEach(i => {\\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\\n})\\n\\n\\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\\nconst event = msg.payload.event;\\n\\nlatestMessage.eventData = msg.payload;\\nlatestMessage.payload = latestMessage._originalPayload;\\ndelete latestMessage._originalPayload;\\n\\nif(env.get('userInfo')) {\\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\\n    latestMessage.userData = userData;\\n}\\n\\nif(msg.event_type === 'mobile_app_notification_cleared') {\\n    node.status({\\n        text: `cleared at: ${getPrettyDate()}`,\\n        shape: 'dot',\\n        fill: 'blue'\\n    });\\n    \\n    return [null, latestMessage];\\n}\\n\\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\\nnode.status({\\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\\n    shape: 'dot',\\n    fill: 'green'\\n});\\n\\nreturn latestMessage;\\n\\n\\nfunction getPrettyDate() {\\n    return new Date().toLocaleDateString('en-US', {\\n        month: 'short',\\n        day: 'numeric',\\n        hour12: false,\\n        hour: 'numeric',\\n        minute: 'numeric',\\n    });\\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/auth/list\\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            message: \\"clear_notification\\",\\n            data: {\\n                tag: flow.get('notificationTag'),\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]}]\n
',6),h=s("thead",null,[s("tr",null,[s("th",null,"Options"),s("th",null,"Description"),s("th",{style:{"text-align":"center"}},"Documentation")])],-1),_=s("tr",null,[s("td",null,"Notify Service"),s("td",null,[n("Can take multiple services as a comma delimited list e.g.: "),s("code",null,"mobile_app_username, mobile_app_username2")]),s("td",{style:{"text-align":"center"}})],-1),w=s("td",null,"Title",-1),x=s("td",null,"Top line of text",-1),T={style:{"text-align":"center"}},U={href:"https://companion.home-assistant.io/docs/notifications/notifications-basic",target:"_blank",rel:"noopener noreferrer"},S=s("td",null,"Message",-1),z=s("td",null,"Second line of text accepts HTML tags",-1),I={style:{"text-align":"center"}},D={href:"https://companion.home-assistant.io/docs/notifications/notifications-basic#notification-message-html-formatting",target:"_blank",rel:"noopener noreferrer"},A=s("td",null,"Action Title",-1),$=s("td",null,"The button title",-1),M={style:{"text-align":"center"}},j={href:"https://companion.home-assistant.io/docs/notifications/actionable-notifications#building-automations-for-notification-actions",target:"_blank",rel:"noopener noreferrer"},P=s("td",null,"Action URI",-1),R=s("td",null,[n("lovelace dashboard, "),s("code",null,"https://"),n(" or "),s("code",null,"app://"),n(". If URI is defined no action is returned to Node-RED")],-1),C={style:{"text-align":"center"}},N={href:"https://companion.home-assistant.io/docs/notifications/actionable-notifications#building-automations-for-notification-actions",target:"_blank",rel:"noopener noreferrer"},E=s("tr",null,[s("td",null,"User Info"),s("td",null,[n("Will resolve user info in Node-RED and place it in "),s("code",null,"msg.userData")]),s("td",{style:{"text-align":"center"}})],-1),L=s("td",null,"Sticky",-1),H=s("td",null,"Set whether to dismiss the notification upon selecting it or not",-1),G={style:{"text-align":"center"}},O={href:"https://companion.home-assistant.io/docs/notifications/notifications-basic#sticky-notification",target:"_blank",rel:"noopener noreferrer"},F=s("td",null,"Group",-1),V=s("td",null,"string",-1),B={style:{"text-align":"center"}},Y={href:"https://companion.home-assistant.io/docs/notifications/notifications-basic#thread-id-grouping-notifications",target:"_blank",rel:"noopener noreferrer"},Q=s("td",null,"Color",-1),W=s("td",null,"Color name or the hex code",-1),J={style:{"text-align":"center"}},K={href:"https://companion.home-assistant.io/docs/notifications/notifications-basic#notification-color",target:"_blank",rel:"noopener noreferrer"},X=s("td",null,"Timeout",-1),Z=s("td",null,"How long a notification will be shown on a users device before being removed automatically",-1),ss={style:{"text-align":"center"}},ns={href:"https://companion.home-assistant.io/docs/notifications/notifications-basic#notification-timeout",target:"_blank",rel:"noopener noreferrer"},as=s("td",null,"Icon",-1),ts=s("td",null,"Path to icon",-1),ps={style:{"text-align":"center"}},os={href:"https://companion.home-assistant.io/docs/notifications/notifications-basic#notification-icon",target:"_blank",rel:"noopener noreferrer"},es=p('

Any setting can be set or overwritten using msg.actionable to pass a notification object into the node.

Demo flow

screenshot

[{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\\n[1,2,3].forEach(i => {\\n    const name = `action${i}`\\n    const id = flow.get(`${name}Id`);\\n    const title = env.get(`${name}Title`);\\n    const uri = env.get(`${name}Uri`);\\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\\n    \\n    actions.push({\\n        action,\\n        title,\\n        uri\\n    });\\n});\\n\\nmsg._originalPayload = msg.payload;\\nflow.set('latestMessage', msg);\\n\\nconst services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            title: env.get('title'),\\n            message: env.get('message'),\\n            data: {\\n                tag: flow.get('notificationTag'),\\n                actions,\\n                color: env.get(\\"color\\"),\\n                group: env.get(\\"group\\"),\\n                sticky: env.get(\\"sticky\\"),\\n                timeout: env.get(\\"timeout\\"),\\n                icon: env.get(\\"icon\\")\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\\n\\n[1,2,3].forEach(i => {\\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\\n})\\n\\n\\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\\nconst event = msg.payload.event;\\n\\nlatestMessage.eventData = msg.payload;\\nlatestMessage.payload = latestMessage._originalPayload;\\ndelete latestMessage._originalPayload;\\n\\nif(env.get('userInfo')) {\\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\\n    latestMessage.userData = userData;\\n}\\n\\nif(msg.event_type === 'mobile_app_notification_cleared') {\\n    node.status({\\n        text: `cleared at: ${getPrettyDate()}`,\\n        shape: 'dot',\\n        fill: 'blue'\\n    });\\n    \\n    return [null, latestMessage];\\n}\\n\\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\\nnode.status({\\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\\n    shape: 'dot',\\n    fill: 'green'\\n});\\n\\nreturn latestMessage;\\n\\n\\nfunction getPrettyDate() {\\n    return new Date().toLocaleDateString('en-US', {\\n        month: 'short',\\n        day: 'numeric',\\n        hour12: false,\\n        hour: 'numeric',\\n        minute: 'numeric',\\n    });\\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/auth/list\\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            message: \\"clear_notification\\",\\n            data: {\\n                tag: flow.get('notificationTag'),\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"581acb2a.792564","type":"subflow:6dc0247c.d7210c","z":"31cdc.c18e83244","name":"","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"testing actionable notification","type":"str"},{"name":"action1Title","value":"action one","type":"str"},{"name":"action2Title","value":"open HA","type":"str"},{"name":"action2Uri","value":"/lovelace/0","type":"str"},{"name":"action3Title","value":"action three","type":"str"},{"name":"userInfo","type":"bool","value":"true"},{"name":"group","value":"","type":"str"}],"x":436,"y":1136,"wires":[["d2b46240.6de89"],["a63fb7bc.64af88"],["2f4904b8.568d3c"],["75334c15.956694"]]},{"id":"aa8e9e73.4957f","type":"inject","z":"31cdc.c18e83244","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"abc","payload":"default payload","payloadType":"str","x":202,"y":1136,"wires":[["581acb2a.792564"]]},{"id":"d2b46240.6de89","type":"debug","z":"31cdc.c18e83244","name":"action1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1088,"wires":[]},{"id":"a63fb7bc.64af88","type":"debug","z":"31cdc.c18e83244","name":"action2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1120,"wires":[]},{"id":"2f4904b8.568d3c","type":"debug","z":"31cdc.c18e83244","name":"action3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1152,"wires":[]},{"id":"75334c15.956694","type":"debug","z":"31cdc.c18e83244","name":"cleared","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1184,"wires":[]},{"id":"81797230.4299e","type":"inject","z":"31cdc.c18e83244","name":"clear_notification","props":[{"p":"clear_notification","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":208,"y":1184,"wires":[["581acb2a.792564"]]}]\n

Use Case 1: Get a notification when garage door is left open with ability to ignore the alert for an amount of time

screenshot

[{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\\n[1,2,3].forEach(i => {\\n    const name = `action${i}`\\n    const id = flow.get(`${name}Id`);\\n    const title = env.get(`${name}Title`);\\n    const uri = env.get(`${name}Uri`);\\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\\n    \\n    actions.push({\\n        action,\\n        title,\\n        uri\\n    });\\n});\\n\\nmsg._originalPayload = msg.payload;\\nflow.set('latestMessage', msg);\\n\\nconst services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            title: env.get('title'),\\n            message: env.get('message'),\\n            data: {\\n                tag: flow.get('notificationTag'),\\n                actions,\\n                color: env.get(\\"color\\"),\\n                group: env.get(\\"group\\"),\\n                sticky: env.get(\\"sticky\\"),\\n                timeout: env.get(\\"timeout\\"),\\n                icon: env.get(\\"icon\\")\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\\n\\n[1,2,3].forEach(i => {\\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\\n})\\n\\n\\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\\nconst event = msg.payload.event;\\n\\nlatestMessage.eventData = msg.payload;\\nlatestMessage.payload = latestMessage._originalPayload;\\ndelete latestMessage._originalPayload;\\n\\nif(env.get('userInfo')) {\\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\\n    latestMessage.userData = userData;\\n}\\n\\nif(msg.event_type === 'mobile_app_notification_cleared') {\\n    node.status({\\n        text: `cleared at: ${getPrettyDate()}`,\\n        shape: 'dot',\\n        fill: 'blue'\\n    });\\n    \\n    return [null, latestMessage];\\n}\\n\\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\\nnode.status({\\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\\n    shape: 'dot',\\n    fill: 'green'\\n});\\n\\nreturn latestMessage;\\n\\n\\nfunction getPrettyDate() {\\n    return new Date().toLocaleDateString('en-US', {\\n        month: 'short',\\n        day: 'numeric',\\n        hour12: false,\\n        hour: 'numeric',\\n        minute: 'numeric',\\n    });\\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/auth/list\\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            message: \\"clear_notification\\",\\n            data: {\\n                tag: flow.get('notificationTag'),\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"bec57b08.0a8f08","type":"time-range-switch","z":"31cdc.c18e83244","name":"","lat":"","lon":"","startTime":"sunsetStart","endTime":"6:00","startOffset":"-15","endOffset":0,"x":474,"y":1552,"wires":[["1b96dc9e.4f1fe3"],[]]},{"id":"31d5412.74a31be","type":"poll-state","z":"31cdc.c18e83244","name":"garage door open?","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"30","updateIntervalUnits":"seconds","outputinitially":true,"outputonchanged":true,"entity_id":"cover.garage_door","state_type":"str","halt_if":"open","halt_if_type":"str","halt_if_compare":"is","outputs":2,"x":122,"y":1584,"wires":[["6566fa4.a832004"],["5485b497.b4d90c"]]},{"id":"765bef97.90e0e","type":"throttle","z":"31cdc.c18e83244","name":"Once / 30 mins","throttleType":"time","timeLimit":"15","timeLimitType":"minutes","countLimit":0,"blockSize":0,"locked":false,"x":848,"y":1600,"wires":[["587bab85.857fe4"]]},{"id":"587bab85.857fe4","type":"subflow:6dc0247c.d7210c","z":"31cdc.c18e83244","name":"close garage door?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Garage Door","type":"str"},{"name":"message","value":"Garage Door is Open","type":"str"},{"name":"action1Title","value":"Close Door","type":"str"},{"name":"action2Title","value":"Ignore 1 hour","type":"str"},{"name":"action3Title","value":"Ignore 2 hours","type":"str"},{"name":"group","value":"","type":"str"}],"x":1050,"y":1600,"wires":[["e85a9609.74ddd8"],["8c90dfc.28f2f2"],["df484d95.35a35"],["13c8aaf9.466e05"]],"icon":"font-awesome/fa-car"},{"id":"e85a9609.74ddd8","type":"api-call-service","z":"31cdc.c18e83244","name":"close garage door","version":1,"debugenabled":false,"service_domain":"cover","service":"close_cover","entityId":"cover.garage_door","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1258,"y":1552,"wires":[[]]},{"id":"1d0b3f5b.37aab1","type":"api-current-state","z":"31cdc.c18e83244","name":"not home?","version":1,"outputs":2,"halt_if":"home","halt_if_type":"num","halt_if_compare":"is_not","override_topic":false,"entity_id":"person.jason","state_type":"str","state_location":"","override_payload":"none","entity_location":"","override_data":"none","blockInputOverrides":false,"x":662,"y":1600,"wires":[["765bef97.90e0e"],[]]},{"id":"8c90dfc.28f2f2","type":"change","z":"31cdc.c18e83244","name":"","rules":[{"t":"set","p":"ignore","pt":"msg","to":"60","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1183,"y":1600,"wires":[["88fd9ca4.3ea69"]],"l":false},{"id":"df484d95.35a35","type":"change","z":"31cdc.c18e83244","name":"","rules":[{"t":"set","p":"ignore","pt":"msg","to":"120","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1183,"y":1632,"wires":[["88fd9ca4.3ea69"]],"l":false},{"id":"6566fa4.a832004","type":"function","z":"31cdc.c18e83244","name":"ignore?","func":"if(msg.ignore) {\\n    const timeout = Date.now() + msg.ignore * 60000;\\n    const d = new Date(timeout);\\n    context.set('timeout', timeout)\\n    node.status({text: `Ignoring until ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`, fill: \\"red\\"});\\n    return;\\n}\\n\\nconst timeout = context.get('timeout') || 0;\\n\\nif(timeout > Date.now()) return;\\n\\nnode.status({});\\n\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":300,"y":1584,"wires":[["bec57b08.0a8f08","8f5a5cc3.fb235"]]},{"id":"88fd9ca4.3ea69","type":"link out","z":"31cdc.c18e83244","name":"Ignore","links":["9e5e4c22.4d925"],"x":1298,"y":1600,"wires":[],"l":true},{"id":"9e5e4c22.4d925","type":"link in","z":"31cdc.c18e83244","name":"","links":["88fd9ca4.3ea69"],"x":191,"y":1536,"wires":[["6566fa4.a832004"]]},{"id":"13c8aaf9.466e05","type":"change","z":"31cdc.c18e83244","name":"","rules":[{"t":"set","p":"ignore","pt":"msg","to":"30","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1183,"y":1664,"wires":[["88fd9ca4.3ea69"]],"l":false},{"id":"8f5a5cc3.fb235","type":"trigger","z":"31cdc.c18e83244","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"2","extend":false,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":454,"y":1600,"wires":[["1d0b3f5b.37aab1"]]},{"id":"5485b497.b4d90c","type":"change","z":"31cdc.c18e83244","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":1632,"wires":[["8f5a5cc3.fb235","1b96dc9e.4f1fe3"]]},{"id":"1b96dc9e.4f1fe3","type":"trigger","z":"31cdc.c18e83244","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"15","extend":false,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":662,"y":1552,"wires":[["765bef97.90e0e"]]}]\n

Required Nodes

',8),us={href:"https://flows.nodered.org/node/node-red-contrib-time-range-switch",target:"_blank",rel:"noopener noreferrer"},cs=p('

Use Case 2: Ask if vacation mode should be turned on after being away for 24 hours

screenshot

[{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\\n[1,2,3].forEach(i => {\\n    const name = `action${i}`\\n    const id = flow.get(`${name}Id`);\\n    const title = env.get(`${name}Title`);\\n    const uri = env.get(`${name}Uri`);\\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\\n    \\n    actions.push({\\n        action,\\n        title,\\n        uri\\n    });\\n});\\n\\nmsg._originalPayload = msg.payload;\\nflow.set('latestMessage', msg);\\n\\nconst services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            title: env.get('title'),\\n            message: env.get('message'),\\n            data: {\\n                tag: flow.get('notificationTag'),\\n                actions,\\n                color: env.get(\\"color\\"),\\n                group: env.get(\\"group\\"),\\n                sticky: env.get(\\"sticky\\"),\\n                timeout: env.get(\\"timeout\\"),\\n                icon: env.get(\\"icon\\")\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\\n\\n[1,2,3].forEach(i => {\\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\\n})\\n\\n\\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\\nconst event = msg.payload.event;\\n\\nlatestMessage.eventData = msg.payload;\\nlatestMessage.payload = latestMessage._originalPayload;\\ndelete latestMessage._originalPayload;\\n\\nif(env.get('userInfo')) {\\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\\n    latestMessage.userData = userData;\\n}\\n\\nif(msg.event_type === 'mobile_app_notification_cleared') {\\n    node.status({\\n        text: `cleared at: ${getPrettyDate()}`,\\n        shape: 'dot',\\n        fill: 'blue'\\n    });\\n    \\n    return [null, latestMessage];\\n}\\n\\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\\nnode.status({\\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\\n    shape: 'dot',\\n    fill: 'green'\\n});\\n\\nreturn latestMessage;\\n\\n\\nfunction getPrettyDate() {\\n    return new Date().toLocaleDateString('en-US', {\\n        month: 'short',\\n        day: 'numeric',\\n        hour12: false,\\n        hour: 'numeric',\\n        minute: 'numeric',\\n    });\\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/auth/list\\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            message: \\"clear_notification\\",\\n            data: {\\n                tag: flow.get('notificationTag'),\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"b35b9988.72c6d8","type":"server-state-changed","z":"f6d789f6.6b5388","name":"Away?","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"24","forType":"num","forUnits":"hours","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":290,"y":256,"wires":[["4587eb7f.fb86a4"],[]]},{"id":"4587eb7f.fb86a4","type":"api-current-state","z":"f6d789f6.6b5388","name":"Vacation mode off?","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":458,"y":256,"wires":[["e5d8423c.2ccfe"],[]]},{"id":"be568091.56bbb","type":"api-call-service","z":"f6d789f6.6b5388","name":"Turn On Vacation Mode","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":942,"y":256,"wires":[[]]},{"id":"e5d8423c.2ccfe","type":"subflow:6dc0247c.d7210c","z":"f6d789f6.6b5388","name":"Turn on Vacation Mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been away for 24 hours.<br>Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":686,"y":272,"wires":[["be568091.56bbb"],[],[],[]]}]\n

Also see:

',4);function rs(ls,ks){const t=o("ExternalLinkIcon"),e=o("RouterLink");return c(),r("div",null,[d,s("div",m,[b,s("p",null,[n("Post questions and follow the discussion about this recipe "),s("a",f,[n("here"),a(t)])])]),v,s("table",null,[h,s("tbody",null,[_,s("tr",null,[w,x,s("td",T,[s("a",U,[n("link"),a(t)])])]),s("tr",null,[S,z,s("td",I,[s("a",D,[n("link"),a(t)])])]),s("tr",null,[A,$,s("td",M,[s("a",j,[n("link"),a(t)])])]),s("tr",null,[P,R,s("td",C,[s("a",N,[n("link"),a(t)])])]),E,s("tr",null,[L,H,s("td",G,[s("a",O,[n("link"),a(t)])])]),s("tr",null,[F,V,s("td",B,[s("a",Y,[n("link"),a(t)])])]),s("tr",null,[Q,W,s("td",J,[s("a",K,[n("link"),a(t)])])]),s("tr",null,[X,Z,s("td",ss,[s("a",ns,[n("link"),a(t)])])]),s("tr",null,[as,ts,s("td",ps,[s("a",os,[n("link"),a(t)])])])])]),es,s("ul",null,[s("li",null,[s("a",us,[n("time-range-switch"),a(t)])])]),cs,s("ul",null,[s("li",null,[a(e,{to:"/cookbook/vacation-mode.html"},{default:l(()=>[n("Cookbook: Vacation Mode")]),_:1})])])])}const qs=u(g,[["render",rs],["__file","actionable-notifications-subflow-for-android.html.vue"]]);export{qs as default}; diff --git a/assets/actionable-notifications-subflow-for-android_01-Ff8j17af.png b/assets/actionable-notifications-subflow-for-android_01-Ff8j17af.png new file mode 100644 index 0000000000..36302f4515 Binary files /dev/null and b/assets/actionable-notifications-subflow-for-android_01-Ff8j17af.png differ diff --git a/assets/actionable-notifications-subflow-for-android_02-E9GuL3i2.png b/assets/actionable-notifications-subflow-for-android_02-E9GuL3i2.png new file mode 100644 index 0000000000..4416bd797e Binary files /dev/null and b/assets/actionable-notifications-subflow-for-android_02-E9GuL3i2.png differ diff --git a/assets/actionable-notifications-subflow-for-android_03-CpQYr5Am.png b/assets/actionable-notifications-subflow-for-android_03-CpQYr5Am.png new file mode 100644 index 0000000000..7718831898 Binary files /dev/null and b/assets/actionable-notifications-subflow-for-android_03-CpQYr5Am.png differ diff --git a/assets/actionable-notifications-subflow-for-android_04-p0E-PxHx.png b/assets/actionable-notifications-subflow-for-android_04-p0E-PxHx.png new file mode 100644 index 0000000000..9fe308febc Binary files /dev/null and b/assets/actionable-notifications-subflow-for-android_04-p0E-PxHx.png differ diff --git a/assets/app-DW3AHQOa.js b/assets/app-DW3AHQOa.js new file mode 100644 index 0000000000..db536401b6 --- /dev/null +++ b/assets/app-DW3AHQOa.js @@ -0,0 +1,16 @@ +function Li(e,t){const n=new Set(e.split(","));return l=>n.has(l)}const we={},an=[],et=()=>{},ha=()=>!1,Bn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ti=e=>e.startsWith("onUpdate:"),Oe=Object.assign,Si=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},pa=Object.prototype.hasOwnProperty,pe=(e,t)=>pa.call(e,t),Q=Array.isArray,cn=e=>zn(e)==="[object Map]",Ol=e=>zn(e)==="[object Set]",co=e=>zn(e)==="[object Date]",re=e=>typeof e=="function",me=e=>typeof e=="string",Dt=e=>typeof e=="symbol",ye=e=>e!==null&&typeof e=="object",Cr=e=>(ye(e)||re(e))&&re(e.then)&&re(e.catch),Ar=Object.prototype.toString,zn=e=>Ar.call(e),ga=e=>zn(e).slice(8,-1),Or=e=>zn(e)==="[object Object]",Ci=e=>me(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Cn=Li(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Rl=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},va=/-(\w)/g,dt=Rl(e=>e.replace(va,(t,n)=>n?n.toUpperCase():"")),ma=/\B([A-Z])/g,Zt=Rl(e=>e.replace(ma,"-$1").toLowerCase()),Pl=Rl(e=>e.charAt(0).toUpperCase()+e.slice(1)),Wl=Rl(e=>e?`on${Pl(e)}`:""),Nt=(e,t)=>!Object.is(e,t),fl=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},ai=e=>{const t=parseFloat(e);return isNaN(t)?e:t},_a=e=>{const t=me(e)?Number(e):NaN;return isNaN(t)?e:t};let uo;const Rr=()=>uo||(uo=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Un(e){if(Q(e)){const t={};for(let n=0;n{if(n){const l=n.split(ya);l.length>1&&(t[l[0].trim()]=l[1].trim())}}),t}function Ke(e){let t="";if(me(e))t=e;else if(Q(e))for(let n=0;nIl(n,t))}const Ae=e=>me(e)?e:e==null?"":Q(e)||ye(e)&&(e.toString===Ar||!re(e.toString))?JSON.stringify(e,Dr,2):String(e),Dr=(e,t)=>t&&t.__v_isRef?Dr(e,t.value):cn(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[l,i],o)=>(n[Kl(l,o)+" =>"]=i,n),{})}:Ol(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>Kl(n))}:Dt(t)?Kl(t):ye(t)&&!Q(t)&&!Or(t)?String(t):t,Kl=(e,t="")=>{var n;return Dt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};let Ye;class Ta{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ye,!t&&Ye&&(this.index=(Ye.scopes||(Ye.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Ye;try{return Ye=this,t()}finally{Ye=n}}}on(){Ye=this}off(){Ye=this.parent}stop(t){if(this._active){let n,l;for(n=0,l=this.effects.length;n=2))break;en(),this._queryings--}return this._dirtyLevel>=2}set dirty(t){this._dirtyLevel=t?3:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=Rt,n=Gt;try{return Rt=!0,Gt=this,this._runnings++,fo(this),this.fn()}finally{ho(this),this._runnings--,Gt=n,Rt=t}}stop(){var t;this.active&&(fo(this),ho(this),(t=this.onStop)==null||t.call(this),this.active=!1)}}function Oa(e){return e.value}function fo(e){e._trackId++,e._depsLength=0}function ho(e){if(e.deps&&e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},vl=new WeakMap,Jt=Symbol(""),di=Symbol("");function Ge(e,t,n){if(Rt&&Gt){let l=vl.get(e);l||vl.set(e,l=new Map);let i=l.get(n);i||l.set(n,i=Vr(()=>l.delete(n))),$r(Gt,i)}}function vt(e,t,n,l,i,o){const r=vl.get(e);if(!r)return;let a=[];if(t==="clear")a=[...r.values()];else if(n==="length"&&Q(e)){const s=Number(l);r.forEach((c,u)=>{(u==="length"||!Dt(u)&&u>=s)&&a.push(c)})}else switch(n!==void 0&&a.push(r.get(n)),t){case"add":Q(e)?Ci(n)&&a.push(r.get("length")):(a.push(r.get(Jt)),cn(e)&&a.push(r.get(di)));break;case"delete":Q(e)||(a.push(r.get(Jt)),cn(e)&&a.push(r.get(di)));break;case"set":cn(e)&&a.push(r.get(Jt));break}Oi();for(const s of a)s&&Fr(s,3);Ri()}function Ra(e,t){var n;return(n=vl.get(e))==null?void 0:n.get(t)}const Pa=Li("__proto__,__v_isRef,__isVue"),Hr=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Dt)),po=Ia();function Ia(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const l=ve(this);for(let o=0,r=this.length;o{e[t]=function(...n){Xt(),Oi();const l=ve(this)[t].apply(this,n);return Ri(),en(),l}}),e}function Da(e){const t=ve(this);return Ge(t,"has",e),t.hasOwnProperty(e)}class jr{constructor(t=!1,n=!1){this._isReadonly=t,this._shallow=n}get(t,n,l){const i=this._isReadonly,o=this._shallow;if(n==="__v_isReactive")return!i;if(n==="__v_isReadonly")return i;if(n==="__v_isShallow")return o;if(n==="__v_raw")return l===(i?o?qa:Wr:o?Ur:zr).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(l)?t:void 0;const r=Q(t);if(!i){if(r&&pe(po,n))return Reflect.get(po,n,l);if(n==="hasOwnProperty")return Da}const a=Reflect.get(t,n,l);return(Dt(n)?Hr.has(n):Pa(n))||(i||Ge(t,"get",n),o)?a:je(a)?r&&Ci(n)?a:a.value:ye(a)?i?bn(a):Wn(a):a}}class Br extends jr{constructor(t=!1){super(!1,t)}set(t,n,l,i){let o=t[n];if(!this._shallow){const s=pn(o);if(!ml(l)&&!pn(l)&&(o=ve(o),l=ve(l)),!Q(t)&&je(o)&&!je(l))return s?!1:(o.value=l,!0)}const r=Q(t)&&Ci(n)?Number(n)e,Dl=e=>Reflect.getPrototypeOf(e);function Zn(e,t,n=!1,l=!1){e=e.__v_raw;const i=ve(e),o=ve(t);n||(Nt(t,o)&&Ge(i,"get",t),Ge(i,"get",o));const{has:r}=Dl(i),a=l?Pi:n?Ni:Dn;if(r.call(i,t))return a(e.get(t));if(r.call(i,o))return a(e.get(o));e!==i&&e.get(t)}function Xn(e,t=!1){const n=this.__v_raw,l=ve(n),i=ve(e);return t||(Nt(e,i)&&Ge(l,"has",e),Ge(l,"has",i)),e===i?n.has(e):n.has(e)||n.has(i)}function el(e,t=!1){return e=e.__v_raw,!t&&Ge(ve(e),"iterate",Jt),Reflect.get(e,"size",e)}function go(e){e=ve(e);const t=ve(this);return Dl(t).has.call(t,e)||(t.add(e),vt(t,"add",e,e)),this}function vo(e,t){t=ve(t);const n=ve(this),{has:l,get:i}=Dl(n);let o=l.call(n,e);o||(e=ve(e),o=l.call(n,e));const r=i.call(n,e);return n.set(e,t),o?Nt(t,r)&&vt(n,"set",e,t):vt(n,"add",e,t),this}function mo(e){const t=ve(this),{has:n,get:l}=Dl(t);let i=n.call(t,e);i||(e=ve(e),i=n.call(t,e)),l&&l.call(t,e);const o=t.delete(e);return i&&vt(t,"delete",e,void 0),o}function _o(){const e=ve(this),t=e.size!==0,n=e.clear();return t&&vt(e,"clear",void 0,void 0),n}function tl(e,t){return function(l,i){const o=this,r=o.__v_raw,a=ve(r),s=t?Pi:e?Ni:Dn;return!e&&Ge(a,"iterate",Jt),r.forEach((c,u)=>l.call(i,s(c),s(u),o))}}function nl(e,t,n){return function(...l){const i=this.__v_raw,o=ve(i),r=cn(o),a=e==="entries"||e===Symbol.iterator&&r,s=e==="keys"&&r,c=i[e](...l),u=n?Pi:t?Ni:Dn;return!t&&Ge(o,"iterate",s?di:Jt),{next(){const{value:d,done:f}=c.next();return f?{value:d,done:f}:{value:a?[u(d[0]),u(d[1])]:u(d),done:f}},[Symbol.iterator](){return this}}}}function wt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Va(){const e={get(o){return Zn(this,o)},get size(){return el(this)},has:Xn,add:go,set:vo,delete:mo,clear:_o,forEach:tl(!1,!1)},t={get(o){return Zn(this,o,!1,!0)},get size(){return el(this)},has:Xn,add:go,set:vo,delete:mo,clear:_o,forEach:tl(!1,!0)},n={get(o){return Zn(this,o,!0)},get size(){return el(this,!0)},has(o){return Xn.call(this,o,!0)},add:wt("add"),set:wt("set"),delete:wt("delete"),clear:wt("clear"),forEach:tl(!0,!1)},l={get(o){return Zn(this,o,!0,!0)},get size(){return el(this,!0)},has(o){return Xn.call(this,o,!0)},add:wt("add"),set:wt("set"),delete:wt("delete"),clear:wt("clear"),forEach:tl(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=nl(o,!1,!1),n[o]=nl(o,!0,!1),t[o]=nl(o,!1,!0),l[o]=nl(o,!0,!0)}),[e,n,t,l]}const[Ha,ja,Ba,za]=Va();function Ii(e,t){const n=t?e?za:Ba:e?ja:Ha;return(l,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?l:Reflect.get(pe(n,i)&&i in l?n:l,i,o)}const Ua={get:Ii(!1,!1)},Wa={get:Ii(!1,!0)},Ka={get:Ii(!0,!1)},zr=new WeakMap,Ur=new WeakMap,Wr=new WeakMap,qa=new WeakMap;function Ga(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Ja(e){return e.__v_skip||!Object.isExtensible(e)?0:Ga(ga(e))}function Wn(e){return pn(e)?e:Di(e,!1,Ma,Ua,zr)}function Kr(e){return Di(e,!1,Fa,Wa,Ur)}function bn(e){return Di(e,!0,$a,Ka,Wr)}function Di(e,t,n,l,i){if(!ye(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=i.get(e);if(o)return o;const r=Ja(e);if(r===0)return e;const a=new Proxy(e,r===2?l:n);return i.set(e,a),a}function un(e){return pn(e)?un(e.__v_raw):!!(e&&e.__v_isReactive)}function pn(e){return!!(e&&e.__v_isReadonly)}function ml(e){return!!(e&&e.__v_isShallow)}function qr(e){return un(e)||pn(e)}function ve(e){const t=e&&e.__v_raw;return t?ve(t):e}function Gr(e){return gl(e,"__v_skip",!0),e}const Dn=e=>ye(e)?Wn(e):e,Ni=e=>ye(e)?bn(e):e;class Jr{constructor(t,n,l,i){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new Ai(()=>t(this._value),()=>_l(this,1)),this.effect.computed=this,this.effect.active=this._cacheable=!i,this.__v_isReadonly=l}get value(){const t=ve(this);return Mi(t),(!t._cacheable||t.effect.dirty)&&Nt(t._value,t._value=t.effect.run())&&_l(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function Ya(e,t,n=!1){let l,i;const o=re(e);return o?(l=e,i=et):(l=e.get,i=e.set),new Jr(l,i,o||!i,n)}function Mi(e){Rt&&Gt&&(e=ve(e),$r(Gt,e.dep||(e.dep=Vr(()=>e.dep=void 0,e instanceof Jr?e:void 0))))}function _l(e,t=3,n){e=ve(e);const l=e.dep;l&&Fr(l,t)}function je(e){return!!(e&&e.__v_isRef===!0)}function de(e){return Yr(e,!1)}function $i(e){return Yr(e,!0)}function Yr(e,t){return je(e)?e:new Qa(e,t)}class Qa{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:ve(t),this._value=n?t:Dn(t)}get value(){return Mi(this),this._value}set value(t){const n=this.__v_isShallow||ml(t)||pn(t);t=n?t:ve(t),Nt(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:Dn(t),_l(this,3))}}function ne(e){return je(e)?e.value:e}const Za={get:(e,t,n)=>ne(Reflect.get(e,t,n)),set:(e,t,n,l)=>{const i=e[t];return je(i)&&!je(n)?(i.value=n,!0):Reflect.set(e,t,n,l)}};function Qr(e){return un(e)?e:new Proxy(e,Za)}class Xa{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:n,set:l}=t(()=>Mi(this),()=>_l(this));this._get=n,this._set=l}get value(){return this._get()}set value(t){this._set(t)}}function ec(e){return new Xa(e)}function Nl(e){const t=Q(e)?new Array(e.length):{};for(const n in e)t[n]=nc(e,n);return t}class tc{constructor(t,n,l){this._object=t,this._key=n,this._defaultValue=l,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return Ra(ve(this._object),this._key)}}function nc(e,t,n){const l=e[t];return je(l)?l:new tc(e,t,n)}function Pt(e,t,n,l){let i;try{i=l?e(...l):e()}catch(o){Kn(o,t,n)}return i}function tt(e,t,n,l){if(re(e)){const o=Pt(e,t,n,l);return o&&Cr(o)&&o.catch(r=>{Kn(r,t,n)}),o}const i=[];for(let o=0;o>>1,i=He[l],o=Mn(i);out&&He.splice(t,1)}function rc(e){Q(e)?dn.push(...e):(!gt||!gt.includes(e,e.allowRecurse?Ut+1:Ut))&&dn.push(e),Xr()}function bo(e,t,n=Nn?ut+1:0){for(;nMn(n)-Mn(l)),Ut=0;Ute.id==null?1/0:e.id,sc=(e,t)=>{const n=Mn(e)-Mn(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function es(e){fi=!1,Nn=!0,He.sort(sc);try{for(ut=0;utme(g)?g.trim():g)),d&&(i=n.map(ai))}let a,s=l[a=Wl(t)]||l[a=Wl(dt(t))];!s&&o&&(s=l[a=Wl(Zt(t))]),s&&tt(s,e,6,i);const c=l[a+"Once"];if(c){if(!e.emitted)e.emitted={};else if(e.emitted[a])return;e.emitted[a]=!0,tt(c,e,6,i)}}function ts(e,t,n=!1){const l=t.emitsCache,i=l.get(e);if(i!==void 0)return i;const o=e.emits;let r={},a=!1;if(!re(e)){const s=c=>{const u=ts(c,t,!0);u&&(a=!0,Oe(r,u))};!n&&t.mixins.length&&t.mixins.forEach(s),e.extends&&s(e.extends),e.mixins&&e.mixins.forEach(s)}return!o&&!a?(ye(e)&&l.set(e,null),null):(Q(o)?o.forEach(s=>r[s]=null):Oe(r,o),ye(e)&&l.set(e,r),r)}function $l(e,t){return!e||!Bn(t)?!1:(t=t.slice(2).replace(/Once$/,""),pe(e,t[0].toLowerCase()+t.slice(1))||pe(e,Zt(t))||pe(e,t))}let $e=null,ns=null;function yl(e){const t=$e;return $e=e,ns=e&&e.type.__scopeId||null,t}function Me(e,t=$e,n){if(!t||e._n)return e;const l=(...i)=>{l._d&&Ro(-1);const o=yl(t);let r;try{r=e(...i)}finally{yl(o),l._d&&Ro(1)}return r};return l._n=!0,l._c=!0,l._d=!0,l}function ql(e){const{type:t,vnode:n,proxy:l,withProxy:i,props:o,propsOptions:[r],slots:a,attrs:s,emit:c,render:u,renderCache:d,data:f,setupState:g,ctx:b,inheritAttrs:w}=e;let T,x;const A=yl(e);try{if(n.shapeFlag&4){const E=i||l,O=E;T=lt(u.call(O,E,d,o,g,f,b)),x=s}else{const E=t;T=lt(E.length>1?E(o,{attrs:s,slots:a,emit:c}):E(o,null)),x=t.props?s:cc(s)}}catch(E){Rn.length=0,Kn(E,e,1),T=ie(Qe)}let v=T;if(x&&w!==!1){const E=Object.keys(x),{shapeFlag:O}=v;E.length&&O&7&&(r&&E.some(Ti)&&(x=uc(x,r)),v=$t(v,x))}return n.dirs&&(v=$t(v),v.dirs=v.dirs?v.dirs.concat(n.dirs):n.dirs),n.transition&&(v.transition=n.transition),T=v,yl(A),T}const cc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Bn(n))&&((t||(t={}))[n]=e[n]);return t},uc=(e,t)=>{const n={};for(const l in e)(!Ti(l)||!(l.slice(9)in t))&&(n[l]=e[l]);return n};function dc(e,t,n){const{props:l,children:i,component:o}=e,{props:r,children:a,patchFlag:s}=t,c=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&s>=0){if(s&1024)return!0;if(s&16)return l?yo(l,r,c):!!r;if(s&8){const u=t.dynamicProps;for(let d=0;de.__isSuspense;function is(e,t){t&&t.pendingBranch?Q(e)?t.effects.push(...e):t.effects.push(e):rc(e)}const vc=Symbol.for("v-scx"),mc=()=>Se(vc);function os(e,t){return Vi(e,null,t)}const ll={};function qe(e,t,n){return Vi(e,t,n)}function Vi(e,t,{immediate:n,deep:l,flush:i,once:o,onTrack:r,onTrigger:a}=we){if(t&&o){const O=t;t=(...G)=>{O(...G),E()}}const s=De,c=O=>l===!0?O:qt(O,l===!1?1:void 0);let u,d=!1,f=!1;if(je(e)?(u=()=>e.value,d=ml(e)):un(e)?(u=()=>c(e),d=!0):Q(e)?(f=!0,d=e.some(O=>un(O)||ml(O)),u=()=>e.map(O=>{if(je(O))return O.value;if(un(O))return c(O);if(re(O))return Pt(O,s,2)})):re(e)?t?u=()=>Pt(e,s,2):u=()=>(g&&g(),tt(e,s,3,[b])):u=et,t&&l){const O=u;u=()=>qt(O())}let g,b=O=>{g=v.onStop=()=>{Pt(O,s,4),g=v.onStop=void 0}},w;if(Jn)if(b=et,t?n&&tt(t,s,3,[u(),f?[]:void 0,b]):u(),i==="sync"){const O=mc();w=O.__watcherHandles||(O.__watcherHandles=[])}else return et;let T=f?new Array(e.length).fill(ll):ll;const x=()=>{if(!(!v.active||!v.dirty))if(t){const O=v.run();(l||d||(f?O.some((G,F)=>Nt(G,T[F])):Nt(O,T)))&&(g&&g(),tt(t,s,3,[O,T===ll?void 0:f&&T[0]===ll?[]:T,b]),T=O)}else v.run()};x.allowRecurse=!!t;let A;i==="sync"?A=x:i==="post"?A=()=>We(x,s&&s.suspense):(x.pre=!0,s&&(x.id=s.uid),A=()=>Ml(x));const v=new Ai(u,et,A),E=()=>{v.stop(),s&&s.scope&&Si(s.scope.effects,v)};return t?n?x():T=v.run():i==="post"?We(v.run.bind(v),s&&s.suspense):v.run(),w&&w.push(E),E}function _c(e,t,n){const l=this.proxy,i=me(e)?e.includes(".")?rs(l,e):()=>l[e]:e.bind(l,l);let o;re(t)?o=t:(o=t.handler,n=t);const r=De;vn(this);const a=Vi(i,o.bind(l),n);return r?vn(r):Qt(),a}function rs(e,t){const n=t.split(".");return()=>{let l=e;for(let i=0;i0){if(n>=t)return e;n++}if(l=l||new Set,l.has(e))return e;if(l.add(e),je(e))qt(e.value,t,n,l);else if(Q(e))for(let i=0;i{qt(i,t,n,l)});else if(Or(e))for(const i in e)qt(e[i],t,n,l);return e}function kl(e,t){const n=$e;if(n===null)return e;const l=Bl(n)||n.proxy,i=e.dirs||(e.dirs=[]);for(let o=0;o{e.isMounted=!0}),Gn(()=>{e.isUnmounting=!0}),e}const Ze=[Function,Array],ss={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Ze,onEnter:Ze,onAfterEnter:Ze,onEnterCancelled:Ze,onBeforeLeave:Ze,onLeave:Ze,onAfterLeave:Ze,onLeaveCancelled:Ze,onBeforeAppear:Ze,onAppear:Ze,onAfterAppear:Ze,onAppearCancelled:Ze},yc={name:"BaseTransition",props:ss,setup(e,{slots:t}){const n=jl(),l=bc();let i;return()=>{const o=t.default&&cs(t.default(),!0);if(!o||!o.length)return;let r=o[0];if(o.length>1){for(const w of o)if(w.type!==Qe){r=w;break}}const a=ve(e),{mode:s}=a;if(l.isLeaving)return Gl(r);const c=Eo(r);if(!c)return Gl(r);const u=hi(c,a,l,n);pi(c,u);const d=n.subTree,f=d&&Eo(d);let g=!1;const{getTransitionKey:b}=c.type;if(b){const w=b();i===void 0?i=w:w!==i&&(i=w,g=!0)}if(f&&f.type!==Qe&&(!Wt(c,f)||g)){const w=hi(f,a,l,n);if(pi(f,w),s==="out-in")return l.isLeaving=!0,w.afterLeave=()=>{l.isLeaving=!1,n.update.active!==!1&&(n.effect.dirty=!0,n.update())},Gl(r);s==="in-out"&&c.type!==Qe&&(w.delayLeave=(T,x,A)=>{const v=as(l,f);v[String(f.key)]=f,T[St]=()=>{x(),T[St]=void 0,delete u.delayedLeave},u.delayedLeave=A})}return r}}},kc=yc;function as(e,t){const{leavingVNodes:n}=e;let l=n.get(t.type);return l||(l=Object.create(null),n.set(t.type,l)),l}function hi(e,t,n,l){const{appear:i,mode:o,persisted:r=!1,onBeforeEnter:a,onEnter:s,onAfterEnter:c,onEnterCancelled:u,onBeforeLeave:d,onLeave:f,onAfterLeave:g,onLeaveCancelled:b,onBeforeAppear:w,onAppear:T,onAfterAppear:x,onAppearCancelled:A}=t,v=String(e.key),E=as(n,e),O=(_,N)=>{_&&tt(_,l,9,N)},G=(_,N)=>{const P=N[1];O(_,N),Q(_)?_.every(J=>J.length<=1)&&P():_.length<=1&&P()},F={mode:o,persisted:r,beforeEnter(_){let N=a;if(!n.isMounted)if(i)N=w||a;else return;_[St]&&_[St](!0);const P=E[v];P&&Wt(e,P)&&P.el[St]&&P.el[St](),O(N,[_])},enter(_){let N=s,P=c,J=u;if(!n.isMounted)if(i)N=T||s,P=x||c,J=A||u;else return;let L=!1;const $=_[il]=le=>{L||(L=!0,le?O(J,[_]):O(P,[_]),F.delayedLeave&&F.delayedLeave(),_[il]=void 0)};N?G(N,[_,$]):$()},leave(_,N){const P=String(e.key);if(_[il]&&_[il](!0),n.isUnmounting)return N();O(d,[_]);let J=!1;const L=_[St]=$=>{J||(J=!0,N(),$?O(b,[_]):O(g,[_]),_[St]=void 0,E[P]===e&&delete E[P])};E[P]=e,f?G(f,[_,L]):L()},clone(_){return hi(_,t,n,l)}};return F}function Gl(e){if(qn(e))return e=$t(e),e.children=null,e}function Eo(e){return qn(e)?e.children?e.children[0]:void 0:e}function pi(e,t){e.shapeFlag&6&&e.component?pi(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function cs(e,t=!1,n){let l=[],i=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function z(e){re(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:l,delay:i=200,timeout:o,suspensible:r=!0,onError:a}=e;let s=null,c,u=0;const d=()=>(u++,s=null,f()),f=()=>{let g;return s||(g=s=t().catch(b=>{if(b=b instanceof Error?b:new Error(String(b)),a)return new Promise((w,T)=>{a(b,()=>w(d()),()=>T(b),u+1)});throw b}).then(b=>g!==s&&s?s:(b&&(b.__esModule||b[Symbol.toStringTag]==="Module")&&(b=b.default),c=b,b)))};return fe({name:"AsyncComponentWrapper",__asyncLoader:f,get __asyncResolved(){return c},setup(){const g=De;if(c)return()=>Jl(c,g);const b=A=>{s=null,Kn(A,g,13,!l)};if(r&&g.suspense||Jn)return f().then(A=>()=>Jl(A,g)).catch(A=>(b(A),()=>l?ie(l,{error:A}):null));const w=de(!1),T=de(),x=de(!!i);return i&&setTimeout(()=>{x.value=!1},i),o!=null&&setTimeout(()=>{if(!w.value&&!T.value){const A=new Error(`Async component timed out after ${o}ms.`);b(A),T.value=A}},o),f().then(()=>{w.value=!0,g.parent&&qn(g.parent.vnode)&&(g.parent.effect.dirty=!0,Ml(g.parent.update))}).catch(A=>{b(A),T.value=A}),()=>{if(w.value&&c)return Jl(c,g);if(T.value&&l)return ie(l,{error:T.value});if(n&&!x.value)return ie(n)}}})}function Jl(e,t){const{ref:n,props:l,children:i,ce:o}=t.vnode,r=ie(e,l,i);return r.ref=n,r.ce=o,delete t.vnode.ce,r}const qn=e=>e.type.__isKeepAlive;function Ec(e,t){us(e,"a",t)}function wc(e,t){us(e,"da",t)}function us(e,t,n=De){const l=e.__wdc||(e.__wdc=()=>{let i=n;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(Fl(t,l,n),n){let i=n.parent;for(;i&&i.parent;)qn(i.parent.vnode)&&xc(l,t,n,i),i=i.parent}}function xc(e,t,n,l){const i=Fl(t,e,l,!0);Vl(()=>{Si(l[t],i)},n)}function Fl(e,t,n=De,l=!1){if(n){const i=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...r)=>{if(n.isUnmounted)return;Xt(),vn(n);const a=tt(t,n,e,r);return Qt(),en(),a});return l?i.unshift(o):i.push(o),o}}const yt=e=>(t,n=De)=>(!Jn||e==="sp")&&Fl(e,(...l)=>t(...l),n),Lc=yt("bm"),Fe=yt("m"),Tc=yt("bu"),Sc=yt("u"),Gn=yt("bum"),Vl=yt("um"),Cc=yt("sp"),Ac=yt("rtg"),Oc=yt("rtc");function Rc(e,t=De){Fl("ec",e,t)}function Mt(e,t,n,l){let i;const o=n;if(Q(e)||me(e)){i=new Array(e.length);for(let r=0,a=e.length;rt(r,a,void 0,o));else{const r=Object.keys(e);i=new Array(r.length);for(let a=0,s=r.length;aLl(t)?!(t.type===Qe||t.type===Ee&&!ds(t.children)):!0)?e:null}const gi=e=>e?xs(e)?Bl(e)||e.proxy:gi(e.parent):null,An=Oe(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>gi(e.parent),$root:e=>gi(e.root),$emit:e=>e.emit,$options:e=>Hi(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,Ml(e.update)}),$nextTick:e=>e.n||(e.n=yn.bind(e.proxy)),$watch:e=>_c.bind(e)}),Yl=(e,t)=>e!==we&&!e.__isScriptSetup&&pe(e,t),Pc={get({_:e},t){const{ctx:n,setupState:l,data:i,props:o,accessCache:r,type:a,appContext:s}=e;let c;if(t[0]!=="$"){const g=r[t];if(g!==void 0)switch(g){case 1:return l[t];case 2:return i[t];case 4:return n[t];case 3:return o[t]}else{if(Yl(l,t))return r[t]=1,l[t];if(i!==we&&pe(i,t))return r[t]=2,i[t];if((c=e.propsOptions[0])&&pe(c,t))return r[t]=3,o[t];if(n!==we&&pe(n,t))return r[t]=4,n[t];vi&&(r[t]=0)}}const u=An[t];let d,f;if(u)return t==="$attrs"&&Ge(e,"get",t),u(e);if((d=a.__cssModules)&&(d=d[t]))return d;if(n!==we&&pe(n,t))return r[t]=4,n[t];if(f=s.config.globalProperties,pe(f,t))return f[t]},set({_:e},t,n){const{data:l,setupState:i,ctx:o}=e;return Yl(i,t)?(i[t]=n,!0):l!==we&&pe(l,t)?(l[t]=n,!0):pe(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:l,appContext:i,propsOptions:o}},r){let a;return!!n[r]||e!==we&&pe(e,r)||Yl(t,r)||(a=o[0])&&pe(a,r)||pe(l,r)||pe(An,r)||pe(i.config.globalProperties,r)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:pe(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function wo(e){return Q(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let vi=!0;function Ic(e){const t=Hi(e),n=e.proxy,l=e.ctx;vi=!1,t.beforeCreate&&xo(t.beforeCreate,e,"bc");const{data:i,computed:o,methods:r,watch:a,provide:s,inject:c,created:u,beforeMount:d,mounted:f,beforeUpdate:g,updated:b,activated:w,deactivated:T,beforeDestroy:x,beforeUnmount:A,destroyed:v,unmounted:E,render:O,renderTracked:G,renderTriggered:F,errorCaptured:_,serverPrefetch:N,expose:P,inheritAttrs:J,components:L,directives:$,filters:le}=t;if(c&&Dc(c,l,null),r)for(const Z in r){const K=r[Z];re(K)&&(l[Z]=K.bind(n))}if(i){const Z=i.call(n,n);ye(Z)&&(e.data=Wn(Z))}if(vi=!0,o)for(const Z in o){const K=o[Z],Re=re(K)?K.bind(n,n):re(K.get)?K.get.bind(n,n):et,Ne=!re(K)&&re(K.set)?K.set.bind(n):et,Ue=j({get:Re,set:Ne});Object.defineProperty(l,Z,{enumerable:!0,configurable:!0,get:()=>Ue.value,set:Ve=>Ue.value=Ve})}if(a)for(const Z in a)fs(a[Z],l,n,Z);if(s){const Z=re(s)?s.call(n):s;Reflect.ownKeys(Z).forEach(K=>{Yt(K,Z[K])})}u&&xo(u,e,"c");function D(Z,K){Q(K)?K.forEach(Re=>Z(Re.bind(n))):K&&Z(K.bind(n))}if(D(Lc,d),D(Fe,f),D(Tc,g),D(Sc,b),D(Ec,w),D(wc,T),D(Rc,_),D(Oc,G),D(Ac,F),D(Gn,A),D(Vl,E),D(Cc,N),Q(P))if(P.length){const Z=e.exposed||(e.exposed={});P.forEach(K=>{Object.defineProperty(Z,K,{get:()=>n[K],set:Re=>n[K]=Re})})}else e.exposed||(e.exposed={});O&&e.render===et&&(e.render=O),J!=null&&(e.inheritAttrs=J),L&&(e.components=L),$&&(e.directives=$)}function Dc(e,t,n=et){Q(e)&&(e=mi(e));for(const l in e){const i=e[l];let o;ye(i)?"default"in i?o=Se(i.from||l,i.default,!0):o=Se(i.from||l):o=Se(i),je(o)?Object.defineProperty(t,l,{enumerable:!0,configurable:!0,get:()=>o.value,set:r=>o.value=r}):t[l]=o}}function xo(e,t,n){tt(Q(e)?e.map(l=>l.bind(t.proxy)):e.bind(t.proxy),t,n)}function fs(e,t,n,l){const i=l.includes(".")?rs(n,l):()=>n[l];if(me(e)){const o=t[e];re(o)&&qe(i,o)}else if(re(e))qe(i,e.bind(n));else if(ye(e))if(Q(e))e.forEach(o=>fs(o,t,n,l));else{const o=re(e.handler)?e.handler.bind(n):t[e.handler];re(o)&&qe(i,o,e)}}function Hi(e){const t=e.type,{mixins:n,extends:l}=t,{mixins:i,optionsCache:o,config:{optionMergeStrategies:r}}=e.appContext,a=o.get(t);let s;return a?s=a:!i.length&&!n&&!l?s=t:(s={},i.length&&i.forEach(c=>El(s,c,r,!0)),El(s,t,r)),ye(t)&&o.set(t,s),s}function El(e,t,n,l=!1){const{mixins:i,extends:o}=t;o&&El(e,o,n,!0),i&&i.forEach(r=>El(e,r,n,!0));for(const r in t)if(!(l&&r==="expose")){const a=Nc[r]||n&&n[r];e[r]=a?a(e[r],t[r]):t[r]}return e}const Nc={data:Lo,props:To,emits:To,methods:Sn,computed:Sn,beforeCreate:Be,created:Be,beforeMount:Be,mounted:Be,beforeUpdate:Be,updated:Be,beforeDestroy:Be,beforeUnmount:Be,destroyed:Be,unmounted:Be,activated:Be,deactivated:Be,errorCaptured:Be,serverPrefetch:Be,components:Sn,directives:Sn,watch:$c,provide:Lo,inject:Mc};function Lo(e,t){return t?e?function(){return Oe(re(e)?e.call(this,this):e,re(t)?t.call(this,this):t)}:t:e}function Mc(e,t){return Sn(mi(e),mi(t))}function mi(e){if(Q(e)){const t={};for(let n=0;n1)return n&&re(t)?t.call(l&&l.proxy):t}}function Hc(e,t,n,l=!1){const i={},o={};gl(o,Hl,1),e.propsDefaults=Object.create(null),ps(e,t,i,o);for(const r in e.propsOptions[0])r in i||(i[r]=void 0);n?e.props=l?i:Kr(i):e.type.props?e.props=i:e.props=o,e.attrs=o}function jc(e,t,n,l){const{props:i,attrs:o,vnode:{patchFlag:r}}=e,a=ve(i),[s]=e.propsOptions;let c=!1;if((l||r>0)&&!(r&16)){if(r&8){const u=e.vnode.dynamicProps;for(let d=0;d{s=!0;const[f,g]=gs(d,t,!0);Oe(r,f),g&&a.push(...g)};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!s)return ye(e)&&l.set(e,an),an;if(Q(o))for(let u=0;u-1,g[1]=w<0||b-1||pe(g,"default"))&&a.push(d)}}}const c=[r,a];return ye(e)&&l.set(e,c),c}function So(e){return e[0]!=="$"}function Co(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function Ao(e,t){return Co(e)===Co(t)}function Oo(e,t){return Q(t)?t.findIndex(n=>Ao(n,e)):re(t)&&Ao(t,e)?0:-1}const vs=e=>e[0]==="_"||e==="$stable",ji=e=>Q(e)?e.map(lt):[lt(e)],Bc=(e,t,n)=>{if(t._n)return t;const l=Me((...i)=>ji(t(...i)),n);return l._c=!1,l},ms=(e,t,n)=>{const l=e._ctx;for(const i in e){if(vs(i))continue;const o=e[i];if(re(o))t[i]=Bc(i,o,l);else if(o!=null){const r=ji(o);t[i]=()=>r}}},_s=(e,t)=>{const n=ji(t);e.slots.default=()=>n},zc=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=ve(t),gl(t,"_",n)):ms(t,e.slots={})}else e.slots={},t&&_s(e,t);gl(e.slots,Hl,1)},Uc=(e,t,n)=>{const{vnode:l,slots:i}=e;let o=!0,r=we;if(l.shapeFlag&32){const a=t._;a?n&&a===1?o=!1:(Oe(i,t),!n&&a===1&&delete i._):(o=!t.$stable,ms(t,i)),r=t}else t&&(_s(e,t),r={default:1});if(o)for(const a in i)!vs(a)&&r[a]==null&&delete i[a]};function xl(e,t,n,l,i=!1){if(Q(e)){e.forEach((f,g)=>xl(f,t&&(Q(t)?t[g]:t),n,l,i));return}if(fn(l)&&!i)return;const o=l.shapeFlag&4?Bl(l.component)||l.component.proxy:l.el,r=i?null:o,{i:a,r:s}=e,c=t&&t.r,u=a.refs===we?a.refs={}:a.refs,d=a.setupState;if(c!=null&&c!==s&&(me(c)?(u[c]=null,pe(d,c)&&(d[c]=null)):je(c)&&(c.value=null)),re(s))Pt(s,a,12,[r,u]);else{const f=me(s),g=je(s);if(f||g){const b=()=>{if(e.f){const w=f?pe(d,s)?d[s]:u[s]:s.value;i?Q(w)&&Si(w,o):Q(w)?w.includes(o)||w.push(o):f?(u[s]=[o],pe(d,s)&&(d[s]=u[s])):(s.value=[o],e.k&&(u[e.k]=s.value))}else f?(u[s]=r,pe(d,s)&&(d[s]=r)):g&&(s.value=r,e.k&&(u[e.k]=r))};r?(b.id=-1,We(b,n)):b()}}}let xt=!1;const Wc=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Kc=e=>e.namespaceURI.includes("MathML"),ol=e=>{if(Wc(e))return"svg";if(Kc(e))return"mathml"},rl=e=>e.nodeType===8;function qc(e){const{mt:t,p:n,o:{patchProp:l,createText:i,nextSibling:o,parentNode:r,remove:a,insert:s,createComment:c}}=e,u=(v,E)=>{if(!E.hasChildNodes()){n(null,v,E),bl(),E._vnode=v;return}xt=!1,d(E.firstChild,v,null,null,null),bl(),E._vnode=v,xt&&console.error("Hydration completed but contains mismatches.")},d=(v,E,O,G,F,_=!1)=>{const N=rl(v)&&v.data==="[",P=()=>w(v,E,O,G,F,N),{type:J,ref:L,shapeFlag:$,patchFlag:le}=E;let se=v.nodeType;E.el=v,le===-2&&(_=!1,E.dynamicChildren=null);let D=null;switch(J){case gn:se!==3?E.children===""?(s(E.el=i(""),r(v),v),D=v):D=P():(v.data!==E.children&&(xt=!0,v.data=E.children),D=o(v));break;case Qe:A(v)?(D=o(v),x(E.el=v.content.firstChild,v,O)):se!==8||N?D=P():D=o(v);break;case On:if(N&&(v=o(v),se=v.nodeType),se===1||se===3){D=v;const Z=!E.children.length;for(let K=0;K{_=_||!!E.dynamicChildren;const{type:N,props:P,patchFlag:J,shapeFlag:L,dirs:$,transition:le}=E,se=N==="input"||N==="option";if(se||J!==-1){$&&ct(E,null,O,"created");let D=!1;if(A(v)){D=bs(G,le)&&O&&O.vnode.props&&O.vnode.props.appear;const K=v.content.firstChild;D&&le.beforeEnter(K),x(K,v,O),E.el=v=K}if(L&16&&!(P&&(P.innerHTML||P.textContent))){let K=g(v.firstChild,E,v,O,G,F,_);for(;K;){xt=!0;const Re=K;K=K.nextSibling,a(Re)}}else L&8&&v.textContent!==E.children&&(xt=!0,v.textContent=E.children);if(P)if(se||!_||J&48)for(const K in P)(se&&(K.endsWith("value")||K==="indeterminate")||Bn(K)&&!Cn(K)||K[0]===".")&&l(v,K,null,P[K],void 0,void 0,O);else P.onClick&&l(v,"onClick",null,P.onClick,void 0,void 0,O);let Z;(Z=P&&P.onVnodeBeforeMount)&&Xe(Z,O,E),$&&ct(E,null,O,"beforeMount"),((Z=P&&P.onVnodeMounted)||$||D)&&is(()=>{Z&&Xe(Z,O,E),D&&le.enter(v),$&&ct(E,null,O,"mounted")},G)}return v.nextSibling},g=(v,E,O,G,F,_,N)=>{N=N||!!E.dynamicChildren;const P=E.children,J=P.length;for(let L=0;L{const{slotScopeIds:N}=E;N&&(F=F?F.concat(N):N);const P=r(v),J=g(o(v),E,P,O,G,F,_);return J&&rl(J)&&J.data==="]"?o(E.anchor=J):(xt=!0,s(E.anchor=c("]"),P,J),J)},w=(v,E,O,G,F,_)=>{if(xt=!0,E.el=null,_){const J=T(v);for(;;){const L=o(v);if(L&&L!==J)a(L);else break}}const N=o(v),P=r(v);return a(v),n(null,E,P,N,O,G,ol(P),F),N},T=(v,E="[",O="]")=>{let G=0;for(;v;)if(v=o(v),v&&rl(v)&&(v.data===E&&G++,v.data===O)){if(G===0)return o(v);G--}return v},x=(v,E,O)=>{const G=E.parentNode;G&&G.replaceChild(v,E);let F=O;for(;F;)F.vnode.el===E&&(F.vnode.el=F.subTree.el=v),F=F.parent},A=v=>v.nodeType===1&&v.tagName.toLowerCase()==="template";return[u,d]}const We=is;function Gc(e){return Jc(e,qc)}function Jc(e,t){const n=Rr();n.__VUE__=!0;const{insert:l,remove:i,patchProp:o,createElement:r,createText:a,createComment:s,setText:c,setElementText:u,parentNode:d,nextSibling:f,setScopeId:g=et,insertStaticContent:b}=e,w=(h,p,m,k=null,C=null,R=null,B=void 0,M=null,H=!!p.dynamicChildren)=>{if(h===p)return;h&&!Wt(h,p)&&(k=S(h),Ve(h,C,R,!0),h=null),p.patchFlag===-2&&(H=!1,p.dynamicChildren=null);const{type:I,ref:q,shapeFlag:te}=p;switch(I){case gn:T(h,p,m,k);break;case Qe:x(h,p,m,k);break;case On:h==null&&A(p,m,k,B);break;case Ee:L(h,p,m,k,C,R,B,M,H);break;default:te&1?O(h,p,m,k,C,R,B,M,H):te&6?$(h,p,m,k,C,R,B,M,H):(te&64||te&128)&&I.process(h,p,m,k,C,R,B,M,H,V)}q!=null&&C&&xl(q,h&&h.ref,R,p||h,!p)},T=(h,p,m,k)=>{if(h==null)l(p.el=a(p.children),m,k);else{const C=p.el=h.el;p.children!==h.children&&c(C,p.children)}},x=(h,p,m,k)=>{h==null?l(p.el=s(p.children||""),m,k):p.el=h.el},A=(h,p,m,k)=>{[h.el,h.anchor]=b(h.children,p,m,k,h.el,h.anchor)},v=({el:h,anchor:p},m,k)=>{let C;for(;h&&h!==p;)C=f(h),l(h,m,k),h=C;l(p,m,k)},E=({el:h,anchor:p})=>{let m;for(;h&&h!==p;)m=f(h),i(h),h=m;i(p)},O=(h,p,m,k,C,R,B,M,H)=>{p.type==="svg"?B="svg":p.type==="math"&&(B="mathml"),h==null?G(p,m,k,C,R,B,M,H):N(h,p,C,R,B,M,H)},G=(h,p,m,k,C,R,B,M)=>{let H,I;const{props:q,shapeFlag:te,transition:X,dirs:oe}=h;if(H=h.el=r(h.type,R,q&&q.is,q),te&8?u(H,h.children):te&16&&_(h.children,H,null,k,C,Ql(h,R),B,M),oe&&ct(h,null,k,"created"),F(H,h,h.scopeId,B,k),q){for(const be in q)be!=="value"&&!Cn(be)&&o(H,be,null,q[be],R,h.children,k,C,Pe);"value"in q&&o(H,"value",null,q.value,R),(I=q.onVnodeBeforeMount)&&Xe(I,k,h)}oe&&ct(h,null,k,"beforeMount");const ae=bs(C,X);ae&&X.beforeEnter(H),l(H,p,m),((I=q&&q.onVnodeMounted)||ae||oe)&&We(()=>{I&&Xe(I,k,h),ae&&X.enter(H),oe&&ct(h,null,k,"mounted")},C)},F=(h,p,m,k,C)=>{if(m&&g(h,m),k)for(let R=0;R{for(let I=H;I{const M=p.el=h.el;let{patchFlag:H,dynamicChildren:I,dirs:q}=p;H|=h.patchFlag&16;const te=h.props||we,X=p.props||we;let oe;if(m&&Ht(m,!1),(oe=X.onVnodeBeforeUpdate)&&Xe(oe,m,p,h),q&&ct(p,h,m,"beforeUpdate"),m&&Ht(m,!0),I?P(h.dynamicChildren,I,M,m,k,Ql(p,C),R):B||K(h,p,M,null,m,k,Ql(p,C),R,!1),H>0){if(H&16)J(M,p,te,X,m,k,C);else if(H&2&&te.class!==X.class&&o(M,"class",null,X.class,C),H&4&&o(M,"style",te.style,X.style,C),H&8){const ae=p.dynamicProps;for(let be=0;be{oe&&Xe(oe,m,p,h),q&&ct(p,h,m,"updated")},k)},P=(h,p,m,k,C,R,B)=>{for(let M=0;M{if(m!==k){if(m!==we)for(const M in m)!Cn(M)&&!(M in k)&&o(h,M,m[M],null,B,p.children,C,R,Pe);for(const M in k){if(Cn(M))continue;const H=k[M],I=m[M];H!==I&&M!=="value"&&o(h,M,I,H,B,p.children,C,R,Pe)}"value"in k&&o(h,"value",m.value,k.value,B)}},L=(h,p,m,k,C,R,B,M,H)=>{const I=p.el=h?h.el:a(""),q=p.anchor=h?h.anchor:a("");let{patchFlag:te,dynamicChildren:X,slotScopeIds:oe}=p;oe&&(M=M?M.concat(oe):oe),h==null?(l(I,m,k),l(q,m,k),_(p.children,m,q,C,R,B,M,H)):te>0&&te&64&&X&&h.dynamicChildren?(P(h.dynamicChildren,X,m,C,R,B,M),(p.key!=null||C&&p===C.subTree)&&ys(h,p,!0)):K(h,p,m,q,C,R,B,M,H)},$=(h,p,m,k,C,R,B,M,H)=>{p.slotScopeIds=M,h==null?p.shapeFlag&512?C.ctx.activate(p,m,k,B,H):le(p,m,k,C,R,B,H):se(h,p,H)},le=(h,p,m,k,C,R,B)=>{const M=h.component=iu(h,k,C);if(qn(h)&&(M.ctx.renderer=V),ou(M),M.asyncDep){if(C&&C.registerDep(M,D),!h.el){const H=M.subTree=ie(Qe);x(null,H,p,m)}}else D(M,h,p,m,C,R,B)},se=(h,p,m)=>{const k=p.component=h.component;if(dc(h,p,m))if(k.asyncDep&&!k.asyncResolved){Z(k,p,m);return}else k.next=p,oc(k.update),k.effect.dirty=!0,k.update();else p.el=h.el,k.vnode=p},D=(h,p,m,k,C,R,B)=>{const M=()=>{if(h.isMounted){let{next:q,bu:te,u:X,parent:oe,vnode:ae}=h;{const ln=ks(h);if(ln){q&&(q.el=ae.el,Z(h,q,B)),ln.asyncDep.then(()=>{h.isUnmounted||M()});return}}let be=q,xe;Ht(h,!1),q?(q.el=ae.el,Z(h,q,B)):q=ae,te&&fl(te),(xe=q.props&&q.props.onVnodeBeforeUpdate)&&Xe(xe,oe,q,ae),Ht(h,!0);const Ie=ql(h),nt=h.subTree;h.subTree=Ie,w(nt,Ie,d(nt.el),S(nt),h,C,R),q.el=Ie.el,be===null&&fc(h,Ie.el),X&&We(X,C),(xe=q.props&&q.props.onVnodeUpdated)&&We(()=>Xe(xe,oe,q,ae),C)}else{let q;const{el:te,props:X}=p,{bm:oe,m:ae,parent:be}=h,xe=fn(p);if(Ht(h,!1),oe&&fl(oe),!xe&&(q=X&&X.onVnodeBeforeMount)&&Xe(q,be,p),Ht(h,!0),te&&ue){const Ie=()=>{h.subTree=ql(h),ue(te,h.subTree,h,C,null)};xe?p.type.__asyncLoader().then(()=>!h.isUnmounted&&Ie()):Ie()}else{const Ie=h.subTree=ql(h);w(null,Ie,m,k,h,C,R),p.el=Ie.el}if(ae&&We(ae,C),!xe&&(q=X&&X.onVnodeMounted)){const Ie=p;We(()=>Xe(q,be,Ie),C)}(p.shapeFlag&256||be&&fn(be.vnode)&&be.vnode.shapeFlag&256)&&h.a&&We(h.a,C),h.isMounted=!0,p=m=k=null}},H=h.effect=new Ai(M,et,()=>Ml(I),h.scope),I=h.update=()=>{H.dirty&&H.run()};I.id=h.uid,Ht(h,!0),I()},Z=(h,p,m)=>{p.component=h;const k=h.vnode.props;h.vnode=p,h.next=null,jc(h,p.props,k,m),Uc(h,p.children,m),Xt(),bo(h),en()},K=(h,p,m,k,C,R,B,M,H=!1)=>{const I=h&&h.children,q=h?h.shapeFlag:0,te=p.children,{patchFlag:X,shapeFlag:oe}=p;if(X>0){if(X&128){Ne(I,te,m,k,C,R,B,M,H);return}else if(X&256){Re(I,te,m,k,C,R,B,M,H);return}}oe&8?(q&16&&Pe(I,C,R),te!==I&&u(m,te)):q&16?oe&16?Ne(I,te,m,k,C,R,B,M,H):Pe(I,C,R,!0):(q&8&&u(m,""),oe&16&&_(te,m,k,C,R,B,M,H))},Re=(h,p,m,k,C,R,B,M,H)=>{h=h||an,p=p||an;const I=h.length,q=p.length,te=Math.min(I,q);let X;for(X=0;Xq?Pe(h,C,R,!0,!1,te):_(p,m,k,C,R,B,M,H,te)},Ne=(h,p,m,k,C,R,B,M,H)=>{let I=0;const q=p.length;let te=h.length-1,X=q-1;for(;I<=te&&I<=X;){const oe=h[I],ae=p[I]=H?Ct(p[I]):lt(p[I]);if(Wt(oe,ae))w(oe,ae,m,null,C,R,B,M,H);else break;I++}for(;I<=te&&I<=X;){const oe=h[te],ae=p[X]=H?Ct(p[X]):lt(p[X]);if(Wt(oe,ae))w(oe,ae,m,null,C,R,B,M,H);else break;te--,X--}if(I>te){if(I<=X){const oe=X+1,ae=oeX)for(;I<=te;)Ve(h[I],C,R,!0),I++;else{const oe=I,ae=I,be=new Map;for(I=ae;I<=X;I++){const Je=p[I]=H?Ct(p[I]):lt(p[I]);Je.key!=null&&be.set(Je.key,I)}let xe,Ie=0;const nt=X-ae+1;let ln=!1,ro=0;const En=new Array(nt);for(I=0;I=nt){Ve(Je,C,R,!0);continue}let at;if(Je.key!=null)at=be.get(Je.key);else for(xe=ae;xe<=X;xe++)if(En[xe-ae]===0&&Wt(Je,p[xe])){at=xe;break}at===void 0?Ve(Je,C,R,!0):(En[at-ae]=I+1,at>=ro?ro=at:ln=!0,w(Je,p[at],m,null,C,R,B,M,H),Ie++)}const so=ln?Yc(En):an;for(xe=so.length-1,I=nt-1;I>=0;I--){const Je=ae+I,at=p[Je],ao=Je+1{const{el:R,type:B,transition:M,children:H,shapeFlag:I}=h;if(I&6){Ue(h.component.subTree,p,m,k);return}if(I&128){h.suspense.move(p,m,k);return}if(I&64){B.move(h,p,m,V);return}if(B===Ee){l(R,p,m);for(let te=0;teM.enter(R),C);else{const{leave:te,delayLeave:X,afterLeave:oe}=M,ae=()=>l(R,p,m),be=()=>{te(R,()=>{ae(),oe&&oe()})};X?X(R,ae,be):be()}else l(R,p,m)},Ve=(h,p,m,k=!1,C=!1)=>{const{type:R,props:B,ref:M,children:H,dynamicChildren:I,shapeFlag:q,patchFlag:te,dirs:X}=h;if(M!=null&&xl(M,null,m,h,!0),q&256){p.ctx.deactivate(h);return}const oe=q&1&&X,ae=!fn(h);let be;if(ae&&(be=B&&B.onVnodeBeforeUnmount)&&Xe(be,p,h),q&6)st(h.component,m,k);else{if(q&128){h.suspense.unmount(m,k);return}oe&&ct(h,null,p,"beforeUnmount"),q&64?h.type.remove(h,p,m,C,V,k):I&&(R!==Ee||te>0&&te&64)?Pe(I,p,m,!1,!0):(R===Ee&&te&384||!C&&q&16)&&Pe(H,p,m),k&&kt(h)}(ae&&(be=B&&B.onVnodeUnmounted)||oe)&&We(()=>{be&&Xe(be,p,h),oe&&ct(h,null,p,"unmounted")},m)},kt=h=>{const{type:p,el:m,anchor:k,transition:C}=h;if(p===Ee){Et(m,k);return}if(p===On){E(h);return}const R=()=>{i(m),C&&!C.persisted&&C.afterLeave&&C.afterLeave()};if(h.shapeFlag&1&&C&&!C.persisted){const{leave:B,delayLeave:M}=C,H=()=>B(m,R);M?M(h.el,R,H):H()}else R()},Et=(h,p)=>{let m;for(;h!==p;)m=f(h),i(h),h=m;i(p)},st=(h,p,m)=>{const{bum:k,scope:C,update:R,subTree:B,um:M}=h;k&&fl(k),C.stop(),R&&(R.active=!1,Ve(B,h,p,m)),M&&We(M,p),We(()=>{h.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&h.asyncDep&&!h.asyncResolved&&h.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},Pe=(h,p,m,k=!1,C=!1,R=0)=>{for(let B=R;Bh.shapeFlag&6?S(h.component.subTree):h.shapeFlag&128?h.suspense.next():f(h.anchor||h.el),W=(h,p,m)=>{h==null?p._vnode&&Ve(p._vnode,null,null,!0):w(p._vnode||null,h,p,null,null,null,m),bo(),bl(),p._vnode=h},V={p:w,um:Ve,m:Ue,r:kt,mt:le,mc:_,pc:K,pbc:P,n:S,o:e};let Y,ue;return t&&([Y,ue]=t(V)),{render:W,hydrate:Y,createApp:Vc(W,Y)}}function Ql({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Ht({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function bs(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ys(e,t,n=!1){const l=e.children,i=t.children;if(Q(l)&&Q(i))for(let o=0;o>1,e[n[a]]0&&(t[l]=n[o-1]),n[o]=l)}}for(o=n.length,r=n[o-1];o-- >0;)n[o]=r,r=t[r];return n}function ks(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:ks(t)}const Qc=e=>e.__isTeleport,Ee=Symbol.for("v-fgt"),gn=Symbol.for("v-txt"),Qe=Symbol.for("v-cmt"),On=Symbol.for("v-stc"),Rn=[];let it=null;function U(e=!1){Rn.push(it=e?null:[])}function Zc(){Rn.pop(),it=Rn[Rn.length-1]||null}let $n=1;function Ro(e){$n+=e}function Es(e){return e.dynamicChildren=$n>0?it||an:null,Zc(),$n>0&&it&&it.push(e),e}function ee(e,t,n,l,i,o){return Es(ge(e,t,n,l,i,o,!0))}function Ce(e,t,n,l,i){return Es(ie(e,t,n,l,i,!0))}function Ll(e){return e?e.__v_isVNode===!0:!1}function Wt(e,t){return e.type===t.type&&e.key===t.key}const Hl="__vInternal",ws=({key:e})=>e??null,hl=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?me(e)||je(e)||re(e)?{i:$e,r:e,k:t,f:!!n}:e:null);function ge(e,t=null,n=null,l=0,i=null,o=e===Ee?0:1,r=!1,a=!1){const s={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ws(t),ref:t&&hl(t),scopeId:ns,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:l,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:$e};return a?(Bi(s,n),o&128&&e.normalize(s)):n&&(s.shapeFlag|=me(n)?8:16),$n>0&&!r&&it&&(s.patchFlag>0||o&6)&&s.patchFlag!==32&&it.push(s),s}const ie=Xc;function Xc(e,t=null,n=null,l=0,i=null,o=!1){if((!e||e===hc)&&(e=Qe),Ll(e)){const a=$t(e,t,!0);return n&&Bi(a,n),$n>0&&!o&&it&&(a.shapeFlag&6?it[it.indexOf(e)]=a:it.push(a)),a.patchFlag|=-2,a}if(uu(e)&&(e=e.__vccOpts),t){t=eu(t);let{class:a,style:s}=t;a&&!me(a)&&(t.class=Ke(a)),ye(s)&&(qr(s)&&!Q(s)&&(s=Oe({},s)),t.style=Un(s))}const r=me(e)?1:gc(e)?128:Qc(e)?64:ye(e)?4:re(e)?2:0;return ge(e,t,n,l,i,r,o,!0)}function eu(e){return e?qr(e)||Hl in e?Oe({},e):e:null}function $t(e,t,n=!1){const{props:l,ref:i,patchFlag:o,children:r}=e,a=t?bi(l||{},t):l;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:a,key:a&&ws(a),ref:t&&t.ref?n&&i?Q(i)?i.concat(hl(t)):[i,hl(t)]:hl(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:r,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Ee?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&$t(e.ssContent),ssFallback:e.ssFallback&&$t(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Ft(e=" ",t=0){return ie(gn,null,e,t)}function tu(e,t){const n=ie(On,null,e);return n.staticCount=t,n}function Te(e="",t=!1){return t?(U(),Ce(Qe,null,e)):ie(Qe,null,e)}function lt(e){return e==null||typeof e=="boolean"?ie(Qe):Q(e)?ie(Ee,null,e.slice()):typeof e=="object"?Ct(e):ie(gn,null,String(e))}function Ct(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:$t(e)}function Bi(e,t){let n=0;const{shapeFlag:l}=e;if(t==null)t=null;else if(Q(t))n=16;else if(typeof t=="object")if(l&65){const i=t.default;i&&(i._c&&(i._d=!1),Bi(e,i()),i._c&&(i._d=!0));return}else{n=32;const i=t._;!i&&!(Hl in t)?t._ctx=$e:i===3&&$e&&($e.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else re(t)?(t={default:t,_ctx:$e},n=32):(t=String(t),l&64?(n=16,t=[Ft(t)]):n=8);e.children=t,e.shapeFlag|=n}function bi(...e){const t={};for(let n=0;nDe||$e;let zi,yi;{const e=Rr(),t=(n,l)=>{let i;return(i=e[n])||(i=e[n]=[]),i.push(l),o=>{i.length>1?i.forEach(r=>r(o)):i[0](o)}};zi=t("__VUE_INSTANCE_SETTERS__",n=>De=n),yi=t("__VUE_SSR_SETTERS__",n=>Jn=n)}const vn=e=>{zi(e),e.scope.on()},Qt=()=>{De&&De.scope.off(),zi(null)};function xs(e){return e.vnode.shapeFlag&4}let Jn=!1;function ou(e,t=!1){t&&yi(t);const{props:n,children:l}=e.vnode,i=xs(e);Hc(e,n,i,t),zc(e,l);const o=i?ru(e,t):void 0;return t&&yi(!1),o}function ru(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=Gr(new Proxy(e.ctx,Pc));const{setup:l}=n;if(l){const i=e.setupContext=l.length>1?au(e):null;vn(e),Xt();const o=Pt(l,e,0,[e.props,i]);if(en(),Qt(),Cr(o)){if(o.then(Qt,Qt),t)return o.then(r=>{Po(e,r,t)}).catch(r=>{Kn(r,e,0)});e.asyncDep=o}else Po(e,o,t)}else Ls(e,t)}function Po(e,t,n){re(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ye(t)&&(e.setupState=Qr(t)),Ls(e,n)}let Io;function Ls(e,t,n){const l=e.type;if(!e.render){if(!t&&Io&&!l.render){const i=l.template||Hi(e).template;if(i){const{isCustomElement:o,compilerOptions:r}=e.appContext.config,{delimiters:a,compilerOptions:s}=l,c=Oe(Oe({isCustomElement:o,delimiters:a},r),s);l.render=Io(i,c)}}e.render=l.render||et}{vn(e),Xt();try{Ic(e)}finally{en(),Qt()}}}function su(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return Ge(e,"get","$attrs"),t[n]}}))}function au(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return su(e)},slots:e.slots,emit:e.emit,expose:t}}function Bl(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Qr(Gr(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in An)return An[n](e)},has(t,n){return n in t||n in An}}))}function cu(e,t=!0){return re(e)?e.displayName||e.name:e.name||t&&e.__name}function uu(e){return re(e)&&"__vccOpts"in e}const j=(e,t)=>Ya(e,t,Jn);function ce(e,t,n){const l=arguments.length;return l===2?ye(t)&&!Q(t)?Ll(t)?ie(e,null,[t]):ie(e,t):ie(e,null,t):(l>3?n=Array.prototype.slice.call(arguments,2):l===3&&Ll(n)&&(n=[n]),ie(e,t,n))}const du="3.4.4",fu="http://www.w3.org/2000/svg",hu="http://www.w3.org/1998/Math/MathML",At=typeof document<"u"?document:null,Do=At&&At.createElement("template"),pu={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,l)=>{const i=t==="svg"?At.createElementNS(fu,e):t==="mathml"?At.createElementNS(hu,e):At.createElement(e,n?{is:n}:void 0);return e==="select"&&l&&l.multiple!=null&&i.setAttribute("multiple",l.multiple),i},createText:e=>At.createTextNode(e),createComment:e=>At.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>At.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,l,i,o){const r=n?n.previousSibling:t.lastChild;if(i&&(i===o||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),n),!(i===o||!(i=i.nextSibling)););else{Do.innerHTML=l==="svg"?`${e}`:l==="mathml"?`${e}`:e;const a=Do.content;if(l==="svg"||l==="mathml"){const s=a.firstChild;for(;s.firstChild;)a.appendChild(s.firstChild);a.removeChild(s)}t.insertBefore(a,n)}return[r?r.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Lt="transition",wn="animation",Fn=Symbol("_vtc"),Yn=(e,{slots:t})=>ce(kc,gu(e),t);Yn.displayName="Transition";const Ts={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};Yn.props=Oe({},ss,Ts);const jt=(e,t=[])=>{Q(e)?e.forEach(n=>n(...t)):e&&e(...t)},No=e=>e?Q(e)?e.some(t=>t.length>1):e.length>1:!1;function gu(e){const t={};for(const L in e)L in Ts||(t[L]=e[L]);if(e.css===!1)return t;const{name:n="v",type:l,duration:i,enterFromClass:o=`${n}-enter-from`,enterActiveClass:r=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:s=o,appearActiveClass:c=r,appearToClass:u=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:g=`${n}-leave-to`}=e,b=vu(i),w=b&&b[0],T=b&&b[1],{onBeforeEnter:x,onEnter:A,onEnterCancelled:v,onLeave:E,onLeaveCancelled:O,onBeforeAppear:G=x,onAppear:F=A,onAppearCancelled:_=v}=t,N=(L,$,le)=>{Bt(L,$?u:a),Bt(L,$?c:r),le&&le()},P=(L,$)=>{L._isLeaving=!1,Bt(L,d),Bt(L,g),Bt(L,f),$&&$()},J=L=>($,le)=>{const se=L?F:A,D=()=>N($,L,le);jt(se,[$,D]),Mo(()=>{Bt($,L?s:o),Tt($,L?u:a),No(se)||$o($,l,w,D)})};return Oe(t,{onBeforeEnter(L){jt(x,[L]),Tt(L,o),Tt(L,r)},onBeforeAppear(L){jt(G,[L]),Tt(L,s),Tt(L,c)},onEnter:J(!1),onAppear:J(!0),onLeave(L,$){L._isLeaving=!0;const le=()=>P(L,$);Tt(L,d),bu(),Tt(L,f),Mo(()=>{L._isLeaving&&(Bt(L,d),Tt(L,g),No(E)||$o(L,l,T,le))}),jt(E,[L,le])},onEnterCancelled(L){N(L,!1),jt(v,[L])},onAppearCancelled(L){N(L,!0),jt(_,[L])},onLeaveCancelled(L){P(L),jt(O,[L])}})}function vu(e){if(e==null)return null;if(ye(e))return[Zl(e.enter),Zl(e.leave)];{const t=Zl(e);return[t,t]}}function Zl(e){return _a(e)}function Tt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Fn]||(e[Fn]=new Set)).add(t)}function Bt(e,t){t.split(/\s+/).forEach(l=>l&&e.classList.remove(l));const n=e[Fn];n&&(n.delete(t),n.size||(e[Fn]=void 0))}function Mo(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let mu=0;function $o(e,t,n,l){const i=e._endId=++mu,o=()=>{i===e._endId&&l()};if(n)return setTimeout(o,n);const{type:r,timeout:a,propCount:s}=_u(e,t);if(!r)return l();const c=r+"end";let u=0;const d=()=>{e.removeEventListener(c,f),o()},f=g=>{g.target===e&&++u>=s&&d()};setTimeout(()=>{u(n[b]||"").split(", "),i=l(`${Lt}Delay`),o=l(`${Lt}Duration`),r=Fo(i,o),a=l(`${wn}Delay`),s=l(`${wn}Duration`),c=Fo(a,s);let u=null,d=0,f=0;t===Lt?r>0&&(u=Lt,d=r,f=o.length):t===wn?c>0&&(u=wn,d=c,f=s.length):(d=Math.max(r,c),u=d>0?r>c?Lt:wn:null,f=u?u===Lt?o.length:s.length:0);const g=u===Lt&&/\b(transform|all)(,|$)/.test(l(`${Lt}Property`).toString());return{type:u,timeout:d,propCount:f,hasTransform:g}}function Fo(e,t){for(;e.lengthVo(n)+Vo(e[l])))}function Vo(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function bu(){return document.body.offsetHeight}function yu(e,t,n){const l=e[Fn];l&&(t=(t?[t,...l]:[...l]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Ui=Symbol("_vod"),Tl={beforeMount(e,{value:t},{transition:n}){e[Ui]=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):xn(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:l}){!t!=!n&&(l?t?(l.beforeEnter(e),xn(e,!0),l.enter(e)):l.leave(e,()=>{xn(e,!1)}):xn(e,t))},beforeUnmount(e,{value:t}){xn(e,t)}};function xn(e,t){e.style.display=t?e[Ui]:"none"}const ku=Symbol("");function Eu(e,t,n){const l=e.style,i=me(n);if(n&&!i){if(t&&!me(t))for(const o in t)n[o]==null&&ki(l,o,"");for(const o in n)ki(l,o,n[o])}else{const o=l.display;if(i){if(t!==n){const r=l[ku];r&&(n+=";"+r),l.cssText=n}}else t&&e.removeAttribute("style");Ui in e&&(l.display=o)}}const Ho=/\s*!important$/;function ki(e,t,n){if(Q(n))n.forEach(l=>ki(e,t,l));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const l=wu(e,t);Ho.test(n)?e.setProperty(Zt(l),n.replace(Ho,""),"important"):e[l]=n}}const jo=["Webkit","Moz","ms"],Xl={};function wu(e,t){const n=Xl[t];if(n)return n;let l=dt(t);if(l!=="filter"&&l in e)return Xl[t]=l;l=Pl(l);for(let i=0;iei||(Au.then(()=>ei=0),ei=Date.now());function Ru(e,t){const n=l=>{if(!l._vts)l._vts=Date.now();else if(l._vts<=n.attached)return;tt(Pu(l,n.value),t,5,[l])};return n.value=e,n.attached=Ou(),n}function Pu(e,t){if(Q(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(l=>i=>!i._stopped&&l&&l(i))}else return t}const Wo=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Iu=(e,t,n,l,i,o,r,a,s)=>{const c=i==="svg";t==="class"?yu(e,l,c):t==="style"?Eu(e,n,l):Bn(t)?Ti(t)||Su(e,t,n,l,r):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Du(e,t,l,c))?Lu(e,t,l,o,r,a,s):(t==="true-value"?e._trueValue=l:t==="false-value"&&(e._falseValue=l),xu(e,t,l,c))};function Du(e,t,n,l){if(l)return!!(t==="innerHTML"||t==="textContent"||t in e&&Wo(t)&&re(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return Wo(t)&&me(n)?!1:t in e}const Sl=e=>{const t=e.props["onUpdate:modelValue"]||!1;return Q(t)?n=>fl(t,n):t};function Nu(e){e.target.composing=!0}function Ko(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const hn=Symbol("_assign"),bv={created(e,{modifiers:{lazy:t,trim:n,number:l}},i){e[hn]=Sl(i);const o=l||i.props&&i.props.type==="number";Kt(e,t?"change":"input",r=>{if(r.target.composing)return;let a=e.value;n&&(a=a.trim()),o&&(a=ai(a)),e[hn](a)}),n&&Kt(e,"change",()=>{e.value=e.value.trim()}),t||(Kt(e,"compositionstart",Nu),Kt(e,"compositionend",Ko),Kt(e,"change",Ko))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:l,number:i}},o){if(e[hn]=Sl(o),e.composing)return;const r=i||e.type==="number"?ai(e.value):e.value,a=t??"";r!==a&&(document.activeElement===e&&e.type!=="range"&&(n||l&&e.value.trim()===a)||(e.value=a))}},yv={deep:!0,created(e,t,n){e[hn]=Sl(n),Kt(e,"change",()=>{const l=e._modelValue,i=Mu(e),o=e.checked,r=e[hn];if(Q(l)){const a=Ir(l,i),s=a!==-1;if(o&&!s)r(l.concat(i));else if(!o&&s){const c=[...l];c.splice(a,1),r(c)}}else if(Ol(l)){const a=new Set(l);o?a.add(i):a.delete(i),r(a)}else r(Ss(e,o))})},mounted:qo,beforeUpdate(e,t,n){e[hn]=Sl(n),qo(e,t,n)}};function qo(e,{value:t,oldValue:n},l){e._modelValue=t,Q(t)?e.checked=Ir(t,l.props.value)>-1:Ol(t)?e.checked=t.has(l.props.value):t!==n&&(e.checked=Il(t,Ss(e,!0)))}function Mu(e){return"_value"in e?e._value:e.value}function Ss(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const $u={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},Fu=(e,t)=>{const n=e._withKeys||(e._withKeys={}),l=t.join(".");return n[l]||(n[l]=i=>{if(!("key"in i))return;const o=Zt(i.key);if(t.some(r=>r===o||$u[r]===o))return e(i)})},Vu=Oe({patchProp:Iu},pu);let ti,Go=!1;function Hu(){return ti=Go?ti:Gc(Vu),Go=!0,ti}const ju=(...e)=>{const t=Hu().createApp(...e),{mount:n}=t;return t.mount=l=>{const i=zu(l);if(i)return n(i,!0,Bu(i))},t};function Bu(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function zu(e){return me(e)?document.querySelector(e):e}const Uu="modulepreload",Wu=function(e){return"/node-red-contrib-home-assistant-websocket/"+e},Jo={},y=function(t,n,l){let i=Promise.resolve();return n&&n.length>0&&(document.getElementsByTagName("link"),i=Promise.all(n.map(o=>{if(o=Wu(o),o in Jo)return;Jo[o]=!0;const r=o.endsWith(".css"),a=r?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${a}`))return;const s=document.createElement("link");if(s.rel=r?"stylesheet":Uu,r||(s.as="script",s.crossOrigin=""),s.href=o,document.head.appendChild(s),r)return new Promise((c,u)=>{s.addEventListener("load",c),s.addEventListener("error",()=>u(new Error(`Unable to preload CSS for ${o}`)))})}))),i.then(()=>t()).catch(o=>{const r=new Event("vite:preloadError",{cancelable:!0});if(r.payload=o,window.dispatchEvent(r),!r.defaultPrevented)throw o})},Ku={"v-39a2059c":()=>y(()=>import("./FAQ.html-DJ7cnGer.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8daa1a0e":()=>y(()=>import("./index.html-DTszCqDu.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0b911545":()=>y(()=>import("./index.html-WMUoZnqy.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6fb8d56c":()=>y(()=>import("./actionable-notifications-subflow-for-android.html-BoPaXVyh.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1fbf71d1":()=>y(()=>import("./check-if-an-entity-was-turned-on-in-the-last-24-hours.html-Bb7POubS.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fea818b6":()=>y(()=>import("./expiration-date-monitor.html-4_kB1H6C.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7bcde729":()=>y(()=>import("./get-state_changed-events-based-on-area.html-CwF3ERMA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-012b1d03":()=>y(()=>import("./holiday-lights-scheduler-and-demo-mode-for-wled.html-BuFgBLlB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-cf275bea":()=>y(()=>import("./motion-triggered-light.html-BsdTkCoX.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1dd3ec5e":()=>y(()=>import("./saving-and-restoring-states.html-Bn4K2Zdu.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-97152f42":()=>y(()=>import("./starting-flow-after-home-assistant-restart.html-DKAjP2bd.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a932050c":()=>y(()=>import("./sun-events.html-DbAS3TBD.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5c086d70":()=>y(()=>import("./using-date-and-time-entities-to-trigger-flows.html-D1R0f_8A.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-77a2982b":()=>y(()=>import("./vacation-mode.html-B2l6IzlV.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fffb8e28":()=>y(()=>import("./index.html-uF_24AQ3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1a5d6ff7":()=>y(()=>import("./action.html-DvTgX1MB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-9a822240":()=>y(()=>import("./conditionals.html-wYgbDmQg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-531add2c":()=>y(()=>import("./development.html-kF-1ViGv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-348298ce":()=>y(()=>import("./diagnostics.html-d7C2KoqA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-44d4584b":()=>y(()=>import("./documentation.html-gj5aEpbG.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-746a0799":()=>y(()=>import("./first-automation.html-RzwC4Kux.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d0112c92":()=>y(()=>import("./migration.html-BjOR_TVH.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4970f119":()=>y(()=>import("./mustache-templates.html-BLOVAawv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5104ae33":()=>y(()=>import("./API.html-DH3PYQg3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-15051314":()=>y(()=>import("./index.html-Bw0kX1wh.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2ab02ccf":()=>y(()=>import("./action.html-DFolIjbw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-741d68b2":()=>y(()=>import("./binary-sensor.html-DB_qPuWM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-636bc153":()=>y(()=>import("./button.html-D9AM0-MO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1d084902":()=>y(()=>import("./config-server.html-B9BPPMNa.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-03774460":()=>y(()=>import("./current-state.html-BmYsyJ0a.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a0d46818":()=>y(()=>import("./device-config.html-DBtsAxx_.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7053a0af":()=>y(()=>import("./device.html-E7Z05I5q.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-28f3a601":()=>y(()=>import("./entity-config.html-C3xR_Dqh.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-18af4b42":()=>y(()=>import("./entity.html-jUBk_EPe.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8faf5710":()=>y(()=>import("./events-all.html-DbDqpqdo.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-52df608a":()=>y(()=>import("./events-calendar.html-J-EltcIZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-15feb788":()=>y(()=>import("./events-state.html-6HE_HLPq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2832d8e2":()=>y(()=>import("./fire-event.html-C7OeQhev.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f5f1da26":()=>y(()=>import("./get-entities.html-D6RrCGBK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-56e234f0":()=>y(()=>import("./get-history.html-TruWrGGx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0f75f8c8":()=>y(()=>import("./number.html-CZ8kRhZm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4c846822":()=>y(()=>import("./poll-state.html-UM4aczzK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-ba5fb488":()=>y(()=>import("./render-template.html-KPEunZUG.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4dbc7c6e":()=>y(()=>import("./select.html-Ca9oVm0u.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-275c29cb":()=>y(()=>import("./sensor.html-DnVsLR7L.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-35c07dc2":()=>y(()=>import("./sentence.html-spCQS_3K.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4b35e291":()=>y(()=>import("./switch.html-BDSO4KRT.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8d481eda":()=>y(()=>import("./tag.html-CUfdOsmM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-092d5338":()=>y(()=>import("./text.html-DGk7Mgec.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4de356ea":()=>y(()=>import("./time-entity.html-D25rrN03.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4934c998":()=>y(()=>import("./time.html-B0UXqkE9.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-bdb50f9e":()=>y(()=>import("./trigger-state.html-NF29hhpB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-eda05c32":()=>y(()=>import("./update-config.html-BbAjktc_.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-77b94402":()=>y(()=>import("./wait-until.html-BbqRjVUv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-52885c54":()=>y(()=>import("./webhook.html-FcIF4iwS.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-66fcac19":()=>y(()=>import("./zone.html-B_JK36d1.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-21070556":()=>y(()=>import("./index.html-DwBRaoZp.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-421eb385":()=>y(()=>import("./call-service.html-D6PcUpsv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-cddd5a70":()=>y(()=>import("./change-node.html-C2k8BCNM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-288c9e6c":()=>y(()=>import("./current-state.html-Dan7zvVz.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-57761d4e":()=>y(()=>import("./events-state.html-BDdmzcJp.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-76287ba8":()=>y(()=>import("./functions.html-B4SImbwx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-18acdc11":()=>y(()=>import("./sensor.html-BYmlIVNO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3bf2614c":()=>y(()=>import("./switch-node.html-CMVtiJEI.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e2ca69aa":()=>y(()=>import("./trigger-state.html-DGjipkAb.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-28c12b06":()=>y(()=>import("./index.html-CqxUbxbp.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-16946cd2":()=>y(()=>import("./exposed-nodes.html-ILHhxMf-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e0a0c596":()=>y(()=>import("./index.html-BqcXEfG9.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-30bc7e2c":()=>y(()=>import("./jsonata-primer.html-DHSKk7gq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3706649a":()=>y(()=>import("./404.html-5sy5zeZP.js"),__vite__mapDeps([])).then(({data:e})=>e)},qu=JSON.parse('{"base":"/node-red-contrib-home-assistant-websocket/","lang":"en-US","title":"node-red-contrib-home-assistant-websocket","description":"Node-RED integration with Home Assistant through the WebSocket and HTTP API","head":[["link",{"rel":"icon","href":"/favicon.ico"}]],"locales":{}}');var Gu=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),Ju=e=>{const t=new Set,n=[];return e.forEach(l=>{const i=Gu(l);t.has(i)||(t.add(i),n.push(l))}),n},Qn=e=>/^(https?:)?\/\//.test(e),Yu=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Wi=e=>Object.prototype.toString.call(e)==="[object Object]",Cs=e=>e[e.length-1]==="/"?e.slice(0,-1):e,As=e=>e[0]==="/"?e.slice(1):e,Os=(e,t)=>{const n=Object.keys(e).sort((l,i)=>{const o=i.split("/").length-l.split("/").length;return o!==0?o:i.length-l.length});for(const l of n)if(t.startsWith(l))return l;return"/"};const Rs={"v-39a2059c":z(()=>y(()=>import("./FAQ.html-BnloOyfX.js"),__vite__mapDeps([]))),"v-8daa1a0e":z(()=>y(()=>import("./index.html-DEOTEIXH.js"),__vite__mapDeps([]))),"v-0b911545":z(()=>y(()=>import("./index.html-BOJH-tw9.js"),__vite__mapDeps([]))),"v-6fb8d56c":z(()=>y(()=>import("./actionable-notifications-subflow-for-android.html-DtDChOoX.js"),__vite__mapDeps([]))),"v-1fbf71d1":z(()=>y(()=>import("./check-if-an-entity-was-turned-on-in-the-last-24-hours.html-DNFiTfl7.js"),__vite__mapDeps([]))),"v-fea818b6":z(()=>y(()=>import("./expiration-date-monitor.html-DWNCvrSy.js"),__vite__mapDeps([]))),"v-7bcde729":z(()=>y(()=>import("./get-state_changed-events-based-on-area.html-DbqIqKcr.js"),__vite__mapDeps([]))),"v-012b1d03":z(()=>y(()=>import("./holiday-lights-scheduler-and-demo-mode-for-wled.html-BwE_uZSM.js"),__vite__mapDeps([]))),"v-cf275bea":z(()=>y(()=>import("./motion-triggered-light.html-Iz8Qowho.js"),__vite__mapDeps([]))),"v-1dd3ec5e":z(()=>y(()=>import("./saving-and-restoring-states.html-DqoxYXhp.js"),__vite__mapDeps([]))),"v-97152f42":z(()=>y(()=>import("./starting-flow-after-home-assistant-restart.html-CNeWpRUR.js"),__vite__mapDeps([]))),"v-a932050c":z(()=>y(()=>import("./sun-events.html-BgsSnipk.js"),__vite__mapDeps([0,1]))),"v-5c086d70":z(()=>y(()=>import("./using-date-and-time-entities-to-trigger-flows.html-BMs5a4o1.js"),__vite__mapDeps([]))),"v-77a2982b":z(()=>y(()=>import("./vacation-mode.html-B7J9q-nz.js"),__vite__mapDeps([]))),"v-fffb8e28":z(()=>y(()=>import("./index.html-B8GPYcQt.js"),__vite__mapDeps([]))),"v-1a5d6ff7":z(()=>y(()=>import("./action.html-CDqqIuhb.js"),__vite__mapDeps([]))),"v-9a822240":z(()=>y(()=>import("./conditionals.html-DxXN_ykY.js"),__vite__mapDeps([]))),"v-531add2c":z(()=>y(()=>import("./development.html-BnHcbBQ7.js"),__vite__mapDeps([]))),"v-348298ce":z(()=>y(()=>import("./diagnostics.html-DkEWMJq5.js"),__vite__mapDeps([]))),"v-44d4584b":z(()=>y(()=>import("./documentation.html-Db4YoijQ.js"),__vite__mapDeps([]))),"v-746a0799":z(()=>y(()=>import("./first-automation.html-U01iwXIn.js"),__vite__mapDeps([2,1]))),"v-d0112c92":z(()=>y(()=>import("./migration.html-DHBQGdN5.js"),__vite__mapDeps([]))),"v-4970f119":z(()=>y(()=>import("./mustache-templates.html-HaF7DCkI.js"),__vite__mapDeps([]))),"v-5104ae33":z(()=>y(()=>import("./API.html-BA2ozcqM.js"),__vite__mapDeps([]))),"v-15051314":z(()=>y(()=>import("./index.html-BhVmmYi-.js"),__vite__mapDeps([]))),"v-2ab02ccf":z(()=>y(()=>import("./action.html-CVd1_Ell.js"),__vite__mapDeps([]))),"v-741d68b2":z(()=>y(()=>import("./binary-sensor.html-DbMx8MUV.js"),__vite__mapDeps([]))),"v-636bc153":z(()=>y(()=>import("./button.html-DJLpLyCD.js"),__vite__mapDeps([]))),"v-1d084902":z(()=>y(()=>import("./config-server.html-DgWwM5Tw.js"),__vite__mapDeps([]))),"v-03774460":z(()=>y(()=>import("./current-state.html-aEJCnhno.js"),__vite__mapDeps([]))),"v-a0d46818":z(()=>y(()=>import("./device-config.html-BK4OG4oz.js"),__vite__mapDeps([]))),"v-7053a0af":z(()=>y(()=>import("./device.html-CMu5d7xr.js"),__vite__mapDeps([]))),"v-28f3a601":z(()=>y(()=>import("./entity-config.html-k1lGGcxI.js"),__vite__mapDeps([]))),"v-18af4b42":z(()=>y(()=>import("./entity.html-rEDHJL39.js"),__vite__mapDeps([]))),"v-8faf5710":z(()=>y(()=>import("./events-all.html-CIdgH7aC.js"),__vite__mapDeps([]))),"v-52df608a":z(()=>y(()=>import("./events-calendar.html-BvVJPsDC.js"),__vite__mapDeps([]))),"v-15feb788":z(()=>y(()=>import("./events-state.html-BxHuLD51.js"),__vite__mapDeps([]))),"v-2832d8e2":z(()=>y(()=>import("./fire-event.html-CFPfjQeh.js"),__vite__mapDeps([]))),"v-f5f1da26":z(()=>y(()=>import("./get-entities.html-Dnp5j9U7.js"),__vite__mapDeps([]))),"v-56e234f0":z(()=>y(()=>import("./get-history.html-D06ElvwU.js"),__vite__mapDeps([]))),"v-0f75f8c8":z(()=>y(()=>import("./number.html-DsWqf7c6.js"),__vite__mapDeps([]))),"v-4c846822":z(()=>y(()=>import("./poll-state.html-BosF6sYi.js"),__vite__mapDeps([]))),"v-ba5fb488":z(()=>y(()=>import("./render-template.html-C5DI6JF3.js"),__vite__mapDeps([]))),"v-4dbc7c6e":z(()=>y(()=>import("./select.html-BejfjQRf.js"),__vite__mapDeps([]))),"v-275c29cb":z(()=>y(()=>import("./sensor.html-CesHJDlf.js"),__vite__mapDeps([]))),"v-35c07dc2":z(()=>y(()=>import("./sentence.html-DrsbxzcE.js"),__vite__mapDeps([]))),"v-4b35e291":z(()=>y(()=>import("./switch.html-BsSKqMFL.js"),__vite__mapDeps([]))),"v-8d481eda":z(()=>y(()=>import("./tag.html-Bt41HB9x.js"),__vite__mapDeps([]))),"v-092d5338":z(()=>y(()=>import("./text.html-CoRz7I1B.js"),__vite__mapDeps([]))),"v-4de356ea":z(()=>y(()=>import("./time-entity.html-Dqh-2uOd.js"),__vite__mapDeps([]))),"v-4934c998":z(()=>y(()=>import("./time.html-DSURmXX5.js"),__vite__mapDeps([]))),"v-bdb50f9e":z(()=>y(()=>import("./trigger-state.html-3KwTutxw.js"),__vite__mapDeps([]))),"v-eda05c32":z(()=>y(()=>import("./update-config.html-Ctl76Lel.js"),__vite__mapDeps([]))),"v-77b94402":z(()=>y(()=>import("./wait-until.html-CgFxsoz7.js"),__vite__mapDeps([]))),"v-52885c54":z(()=>y(()=>import("./webhook.html-CQCZ7xuU.js"),__vite__mapDeps([]))),"v-66fcac19":z(()=>y(()=>import("./zone.html-CJBJZBw6.js"),__vite__mapDeps([]))),"v-21070556":z(()=>y(()=>import("./index.html-CWawZjlF.js"),__vite__mapDeps([]))),"v-421eb385":z(()=>y(()=>import("./call-service.html-BLSy7J4X.js"),__vite__mapDeps([]))),"v-cddd5a70":z(()=>y(()=>import("./change-node.html-DvnmySvX.js"),__vite__mapDeps([]))),"v-288c9e6c":z(()=>y(()=>import("./current-state.html-BMmGCQGb.js"),__vite__mapDeps([]))),"v-57761d4e":z(()=>y(()=>import("./events-state.html-BUeuT8p5.js"),__vite__mapDeps([]))),"v-76287ba8":z(()=>y(()=>import("./functions.html-CmkTFp8c.js"),__vite__mapDeps([]))),"v-18acdc11":z(()=>y(()=>import("./sensor.html-Cb1LErrD.js"),__vite__mapDeps([]))),"v-3bf2614c":z(()=>y(()=>import("./switch-node.html-CHtn4s3S.js"),__vite__mapDeps([]))),"v-e2ca69aa":z(()=>y(()=>import("./trigger-state.html-DOz_296k.js"),__vite__mapDeps([]))),"v-28c12b06":z(()=>y(()=>import("./index.html-XbMl3aUj.js"),__vite__mapDeps([]))),"v-16946cd2":z(()=>y(()=>import("./exposed-nodes.html-Db4LuLE5.js"),__vite__mapDeps([]))),"v-e0a0c596":z(()=>y(()=>import("./index.html-CDTosV2S.js"),__vite__mapDeps([]))),"v-30bc7e2c":z(()=>y(()=>import("./jsonata-primer.html-Nla_OrjS.js"),__vite__mapDeps([]))),"v-3706649a":z(()=>y(()=>import("./404.html-DBjtgjki.js"),__vite__mapDeps([])))};var Qu=Symbol(""),Ps=Symbol(""),Zu=bn({key:"",path:"",title:"",lang:"",frontmatter:{},headers:[]}),It=()=>{const e=Se(Ps);if(!e)throw new Error("pageData() is called without provider.");return e},Is=Symbol(""),mt=()=>{const e=Se(Is);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},Ds=Symbol(""),Xu=()=>{const e=Se(Ds);if(!e)throw new Error("usePageHead() is called without provider.");return e},ed=Symbol(""),Ns=Symbol(""),td=()=>{const e=Se(Ns);if(!e)throw new Error("usePageLang() is called without provider.");return e},Ms=Symbol(""),nd=()=>{const e=Se(Ms);if(!e)throw new Error("usePageLayout() is called without provider.");return e},ld=de(Ku),Ki=Symbol(""),kn=()=>{const e=Se(Ki);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},sn=de(qu),$s=()=>sn,Fs=Symbol(""),qi=()=>{const e=Se(Fs);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},id=Symbol(""),od="Layout",rd="NotFound",ht=Wn({resolveLayouts:e=>e.reduce((t,n)=>({...t,...n.layouts}),{}),resolvePageData:async e=>{const t=ld.value[e];return await(t==null?void 0:t())??Zu},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const l=me(t.description)?t.description:n.description,i=[...Q(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:l}]];return Ju(i)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(n=>!!n).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||"en-US",resolvePageLayout:(e,t)=>{let n;if(e.path){const l=e.frontmatter.layout;me(l)?n=l:n=od}else n=rd;return t[n]},resolveRouteLocale:(e,t)=>Os(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),Gi=fe({name:"ClientOnly",setup(e,t){const n=de(!1);return Fe(()=>{n.value=!0}),()=>{var l,i;return n.value?(i=(l=t.slots).default)==null?void 0:i.call(l):null}}}),sd=fe({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=It(),n=j(()=>Rs[e.pageKey||t.value.key]);return()=>n.value?ce(n.value):ce("div","404 Not Found")}}),rt=(e={})=>e,Ji=e=>Qn(e)?e:`/node-red-contrib-home-assistant-websocket/${As(e)}`;function Vs(e,t,n){var l,i,o;t===void 0&&(t=50),n===void 0&&(n={});var r=(l=n.isImmediate)!=null&&l,a=(i=n.callback)!=null&&i,s=n.maxWait,c=Date.now(),u=[];function d(){if(s!==void 0){var g=Date.now()-c;if(g+t>=s)return s-g}return t}var f=function(){var g=[].slice.call(arguments),b=this;return new Promise(function(w,T){var x=r&&o===void 0;if(o!==void 0&&clearTimeout(o),o=setTimeout(function(){if(o=void 0,c=Date.now(),!r){var v=e.apply(b,g);a&&a(v),u.forEach(function(E){return(0,E.resolve)(v)}),u=[]}},d()),x){var A=e.apply(b,g);return a&&a(A),w(A)}u.push({resolve:w,reject:T})})};return f.cancel=function(g){o!==void 0&&clearTimeout(o),u.forEach(function(b){return(0,b.reject)(g)}),u=[]},f}/*! + * vue-router v4.2.5 + * (c) 2023 Eduardo San Martin Morote + * @license MIT + */const rn=typeof window<"u";function ad(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const _e=Object.assign;function ni(e,t){const n={};for(const l in t){const i=t[l];n[l]=ot(i)?i.map(e):e(i)}return n}const Pn=()=>{},ot=Array.isArray,cd=/\/$/,ud=e=>e.replace(cd,"");function li(e,t,n="/"){let l,i={},o="",r="";const a=t.indexOf("#");let s=t.indexOf("?");return a=0&&(s=-1),s>-1&&(l=t.slice(0,s),o=t.slice(s+1,a>-1?a:t.length),i=e(o)),a>-1&&(l=l||t.slice(0,a),r=t.slice(a,t.length)),l=pd(l??t,n),{fullPath:l+(o&&"?")+o+r,path:l,query:i,hash:r}}function dd(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Yo(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function fd(e,t,n){const l=t.matched.length-1,i=n.matched.length-1;return l>-1&&l===i&&mn(t.matched[l],n.matched[i])&&Hs(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function mn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Hs(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!hd(e[n],t[n]))return!1;return!0}function hd(e,t){return ot(e)?Qo(e,t):ot(t)?Qo(t,e):e===t}function Qo(e,t){return ot(t)?e.length===t.length&&e.every((n,l)=>n===t[l]):e.length===1&&e[0]===t}function pd(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),l=e.split("/"),i=l[l.length-1];(i===".."||i===".")&&l.push("");let o=n.length-1,r,a;for(r=0;r1&&o--;else break;return n.slice(0,o).join("/")+"/"+l.slice(r-(r===l.length?1:0)).join("/")}var Vn;(function(e){e.pop="pop",e.push="push"})(Vn||(Vn={}));var In;(function(e){e.back="back",e.forward="forward",e.unknown=""})(In||(In={}));function gd(e){if(!e)if(rn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),ud(e)}const vd=/^[^#]+#/;function md(e,t){return e.replace(vd,"#")+t}function _d(e,t){const n=document.documentElement.getBoundingClientRect(),l=e.getBoundingClientRect();return{behavior:t.behavior,left:l.left-n.left-(t.left||0),top:l.top-n.top-(t.top||0)}}const zl=()=>({left:window.pageXOffset,top:window.pageYOffset});function bd(e){let t;if("el"in e){const n=e.el,l=typeof n=="string"&&n.startsWith("#"),i=typeof n=="string"?l?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=_d(i,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.pageXOffset,t.top!=null?t.top:window.pageYOffset)}function Zo(e,t){return(history.state?history.state.position-t:-1)+e}const Ei=new Map;function yd(e,t){Ei.set(e,t)}function kd(e){const t=Ei.get(e);return Ei.delete(e),t}let Ed=()=>location.protocol+"//"+location.host;function js(e,t){const{pathname:n,search:l,hash:i}=t,o=e.indexOf("#");if(o>-1){let a=i.includes(e.slice(o))?e.slice(o).length:1,s=i.slice(a);return s[0]!=="/"&&(s="/"+s),Yo(s,"")}return Yo(n,e)+l+i}function wd(e,t,n,l){let i=[],o=[],r=null;const a=({state:f})=>{const g=js(e,location),b=n.value,w=t.value;let T=0;if(f){if(n.value=g,t.value=f,r&&r===b){r=null;return}T=w?f.position-w.position:0}else l(g);i.forEach(x=>{x(n.value,b,{delta:T,type:Vn.pop,direction:T?T>0?In.forward:In.back:In.unknown})})};function s(){r=n.value}function c(f){i.push(f);const g=()=>{const b=i.indexOf(f);b>-1&&i.splice(b,1)};return o.push(g),g}function u(){const{history:f}=window;f.state&&f.replaceState(_e({},f.state,{scroll:zl()}),"")}function d(){for(const f of o)f();o=[],window.removeEventListener("popstate",a),window.removeEventListener("beforeunload",u)}return window.addEventListener("popstate",a),window.addEventListener("beforeunload",u,{passive:!0}),{pauseListeners:s,listen:c,destroy:d}}function Xo(e,t,n,l=!1,i=!1){return{back:e,current:t,forward:n,replaced:l,position:window.history.length,scroll:i?zl():null}}function xd(e){const{history:t,location:n}=window,l={value:js(e,n)},i={value:t.state};i.value||o(l.value,{back:null,current:l.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function o(s,c,u){const d=e.indexOf("#"),f=d>-1?(n.host&&document.querySelector("base")?e:e.slice(d))+s:Ed()+e+s;try{t[u?"replaceState":"pushState"](c,"",f),i.value=c}catch(g){console.error(g),n[u?"replace":"assign"](f)}}function r(s,c){const u=_e({},t.state,Xo(i.value.back,s,i.value.forward,!0),c,{position:i.value.position});o(s,u,!0),l.value=s}function a(s,c){const u=_e({},i.value,t.state,{forward:s,scroll:zl()});o(u.current,u,!0);const d=_e({},Xo(l.value,s,null),{position:u.position+1},c);o(s,d,!1),l.value=s}return{location:l,state:i,push:a,replace:r}}function Ld(e){e=gd(e);const t=xd(e),n=wd(e,t.state,t.location,t.replace);function l(o,r=!0){r||n.pauseListeners(),history.go(o)}const i=_e({location:"",base:e,go:l,createHref:md.bind(null,e)},t,n);return Object.defineProperty(i,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,"state",{enumerable:!0,get:()=>t.state.value}),i}function Td(e){return typeof e=="string"||e&&typeof e=="object"}function Bs(e){return typeof e=="string"||typeof e=="symbol"}const pt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},zs=Symbol("");var er;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(er||(er={}));function _n(e,t){return _e(new Error,{type:e,[zs]:!0},t)}function ft(e,t){return e instanceof Error&&zs in e&&(t==null||!!(e.type&t))}const tr="[^/]+?",Sd={sensitive:!1,strict:!1,start:!0,end:!0},Cd=/[.+*?^${}()[\]/\\]/g;function Ad(e,t){const n=_e({},Sd,t),l=[];let i=n.start?"^":"";const o=[];for(const c of e){const u=c.length?[]:[90];n.strict&&!c.length&&(i+="/");for(let d=0;dt.length?t.length===1&&t[0]===80?1:-1:0}function Rd(e,t){let n=0;const l=e.score,i=t.score;for(;n0&&t[t.length-1]<0}const Pd={type:0,value:""},Id=/[a-zA-Z0-9_]/;function Dd(e){if(!e)return[[]];if(e==="/")return[[Pd]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(g){throw new Error(`ERR (${n})/"${c}": ${g}`)}let n=0,l=n;const i=[];let o;function r(){o&&i.push(o),o=[]}let a=0,s,c="",u="";function d(){c&&(n===0?o.push({type:0,value:c}):n===1||n===2||n===3?(o.length>1&&(s==="*"||s==="+")&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),o.push({type:1,value:c,regexp:u,repeatable:s==="*"||s==="+",optional:s==="*"||s==="?"})):t("Invalid state to consume buffer"),c="")}function f(){c+=s}for(;a{r(A)}:Pn}function r(u){if(Bs(u)){const d=l.get(u);d&&(l.delete(u),n.splice(n.indexOf(d),1),d.children.forEach(r),d.alias.forEach(r))}else{const d=n.indexOf(u);d>-1&&(n.splice(d,1),u.record.name&&l.delete(u.record.name),u.children.forEach(r),u.alias.forEach(r))}}function a(){return n}function s(u){let d=0;for(;d=0&&(u.record.path!==n[d].record.path||!Us(u,n[d]));)d++;n.splice(d,0,u),u.record.name&&!ir(u)&&l.set(u.record.name,u)}function c(u,d){let f,g={},b,w;if("name"in u&&u.name){if(f=l.get(u.name),!f)throw _n(1,{location:u});w=f.record.name,g=_e(lr(d.params,f.keys.filter(A=>!A.optional).map(A=>A.name)),u.params&&lr(u.params,f.keys.map(A=>A.name))),b=f.stringify(g)}else if("path"in u)b=u.path,f=n.find(A=>A.re.test(b)),f&&(g=f.parse(b),w=f.record.name);else{if(f=d.name?l.get(d.name):n.find(A=>A.re.test(d.path)),!f)throw _n(1,{location:u,currentLocation:d});w=f.record.name,g=_e({},d.params,u.params),b=f.stringify(g)}const T=[];let x=f;for(;x;)T.unshift(x.record),x=x.parent;return{name:w,path:b,params:g,matched:T,meta:Vd(T)}}return e.forEach(u=>o(u)),{addRoute:o,resolve:c,removeRoute:r,getRoutes:a,getRecordMatcher:i}}function lr(e,t){const n={};for(const l of t)l in e&&(n[l]=e[l]);return n}function $d(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:Fd(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function Fd(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const l in e.components)t[l]=typeof n=="object"?n[l]:n;return t}function ir(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Vd(e){return e.reduce((t,n)=>_e(t,n.meta),{})}function or(e,t){const n={};for(const l in e)n[l]=l in t?t[l]:e[l];return n}function Us(e,t){return t.children.some(n=>n===e||Us(e,n))}const Ws=/#/g,Hd=/&/g,jd=/\//g,Bd=/=/g,zd=/\?/g,Ks=/\+/g,Ud=/%5B/g,Wd=/%5D/g,qs=/%5E/g,Kd=/%60/g,Gs=/%7B/g,qd=/%7C/g,Js=/%7D/g,Gd=/%20/g;function Yi(e){return encodeURI(""+e).replace(qd,"|").replace(Ud,"[").replace(Wd,"]")}function Jd(e){return Yi(e).replace(Gs,"{").replace(Js,"}").replace(qs,"^")}function wi(e){return Yi(e).replace(Ks,"%2B").replace(Gd,"+").replace(Ws,"%23").replace(Hd,"%26").replace(Kd,"`").replace(Gs,"{").replace(Js,"}").replace(qs,"^")}function Yd(e){return wi(e).replace(Bd,"%3D")}function Qd(e){return Yi(e).replace(Ws,"%23").replace(zd,"%3F")}function Zd(e){return e==null?"":Qd(e).replace(jd,"%2F")}function Cl(e){try{return decodeURIComponent(""+e)}catch{}return""+e}function Xd(e){const t={};if(e===""||e==="?")return t;const l=(e[0]==="?"?e.slice(1):e).split("&");for(let i=0;io&&wi(o)):[l&&wi(l)]).forEach(o=>{o!==void 0&&(t+=(t.length?"&":"")+n,o!=null&&(t+="="+o))})}return t}function ef(e){const t={};for(const n in e){const l=e[n];l!==void 0&&(t[n]=ot(l)?l.map(i=>i==null?null:""+i):l==null?l:""+l)}return t}const tf=Symbol(""),sr=Symbol(""),Ul=Symbol(""),Qi=Symbol(""),xi=Symbol("");function Ln(){let e=[];function t(l){return e.push(l),()=>{const i=e.indexOf(l);i>-1&&e.splice(i,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Ot(e,t,n,l,i){const o=l&&(l.enterCallbacks[i]=l.enterCallbacks[i]||[]);return()=>new Promise((r,a)=>{const s=d=>{d===!1?a(_n(4,{from:n,to:t})):d instanceof Error?a(d):Td(d)?a(_n(2,{from:t,to:d})):(o&&l.enterCallbacks[i]===o&&typeof d=="function"&&o.push(d),r())},c=e.call(l&&l.instances[i],t,n,s);let u=Promise.resolve(c);e.length<3&&(u=u.then(s)),u.catch(d=>a(d))})}function ii(e,t,n,l){const i=[];for(const o of e)for(const r in o.components){let a=o.components[r];if(!(t!=="beforeRouteEnter"&&!o.instances[r]))if(nf(a)){const c=(a.__vccOpts||a)[t];c&&i.push(Ot(c,n,l,o,r))}else{let s=a();i.push(()=>s.then(c=>{if(!c)return Promise.reject(new Error(`Couldn't resolve component "${r}" at "${o.path}"`));const u=ad(c)?c.default:c;o.components[r]=u;const f=(u.__vccOpts||u)[t];return f&&Ot(f,n,l,o,r)()}))}}return i}function nf(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function ar(e){const t=Se(Ul),n=Se(Qi),l=j(()=>t.resolve(ne(e.to))),i=j(()=>{const{matched:s}=l.value,{length:c}=s,u=s[c-1],d=n.matched;if(!u||!d.length)return-1;const f=d.findIndex(mn.bind(null,u));if(f>-1)return f;const g=cr(s[c-2]);return c>1&&cr(u)===g&&d[d.length-1].path!==g?d.findIndex(mn.bind(null,s[c-2])):f}),o=j(()=>i.value>-1&&sf(n.params,l.value.params)),r=j(()=>i.value>-1&&i.value===n.matched.length-1&&Hs(n.params,l.value.params));function a(s={}){return rf(s)?t[ne(e.replace)?"replace":"push"](ne(e.to)).catch(Pn):Promise.resolve()}return{route:l,href:j(()=>l.value.href),isActive:o,isExactActive:r,navigate:a}}const lf=fe({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:ar,setup(e,{slots:t}){const n=Wn(ar(e)),{options:l}=Se(Ul),i=j(()=>({[ur(e.activeClass,l.linkActiveClass,"router-link-active")]:n.isActive,[ur(e.exactActiveClass,l.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const o=t.default&&t.default(n);return e.custom?o:ce("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:i.value},o)}}}),of=lf;function rf(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function sf(e,t){for(const n in t){const l=t[n],i=e[n];if(typeof l=="string"){if(l!==i)return!1}else if(!ot(i)||i.length!==l.length||l.some((o,r)=>o!==i[r]))return!1}return!0}function cr(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const ur=(e,t,n)=>e??t??n,af=fe({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const l=Se(xi),i=j(()=>e.route||l.value),o=Se(sr,0),r=j(()=>{let c=ne(o);const{matched:u}=i.value;let d;for(;(d=u[c])&&!d.components;)c++;return c}),a=j(()=>i.value.matched[r.value]);Yt(sr,j(()=>r.value+1)),Yt(tf,a),Yt(xi,i);const s=de();return qe(()=>[s.value,a.value,e.name],([c,u,d],[f,g,b])=>{u&&(u.instances[d]=c,g&&g!==u&&c&&c===f&&(u.leaveGuards.size||(u.leaveGuards=g.leaveGuards),u.updateGuards.size||(u.updateGuards=g.updateGuards))),c&&u&&(!g||!mn(u,g)||!f)&&(u.enterCallbacks[d]||[]).forEach(w=>w(c))},{flush:"post"}),()=>{const c=i.value,u=e.name,d=a.value,f=d&&d.components[u];if(!f)return dr(n.default,{Component:f,route:c});const g=d.props[u],b=g?g===!0?c.params:typeof g=="function"?g(c):g:null,T=ce(f,_e({},b,t,{onVnodeUnmounted:x=>{x.component.isUnmounted&&(d.instances[u]=null)},ref:s}));return dr(n.default,{Component:T,route:c})||T}}});function dr(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Ys=af;function cf(e){const t=Md(e.routes,e),n=e.parseQuery||Xd,l=e.stringifyQuery||rr,i=e.history,o=Ln(),r=Ln(),a=Ln(),s=$i(pt);let c=pt;rn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const u=ni.bind(null,S=>""+S),d=ni.bind(null,Zd),f=ni.bind(null,Cl);function g(S,W){let V,Y;return Bs(S)?(V=t.getRecordMatcher(S),Y=W):Y=S,t.addRoute(Y,V)}function b(S){const W=t.getRecordMatcher(S);W&&t.removeRoute(W)}function w(){return t.getRoutes().map(S=>S.record)}function T(S){return!!t.getRecordMatcher(S)}function x(S,W){if(W=_e({},W||s.value),typeof S=="string"){const m=li(n,S,W.path),k=t.resolve({path:m.path},W),C=i.createHref(m.fullPath);return _e(m,k,{params:f(k.params),hash:Cl(m.hash),redirectedFrom:void 0,href:C})}let V;if("path"in S)V=_e({},S,{path:li(n,S.path,W.path).path});else{const m=_e({},S.params);for(const k in m)m[k]==null&&delete m[k];V=_e({},S,{params:d(m)}),W.params=d(W.params)}const Y=t.resolve(V,W),ue=S.hash||"";Y.params=u(f(Y.params));const h=dd(l,_e({},S,{hash:Jd(ue),path:Y.path})),p=i.createHref(h);return _e({fullPath:h,hash:ue,query:l===rr?ef(S.query):S.query||{}},Y,{redirectedFrom:void 0,href:p})}function A(S){return typeof S=="string"?li(n,S,s.value.path):_e({},S)}function v(S,W){if(c!==S)return _n(8,{from:W,to:S})}function E(S){return F(S)}function O(S){return E(_e(A(S),{replace:!0}))}function G(S){const W=S.matched[S.matched.length-1];if(W&&W.redirect){const{redirect:V}=W;let Y=typeof V=="function"?V(S):V;return typeof Y=="string"&&(Y=Y.includes("?")||Y.includes("#")?Y=A(Y):{path:Y},Y.params={}),_e({query:S.query,hash:S.hash,params:"path"in Y?{}:S.params},Y)}}function F(S,W){const V=c=x(S),Y=s.value,ue=S.state,h=S.force,p=S.replace===!0,m=G(V);if(m)return F(_e(A(m),{state:typeof m=="object"?_e({},ue,m.state):ue,force:h,replace:p}),W||V);const k=V;k.redirectedFrom=W;let C;return!h&&fd(l,Y,V)&&(C=_n(16,{to:k,from:Y}),Ue(Y,Y,!0,!1)),(C?Promise.resolve(C):P(k,Y)).catch(R=>ft(R)?ft(R,2)?R:Ne(R):K(R,k,Y)).then(R=>{if(R){if(ft(R,2))return F(_e({replace:p},A(R.to),{state:typeof R.to=="object"?_e({},ue,R.to.state):ue,force:h}),W||k)}else R=L(k,Y,!0,p,ue);return J(k,Y,R),R})}function _(S,W){const V=v(S,W);return V?Promise.reject(V):Promise.resolve()}function N(S){const W=Et.values().next().value;return W&&typeof W.runWithContext=="function"?W.runWithContext(S):S()}function P(S,W){let V;const[Y,ue,h]=uf(S,W);V=ii(Y.reverse(),"beforeRouteLeave",S,W);for(const m of Y)m.leaveGuards.forEach(k=>{V.push(Ot(k,S,W))});const p=_.bind(null,S,W);return V.push(p),Pe(V).then(()=>{V=[];for(const m of o.list())V.push(Ot(m,S,W));return V.push(p),Pe(V)}).then(()=>{V=ii(ue,"beforeRouteUpdate",S,W);for(const m of ue)m.updateGuards.forEach(k=>{V.push(Ot(k,S,W))});return V.push(p),Pe(V)}).then(()=>{V=[];for(const m of h)if(m.beforeEnter)if(ot(m.beforeEnter))for(const k of m.beforeEnter)V.push(Ot(k,S,W));else V.push(Ot(m.beforeEnter,S,W));return V.push(p),Pe(V)}).then(()=>(S.matched.forEach(m=>m.enterCallbacks={}),V=ii(h,"beforeRouteEnter",S,W),V.push(p),Pe(V))).then(()=>{V=[];for(const m of r.list())V.push(Ot(m,S,W));return V.push(p),Pe(V)}).catch(m=>ft(m,8)?m:Promise.reject(m))}function J(S,W,V){a.list().forEach(Y=>N(()=>Y(S,W,V)))}function L(S,W,V,Y,ue){const h=v(S,W);if(h)return h;const p=W===pt,m=rn?history.state:{};V&&(Y||p?i.replace(S.fullPath,_e({scroll:p&&m&&m.scroll},ue)):i.push(S.fullPath,ue)),s.value=S,Ue(S,W,V,p),Ne()}let $;function le(){$||($=i.listen((S,W,V)=>{if(!st.listening)return;const Y=x(S),ue=G(Y);if(ue){F(_e(ue,{replace:!0}),Y).catch(Pn);return}c=Y;const h=s.value;rn&&yd(Zo(h.fullPath,V.delta),zl()),P(Y,h).catch(p=>ft(p,12)?p:ft(p,2)?(F(p.to,Y).then(m=>{ft(m,20)&&!V.delta&&V.type===Vn.pop&&i.go(-1,!1)}).catch(Pn),Promise.reject()):(V.delta&&i.go(-V.delta,!1),K(p,Y,h))).then(p=>{p=p||L(Y,h,!1),p&&(V.delta&&!ft(p,8)?i.go(-V.delta,!1):V.type===Vn.pop&&ft(p,20)&&i.go(-1,!1)),J(Y,h,p)}).catch(Pn)}))}let se=Ln(),D=Ln(),Z;function K(S,W,V){Ne(S);const Y=D.list();return Y.length?Y.forEach(ue=>ue(S,W,V)):console.error(S),Promise.reject(S)}function Re(){return Z&&s.value!==pt?Promise.resolve():new Promise((S,W)=>{se.add([S,W])})}function Ne(S){return Z||(Z=!S,le(),se.list().forEach(([W,V])=>S?V(S):W()),se.reset()),S}function Ue(S,W,V,Y){const{scrollBehavior:ue}=e;if(!rn||!ue)return Promise.resolve();const h=!V&&kd(Zo(S.fullPath,0))||(Y||!V)&&history.state&&history.state.scroll||null;return yn().then(()=>ue(S,W,h)).then(p=>p&&bd(p)).catch(p=>K(p,S,W))}const Ve=S=>i.go(S);let kt;const Et=new Set,st={currentRoute:s,listening:!0,addRoute:g,removeRoute:b,hasRoute:T,getRoutes:w,resolve:x,options:e,push:E,replace:O,go:Ve,back:()=>Ve(-1),forward:()=>Ve(1),beforeEach:o.add,beforeResolve:r.add,afterEach:a.add,onError:D.add,isReady:Re,install(S){const W=this;S.component("RouterLink",of),S.component("RouterView",Ys),S.config.globalProperties.$router=W,Object.defineProperty(S.config.globalProperties,"$route",{enumerable:!0,get:()=>ne(s)}),rn&&!kt&&s.value===pt&&(kt=!0,E(i.location).catch(ue=>{}));const V={};for(const ue in pt)Object.defineProperty(V,ue,{get:()=>s.value[ue],enumerable:!0});S.provide(Ul,W),S.provide(Qi,Kr(V)),S.provide(xi,s);const Y=S.unmount;Et.add(S),S.unmount=function(){Et.delete(S),Et.size<1&&(c=pt,$&&$(),$=null,s.value=pt,kt=!1,Z=!1),Y()}}};function Pe(S){return S.reduce((W,V)=>W.then(()=>N(V)),Promise.resolve())}return st}function uf(e,t){const n=[],l=[],i=[],o=Math.max(t.matched.length,e.matched.length);for(let r=0;rmn(c,a))?l.push(a):n.push(a));const s=e.matched[r];s&&(t.matched.find(c=>mn(c,s))||i.push(s))}return[n,l,i]}function tn(){return Se(Ul)}function nn(){return Se(Qi)}const df=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:l=5})=>{const i=tn(),r=Vs(()=>{var w,T;const a=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(a-0)f.some(A=>A.hash===x.hash));for(let x=0;x=(((w=A.parentElement)==null?void 0:w.offsetTop)??0)-l,O=!v||a<(((T=v.parentElement)==null?void 0:T.offsetTop)??0)-l;if(!(E&&O))continue;const F=decodeURIComponent(i.currentRoute.value.hash),_=decodeURIComponent(A.hash);if(F===_)return;if(d){for(let N=x+1;N{window.addEventListener("scroll",r)}),Gn(()=>{window.removeEventListener("scroll",r)})},fr=async(e,t)=>{const{scrollBehavior:n}=e.options;e.options.scrollBehavior=void 0,await e.replace({query:e.currentRoute.value.query,hash:t}).finally(()=>e.options.scrollBehavior=n)},ff="a.sidebar-item",hf=".header-anchor",pf=300,gf=5,vf=rt({setup(){df({headerLinkSelector:ff,headerAnchorSelector:hf,delay:pf,offset:gf})}}),hr=()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,mf=()=>window.scrollTo({top:0,behavior:"smooth"}),_f=fe({name:"BackToTop",setup(){const e=de(0),t=j(()=>e.value>300),n=Vs(()=>{e.value=hr()},100);Fe(()=>{e.value=hr(),window.addEventListener("scroll",()=>n())});const l=ce("div",{class:"back-to-top",onClick:mf});return()=>ce(Yn,{name:"back-to-top"},()=>t.value?l:null)}}),bf=rt({rootComponents:[_f]}),yf=ce("svg",{class:"external-link-icon",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},[ce("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}),ce("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"})]),kf=fe({name:"ExternalLinkIcon",props:{locales:{type:Object,required:!1,default:()=>({})}},setup(e){const t=kn(),n=j(()=>e.locales[t.value]??{openInNewWindow:"open in new window"});return()=>ce("span",[yf,ce("span",{class:"external-link-icon-sr-only"},n.value.openInNewWindow)])}});var Ef={"/":{openInNewWindow:"open in new window"}};const wf=Ef,xf=rt({enhance({app:e}){e.component("ExternalLinkIcon",ce(kf,{locales:wf}))}});/*! medium-zoom 1.1.0 | MIT License | https://github.com/francoischalifour/medium-zoom */var zt=Object.assign||function(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:{},l=window.Promise||function(L){function $(){}L($,$)},i=function(L){var $=L.target;if($===N){b();return}v.indexOf($)!==-1&&w({target:$})},o=function(){if(!(O||!_.original)){var L=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(G-L)>F.scrollOffset&&setTimeout(b,150)}},r=function(L){var $=L.key||L.keyCode;($==="Escape"||$==="Esc"||$===27)&&b()},a=function(){var L=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},$=L;if(L.background&&(N.style.background=L.background),L.container&&L.container instanceof Object&&($.container=zt({},F.container,L.container)),L.template){var le=pl(L.template)?L.template:document.querySelector(L.template);$.template=le}return F=zt({},F,$),v.forEach(function(se){se.dispatchEvent(on("medium-zoom:update",{detail:{zoom:P}}))}),P},s=function(){var L=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return e(zt({},F,L))},c=function(){for(var L=arguments.length,$=Array(L),le=0;le0?$.reduce(function(D,Z){return[].concat(D,gr(Z))},[]):v;return se.forEach(function(D){D.classList.remove("medium-zoom-image"),D.dispatchEvent(on("medium-zoom:detach",{detail:{zoom:P}}))}),v=v.filter(function(D){return se.indexOf(D)===-1}),P},d=function(L,$){var le=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return v.forEach(function(se){se.addEventListener("medium-zoom:"+L,$,le)}),E.push({type:"medium-zoom:"+L,listener:$,options:le}),P},f=function(L,$){var le=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return v.forEach(function(se){se.removeEventListener("medium-zoom:"+L,$,le)}),E=E.filter(function(se){return!(se.type==="medium-zoom:"+L&&se.listener.toString()===$.toString())}),P},g=function(){var L=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},$=L.target,le=function(){var D={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},Z=void 0,K=void 0;if(F.container)if(F.container instanceof Object)D=zt({},D,F.container),Z=D.width-D.left-D.right-F.margin*2,K=D.height-D.top-D.bottom-F.margin*2;else{var Re=pl(F.container)?F.container:document.querySelector(F.container),Ne=Re.getBoundingClientRect(),Ue=Ne.width,Ve=Ne.height,kt=Ne.left,Et=Ne.top;D=zt({},D,{width:Ue,height:Ve,left:kt,top:Et})}Z=Z||D.width-F.margin*2,K=K||D.height-F.margin*2;var st=_.zoomedHd||_.original,Pe=pr(st)?Z:st.naturalWidth||Z,S=pr(st)?K:st.naturalHeight||K,W=st.getBoundingClientRect(),V=W.top,Y=W.left,ue=W.width,h=W.height,p=Math.min(Math.max(ue,Pe),Z)/ue,m=Math.min(Math.max(h,S),K)/h,k=Math.min(p,m),C=(-Y+(Z-ue)/2+F.margin+D.left)/k,R=(-V+(K-h)/2+F.margin+D.top)/k,B="scale("+k+") translate3d("+C+"px, "+R+"px, 0)";_.zoomed.style.transform=B,_.zoomedHd&&(_.zoomedHd.style.transform=B)};return new l(function(se){if($&&v.indexOf($)===-1){se(P);return}var D=function Ue(){O=!1,_.zoomed.removeEventListener("transitionend",Ue),_.original.dispatchEvent(on("medium-zoom:opened",{detail:{zoom:P}})),se(P)};if(_.zoomed){se(P);return}if($)_.original=$;else if(v.length>0){var Z=v;_.original=Z[0]}else{se(P);return}if(_.original.dispatchEvent(on("medium-zoom:open",{detail:{zoom:P}})),G=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,O=!0,_.zoomed=Sf(_.original),document.body.appendChild(N),F.template){var K=pl(F.template)?F.template:document.querySelector(F.template);_.template=document.createElement("div"),_.template.appendChild(K.content.cloneNode(!0)),document.body.appendChild(_.template)}if(_.original.parentElement&&_.original.parentElement.tagName==="PICTURE"&&_.original.currentSrc&&(_.zoomed.src=_.original.currentSrc),document.body.appendChild(_.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),_.original.classList.add("medium-zoom-image--hidden"),_.zoomed.classList.add("medium-zoom-image--opened"),_.zoomed.addEventListener("click",b),_.zoomed.addEventListener("transitionend",D),_.original.getAttribute("data-zoom-src")){_.zoomedHd=_.zoomed.cloneNode(),_.zoomedHd.removeAttribute("srcset"),_.zoomedHd.removeAttribute("sizes"),_.zoomedHd.removeAttribute("loading"),_.zoomedHd.src=_.zoomed.getAttribute("data-zoom-src"),_.zoomedHd.onerror=function(){clearInterval(Re),console.warn("Unable to reach the zoom image target "+_.zoomedHd.src),_.zoomedHd=null,le()};var Re=setInterval(function(){_.zoomedHd.complete&&(clearInterval(Re),_.zoomedHd.classList.add("medium-zoom-image--opened"),_.zoomedHd.addEventListener("click",b),document.body.appendChild(_.zoomedHd),le())},10)}else if(_.original.hasAttribute("srcset")){_.zoomedHd=_.zoomed.cloneNode(),_.zoomedHd.removeAttribute("sizes"),_.zoomedHd.removeAttribute("loading");var Ne=_.zoomedHd.addEventListener("load",function(){_.zoomedHd.removeEventListener("load",Ne),_.zoomedHd.classList.add("medium-zoom-image--opened"),_.zoomedHd.addEventListener("click",b),document.body.appendChild(_.zoomedHd),le()})}else le()})},b=function(){return new l(function(L){if(O||!_.original){L(P);return}var $=function le(){_.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(_.zoomed),_.zoomedHd&&document.body.removeChild(_.zoomedHd),document.body.removeChild(N),_.zoomed.classList.remove("medium-zoom-image--opened"),_.template&&document.body.removeChild(_.template),O=!1,_.zoomed.removeEventListener("transitionend",le),_.original.dispatchEvent(on("medium-zoom:closed",{detail:{zoom:P}})),_.original=null,_.zoomed=null,_.zoomedHd=null,_.template=null,L(P)};O=!0,document.body.classList.remove("medium-zoom--opened"),_.zoomed.style.transform="",_.zoomedHd&&(_.zoomedHd.style.transform=""),_.template&&(_.template.style.transition="opacity 150ms",_.template.style.opacity=0),_.original.dispatchEvent(on("medium-zoom:close",{detail:{zoom:P}})),_.zoomed.addEventListener("transitionend",$)})},w=function(){var L=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},$=L.target;return _.original?b():g({target:$})},T=function(){return F},x=function(){return v},A=function(){return _.original},v=[],E=[],O=!1,G=0,F=n,_={original:null,zoomed:null,zoomedHd:null,template:null};Object.prototype.toString.call(t)==="[object Object]"?F=t:(t||typeof t=="string")&&c(t),F=zt({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},F);var N=Tf(F.background);document.addEventListener("click",i),document.addEventListener("keyup",r),document.addEventListener("scroll",o),window.addEventListener("resize",b);var P={open:g,close:b,toggle:w,update:a,clone:s,attach:c,detach:u,on:d,off:f,getOptions:T,getImages:x,getZoomedImage:A};return P};function Af(e,t){t===void 0&&(t={});var n=t.insertAt;if(!(typeof document>"u")){var l=document.head||document.getElementsByTagName("head")[0],i=document.createElement("style");i.type="text/css",n==="top"&&l.firstChild?l.insertBefore(i,l.firstChild):l.appendChild(i),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(document.createTextNode(e))}}var Of=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";Af(Of);const Rf=Symbol("mediumZoom");var Pf={};const If=".theme-default-content > img, .theme-default-content :not(a) > img",Df=Pf,Nf=300,Mf=rt({enhance({app:e,router:t}){const n=Cf(Df);n.refresh=(l=If)=>{n.detach(),n.attach(l)},e.provide(Rf,n),t.afterEach(()=>{setTimeout(()=>n.refresh(),Nf)})}});/** + * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT + */const he={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},status:null,set:e=>{const t=he.isStarted();e=oi(e,he.settings.minimum,1),he.status=e===1?null:e;const n=he.render(!t),l=n.querySelector(he.settings.barSelector),i=he.settings.speed,o=he.settings.easing;return n.offsetWidth,$f(r=>{al(l,{transform:"translate3d("+vr(e)+"%,0,0)",transition:"all "+i+"ms "+o}),e===1?(al(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){al(n,{transition:"all "+i+"ms linear",opacity:"0"}),setTimeout(function(){he.remove(),r()},i)},i)):setTimeout(()=>r(),i)}),he},isStarted:()=>typeof he.status=="number",start:()=>{he.status||he.set(0);const e=()=>{setTimeout(()=>{he.status&&(he.trickle(),e())},he.settings.trickleSpeed)};return he.settings.trickle&&e(),he},done:e=>!e&&!he.status?he:he.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=he.status;return t?(typeof e!="number"&&(e=(1-t)*oi(Math.random()*t,.1,.95)),t=oi(t+e,0,.994),he.set(t)):he.start()},trickle:()=>he.inc(Math.random()*he.settings.trickleRate),render:e=>{if(he.isRendered())return document.getElementById("nprogress");mr(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=he.settings.template;const n=t.querySelector(he.settings.barSelector),l=e?"-100":vr(he.status||0),i=document.querySelector(he.settings.parent);return al(n,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),i!==document.body&&mr(i,"nprogress-custom-parent"),i==null||i.appendChild(t),t},remove:()=>{_r(document.documentElement,"nprogress-busy"),_r(document.querySelector(he.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&Ff(e)},isRendered:()=>!!document.getElementById("nprogress")},oi=(e,t,n)=>en?n:e,vr=e=>(-1+e)*100,$f=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),al=function(){const e=["Webkit","O","Moz","ms"],t={};function n(r){return r.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,s){return s.toUpperCase()})}function l(r){const a=document.body.style;if(r in a)return r;let s=e.length;const c=r.charAt(0).toUpperCase()+r.slice(1);let u;for(;s--;)if(u=e[s]+c,u in a)return u;return r}function i(r){return r=n(r),t[r]??(t[r]=l(r))}function o(r,a,s){a=i(a),r.style[a]=s}return function(r,a){for(const s in a){const c=a[s];c!==void 0&&Object.prototype.hasOwnProperty.call(a,s)&&o(r,s,c)}}}(),Qs=(e,t)=>(typeof e=="string"?e:Zi(e)).indexOf(" "+t+" ")>=0,mr=(e,t)=>{const n=Zi(e),l=n+t;Qs(n,t)||(e.className=l.substring(1))},_r=(e,t)=>{const n=Zi(e);if(!Qs(e,t))return;const l=n.replace(" "+t+" "," ");e.className=l.substring(1,l.length-1)},Zi=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),Ff=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},Vf=()=>{Fe(()=>{const e=tn(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||he.start()}),e.afterEach(n=>{t.add(n.path),he.done()})})},Hf=rt({setup(){Vf()}}),jf=JSON.parse(`{"repo":"zachowj/node-red-contrib-home-assistant-websocket","repoLabel":"Github","docsDir":"docs","docsBranch":"main","editLinkText":"Help us improve this page!","navbar":[{"text":"Guides","link":"/guide/"},{"text":"Nodes","link":"/node/"},{"text":"FAQ","link":"/FAQ.md"},{"text":"Cookbook","link":"/cookbook/"},{"text":"Scrubber","link":"/scrubber/"},{"text":"Forums","link":"https://github.com/zachowj/node-red-contrib-home-assistant-websocket/discussions"}],"sidebar":{"/cookbook/":[{"text":"Cookbook","collapsible":false,"children":[{"text":"JSONata","collapsible":false,"children":["/cookbook/jsonata/call-service","/cookbook/jsonata/change-node","/cookbook/jsonata/current-state","/cookbook/jsonata/events-state","/cookbook/jsonata/functions","/cookbook/jsonata/sensor","/cookbook/jsonata/switch-node","/cookbook/jsonata/trigger-state"]},"/cookbook/motion-triggered-light","/cookbook/saving-and-restoring-states","/cookbook/get-state_changed-events-based-on-area","/cookbook/sun-events","/cookbook/vacation-mode","/cookbook/expiration-date-monitor","/cookbook/using-date-and-time-entities-to-trigger-flows","/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours","/cookbook/starting-flow-after-home-assistant-restart","/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled","/cookbook/actionable-notifications-subflow-for-android"]}],"/guide/":[{"text":"Guides","collapsible":false,"children":["/guide/","/guide/first-automation","/guide/action","/guide/conditionals","/guide/mustache-templates",{"text":"JSONata","collapsible":false,"children":["/guide/jsonata/","/guide/jsonata/jsonata-primer"]},"/guide/diagnostics"]},{"text":"Custom Integration","collapsible":false,"children":["/guide/custom_integration/","/guide/custom_integration/exposed-nodes"]},{"text":"Contribute to","collapsible":false,"children":["/guide/development","/guide/documentation"]}],"/node/":[{"text":"Config Nodes","collapsible":true,"children":["device-config","entity-config","config-server"]},{"text":"General Nodes","collapsible":true,"children":["action","API","current-state","device","events-all","events-calendar","events-state","fire-event","get-entities","get-history","poll-state","render-template","sentence","tag","time","trigger-state","wait-until","webhook","zone"]},{"text":"Entity Nodes","collapsible":true,"children":["binary-sensor","button","entity","number","select","sensor","switch","text",{"text":"Time","link":"time-entity"},"update-config"]}]},"locales":{"/":{"selectLanguageName":"English"}},"colorMode":"auto","colorModeSwitch":true,"logo":null,"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebarDepth":2,"editLink":true,"lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),Bf=de(jf),Zs=()=>Bf,Xs=Symbol(""),zf=()=>{const e=Se(Xs);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},Uf=(e,t)=>{const{locales:n,...l}=e;return{...l,...n==null?void 0:n[t]}},Wf=rt({enhance({app:e}){const t=Zs(),n=e._context.provides[Ki],l=j(()=>Uf(t.value,n.value));e.provide(Xs,l),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return l.value}}})}}),Kf=fe({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,n)=>(U(),ee("span",{class:Ke(["badge",e.type]),style:Un({verticalAlign:e.vertical})},[ke(t.$slots,"default",{},()=>[Ft(Ae(e.text),1)])],6))}}),Le=(e,t)=>{const n=e.__vccOpts||e;for(const[l,i]of t)n[l]=i;return n},qf=Le(Kf,[["__file","Badge.vue"]]);function br(e,t){var n;const l=$i();return os(()=>{l.value=e()},{...t,flush:(n=void 0)!=null?n:"sync"}),bn(l)}function Gf(e,t){let n,l,i;const o=de(!0),r=()=>{o.value=!0,i()};qe(e,r,{flush:"sync"});const a=typeof t=="function"?t:t.get,s=typeof t=="function"?void 0:t.set,c=ec((u,d)=>(l=u,i=d,{get(){return o.value&&(n=a(),o.value=!1),l(),n},set(f){s==null||s(f)}}));return Object.isExtensible(c)&&(c.trigger=r),c}function Xi(e){return Ca()?(Aa(e),!0):!1}function Vt(e){return typeof e=="function"?e():ne(e)}const eo=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Jf=Object.prototype.toString,Yf=e=>Jf.call(e)==="[object Object]",Qf=()=>{};function Zf(e,t){function n(...l){return new Promise((i,o)=>{Promise.resolve(e(()=>t.apply(this,l),{fn:t,thisArg:this,args:l})).then(i).catch(o)})}return n}const ea=e=>e();function Xf(e=ea){const t=de(!0);function n(){t.value=!1}function l(){t.value=!0}const i=(...o)=>{t.value&&e(...o)};return{isActive:bn(t),pause:n,resume:l,eventFilter:i}}function eh(e){let t;function n(){return t||(t=e()),t}return n.reset=async()=>{const l=t;t=void 0,l&&await l},n}function th(e){return jl()}function nh(e,t,n={}){const{eventFilter:l=ea,...i}=n;return qe(e,Zf(l,t),i)}function lh(e,t,n={}){const{eventFilter:l,...i}=n,{eventFilter:o,pause:r,resume:a,isActive:s}=Xf(l);return{stop:nh(e,t,{...i,eventFilter:o}),pause:r,resume:a,isActive:s}}function ih(e,t=!0,n){th()?Fe(e,n):t?e():yn(e)}function oh(e,t,n={}){const{immediate:l=!0}=n,i=de(!1);let o=null;function r(){o&&(clearTimeout(o),o=null)}function a(){i.value=!1,r()}function s(...c){r(),i.value=!0,o=setTimeout(()=>{i.value=!1,o=null,e(...c)},Vt(t))}return l&&(i.value=!0,eo&&s()),Xi(a),{isPending:bn(i),start:s,stop:a}}function rh(e=!1,t={}){const{truthyValue:n=!0,falsyValue:l=!1}=t,i=je(e),o=de(e);function r(a){if(arguments.length)return o.value=a,o.value;{const s=Vt(n);return o.value=o.value===s?Vt(l):s,o.value}}return i?r:[o,r]}function sh(e){var t;const n=Vt(e);return(t=n==null?void 0:n.$el)!=null?t:n}const Al=eo?window:void 0,ta=eo?window.navigator:void 0;function Hn(...e){let t,n,l,i;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,l,i]=e,t=Al):[t,n,l,i]=e,!t)return Qf;Array.isArray(n)||(n=[n]),Array.isArray(l)||(l=[l]);const o=[],r=()=>{o.forEach(u=>u()),o.length=0},a=(u,d,f,g)=>(u.addEventListener(d,f,g),()=>u.removeEventListener(d,f,g)),s=qe(()=>[sh(t),Vt(i)],([u,d])=>{if(r(),!u)return;const f=Yf(d)?{...d}:d;o.push(...n.flatMap(g=>l.map(b=>a(u,g,b,f))))},{immediate:!0,flush:"post"}),c=()=>{s(),r()};return Xi(c),c}function ah(){const e=de(!1);return jl()&&Fe(()=>{e.value=!0}),e}function to(e){const t=ah();return j(()=>(t.value,!!e()))}function ch(e,t={}){const{window:n=Al}=t,l=to(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let i;const o=de(!1),r=c=>{o.value=c.matches},a=()=>{i&&("removeEventListener"in i?i.removeEventListener("change",r):i.removeListener(r))},s=os(()=>{l.value&&(a(),i=n.matchMedia(Vt(e)),"addEventListener"in i?i.addEventListener("change",r):i.addListener(r),o.value=i.matches)});return Xi(()=>{s(),a(),i=void 0}),o}function yr(e,t={}){const{controls:n=!1,navigator:l=ta}=t,i=to(()=>l&&"permissions"in l);let o;const r=typeof e=="string"?{name:e}:e,a=de(),s=()=>{o&&(a.value=o.state)},c=eh(async()=>{if(i.value){if(!o)try{o=await l.permissions.query(r),Hn(o,"change",s),s()}catch{a.value="prompt"}return o}});return c(),n?{state:a,isSupported:i,query:c}:a}function uh(e={}){const{navigator:t=ta,read:n=!1,source:l,copiedDuring:i=1500,legacy:o=!1}=e,r=to(()=>t&&"clipboard"in t),a=yr("clipboard-read"),s=yr("clipboard-write"),c=j(()=>r.value||o),u=de(""),d=de(!1),f=oh(()=>d.value=!1,i);function g(){r.value&&a.value!=="denied"?t.clipboard.readText().then(x=>{u.value=x}):u.value=T()}c.value&&n&&Hn(["copy","cut"],g);async function b(x=Vt(l)){c.value&&x!=null&&(r.value&&s.value!=="denied"?await t.clipboard.writeText(x):w(x),u.value=x,d.value=!0,f.start())}function w(x){const A=document.createElement("textarea");A.value=x??"",A.style.position="absolute",A.style.opacity="0",document.body.appendChild(A),A.select(),document.execCommand("copy"),A.remove()}function T(){var x,A,v;return(v=(A=(x=document==null?void 0:document.getSelection)==null?void 0:x.call(document))==null?void 0:A.toString())!=null?v:""}return{isSupported:c,text:u,copied:d,copy:b}}const cl=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},ul="__vueuse_ssr_handlers__",dh=fh();function fh(){return ul in cl||(cl[ul]=cl[ul]||{}),cl[ul]}function hh(e,t){return dh[e]||t}function ph(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const gh={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},kr="vueuse-storage";function na(e,t,n,l={}){var i;const{flush:o="pre",deep:r=!0,listenToStorageChanges:a=!0,writeDefaults:s=!0,mergeDefaults:c=!1,shallow:u,window:d=Al,eventFilter:f,onError:g=N=>{console.error(N)},initOnMounted:b}=l,w=(u?$i:de)(typeof t=="function"?t():t);if(!n)try{n=hh("getDefaultStorage",()=>{var N;return(N=Al)==null?void 0:N.localStorage})()}catch(N){g(N)}if(!n)return w;const T=Vt(t),x=ph(T),A=(i=l.serializer)!=null?i:gh[x],{pause:v,resume:E}=lh(w,()=>O(w.value),{flush:o,deep:r,eventFilter:f});return d&&a&&ih(()=>{Hn(d,"storage",_),Hn(d,kr,F),b&&_()}),b||_(),w;function O(N){try{if(N==null)n.removeItem(e);else{const P=A.write(N),J=n.getItem(e);J!==P&&(n.setItem(e,P),d&&d.dispatchEvent(new CustomEvent(kr,{detail:{key:e,oldValue:J,newValue:P,storageArea:n}})))}}catch(P){g(P)}}function G(N){const P=N?N.newValue:n.getItem(e);if(P==null)return s&&T!=null&&n.setItem(e,A.write(T)),T;if(!N&&c){const J=A.read(P);return typeof c=="function"?c(J,T):x==="object"&&!Array.isArray(J)?{...T,...J}:J}else return typeof P!="string"?P:A.read(P)}function F(N){_(N.detail)}function _(N){if(!(N&&N.storageArea!==n)){if(N&&N.key==null){w.value=T;return}if(!(N&&N.key!==e)){v();try{(N==null?void 0:N.newValue)!==A.write(w.value)&&(w.value=G(N))}catch(P){g(P)}finally{N?yn(E):E()}}}}}function vh(e){return ch("(prefers-color-scheme: dark)",e)}const mh=fe({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const n=de([]),l=de(-1),i=na("vuepress-code-group",{}),o=j(()=>n.value.map(c=>c.innerText).join(","));Fe(()=>{qe(()=>i.value[o.value],(c=-1)=>{l.value!==c&&(l.value=c)},{immediate:!0}),qe(l,c=>{i.value[o.value]!==c&&(i.value[o.value]=c)})});const r=(c=l.value)=>{c{c>0?l.value=c-1:l.value=n.value.length-1,n.value[l.value].focus()},s=(c,u)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),l.value=u):c.key==="ArrowRight"?(c.preventDefault(),r(u)):c.key==="ArrowLeft"&&(c.preventDefault(),a(u))};return()=>{var u;const c=(((u=t.default)==null?void 0:u.call(t))||[]).filter(d=>d.type.name==="CodeGroupItem").map(d=>(d.props===null&&(d.props={}),d));return c.length===0?null:(l.value<0||l.value>c.length-1?(l.value=c.findIndex(d=>d.props.active===""||d.props.active===!0),l.value===-1&&(l.value=0)):c.forEach((d,f)=>{d.props.active=f===l.value}),ce("div",{class:"code-group"},[ce("div",{class:"code-group__nav"},ce("ul",{class:"code-group__ul"},c.map((d,f)=>{const g=f===l.value;return ce("li",{class:"code-group__li"},ce("button",{ref:b=>{b&&(n.value[f]=b)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":g},ariaPressed:g,ariaExpanded:g,onClick:()=>l.value=f,onKeydown:b=>s(b,f)},d.props.title))}))),c]))}}}),_h=["aria-selected"],bh=fe({name:"CodeGroupItem"}),yh=fe({...bh,props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,n)=>(U(),ee("div",{class:Ke(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[ke(t.$slots,"default")],10,_h))}}),kh=Le(yh,[["__file","CodeGroupItem.vue"]]),Eh=()=>Zs(),ze=()=>zf(),la=Symbol(""),no=()=>{const e=Se(la);if(!e)throw new Error("useDarkMode() is called without provider.");return e},wh=()=>{const e=ze(),t=vh(),n=na("vuepress-color-scheme",e.value.colorMode),l=j({get(){return e.value.colorModeSwitch?n.value==="auto"?t.value:n.value==="dark":e.value.colorMode==="dark"},set(i){i===t.value?n.value="auto":n.value=i?"dark":"light"}});Yt(la,l),xh(l)},xh=e=>{const t=(n=e.value)=>{const l=window==null?void 0:window.document.querySelector("html");l==null||l.classList.toggle("dark",n)};Fe(()=>{qe(e,t,{immediate:!0})}),Vl(()=>t())},ia=(...e)=>{const n=tn().resolve(...e),l=n.matched[n.matched.length-1];if(!(l!=null&&l.redirect))return n;const{redirect:i}=l,o=re(i)?i(n):i,r=me(o)?{path:o}:o;return ia({hash:n.hash,query:n.query,params:n.params,...r})},lo=e=>{const t=ia(encodeURI(e));return{text:t.meta.title||e,link:t.name==="404"?e:t.fullPath}};let ri=null,Tn=null;const Lh={wait:()=>ri,pending:()=>{ri=new Promise(e=>Tn=e)},resolve:()=>{Tn==null||Tn(),ri=null,Tn=null}},oa=()=>Lh,ra=Symbol("sidebarItems"),io=()=>{const e=Se(ra);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},Th=()=>{const e=ze(),t=mt(),n=j(()=>Sh(t.value,e.value));Yt(ra,n)},Sh=(e,t)=>{const n=e.sidebar??t.sidebar??"auto",l=e.sidebarDepth??t.sidebarDepth??2;return e.home||n===!1?[]:n==="auto"?Ah(l):Q(n)?sa(n,l):Wi(n)?Oh(n,l):[]},Ch=(e,t)=>({text:e.title,link:e.link,children:oo(e.children,t)}),oo=(e,t)=>t>0?e.map(n=>Ch(n,t-1)):[],Ah=e=>{const t=It();return[{text:t.value.title,children:oo(t.value.headers,e)}]},sa=(e,t)=>{const n=nn(),l=It(),i=o=>{var a;let r;if(me(o)?r=lo(o):r=o,r.children)return{...r,children:r.children.map(s=>i(s))};if(r.link===n.path){const s=((a=l.value.headers[0])==null?void 0:a.level)===1?l.value.headers[0].children:l.value.headers;return{...r,children:oo(s,t)}}return r};return e.map(o=>i(o))},Oh=(e,t)=>{const n=nn(),l=Os(e,n.path),i=e[l]??[];return sa(i,t)},Rh="719px",Ph={mobile:Rh};var jn;(function(e){e.MOBILE="mobile"})(jn||(jn={}));var Sr;const Ih={[jn.MOBILE]:Number.parseInt((Sr=Ph.mobile)==null?void 0:Sr.replace("px",""),10)},aa=(e,t)=>{const n=Ih[e];Number.isInteger(n)&&Fe(()=>{t(n),window.addEventListener("resize",()=>t(n),!1),window.addEventListener("orientationchange",()=>t(n),!1)})},Dh={},Nh={class:"theme-default-content"};function Mh(e,t){const n=bt("Content");return U(),ee("div",Nh,[ie(n)])}const $h=Le(Dh,[["render",Mh],["__file","HomeContent.vue"]]),Fh={key:0,class:"features"},Vh=fe({__name:"HomeFeatures",setup(e){const t=mt(),n=j(()=>Q(t.value.features)?t.value.features:[]);return(l,i)=>n.value.length?(U(),ee("div",Fh,[(U(!0),ee(Ee,null,Mt(n.value,o=>(U(),ee("div",{key:o.title,class:"feature"},[ge("h2",null,Ae(o.title),1),ge("p",null,Ae(o.details),1)]))),128))])):Te("v-if",!0)}}),Hh=Le(Vh,[["__file","HomeFeatures.vue"]]),jh=["innerHTML"],Bh=["textContent"],zh=fe({__name:"HomeFooter",setup(e){const t=mt(),n=j(()=>t.value.footer),l=j(()=>t.value.footerHtml);return(i,o)=>n.value?(U(),ee(Ee,{key:0},[Te(" eslint-disable-next-line vue/no-v-html "),l.value?(U(),ee("div",{key:0,class:"footer",innerHTML:n.value},null,8,jh)):(U(),ee("div",{key:1,class:"footer",textContent:Ae(n.value)},null,8,Bh))],64)):Te("v-if",!0)}}),Uh=Le(zh,[["__file","HomeFooter.vue"]]),Wh=["href","rel","target","aria-label"],Kh=fe({inheritAttrs:!1}),qh=fe({...Kh,__name:"AutoLink",props:{item:{type:Object,required:!0}},setup(e){const t=e,n=nn(),l=$s(),{item:i}=Nl(t),o=j(()=>Qn(i.value.link)),r=j(()=>!o.value&&Yu(i.value.link)),a=j(()=>{if(!r.value){if(i.value.target)return i.value.target;if(o.value)return"_blank"}}),s=j(()=>a.value==="_blank"),c=j(()=>!o.value&&!r.value&&!s.value),u=j(()=>{if(!r.value){if(i.value.rel)return i.value.rel;if(s.value)return"noopener noreferrer"}}),d=j(()=>i.value.ariaLabel||i.value.text),f=j(()=>{const w=Object.keys(l.value.locales);return w.length?!w.some(T=>T===i.value.link):i.value.link!=="/"}),g=j(()=>f.value?n.path.startsWith(i.value.link):!1),b=j(()=>c.value?i.value.activeMatch?new RegExp(i.value.activeMatch).test(n.path):g.value:!1);return(w,T)=>{const x=bt("RouterLink"),A=bt("AutoLinkExternalIcon");return c.value?(U(),Ce(x,bi({key:0,class:{"router-link-active":b.value},to:ne(i).link,"aria-label":d.value},w.$attrs),{default:Me(()=>[ke(w.$slots,"before"),Ft(" "+Ae(ne(i).text)+" ",1),ke(w.$slots,"after")]),_:3},16,["class","to","aria-label"])):(U(),ee("a",bi({key:1,class:"external-link",href:ne(i).link,rel:u.value,target:a.value,"aria-label":d.value},w.$attrs),[ke(w.$slots,"before"),Ft(" "+Ae(ne(i).text)+" ",1),s.value?(U(),Ce(A,{key:0})):Te("v-if",!0),ke(w.$slots,"after")],16,Wh))}}}),_t=Le(qh,[["__file","AutoLink.vue"]]),Gh={class:"hero"},Jh={key:0,id:"main-title"},Yh={key:1,class:"description"},Qh={key:2,class:"actions"},Zh=fe({__name:"HomeHero",setup(e){const t=mt(),n=qi(),l=no(),i=j(()=>l.value&&t.value.heroImageDark!==void 0?t.value.heroImageDark:t.value.heroImage),o=j(()=>t.value.heroAlt||a.value||"hero"),r=j(()=>t.value.heroHeight||280),a=j(()=>t.value.heroText===null?null:t.value.heroText||n.value.title||"Hello"),s=j(()=>t.value.tagline===null?null:t.value.tagline||n.value.description||"Welcome to your VuePress site"),c=j(()=>Q(t.value.actions)?t.value.actions.map(({text:d,link:f,type:g="primary"})=>({text:d,link:f,type:g})):[]),u=()=>{if(!i.value)return null;const d=ce("img",{src:Ji(i.value),alt:o.value,height:r.value});return t.value.heroImageDark===void 0?d:ce(Gi,()=>d)};return(d,f)=>(U(),ee("header",Gh,[ie(u),a.value?(U(),ee("h1",Jh,Ae(a.value),1)):Te("v-if",!0),s.value?(U(),ee("p",Yh,Ae(s.value),1)):Te("v-if",!0),c.value.length?(U(),ee("p",Qh,[(U(!0),ee(Ee,null,Mt(c.value,g=>(U(),Ce(_t,{key:g.text,class:Ke(["action-button",[g.type]]),item:g},null,8,["class","item"]))),128))])):Te("v-if",!0)]))}}),Xh=Le(Zh,[["__file","HomeHero.vue"]]),ep={class:"home"},tp=fe({__name:"Home",setup(e){return(t,n)=>(U(),ee("main",ep,[ie(Xh),ie(Hh),ie($h),ie(Uh)]))}}),np=Le(tp,[["__file","Home.vue"]]),lp=fe({__name:"NavbarBrand",setup(e){const t=kn(),n=qi(),l=ze(),i=no(),o=j(()=>l.value.home||t.value),r=j(()=>n.value.title),a=j(()=>i.value&&l.value.logoDark!==void 0?l.value.logoDark:l.value.logo),s=()=>{if(!a.value)return null;const c=ce("img",{class:"logo",src:Ji(a.value),alt:r.value});return l.value.logoDark===void 0?c:ce(Gi,()=>c)};return(c,u)=>{const d=bt("RouterLink");return U(),Ce(d,{to:o.value},{default:Me(()=>[ie(s),r.value?(U(),ee("span",{key:0,class:Ke(["site-name",{"can-hide":a.value}])},Ae(r.value),3)):Te("v-if",!0)]),_:1},8,["to"])}}}),ip=Le(lp,[["__file","NavbarBrand.vue"]]),op=fe({__name:"DropdownTransition",setup(e){const t=l=>{l.style.height=l.scrollHeight+"px"},n=l=>{l.style.height=""};return(l,i)=>(U(),Ce(Yn,{name:"dropdown",onEnter:t,onAfterEnter:n,onBeforeLeave:t},{default:Me(()=>[ke(l.$slots,"default")]),_:3}))}}),ca=Le(op,[["__file","DropdownTransition.vue"]]),rp=["aria-label"],sp={class:"title"},ap=ge("span",{class:"arrow down"},null,-1),cp=["aria-label"],up={class:"title"},dp={class:"navbar-dropdown"},fp={class:"navbar-dropdown-subtitle"},hp={key:1},pp={class:"navbar-dropdown-subitem-wrapper"},gp=fe({__name:"NavbarDropdown",props:{item:{type:Object,required:!0}},setup(e){const t=e,{item:n}=Nl(t),l=j(()=>n.value.ariaLabel||n.value.text),i=de(!1),o=nn();qe(()=>o.path,()=>{i.value=!1});const r=s=>{s.detail===0?i.value=!i.value:i.value=!1},a=(s,c)=>c[c.length-1]===s;return(s,c)=>(U(),ee("div",{class:Ke(["navbar-dropdown-wrapper",{open:i.value}])},[ge("button",{class:"navbar-dropdown-title",type:"button","aria-label":l.value,onClick:r},[ge("span",sp,Ae(ne(n).text),1),ap],8,rp),ge("button",{class:"navbar-dropdown-title-mobile",type:"button","aria-label":l.value,onClick:c[0]||(c[0]=u=>i.value=!i.value)},[ge("span",up,Ae(ne(n).text),1),ge("span",{class:Ke(["arrow",i.value?"down":"right"])},null,2)],8,cp),ie(ca,null,{default:Me(()=>[kl(ge("ul",dp,[(U(!0),ee(Ee,null,Mt(ne(n).children,u=>(U(),ee("li",{key:u.text,class:"navbar-dropdown-item"},[u.children?(U(),ee(Ee,{key:0},[ge("h4",fp,[u.link?(U(),Ce(_t,{key:0,item:u,onFocusout:d=>a(u,ne(n).children)&&u.children.length===0&&(i.value=!1)},null,8,["item","onFocusout"])):(U(),ee("span",hp,Ae(u.text),1))]),ge("ul",pp,[(U(!0),ee(Ee,null,Mt(u.children,d=>(U(),ee("li",{key:d.link,class:"navbar-dropdown-subitem"},[ie(_t,{item:d,onFocusout:f=>a(d,u.children)&&a(u,ne(n).children)&&(i.value=!1)},null,8,["item","onFocusout"])]))),128))])],64)):(U(),Ce(_t,{key:1,item:u,onFocusout:d=>a(u,ne(n).children)&&(i.value=!1)},null,8,["item","onFocusout"]))]))),128))],512),[[Tl,i.value]])]),_:1})],2))}}),vp=Le(gp,[["__file","NavbarDropdown.vue"]]),Er=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),mp=(e,t)=>{if(t.hash===e)return!0;const n=Er(t.path),l=Er(e);return n===l},ua=(e,t)=>e.link&&mp(e.link,t)?!0:e.children?e.children.some(n=>ua(n,t)):!1,da=e=>!Qn(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,_p={GitHub:":repo/edit/:branch/:path",GitLab:":repo/-/edit/:branch/:path",Gitee:":repo/edit/:branch/:path",Bitbucket:":repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default"},bp=({docsRepo:e,editLinkPattern:t})=>{if(t)return t;const n=da(e);return n!==null?_p[n]:null},yp=({docsRepo:e,docsBranch:t,docsDir:n,filePathRelative:l,editLinkPattern:i})=>{if(!l)return null;const o=bp({docsRepo:e,editLinkPattern:i});return o?o.replace(/:repo/,Qn(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,As(`${Cs(n)}/${l}`)):null},kp={key:0,class:"navbar-items"},Ep=fe({__name:"NavbarItems",setup(e){const t=()=>{const u=tn(),d=kn(),f=$s(),g=qi(),b=Eh(),w=ze();return j(()=>{const T=Object.keys(f.value.locales);if(T.length<2)return[];const x=u.currentRoute.value.path,A=u.currentRoute.value.fullPath;return[{text:`${w.value.selectLanguageText}`,ariaLabel:`${w.value.selectLanguageAriaLabel??w.value.selectLanguageText}`,children:T.map(E=>{var P,J;const O=((P=f.value.locales)==null?void 0:P[E])??{},G=((J=b.value.locales)==null?void 0:J[E])??{},F=`${O.lang}`,_=G.selectLanguageName??F;let N;if(F===g.value.lang)N=A;else{const L=x.replace(d.value,E);u.getRoutes().some($=>$.path===L)?N=A.replace(x,L):N=G.home??E}return{text:_,link:N}})}]})},n=()=>{const u=ze(),d=j(()=>u.value.repo),f=j(()=>d.value?da(d.value):null),g=j(()=>d.value&&!Qn(d.value)?`https://github.com/${d.value}`:d.value),b=j(()=>g.value?u.value.repoLabel?u.value.repoLabel:f.value===null?"Source":f.value:null);return j(()=>!g.value||!b.value?[]:[{text:b.value,link:g.value}])},l=u=>me(u)?lo(u):u.children?{...u,children:u.children.map(l)}:u,i=()=>{const u=ze();return j(()=>(u.value.navbar||[]).map(l))},o=de(!1),r=i(),a=t(),s=n(),c=j(()=>[...r.value,...a.value,...s.value]);return aa(jn.MOBILE,u=>{window.innerWidthc.value.length?(U(),ee("nav",kp,[(U(!0),ee(Ee,null,Mt(c.value,f=>(U(),ee("div",{key:f.text,class:"navbar-item"},[f.children?(U(),Ce(vp,{key:0,item:f,class:Ke(o.value?"mobile":"")},null,8,["item","class"])):(U(),Ce(_t,{key:1,item:f},null,8,["item"]))]))),128))])):Te("v-if",!0)}}),fa=Le(Ep,[["__file","NavbarItems.vue"]]),wp=["title"],xp={class:"icon",focusable:"false",viewBox:"0 0 32 32"},Lp=tu('',9),Tp=[Lp],Sp={class:"icon",focusable:"false",viewBox:"0 0 32 32"},Cp=ge("path",{d:"M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z",fill:"currentColor"},null,-1),Ap=[Cp],Op=fe({__name:"ToggleColorModeButton",setup(e){const t=ze(),n=no(),l=()=>{n.value=!n.value};return(i,o)=>(U(),ee("button",{class:"toggle-color-mode-button",title:ne(t).toggleColorMode,onClick:l},[kl((U(),ee("svg",xp,Tp,512)),[[Tl,!ne(n)]]),kl((U(),ee("svg",Sp,Ap,512)),[[Tl,ne(n)]])],8,wp))}}),Rp=Le(Op,[["__file","ToggleColorModeButton.vue"]]),Pp=["title"],Ip=ge("div",{class:"icon","aria-hidden":"true"},[ge("span"),ge("span"),ge("span")],-1),Dp=[Ip],Np=fe({__name:"ToggleSidebarButton",emits:["toggle"],setup(e){const t=ze();return(n,l)=>(U(),ee("div",{class:"toggle-sidebar-button",title:ne(t).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:l[0]||(l[0]=i=>n.$emit("toggle"))},Dp,8,Pp))}}),Mp=Le(Np,[["__file","ToggleSidebarButton.vue"]]),$p=fe({__name:"Navbar",emits:["toggle-sidebar"],setup(e){const t=ze(),n=de(null),l=de(null),i=de(0),o=j(()=>i.value?{maxWidth:i.value+"px"}:{});aa(jn.MOBILE,a=>{var c;const s=r(n.value,"paddingLeft")+r(n.value,"paddingRight");window.innerWidth{const c=bt("NavbarSearch");return U(),ee("header",{ref_key:"navbar",ref:n,class:"navbar"},[ie(Mp,{onToggle:s[0]||(s[0]=u=>a.$emit("toggle-sidebar"))}),ge("span",{ref_key:"navbarBrand",ref:l},[ie(ip)],512),ge("div",{class:"navbar-items-wrapper",style:Un(o.value)},[ke(a.$slots,"before"),ie(fa,{class:"can-hide"}),ke(a.$slots,"after"),ne(t).colorModeSwitch?(U(),Ce(Rp,{key:0})):Te("v-if",!0),ie(c)],4)],512)}}}),Fp=Le($p,[["__file","Navbar.vue"]]),Vp={class:"page-meta"},Hp={key:0,class:"meta-item edit-link"},jp={key:1,class:"meta-item last-updated"},Bp={class:"meta-item-label"},zp={class:"meta-item-info"},Up={key:2,class:"meta-item contributors"},Wp={class:"meta-item-label"},Kp={class:"meta-item-info"},qp=["title"],Gp=fe({__name:"PageMeta",setup(e){const t=()=>{const s=ze(),c=It(),u=mt();return j(()=>{if(!(u.value.editLink??s.value.editLink??!0))return null;const{repo:f,docsRepo:g=f,docsBranch:b="main",docsDir:w="",editLinkText:T}=s.value;if(!g)return null;const x=yp({docsRepo:g,docsBranch:b,docsDir:w,filePathRelative:c.value.filePathRelative,editLinkPattern:u.value.editLinkPattern??s.value.editLinkPattern});return x?{text:T??"Edit this page",link:x}:null})},n=()=>{const s=ze(),c=It(),u=mt();return j(()=>{var g,b;return!(u.value.lastUpdated??s.value.lastUpdated??!0)||!((g=c.value.git)!=null&&g.updatedTime)?null:new Date((b=c.value.git)==null?void 0:b.updatedTime).toLocaleString()})},l=()=>{const s=ze(),c=It(),u=mt();return j(()=>{var f;return u.value.contributors??s.value.contributors??!0?((f=c.value.git)==null?void 0:f.contributors)??null:null})},i=ze(),o=t(),r=n(),a=l();return(s,c)=>{const u=bt("ClientOnly");return U(),ee("footer",Vp,[ne(o)?(U(),ee("div",Hp,[ie(_t,{class:"meta-item-label",item:ne(o)},null,8,["item"])])):Te("v-if",!0),ne(r)?(U(),ee("div",jp,[ge("span",Bp,Ae(ne(i).lastUpdatedText)+": ",1),ie(u,null,{default:Me(()=>[ge("span",zp,Ae(ne(r)),1)]),_:1})])):Te("v-if",!0),ne(a)&&ne(a).length?(U(),ee("div",Up,[ge("span",Wp,Ae(ne(i).contributorsText)+": ",1),ge("span",Kp,[(U(!0),ee(Ee,null,Mt(ne(a),(d,f)=>(U(),ee(Ee,{key:f},[ge("span",{class:"contributor",title:`email: ${d.email}`},Ae(d.name),9,qp),f!==ne(a).length-1?(U(),ee(Ee,{key:0},[Ft(", ")],64)):Te("v-if",!0)],64))),128))])])):Te("v-if",!0)])}}}),Jp=Le(Gp,[["__file","PageMeta.vue"]]),Yp={key:0,class:"page-nav"},Qp={class:"inner"},Zp={key:0,class:"prev"},Xp={key:1,class:"next"},eg=fe({__name:"PageNav",setup(e){const t=s=>s===!1?null:me(s)?lo(s):Wi(s)?s:!1,n=(s,c,u)=>{const d=s.findIndex(f=>f.link===c);if(d!==-1){const f=s[d+u];return f!=null&&f.link?f:null}for(const f of s)if(f.children){const g=n(f.children,c,u);if(g)return g}return null},l=mt(),i=io(),o=nn(),r=j(()=>{const s=t(l.value.prev);return s!==!1?s:n(i.value,o.path,-1)}),a=j(()=>{const s=t(l.value.next);return s!==!1?s:n(i.value,o.path,1)});return(s,c)=>r.value||a.value?(U(),ee("nav",Yp,[ge("p",Qp,[r.value?(U(),ee("span",Zp,[ie(_t,{item:r.value},null,8,["item"])])):Te("v-if",!0),a.value?(U(),ee("span",Xp,[ie(_t,{item:a.value},null,8,["item"])])):Te("v-if",!0)])])):Te("v-if",!0)}}),tg=Le(eg,[["__file","PageNav.vue"]]),ng={class:"page"},lg={class:"theme-default-content"},ig=fe({__name:"Page",setup(e){return(t,n)=>{const l=bt("Content");return U(),ee("main",ng,[ke(t.$slots,"top"),ge("div",lg,[ke(t.$slots,"content-top"),ie(l),ke(t.$slots,"content-bottom")]),ie(Jp),ie(tg),ke(t.$slots,"bottom")])}}}),og=Le(ig,[["__file","Page.vue"]]),rg={class:"sidebar-item-children"},sg=fe({__name:"SidebarItem",props:{item:{type:Object,required:!0},depth:{type:Number,required:!1,default:0}},setup(e){const t=e,{item:n,depth:l}=Nl(t),i=nn(),o=tn(),r=j(()=>ua(n.value,i)),a=j(()=>({"sidebar-item":!0,"sidebar-heading":l.value===0,active:r.value,collapsible:n.value.collapsible})),s=j(()=>n.value.collapsible?r.value:!0),[c,u]=rh(s.value),d=g=>{n.value.collapsible&&(g.preventDefault(),u())},f=o.afterEach(g=>{yn(()=>{c.value=s.value})});return Gn(()=>{f()}),(g,b)=>{var T;const w=bt("SidebarItem",!0);return U(),ee("li",null,[ne(n).link?(U(),Ce(_t,{key:0,class:Ke(a.value),item:ne(n)},null,8,["class","item"])):(U(),ee("p",{key:1,tabindex:"0",class:Ke(a.value),onClick:d,onKeydown:Fu(d,["enter"])},[Ft(Ae(ne(n).text)+" ",1),ne(n).collapsible?(U(),ee("span",{key:0,class:Ke(["arrow",ne(c)?"down":"right"])},null,2)):Te("v-if",!0)],34)),(T=ne(n).children)!=null&&T.length?(U(),Ce(ca,{key:2},{default:Me(()=>[kl(ge("ul",rg,[(U(!0),ee(Ee,null,Mt(ne(n).children,x=>(U(),Ce(w,{key:`${ne(l)}${x.text}${x.link}`,item:x,depth:ne(l)+1},null,8,["item","depth"]))),128))],512),[[Tl,ne(c)]])]),_:1})):Te("v-if",!0)])}}}),ag=Le(sg,[["__file","SidebarItem.vue"]]),cg={key:0,class:"sidebar-items"},ug=fe({__name:"SidebarItems",setup(e){const t=nn(),n=io();return Fe(()=>{qe(()=>t.hash,l=>{const i=document.querySelector(".sidebar");if(!i)return;const o=document.querySelector(`.sidebar a.sidebar-item[href="${t.path}${l}"]`);if(!o)return;const{top:r,height:a}=i.getBoundingClientRect(),{top:s,height:c}=o.getBoundingClientRect();sr+a&&o.scrollIntoView(!1)})}),(l,i)=>ne(n).length?(U(),ee("ul",cg,[(U(!0),ee(Ee,null,Mt(ne(n),o=>(U(),Ce(ag,{key:`${o.text}${o.link}`,item:o},null,8,["item"]))),128))])):Te("v-if",!0)}}),dg=Le(ug,[["__file","SidebarItems.vue"]]),fg={class:"sidebar"},hg=fe({__name:"Sidebar",setup(e){return(t,n)=>(U(),ee("aside",fg,[ie(fa),ke(t.$slots,"top"),ie(dg),ke(t.$slots,"bottom")]))}}),pg=Le(hg,[["__file","Sidebar.vue"]]),gg=fe({__name:"Layout",setup(e){const t=It(),n=mt(),l=ze(),i=j(()=>n.value.navbar!==!1&&l.value.navbar!==!1),o=io(),r=de(!1),a=T=>{r.value=typeof T=="boolean"?T:!r.value},s={x:0,y:0},c=T=>{s.x=T.changedTouches[0].clientX,s.y=T.changedTouches[0].clientY},u=T=>{const x=T.changedTouches[0].clientX-s.x,A=T.changedTouches[0].clientY-s.y;Math.abs(x)>Math.abs(A)&&Math.abs(x)>40&&(x>0&&s.x<=80?a(!0):a(!1))},d=j(()=>[{"no-navbar":!i.value,"no-sidebar":!o.value.length,"sidebar-open":r.value},n.value.pageClass]);let f;Fe(()=>{f=tn().afterEach(()=>{a(!1)})}),Vl(()=>{f()});const g=oa(),b=g.resolve,w=g.pending;return(T,x)=>(U(),ee("div",{class:Ke(["theme-container",d.value]),onTouchstart:c,onTouchend:u},[ke(T.$slots,"navbar",{},()=>[i.value?(U(),Ce(Fp,{key:0,onToggleSidebar:a},{before:Me(()=>[ke(T.$slots,"navbar-before")]),after:Me(()=>[ke(T.$slots,"navbar-after")]),_:3})):Te("v-if",!0)]),ge("div",{class:"sidebar-mask",onClick:x[0]||(x[0]=A=>a(!1))}),ke(T.$slots,"sidebar",{},()=>[ie(pg,null,{top:Me(()=>[ke(T.$slots,"sidebar-top")]),bottom:Me(()=>[ke(T.$slots,"sidebar-bottom")]),_:3})]),ke(T.$slots,"page",{},()=>[ne(n).home?(U(),Ce(np,{key:0})):(U(),Ce(Yn,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:ne(b),onBeforeLeave:ne(w)},{default:Me(()=>[(U(),Ce(og,{key:ne(t).path},{top:Me(()=>[ke(T.$slots,"page-top")]),"content-top":Me(()=>[ke(T.$slots,"page-content-top")]),"content-bottom":Me(()=>[ke(T.$slots,"page-content-bottom")]),bottom:Me(()=>[ke(T.$slots,"page-bottom")]),_:3}))]),_:3},8,["onBeforeEnter","onBeforeLeave"]))])],34))}}),vg=Le(gg,[["__file","Layout.vue"]]),mg={class:"theme-container"},_g={class:"page"},bg={class:"theme-default-content"},yg=ge("h1",null,"404",-1),kg=fe({__name:"NotFound",setup(e){const t=kn(),n=ze(),l=n.value.notFound??["Not Found"],i=()=>l[Math.floor(Math.random()*l.length)],o=n.value.home??t.value,r=n.value.backToHome??"Back to home";return(a,s)=>{const c=bt("RouterLink");return U(),ee("div",mg,[ge("main",_g,[ge("div",bg,[yg,ge("blockquote",null,Ae(i()),1),ie(c,{to:ne(o)},{default:Me(()=>[Ft(Ae(ne(r)),1)]),_:1},8,["to"])])])])}}}),Eg=Le(kg,[["__file","NotFound.vue"]]),wg=rt({enhance({app:e,router:t}){e.component("Badge",qf),e.component("CodeGroup",mh),e.component("CodeGroupItem",kh),e.component("AutoLinkExternalIcon",()=>{const l=e.component("ExternalLinkIcon");return l?ce(l):null}),e.component("NavbarSearch",()=>{const l=e.component("Docsearch")||e.component("SearchBox");return l?ce(l):null});const n=t.options.scrollBehavior;t.options.scrollBehavior=async(...l)=>(await oa().wait(),n(...l))},setup(){wh(),Th()},layouts:{Layout:vg,NotFound:Eg}}),xg=e=>{if(window.dataLayer&&window.gtag)return;const t=document.createElement("script");t.src=`https://www.googletagmanager.com/gtag/js?id=${e.id}`,t.async=!0,document.head.appendChild(t),window.dataLayer=window.dataLayer||[],window.gtag=function(){dataLayer.push(arguments)},gtag("js",new Date),e.debug?gtag("config",e.id,{debug_mode:!0}):gtag("config",e.id)};var Lg={id:"G-T0F3RKFVF3"};const Tg=Lg,Sg=rt({enhance(){xg(Tg)}}),Cg={};function Ag(){const e=de(!1);return jl()&&Fe(()=>{e.value=!0}),e}function Og(e){return Ag(),j(()=>!!e())}const Rg=()=>Og(()=>typeof window<"u"&&window.navigator&&"userAgent"in window.navigator),Pg=()=>{const e=Rg();return j(()=>e.value&&/\b(?:Android|iPhone)/i.test(navigator.userAgent))},Ig=e=>{const t=kn();return j(()=>e[t.value])};var Dg={"/":{copy:"Copy code",copied:"Copied",hint:"Copied successfully"}},Ng=['.theme-default-content div[class*="language-"] pre'];const Mg=800,$g=2e3,Fg=Dg,Vg=Ng,wr=!1,si=new Map,Hg=()=>{const{copy:e}=uh({legacy:!0}),t=Ig(Fg),n=It(),l=Pg(),i=a=>{if(!a.hasAttribute("copy-code-registered")){const s=document.createElement("button");s.type="button",s.classList.add("copy-code-button"),s.innerHTML='
',s.setAttribute("aria-label",t.value.copy),s.setAttribute("data-copied",t.value.copied),a.parentElement&&a.parentElement.insertBefore(s,a),a.setAttribute("copy-code-registered","")}},o=()=>yn().then(()=>new Promise(a=>{setTimeout(()=>{Vg.forEach(s=>{document.querySelectorAll(s).forEach(i)}),a()},Mg)})),r=(a,s,c)=>{let{innerText:u=""}=s;/language-(shellscript|shell|bash|sh|zsh)/.test(a.classList.toString())&&(u=u.replace(/^ *(\$|>) /gm,"")),e(u).then(()=>{c.classList.add("copied"),clearTimeout(si.get(c));const d=setTimeout(()=>{c.classList.remove("copied"),c.blur(),si.delete(c)},$g);si.set(c,d)})};Fe(()=>{(!l.value||wr)&&o(),Hn("click",a=>{const s=a.target;if(s.matches('div[class*="language-"] > button.copy')){const c=s.parentElement,u=s.nextElementSibling;u&&r(c,u,s)}else if(s.matches('div[class*="language-"] div.copy-icon')){const c=s.parentElement,u=c.parentElement,d=c.nextElementSibling;d&&r(u,d,c)}}),qe(()=>n.value.path,()=>{(!l.value||wr)&&o()})})};var jg=rt({setup:()=>{Hg()}});const Bg={enhance:({app:e})=>{e.component("DocsOnly",z(()=>y(()=>import("./DocsOnly-DuK4YSKt.js"),__vite__mapDeps([])))),e.component("InfoPanelOnly",z(()=>y(()=>import("./InfoPanelOnly-hbUXTFuy.js"),__vite__mapDeps([])))),e.component("Scrubber",z(()=>y(()=>import("./Scrubber-DmfvHnqw.js"),__vite__mapDeps([]))))}},zg=e=>e instanceof Element?document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")):!1,Ug=(e,t)=>t.some(n=>{if(me(n))return n===e.key;const{key:l,ctrl:i=!1,shift:o=!1,alt:r=!1}=n;return l===e.key&&i===e.ctrlKey&&o===e.shiftKey&&r===e.altKey}),Wg=/[^\x00-\x7F]/,Kg=e=>e.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t),xr=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),Lr=(e,t)=>{const n=t.join(" "),l=Kg(e);if(Wg.test(e))return l.some(r=>n.toLowerCase().indexOf(r)>-1);const i=e.endsWith(" ");return new RegExp(l.map((r,a)=>l.length===a+1&&!i?`(?=.*\\b${xr(r)})`:`(?=.*\\b${xr(r)}\\b)`).join("")+".+","gi").test(n)},qg=({input:e,hotKeys:t})=>{if(t.value.length===0)return;const n=l=>{e.value&&Ug(l,t.value)&&!zg(l.target)&&(l.preventDefault(),e.value.focus())};Fe(()=>{document.addEventListener("keydown",n)}),Gn(()=>{document.removeEventListener("keydown",n)})},Gg=[{title:"FAQ",headers:[{level:2,title:"What is what",slug:"what-is-what",link:"#what-is-what",children:[]},{level:2,title:"Entities not showing in the autocomplete dropdown",slug:"entities-not-showing-in-the-autocomplete-dropdown",link:"#entities-not-showing-in-the-autocomplete-dropdown",children:[]},{level:2,title:"Entity could not be found in cache for entity_id: ???",slug:"entity-could-not-be-found-in-cache-for-entity-id",link:"#entity-could-not-be-found-in-cache-for-entity-id",children:[]},{level:2,title:"Why do some of my nodes have a yellow font?",slug:"why-do-some-of-my-nodes-have-a-yellow-font",link:"#why-do-some-of-my-nodes-have-a-yellow-font",children:[]}],path:"/FAQ.html",pathLocale:"/",extraFields:[]},{title:"",headers:[],path:"/",pathLocale:"/",extraFields:[]},{title:"Cookbook",headers:[],path:"/cookbook/",pathLocale:"/",extraFields:[]},{title:"Actionable Notifications Subflow for Android",headers:[{level:2,title:"Demo flow",slug:"demo-flow",link:"#demo-flow",children:[]},{level:2,title:"Use Case 1: Get a notification when garage door is left open with ability to ignore the alert for an amount of time",slug:"use-case-1-get-a-notification-when-garage-door-is-left-open-with-ability-to-ignore-the-alert-for-an-amount-of-time",link:"#use-case-1-get-a-notification-when-garage-door-is-left-open-with-ability-to-ignore-the-alert-for-an-amount-of-time",children:[]},{level:2,title:"Use Case 2: Ask if vacation mode should be turned on after being away for 24 hours",slug:"use-case-2-ask-if-vacation-mode-should-be-turned-on-after-being-away-for-24-hours",link:"#use-case-2-ask-if-vacation-mode-should-be-turned-on-after-being-away-for-24-hours",children:[]}],path:"/cookbook/actionable-notifications-subflow-for-android.html",pathLocale:"/",extraFields:[]},{title:"Check if an entity was a certain state in the last 24 hours",headers:[],path:"/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html",pathLocale:"/",extraFields:[]},{title:"Expiration Date Monitor with notification",headers:[{level:2,title:"Home Assistant stuff",slug:"home-assistant-stuff",link:"#home-assistant-stuff",children:[]},{level:2,title:"Node-RED stuff",slug:"node-red-stuff",link:"#node-red-stuff",children:[]}],path:"/cookbook/expiration-date-monitor.html",pathLocale:"/",extraFields:[]},{title:"Get state_changed Events Based on Area",headers:[],path:"/cookbook/get-state_changed-events-based-on-area.html",pathLocale:"/",extraFields:[]},{title:"Holiday lights scheduler and demo mode for WLED",headers:[{level:3,title:"Version 1",slug:"version-1",link:"#version-1",children:[]},{level:2,title:"Requirements",slug:"requirements",link:"#requirements",children:[{level:3,title:"Integrations",slug:"integrations",link:"#integrations",children:[]},{level:3,title:"Nodes",slug:"nodes",link:"#nodes",children:[]}]},{level:2,title:"Setup",slug:"setup",link:"#setup",children:[{level:3,title:"WLED variables",slug:"wled-variables",link:"#wled-variables",children:[]},{level:3,title:"Setting date ranges up",slug:"setting-date-ranges-up",link:"#setting-date-ranges-up",children:[]},{level:3,title:"Home Assistant Entities",slug:"home-assistant-entities",link:"#home-assistant-entities",children:[]}]},{level:2,title:"Lovelace UI",slug:"lovelace-ui",link:"#lovelace-ui",children:[]},{level:2,title:"Things that could have been added but never got around to it",slug:"things-that-could-have-been-added-but-never-got-around-to-it",link:"#things-that-could-have-been-added-but-never-got-around-to-it",children:[]}],path:"/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.html",pathLocale:"/",extraFields:[]},{title:"Motion Triggered Light",headers:[{level:2,title:"Example 1",slug:"example-1",link:"#example-1",children:[]},{level:2,title:"Example 2",slug:"example-2",link:"#example-2",children:[]}],path:"/cookbook/motion-triggered-light.html",pathLocale:"/",extraFields:[]},{title:"Saving and Restoring States",headers:[{level:2,title:"Using Home Assistant scene creation",slug:"using-home-assistant-scene-creation",link:"#using-home-assistant-scene-creation",children:[]},{level:2,title:"Using the get entities node",slug:"using-the-get-entities-node",link:"#using-the-get-entities-node",children:[]}],path:"/cookbook/saving-and-restoring-states.html",pathLocale:"/",extraFields:[]},{title:"Starting a flow after a Home Assistant restart",headers:[{level:2,title:"Create an input boolean using the Helpers menu (Configuration -> Helpers)",slug:"create-an-input-boolean-using-the-helpers-menu-configuration-helpers",link:"#create-an-input-boolean-using-the-helpers-menu-configuration-helpers",children:[]},{level:2,title:"Create the Home Assistant automation",slug:"create-the-home-assistant-automation",link:"#create-the-home-assistant-automation",children:[]}],path:"/cookbook/starting-flow-after-home-assistant-restart.html",pathLocale:"/",extraFields:[]},{title:"Turn Light On/Off with Sunset/Sunrise",headers:[{level:2,title:"Option 1",slug:"option-1",link:"#option-1",children:[]},{level:2,title:"Option 2",slug:"option-2",link:"#option-2",children:[]},{level:2,title:"Option 3",slug:"option-3",link:"#option-3",children:[]}],path:"/cookbook/sun-events.html",pathLocale:"/",extraFields:[]},{title:"Using Date and Time entities to trigger flows",headers:[{level:2,title:"Using the time node",slug:"using-the-time-node",link:"#using-the-time-node",children:[]},{level:2,title:"Home Assistant Companion app next alarm sensor",slug:"home-assistant-companion-app-next-alarm-sensor",link:"#home-assistant-companion-app-next-alarm-sensor",children:[{level:3,title:"Adding an offset and on/off switch",slug:"adding-an-offset-and-on-off-switch",link:"#adding-an-offset-and-on-off-switch",children:[]},{level:3,title:"Managing alarm from multiple phones",slug:"managing-alarm-from-multiple-phones",link:"#managing-alarm-from-multiple-phones",children:[]}]},{level:2,title:"Daily alarm using Datetime Entity",slug:"daily-alarm-using-datetime-entity",link:"#daily-alarm-using-datetime-entity",children:[]}],path:"/cookbook/using-date-and-time-entities-to-trigger-flows.html",pathLocale:"/",extraFields:[]},{title:"Vacation Mode",headers:[{level:2,title:"Step 1",slug:"step-1",link:"#step-1",children:[]},{level:2,title:"Step 2",slug:"step-2",link:"#step-2",children:[]},{level:2,title:"Step 3",slug:"step-3",link:"#step-3",children:[]},{level:2,title:"Step 4",slug:"step-4",link:"#step-4",children:[]}],path:"/cookbook/vacation-mode.html",pathLocale:"/",extraFields:[]},{title:"Getting Started",headers:[{level:2,title:"Prerequisites",slug:"prerequisites",link:"#prerequisites",children:[]},{level:2,title:"Installation",slug:"installation",link:"#installation",children:[{level:3,title:"Using the Palette Manager",slug:"using-the-palette-manager",link:"#using-the-palette-manager",children:[]},{level:3,title:"Using npm from the command line",slug:"using-npm-from-the-command-line",link:"#using-npm-from-the-command-line",children:[]},{level:3,title:"Home Assistant Add-on",slug:"home-assistant-add-on",link:"#home-assistant-add-on",children:[]}]},{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Generate Access Token",slug:"generate-access-token",link:"#generate-access-token",children:[]}]}],path:"/guide/",pathLocale:"/",extraFields:[]},{title:"Action Tips and Tricks",headers:[{level:2,title:"Homeassistant Domain",slug:"homeassistant-domain",link:"#homeassistant-domain",children:[]},{level:2,title:"Using Mustache Templates",slug:"using-mustache-templates",link:"#using-mustache-templates",children:[]},{level:2,title:"Targets",slug:"targets",link:"#targets",children:[]},{level:2,title:"Data Field",slug:"data-field",link:"#data-field",children:[{level:3,title:"Inserting a message property into a string",slug:"inserting-a-message-property-into-a-string",link:"#inserting-a-message-property-into-a-string",children:[]},{level:3,title:"Getting a property value of a Home Assistant entity",slug:"getting-a-property-value-of-a-home-assistant-entity",link:"#getting-a-property-value-of-a-home-assistant-entity",children:[]},{level:3,title:"Doing arithmetic",slug:"doing-arithmetic",link:"#doing-arithmetic",children:[]},{level:3,title:"Create a comma-delimited entity id list",slug:"create-a-comma-delimited-entity-id-list",link:"#create-a-comma-delimited-entity-id-list",children:[]}]}],path:"/guide/action.html",pathLocale:"/",extraFields:[]},{title:"Conditionals",headers:[{level:2,title:"Rules",slug:"rules",link:"#rules",children:[{level:3,title:"is and is not",slug:"is-and-is-not",link:"#is-and-is-not",children:[]},{level:3,title:"< and <= and > and >=",slug:"and-and-and",link:"#and-and-and",children:[]},{level:3,title:"in and not in",slug:"in-and-not-in",link:"#in-and-not-in",children:[]},{level:3,title:"JSONata",slug:"jsonata",link:"#jsonata",children:[]},{level:3,title:"starts with",slug:"starts-with",link:"#starts-with",children:[]},{level:3,title:"in group",slug:"in-group",link:"#in-group",children:[]}]},{level:2,title:"Value Types",slug:"value-types",link:"#value-types",children:[{level:3,title:"string and number and boolean and regular expression and JSONata expression",slug:"string-and-number-and-boolean-and-regular-expression-and-jsonata-expression",link:"#string-and-number-and-boolean-and-regular-expression-and-jsonata-expression",children:[]},{level:3,title:"msg and flow and global",slug:"msg-and-flow-and-global",link:"#msg-and-flow-and-global",children:[]},{level:3,title:"entity and prevEntity",slug:"entity-and-preventity",link:"#entity-and-preventity",children:[]}]}],path:"/guide/conditionals.html",pathLocale:"/",extraFields:[]},{title:"Development",headers:[{level:2,title:"Environment setup",slug:"environment-setup",link:"#environment-setup",children:[{level:3,title:"Setup using the VS Code dev container",slug:"setup-using-the-vs-code-dev-container",link:"#setup-using-the-vs-code-dev-container",children:[]},{level:3,title:"Setup locally",slug:"setup-locally",link:"#setup-locally",children:[]},{level:3,title:"Accessing",slug:"accessing",link:"#accessing",children:[]},{level:3,title:"Linting",slug:"linting",link:"#linting",children:[]},{level:3,title:"Testing",slug:"testing",link:"#testing",children:[]}]}],path:"/guide/development.html",pathLocale:"/",extraFields:[]},{title:"Diagnostics Information",headers:[{level:2,title:"Overview",slug:"overview",link:"#overview",children:[]},{level:2,title:"Before version 0.62.0",slug:"before-version-0-62-0",link:"#before-version-0-62-0",children:[{level:3,title:"Flow",slug:"flow",link:"#flow",children:[]},{level:3,title:"Usage",slug:"usage",link:"#usage",children:[]}]}],path:"/guide/diagnostics.html",pathLocale:"/",extraFields:[]},{title:"Documentation",headers:[{level:2,title:"Small changes",slug:"small-changes",link:"#small-changes",children:[]},{level:2,title:"Local development",slug:"local-development",link:"#local-development",children:[{level:3,title:"Developing with Visual Studio Code and Docker",slug:"developing-with-visual-studio-code-and-docker",link:"#developing-with-visual-studio-code-and-docker",children:[]},{level:3,title:"Manual environment",slug:"manual-environment",link:"#manual-environment",children:[]}]}],path:"/guide/documentation.html",pathLocale:"/",extraFields:[]},{title:"First Automation",headers:[{level:2,title:"Events: state",slug:"events-state",link:"#events-state",children:[]},{level:2,title:"Entity ID",slug:"entity-id",link:"#entity-id",children:[]},{level:2,title:"If State",slug:"if-state",link:"#if-state",children:[]},{level:2,title:"Call Service",slug:"call-service",link:"#call-service",children:[]},{level:2,title:"Complete Automation",slug:"complete-automation",link:"#complete-automation",children:[]}],path:"/guide/first-automation.html",pathLocale:"/",extraFields:[]},{title:"Migration",headers:[{level:2,title:"Current-State Node Output",slug:"current-state-node-output",link:"#current-state-node-output",children:[]},{level:2,title:"Poll-State Node Output",slug:"poll-state-node-output",link:"#poll-state-node-output",children:[]}],path:"/guide/migration.html",pathLocale:"/",extraFields:[]},{title:"Mustache Templates",headers:[],path:"/guide/mustache-templates.html",pathLocale:"/",extraFields:[]},{title:"API",headers:[{level:2,title:"Config",slug:"config",link:"#config",children:[{level:3,title:"Protocol",slug:"protocol",link:"#protocol",children:[]},{level:3,title:"Method",slug:"method",link:"#method",children:[]},{level:3,title:"Path",slug:"path",link:"#path",children:[]},{level:3,title:"Params",slug:"params",link:"#params",children:[]},{level:3,title:"Data",slug:"data",link:"#data",children:[]},{level:3,title:"Results",slug:"results",link:"#results",children:[]}]},{level:2,title:"Input",slug:"input",link:"#input",children:[{level:3,title:"protocol",slug:"protocol-1",link:"#protocol-1",children:[]},{level:3,title:"method",slug:"method-1",link:"#method-1",children:[]},{level:3,title:"path",slug:"path-1",link:"#path-1",children:[]},{level:3,title:"data",slug:"data-1",link:"#data-1",children:[]},{level:3,title:"location",slug:"location",link:"#location",children:[]},{level:3,title:"locationType",slug:"locationtype",link:"#locationtype",children:[]}]},{level:2,title:"Output",slug:"output",link:"#output",children:[]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/API.html",pathLocale:"/",extraFields:[]},{title:"Nodes",headers:[{level:2,title:"Action",slug:"action",link:"#action",children:[]},{level:2,title:"API",slug:"api",link:"#api",children:[]},{level:2,title:"Binary Sensor",slug:"binary-sensor",link:"#binary-sensor",children:[]},{level:2,title:"Button",slug:"button",link:"#button",children:[]},{level:2,title:"Current State",slug:"current-state",link:"#current-state",children:[]},{level:2,title:"Device",slug:"device",link:"#device",children:[]},{level:2,title:"Device Config",slug:"device-config",link:"#device-config",children:[]},{level:2,title:"Entity",slug:"entity",link:"#entity",children:[]},{level:2,title:"Entity Config",slug:"entity-config",link:"#entity-config",children:[]},{level:2,title:"Events: all",slug:"events-all",link:"#events-all",children:[]},{level:2,title:"Events: state",slug:"events-state",link:"#events-state",children:[]},{level:2,title:"Fire Event",slug:"fire-event",link:"#fire-event",children:[]},{level:2,title:"Get Entities",slug:"get-entities",link:"#get-entities",children:[]},{level:2,title:"Get History",slug:"get-history",link:"#get-history",children:[]},{level:2,title:"Number",slug:"number",link:"#number",children:[]},{level:2,title:"Poll State",slug:"poll-state",link:"#poll-state",children:[]},{level:2,title:"Render Template",slug:"render-template",link:"#render-template",children:[]},{level:2,title:"Select",slug:"select",link:"#select",children:[]},{level:2,title:"Sensor",slug:"sensor",link:"#sensor",children:[]},{level:2,title:"Sentence",slug:"sentence",link:"#sentence",children:[]},{level:2,title:"Server Config",slug:"server-config",link:"#server-config",children:[]},{level:2,title:"Switch",slug:"switch",link:"#switch",children:[]},{level:2,title:"Tag",slug:"tag",link:"#tag",children:[]},{level:2,title:"Text",slug:"text",link:"#text",children:[]},{level:2,title:"Time",slug:"time",link:"#time",children:[]},{level:2,title:"Trigger: state",slug:"trigger-state",link:"#trigger-state",children:[]},{level:2,title:"Update Config",slug:"update-config",link:"#update-config",children:[]},{level:2,title:"Wait Until",slug:"wait-until",link:"#wait-until",children:[]},{level:2,title:"Webhook",slug:"webhook",link:"#webhook",children:[]},{level:2,title:"Zone",slug:"zone",link:"#zone",children:[]}],path:"/node/",pathLocale:"/",extraFields:[]},{title:"Action",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Action",slug:"action-1",link:"#action-1",children:[]},{level:3,title:"Floor",slug:"floor",link:"#floor",children:[]},{level:3,title:"Area",slug:"area",link:"#area",children:[]},{level:3,title:"Device",slug:"device",link:"#device",children:[]},{level:3,title:"Entity",slug:"entity",link:"#entity",children:[]},{level:3,title:"Label",slug:"label",link:"#label",children:[]},{level:3,title:"Data",slug:"data",link:"#data",children:[]},{level:3,title:"Merge Context",slug:"merge-context",link:"#merge-context",children:[]},{level:3,title:"Alternative Template Tags",slug:"alternative-template-tags",link:"#alternative-template-tags",children:[]},{level:3,title:"Queue",slug:"queue",link:"#queue",children:[]}]},{level:2,title:"Input",slug:"input",link:"#input",children:[{level:3,title:"action",slug:"action-2",link:"#action-2",children:[]},{level:3,title:"data",slug:"data-1",link:"#data-1",children:[]},{level:3,title:"target",slug:"target",link:"#target",children:[]}]},{level:2,title:"Output",slug:"output",link:"#output",children:[]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/action.html",pathLocale:"/",extraFields:[]},{title:"Binary Sensor",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"State",slug:"state",link:"#state",children:[]},{level:3,title:"Attributes",slug:"attributes",link:"#attributes",children:[]},{level:3,title:"Input Override",slug:"input-override",link:"#input-override",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"state",slug:"state-1",link:"#state-1",children:[]},{level:3,title:"attributes",slug:"attributes-1",link:"#attributes-1",children:[]}]}],path:"/node/binary-sensor.html",pathLocale:"/",extraFields:[]},{title:"Button",headers:[{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]}],path:"/node/button.html",pathLocale:"/",extraFields:[]},{title:"Server Config",headers:[{level:2,title:"Config",slug:"config",link:"#config",children:[{level:3,title:"Name",slug:"name",link:"#name",children:[]},{level:3,title:"Using the Home Assistant Add-on",slug:"using-the-home-assistant-add-on",link:"#using-the-home-assistant-add-on",children:[]},{level:3,title:"Base URL",slug:"base-url",link:"#base-url",children:[]},{level:3,title:"Access Token",slug:"access-token",link:"#access-token",children:[]},{level:3,title:"Unauthorized SSL Certificates",slug:"unauthorized-ssl-certificates",link:"#unauthorized-ssl-certificates",children:[]},{level:3,title:"State Boolean",slug:"state-boolean",link:"#state-boolean",children:[]},{level:3,title:"Enable Heartbeat",slug:"enable-heartbeat",link:"#enable-heartbeat",children:[]},{level:3,title:"Heartbeat Interval",slug:"heartbeat-interval",link:"#heartbeat-interval",children:[]},{level:3,title:"Enable Global Context Store",slug:"enable-global-context-store",link:"#enable-global-context-store",children:[]}]},{level:2,title:"UI Settings",slug:"ui-settings",link:"#ui-settings",children:[{level:3,title:"Cache Autocomplete Results",slug:"cache-autocomplete-results",link:"#cache-autocomplete-results",children:[]},{level:3,title:"ID Selector Display",slug:"id-selector-display",link:"#id-selector-display",children:[]},{level:3,title:"Status Date Format",slug:"status-date-format",link:"#status-date-format",children:[]}]},{level:2,title:"Details",slug:"details",link:"#details",children:[{level:3,title:"Context",slug:"context",link:"#context",children:[]},{level:3,title:"Context Example",slug:"context-example",link:"#context-example",children:[]}]},{level:2,title:"Connection Issues",slug:"connection-issues",link:"#connection-issues",children:[]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/config-server.html",pathLocale:"/",extraFields:[]},{title:"Current State",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entity ID",slug:"entity-id",link:"#entity-id",children:[]},{level:3,title:"If State",slug:"if-state",link:"#if-state",children:[]},{level:3,title:"For",slug:"for",link:"#for",children:[]},{level:3,title:"State Type",slug:"state-type",link:"#state-type",children:[]},{level:3,title:"Block Input Overrides",slug:"block-input-overrides",link:"#block-input-overrides",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"payload.entityId",slug:"payload-entityid",link:"#payload-entityid",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/current-state.html",pathLocale:"/",extraFields:[]},{title:"Device Config",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Name",slug:"name",link:"#name",children:[]},{level:3,title:"Manufacturer",slug:"manufacturer",link:"#manufacturer",children:[]},{level:3,title:"Model",slug:"model",link:"#model",children:[]},{level:3,title:"Software Version",slug:"software-version",link:"#software-version",children:[]},{level:3,title:"Hardware Version",slug:"hardware-version",link:"#hardware-version",children:[]}]}],path:"/node/device-config.html",pathLocale:"/",extraFields:[]},{title:"Device",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Type",slug:"type",link:"#type",children:[]},{level:3,title:"Device",slug:"device-1",link:"#device-1",children:[]},{level:3,title:"Trigger",slug:"trigger",link:"#trigger",children:[]},{level:3,title:"Action",slug:"action",link:"#action",children:[]},{level:3,title:"Capabilities",slug:"capabilities",link:"#capabilities",children:[]},{level:3,title:"Expose as",slug:"expose-as",link:"#expose-as",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]}],path:"/node/device.html",pathLocale:"/",extraFields:[]},{title:"Entity Config",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Name",slug:"name",link:"#name",children:[]},{level:3,title:"Device",slug:"device",link:"#device",children:[]},{level:3,title:"Type",slug:"type",link:"#type",children:[]},{level:3,title:"Resend state and attributes",slug:"resend-state-and-attributes",link:"#resend-state-and-attributes",children:[]},{level:3,title:"Other Properties",slug:"other-properties",link:"#other-properties",children:[]}]}],path:"/node/entity-config.html",pathLocale:"/",extraFields:[]},{title:"Entity",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Type",slug:"type",link:"#type",children:[]},{level:3,title:"Home Assistant Config",slug:"home-assistant-config",link:"#home-assistant-config",children:[]}]},{level:2,title:"Sensor Configuration",slug:"sensor-configuration",link:"#sensor-configuration",children:[{level:3,title:"State",slug:"state",link:"#state",children:[]},{level:3,title:"Attributes",slug:"attributes",link:"#attributes",children:[]},{level:3,title:"Input Override",slug:"input-override",link:"#input-override",children:[]},{level:3,title:"Resend state and attributes",slug:"resend-state-and-attributes",link:"#resend-state-and-attributes",children:[]}]},{level:2,title:"Switch Configuration",slug:"switch-configuration",link:"#switch-configuration",children:[{level:3,title:"Output on state change",slug:"output-on-state-change",link:"#output-on-state-change",children:[]},{level:3,title:"Payload",slug:"payload",link:"#payload",children:[]}]},{level:2,title:"Sensors Inputs",slug:"sensors-inputs",link:"#sensors-inputs",children:[{level:3,title:"state",slug:"state-1",link:"#state-1",children:[]},{level:3,title:"attributes",slug:"attributes-1",link:"#attributes-1",children:[]}]},{level:2,title:"Switch Inputs",slug:"switch-inputs",link:"#switch-inputs",children:[{level:3,title:"msg.enable",slug:"msg-enable",link:"#msg-enable",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]}],path:"/node/entity.html",pathLocale:"/",extraFields:[]},{title:"Events: all",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Name",slug:"name",link:"#name",children:[]},{level:3,title:"Event Type",slug:"event-type",link:"#event-type",children:[]},{level:3,title:"Event data",slug:"event-data",link:"#event-data",children:[]},{level:3,title:"Output only after Home Assistant is running",slug:"output-only-after-home-assistant-is-running",link:"#output-only-after-home-assistant-is-running",children:[]},{level:3,title:"Expose as",slug:"expose-as",link:"#expose-as",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"Client Events",slug:"client-events",link:"#client-events",children:[]}],path:"/node/events-all.html",pathLocale:"/",extraFields:[]},{title:"Events: calendar",headers:[{level:2,title:"Configuration:",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entity ID",slug:"entity-id",link:"#entity-id",children:[]},{level:3,title:"Relative To",slug:"relative-to",link:"#relative-to",children:[]},{level:3,title:"Offset",slug:"offset",link:"#offset",children:[]},{level:3,title:"Conditions",slug:"conditions",link:"#conditions",children:[]},{level:3,title:"Expose to Home Assistant",slug:"expose-to-home-assistant",link:"#expose-to-home-assistant",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]}],path:"/node/events-calendar.html",pathLocale:"/",extraFields:[]},{title:"Events: state",headers:[{level:2,title:"Configuration:",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entity",slug:"entity",link:"#entity",children:[]},{level:3,title:"If State",slug:"if-state",link:"#if-state",children:[]},{level:3,title:"For",slug:"for",link:"#for",children:[]},{level:3,title:"State Type",slug:"state-type",link:"#state-type",children:[]},{level:3,title:"Ignore state change event",slug:"ignore-state-change-event",link:"#ignore-state-change-event",children:[]},{level:3,title:"Output on Connect",slug:"output-on-connect",link:"#output-on-connect",children:[]},{level:3,title:"Expose to Home Assistant",slug:"expose-to-home-assistant",link:"#expose-to-home-assistant",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]}],path:"/node/events-state.html",pathLocale:"/",extraFields:[]},{title:"Fire Event",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Event",slug:"event",link:"#event",children:[]},{level:3,title:"data",slug:"data",link:"#data",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"payload.event",slug:"payload-event",link:"#payload-event",children:[]},{level:3,title:"payload.data",slug:"payload-data",link:"#payload-data",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"payload.event_type",slug:"payload-event-type",link:"#payload-event-type",children:[]},{level:3,title:"payload.data",slug:"payload-data-1",link:"#payload-data-1",children:[]}]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/fire-event.html",pathLocale:"/",extraFields:[]},{title:"Get Entities",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Search Criteria",slug:"search-criteria",link:"#search-criteria",children:[]},{level:3,title:"Property",slug:"property",link:"#property",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"payload",slug:"payload",link:"#payload",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"Array",slug:"array",link:"#array",children:[]},{level:3,title:"Count",slug:"count",link:"#count",children:[]},{level:3,title:"Random",slug:"random",link:"#random",children:[]},{level:3,title:"Split",slug:"split",link:"#split",children:[]}]},{level:2,title:"State Object Format",slug:"state-object-format",link:"#state-object-format",children:[{level:3,title:"entity_id",slug:"entity-id",link:"#entity-id",children:[]},{level:3,title:"state",slug:"state",link:"#state",children:[]},{level:3,title:"attributes",slug:"attributes",link:"#attributes",children:[]},{level:3,title:"last_changed",slug:"last-changed",link:"#last-changed",children:[]},{level:3,title:"timeSinceChangedMs",slug:"timesincechangedms",link:"#timesincechangedms",children:[]},{level:3,title:"last_updated",slug:"last-updated",link:"#last-updated",children:[]},{level:3,title:"context",slug:"context",link:"#context",children:[]}]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/get-entities.html",pathLocale:"/",extraFields:[]},{title:"Get History",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entity ID",slug:"entity-id",link:"#entity-id",children:[]},{level:3,title:"Entity ID Type",slug:"entity-id-type",link:"#entity-id-type",children:[]},{level:3,title:"Start Date",slug:"start-date",link:"#start-date",children:[]},{level:3,title:"End Date",slug:"end-date",link:"#end-date",children:[]},{level:3,title:"Use Relative Time",slug:"use-relative-time",link:"#use-relative-time",children:[]},{level:3,title:"In the Last",slug:"in-the-last",link:"#in-the-last",children:[]},{level:3,title:"Flatten Results",slug:"flatten-results",link:"#flatten-results",children:[]},{level:3,title:"Output Types",slug:"output-types",link:"#output-types",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"entityId",slug:"entityid",link:"#entityid",children:[]},{level:3,title:"entityIdType",slug:"entityidtype",link:"#entityidtype",children:[]},{level:3,title:"startDate",slug:"startdate",link:"#startdate",children:[]},{level:3,title:"endDate",slug:"enddate",link:"#enddate",children:[]},{level:3,title:"relativeTime",slug:"relativetime",link:"#relativetime",children:[]},{level:3,title:"flatten",slug:"flatten",link:"#flatten",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"payload",slug:"payload",link:"#payload",children:[]}]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/get-history.html",pathLocale:"/",extraFields:[]},{title:"Number",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Mode",slug:"mode",link:"#mode",children:[]},{level:3,title:"Value",slug:"value",link:"#value",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"value",slug:"value-1",link:"#value-1",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]}],path:"/node/number.html",pathLocale:"/",extraFields:[]},{title:"Poll State",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entity ID",slug:"entity-id",link:"#entity-id",children:[]},{level:3,title:"Update Interval",slug:"update-interval",link:"#update-interval",children:[]},{level:3,title:"If State",slug:"if-state",link:"#if-state",children:[]},{level:3,title:"State Type",slug:"state-type",link:"#state-type",children:[]},{level:3,title:"Output Initially",slug:"output-initially",link:"#output-initially",children:[]},{level:3,title:"Expose to Home Assistant",slug:"expose-to-home-assistant",link:"#expose-to-home-assistant",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"topic",slug:"topic",link:"#topic",children:[]},{level:3,title:"payload",slug:"payload",link:"#payload",children:[]},{level:3,title:"data.timeSinceChanged",slug:"data-timesincechanged",link:"#data-timesincechanged",children:[]},{level:3,title:"data.timeSinceChangedMs",slug:"data-timesincechangedms",link:"#data-timesincechangedms",children:[]}]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/poll-state.html",pathLocale:"/",extraFields:[]},{title:"Render Template",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"template",slug:"template",link:"#template",children:[]},{level:3,title:"Template Location",slug:"template-location",link:"#template-location",children:[]},{level:3,title:"Results",slug:"results",link:"#results",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"template",slug:"template-1",link:"#template-1",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"template",slug:"template-2",link:"#template-2",children:[]},{level:3,title:"payload",slug:"payload",link:"#payload",children:[]}]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/render-template.html",pathLocale:"/",extraFields:[]},{title:"Select",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Mode",slug:"mode",link:"#mode",children:[]},{level:3,title:"value",slug:"value",link:"#value",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"Value",slug:"value-1",link:"#value-1",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]}],path:"/node/select.html",pathLocale:"/",extraFields:[]},{title:"Sensor",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"State",slug:"state",link:"#state",children:[]},{level:3,title:"Attributes",slug:"attributes",link:"#attributes",children:[]},{level:3,title:"Input Override",slug:"input-override",link:"#input-override",children:[]},{level:3,title:"Resend state and attributes",slug:"resend-state-and-attributes",link:"#resend-state-and-attributes",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"state",slug:"state-1",link:"#state-1",children:[]},{level:3,title:"attributes",slug:"attributes-1",link:"#attributes-1",children:[]}]}],path:"/node/sensor.html",pathLocale:"/",extraFields:[]},{title:"Sentence",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Sentences",slug:"sentences",link:"#sentences",children:[]},{level:3,title:"Expose as",slug:"expose-as",link:"#expose-as",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]}],path:"/node/sentence.html",pathLocale:"/",extraFields:[]},{title:"Switch",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Enable input",slug:"enable-input",link:"#enable-input",children:[]},{level:3,title:"Output on state change",slug:"output-on-state-change",link:"#output-on-state-change",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"msg.enable",slug:"msg-enable",link:"#msg-enable",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]}],path:"/node/switch.html",pathLocale:"/",extraFields:[]},{title:"Tag",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Tags",slug:"tags",link:"#tags",children:[]},{level:3,title:"Devices",slug:"devices",link:"#devices",children:[]},{level:3,title:"Expose as",slug:"expose-as",link:"#expose-as",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"event object",slug:"event-object",link:"#event-object",children:[]}]}],path:"/node/tag.html",pathLocale:"/",extraFields:[]},{title:"Text",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Mode",slug:"mode",link:"#mode",children:[]},{level:3,title:"Text",slug:"text-1",link:"#text-1",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"Text",slug:"text-2",link:"#text-2",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]}],path:"/node/text.html",pathLocale:"/",extraFields:[]},{title:"Time",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Mode",slug:"mode",link:"#mode",children:[]},{level:3,title:"Value",slug:"value",link:"#value",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"value",slug:"value-1",link:"#value-1",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]}],path:"/node/time-entity.html",pathLocale:"/",extraFields:[]},{title:"Time",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entity Id",slug:"entity-id",link:"#entity-id",children:[]},{level:3,title:"Property",slug:"property",link:"#property",children:[]},{level:3,title:"Offset",slug:"offset",link:"#offset",children:[]},{level:3,title:"Randomize time within the offset",slug:"randomize-time-within-the-offset",link:"#randomize-time-within-the-offset",children:[]},{level:3,title:"Payload",slug:"payload",link:"#payload",children:[]},{level:3,title:"Repeat Daily",slug:"repeat-daily",link:"#repeat-daily",children:[]},{level:3,title:"Expose as",slug:"expose-as",link:"#expose-as",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"topic",slug:"topic",link:"#topic",children:[]},{level:3,title:"payload",slug:"payload-1",link:"#payload-1",children:[]},{level:3,title:"data",slug:"data",link:"#data",children:[]}]}],path:"/node/time.html",pathLocale:"/",extraFields:[]},{title:"Trigger: state",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entity",slug:"entity",link:"#entity",children:[]},{level:3,title:"State Type",slug:"state-type",link:"#state-type",children:[]},{level:3,title:"Conditions",slug:"conditions",link:"#conditions",children:[]},{level:3,title:"Custom Outputs",slug:"custom-outputs",link:"#custom-outputs",children:[]},{level:3,title:"Output on connect",slug:"output-on-connect",link:"#output-on-connect",children:[]},{level:3,title:"Enable input",slug:"enable-input",link:"#enable-input",children:[]},{level:3,title:"Output debug information",slug:"output-debug-information",link:"#output-debug-information",children:[]},{level:3,title:"Expose to Home Assistant",slug:"expose-to-home-assistant",link:"#expose-to-home-assistant",children:[]}]},{level:2,title:"Input",slug:"input",link:"#input",children:[{level:3,title:"Enable / Disable",slug:"enable-disable",link:"#enable-disable",children:[]}]},{level:2,title:"Output",slug:"output",link:"#output",children:[{level:3,title:"topic",slug:"topic",link:"#topic",children:[]},{level:3,title:"payload",slug:"payload",link:"#payload",children:[]},{level:3,title:"data",slug:"data",link:"#data",children:[]}]},{level:2,title:"Testing",slug:"testing",link:"#testing",children:[]},{level:2,title:"References",slug:"references",link:"#references",children:[]}],path:"/node/trigger-state.html",pathLocale:"/",extraFields:[]},{title:"Update Config",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Name",slug:"name",link:"#name",children:[]},{level:3,title:"Server",slug:"server",link:"#server",children:[]},{level:3,title:"Entity Config",slug:"entity-config",link:"#entity-config",children:[]}]},{level:2,title:"Inputs",slug:"inputs",link:"#inputs",children:[{level:3,title:"Example input",slug:"example-input",link:"#example-input",children:[]},{level:3,title:"id",slug:"id",link:"#id",children:[]},{level:3,title:"icon",slug:"icon",link:"#icon",children:[]},{level:3,title:"name",slug:"name-1",link:"#name-1",children:[]},{level:3,title:"entityPicture",slug:"entitypicture",link:"#entitypicture",children:[]}]},{level:2,title:"Examples",slug:"examples",link:"#examples",children:[]}],path:"/node/update-config.html",pathLocale:"/",extraFields:[]},{title:"Wait Until",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entities",slug:"entities",link:"#entities",children:[]},{level:3,title:"Wait Until",slug:"wait-until-1",link:"#wait-until-1",children:[]},{level:3,title:"Timeout",slug:"timeout",link:"#timeout",children:[]},{level:3,title:"Check against the current state",slug:"check-against-the-current-state",link:"#check-against-the-current-state",children:[]}]},{level:2,title:"Input",slug:"input",link:"#input",children:[{level:3,title:"reset",slug:"reset",link:"#reset",children:[]},{level:3,title:"payload",slug:"payload",link:"#payload",children:[]},{level:3,title:"Example",slug:"example",link:"#example",children:[]}]},{level:2,title:"Output",slug:"output",link:"#output",children:[]}],path:"/node/wait-until.html",pathLocale:"/",extraFields:[]},{title:"Webhook",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"ID",slug:"id",link:"#id",children:[]},{level:3,title:"Allowed Methods",slug:"allowed-methods",link:"#allowed-methods",children:[]},{level:3,title:"Expose as",slug:"expose-as",link:"#expose-as",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[]}],path:"/node/webhook.html",pathLocale:"/",extraFields:[]},{title:"Zone",headers:[{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[{level:3,title:"Entities",slug:"entities",link:"#entities",children:[]},{level:3,title:"Event",slug:"event",link:"#event",children:[]},{level:3,title:"Zones",slug:"zones",link:"#zones",children:[]}]},{level:2,title:"Outputs",slug:"outputs",link:"#outputs",children:[{level:3,title:"topic",slug:"topic",link:"#topic",children:[]},{level:3,title:"payload",slug:"payload",link:"#payload",children:[]},{level:3,title:"data",slug:"data",link:"#data",children:[]},{level:3,title:"zones",slug:"zones-1",link:"#zones-1",children:[]}]}],path:"/node/zone.html",pathLocale:"/",extraFields:[]},{title:"Scrubber",headers:[{level:2,title:"What does this do?",slug:"what-does-this-do",link:"#what-does-this-do",children:[]}],path:"/scrubber/",pathLocale:"/",extraFields:[]},{title:"Call Service",headers:[{level:2,title:"Passing variables to WebSocket nodes in summary",slug:"passing-variables-to-websocket-nodes-in-summary",link:"#passing-variables-to-websocket-nodes-in-summary",children:[]},{level:2,title:"JSONata and the Call Service node",slug:"jsonata-and-the-call-service-node",link:"#jsonata-and-the-call-service-node",children:[]},{level:2,title:"Setting the Data field",slug:"setting-the-data-field",link:"#setting-the-data-field",children:[{level:3,title:"Settings a data property from a Home Assistant entity",slug:"settings-a-data-property-from-a-home-assistant-entity",link:"#settings-a-data-property-from-a-home-assistant-entity",children:[]},{level:3,title:"Setting a data property from a Home Assistant entity with a calculation",slug:"setting-a-data-property-from-a-home-assistant-entity-with-a-calculation",link:"#setting-a-data-property-from-a-home-assistant-entity-with-a-calculation",children:[]},{level:3,title:"Increase lights brightness with remote",slug:"increase-lights-brightness-with-remote",link:"#increase-lights-brightness-with-remote",children:[]},{level:3,title:"Setting target temperature on air-conditioning unit",slug:"setting-target-temperature-on-air-conditioning-unit",link:"#setting-target-temperature-on-air-conditioning-unit",children:[]},{level:3,title:"Notification of lights left on when leaving home",slug:"notification-of-lights-left-on-when-leaving-home",link:"#notification-of-lights-left-on-when-leaving-home",children:[]}]},{level:2,title:"Processing a service call return",slug:"processing-a-service-call-return",link:"#processing-a-service-call-return",children:[]}],path:"/cookbook/jsonata/call-service.html",pathLocale:"/",extraFields:[]},{title:"Change node",headers:[{level:2,title:"Read a person state history for the past week",slug:"read-a-person-state-history-for-the-past-week",link:"#read-a-person-state-history-for-the-past-week",children:[]},{level:2,title:"Report only those periods when 'not home' during the day",slug:"report-only-those-periods-when-not-home-during-the-day",link:"#report-only-those-periods-when-not-home-during-the-day",children:[]}],path:"/cookbook/jsonata/change-node.html",pathLocale:"/",extraFields:[]},{title:"Current State",headers:[{level:3,title:"Creating output properties",slug:"creating-output-properties",link:"#creating-output-properties",children:[]},{level:3,title:"Providing a conditional test value (JSONata expression as a value)",slug:"providing-a-conditional-test-value-jsonata-expression-as-a-value",link:"#providing-a-conditional-test-value-jsonata-expression-as-a-value",children:[]},{level:3,title:"Generating UI field setting values",slug:"generating-ui-field-setting-values",link:"#generating-ui-field-setting-values",children:[]},{level:3,title:"Conditional test (JSONata expression as a Boolean result)",slug:"conditional-test-jsonata-expression-as-a-boolean-result",link:"#conditional-test-jsonata-expression-as-a-boolean-result",children:[]}],path:"/cookbook/jsonata/current-state.html",pathLocale:"/",extraFields:[]},{title:"Events: state",headers:[{level:3,title:"Providing a conditional test value (JSONata expression as a value)",slug:"providing-a-conditional-test-value-jsonata-expression-as-a-value",link:"#providing-a-conditional-test-value-jsonata-expression-as-a-value",children:[]},{level:3,title:"Conditional test (JSONata expression as a Boolean result)",slug:"conditional-test-jsonata-expression-as-a-boolean-result",link:"#conditional-test-jsonata-expression-as-a-boolean-result",children:[]},{level:3,title:"Creating output properties",slug:"creating-output-properties",link:"#creating-output-properties",children:[]},{level:3,title:"OR conditional for the Events: state node",slug:"or-conditional-for-the-events-state-node",link:"#or-conditional-for-the-events-state-node",children:[]}],path:"/cookbook/jsonata/events-state.html",pathLocale:"/",extraFields:[]},{title:"Other functions",headers:[{level:3,title:"Reading entity state and entity attributes with $entity() and $prevEntity()",slug:"reading-entity-state-and-entity-attributes-with-entity-and-preventity",link:"#reading-entity-state-and-entity-attributes-with-entity-and-preventity",children:[]},{level:3,title:"Using $entities() to return one or all entities",slug:"using-entities-to-return-one-or-all-entities",link:"#using-entities-to-return-one-or-all-entities",children:[]},{level:3,title:"Using $areas(), $areaDevices and $areaEntities()",slug:"using-areas-areadevices-and-areaentities",link:"#using-areas-areadevices-and-areaentities",children:[]}],path:"/cookbook/jsonata/functions.html",pathLocale:"/",extraFields:[]},{title:"Sensor",headers:[{level:3,title:"Setting the sensor state value",slug:"setting-the-sensor-state-value",link:"#setting-the-sensor-state-value",children:[]},{level:3,title:"Setting an attribute value",slug:"setting-an-attribute-value",link:"#setting-an-attribute-value",children:[]},{level:3,title:"Responding to state changes using JSONata",slug:"responding-to-state-changes-using-jsonata",link:"#responding-to-state-changes-using-jsonata",children:[]}],path:"/cookbook/jsonata/sensor.html",pathLocale:"/",extraFields:[]},{title:"Switch node",headers:[{level:3,title:"Using JSONata in switch routing",slug:"using-jsonata-in-switch-routing",link:"#using-jsonata-in-switch-routing",children:[]}],path:"/cookbook/jsonata/switch-node.html",pathLocale:"/",extraFields:[]},{title:"Trigger: state",headers:[{level:3,title:"Using JSONata to set a condition value",slug:"using-jsonata-to-set-a-condition-value",link:"#using-jsonata-to-set-a-condition-value",children:[]},{level:3,title:"Using JSONata to create a custom message",slug:"using-jsonata-to-create-a-custom-message",link:"#using-jsonata-to-create-a-custom-message",children:[]}],path:"/cookbook/jsonata/trigger-state.html",pathLocale:"/",extraFields:[]},{title:"Getting Started",headers:[{level:2,title:"Installation",slug:"installation",link:"#installation",children:[]},{level:2,title:"Tip",slug:"tip",link:"#tip",children:[]}],path:"/guide/custom_integration/",pathLocale:"/",extraFields:[]},{title:"Exposed Nodes",headers:[{level:2,title:"Available to all event nodes",slug:"available-to-all-event-nodes",link:"#available-to-all-event-nodes",children:[]},{level:2,title:"Trigger an exposed event node from a service call nodered.trigger",slug:"trigger-an-exposed-event-node-from-a-service-call-nodered-trigger",link:"#trigger-an-exposed-event-node-from-a-service-call-nodered-trigger",children:[{level:3,title:"entity_id",slug:"entity-id",link:"#entity-id",children:[]},{level:3,title:"output_path",slug:"output-path",link:"#output-path",children:[]},{level:3,title:"message",slug:"message",link:"#message",children:[]}]}],path:"/guide/custom_integration/exposed-nodes.html",pathLocale:"/",extraFields:[]},{title:"JSONata",headers:[{level:2,title:"Examples of using JSONata in the Home Assistant Nodes:",slug:"examples-of-using-jsonata-in-the-home-assistant-nodes",link:"#examples-of-using-jsonata-in-the-home-assistant-nodes",children:[]},{level:2,title:"Home Assistant functions",slug:"home-assistant-functions",link:"#home-assistant-functions",children:[]},{level:2,title:"Exposed Lodash functions",slug:"exposed-lodash-functions",link:"#exposed-lodash-functions",children:[]}],path:"/guide/jsonata/",pathLocale:"/",extraFields:[]},{title:"JSONata primer",headers:[{level:2,title:"The mapping (iteration) operator .",slug:"the-mapping-iteration-operator",link:"#the-mapping-iteration-operator",children:[]},{level:2,title:"The filter (selection) operator [ ]",slug:"the-filter-selection-operator",link:"#the-filter-selection-operator",children:[]},{level:2,title:"The reduce (aggregation) operator { }",slug:"the-reduce-aggregation-operator",link:"#the-reduce-aggregation-operator",children:[]},{level:2,title:"The order-by (sort) operator ^( )",slug:"the-order-by-sort-operator",link:"#the-order-by-sort-operator",children:[]},{level:2,title:"Other Operators",slug:"other-operators",link:"#other-operators",children:[]},{level:2,title:"Variables",slug:"variables",link:"#variables",children:[]},{level:2,title:"Functions",slug:"functions",link:"#functions",children:[]},{level:2,title:"Code blocks",slug:"code-blocks",link:"#code-blocks",children:[]},{level:2,title:"How it works in practice",slug:"how-it-works-in-practice",link:"#how-it-works-in-practice",children:[]},{level:2,title:"Errors and error handling",slug:"errors-and-error-handling",link:"#errors-and-error-handling",children:[]},{level:2,title:"Writing JSONata code",slug:"writing-jsonata-code",link:"#writing-jsonata-code",children:[]},{level:2,title:"What JSONata cannot do",slug:"what-jsonata-cannot-do",link:"#what-jsonata-cannot-do",children:[]}],path:"/guide/jsonata/jsonata-primer.html",pathLocale:"/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}],Jg=de(Gg),Yg=()=>Jg,Qg=({searchIndex:e,routeLocale:t,query:n,maxSuggestions:l})=>{const i=j(()=>e.value.filter(o=>o.pathLocale===t.value));return j(()=>{const o=n.value.trim().toLowerCase();if(!o)return[];const r=[],a=(s,c)=>{Lr(o,[c.title])&&r.push({link:`${s.path}#${c.slug}`,title:s.title,header:c.title});for(const u of c.children){if(r.length>=l.value)return;a(s,u)}};for(const s of i.value){if(r.length>=l.value)break;if(Lr(o,[s.title,...s.extraFields])){r.push({link:s.path,title:s.title});continue}for(const c of s.headers){if(r.length>=l.value)break;a(s,c)}}return r})},Zg=e=>{const t=de(0);return{focusIndex:t,focusNext:()=>{t.value{t.value>0?t.value-=1:t.value=e.value.length-1}}},Xg=fe({name:"SearchBox",props:{locales:{type:Object,required:!1,default:()=>({})},hotKeys:{type:Array,required:!1,default:()=>[]},maxSuggestions:{type:Number,required:!1,default:5}},setup(e){const{locales:t,hotKeys:n,maxSuggestions:l}=Nl(e),i=tn(),o=kn(),r=Yg(),a=de(null),s=de(!1),c=de(""),u=j(()=>t.value[o.value]??{}),d=Qg({searchIndex:r,routeLocale:o,query:c,maxSuggestions:l}),{focusIndex:f,focusNext:g,focusPrev:b}=Zg(d);qg({input:a,hotKeys:n});const w=j(()=>s.value&&!!d.value.length),T=()=>{w.value&&b()},x=()=>{w.value&&g()},A=v=>{if(!w.value)return;const E=d.value[v];E&&i.push(E.link).then(()=>{c.value="",f.value=0})};return()=>ce("form",{class:"search-box",role:"search"},[ce("input",{ref:a,type:"search",placeholder:u.value.placeholder,autocomplete:"off",spellcheck:!1,value:c.value,onFocus:()=>s.value=!0,onBlur:()=>s.value=!1,onInput:v=>c.value=v.target.value,onKeydown:v=>{switch(v.key){case"ArrowUp":{T();break}case"ArrowDown":{x();break}case"Enter":{v.preventDefault(),A(f.value);break}}}}),w.value&&ce("ul",{class:"suggestions",onMouseleave:()=>f.value=-1},d.value.map(({link:v,title:E,header:O},G)=>ce("li",{class:["suggestion",{focus:f.value===G}],onMouseenter:()=>f.value=G,onMousedown:()=>A(G)},ce("a",{href:v,onClick:F=>F.preventDefault()},[ce("span",{class:"page-title"},E),O&&ce("span",{class:"page-header"},`> ${O}`)]))))])}});var ev=["s","/"],tv={};const nv=tv,lv=ev,iv=5,ov=rt({enhance({app:e}){e.component("SearchBox",t=>ce(Xg,{locales:nv,hotKeys:lv,maxSuggestions:iv,...t}))}}),rv=[{from:"/cookbook/get-entities.html",to:"/node/get-entities.html"},{from:"/guide/custom_integration/switch.html",to:"/node/switch.html"},{from:"/node/call-service.html",to:"/node/action.html"},{from:"/guide/call-service.html",to:"/guide/action.html"}],sv=rt({enhance({router:e}){rv.forEach(t=>{e.addRoute({path:t.from,redirect:t.to})})}}),dl=[vf,bf,xf,Mf,Hf,Wf,wg,Sg,Cg,jg,Bg,ov,sv],av=[["v-39a2059c","/FAQ.html",{title:"FAQ"},[":md"]],["v-8daa1a0e","/",{title:""},["/README.md"]],["v-0b911545","/cookbook/",{title:"Cookbook"},["/cookbook/README.md"]],["v-6fb8d56c","/cookbook/actionable-notifications-subflow-for-android.html",{title:"Actionable Notifications Subflow for Android"},[":md"]],["v-1fbf71d1","/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html",{title:"Check if an entity was a certain state in the last 24 hours"},[":md"]],["v-fea818b6","/cookbook/expiration-date-monitor.html",{title:"Expiration Date Monitor with notification"},[":md"]],["v-7bcde729","/cookbook/get-state_changed-events-based-on-area.html",{title:"Get state_changed Events Based on Area"},[":md"]],["v-012b1d03","/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.html",{title:"Holiday lights scheduler and demo mode for WLED"},[":md"]],["v-cf275bea","/cookbook/motion-triggered-light.html",{title:"Motion Triggered Light"},[":md"]],["v-1dd3ec5e","/cookbook/saving-and-restoring-states.html",{title:"Saving and Restoring States"},[":md"]],["v-97152f42","/cookbook/starting-flow-after-home-assistant-restart.html",{title:"Starting a flow after a Home Assistant restart"},[":md"]],["v-a932050c","/cookbook/sun-events.html",{title:"Turn Light On/Off with Sunset/Sunrise"},[":md"]],["v-5c086d70","/cookbook/using-date-and-time-entities-to-trigger-flows.html",{title:"Using Date and Time entities to trigger flows"},[":md"]],["v-77a2982b","/cookbook/vacation-mode.html",{title:"Vacation Mode"},[":md"]],["v-fffb8e28","/guide/",{title:"Getting Started"},["/guide/README.md"]],["v-1a5d6ff7","/guide/action.html",{title:"Action Tips and Tricks"},[":md"]],["v-9a822240","/guide/conditionals.html",{title:"Conditionals"},[":md"]],["v-531add2c","/guide/development.html",{title:"Development"},[":md"]],["v-348298ce","/guide/diagnostics.html",{title:"Diagnostics Information"},[":md"]],["v-44d4584b","/guide/documentation.html",{title:"Documentation"},[":md"]],["v-746a0799","/guide/first-automation.html",{title:"First Automation"},[":md"]],["v-d0112c92","/guide/migration.html",{title:"Migration"},[":md"]],["v-4970f119","/guide/mustache-templates.html",{title:"Mustache Templates"},[":md"]],["v-5104ae33","/node/API.html",{title:"API"},[":md"]],["v-15051314","/node/",{title:"Nodes"},["/node/README.md"]],["v-2ab02ccf","/node/action.html",{title:"Action"},[":md"]],["v-741d68b2","/node/binary-sensor.html",{title:"Binary Sensor"},[":md"]],["v-636bc153","/node/button.html",{title:"Button"},[":md"]],["v-1d084902","/node/config-server.html",{title:"Server Config"},[":md"]],["v-03774460","/node/current-state.html",{title:"Current State"},[":md"]],["v-a0d46818","/node/device-config.html",{title:"Device Config"},[":md"]],["v-7053a0af","/node/device.html",{title:"Device"},[":md"]],["v-28f3a601","/node/entity-config.html",{title:"Entity Config"},[":md"]],["v-18af4b42","/node/entity.html",{title:"Entity"},[":md"]],["v-8faf5710","/node/events-all.html",{title:"Events: all"},[":md"]],["v-52df608a","/node/events-calendar.html",{title:"Events: calendar"},[":md"]],["v-15feb788","/node/events-state.html",{title:"Events: state"},[":md"]],["v-2832d8e2","/node/fire-event.html",{title:"Fire Event"},[":md"]],["v-f5f1da26","/node/get-entities.html",{title:"Get Entities"},[":md"]],["v-56e234f0","/node/get-history.html",{title:"Get History"},[":md"]],["v-0f75f8c8","/node/number.html",{title:"Number"},[":md"]],["v-4c846822","/node/poll-state.html",{title:"Poll State"},[":md"]],["v-ba5fb488","/node/render-template.html",{title:"Render Template"},[":md"]],["v-4dbc7c6e","/node/select.html",{title:"Select"},[":md"]],["v-275c29cb","/node/sensor.html",{title:"Sensor"},[":md"]],["v-35c07dc2","/node/sentence.html",{title:"Sentence"},[":md"]],["v-4b35e291","/node/switch.html",{title:"Switch"},[":md"]],["v-8d481eda","/node/tag.html",{title:"Tag"},[":md"]],["v-092d5338","/node/text.html",{title:"Text"},[":md"]],["v-4de356ea","/node/time-entity.html",{title:"Time"},[":md"]],["v-4934c998","/node/time.html",{title:"Time"},[":md"]],["v-bdb50f9e","/node/trigger-state.html",{title:"Trigger: state"},[":md"]],["v-eda05c32","/node/update-config.html",{title:"Update Config"},[":md"]],["v-77b94402","/node/wait-until.html",{title:"Wait Until"},[":md"]],["v-52885c54","/node/webhook.html",{title:"Webhook"},[":md"]],["v-66fcac19","/node/zone.html",{title:"Zone"},[":md"]],["v-21070556","/scrubber/",{title:"Scrubber"},["/scrubber/index.md"]],["v-421eb385","/cookbook/jsonata/call-service.html",{title:"Call Service"},[":md"]],["v-cddd5a70","/cookbook/jsonata/change-node.html",{title:"Change node"},[":md"]],["v-288c9e6c","/cookbook/jsonata/current-state.html",{title:"Current State"},[":md"]],["v-57761d4e","/cookbook/jsonata/events-state.html",{title:"Events: state"},[":md"]],["v-76287ba8","/cookbook/jsonata/functions.html",{title:"Other functions"},[":md"]],["v-18acdc11","/cookbook/jsonata/sensor.html",{title:"Sensor"},[":md"]],["v-3bf2614c","/cookbook/jsonata/switch-node.html",{title:"Switch node"},[":md"]],["v-e2ca69aa","/cookbook/jsonata/trigger-state.html",{title:"Trigger: state"},[":md"]],["v-28c12b06","/guide/custom_integration/",{title:"Getting Started"},["/guide/custom_integration/README.md"]],["v-16946cd2","/guide/custom_integration/exposed-nodes.html",{title:"Exposed Nodes"},[":md"]],["v-e0a0c596","/guide/jsonata/",{title:"JSONata"},["/guide/jsonata/index.md"]],["v-30bc7e2c","/guide/jsonata/jsonata-primer.html",{title:"JSONata primer"},[":md"]],["v-3706649a","/404.html",{title:""},[]]];var Tr=fe({name:"Vuepress",setup(){const e=nd();return()=>ce(e.value)}}),cv=()=>av.reduce((e,[t,n,l,i])=>(e.push({name:t,path:n,component:Tr,meta:l},{path:n.endsWith("/")?n+"index.html":n.substring(0,n.length-5),redirect:n},...i.map(o=>({path:o===":md"?n.substring(0,n.length-5)+".md":o,redirect:n}))),e),[{name:"404",path:"/:catchAll(.*)",component:Tr}]),uv=Ld,dv=()=>{const e=cf({history:uv(Cs("/node-red-contrib-home-assistant-websocket/")),routes:cv(),scrollBehavior:(t,n,l)=>l||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{var l;(t.path!==n.path||n===pt)&&([t.meta._data]=await Promise.all([ht.resolvePageData(t.name),(l=Rs[t.name])==null?void 0:l.__asyncLoader()]))}),e},fv=e=>{e.component("ClientOnly",Gi),e.component("Content",sd)},hv=(e,t,n)=>{const l=br(()=>t.currentRoute.value.path),i=br(()=>ht.resolveRouteLocale(sn.value.locales,l.value)),o=Gf(l,()=>t.currentRoute.value.meta._data),r=j(()=>ht.resolveLayouts(n)),a=j(()=>ht.resolveSiteLocaleData(sn.value,i.value)),s=j(()=>ht.resolvePageFrontmatter(o.value)),c=j(()=>ht.resolvePageHeadTitle(o.value,a.value)),u=j(()=>ht.resolvePageHead(c.value,s.value,a.value)),d=j(()=>ht.resolvePageLang(o.value,a.value)),f=j(()=>ht.resolvePageLayout(o.value,r.value));return e.provide(Qu,r),e.provide(Ps,o),e.provide(Is,s),e.provide(ed,c),e.provide(Ds,u),e.provide(Ns,d),e.provide(Ms,f),e.provide(Ki,i),e.provide(Fs,a),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>s.value},$head:{get:()=>u.value},$headTitle:{get:()=>c.value},$lang:{get:()=>d.value},$page:{get:()=>o.value},$routeLocale:{get:()=>i.value},$site:{get:()=>sn.value},$siteLocale:{get:()=>a.value},$withBase:{get:()=>Ji}}),{layouts:r,pageData:o,pageFrontmatter:s,pageHead:u,pageHeadTitle:c,pageLang:d,pageLayout:f,routeLocale:i,siteData:sn,siteLocaleData:a}},pv=()=>{const e=Xu(),t=td(),n=de([]),l=()=>{e.value.forEach(o=>{const r=gv(o);r&&n.value.push(r)})},i=()=>{document.documentElement.lang=t.value,n.value.forEach(o=>{o.parentNode===document.head&&document.head.removeChild(o)}),n.value.splice(0,n.value.length),e.value.forEach(o=>{const r=vv(o);r!==null&&(document.head.appendChild(r),n.value.push(r))})};Yt(id,i),Fe(()=>{l(),i(),qe(()=>e.value,i)})},gv=([e,t,n=""])=>{const l=Object.entries(t).map(([a,s])=>me(s)?`[${a}=${JSON.stringify(s)}]`:s===!0?`[${a}]`:"").join(""),i=`head > ${e}${l}`;return Array.from(document.querySelectorAll(i)).find(a=>a.innerText===n)||null},vv=([e,t,n])=>{if(!me(e))return null;const l=document.createElement(e);return Wi(t)&&Object.entries(t).forEach(([i,o])=>{me(o)?l.setAttribute(i,o):o===!0&&l.setAttribute(i,"")}),me(n)&&l.appendChild(document.createTextNode(n)),l},mv=ju,_v=async()=>{var n;const e=mv({name:"VuepressApp",setup(){var l;pv();for(const i of dl)(l=i.setup)==null||l.call(i);return()=>[ce(Ys),...dl.flatMap(({rootComponents:i=[]})=>i.map(o=>ce(o)))]}}),t=dv();fv(e),hv(e,t,dl);for(const l of dl)await((n=l.enhance)==null?void 0:n.call(l,{app:e,router:t,siteData:sn}));return e.use(t),{app:e,router:t}};_v().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{Yn as T,Le as _,ge as a,ie as b,ee as c,_v as createVueApp,Ft as d,tu as e,Te as f,ke as g,kl as h,bv as i,U as o,bt as r,yv as v,Me as w}; +function __vite__mapDeps(indexes) { + if (!__vite__mapDeps.viteFileDeps) { + __vite__mapDeps.viteFileDeps = ["assets/sun-events.html-BgsSnipk.js","assets/first-automation_05-BSXfHgTV.js","assets/first-automation.html-U01iwXIn.js"] + } + return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) +} diff --git a/assets/binary-sensor.html-DB_qPuWM.js b/assets/binary-sensor.html-DB_qPuWM.js new file mode 100644 index 0000000000..b34e6f9d1b --- /dev/null +++ b/assets/binary-sensor.html-DB_qPuWM.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-741d68b2","path":"/node/binary-sensor.html","title":"Binary Sensor","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"State","slug":"state","link":"#state","children":[]},{"level":3,"title":"Attributes","slug":"attributes","link":"#attributes","children":[]},{"level":3,"title":"Input Override","slug":"input-override","link":"#input-override","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"state","slug":"state-1","link":"#state-1","children":[]},{"level":3,"title":"attributes","slug":"attributes-1","link":"#attributes-1","children":[]}]}],"git":{"updatedTime":1721424946000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1},{"name":"Mikko Tervala","email":"miksu103@gmail.com","commits":1}]},"filePathRelative":"node/binary-sensor.md"}');export{t as data}; diff --git a/assets/binary-sensor.html-DbMx8MUV.js b/assets/binary-sensor.html-DbMx8MUV.js new file mode 100644 index 0000000000..a673583fa1 --- /dev/null +++ b/assets/binary-sensor.html-DbMx8MUV.js @@ -0,0 +1 @@ +import{_ as i,r as a,o as r,c as d,a as e,d as t,b as n,e as c}from"./app-DW3AHQOa.js";const h={},l={class:"custom-container warning"},u=e("p",{class:"custom-container-title"},"WARNING",-1),p={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},b=e("h1",{id:"binary-sensor",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#binary-sensor","aria-hidden":"true"},"#"),t(" Binary Sensor")],-1),_=e("p",null,"Creates a binary sensor in Home Assistant which can be manipulated from this node.",-1),f=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),m={id:"state",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#state","aria-hidden":"true"},"#",-1),y=c('
  • Type: boolean

The state of the entity should be updated to

To set the Home Assistant state to Unknown, send a state with a js expression null.

Attributes

  • Type: Object

Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

Input Override

  • Type: string
  • Values: accept | merge | block

Determine how input values will be handled. When merge is selected the message object values will override the configuration values.

Inputs

properties of msg.payload

state

  • Type: string | number | boolean

The value of the entity state will be updated.

attributes

  • Type: Object

Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

',17);function x(v,T){const o=a("ExternalLinkIcon"),s=a("Badge");return r(),d("div",null,[e("div",l,[u,e("p",null,[e("em",null,[t("Needs "),e("a",p,[t("Custom Integration"),n(o)]),t(" installed in Home Assistant for this node to function")])])]),b,_,f,e("h3",m,[g,t(" State "),n(s,{text:"required"})]),y])}const w=i(h,[["render",x],["__file","binary-sensor.html.vue"]]);export{w as default}; diff --git a/assets/button.html-D9AM0-MO.js b/assets/button.html-D9AM0-MO.js new file mode 100644 index 0000000000..1efde93581 --- /dev/null +++ b/assets/button.html-D9AM0-MO.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-636bc153","path":"/node/button.html","title":"Button","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]}],"git":{"updatedTime":1662369628000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/button.md"}');export{t as data}; diff --git a/assets/button.html-DJLpLyCD.js b/assets/button.html-DJLpLyCD.js new file mode 100644 index 0000000000..77e955e071 --- /dev/null +++ b/assets/button.html-DJLpLyCD.js @@ -0,0 +1 @@ +import{_ as s,r as a,o as i,c as r,a as e,d as t,b as n,e as c}from"./app-DW3AHQOa.js";const d={},l={class:"custom-container warning"},h=e("p",{class:"custom-container-title"},"WARNING",-1),u={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},_=e("h1",{id:"button",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#button","aria-hidden":"true"},"#"),t(" Button")],-1),p={href:"https://developers.home-assistant.io/docs/core/entity/button",target:"_blank",rel:"noopener noreferrer"},f=c('

Outputs

Value types:

  • entity: complete entity object
  • entity id: entity id of the pressed button
  • entity state: entity state of the pressed button
  • config: config properties of the node
',3);function m(b,g){const o=a("ExternalLinkIcon");return i(),r("div",null,[e("div",l,[h,e("p",null,[e("em",null,[t("Needs "),e("a",u,[t("Custom Integration"),n(o)]),t(" installed in Home Assistant for this node to function")])])]),_,e("p",null,[t("Creates a "),e("a",p,[t("button entity"),n(o)]),t(" in Home Assistant that will trigger the flow when pressed.")]),f])}const x=s(d,[["render",m],["__file","button.html.vue"]]);export{x as default}; diff --git a/assets/call-service.html-BLSy7J4X.js b/assets/call-service.html-BLSy7J4X.js new file mode 100644 index 0000000000..dedf9c33c4 --- /dev/null +++ b/assets/call-service.html-BLSy7J4X.js @@ -0,0 +1,38 @@ +import{_ as p,r as e,o as u,c,a as s,b as a,w as t,d as o,e as r}from"./app-DW3AHQOa.js";const l="/node-red-contrib-home-assistant-websocket/assets/jsonata_1_1-BOrSTtQg.png",k={},i=r('

Call Service

Integrations in Home Assistant provide service calls that can be used, for example, to set target temperature on heaters and air-conditioning units. All service calls can be found and tested within Home Assistant Developer toolbox, and it is also useful to check the integration documentation to identify exactly what is required for a successful service call.

All service calls require:

  • a domain (integration platform) such as 'climate'
  • a service call within this domain, such as 'set_temperature'
  • a target entity or entities (or area or device containing entities) to apply the service to
  • a JSON data object, containing any additional required and optional parameters

The data object will vary, depending on the integration and service call, from an empty object {} to something much more complex. Constructing this data object correctly is key to a successful service call, and JSONata rather than mustache templating should ideally be used to achieve this.

Note: The data field used in a service call must be a valid JSON object.

  • Mustache templates are delimited with {{msg.payload}}. Although acceptable in most JSON input fields, this is invalid syntax in JSONata expressions and must not be used.
  • Home Assistant configuration uses YAML constructs, containing space-tabulation for objects and '-' for arrays. This format is incompatible with both JSON and JSONata, but YAML constructs can be converted to JSON.
  • The WebSocket nodes Data UI field option typically offers two input methods:
    • {} for JSON - this must be strict JSON formed with all literals and string keys. Mustache templates may work successfully in simple strings. JSONata will not work here. The JSON option cannot accept anything other than literals and Mustache templates.
    • J: for JSONata (expression) - this must evaluate to strict JSON, but can be formed with expressions in both the object keys (evaluating as strings) and the object values. In JSONata, literals evaluate as themselves, so the JSONata option can accept a JSON literal construct.

Passing variables to WebSocket nodes in summary

JSONata in Node-RED nodes accesses the incoming message as a JSON object. Thus msg.payload is referenced just as payload and is evaluated as the value of that key. The leading 'msg.' is not required, and {{ payload }} is invalid JSONata syntax.

Node-RED typically uses msg.payload to pass values between nodes, however any field can be used. Most WebSocket nodes have output properties that default to set msg.data to the entity details, and therefore in the flow following (not in) the node, data.state will typically provide the state value of the entity that was the subject of the preceding WebSocket node.

Within the WebSocket node itself, the entity data is accessed using the special JSONata $entity() function, hence $entity().state would be used. In a similar manner, the $entities() function can reference any Home Assistant entity, and $entities('sensor.date_time').state would return the state value of the given date_time sensor.

In JSONata, as well as using message fields or the entity functions, Node-RED provides functions to access environment variables using $env('ENV_NAME'). Global context can be read using $globalContext(name[, store]) and flow context likewise as $flowContext(name[, store]).

JSONata and the Call Service node

For Node-RED flows with a Call Service node there are three locations where the Data object can be defined.

  • Directly in the Call Service node UI 'Data' field, using the JSONata option.
  • In a preceding Change node, passing the Service Call settings in a msg.payload object.
  • In a flow trigger node, such as Events: state node, generated as an output msg.payload object.

There are advantages and drawbacks to each approach, and personal choice as well as the particular case and need will influence your flow design.

screenshot

Here are three examples, each using JSONata to set the required Data object, and one example of using JSONata to process service call return data.

[{"id":"0050317002075c30","type":"group","z":"776c027950fc8c3f","name":"Call Service node - build a data object / process call return","style":{"label":true,"color":"#000000"},"nodes":["a67d69634829a418","86cbf80d.5a9cf8","8aad6643.9ee7a8","897a31873370f8cb","3bbb02bc34fb543a","6601ecbcd16c5aa3","fe24231bb58e259d","b0b87dc3a978e67e","8602b67dfe66a5e3","fe9baddadc8fea32","fd65cb1e1c933b3a","0acd153a39f25184","be9ef2598f33324a","8446a03e6d2b76a3","3c75c1ae78ed9894","9fc179c38d22f267","c84c9a405862bb69","f0d2bc4cc11a7608"],"x":34,"y":39,"w":1212,"h":442},{"id":"a67d69634829a418","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"","server":"","version":5,"debugenabled":false,"domain":"climate","service":"set_temperature","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1030,"y":220,"wires":[[]]},{"id":"86cbf80d.5a9cf8","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"","server":"","version":5,"debugenabled":false,"domain":"light","service":"turn_on","areaId":[],"deviceId":[],"entityId":["light.kitchen"],"data":"{\\"brightness\\": $min([$entities(\\"light.kitchen\\").attributes.brightness + $number($entities(\\"input_number.brightness\\").state), 255])}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"data"}],"queue":"none","output_location":"payload","output_location_type":"msg","x":730,"y":120,"wires":[[]]},{"id":"8aad6643.9ee7a8","type":"server-state-changed","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Remote Button","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"sensor.button","entityIdType":"exact","outputInitially":false,"stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":520,"y":120,"wires":[["86cbf80d.5a9cf8"]]},{"id":"897a31873370f8cb","type":"server-state-changed","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Input Number (Temp)","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"input_number.help_temp_number","entityIdType":"exact","outputInitially":false,"stateType":"num","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":540,"y":220,"wires":[["fe24231bb58e259d"]]},{"id":"3bbb02bc34fb543a","type":"inject","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Manual Test","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":530,"y":80,"wires":[["86cbf80d.5a9cf8"]]},{"id":"6601ecbcd16c5aa3","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1a - JSONata builds object in Call Service node \\\\n Increase light brightness with remote","info":"","x":240,"y":100,"wires":[]},{"id":"fe24231bb58e259d","type":"change","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Service Call Settings","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\\t   \\"target\\": {\\"entity_id\\": $globalContext(\\"AClist\\")},\\t   \\"data\\": {\\t       \\"temperature\\": payload,\\t       \\"hvac_mode\\": payload>20 ? \\"heat\\" : \\"cool\\"\\t   }\\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":220,"wires":[["a67d69634829a418"]]},{"id":"b0b87dc3a978e67e","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Send notification","server":"","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_geoff_phone","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":790,"y":300,"wires":[[]]},{"id":"8602b67dfe66a5e3","type":"server-state-changed","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Last person to leave","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"person.","entityIdType":"substring","outputInitially":false,"stateType":"str","ifState":"\\"home\\" in $entities().*[$substringBefore(entity_id,\\".\\")=\\"person\\"].state","ifStateType":"jsonata","ifStateOperator":"jsonata","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\\t    \\"data\\": {\\t        \\"message\\": \\"The \\" & $join($entities().*[state = \\"on\\" and entity_id ~> /^light|^switch/].attributes.friendly_name, \\", \\") & \\" are on.\\",\\t        \\"title\\": \\"Things Left On \\" & $entity().attributes.friendly_name\\t    }\\t}","valueType":"jsonata"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":530,"y":300,"wires":[[],["b0b87dc3a978e67e"]]},{"id":"fe9baddadc8fea32","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"","server":"","version":5,"debugenabled":false,"domain":"weather","service":"get_forecasts","areaId":[],"deviceId":[],"entityId":["weather.forecast_home"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"results","propertyType":"msg","value":"","valueType":"results"}],"queue":"none","x":360,"y":440,"wires":[["8446a03e6d2b76a3"]]},{"id":"fd65cb1e1c933b3a","type":"inject","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Set Forecast type","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\\"data\\": {\\"type\\": \\"hourly\\"}}","payloadType":"jsonata","x":160,"y":440,"wires":[["fe9baddadc8fea32"]]},{"id":"0acd153a39f25184","type":"debug","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Start Hour","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"$substringAfter(payload.time,\\"T\\")~>$substringBefore(\\"+\\")","targetType":"jsonata","statusVal":"$substringAfter(payload.time,\\"T\\")~>$substringBefore(\\"+\\")","statusType":"auto","x":1130,"y":440,"wires":[]},{"id":"be9ef2598f33324a","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1d - JSONata extracts details from service call return \\\\n using Inject, Change, and Debug nodes","info":"","x":250,"y":380,"wires":[]},{"id":"8446a03e6d2b76a3","type":"change","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Extract forecast time and arrays of hourly temp, cloud, and rain","rules":[{"t":"set","p":"payload","pt":"msg","to":"results.*.forecast{\\t   \\"time\\": $[0].datetime,\\t   \\"temp\\": $.temperature,\\t   \\"cloud\\": $.cloud_coverage,\\t   \\"rain\\": $.precipitation\\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":440,"wires":[["0acd153a39f25184","3c75c1ae78ed9894"]]},{"id":"3c75c1ae78ed9894","type":"debug","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1120,"y":400,"wires":[]},{"id":"9fc179c38d22f267","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1b - JSONata builds object in Change Node \\\\n Set a/c target temperature and mode","info":"","x":230,"y":200,"wires":[]},{"id":"c84c9a405862bb69","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1c - JSONata builds object in Event: State node \\\\n Send notification when leaving home","info":"","x":240,"y":300,"wires":[]},{"id":"f0d2bc4cc11a7608","type":"inject","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Turn Off","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\\t   \\"domain\\": \\"homeassistant\\",\\t   \\"service\\": \\"turn_off\\",\\t   \\"target\\": {\\t       \\"area_id\\": [\\"bedroom\\"]\\t   },\\t   \\"data\\": {} \\t}","payloadType":"jsonata","x":820,"y":180,"wires":[["a67d69634829a418"]]}]
+

Setting the Data field

Settings a data property from a Home Assistant entity

Example: A Call Service node that sets the target temperature of a climate entity to the current temperature of a sensor entity.

{
+  "temperature": $entities("sensor.living_room_temperature").state
+}
+

Setting a data property from a Home Assistant entity with a calculation

Here the state of a sensor entity is read, converted to a number, and then increased by 3.

WARNING

States from Home Assistant are always strings, and so any calculations must be converted to a number first.

{
+  "temperature": $number($entities("sensor.living_room_temperature").state) + 3
+}
+

Increase lights brightness with remote

Example: A remote with a button that when clicked increases the brightness of a given light by an amount that is set from an input_number inside Home Assistant.

JSONata expression in the Call Service node UI Data field. Nothing special is required as input to this node as all the settings are completed within the node itself.

{
+  "brightness": $min([
+    $entities("light.kitchen").attributes.brightness +
+      $number($entities("input_number.brightness").state),
+    255
+  ])
+}
+

Setting target temperature on air-conditioning unit

Example: Set the target temperature (and mode) for air-conditioning unit from the input msg.payload value.

Here a Change node is used to build the msg.payload object required to set the Call Service node parameters, including the nested data field. In a Change node, the special WebSocket $entity() and $entities() functions are not available, however we can still perform a read from global context using the Node-RED $globalContext() function. These Node-RED functions can be used to bring in values from context and environment variables.

{
+   "target": {"entity_id": $globalContext("AClist")},
+   "data": {
+       "temperature": payload,
+       "hvac_mode": payload>20 ? "heat" : "cool"
+   }
+}
+

The Call Service node can accept from one to all of the UI parameters in msg.payload, and where given these each take precedence over any UI settings. Default settings can therefore be set in the UI, and can then be over-riden by the input message, including when using settings from Inject nodes as shown in the example.

Notification of lights left on when leaving home

Example: Get notified when lights or switches are left on when you leave.

This example uses JSONata in two places in the Events: state node. The state value test is a JSONata expression that must return true for the node to output a message (upper output). This code selects an array of all entity states for entities starting with 'person', and will return true if this array contains one or more with state "home". The expression will therefore only return false when no-one is home, and we can use the lower (condition fail) output rather than using the JSONata $not() function to look for 'not home'.

"home" in $entities().*[$substringBefore(entity_id,".")="person"].state
+

JSONata is also then used in the output properties to create the required object for a notification service call. It uses $entities().* with a filter looking for those with "light" or "switch" in the entity_id and state "on", then selecting the friendly_name, and joining all those found into a string list in the message.

The message title uses $entity().attributes.friendly_name to add the name of the person who just left home to the message title.

{
+    "data": {
+        "message": "The " &
+          $join($entities().*[state = "on" and entity_id ~>
+          /^light|^switch/].attributes.friendly_name, ", ") &
+          " are on.",
+        "title": "Things Left On " & $entity().attributes.friendly_name
+    }
+}
+

In this example all the parameter setup is performed in the Events: state node, so the Call Service node can accept all the required parameters just from the input msg.payload object.

Processing a service call return

Home Assistant service calls can provide data returned as a result of the call, and JSONata is an ideal tool to manage any resulting JSON object and array structures. This example uses JSONata to extract and manipulate weather forecasts, providing a summary in a modified format.

Example: The forecast service call now returns an array of forecasts. JSONata is used to iterate over all forecasts, returning an new object for each, with a time and arrays for temperature, cloud coverage, and precipitation only.

results.*.forecast{
+   "time": $[0].datetime,
+   "temp": $.temperature,
+   "cloud": $.cloud_coverage,
+   "rain": $.precipitation
+}
+

Also see:

`,49);function q(y,g){const n=e("RouterLink");return u(),c("div",null,[i,s("ul",null,[s("li",null,[a(n,{to:"/guide/jsonata/"},{default:t(()=>[o("JSONata guide")]),_:1})]),s("li",null,[a(n,{to:"/guide/jsonata/jsonata-primer.html"},{default:t(()=>[o("JSONata primer")]),_:1})])])])}const m=p(k,[["render",q],["__file","call-service.html.vue"]]);export{m as default}; diff --git a/assets/call-service.html-D6PcUpsv.js b/assets/call-service.html-D6PcUpsv.js new file mode 100644 index 0000000000..f8c1f74a71 --- /dev/null +++ b/assets/call-service.html-D6PcUpsv.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-421eb385","path":"/cookbook/jsonata/call-service.html","title":"Call Service","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Passing variables to WebSocket nodes in summary","slug":"passing-variables-to-websocket-nodes-in-summary","link":"#passing-variables-to-websocket-nodes-in-summary","children":[]},{"level":2,"title":"JSONata and the Call Service node","slug":"jsonata-and-the-call-service-node","link":"#jsonata-and-the-call-service-node","children":[]},{"level":2,"title":"Setting the Data field","slug":"setting-the-data-field","link":"#setting-the-data-field","children":[{"level":3,"title":"Settings a data property from a Home Assistant entity","slug":"settings-a-data-property-from-a-home-assistant-entity","link":"#settings-a-data-property-from-a-home-assistant-entity","children":[]},{"level":3,"title":"Setting a data property from a Home Assistant entity with a calculation","slug":"setting-a-data-property-from-a-home-assistant-entity-with-a-calculation","link":"#setting-a-data-property-from-a-home-assistant-entity-with-a-calculation","children":[]},{"level":3,"title":"Increase lights brightness with remote","slug":"increase-lights-brightness-with-remote","link":"#increase-lights-brightness-with-remote","children":[]},{"level":3,"title":"Setting target temperature on air-conditioning unit","slug":"setting-target-temperature-on-air-conditioning-unit","link":"#setting-target-temperature-on-air-conditioning-unit","children":[]},{"level":3,"title":"Notification of lights left on when leaving home","slug":"notification-of-lights-left-on-when-leaving-home","link":"#notification-of-lights-left-on-when-leaving-home","children":[]}]},{"level":2,"title":"Processing a service call return","slug":"processing-a-service-call-return","link":"#processing-a-service-call-return","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"cookbook/jsonata/call-service.md"}');export{e as data}; diff --git a/assets/call-service_02-CqOu7WiP.png b/assets/call-service_02-CqOu7WiP.png new file mode 100644 index 0000000000..56126dcb1a Binary files /dev/null and b/assets/call-service_02-CqOu7WiP.png differ diff --git a/assets/call-service_03-BfEbDwOv.png b/assets/call-service_03-BfEbDwOv.png new file mode 100644 index 0000000000..2456bd029d Binary files /dev/null and b/assets/call-service_03-BfEbDwOv.png differ diff --git a/assets/call-service_05-DBq2t9ez.png b/assets/call-service_05-DBq2t9ez.png new file mode 100644 index 0000000000..107ea7d25c Binary files /dev/null and b/assets/call-service_05-DBq2t9ez.png differ diff --git a/assets/call-service_06-Cdv6oWF6.png b/assets/call-service_06-Cdv6oWF6.png new file mode 100644 index 0000000000..456bbbc525 Binary files /dev/null and b/assets/call-service_06-Cdv6oWF6.png differ diff --git a/assets/call-service_07-CDDnq17z.png b/assets/call-service_07-CDDnq17z.png new file mode 100644 index 0000000000..301c7d8ee2 Binary files /dev/null and b/assets/call-service_07-CDDnq17z.png differ diff --git a/assets/call-service_08-HfAzx-i_.png b/assets/call-service_08-HfAzx-i_.png new file mode 100644 index 0000000000..8295db01ae Binary files /dev/null and b/assets/call-service_08-HfAzx-i_.png differ diff --git a/assets/change-node.html-C2k8BCNM.js b/assets/change-node.html-C2k8BCNM.js new file mode 100644 index 0000000000..de5e9d2c30 --- /dev/null +++ b/assets/change-node.html-C2k8BCNM.js @@ -0,0 +1 @@ +const e=JSON.parse(`{"key":"v-cddd5a70","path":"/cookbook/jsonata/change-node.html","title":"Change node","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Read a person state history for the past week","slug":"read-a-person-state-history-for-the-past-week","link":"#read-a-person-state-history-for-the-past-week","children":[]},{"level":2,"title":"Report only those periods when 'not home' during the day","slug":"report-only-those-periods-when-not-home-during-the-day","link":"#report-only-those-periods-when-not-home-during-the-day","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/jsonata/change-node.md"}`);export{e as data}; diff --git a/assets/change-node.html-DvnmySvX.js b/assets/change-node.html-DvnmySvX.js new file mode 100644 index 0000000000..d89f89af75 --- /dev/null +++ b/assets/change-node.html-DvnmySvX.js @@ -0,0 +1,60 @@ +import{_ as p,r as e,o as u,c as r,a as s,b as t,w as a,d as o,e as c}from"./app-DW3AHQOa.js";const l="/node-red-contrib-home-assistant-websocket/assets/jsonata_7_1-BgEt8HOI.png",i={},k=c('

Change node

Using JSONata for more complex tasks:

Many automations can be coded using a simple JSONata expression at some convenient point in the flow, often directly within one of the WebSocket nodes. Where the data involved is a more complex structure, then JSONata is a powerful tool for manipulating JSON objects and arrays. Almost all computation can be achieved using JSONata in a Change node in place of using a Function node.

Read a person state history for the past week

Since Home Assistant stores state history for 10 days by default, it is possible to read historic state records. The Get History node can do this for any given entity, and using relative time it is easy to obtain an array of past state-change events.

There are no opportunities to use JSONata within the Get History node itself, however JSONata can be used both to setup the node parameters and to manipulate the returned array. In this example, JSONata is used extensively to:

  • set the input parameters for the time period required
  • read the current entity state for 'now' and the given entity ID
  • add an 'event' for 'now' and an 'event' for the start history-period time
  • calculate the time interval between successive state changes to create 'event-periods'
  • filter out any event periods less than, say, 50 minutes or for state 'unknown'
  • compact any now sequential equal-state events into one longer period

This returns a filtered array of entity states, with the time that state period started and the time it ended, and the duration in minutes. The requirement for extensive data processing here is due to the way 'person' sensors report, giving rise to short periods of 'unknown' or 'away' because Wi-Fi signal or a smart phone has gone 'off-line'.

screenshot

[{"id":"1997b594da7d37b1","type":"group","z":"776c027950fc8c3f","name":"Process history data using JSONata in a change node","style":{"label":true,"color":"#000000"},"nodes":["bd6511844a39ca08","3d87bbb92fa35243","9a3ca494edc54a30","3a4534cdc46ae67d","891ee0da3deec2c1","27f0ecf4ea3dc24f","d5dc0b522463577a"],"x":34,"y":2499,"w":1312,"h":122},{"id":"bd6511844a39ca08","type":"api-current-state","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Get current state","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"person.george","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"payload ~> |$|{\\"entityId\\": $entity().entity_id}|","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":350,"y":2540,"wires":[["9a3ca494edc54a30"]]},{"id":"3d87bbb92fa35243","type":"inject","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Set parameters","props":[{"p":"payload"},{"p":"startAt","v":"$fromMillis($millis()-(7*24*60*60000))","vt":"jsonata"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\\"relativeTime\\": \\"1 week\\"\\t}","payloadType":"jsonata","x":160,"y":2540,"wires":[["bd6511844a39ca08"]]},{"id":"9a3ca494edc54a30","type":"api-get-history","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Read history","server":"","version":1,"startDate":"","endDate":"","entityId":"","entityIdType":"equals","useRelativeTime":true,"relativeTime":"","flatten":true,"outputType":"array","outputLocationType":"msg","outputLocation":"payload","x":530,"y":2540,"wires":[["3a4534cdc46ae67d"]]},{"id":"3a4534cdc46ae67d","type":"change","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Get filtered state periods","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\\t/* FILTER parameters */\\t    $fMins:=50;\\t\\t/* get current state from entity 'data', and set the 'last_changed' to now */\\t    $first:= data~>|$|{\\"last_changed\\": $now()}|;\\t\\t/* add this to far end of history payload array, then sort by reverse time order */\\t    $x:=$append(payload, $first)^(>last_changed,>last_updated);\\t\\t/* copy the oldest state value, and add in as the first record at start of history */\\t/* we now have a 'now' and 'start of history' record, even if payload was empty    */    \\t    $x:=$append($x,{\\"state\\": $x[0].state, \\"last_changed\\": startAt});\\t\\t/* create array of state changes, with how long they have been in that state */\\t/* remove any zero periods and unknown states FILTER OUT AS REQUIRED         */\\t    $events:=$x#$i.(\\t        $prior:= $i>0 ? $x[$i-1] : {\\"first\\": $now()};\\t        {\\"index\\": $i,\\t         \\"state\\": state,\\t         \\"from\\": last_changed,\\t         \\"upto\\": $prior.last_changed,\\t         \\"dmins\\": ($toMillis($prior.last_changed)-$toMillis(last_changed))/60000~>$round(0)\\t        }\\t    )[dmins>$fMins and state!=\\"unknown\\"];\\t\\t/* merge consecutive records with the same state into one longer period */\\t/* get each event position as 'start - middle - end' or 'only'          */\\t\\t    $temp:=$events#$v.(\\t        $back:= $v<1 ? false : state = $events[$v-1].state;\\t        $next:= state = $events[$v+1].state;\\t        $position:=( $back ? ($next ? \\"middle\\" : \\"end\\") : ($next ? \\"start\\" : \\"only\\") );\\t        $~>|$|{\\"index\\": $v, \\"position\\": $position}|\\t    );\\t\\t/* get start and end indexes, and zip into a sequence array of [start, end]  */\\t/* map this array of sequences to an array of objects, one for each sequence */\\t/* where the object is the combination of a run of the same state value      */\\t\\t    $chain:=$zip($temp[position=\\"start\\"].index, $temp[position=\\"end\\"].index);\\t\\t    $array:=$map($chain, function($item) {(\\t        $recA:=$events[$item[0]];\\t        $recB:=$events[$item[1]];\\t        {\\"state\\": $recA.state,\\t        \\"from\\": $recB.from,\\t        \\"upto\\":  $recA.upto,\\t        \\"dmins\\": ($toMillis($recA.upto)-$toMillis($recB.from))/60000~>$round(0),\\t        \\"position\\": \\"merged\\"}\\t        )\\t    });\\t\\t/* combine the 'only' single events with the now-merged sequences, and sort by time */\\t    $append($temp[position=\\"only\\"], $array)^(>from);\\t\\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":2540,"wires":[["891ee0da3deec2c1","27f0ecf4ea3dc24f"]]},{"id":"891ee0da3deec2c1","type":"debug","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"State History Events","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1200,"y":2540,"wires":[]},{"id":"27f0ecf4ea3dc24f","type":"change","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"When 'not home' during the day","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[state=\\"not_home\\" and ($substringBefore(from,\\"T\\") = $substringBefore(upto,\\"T\\") ) ]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":2580,"wires":[["d5dc0b522463577a"]]},{"id":"d5dc0b522463577a","type":"debug","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Out during the day","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1190,"y":2580,"wires":[]}]
+
(
+/* FILTER parameters */
+    $fMins:=50;
+
+/* get current state from entity 'data', and set the 'last_changed' to now */
+    $first:= data~>|$|{"last_changed": $now()}|;
+
+/* add this to far end of history payload array, then sort by reverse time order */
+    $x:=$append(payload, $first)^(>last_changed,>last_updated);
+
+/* copy the oldest state value, and add in as the first record at start of history */
+/* we now have a 'now' and 'start of history' record, even if payload was empty    */
+    $x:=$append($x,{"state": $x[0].state, "last_changed": startAt});
+
+/* create array of state changes, with how long they have been in that state */
+/* remove any zero periods and unknown states FILTER OUT AS REQUIRED         */
+    $events:=$x#$i.(
+        $prior:= $i>0 ? $x[$i-1] : {"first": $now()};
+        {"index": $i,
+         "state": state,
+         "from": last_changed,
+         "upto": $prior.last_changed,
+         "dmins": ($toMillis($prior.last_changed)-$toMillis(last_changed))/60000~>$round(0)
+        }
+    )[dmins>$fMins and state!="unknown"];
+
+/* merge consecutive records with the same state into one longer period */
+/* get each event position as 'start - middle - end' or 'only'          */
+
+    $temp:=$events#$v.(
+        $back:= $v<1 ? false : state = $events[$v-1].state;
+        $next:= state = $events[$v+1].state;
+        $position:=( $back ? ($next ? "middle" : "end") : ($next ? "start" : "only") );
+        $~>|$|{"index": $v, "position": $position}|
+    );
+
+/* get start and end indexes, and zip into a sequence array of [start, end]  */
+/* map this array of sequences to an array of objects, one for each sequence */
+/* where the object is the combination of a run of the same state value      */
+
+    $chain:=$zip($temp[position="start"].index, $temp[position="end"].index);
+
+    $array:=$map($chain, function($item) {(
+        $recA:=$events[$item[0]];
+        $recB:=$events[$item[1]];
+        {"state": $recA.state,
+        "from": $recB.from,
+        "upto":  $recA.upto,
+        "dmins": ($toMillis($recA.upto)-$toMillis($recB.from))/60000~>$round(0),
+        "position": "merged"}
+        )
+    });
+
+/* combine the 'only' single events with the now-merged sequences, and sort by time */
+    $append($temp[position="only"], $array)^(>from);
+
+)
+

Notes:

The Inject node uses JSONata to initially create msg.payload as a data object, setting the relative time parameter for the Get History node, and also setting the timestamp for the effective start of this time period.

The Current State node uses JSONata in the output to retain msg.payload and also merge in the entityId using $entity().entity_id. This now sets msg.payload with the required input parameters for the Get History node (which therefore requires no UI settings). Full entity details are also captured in msg.data as usual.

::: caution This example code has been tested but person sensors can go 'off line' for long periods and the exact nature of the output data should be checked by experimentation. :::

Report only those periods when 'not home' during the day

Once state history has been manipulated like this into an event-array, it is easy to ask questions, such as "how many times has this person been away this week?"

The question "when was this person away during the day?" for example, can be answered by filtering the state event array, to look for 'not home' and for the event period (both start and end) to be entirely on the same date.

payload[state="not_home" and ($substringBefore(from,"T") = $substringBefore(upto,"T") ) ]
+

Note on history records:

In asking for the history for the past 24 hours, the Get History node will return an array of all state change events that occurred within that time period. If the current state has been unchanged for the entire period requested, then an empty array will be returned.

To address this, the JSONata code here first adds a record for 'now' with the current state. The code then finds the oldest state (which may well be the current 'now' state just added) and adds that as a record for 'the start of the time period requested' at that state. This ensures that the returned history event array is topped and tailed. The minimum state event array will therefore be one entry from start of history request to now, at the current state.

Also see:

`,23);function q(d,y){const n=e("RouterLink");return u(),r("div",null,[k,s("ul",null,[s("li",null,[t(n,{to:"/guide/jsonata/"},{default:a(()=>[o("JSONata guide")]),_:1})]),s("li",null,[t(n,{to:"/guide/jsonata/jsonata-primer.html"},{default:a(()=>[o("JSONata primer")]),_:1})])])])}const h=p(i,[["render",q],["__file","change-node.html.vue"]]);export{h as default}; diff --git a/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours.html-Bb7POubS.js b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours.html-Bb7POubS.js new file mode 100644 index 0000000000..5d2a61e2b1 --- /dev/null +++ b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours.html-Bb7POubS.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-1fbf71d1","path":"/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html","title":"Check if an entity was a certain state in the last 24 hours","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.md"}');export{t as data}; diff --git a/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours.html-DNFiTfl7.js b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours.html-DNFiTfl7.js new file mode 100644 index 0000000000..7153da70cb --- /dev/null +++ b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours.html-DNFiTfl7.js @@ -0,0 +1,3 @@ +import{_ as s,o as n,c as a,e as t}from"./app-DW3AHQOa.js";const p="/node-red-contrib-home-assistant-websocket/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_01-BvAOESUS.png",o="/node-red-contrib-home-assistant-websocket/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_02-CCEMNzXI.png",e={},u=t('

Check if an entity was a certain state in the last 24 hours

Use the get-history to get a list of state changes for the last 24 hours. Filter them using a switch node looking for a given state and then count the remaining to see if the entity was in that state during the time frame.

screenshot

[{"id":"3f683250.b26f1e","type":"inject","z":"ffbd7f06.4a014","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":236,"y":1008,"wires":[["e60a02e6.d2afc"]]},{"id":"aa3e26cd.152828","type":"debug","z":"ffbd7f06.4a014","name":"do something","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":976,"y":1008,"wires":[]},{"id":"e60a02e6.d2afc","type":"api-get-history","z":"ffbd7f06.4a014","name":"","startdate":"","enddate":"","entityid":"light.kitchen_light","entityidtype":"is","useRelativeTime":true,"relativeTime":"24 hours","flatten":true,"output_type":"split","output_location_type":"msg","output_location":"payload","x":380,"y":1008,"wires":[["b162effa.fc78f"]]},{"id":"b162effa.fc78f","type":"switch","z":"ffbd7f06.4a014","name":"on?","property":"payload.state","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":true,"outputs":1,"x":530,"y":1008,"wires":[["e4b98b67.bde238"]]},{"id":"e4b98b67.bde238","type":"join","z":"ffbd7f06.4a014","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":658,"y":1008,"wires":[["fff04d54.5615e"]]},{"id":"fff04d54.5615e","type":"switch","z":"ffbd7f06.4a014","name":"count > 0","property":"payload.length","propertyType":"msg","rules":[{"t":"gt","v":"0","vt":"num"}],"checkall":"true","repair":true,"outputs":1,"x":796,"y":1008,"wires":[["aa3e26cd.152828"]]}]
+

Here's the same example but using a function node.

screenshot

[{"id":"f79cd7b0.604f98","type":"inject","z":"ffbd7f06.4a014","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":332,"y":1200,"wires":[["753a1de3.091fa4"]]},{"id":"753a1de3.091fa4","type":"api-get-history","z":"ffbd7f06.4a014","name":"","startdate":"","enddate":"","entityid":"light.kitchen_light","entityidtype":"is","useRelativeTime":true,"relativeTime":"24 hours","flatten":true,"output_type":"array","output_location_type":"msg","output_location":"payload","x":476,"y":1200,"wires":[["389b5575.43217a"]]},{"id":"389b5575.43217a","type":"function","z":"ffbd7f06.4a014","name":"check state","func":"const state = \\"on\\";\\nconst filtered = msg.payload.filter((entity) => entity.state === state);\\n\\nif(filtered.length > 0) {\\n    msg.payload = filtered;\\n    return msg;\\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":644,"y":1200,"wires":[["6a582450.883bdc"]]},{"id":"6a582450.883bdc","type":"debug","z":"ffbd7f06.4a014","name":"do something","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":832,"y":1200,"wires":[]}]
+
`,7),c=[u];function r(l,k){return n(),a("div",null,c)}const i=s(e,[["render",r],["__file","check-if-an-entity-was-turned-on-in-the-last-24-hours.html.vue"]]);export{i as default}; diff --git a/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_01-BvAOESUS.png b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_01-BvAOESUS.png new file mode 100644 index 0000000000..f496463240 Binary files /dev/null and b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_01-BvAOESUS.png differ diff --git a/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_02-CCEMNzXI.png b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_02-CCEMNzXI.png new file mode 100644 index 0000000000..935201cec0 Binary files /dev/null and b/assets/check-if-an-entity-was-turned-on-in-the-last-24-hours_02-CCEMNzXI.png differ diff --git a/assets/conditionals.html-DxXN_ykY.js b/assets/conditionals.html-DxXN_ykY.js new file mode 100644 index 0000000000..4be1382ed1 --- /dev/null +++ b/assets/conditionals.html-DxXN_ykY.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as d,e as n}from"./app-DW3AHQOa.js";const t={},o=n('

Conditionals

Rules

is and is not

< and <= and > and >=

in and not in

The value is expected to be a comma-separated list of items.

JSONata

When this is selected as a rule it expects a boolean to be returned by the value.

starts with

in group

Value Types

string and number and boolean and regular expression and JSONata expression

Evaluates and returns the value as the selected type.

msg and flow and global

Reference to the different contexts of Node-RED.

entity and prevEntity

Reference the entity that triggered the node.

  • entity is the current state entity
  • prevEntity is the previous state entity
',18),i=[o];function r(s,c){return a(),d("div",null,i)}const l=e(t,[["render",r],["__file","conditionals.html.vue"]]);export{l as default}; diff --git a/assets/conditionals.html-wYgbDmQg.js b/assets/conditionals.html-wYgbDmQg.js new file mode 100644 index 0000000000..2055b09d21 --- /dev/null +++ b/assets/conditionals.html-wYgbDmQg.js @@ -0,0 +1 @@ +const n=JSON.parse('{"key":"v-9a822240","path":"/guide/conditionals.html","title":"Conditionals","lang":"en-US","frontmatter":{"sidebarDepth":2},"headers":[{"level":2,"title":"Rules","slug":"rules","link":"#rules","children":[{"level":3,"title":"is and is not","slug":"is-and-is-not","link":"#is-and-is-not","children":[]},{"level":3,"title":"< and <= and > and >=","slug":"and-and-and","link":"#and-and-and","children":[]},{"level":3,"title":"in and not in","slug":"in-and-not-in","link":"#in-and-not-in","children":[]},{"level":3,"title":"JSONata","slug":"jsonata","link":"#jsonata","children":[]},{"level":3,"title":"starts with","slug":"starts-with","link":"#starts-with","children":[]},{"level":3,"title":"in group","slug":"in-group","link":"#in-group","children":[]}]},{"level":2,"title":"Value Types","slug":"value-types","link":"#value-types","children":[{"level":3,"title":"string and number and boolean and regular expression and JSONata expression","slug":"string-and-number-and-boolean-and-regular-expression-and-jsonata-expression","link":"#string-and-number-and-boolean-and-regular-expression-and-jsonata-expression","children":[]},{"level":3,"title":"msg and flow and global","slug":"msg-and-flow-and-global","link":"#msg-and-flow-and-global","children":[]},{"level":3,"title":"entity and prevEntity","slug":"entity-and-preventity","link":"#entity-and-preventity","children":[]}]}],"git":{"updatedTime":1582677447000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":4}]},"filePathRelative":"guide/conditionals.md"}');export{n as data}; diff --git a/assets/config-server.html-B9BPPMNa.js b/assets/config-server.html-B9BPPMNa.js new file mode 100644 index 0000000000..bc2ce954b4 --- /dev/null +++ b/assets/config-server.html-B9BPPMNa.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1d084902","path":"/node/config-server.html","title":"Server Config","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Config","slug":"config","link":"#config","children":[{"level":3,"title":"Name","slug":"name","link":"#name","children":[]},{"level":3,"title":"Using the Home Assistant Add-on","slug":"using-the-home-assistant-add-on","link":"#using-the-home-assistant-add-on","children":[]},{"level":3,"title":"Base URL","slug":"base-url","link":"#base-url","children":[]},{"level":3,"title":"Access Token","slug":"access-token","link":"#access-token","children":[]},{"level":3,"title":"Unauthorized SSL Certificates","slug":"unauthorized-ssl-certificates","link":"#unauthorized-ssl-certificates","children":[]},{"level":3,"title":"State Boolean","slug":"state-boolean","link":"#state-boolean","children":[]},{"level":3,"title":"Enable Heartbeat","slug":"enable-heartbeat","link":"#enable-heartbeat","children":[]},{"level":3,"title":"Heartbeat Interval","slug":"heartbeat-interval","link":"#heartbeat-interval","children":[]},{"level":3,"title":"Enable Global Context Store","slug":"enable-global-context-store","link":"#enable-global-context-store","children":[]}]},{"level":2,"title":"UI Settings","slug":"ui-settings","link":"#ui-settings","children":[{"level":3,"title":"Cache Autocomplete Results","slug":"cache-autocomplete-results","link":"#cache-autocomplete-results","children":[]},{"level":3,"title":"ID Selector Display","slug":"id-selector-display","link":"#id-selector-display","children":[]},{"level":3,"title":"Status Date Format","slug":"status-date-format","link":"#status-date-format","children":[]}]},{"level":2,"title":"Details","slug":"details","link":"#details","children":[{"level":3,"title":"Context","slug":"context","link":"#context","children":[]},{"level":3,"title":"Context Example","slug":"context-example","link":"#context-example","children":[]}]},{"level":2,"title":"Connection Issues","slug":"connection-issues","link":"#connection-issues","children":[]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1663824713000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":10}]},"filePathRelative":"node/config-server.md"}');export{e as data}; diff --git a/assets/config-server.html-DgWwM5Tw.js b/assets/config-server.html-DgWwM5Tw.js new file mode 100644 index 0000000000..c66b3d843b --- /dev/null +++ b/assets/config-server.html-DgWwM5Tw.js @@ -0,0 +1,5 @@ +import{_ as o,r as i,o as r,c,a as e,d as a,b as n,e as s}from"./app-DW3AHQOa.js";const d={},h=s('

Server Config

Home Assistant connection configuration

Config

Name

  • Type: string

Label for this configuration, see details below for implications

Using the Home Assistant Add-on

  • Type: boolean

If you're running Node-RED as a Hass.io Add-on check this. No other information is needed.

Base URL

  • Type: string

The base URL and port of the Home Assistant instance can be reached at, for example: http://192.168.0.100:8123 or https://homeassistant.mysite.com

Access Token

  • Type: string

Long-lived Access Token used to contact the API

Unauthorized SSL Certificates

  • Type: boolean

This will allow you to use self-signed certificates. Only use this if you know what you're doing.

State Boolean

  • Type: string | delimited

A list of strings, not case sensitive, delimited by vertical pipe, |, that will return true for State Type Boolean.

Enable Heartbeat

  • Type: boolean

Heartbeat will send a ping message using the websocket connection to Home Assistant every X seconds. If a pong response is not received within 5 seconds Node-RED will attempt to reconnect to Home Assistant.

Heartbeat Interval

  • Type: number

The interval at which the ping message is sent to Home Assistant. The minimum value is 10 seconds.

Enable Global Context Store

  • Type: boolean

If enabled, the global context store will be used to store the Home Assistant connection, state, and service information. This allows you to use the information in other nodes using context functions.

Example below

UI Settings

Cache Autocomplete Results

Enables the caching of the JSON autocomplete requests. Enabling or disabling this may require a restart of Node-RED for it to take effect.

ID Selector Display

Which text to show in the selector after the id has been chosen.

Status Date Format

Separator

A string that will appear in the status of an event node between the state and date string.

Other options

',40),l={href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options",target:"_blank",rel:"noopener noreferrer"},p=s(`

Details

Every node requires a configuration attached to define how to contact Home Assistant, which is this config node's main purpose.

Context

Each config node will also make some data available in the global context, the Name value in this node is used as, camelcase, and the namespace for those values

Currently states, services, and events is made available in the global context. states is always set to all available states at startup and updated whenever state changes occur so it should be always up to date. services and events is only updated on initial deploy.

Context Example

Say we have a config node with the name Home Assistant, with an entity set up in Home Assistant as switch.my_switch. This state would be available within function nodes and you could fetch using something like the below code

const haCtx = global.get("homeassistant");
+const configCtx = haCtx.homeAssistant;
+const entityState = configCtx.states["switch.my_switch"];
+return entityState.state === "on" ? true : false;
+

Connection Issues

Communication with Home Assistant is accomplished via a combination of WebSocket and the REST API if you are having trouble communicating with home assistant make sure you can access the API outside of node-red, but from the same server node-red is running on, using a REST client, curl, or any number of other methods to validate the connection

References

`,11),u={href:"https://home-assistant.io/developers/rest_api",target:"_blank",rel:"noopener noreferrer"};function f(m,b){const t=i("ExternalLinkIcon");return r(),c("div",null,[h,e("p",null,[a("The other options are directly from "),e("a",l,[a("DateTimeFormat Options"),n(t)]),a(".")]),p,e("p",null,[e("a",u,[a("Home Assistant REST API"),n(t)])])])}const x=o(d,[["render",f],["__file","config-server.html.vue"]]);export{x as default}; diff --git a/assets/current-state.html-BMmGCQGb.js b/assets/current-state.html-BMmGCQGb.js new file mode 100644 index 0000000000..e78dda5c5a --- /dev/null +++ b/assets/current-state.html-BMmGCQGb.js @@ -0,0 +1,14 @@ +import{_ as c,r as o,o as r,c as l,a as n,d as s,b as a,w as p,e}from"./app-DW3AHQOa.js";const k="/node-red-contrib-home-assistant-websocket/assets/jsonata_2_1-AVzKzbZv.png",i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbIAAAA1CAMAAAATb576AAABmFBMVEUqKiouLi49PT09PWk9PY89RlA9U489X6g9aK49jc1DVnxFRUVNTU1NTXVNTZhNXpBNcKpNeK9QRj1SgLVbW1tcTU1dXV1fX19iYmJkZGRpPT1pPWlprOZxTU11TXV1dXV1s+h2TU16enp8VkN+fn6AUk2AgICFhYWIiIiJiYmMjIyPPT2PPWmPUz2Py/+VlZWYTU2Yz/+goKCoXz2oqKisrKyuaD2u5+au5/+wsLCxsbG0dE206f+6urq75P+9vb2+vr6/4O3AwMDCwsLDw8PExMTE2+3FxcXGxsbHx8fIyMjLy8vMzMzNVlfNjT3Nzc3N8//N///Ozs7PXF3Q0NDRlk3R///U1NTY2NjY2arY7e3ciovc3Nzd3d3e7e3g4ODg8//g///h4eHjv5DjzL/j4LXj7e3k5OTmrGnmy4/m5ubm///n5+fos3Xo6Ojq6urrz8/r6+vs7Ozt2art3q/t4LXt7e3w7+/09PT13d78/Pz/y4//z5j/5Lv/567/6bT/7eD/883//83//9H//+D//+b//+j///9NTNToAAADE0lEQVR42u3bCVPTQBgGYIwX1XiLZ73ricYbK6B4oMVgURvRar3xqBB7qemlqFXI33Z3k0baxpmatIbded+ZXtsQKM98u1+bpsdEOEsP/gUgQ0CGgAxkCMgQkIEMARmyiMlKSXWsG1GTJesXlFNaXLRoqXJwZCVVr3RlxxVdZWZlLVc02skirqKWv7WY08qBkSX1ru1aT9LrVM4whCMzjFwqMDK10rVdV1R6rRWFJCtqgZGNdXvfcUNIMiMOMpCBDGQgAxnIuCQriET29YBkZ9VlUcn0h9efikP266zkZOVLMjA3EDbNtCQpJntAhkP0VnF+rHY8yhlZ9vzqLao4ZLV+22v5RmnZPZusLsT45gZ6ZzpL9vPU6f9KljnZs1lAshV3f5yok9Gx3hlyf3ZnlF1fIMUWNmd3SNLSKH1SMauSXYc8VBkli91J5sUhI/VFxMw/ZE6V1fpDpl1uChFTWMXRKquSTS1Pr1X2QZbXDPt5dRGZJNI22cj+M9PCkNH6YmKtE6NdWAvWsjQjsx6mQ97Jvqx9YNKL9yQoWaJtstGLt7ICkZnfX1AxFzKSKp0krQFrwiRk9mzqk8xnIk6RLST7tE9m2fCsaS0rcLOWfT4ob3pjX966T4zEjIm5k9FNFDpAtgzbVUZGfLYf80Oy7LMHSThF1lBlU31UbN3Vpiq7cek2L1X2cZe8/pF9efyX9oNOjZIbWZo1IWSEDlTpg/rEGPbfMU76XMzMSMS1/aBmDWKM7Mrhc7o4VcYafFcyq/0gvQYjI09XJbv9IAvcP7q1NvnzQ3v9lVnCvWOc6msUs6rs2v2syG+lnYmRvZVm1UUWrgly9z2xmqATpETbfn9r2bfdwx16pU3tx+ubLe3H1vECPrDyOTFOyr4Xs7bfl706suTQE3wszNEHVoXYtu2jWZDxQzY9uOfYeAYHX/ghywwejT3P43gZR2QF/V0ehzg5W8twVBpkIAMZyEDWmeAL3t7IAvyCN06j8EYW4GkUOFnJC1mgJyvhlEDuTglEOhCQgQwBGQIykCEgQ0AGMiTY/AYI3Glr/FJkAQAAAABJRU5ErkJggg==",q="/node-red-contrib-home-assistant-websocket/assets/jsonata_boolean-BjpZUFYr.png",y={},g=e('

Current State

The Current State node has several opportunities to use JSONata. This example demonstrates all of these, using a node to fetch the current state of a climate air-conditioning unit.

The default output values for this node include setting msg.payload to the state (which for an A/C unit will be "off", "heat", "cool" or more, depending on the integration) as well as msg.data to the entire entity data object. This holds values for the last changed timestamp as well as attributes such as the friendly name and other integration dependent settings.

screenshot

Here are three examples, showing how to use JSONata to build output properties, to perform If-State conditional tests, and to provide calculated values for UI settings.

[{"id":"d0f1fad3bf96a090","type":"group","z":"776c027950fc8c3f","name":"Current State node - read the state of an entity","style":{"label":true,"color":"#000000"},"nodes":["6394700dfd39838f","8388eb36d3e25254","852c05cf8c7cae73","a3e69091339a457c","11fc322e343cbd9c","6ac52ef3e9010615","63fa3b7423417fe4","a29810da49f1efd4","4f8197db85d55fb5","fd6d41b2f67b85e0","36912490ae36c0db","f84772ea62e6e7ba","6244f42dd53b7e1f","bc6cd64ba0266d97"],"x":34,"y":499,"w":1012,"h":382},{"id":"6394700dfd39838f","type":"api-current-state","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"climate.bedroom_aircon","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"(\\t    $att:=$entity().attributes;\\t    $diff:=$att.temperature-$att.current_temperature;\\t    ($diff>0 ? \\"Heating\\" : \\"Cooling\\") & \\" by \\" & $abs($diff) & \\" degrees required\\"\\t)","valueType":"jsonata"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":430,"y":580,"wires":[["852c05cf8c7cae73"]]},{"id":"8388eb36d3e25254","type":"inject","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":580,"wires":[["6394700dfd39838f"]]},{"id":"852c05cf8c7cae73","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Output Text","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":770,"y":580,"wires":[]},{"id":"a3e69091339a457c","type":"comment","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"2a - JSONata builds output in current state node","info":"","x":240,"y":540,"wires":[]},{"id":"11fc322e343cbd9c","type":"api-current-state","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"","server":"","version":3,"outputs":2,"halt_if":"$entities('sensor.time').state < \\"17:00\\" ? \\"cool\\" : \\"off\\"","halt_if_type":"jsonata","halt_if_compare":"is","entity_id":"climate.bedroom_aircon","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"}],"for":"$entity().state = \\"off\\" ? 0 : 2","forType":"jsonata","forUnits":"hours","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":430,"y":700,"wires":[["63fa3b7423417fe4"],["a29810da49f1efd4"]]},{"id":"6ac52ef3e9010615","type":"inject","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":700,"wires":[["11fc322e343cbd9c"]]},{"id":"63fa3b7423417fe4","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Cooling for 2+ hours before 17:00, or Off","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":840,"y":680,"wires":[]},{"id":"a29810da49f1efd4","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"otherwise","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":700,"y":740,"wires":[]},{"id":"4f8197db85d55fb5","type":"comment","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"2b - JSONata builds conditional test value, and UI parameter","info":"","x":280,"y":660,"wires":[]},{"id":"fd6d41b2f67b85e0","type":"comment","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"2c - JSONata builds conditional Boolean","info":"","x":220,"y":780,"wires":[]},{"id":"36912490ae36c0db","type":"api-current-state","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"","server":"","version":3,"outputs":2,"halt_if":"(\\t    $state:=$entity().state;\\t    $time:=$entities('sensor.time').state;\\t    ($time<=\\"09:00\\" or $time>=\\"17:00\\") and ($state=\\"heat\\" or $state=\\"cool\\")\\t)","halt_if_type":"jsonata","halt_if_compare":"jsonata","entity_id":"climate.bedroom_aircon","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entity"}],"for":"$substringAfter($now(),\\"T\\")>\\"10:00\\" ? 20 : 10","forType":"jsonata","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":430,"y":820,"wires":[["6244f42dd53b7e1f"],["bc6cd64ba0266d97"]]},{"id":"f84772ea62e6e7ba","type":"inject","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":820,"wires":[["36912490ae36c0db"]]},{"id":"6244f42dd53b7e1f","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"On outside of office hours","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload.state","targetType":"msg","statusVal":"payload.state","statusType":"auto","x":850,"y":800,"wires":[]},{"id":"bc6cd64ba0266d97","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"otherwise","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload.state","targetType":"msg","statusVal":"payload.state","statusType":"auto","x":680,"y":840,"wires":[]}]
+

Creating output properties

Example: Report the difference between room temperature and target temperature for an air-conditioning unit.

In the first example we are looking to retrieve the current state and attributes from an air-conditioning unit, and output a text message describing the difference between current and target temperature. The A/C unit current temperature (read only) and the A/C unit target temperature (can be set with a service call) are located in the entity attributes. These are both numbers, so it is very easy to calculate the difference.

Note: The default value msg.data is set only for the output message, and therefore msg.data.state would be used to obtain the entity state in nodes further along the flow, but $entity().state is used to obtain the entity state in JSONata expressions inside the node. When using JSONata to build an output message property, there is no requirement to retain the default output property settings for msg.data unless this is specifically required later in the flow.

(
+    $att:=$entity().attributes;
+    $diff:=$att.temperature-$att.current_temperature;
+    ($diff>0 ? "Heating" : "Cooling") & " by " & $abs($diff) & " degrees required"
+)
+

Providing a conditional test value (JSONata expression as a value)

Example: Output only where the A/C unit has been cooling for two hours and the local time is before 17:00, or when the unit is off.

The Current State node provides for a state value test opportunity, which if set can be used to direct the message output one of two ways, depending whether the entity state passes or fails the test. When the If State option is chosen with a conditional (not JSONata) the condition expects a value to test against. In this example, using JSONata on the right hand side will return the value of the evaluated expression ("cool" before 17:00 and "off" otherwise) to be tested against the current state value and using the chosen conditional operator.

screenshot

$entities('sensor.time').state < "17:00" ? "cool" : "off"
+

Generating UI field setting values

The Current State node also allows for a For, or duration of state test, and here JSONata is again being used to return either '0' when the state is "off" or '2' (hours) when the state is not "off". This complex arrangement will together test for the A/C unit being either immediately off after 17:00, or in cooling mode for at least two hours before 17:00.

$entity().state = "off" ? 0 : 2
+
`,19),d=n("code",null,"$entity().state",-1),f=n("code",null,"$entities('sensor.time').state",-1),m={href:"https://www.home-assistant.io/integrations/time_date/",target:"_blank",rel:"noopener noreferrer"},h=e('

Conditional test (JSONata expression as a Boolean result)

Example: Report the air-conditioning unit being on outside of office hours.

When the If State option is chosen with JSONata (not a conditional) then the right hand side must be a JSONata expression that returns a Boolean value of either true or false. When true the If State test is successful (the message is output from the top exit) when false the test fails (the message is output from the lower exit).

screenshot

In this example the JSONata expression is a code block, obtaining the node subject entity state and separate entity local time as in the previous example, but now combining both into one predicate expression. If the local time is outside 09:00 to 17:00 and the state is either heat or cool, then the expression will return true.

(
+    $state:=$entity().state;
+    $time:=$entities('sensor.time').state;
+    ($time<="09:00" or $time>="17:00") and ($state="heat" or $state="cool")
+)
+

JSONata used at this point can be extensive, with a combination of entity states or attributes and Boolean logic as required. The use of OR to combine various states can only be more easily achieved in this way.

Also see:

`,8);function b(v,x){const u=o("ExternalLinkIcon"),t=o("RouterLink");return r(),l("div",null,[g,n("p",null,[s("Note that here the use of "),d,s(" returns the current state of the node's subject entity, and that "),f,s(" returns the state of another specified entity. The "),n("a",m,[s("Time & Date Integration"),a(u)]),s(" should be added to the configuration file, and then the time sensor will return the current local time. This is useful for local-time condition testing, whereas the time_utc sensor will return UTC-time which is more useful with Home Assistant timestamps.")]),h,n("ul",null,[n("li",null,[a(t,{to:"/guide/jsonata/"},{default:p(()=>[s("JSONata guide")]),_:1})]),n("li",null,[a(t,{to:"/guide/jsonata/jsonata-primer.html"},{default:p(()=>[s("JSONata primer")]),_:1})])])])}const _=c(y,[["render",b],["__file","current-state.html.vue"]]);export{_ as default}; diff --git a/assets/current-state.html-BmYsyJ0a.js b/assets/current-state.html-BmYsyJ0a.js new file mode 100644 index 0000000000..8be66ebb91 --- /dev/null +++ b/assets/current-state.html-BmYsyJ0a.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-03774460","path":"/node/current-state.html","title":"Current State","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entity ID","slug":"entity-id","link":"#entity-id","children":[]},{"level":3,"title":"If State","slug":"if-state","link":"#if-state","children":[]},{"level":3,"title":"For","slug":"for","link":"#for","children":[]},{"level":3,"title":"State Type","slug":"state-type","link":"#state-type","children":[]},{"level":3,"title":"Block Input Overrides","slug":"block-input-overrides","link":"#block-input-overrides","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"payload.entityId","slug":"payload-entityid","link":"#payload-entityid","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1719607434000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":7},{"name":"Simon Kaiser","email":"simon@emperor.ch","commits":1}]},"filePathRelative":"node/current-state.md"}');export{e as data}; diff --git a/assets/current-state.html-Dan7zvVz.js b/assets/current-state.html-Dan7zvVz.js new file mode 100644 index 0000000000..421b776f73 --- /dev/null +++ b/assets/current-state.html-Dan7zvVz.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-288c9e6c","path":"/cookbook/jsonata/current-state.html","title":"Current State","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Creating output properties","slug":"creating-output-properties","link":"#creating-output-properties","children":[]},{"level":3,"title":"Providing a conditional test value (JSONata expression as a value)","slug":"providing-a-conditional-test-value-jsonata-expression-as-a-value","link":"#providing-a-conditional-test-value-jsonata-expression-as-a-value","children":[]},{"level":3,"title":"Generating UI field setting values","slug":"generating-ui-field-setting-values","link":"#generating-ui-field-setting-values","children":[]},{"level":3,"title":"Conditional test (JSONata expression as a Boolean result)","slug":"conditional-test-jsonata-expression-as-a-boolean-result","link":"#conditional-test-jsonata-expression-as-a-boolean-result","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/jsonata/current-state.md"}');export{e as data}; diff --git a/assets/current-state.html-aEJCnhno.js b/assets/current-state.html-aEJCnhno.js new file mode 100644 index 0000000000..41ac9bbe44 --- /dev/null +++ b/assets/current-state.html-aEJCnhno.js @@ -0,0 +1 @@ +import{_ as d,r as n,o as l,c,a as e,d as t,b as o,w as a,e as h}from"./app-DW3AHQOa.js";const u={},f=e("h1",{id:"current-state",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#current-state","aria-hidden":"true"},"#"),t(" Current State")],-1),p=e("p",null,"Returns the current state of an entity. Useful for using conditional logic to automation flows.",-1),_=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),y={id:"entity-id",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#entity-id","aria-hidden":"true"},"#",-1),b=e("li",null,[t("Type: "),e("code",null,"string")],-1),m=e("p",null,"The id of the entity to return.",-1),x=e("h3",{id:"if-state",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#if-state","aria-hidden":"true"},"#"),t(" If State")],-1),v=e("ul",null,[e("li",null,[t("Type: "),e("code",null,"string")])],-1),k=e("p",null,"If the conditional statement is evaluated as true send the message to the first output otherwise send it to the second output. If blank there will only be one output.",-1),T=e("p",null,[e("strong",null,"Also see:")],-1),I=h('

For

  • Type: number

The amount of time the entity state needs to have been constant for the "If state" to be true

State Type

  • Type: string
  • Values: string|number|boolean
  • Default: string

Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

Block Input Overrides

  • Type: boolean
  • Default: false

Stop msg.payload values from overriding local config

Inputs

payload.entityId

  • Type : string

    Overrides or sets the entity id for which the current state is being fetched

Outputs

Value types:

  • entity: full entity object
  • entity id: entity id of the triggered entity
  • entity state: entity state of the triggered entity
  • config: config properties of the node

References

',16),w={href:"https://home-assistant.io/docs/configuration/state_object/",target:"_blank",rel:"noopener noreferrer"};function B(S,C){const r=n("Badge"),i=n("RouterLink"),s=n("ExternalLinkIcon");return l(),c("div",null,[f,p,_,e("h3",y,[g,t(" Entity ID "),o(r,{text:"required"})]),e("ul",null,[b,e("li",null,[t("Accepts "),o(i,{to:"/guide/mustache-templates.html"},{default:a(()=>[t("Mustache Templates")]),_:1})])]),m,x,v,k,T,e("ul",null,[e("li",null,[o(i,{to:"/guide/conditionals.html"},{default:a(()=>[t("Conditionals")]),_:1})])]),I,e("ul",null,[e("li",null,[e("a",w,[t("Home Assistant State Objects"),o(s)])])])])}const O=d(u,[["render",B],["__file","current-state.html.vue"]]);export{O as default}; diff --git a/assets/development.html-BnHcbBQ7.js b/assets/development.html-BnHcbBQ7.js new file mode 100644 index 0000000000..a93ada620b --- /dev/null +++ b/assets/development.html-BnHcbBQ7.js @@ -0,0 +1,11 @@ +import{_ as a,r,o as l,c as i,a as e,d as n,b as o,e as s}from"./app-DW3AHQOa.js";const c={},d=e("h1",{id:"development",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#development","aria-hidden":"true"},"#"),n(" Development")],-1),h={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket/blob/main/CONTRIBUTING.md",target:"_blank",rel:"noopener noreferrer"},p=e("h2",{id:"environment-setup",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#environment-setup","aria-hidden":"true"},"#"),n(" Environment setup")],-1),u=e("p",null,"Here are the steps to successfully setup your development environment to contribute to this project",-1),_=e("h3",{id:"setup-using-the-vs-code-dev-container",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#setup-using-the-vs-code-dev-container","aria-hidden":"true"},"#"),n(" Setup using the VS Code dev container")],-1),m=e("p",null,"This will set up a docker container with all the required tools and dependencies to get started.",-1),g={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket",target:"_blank",rel:"noopener noreferrer"},b=s(`
  • Clone your forked repository to your local machine.

    git clone https://github.com/<GITHUB_USER_NAME>/node-red-contrib-home-assistant-websocket
    +
  • Open the project in VS Code.

  • `,2),f={href:"https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers",target:"_blank",rel:"noopener noreferrer"},k=e("li",null,[e("p",null,'Click the green button in the lower-left corner of the window that says "Reopen in Container".')],-1),v=e("li",null,[e("p",null,"Wait for the container to build and start.")],-1),w=e("li",null,[e("p",null,[n("Open a terminal in VS Code and run "),e("code",null,"npm run dev"),n(" to start the development server.")])],-1),x=e("h3",{id:"setup-locally",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#setup-locally","aria-hidden":"true"},"#"),n(" Setup locally")],-1),y={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket",target:"_blank",rel:"noopener noreferrer"},N=s(`
  • Clone your forked repository to your local machine.

    git clone https://github.com/zachowj/node-red-contrib-home-assistant-websocket
    +
  • create an npm link to your forked project. This will also build this project's dependencies.

    cd node-red-contrib-home-assistant-websocket
    +npm link
    +
  • `,2),E={href:"https://nodered.org/docs/getting-started/local",target:"_blank",rel:"noopener noreferrer"},R=s(`
    cd ~/dev/node-red
    +npm install -g --unsafe-perm node-red
    +
    `,1),C=s(`
  • Install your fork project into local Node-RED using npm link:

    cd ~/dev/node-red
    +npm link node-red-contrib-home-assistant-websocket
    +
  • Starting Node-RED on localhost

    cd ~/dev/node_modules/node-red
    +npm run dev
    +
  • `,2),j=e("h3",{id:"accessing",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#accessing","aria-hidden":"true"},"#"),n(" Accessing")],-1),I=e("p",null,[n("After running "),e("code",null,"npm run dev"),n(" Node-RED will be running on ports 1880 and 3000. You can access the development server at http://localhost:1880 or http://localhost:3000 either port can be used. On port 3000 browser-sync is running and will reload the browser when changes are made to the editor source code.")],-1),T=e("h3",{id:"linting",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#linting","aria-hidden":"true"},"#"),n(" Linting")],-1),S={href:"https://eslint.org/",target:"_blank",rel:"noopener noreferrer"},D={href:"https://prettier.io/",target:"_blank",rel:"noopener noreferrer"},V=e("code",null,"npm run lint",-1),A=e("h3",{id:"testing",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#testing","aria-hidden":"true"},"#"),n(" Testing")],-1),B=e("ol",null,[e("li",null,[n("Run "),e("code",null,"npm run test"),n(" to run the tests.")])],-1);function G(O,z){const t=r("ExternalLinkIcon");return l(),i("div",null,[d,e("p",null,[n("Also see "),e("a",h,[n("CONTRIBUTING.md"),o(t)]),n(".")]),p,u,_,m,e("ol",null,[e("li",null,[e("p",null,[n("Go to the "),e("a",g,[n("Node-RED Home Assistant"),o(t)]),n(" repository and fork it.")])]),b,e("li",null,[e("p",null,[n("Install the "),e("a",f,[n("Remote - Containers"),o(t)]),n(" extension.")])]),k,v,w]),x,e("ol",null,[e("li",null,[e("p",null,[n("Go to the "),e("a",y,[n("Node-RED Home Assistant"),o(t)]),n(" repository and fork it.")])]),N,e("li",null,[e("p",null,[e("a",E,[n("Install"),o(t)]),n(" Node-RED on localhost, assuming we install it on ~/dev directory (you can install it in another location as you wish)")]),R]),C]),j,I,T,e("p",null,[n("This project uses "),e("a",S,[n("ESLint"),o(t)]),n(" and "),e("a",D,[n("Prettier"),o(t)]),n(" to lint and format the code. You can run "),V,n(" to lint the code.")]),A,B])}const L=a(c,[["render",G],["__file","development.html.vue"]]);export{L as default}; diff --git a/assets/development.html-kF-1ViGv.js b/assets/development.html-kF-1ViGv.js new file mode 100644 index 0000000000..05991e9286 --- /dev/null +++ b/assets/development.html-kF-1ViGv.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-531add2c","path":"/guide/development.html","title":"Development","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Environment setup","slug":"environment-setup","link":"#environment-setup","children":[{"level":3,"title":"Setup using the VS Code dev container","slug":"setup-using-the-vs-code-dev-container","link":"#setup-using-the-vs-code-dev-container","children":[]},{"level":3,"title":"Setup locally","slug":"setup-locally","link":"#setup-locally","children":[]},{"level":3,"title":"Accessing","slug":"accessing","link":"#accessing","children":[]},{"level":3,"title":"Linting","slug":"linting","link":"#linting","children":[]},{"level":3,"title":"Testing","slug":"testing","link":"#testing","children":[]}]}],"git":{"updatedTime":1665532209000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"guide/development.md"}');export{e as data}; diff --git a/assets/device-config.html-BK4OG4oz.js b/assets/device-config.html-BK4OG4oz.js new file mode 100644 index 0000000000..4896f5ebdb --- /dev/null +++ b/assets/device-config.html-BK4OG4oz.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as i,e as r}from"./app-DW3AHQOa.js";const d={},n=r('

    Device Config

    Configuration

    Name

    • Type: string

    The name of the device that will show in Home Assistant

    Manufacturer

    • Type: string

    The manufacturer of the device

    Model

    • Type: string

    The model of the device

    Software Version

    • Type: string

    The software version of the device

    Hardware Version

    • Type: string

    The hardware version of the device

    ',17),o=[n];function h(c,t){return a(),i("div",null,o)}const l=e(d,[["render",h],["__file","device-config.html.vue"]]);export{l as default}; diff --git a/assets/device-config.html-DBtsAxx_.js b/assets/device-config.html-DBtsAxx_.js new file mode 100644 index 0000000000..23b0b317ae --- /dev/null +++ b/assets/device-config.html-DBtsAxx_.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-a0d46818","path":"/node/device-config.html","title":"Device Config","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Name","slug":"name","link":"#name","children":[]},{"level":3,"title":"Manufacturer","slug":"manufacturer","link":"#manufacturer","children":[]},{"level":3,"title":"Model","slug":"model","link":"#model","children":[]},{"level":3,"title":"Software Version","slug":"software-version","link":"#software-version","children":[]},{"level":3,"title":"Hardware Version","slug":"hardware-version","link":"#hardware-version","children":[]}]}],"git":{"updatedTime":1662369628000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/device-config.md"}');export{e as data}; diff --git a/assets/device.html-CMu5d7xr.js b/assets/device.html-CMu5d7xr.js new file mode 100644 index 0000000000..06ac94569b --- /dev/null +++ b/assets/device.html-CMu5d7xr.js @@ -0,0 +1 @@ +import{_ as e,o as i,c as a,e as t}from"./app-DW3AHQOa.js";const d={},c=t('

    Device

    Configuration

    Type

    • Type: string
    • Values: trigger | action

    Device

    • Type: string

    Id of the device

    Trigger

    • Type: object

    Home Assistant object of the trigger

    Action

    • Type: object

    Home Assistant object of the action

    Capabilities

    • Type: object

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • config: config properties of the node
    • device id: device id that triggered the node
    • event data: event data received from Home Assistant
    • sent data: data sent to Home Assistant
    ',21),o=[c];function r(n,s){return i(),a("div",null,o)}const l=e(d,[["render",r],["__file","device.html.vue"]]);export{l as default}; diff --git a/assets/device.html-E7Z05I5q.js b/assets/device.html-E7Z05I5q.js new file mode 100644 index 0000000000..4559835063 --- /dev/null +++ b/assets/device.html-E7Z05I5q.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7053a0af","path":"/node/device.html","title":"Device","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Type","slug":"type","link":"#type","children":[]},{"level":3,"title":"Device","slug":"device-1","link":"#device-1","children":[]},{"level":3,"title":"Trigger","slug":"trigger","link":"#trigger","children":[]},{"level":3,"title":"Action","slug":"action","link":"#action","children":[]},{"level":3,"title":"Capabilities","slug":"capabilities","link":"#capabilities","children":[]},{"level":3,"title":"Expose as","slug":"expose-as","link":"#expose-as","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]}],"git":{"updatedTime":1691660859000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":4}]},"filePathRelative":"node/device.md"}');export{e as data}; diff --git a/assets/diagnostics.html-DkEWMJq5.js b/assets/diagnostics.html-DkEWMJq5.js new file mode 100644 index 0000000000..8d66a975b3 --- /dev/null +++ b/assets/diagnostics.html-DkEWMJq5.js @@ -0,0 +1,2 @@ +import{_ as p,r as e,o as r,c,a as s,d as n,b as o,e as a}from"./app-DW3AHQOa.js";const u="/node-red-contrib-home-assistant-websocket/assets/diagnostics_04-Df7nsYrl.png",l="/node-red-contrib-home-assistant-websocket/assets/diagnostics_05-BT6Gqs0E.gif",i="/node-red-contrib-home-assistant-websocket/assets/diagnostics_01-BGDg5hGH.png",k="/node-red-contrib-home-assistant-websocket/assets/diagnostics_02-BCb_i0sN.png",q="/node-red-contrib-home-assistant-websocket/assets/diagnostics_03-DLYbYdSd.png",d={},h=a('

    Diagnostics Information

    Overview

    To assist with troubleshooting, a button has been added to the Node-RED editor that will run a diagnostics flow and copy the output to the clipboard. This output can then be pasted into a GitHub issue or a support forum.

    Note

    Before version 0.62.0, the diagnostics flow was a separate flow that had to be imported into Node-RED. This flow is still available and can be found here.

    screenshot of buton location

    gif for finding button

    Before version 0.62.0

    ',7),g={href:"https://nodered.org/docs/user-guide/editor/workspace/import-export",target:"_blank",rel:"noopener noreferrer"},f=a('

    Flow

    screenshot

    [{"id":"83159f9ffc81a5fd","type":"inject","z":"a3f996b014aea8a5","name":"get environment info","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":226,"y":608,"wires":[["11f9ee4206596633"]]},{"id":"607c82ab3a273e93","type":"debug","z":"a3f996b014aea8a5","name":"copy info from debug tab","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":582,"y":608,"wires":[]},{"id":"11f9ee4206596633","type":"http request","z":"a3f996b014aea8a5","name":"fetch","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://localhost:1880/homeassistant/diagnostics","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":390,"y":608,"wires":[["607c82ab3a273e93"]]}]
    +

    This flow can also be imported directly from the examples section in Node-RED.

    `,4),b={href:"https://nodered.org/docs/user-guide/editor/workspace/import-export",target:"_blank",rel:"noopener noreferrer"},y=a('

    Usage

    1. Import the flow into Node-RED.

    2. Deploy the flow.

    3. Click the Inject node to run the flow.

    screenshot of debug window

    1. Copy the output from the Debug tab.

    screenshot of debug window

    1. Paste the output into a GitHub issue or a support ticket.
    ',6);function m(_,w){const t=e("ExternalLinkIcon");return r(),c("div",null,[h,s("p",null,[n("The supplied diagnostics flow serves as a valuable tool for collecting data about the runtime and the system environment. This flow can be "),s("a",g,[n("imported"),o(t)]),n(" into Node-RED and run. By doing so, it compiles crucial information regarding the runtime and the system environment, enabling users to easily share this data when addressing issues.")]),f,s("ul",null,[s("li",null,[s("a",b,[n("How to import a flow"),o(t)])])]),y])}const x=p(d,[["render",m],["__file","diagnostics.html.vue"]]);export{x as default}; diff --git a/assets/diagnostics.html-d7C2KoqA.js b/assets/diagnostics.html-d7C2KoqA.js new file mode 100644 index 0000000000..9a2383abbb --- /dev/null +++ b/assets/diagnostics.html-d7C2KoqA.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-348298ce","path":"/guide/diagnostics.html","title":"Diagnostics Information","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Overview","slug":"overview","link":"#overview","children":[]},{"level":2,"title":"Before version 0.62.0","slug":"before-version-0-62-0","link":"#before-version-0-62-0","children":[{"level":3,"title":"Flow","slug":"flow","link":"#flow","children":[]},{"level":3,"title":"Usage","slug":"usage","link":"#usage","children":[]}]}],"git":{"updatedTime":1712958426000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"guide/diagnostics.md"}');export{e as data}; diff --git a/assets/diagnostics_01-BGDg5hGH.png b/assets/diagnostics_01-BGDg5hGH.png new file mode 100644 index 0000000000..15865cf3cd Binary files /dev/null and b/assets/diagnostics_01-BGDg5hGH.png differ diff --git a/assets/diagnostics_02-BCb_i0sN.png b/assets/diagnostics_02-BCb_i0sN.png new file mode 100644 index 0000000000..b33a5eb797 Binary files /dev/null and b/assets/diagnostics_02-BCb_i0sN.png differ diff --git a/assets/diagnostics_03-DLYbYdSd.png b/assets/diagnostics_03-DLYbYdSd.png new file mode 100644 index 0000000000..ca2cc7b26c Binary files /dev/null and b/assets/diagnostics_03-DLYbYdSd.png differ diff --git a/assets/diagnostics_04-Df7nsYrl.png b/assets/diagnostics_04-Df7nsYrl.png new file mode 100644 index 0000000000..a65c1786fe Binary files /dev/null and b/assets/diagnostics_04-Df7nsYrl.png differ diff --git a/assets/diagnostics_05-BT6Gqs0E.gif b/assets/diagnostics_05-BT6Gqs0E.gif new file mode 100644 index 0000000000..dcef73b62e Binary files /dev/null and b/assets/diagnostics_05-BT6Gqs0E.gif differ diff --git a/assets/documentation.html-Db4YoijQ.js b/assets/documentation.html-Db4YoijQ.js new file mode 100644 index 0000000000..d8b4fdb712 --- /dev/null +++ b/assets/documentation.html-Db4YoijQ.js @@ -0,0 +1,3 @@ +import{_ as s,r,o as i,c as l,a as e,d as t,b as n,e as a}from"./app-DW3AHQOa.js";const c={},d=e("h1",{id:"documentation",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#documentation","aria-hidden":"true"},"#"),t(" Documentation")],-1),h={href:"https://v2.vuepress.vuejs.org/",target:"_blank",rel:"noopener noreferrer"},p=e("code",null,"docs",-1),u=a('

    Small changes

    If you want to make small changes to the documentation, you can do so directly in the GitHub web interface. Just navigate to the file you want to change and click the pencil icon in the top right corner.

    There is a link on the bottom of each page to edit the file directly in the GitHub web interface.

    Local development

    If you want to make larger changes to the documentation, you can clone the repository.

    Developing with Visual Studio Code and Docker

    ',6),m={href:"https://code.visualstudio.com/",target:"_blank",rel:"noopener noreferrer"},_={href:"https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers",target:"_blank",rel:"noopener noreferrer"},f={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket",target:"_blank",rel:"noopener noreferrer"},g=a(`
  • Clone your forked repository to your local machine.

    git clone https://github.com/<GITHUB_USER_NAME>/node-red-contrib-home-assistant-websocket
    +
  • Open the repository in Visual Studio Code.

  • Click on the green "Open a Remote Window" button in the bottom left corner and select "Reopen in Container".

  • Open a terminal in Visual Studio Code and run npm install --save-dev to install the dependencies.

  • Run npm run docs:dev to start the development server.

  • `,5),v=e("h3",{id:"manual-environment",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#manual-environment","aria-hidden":"true"},"#"),t(" Manual environment")],-1),b={href:"https://nodejs.org/",target:"_blank",rel:"noopener noreferrer"},k={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket",target:"_blank",rel:"noopener noreferrer"},y=a(`
  • Clone your forked repository to your local machine.

    git clone https://github.com/<GITHUB_USER_NAME>/node-red-contrib-home-assistant-websocket
    +
  • Open the repository in your favorite editor.

  • Run npm install --save-dev to install the dependencies.

  • Run npm run docs:dev to start the development server.

  • `,4);function w(x,C){const o=r("ExternalLinkIcon");return i(),l("div",null,[d,e("p",null,[t("The documentation is built with "),e("a",h,[t("VuePress v2"),n(o)]),t(". The pages are written in Markdown and are located in the "),p,t(" directory.")]),u,e("ol",null,[e("li",null,[e("p",null,[t("Install "),e("a",m,[t("Visual Studio Code"),n(o)]),t(".")])]),e("li",null,[e("p",null,[t("Install the "),e("a",_,[t("Remote - Containers"),n(o)]),t(" extension.")])]),e("li",null,[e("p",null,[t("Go to the "),e("a",f,[t("Node-RED Home Assistant"),n(o)]),t(" repository and fork it.")])]),g]),v,e("ol",null,[e("li",null,[e("p",null,[t("Install "),e("a",b,[t("Node.js"),n(o)]),t(".")])]),e("li",null,[e("p",null,[t("Go to the "),e("a",k,[t("Node-RED Home Assistant"),n(o)]),t(" repository and fork it.")])]),y])])}const R=s(c,[["render",w],["__file","documentation.html.vue"]]);export{R as default}; diff --git a/assets/documentation.html-gj5aEpbG.js b/assets/documentation.html-gj5aEpbG.js new file mode 100644 index 0000000000..78c56fdbd5 --- /dev/null +++ b/assets/documentation.html-gj5aEpbG.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-44d4584b","path":"/guide/documentation.html","title":"Documentation","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Small changes","slug":"small-changes","link":"#small-changes","children":[]},{"level":2,"title":"Local development","slug":"local-development","link":"#local-development","children":[{"level":3,"title":"Developing with Visual Studio Code and Docker","slug":"developing-with-visual-studio-code-and-docker","link":"#developing-with-visual-studio-code-and-docker","children":[]},{"level":3,"title":"Manual environment","slug":"manual-environment","link":"#manual-environment","children":[]}]}],"git":{"updatedTime":1707093868000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"guide/documentation.md"}');export{e as data}; diff --git a/assets/entity-config.html-C3xR_Dqh.js b/assets/entity-config.html-C3xR_Dqh.js new file mode 100644 index 0000000000..daccecd9f2 --- /dev/null +++ b/assets/entity-config.html-C3xR_Dqh.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-28f3a601","path":"/node/entity-config.html","title":"Entity Config","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Name","slug":"name","link":"#name","children":[]},{"level":3,"title":"Device","slug":"device","link":"#device","children":[]},{"level":3,"title":"Type","slug":"type","link":"#type","children":[]},{"level":3,"title":"Resend state and attributes","slug":"resend-state-and-attributes","link":"#resend-state-and-attributes","children":[]},{"level":3,"title":"Other Properties","slug":"other-properties","link":"#other-properties","children":[]}]}],"git":{"updatedTime":1665452902000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3},{"name":"Joakim Vindgard","email":"joakim.vindgard@gmail.com","commits":1}]},"filePathRelative":"node/entity-config.md"}');export{e as data}; diff --git a/assets/entity-config.html-k1lGGcxI.js b/assets/entity-config.html-k1lGGcxI.js new file mode 100644 index 0000000000..5d3d7e7871 --- /dev/null +++ b/assets/entity-config.html-k1lGGcxI.js @@ -0,0 +1 @@ +import{_ as d,r as n,o as c,c as h,a as e,b as i,w as l,d as t,e as a}from"./app-DW3AHQOa.js";const u={},p=a('

    Entity Config

    Home Assistant entity config

    Configuration

    Name

    • Type: string

    The name of the entity that will show in Node-RED

    Device

    ',7),_=e("li",null,[t("Type: "),e("code",null,"string")],-1),f=e("p",null,"A list of devices the entity can be associated with. This is used to group entities together in the UI.",-1),m=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"Caveat"),e("p",null,"If the entity has already been registered with Home Assistant when no device was selected. The device will not be added to the Home Assistant until after Home Assistant has been restarted.")],-1),b={id:"type",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#type","aria-hidden":"true"},"#",-1),y=a('
    • Type: string
    • Values: binary_sensor|button|sensor|switch

    Resend state and attributes

    • Type: boolean

    When the entity in Home Assistant is created the state and attributes will also be set. This is only applicable with certain entities nodes.

    Other Properties

    Configuration options are available for the selected entities

    ',6),v={href:"https://developers.home-assistant.io/docs/core/entity",target:"_blank",rel:"noopener noreferrer"};function x(w,T){const o=n("RouterLink"),s=n("Badge"),r=n("ExternalLinkIcon");return c(),h("div",null,[p,e("ul",null,[_,e("li",null,[i(o,{to:"/node/device-config.html"},{default:l(()=>[t("device config documentation")]),_:1})])]),f,m,e("h3",b,[g,t(" Type "),i(s,{text:"required"})]),y,e("p",null,[e("a",v,[t("https://developers.home-assistant.io/docs/core/entity"),i(r)])])])}const C=d(u,[["render",x],["__file","entity-config.html.vue"]]);export{C as default}; diff --git a/assets/entity.html-jUBk_EPe.js b/assets/entity.html-jUBk_EPe.js new file mode 100644 index 0000000000..174eb27304 --- /dev/null +++ b/assets/entity.html-jUBk_EPe.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-18af4b42","path":"/node/entity.html","title":"Entity","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Type","slug":"type","link":"#type","children":[]},{"level":3,"title":"Home Assistant Config","slug":"home-assistant-config","link":"#home-assistant-config","children":[]}]},{"level":2,"title":"Sensor Configuration","slug":"sensor-configuration","link":"#sensor-configuration","children":[{"level":3,"title":"State","slug":"state","link":"#state","children":[]},{"level":3,"title":"Attributes","slug":"attributes","link":"#attributes","children":[]},{"level":3,"title":"Input Override","slug":"input-override","link":"#input-override","children":[]},{"level":3,"title":"Resend state and attributes","slug":"resend-state-and-attributes","link":"#resend-state-and-attributes","children":[]}]},{"level":2,"title":"Switch Configuration","slug":"switch-configuration","link":"#switch-configuration","children":[{"level":3,"title":"Output on state change","slug":"output-on-state-change","link":"#output-on-state-change","children":[]},{"level":3,"title":"Payload","slug":"payload","link":"#payload","children":[]}]},{"level":2,"title":"Sensors Inputs","slug":"sensors-inputs","link":"#sensors-inputs","children":[{"level":3,"title":"state","slug":"state-1","link":"#state-1","children":[]},{"level":3,"title":"attributes","slug":"attributes-1","link":"#attributes-1","children":[]}]},{"level":2,"title":"Switch Inputs","slug":"switch-inputs","link":"#switch-inputs","children":[{"level":3,"title":"msg.enable","slug":"msg-enable","link":"#msg-enable","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]}],"git":{"updatedTime":1662500089000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":6}]},"filePathRelative":"node/entity.md"}');export{t as data}; diff --git a/assets/entity.html-rEDHJL39.js b/assets/entity.html-rEDHJL39.js new file mode 100644 index 0000000000..2ce02aafb0 --- /dev/null +++ b/assets/entity.html-rEDHJL39.js @@ -0,0 +1 @@ +import{_ as d,r as i,o as r,c as h,a as e,d as t,b as a,e as o}from"./app-DW3AHQOa.js";const c={},l=o('

    DEPRECATED

    This node has been deprecated in favor of the individual entity nodes. The individual entity nodes can be used in subflows and added to devices.

    Entity

    Creates an entity in Home Assistant which can be manipulated from this node.

    binary sensor, sensor, and switch

    ',4),u={class:"custom-container warning"},p=e("p",{class:"custom-container-title"},"WARNING",-1),b={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},f=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),g={id:"type",tabindex:"-1"},m=e("a",{class:"header-anchor",href:"#type","aria-hidden":"true"},"#",-1),y=o('
    • Type: string
    • Values binary_sensor|sensor|switch
    • Default: sensor

    The state the entity should be updated to

    Home Assistant Config

    • Type: Object

    Configuration options available for the selected entity

    WARNING

    Entity nodes will not work in a subflow due to the way they register themselves with Home Assistant. After a Node-RED restart, a new entity will be created in Home Assistant.

    Sensor Configuration

    ',7),_={id:"state",tabindex:"-1"},w=e("a",{class:"header-anchor",href:"#state","aria-hidden":"true"},"#",-1),x=o('
    • Type: string | number | boolean

    The state the entity should be updated to

    Attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    Input Override

    • Type: string
    • Values: accept | merge | block

    Determine how input values will be handled. When merge is selected the message object values will override the configuration values.

    Resend state and attributes

    • Type: boolean

    When creating the entity in Home Assistant this will also send the last updated state and attributes then node sent to Home Assistant

    Switch Configuration

    Output on state change

    • Type: boolean

    When the state of the switch changes it will output to the top if the switch is on or to the bottom if it is in the off position.

    Payload

    • Type: str | num | bool | JSONata | timestamp

    Customizable output set to msg.payload if Output on state change is enabled.

    Sensors Inputs

    properties of msg.payload

    state

    • Type: string | number | boolean

    The state the entity should be updated to

    attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    Switch Inputs

    msg.enable

    • Type: boolean

    Set to true to turn on the switch and false to turn off. If the message has a property enable set to the type boolean the node will not have any output.

    Outputs

    Status Color

    • Green/Red: output from the node was due to input to the node
    • Blue: output from the node was due to the state of the node changing
    • Yellow: state of node changed but no output
    ',33);function v(T,A){const s=i("ExternalLinkIcon"),n=i("Badge");return r(),h("div",null,[l,e("div",u,[p,e("p",null,[e("em",null,[t("Needs "),e("a",b,[t("Custom Integration"),a(s)]),t(" installed in Home Assistant for this node to function")])])]),f,e("h3",g,[m,t(" Type "),a(n,{text:"required"})]),y,e("h3",_,[w,t(" State "),a(n,{text:"required"})]),x])}const N=d(c,[["render",v],["__file","entity.html.vue"]]);export{N as default}; diff --git a/assets/events-all.html-CIdgH7aC.js b/assets/events-all.html-CIdgH7aC.js new file mode 100644 index 0000000000..3f8919dff4 --- /dev/null +++ b/assets/events-all.html-CIdgH7aC.js @@ -0,0 +1 @@ +import{_ as o,r as i,o as r,c as l,a as e,d as t,b as s,e as n}from"./app-DW3AHQOa.js";const d={},c=n('

    Events: all

    Listens for all types of events from Home Assistant with the ability to filter by event type.

    Configuration

    Name

    • Type: string

    the name of the node

    Event Type

    • Type: string

    filter by event type or leave blank for all events

    ',9),h={class:"custom-container danger"},u=e("p",{class:"custom-container-title"},"DANGER",-1),p=e("p",null,"Leaving this empty will listen for all events from Home Assistant which may overload the WebSocket message queue.",-1),f={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket/issues/153#issuecomment-539290950",target:"_blank",rel:"noopener noreferrer"},m=n('

    Event data

    • Type: json

    A JSON object that will be compared to the event data. If this JSON is a subset of the event data object, the event will be emitted.

    Output only after Home Assistant is running

    • Type: boolean

    What until Home Assistant has reported its state as running before outputting events. Client events will always output.

    Expose as

    • Type: entity config
    ',8),v={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},g=n('

    Outputs

    Value types:

    • event data: event received from Home Assistant
    • config: config properties of the node

    Client Events

    Use home_assistant_client as the event type to receive events from the Websocket client.

    Events sent from the client:

    • connecting - when trying to connect to HA
    • connected - after the authorization has been accepted
    • disconnected - when the socket stops attempting to connect or disconnected after having been connected
    • error - when a disconnect happens of the WebSocket with an error
    • states_loaded - the first time all states are loaded from HA
    • services_loaded - the first time all services are loaded from HA
    • running - when HA is in a running state and states have been loaded
    ',7);function b(_,y){const a=i("ExternalLinkIcon");return r(),l("div",null,[c,e("div",h,[u,p,e("p",null,[e("a",f,[t("GitHub Issue #153"),s(a)])])]),m,e("p",null,[t("Creates a switch within Home Assistant to enable/disable this node. This feature requires "),e("a",v,[t("Node-RED custom integration"),s(a)]),t(" to be installed in Home Assistant")]),g])}const w=o(d,[["render",b],["__file","events-all.html.vue"]]);export{w as default}; diff --git a/assets/events-all.html-DbDqpqdo.js b/assets/events-all.html-DbDqpqdo.js new file mode 100644 index 0000000000..ba8a70fd11 --- /dev/null +++ b/assets/events-all.html-DbDqpqdo.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8faf5710","path":"/node/events-all.html","title":"Events: all","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Name","slug":"name","link":"#name","children":[]},{"level":3,"title":"Event Type","slug":"event-type","link":"#event-type","children":[]},{"level":3,"title":"Event data","slug":"event-data","link":"#event-data","children":[]},{"level":3,"title":"Output only after Home Assistant is running","slug":"output-only-after-home-assistant-is-running","link":"#output-only-after-home-assistant-is-running","children":[]},{"level":3,"title":"Expose as","slug":"expose-as","link":"#expose-as","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"Client Events","slug":"client-events","link":"#client-events","children":[]}],"git":{"updatedTime":1690703101000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":9}]},"filePathRelative":"node/events-all.md"}');export{e as data}; diff --git a/assets/events-calendar.html-BvVJPsDC.js b/assets/events-calendar.html-BvVJPsDC.js new file mode 100644 index 0000000000..395361d302 --- /dev/null +++ b/assets/events-calendar.html-BvVJPsDC.js @@ -0,0 +1 @@ +import{_ as l,r as a,o as d,c as r,a as e,d as t,b as n,w as c}from"./app-DW3AHQOa.js";const h={},u=e("h1",{id:"events-calendar",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#events-calendar","aria-hidden":"true"},"#"),t(" Events: calendar")],-1),_=e("p",null,"Outputs calendar item events similar to the calendar automation in Home Assistant",-1),f=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration:")],-1),m={id:"entity-id",tabindex:"-1"},p=e("a",{class:"header-anchor",href:"#entity-id","aria-hidden":"true"},"#",-1),b=e("ul",null,[e("li",null,[t("Type: "),e("code",null,"string")])],-1),x=e("p",null,"The entity_id for the calendar that contains triggerable calendar items.",-1),g={id:"relative-to",tabindex:"-1"},v=e("a",{class:"header-anchor",href:"#relative-to","aria-hidden":"true"},"#",-1),y=e("ul",null,[e("li",null,[t("Type: "),e("code",null,"start | end")]),e("li",null,[t("Default: "),e("code",null,"start")])],-1),w=e("p",null,"Whether to trigger an event at the start or end of each matching calendar item.",-1),T={id:"offset",tabindex:"-1"},k=e("a",{class:"header-anchor",href:"#offset","aria-hidden":"true"},"#",-1),A=e("ul",null,[e("li",null,[t("Type: "),e("code",null,"number")]),e("li",null,"Default: 0 seconds")],-1),C=e("p",null,"A negative or positive amount of time to allow the event to be triggered before or after the calendar item's start/end time.",-1),E=e("h3",{id:"conditions",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#conditions","aria-hidden":"true"},"#"),t(" Conditions")],-1),B=e("p",null,'This node has two default outputs "allowed" and "blocked". If all the conditions are true the calendar item will be sent to the output.',-1),H=e("p",null,[e("strong",null,"See Also:")],-1),I=e("h3",{id:"expose-to-home-assistant",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#expose-to-home-assistant","aria-hidden":"true"},"#"),t(" Expose to Home Assistant")],-1),q=e("ul",null,[e("li",null,[t("Type: "),e("code",null,"boolean")])],-1),D={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},L=e("h2",{id:"outputs",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#outputs","aria-hidden":"true"},"#"),t(" Outputs")],-1),N=e("p",null,"Value types:",-1),R=e("ul",null,[e("li",null,[e("code",null,"calendar item"),t(": the calendar item object as provided by the Home Assistant API")])],-1);function V(O,j){const o=a("Badge"),s=a("RouterLink"),i=a("ExternalLinkIcon");return d(),r("div",null,[u,_,f,e("h3",m,[p,t(" Entity ID "),n(o,{text:"required"})]),b,x,e("h3",g,[v,t(" Relative To "),n(o,{text:"required"})]),y,w,e("h3",T,[k,t(" Offset "),n(o,{text:"required"})]),A,C,E,B,H,e("ul",null,[e("li",null,[n(s,{to:"/guide/conditionals.html"},{default:c(()=>[t("Conditionals")]),_:1})])]),I,q,e("p",null,[t("Creates a switch within Home Assistant to enable/disable this node. This feature requires "),e("a",D,[t("Node-RED custom integration"),n(i)]),t(" to be installed in Home Assistant")]),L,N,R])}const P=l(h,[["render",V],["__file","events-calendar.html.vue"]]);export{P as default}; diff --git a/assets/events-calendar.html-J-EltcIZ.js b/assets/events-calendar.html-J-EltcIZ.js new file mode 100644 index 0000000000..d022a0a76b --- /dev/null +++ b/assets/events-calendar.html-J-EltcIZ.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-52df608a","path":"/node/events-calendar.html","title":"Events: calendar","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration:","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entity ID","slug":"entity-id","link":"#entity-id","children":[]},{"level":3,"title":"Relative To","slug":"relative-to","link":"#relative-to","children":[]},{"level":3,"title":"Offset","slug":"offset","link":"#offset","children":[]},{"level":3,"title":"Conditions","slug":"conditions","link":"#conditions","children":[]},{"level":3,"title":"Expose to Home Assistant","slug":"expose-to-home-assistant","link":"#expose-to-home-assistant","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]}],"git":{"updatedTime":1707143696000,"contributors":[{"name":"Nathan Brittain","email":"936564+enjibby@users.noreply.github.com","commits":1}]},"filePathRelative":"node/events-calendar.md"}');export{e as data}; diff --git a/assets/events-state.html-6HE_HLPq.js b/assets/events-state.html-6HE_HLPq.js new file mode 100644 index 0000000000..b53dadc4c6 --- /dev/null +++ b/assets/events-state.html-6HE_HLPq.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-15feb788","path":"/node/events-state.html","title":"Events: state","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration:","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entity","slug":"entity","link":"#entity","children":[]},{"level":3,"title":"If State","slug":"if-state","link":"#if-state","children":[]},{"level":3,"title":"For","slug":"for","link":"#for","children":[]},{"level":3,"title":"State Type","slug":"state-type","link":"#state-type","children":[]},{"level":3,"title":"Ignore state change event","slug":"ignore-state-change-event","link":"#ignore-state-change-event","children":[]},{"level":3,"title":"Output on Connect","slug":"output-on-connect","link":"#output-on-connect","children":[]},{"level":3,"title":"Expose to Home Assistant","slug":"expose-to-home-assistant","link":"#expose-to-home-assistant","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]}],"git":{"updatedTime":1722853970000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":9}]},"filePathRelative":"node/events-state.md"}');export{e as data}; diff --git a/assets/events-state.html-BDdmzcJp.js b/assets/events-state.html-BDdmzcJp.js new file mode 100644 index 0000000000..adddbaab20 --- /dev/null +++ b/assets/events-state.html-BDdmzcJp.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-57761d4e","path":"/cookbook/jsonata/events-state.html","title":"Events: state","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Providing a conditional test value (JSONata expression as a value)","slug":"providing-a-conditional-test-value-jsonata-expression-as-a-value","link":"#providing-a-conditional-test-value-jsonata-expression-as-a-value","children":[]},{"level":3,"title":"Conditional test (JSONata expression as a Boolean result)","slug":"conditional-test-jsonata-expression-as-a-boolean-result","link":"#conditional-test-jsonata-expression-as-a-boolean-result","children":[]},{"level":3,"title":"Creating output properties","slug":"creating-output-properties","link":"#creating-output-properties","children":[]},{"level":3,"title":"OR conditional for the Events: state node","slug":"or-conditional-for-the-events-state-node","link":"#or-conditional-for-the-events-state-node","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/jsonata/events-state.md"}');export{e as data}; diff --git a/assets/events-state.html-BUeuT8p5.js b/assets/events-state.html-BUeuT8p5.js new file mode 100644 index 0000000000..6351a1ad00 --- /dev/null +++ b/assets/events-state.html-BUeuT8p5.js @@ -0,0 +1,50 @@ +import{_ as r,r as o,o as c,c as l,a as s,d as n,b as a,w as p,e}from"./app-DW3AHQOa.js";const k="/node-red-contrib-home-assistant-websocket/assets/jsonata_3_1-DCTS43SR.png",i="/node-red-contrib-home-assistant-websocket/assets/jsonata_value_example-DJn_j-gH.png",q="/node-red-contrib-home-assistant-websocket/assets/jsonata_boolean_example-DbjCVol3.png",d={},y=e('

    Events: state

    The Events: state node receives state change events for one or more entities, and will output a message in response. The message output can be optionally controlled by a test condition on the state value, and also by a test on the length of time the state remains at that value. Both the state test condition and the state time duration can use JSONata. This node can also provide output message properties, again with the ability to use JSONata.

    screenshot

    Here are three examples, showing how to use JSONata to perform If-State conditional tests, and to build output properties.

    [{"id":"35b892e153bb5bc0","type":"group","z":"776c027950fc8c3f","name":"Events: state node - respond to state changes","style":{"label":true,"color":"#000000"},"nodes":["445466367c412014","e27b6ee2807af2eb","4583560d5089575d","24ed76ccd4da5975","266eadf86abd6481","27857c0c670e452b","e2ba71699db68b1a","1d9b8adce4f77e4e","a9b23a3911f5ef89"],"x":34,"y":919,"w":592,"h":342},{"id":"445466367c412014","type":"comment","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"3a - JSONata builds conditional test value","info":"","x":220,"y":960,"wires":[]},{"id":"e27b6ee2807af2eb","type":"server-state-changed","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Switch was on for less than 3 minutes","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"switch\\\\.[a-z][0-9]","entityIdType":"regex","outputInitially":false,"stateType":"str","ifState":"(\\t    $new:=$entity();\\t    $old:=$prevEntity();\\t    $mins:=($toMillis($new.last_changed)-$toMillis($old.last_changed))/60000~>$round(0);\\t    $new.state=\\"off\\" and $old.state=\\"on\\" and $mins<3\\t)","ifStateType":"jsonata","ifStateOperator":"jsonata","outputOnlyOnStateChange":false,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"\\"Device \\" & $entity().attributes.friendly_name & \\" has been on for less than 3 minutes\\"","valueType":"jsonata"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":230,"y":1140,"wires":[["4583560d5089575d"],[]]},{"id":"4583560d5089575d","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Flow trigger","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"topic","targetType":"msg","statusVal":"payload","statusType":"auto","x":490,"y":1140,"wires":[]},{"id":"24ed76ccd4da5975","type":"server-state-changed","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Motion between dawn and dusk","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"motion","entityIdType":"substring","outputInitially":false,"stateType":"str","ifState":"(\\t    $ismotion:= $entity().state=\\"on\\";\\t\\t    $dawn:=$entities('sensor.sun_next_dawn').state;\\t    $dusk:=$entities('sensor.sun_next_dusk').state;\\t    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(\\",\\");\\t\\t    $isdawn:= $date=$substringBefore($dawn,\\"T\\");\\t    $isdusk:= $date!=$substringBefore($dusk,\\"T\\");\\t    \\t    $ismotion and ($isdawn or $isdusk)\\t)","ifStateType":"jsonata","ifStateOperator":"jsonata","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"(\\t    $ismotion:= $entity().state=\\"on\\";\\t\\t    $dawn:=$entities('sensor.sun_next_dawn').state;\\t    $dusk:=$entities('sensor.sun_next_dusk').state;\\t    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(\\",\\");\\t\\t    $isdawn:= $date=$substringBefore($dawn,\\"T\\");\\t    $isdusk:= $date!=$substringBefore($dusk,\\"T\\");\\t    \\t    $fire:= $ismotion and ($isdawn or $isdusk);\\t\\t    {\\"motion\\": $ismotion,\\t    \\"dawn\\": $dawn,\\t    \\"dusk\\": $dusk,\\t    \\"date\\": $date,\\t    \\"isdawn\\": $isdawn,\\t    \\"isdusk\\": $isdusk,\\t    \\"fire\\": $fire\\t    }\\t)","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":210,"y":1220,"wires":[["266eadf86abd6481"],[]]},{"id":"266eadf86abd6481","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Dawn or Dusk","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload.isdawn ? \\"Before Dawn\\" : payload.isdusk ? \\"After Dusk\\"","statusType":"jsonata","x":500,"y":1220,"wires":[]},{"id":"27857c0c670e452b","type":"server-state-changed","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"motion","entityIdType":"substring","outputInitially":false,"stateType":"str","ifState":"(\\t    $time:=$entities('sensor.time').state;\\t    $append([\\"on\\"], $time<\\"08:30\\" or $time>\\"17:30\\" ? [\\"off\\"]);\\t)    ","ifStateType":"jsonata","ifStateOperator":"includes","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":240,"y":1020,"wires":[["1d9b8adce4f77e4e"],["e2ba71699db68b1a"]]},{"id":"e2ba71699db68b1a","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Condition false","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":500,"y":1040,"wires":[]},{"id":"1d9b8adce4f77e4e","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Condition true","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload=\\"on\\" ? \\"Motion at \\" & $now('[H]:[m]') : \\"end\\"","statusType":"jsonata","x":500,"y":980,"wires":[]},{"id":"a9b23a3911f5ef89","type":"comment","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"3b - JSONata builds conditional Boolean","info":"","x":220,"y":1100,"wires":[]}]
    +

    Providing a conditional test value (JSONata expression as a value)

    Example: Respond to motion events for both "on" (start of motion detection) all day, and also "off" (end of motion detection) but only outside of 08:30 to 17:30.

    (
    +    $time:=$entities('sensor.time').state;
    +    $append(["on"], $time<"08:30" or $time>"17:30" ? ["off"]);
    +)
    +

    When the If State option is chosen with a conditional (not JSONata) the condition expects a value to test against. The result of the JSONata expression is the final line in the code block. This creates an array containing just ["on"] or if the time is before 08:30 or after 17:30, an array of ["on", "off"]. The motion sensor entity state will be compared with this array value using the inclusive condition 'in'.

    screenshot

    ',10),g={href:"https://www.home-assistant.io/integrations/time_date/",target:"_blank",rel:"noopener noreferrer"},b=e('

    Conditional test (JSONata expression as a Boolean result)

    Example: Switch has just been turned off, and was previously on for less than three minutes.

    When the If State option is chosen with JSONata (not a conditional) then the right hand side must be a JSONata expression that returns a Boolean value of either true or false. When true the "If State" test is successful (the message is output from the top exit) when false the test fails (the message is output from the lower exit).

    screenshot

    (
    +    $new:=$entity();
    +    $old:=$prevEntity();
    +    $mins:=($toMillis($new.last_changed)-$toMillis($old.last_changed))/60000~>$round(0);
    +    $new.state="off" and $old.state="on" and $mins<3
    +)
    +
    +

    In all the WebSocket nodes, the $entity() function will return an object for the entity that is the subject of the node. For the Event: nodes, the $entity() return is for the current or new state, and an additional $prevEntity() function will return a similar object for the previous state. Use of both functions allows JSONata expressions to work with and compare the triggering state change.

    Example: Motion has been detected before dawn or after dusk.

    Here JSONata is again used to generate a Boolean result for the If State test. The expression return is the final line in the code block, which tests for motion and either before dawn or after dusk. The use of 'or' here is an example of how JSONata can extend logic testing since the Trigger state node conditions can only group conditions as AND logic.

    (
    +    $ismotion:= $entity().state="on";
    +
    +    $dawn:=$entities('sensor.sun_next_dawn').state;
    +    $dusk:=$entities('sensor.sun_next_dusk').state;
    +    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(",");
    +
    +    $isdawn:= $date=$substringBefore($dawn,"T");
    +    $isdusk:= $date!=$substringBefore($dusk,"T");
    +
    +    $ismotion and ($isdawn or $isdusk)
    +)
    +

    The Sun integration in Home Assistant provides 'nextdawn' and 'next_dusk' sensors, with a date-time string value in UTC. Since the _next dawn will be for today before dawn, but will be for tomorrow after dawn, and similarly the next dusk will be for today before dusk, but for tomorrow after dusk, it is possible to compare just the date parts of the UTC timestamps, so as to determine if the current time is before or after either dawn or dusk.

    Creating output properties

    To extend this last example, JSONata is used to generate an output object. Note that there is no internal connection between the two JSONata expressions, so all the values have to be recalculated as required.

    (
    +    $ismotion:= $entity().state="on";
    +
    +    $dawn:=$entities('sensor.sun_next_dawn').state;
    +    $dusk:=$entities('sensor.sun_next_dusk').state;
    +    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(",");
    +
    +    $isdawn:= $date=$substringBefore($dawn,"T");
    +    $isdusk:= $date!=$substringBefore($dusk,"T");
    +
    +    $fire:= $ismotion and ($isdawn or $isdusk);
    +
    +    {"motion": $ismotion,
    +    "dawn": $dawn,
    +    "dusk": $dusk,
    +    "date": $date,
    +    "isdawn": $isdawn,
    +    "isdusk": $isdusk,
    +    "fire": $fire
    +    }
    +)
    +
    +

    OR conditional for the Events: state node

    The Trigger: state node is great if you have several conditions you want to check for but it doesn't allow use of OR conditions. Using a JSONata expression with an Event: state node will allow you to fill this gap.

    Example: Motion sensor at the front door triggers, and have a text to speech notification be sent if at least one person is home.

    $entity().state = "on" and (
    +   $entities("person.person1").state = "home" or $entities("person.person2").state = "home"
    +)
    +

    Also see:

    `,18);function f(m,h){const u=o("ExternalLinkIcon"),t=o("RouterLink");return c(),l("div",null,[y,s("p",null,[n("This JSONata uses the Date-Time integration sensor to obtain the local time. The "),s("a",g,[n("Time & Date Integration"),a(u)]),n(" should be added to the configuration file, and then the time sensor will return the current local time.")]),b,s("ul",null,[s("li",null,[a(t,{to:"/guide/jsonata/"},{default:p(()=>[n("JSONata guide")]),_:1})]),s("li",null,[a(t,{to:"/guide/jsonata/jsonata-primer.html"},{default:p(()=>[n("JSONata primer")]),_:1})])])])}const w=r(d,[["render",f],["__file","events-state.html.vue"]]);export{w as default}; diff --git a/assets/events-state.html-BxHuLD51.js b/assets/events-state.html-BxHuLD51.js new file mode 100644 index 0000000000..c952067f32 --- /dev/null +++ b/assets/events-state.html-BxHuLD51.js @@ -0,0 +1 @@ +import{_ as l,r as o,o as d,c,a as e,d as t,b as n,w as h,e as i}from"./app-DW3AHQOa.js";const u={},p=e("h1",{id:"events-state",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#events-state","aria-hidden":"true"},"#"),t(" Events: state")],-1),f=e("p",null,"Listens for state changes of entities from Home Assistant.",-1),g=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration:")],-1),_={id:"entity",tabindex:"-1"},b=e("a",{class:"header-anchor",href:"#entity","aria-hidden":"true"},"#",-1),y=i('
    • Type: string

    The entity ID is used to listen for state changes. This can be a entity ID, regex, or a substring. If a regex or substring is used, the node will listen for all entities that match.

    Example:

    • light.kitchen (entity) listens for state changes of the light.kitchen entity
    • ^light.* (regex) listens for state changes of all entities that start with light.
    • light (substring) listens for state changes of all entities that contain light in the entity ID

    If State

    • Type: string

    If the conditional is evaluated as true send the message to the first output otherwise send it to the second output. If blank there will only be one output.

    Also see:

    ',8),m=i('

    For

    • Type: number

    An amount of time an entity's state needs to be in that state before triggering.

    WARNING

    Output on Connect state changes will not start a timer.

    State Type

    • Type: string
    • Values: string|number|boolean
    • Default: string

    Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

    Ignore state change event

    • Type: boolean

    A list of possible states that will be ignored.

    Output on Connect

    • Type: boolean

    Output once on startup/deploy

    Expose to Home Assistant

    • Type: boolean
    ',15),x={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},v=i('

    Outputs

    Value types:

    • event data: full event object
    • entity id: entity id of the triggered entity
    • entity state: entity state of the triggered entity
    • config: config properties of the node
    ',3);function w(T,I){const a=o("Badge"),s=o("RouterLink"),r=o("ExternalLinkIcon");return d(),c("div",null,[p,f,g,e("h3",_,[b,t(" Entity "),n(a,{text:"required"})]),y,e("ul",null,[e("li",null,[n(s,{to:"/guide/conditionals.html"},{default:h(()=>[t("Conditionals")]),_:1})])]),m,e("p",null,[t("Creates a switch within Home Assistant to enable/disable this node. This feature requires "),e("a",x,[t("Node-RED custom integration"),n(r)]),t(" to be installed in Home Assistant")]),v])}const A=l(u,[["render",w],["__file","events-state.html.vue"]]);export{A as default}; diff --git a/assets/expiration-date-monitor.html-4_kB1H6C.js b/assets/expiration-date-monitor.html-4_kB1H6C.js new file mode 100644 index 0000000000..32e03ac042 --- /dev/null +++ b/assets/expiration-date-monitor.html-4_kB1H6C.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-fea818b6","path":"/cookbook/expiration-date-monitor.html","title":"Expiration Date Monitor with notification","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Home Assistant stuff","slug":"home-assistant-stuff","link":"#home-assistant-stuff","children":[]},{"level":2,"title":"Node-RED stuff","slug":"node-red-stuff","link":"#node-red-stuff","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/expiration-date-monitor.md"}');export{t as data}; diff --git a/assets/expiration-date-monitor.html-DWNCvrSy.js b/assets/expiration-date-monitor.html-DWNCvrSy.js new file mode 100644 index 0000000000..b6cc631e43 --- /dev/null +++ b/assets/expiration-date-monitor.html-DWNCvrSy.js @@ -0,0 +1,20 @@ +import{_ as p,r as o,o as e,c as u,a as n,d as s,b as t,e as c}from"./app-DW3AHQOa.js";const r="/node-red-contrib-home-assistant-websocket/assets/expiration-date-monitor_01-D-HOPyeA.png",l="/node-red-contrib-home-assistant-websocket/assets/expiration-date-monitor_02-CLuUTqyf.png",k="/node-red-contrib-home-assistant-websocket/assets/expiration-date-monitor_03-Cmsu_170.png",i={},q=n("h1",{id:"expiration-date-monitor-with-notification",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#expiration-date-monitor-with-notification","aria-hidden":"true"},"#"),s(" Expiration Date Monitor with notification")],-1),y={href:"https://community.home-assistant.io/t/json-object-of-all-input-texts/177146/6",target:"_blank",rel:"noopener noreferrer"},d={href:"https://www.home-assistant.io/integrations/shopping_list/",target:"_blank",rel:"noopener noreferrer"},g=n("p",null,[s("The format of the name in the shopping list would be "),n("code",null,"[item] : [expiration date]"),s(" with a colon separating the item name from the expiration date.")],-1),m=n("h2",{id:"home-assistant-stuff",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#home-assistant-stuff","aria-hidden":"true"},"#"),s(" Home Assistant stuff")],-1),h={href:"https://www.home-assistant.io/integrations/shopping_list/",target:"_blank",rel:"noopener noreferrer"},b=c(`
    # Example configuration.yaml entry
    +shopping_list:
    +

    There's already a lovelace card for the shopping list. I also added an input_number to dynamically control the expiration window to check.

    # Example configuration.yaml entry
    +input_number:
    +  pantry_expiration:
    +    name: Pantry Expiration Window
    +    initial: 90
    +    min: 30
    +    max: 120
    +    step: 1
    +    unit_of_measurement: days
    +    icon: mdi:calendar-clock
    +

    Simple Lovelace config

    image|498x346

    type: vertical-stack
    +cards:
    +  - title: Pantry Items
    +    type: shopping-list
    +  - type: entities
    +    entities:
    +      - input_number.pantry_expiration
    +

    Node-RED stuff

    You can set the inject node to fire at a set time each day or every other day whatever fits your needs.

    image|690x93

    [{"id":"e78bbe2c.9141","type":"inject","z":"56b1c979.b2c618","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":284,"y":1056,"wires":[["720213f9.9bb8fc"]]},{"id":"adeab5ee.bc4098","type":"ha-api","z":"56b1c979.b2c618","name":"Get Items","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"shopping_list/items\\"}","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":652,"y":1056,"wires":[["236e3cd6.fab7d4"]]},{"id":"236e3cd6.fab7d4","type":"function","z":"56b1c979.b2c618","name":"do the stuff","func":"const items = msg.payload;\\n\\nif (items.length === 0) return;\\n\\nconst expItems = [];\\n\\n// Current timestamp + expiration days in milliseconds\\nconst expireWindow = Date.now() + msg.expDays * 8.64e7;\\n\\nitems.forEach(i => {\\n  // If the name doesn't contain the split character don't process\\n  // If complete set to true in the shopping list don't process\\n  if (!i.name.includes(\\":\\") || i.complete === true) return;\\n\\n  // Split the name and remove white spaces\\n  const [name, exp] = i.name.split(\\":\\").map(x => x.trim());\\n\\n  // check for valid date\\n  const expiredDate = Date.parse(exp);\\n  if (isNaN(expiredDate) || expiredDate > expireWindow) return;\\n  \\n  // Add item to expired list\\n  expItems.push({ \\n      name, \\n      exp, \\n      inThePast: expiredDate < Date.now()\\n  });\\n});\\n\\n// If array is empty nothing to report\\nif (expItems.length === 0) return;\\n\\nmsg.payload = expItems;\\n\\nreturn msg;\\n","outputs":1,"noerr":0,"x":822,"y":1056,"wires":[["4270d967.43cc08"]]},{"id":"720213f9.9bb8fc","type":"api-current-state","z":"56b1c979.b2c618","name":"Get expiration window","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_number.pantry_expiration","state_type":"num","state_location":"expDays","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":468,"y":1056,"wires":[["adeab5ee.bc4098"]]},{"id":"4270d967.43cc08","type":"split","z":"56b1c979.b2c618","name":"","splt":"\\\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":290,"y":1120,"wires":[["e1f6793d.9be5f8"]]},{"id":"3d3871cd.cb442e","type":"join","z":"56b1c979.b2c618","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":674,"y":1120,"wires":[["ddffd5ea.ebd528"]]},{"id":"e1f6793d.9be5f8","type":"moment","z":"56b1c979.b2c618","name":"pretty","topic":"","input":"payload.exp","inputType":"msg","inTz":"America/Los_Angeles","adjAmount":0,"adjType":"days","adjDir":"add","format":"timeAgo","locale":"en_US","output":"payload.pretty","outputType":"msg","outTz":"America/Los_Angeles","x":418,"y":1120,"wires":[["c96d522b.7cfbb"]]},{"id":"c96d522b.7cfbb","type":"function","z":"56b1c979.b2c618","name":"format","func":"const d = msg.payload;\\nmsg.payload = `${d.name} expire${d.inThePast ? 'd' : 's'} ${d.pretty}`;\\nreturn msg;","outputs":1,"noerr":0,"x":544,"y":1120,"wires":[["3d3871cd.cb442e"]]},{"id":"ddffd5ea.ebd528","type":"api-call-service","z":"56b1c979.b2c618","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_phone","entityId":"","data":"{\\t    \\"title\\": \\"Pantry Items Expiring:\\",\\t    \\"message\\": $join(payload, \\"\\\\n\\")\\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":882,"y":1120,"wires":[[]]}]\n

    image|551x297

    There's a lot more polish that could go into this such as being notified if the date entered in the shopping list is invalid or doesn't have a date at all. Sort the expired list so that the closest to expiring is at the top.

    ',12);function f(_,x){const a=o("ExternalLinkIcon");return e(),u("div",null,[q,n("p",null,[s("Originally posted "),n("a",y,[s("here"),t(a)]),s(" on the Home Assistant Forums.")]),n("p",null,[s("Here's a demo showing how to build a system to track the expiration date of items in the pantry. Using the Home Assistant "),n("a",d,[s("Shopping List"),t(a)]),s(" as a way to input and update a list of items and their expiration date.")]),g,m,n("p",null,[s("First, you would have to activate the shopping list in the config. "),n("a",h,[s("https://www.home-assistant.io/integrations/shopping_list/"),t(a)])]),b])}const v=p(i,[["render",f],["__file","expiration-date-monitor.html.vue"]]);export{v as default}; diff --git a/assets/expiration-date-monitor_01-D-HOPyeA.png b/assets/expiration-date-monitor_01-D-HOPyeA.png new file mode 100644 index 0000000000..1061a3c1c9 Binary files /dev/null and b/assets/expiration-date-monitor_01-D-HOPyeA.png differ diff --git a/assets/expiration-date-monitor_02-CLuUTqyf.png b/assets/expiration-date-monitor_02-CLuUTqyf.png new file mode 100644 index 0000000000..700cd2e102 Binary files /dev/null and b/assets/expiration-date-monitor_02-CLuUTqyf.png differ diff --git a/assets/expiration-date-monitor_03-Cmsu_170.png b/assets/expiration-date-monitor_03-Cmsu_170.png new file mode 100644 index 0000000000..6d4c1c129d Binary files /dev/null and b/assets/expiration-date-monitor_03-Cmsu_170.png differ diff --git a/assets/exposed-nodes.html-Db4LuLE5.js b/assets/exposed-nodes.html-Db4LuLE5.js new file mode 100644 index 0000000000..dd6ce08836 --- /dev/null +++ b/assets/exposed-nodes.html-Db4LuLE5.js @@ -0,0 +1 @@ +import{_ as i,r as d,o as n,c as l,a as t,b as a,w as s,d as e,e as h}from"./app-DW3AHQOa.js";const r={},c=t("h1",{id:"exposed-nodes",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#exposed-nodes","aria-hidden":"true"},"#"),e(" Exposed Nodes")],-1),u=t("h2",{id:"available-to-all-event-nodes",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#available-to-all-event-nodes","aria-hidden":"true"},"#"),e(" Available to all event nodes")],-1),p=h('

    Trigger an exposed event node from a service call nodered.trigger

    Exposed nodes can be triggered from a service call. The service call is nodered.trigger and it takes the following data properties:

    entity_id

    • Required

    The entity_id of the exposed node to trigger. This is the entity_id of the node in Home Assistant. For example, if the entity_id of the node in Home Assistant is switch.my_node, then the entity_id to use in the service call is switch.my_node.

    output_path

    • Optional
    • Defaults to 0
    • Can be a comma separated list of output paths

    The output path of the node to send the message through. When this value is set to 0, the message will be sent through all output paths. If this value is set to 1, the message will be sent through the first output path. When this value is set to 2, the message will be sent through the second output path, and so on.

    message

    • Required

    The message the triggered node will output. This can be any valid JSON object. For example, if the message is { "payload": "hello world" }, then the message will be sent to the node as msg.payload with the value of hello world.

    ',11);function g(m,f){const o=d("RouterLink");return n(),l("div",null,[c,u,t("p",null,[a(o,{to:"/node/events-all.html"},{default:s(()=>[e("Events: all")]),_:1}),e(", "),a(o,{to:"/node/events-state.html"},{default:s(()=>[e("events: state")]),_:1}),e(", "),a(o,{to:"/node/trigger-state.html"},{default:s(()=>[e("trigger: state")]),_:1}),e(", and "),a(o,{to:"/node/poll-state.html"},{default:s(()=>[e("poll state")]),_:1}),e(" nodes will have the option to be exposed to Home Assistant, and when enabled, it will show up in Home Assistant as a switch. Turning on and off these switches will disable/enable the nodes in Node-RED. This should help people who find themselves having to make input_booleans in HA to enable/disable flows. This is a much cleaner way to do it.")]),p])}const v=i(r,[["render",g],["__file","exposed-nodes.html.vue"]]);export{v as default}; diff --git a/assets/exposed-nodes.html-ILHhxMf-.js b/assets/exposed-nodes.html-ILHhxMf-.js new file mode 100644 index 0000000000..7f15674d3a --- /dev/null +++ b/assets/exposed-nodes.html-ILHhxMf-.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-16946cd2","path":"/guide/custom_integration/exposed-nodes.html","title":"Exposed Nodes","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Available to all event nodes","slug":"available-to-all-event-nodes","link":"#available-to-all-event-nodes","children":[]},{"level":2,"title":"Trigger an exposed event node from a service call nodered.trigger","slug":"trigger-an-exposed-event-node-from-a-service-call-nodered-trigger","link":"#trigger-an-exposed-event-node-from-a-service-call-nodered-trigger","children":[{"level":3,"title":"entity_id","slug":"entity-id","link":"#entity-id","children":[]},{"level":3,"title":"output_path","slug":"output-path","link":"#output-path","children":[]},{"level":3,"title":"message","slug":"message","link":"#message","children":[]}]}],"git":{"updatedTime":1691128871000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"guide/custom_integration/exposed-nodes.md"}');export{e as data}; diff --git a/assets/fire-event.html-C7OeQhev.js b/assets/fire-event.html-C7OeQhev.js new file mode 100644 index 0000000000..7a0685e33b --- /dev/null +++ b/assets/fire-event.html-C7OeQhev.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-2832d8e2","path":"/node/fire-event.html","title":"Fire Event","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Event","slug":"event","link":"#event","children":[]},{"level":3,"title":"data","slug":"data","link":"#data","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"payload.event","slug":"payload-event","link":"#payload-event","children":[]},{"level":3,"title":"payload.data","slug":"payload-data","link":"#payload-data","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"payload.event_type","slug":"payload-event-type","link":"#payload-event-type","children":[]},{"level":3,"title":"payload.data","slug":"payload-data-1","link":"#payload-data-1","children":[]}]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1662358213000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/fire-event.md"}');export{e as data}; diff --git a/assets/fire-event.html-CFPfjQeh.js b/assets/fire-event.html-CFPfjQeh.js new file mode 100644 index 0000000000..1a0280f160 --- /dev/null +++ b/assets/fire-event.html-CFPfjQeh.js @@ -0,0 +1 @@ +import{_ as r,r as t,o as i,c as s,a as e,d as a,b as n,e as c}from"./app-DW3AHQOa.js";const h={},l=e("h1",{id:"fire-event",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#fire-event","aria-hidden":"true"},"#"),a(" Fire Event")],-1),p=e("p",null,"Fire an event to Home Assistants event bus",-1),u=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),a(" Configuration")],-1),f={id:"event",tabindex:"-1"},v=e("a",{class:"header-anchor",href:"#event","aria-hidden":"true"},"#",-1),_=c('
    • Type: string

    Event name to fire

    data

    • Type: Object

    JSON object to pass along

    Inputs

    If the incoming message has a payload property with event set it will override any config values if set. 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. If the node has a property value in its config for Merge Context then the flow and global contexts will be checked for this property which should be an object that will also be merged into the data payload.

    payload.event

    • Type: string

    Event to fire

    payload.data

    • Type: Object

    Event data to send

    Outputs

    payload.event_type

    • Type: string

    Event Type that was fired

    payload.data

    • Type: Object

    The event data sent if one was used

    References

    ',21),y={href:"https://developers.home-assistant.io/docs/en/dev_101_events.html#firing-events",target:"_blank",rel:"noopener noreferrer"};function b(g,m){const o=t("Badge"),d=t("ExternalLinkIcon");return i(),s("div",null,[l,p,u,e("h3",f,[v,a(" Event "),n(o,{text:"required"})]),_,e("p",null,[e("a",y,[a("Home Assistant Events"),n(d)])])])}const E=r(h,[["render",b],["__file","fire-event.html.vue"]]);export{E as default}; diff --git a/assets/first-automation.html-RzwC4Kux.js b/assets/first-automation.html-RzwC4Kux.js new file mode 100644 index 0000000000..e47585c570 --- /dev/null +++ b/assets/first-automation.html-RzwC4Kux.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-746a0799","path":"/guide/first-automation.html","title":"First Automation","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Events: state","slug":"events-state","link":"#events-state","children":[]},{"level":2,"title":"Entity ID","slug":"entity-id","link":"#entity-id","children":[]},{"level":2,"title":"If State","slug":"if-state","link":"#if-state","children":[]},{"level":2,"title":"Call Service","slug":"call-service","link":"#call-service","children":[]},{"level":2,"title":"Complete Automation","slug":"complete-automation","link":"#complete-automation","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":5}]},"filePathRelative":"guide/first-automation.md"}');export{t as data}; diff --git a/assets/first-automation.html-U01iwXIn.js b/assets/first-automation.html-U01iwXIn.js new file mode 100644 index 0000000000..0c86fa7c8b --- /dev/null +++ b/assets/first-automation.html-U01iwXIn.js @@ -0,0 +1,2 @@ +import{_ as r}from"./first-automation_05-BSXfHgTV.js";import{_ as c,r as p,o as u,c as l,a as s,d as n,b as t,w as o,e as i}from"./app-DW3AHQOa.js";const k="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPUAAAA3CAYAAADUkQzaAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAjgSURBVHhe7Z1ZbFRVGMcRDBURBEoBIxIXCvFBXwaVRSKgQYOyiUuwfTCB+AIPmoawpAgEKGBbGxbZBCpLFxAqi4gDGKgsStjamAhEitaACCYGikFA4PN+555z59wzZ+4ynXaGO98/+SXMPcs995zzm7lth5kWQKFQAhWSmkIJWEhqCiVgIakplICFpKZQAhaSmkJp5hw9ex7W7a+Bsu9roebXi/xo4kJSUyiNyMllC+HyT7X8kXOu37wFr8yrhOxZm6DrJ7uh64Iw9JxRCaMWbeM1EhOSmkKJM+cPVUP5c09BWehJfiR2UOg+syuhdfnv0GKvIZ5Em9LT0Hf+Fl6z8SGpKZQ4U/rsE3BlQnfYP/BhOLlwPj+qD75C64QWPLi8BnJWfstrNy4kNYUSR44UzoHDY58H+MBQyGBZtwfgxpUrvNSeo2cvQM+Zm7Qyy/Qq2Aanzl/mreIPSU2h+My1C+dhVa+ultDI2ddbwI7RQ3gNe/CXYl2Mn6F1Ist0m7IBppXv4a3iD0lNofhM1aihUD/O+DlakhrZHuoAdTu38lqRrK82pF7gLnXXKWWQn3SpayoAKnMAinoBzGhPEIHn9LttYFeoVZTQyI33jdvwLi2j2hyf+jRkT12pFVmmd/5qODXXuKVHp2oruWT+E5fUDRfPQsPy16BhartmRZ0sgmhuFndqCbfHRwstODGoBVS/1Dqq3dAPp0FGWb1WZqTt8hOQO+kje7u1I417/UvcOu8xRuI/V5e+yiTbOH0I9J+zBDrN2w6t5n/XpLSctQNaztsLrUp+IIikMK7fYFj5TCb8OOA+RxY/kgGPTV5nb198EDpPWmuI/VuU0G3WnILMqRWsXuane2Bg4SrYOftlJvbd0uHcOu/xL/XxL5jQm/IHa+WLxbCNJ6Hm0jUG/ltXxwmSmkg2j08qhWEjx3tC175V8SHIyiuFzsbPzh0KwtCxYBdkTd4AmQa6+kJsOLmBy+ct/qVe/yaT+oW5S7XyqYTWHIF99X/zxpHgMSzTtdFBUhNBIWNuGNp9/BU8ZJBRsEdbB+lftMaUuuwdbo23+Je6oDuTuv28r7XyCR5dfADW1P4Bd+6azf66fgsmhE8z8N8YLMM6WFfXhwxJTaQbnYt3m1LjL6J9xL/UxklQap14SNuifZBfXQfXbt5m1W/evgvFR+qhU0m1VQf/jcewDIN1sQ22lfuSIamJdIRJjfhIQqUevaUW6q/+yysCVJ25DL2WH9bWRbAM64hgW+xDV5ekJtKRpEt9/b87rMqJPxtgSPlxbZ2ZB85FHcO62AaDfajlCElNpCNJl1rkfk2ZAKMTG9uIqGUISU2kIykjta5MIKITW0Q9jjRe6jBkvRGCHtN0ZTrKoUcoF7IKdGWJpV1OCEI55dqyVCNjYi6E3iiBDE2ZX+S+EtmvHXXdcV3FY6ey5NJn0S4YsWQrHCsaY3LsGNTV1XFDnNPkUjtFFVtEPiYgqVODe19qr2XJoe+SMKxYsQI2bt4C4XDYRlVVFSs7d+4cN0WfpEqNkcUWkdsLvErNNofxbGsipDQXTxzPnhg26xeUQLZVV65vPmOL49aiT8uT6vrfDExeq30etJOP5+Tpz4nEHKcoy4Ms+boVOeTzZk8siXo10s+ZQJ6LXOiRI8vn4ZVNmTP5un1J7TD3eH3iuuzlunUXY3YqE33b66jjc563+EBpz5w54wjWcUrSpZ51MIFSs4WPbBr7Y+VZmYsStYC2DSstlNo3a+99IdVNKz82pYv0ZW4Wfi63cQrhrVd6c2OKJy5bXwZCcNGfOi77ddr7ss4l13eC9SXPkdmfGKt87qhxyLjMveP8qetuE9e9zLp2A3YeMc/qmNTHcYC33PhqrBNZBus43YonVWpZaLmufEwQl9Q21AWMxr6xcIHFRtG3ZfU93TbLmyUa22ZBXJ4wbOPU1I30pxk3F9M8Jl9jBGzPNrNmPh3l84B8rXJfsft1n3vn+VPbe5Qarz1qPNJ8JUBileHGz9B4m60TWQbr4M/YsZK0X5SpQstl6nHE2+23uUjilsi+EfSbQyykdRtlLaS84ZU6MvJmioWLpN6kjjFOR6nlaxCY/bB54ILbroeDUmtF0252F9Tz8Gv1JrX73DeF1Gw88rks7P2K45E+4ielpXb7k5ZO6ET/SYsttGYR1AXEOrZbVWtjYbloK2+EONBKGsF5U7qMU9O3P6ljj0srmh+pWf/m2MXcydcq9689F8N97ptMao/XGb3X4iMlpfby5hOd0E335hNz0UwZlAXUbE77QspCyP1E6nvHeWM6bkq3cTpKrW5aUV8ccxFGc4vpZ7OzuvJ1GfiX2n3um0Jq3bU709g9kqJSJ/1toupCOC2uWpc9NjaHtbFkqUW5LI+/RYzatNL5XaV2Gqej1Py8UntWJomslus2vXWN/AlBL1806jWb51LGxsvVujZc5r5JpOZltn7ltVDXRbMOfknJX5Qhyf4PHWLTCiILFr2pbHVxQymbR5SLzWO15/h9VraPTTlPzE3pMk4XqdX25p9+NPVF/wbynImNbpbxP51Z8skS6OBiiPbGmMw5NGXwLLWB09y7zZ/VltWxj9mpzH7tiPzk5zZv8ZFyf9KSof96margRrVLTaQOKffmEx30IQnJxH6biri9IhKpQeRtom+ZJOttok4E9+OMlFtMDYm4LYsbdisqjYeEvqdA3xg+0mxSNxZ6pSbSEZKaIAIGSU0QAaN5pC7syaTOLNimla+pIKmJdMP64MHCbC6ft/iXev0YJnXfOd4+IjhRkNREujGgUHxE8NtcPm/xL/XP25nUX07392H+jYWkJtKNXeLD/H/x96V5/qU20vD5CCb25vxB0G/uZ9CRvnaHIBJCl+IwvFi0Gr4RQleM5dZ5T3xS4xfkrRjGxG5O2EUSRLqAX5D3j/8voY9Laiv4dZsV79FX2RJEoijqDVCZ2/xfZUuhUFI3JDWFErCQ1BRKwEJSUygBC0lNoQQsJDWFErCQ1BRKwEJSUygBC0lNoQQsJDWFErCQ1BRKoALwP6rrMZVU96IvAAAAAElFTkSuQmCC",q="/node-red-contrib-home-assistant-websocket/assets/first-automation_02-D3oodEl1.png",A="/node-red-contrib-home-assistant-websocket/assets/first-automation_03-Cs4xo4aA.png",d="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAakAAACKCAYAAAAQY7V3AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA41SURBVHhe7d2tb+PKGsfx+0+GmCwvCeklIYcElZwLikJMwg9ZYhSy5EhHCrFUFZWcAqOSqlLQc/2MXzIeO3bipNuZ6fcjjVR3/D7p88u46e5/BAAATxFSAABvEVIAAG8RUgAAbxFSAABvEVIBOhwO8vr6Knmeyz///EOj0WhBNa1dWsO0lk0hpAKjg/r09GQG+OPjo/4uAIRDa5fWMK1lU0FFSAVGB1YbAITunHpGSAVGp8nMoADEQGuZ1rQxhFRg9HkuAMRiqqYRUoEhpADEhJCKDCEFICaEVGQIKQAxIaQiQ0gBiAkhFRlCCkBMrg6pQ/Esu+1alslCkuVatrtnKab/SBifhJACEJN5IXUoJM9SWS8TE0xplptgOhS5ZKkGViLLdSpZXsjpvCokWy1ksei3zfjH4j9Vka1kscrKswsTIQUgJheHlBbxJFnKeruT55NTpoMUzzvZrpfluivJBit+FVK9QCoyWX1xUIVsfEBz2bT31v56ytS62n9qnAFgvotDKt+Usx0NqTSTfCyk8kxSDamTxe1ESKl8U86oNmXpOzIznHJfVbP76gJZHk/DzfSbmVBVWKv1nQJq9t/0aTvuz55Jma83WWfGt/K8Ep8fUpcgpAB8jXkhVRdsbcmPlTxme3l5O8jby16yx5X8MI/7trJ7LuTvxxkh5RS9KqCcIGmX6zBqH9HVy9b25pybA5mAsgtqvX7d3wupsq89x962/pk/k+o+ft1kGvrNtdbrbuxwd+5/3Y77A4DrXR1Sdkvu/5S/fr3IW72u0vWHC9dYSNl9bjFVVX81q+n3d0JJabiM/J7JXr8XUp3ths7FL3NDytyD9lqbwOqGVK+/vRHa73d4AwjTTUNqqHhfHVLmd1T9Aqj7HQupzmO5oZCqf/fVnn+9g+8ZUgMh05k19q+7e28GtgeAG/A0pKyid+uQssKp2cZcU73wLUPK3BP793ylzn3vXzchBeB38DOkzLv47u88uutV284JKVNcnYMSUoQUAD9dHFJanPQTe9MhVUj+80HubvARdFMQrSLaXe4X0MmQsoKn2ld5/vUO7H533aFj+WZWSJmvnXHicR8AD1wcUkaxl/Q+qYq71aoi9i7//krlPknkPt1bBd5VhZS7j1OfnmvDxDT7XX+/gI6FVO+45YbVvqt9fs+Qqu5Z/x4RUgC+1ryQqr2/ZPJwdwyrP9KfZvnuIZOX93ol/FZzQ8oN7+oj6Kdnq26Am5Ar1+m8OQCAK10VUo1irzMn/Qh6Kntq1JeaGtCzDf2eCgB+s5uEFPwxL6T6MyX7wyQA8FUIqcjMnkmZD0ocH/cRUAB8QEhFZnZIAYCHCKnIEFIAYkJIRYaQAhATQioyhBSAmBBSkSGkAMSEkIpMnufy8fFRLwFAuLSWaU0bQ0gF5vX11TQACN059YyQCszhcJCnpyczsMyoAIRIa5fWMK1lWtPGEFIB0kHVAdZpsj7PpdFotJCa1i6tYVMBpQgpAIC3CCkAgLcIKQCAtwgpAIC3CCkAgLcIKQCAtwgpAIC3CCkAgLcIKQCAtwgpAIC3CCkAgLcIKQCAtwipAPEPzNJotJAb/8BsxHRQ+a86AISM/6ojYjqw2gAgdOfUM0IqMDpNZgYFIAZay7SmjSGkAqPPcwEgFlM1jZAKDCEFICaEVGQIKQAxIaQiQ0gBiAkhFRlCCkBMCKnIEFIAYnJ1SB2KZ9lt17JMFpIs17LdPUsx/UfC+CSEFICYzAupQyF5lsp6mZhgSrPcBNOhyCVLNbASWa5TyfJCpvIq3yxksbDaKpOi7ru5IpPVYiXZpx3g6xFSAGJycUgV2UqSZCnr7U6eT06ZDlI872S7Xpbrng4FE1Cb7h9qVaG1kfE/38Ip4wNaSLZaiHPLAcBbF4eUCRENqTSTfCyk8kxSDalydjRcFHPZDPYNfD/fdGZbdp+ezybTGZL2/Vf+99+FrJxU1HXM93ozqepY7b47B60Ketv3mTO8GyKkAMRkXkhZhT35sZLHbC8vbwd5e9lL9riSH+Zx31Z2z4X8/XiqKNYhMFX8TUBZMysnaNyZl870uvvUIKrX72xbHf8YaPay21cfJ4DqPjag5n7X4zYc2s51an95L7NmzMvvV4GfdcL9sttSj3uzvb2xOZ+NZDqGTX8gbw4AfI6rQ8puyf2f8tevF3mr11W6/uki5sxkytZdtypo7vYmiOpv9sLDLbwack2hs/vc8LPZ27SssPPYRTOpc0KqHJNeWFvbmLE4+/FsHVDHE+gu18c79levD/v4AL6Xm4ZUW1ss4yFlaQqUaU3R64dY2+qd9kKqLnxNYdP+tshZRbk/4zqqCq9zPNO+Y0iN9KuBdU4aemNgb3/O8QB8K/6EVMsOmSqkxrYfKmLHAHJmP1YRnAypE32+8zmkhu+rNUaEFADH14XUyOO2Y2HqzoqGDBaxpthlzmM7uwhOPe47+xGWXwgpADG5OKS00Ogn9qZDqpzH/HyQu5MfQa8KZq9ouYXKBIa9j25wDRexet96XicLaj8Aj/uqt7e3DSS4fA6pwXtob3/O8QB8KxeHlFHsJb1PqhDohdS7/Psrlfskkft0X5bFcaYIdfbTDwLzDtxaZzhYupptOl29Iuj8zqsTmE5fIDOri0Kqvsb2fpr7U15rs8I5oTGwzmlu+DvLhBQAx7yQqr2/ZPJwdwyrP9KfZvnuIZOX93ol/FZTA9oGflP4zeymGj8N6Vz7LwmNi0JK1cHUHHNiX4QU8L1dFVKNYq8zJ/0Ieir7s4sVPsPUgAJASG4SUvAHIQUgJoRUZL4spMyjOusxXq+F+WlJAF+LkIoMMykAMSGkIkNIAYgJIRUZQgpATAipyBBSAGJCSEWGkAIQE0IqMnmey8fHR70EAOHSWqY1bQwhFZjX11fTACB059QzQiowh8NBnp6ezMAyowIQIq1dWsO0lmlNG0NIBUgHVQdYp8n6PJdGo9FCalq7tIZNBZQipAAA3iKkAADeIqQAAN4ipAAA3iKkAADeIqQAAN4ipAAA3iKkAADeIqQAAN4ipAAA3iKkAADeIqQAAN4ipALEPzBLo9FCbvwDsxHTQeW/6gAQMv6rjojpwGoDgNCdU88IqcDoNJkZFIAYaC3TmjaGkAqMPs8FgFhM1TRCKjCEFICYEFKRIaQAxISQigwhBSAmhFRkCCkAMSGkIkNIAYjJ1SF1KJ5lt13LMllIslzLdvcsxfQfCeOTEFIAYjIvpA6F5Fkq62ViginNchNMhyKXLNXASmS5TiXLCzmdV4Vkq4UsFsNtM/7R+FaRrWTRrpzLxtq223eJ6txWWVEv9+Wb8jxn7ftzEVIAYnJxSGnhT5KlrLc7eT45ZTpI8byT7XpZrruS4VpfBcG1dX4siAgplx3i3UAfN7Wu9p8aZ2W/IdmUa9/a1PG/jnkNrrLyDgCY4+KQMsVZQyrNJB8LqTyTVEPqZHE7L6SqoMmsIncMD9NXf68qBMdi6vb96oXKWBAN9BWZrJr9lYV2E3xIXeLKkDL37jPCqUFIAbGaF1JtsV5I8mMlj9leXt4O8vayl+xxJT/M476t7J4L+fvxBiFlF8h8Uy4fC1IVYm1np5h2+sx2VqEcLZxOSNUB1T2H0EPKDZ7qmptx3WR6zc19rtfd1NdtWnPvqr52O/eWNPeqbnpPdVxW5f6b7aptusfv3ls9Rnku2YzjD9DX8CrLreP1A6553XWPpfR4m/Jc6v46gLrrO6/PVfmmxrq24TdGAIZcHVJ2S+7/lL9+vchbva7S9YcLh1OUOu1YFKofcvudaF0w6xVMf3uAuX2ubkj1z6G+Dye3/zpzQ8pcT3uNzdh0Q6rX316/9vcLfct5Q2DuZ2d9d39D+7/i+I7mNXzcXMPPCZbe+Tqh2G5cct8AWcvVtqePBWDcTUPK/rltTIXUcN9RPyCqItFsZ/qPFWCkrzqXJnhOn5eqzs1et1OUSu6+fTEvpPRrp3B2imn3vqruuAxsbxsKKXtM3SKvzDY3Or6jP572ePePNd7ffa24etc6uH8Ap3yrkDLF0OxL13OKYsc3C6mhR5+3DImJkHKXK/Y+rzy+Q8fTDZV2jDvXfXTcxj2X/rnZ+tc2vj6Aru8VUqa/LED6u43RA3dDqn8O9X0Y3cfXIKSmHQPnqB1PQgrwysUhpT90+om96ZAq5ys/H+Tuyo+gT/2Qm/52J2N9FVOMeufq6oZUr7CYx1PlfsZ38iVmhZT52hknHvdZxvrd10pX71oH9w/glItDyij2kt4nVaG2WvWD9y7//krlPknkPt1bP5yu6ofb3Ufb6p/iyR9yU8x0Gy1yY321oYLYM1B42n2VrTyfrFfo/DAvpPS2VNdVXXEzNr8ppJrjHQfOWb7y+I7qjYq1vvOaMPs+udw/l95rygrY/rUObA/gpHkhVXt/yeTh7hhWf6Q/zfLdQyYv7/VKvtGCEnGFmBtSZTntvGmoPoJ+ujC7xbeZoQ7ONiZDSnWP3x2jS48/rppJbcw+q+P1A64KpqbfCqCBc1Hd9Y/9/Wsd3h7AsKtCqlHsdeakH0FPZT9dI76UFqiYC8TUgJ7NCZaYVCFFSgAhuElIBaF5XBd5cZoXUv139zEXckIKCMf3CalvYvZMyvxepXpUZVqgRdwEkH0dTtPHgYQUEA5CKjKzQwoAPERIRYaQAhATQioyhBSAmBBSkSGkAMSEkIoMIQUgJoRUZPI8l4+Pj3oJAMKltUxr2hhCKjCvr6+mAUDozqlnhFRgDoeDPD09mYFlRgUgRFq7tIZpLdOaNoaQCpAOqg6wTpP1eS6NRqOF1LR2aQ2bCihFSAEAvEVIAQC8RUgBALxFSAEAvEVIAQC8RUgBALxFSAEAPCXyf6IoLGP62QBZAAAAAElFTkSuQmCC",h={},f=i('

    First Automation

    For your first automation, we'll start simple and set up an automation to turn on and off a light when the sun comes up and goes down.

    This example will use the state, below_horizon/above_horizon, of the sun.sun entity from Home Assistant to trigger the light.

    Events: state

    Place an Events: state node onto the workspace and double click on it to edit.

    screenshot

    Entity ID

    We'll add sun.sun to the Entity ID field and leave the entity id filter type to Exact as we only want to match one entity.

    If State

    If State is a conditional that will be checked against the state of the entity when it triggers the node. If the condition is found to be true the message will be sent out the top output and if found to be false it will be sent out the bottom output. If no conditional value is set there will only be one output and all messages will flow through it.

    For this example we will set the If State to above_horizon.

    screenshot

    Call Service

    Now that the trigger is set up it's time to set up the action. Most communication done with Home Assistant will come in the forms of services calls using the Call Service Node.

    Drag two Call Service nodes onto the workspace and connect them to each of the outputs from the Events: state node.

    screenshot

    Since we made the conditional in the Events: state node if state is equal to above_horizon the top output will be the action to turn off the light and the bottom output will be the action to turn on the light.

    The three fields that are relevant for this example are: Domain, Service, and Entity Id. Domain is going to be light, Service is going to be turn_off, and Entity Id is going to be light.front_porch. The Second Call Service node will be the same except the Service is going to be turn_on.

    screenshot

    Complete Automation

    At this point, you can deploy and should have your first working automation in Node-RED.

    screenshot

    [{"id":"b74ada49.d7e408","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sun.sun","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"above_horizon","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":244,"y":784,"wires":[["1f467cbb.0c3983"],["da5ff3e0.cbb2a"]]},{"id":"1f467cbb.0c3983","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":784,"wires":[[]]},{"id":"da5ff3e0.cbb2a","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":832,"wires":[[]]}]
    +

    Also see:

    `,24),y={href:"https://nodered.org/docs/user-guide/editor/workspace/import-export",target:"_blank",rel:"noopener noreferrer"};function g(m,b){const e=p("ExternalLinkIcon"),a=p("RouterLink");return u(),l("div",null,[f,s("ul",null,[s("li",null,[s("a",y,[n("Importing and Exporting Flows"),t(e)])]),s("li",null,[t(a,{to:"/node/call-service.html"},{default:o(()=>[n("Call Service Node")]),_:1})]),s("li",null,[t(a,{to:"/node/events-state.html"},{default:o(()=>[n("Events: state Node")]),_:1})]),s("li",null,[t(a,{to:"/guide/conditionals.html"},{default:o(()=>[n("Conditionals")]),_:1})])])])}const C=c(h,[["render",g],["__file","first-automation.html.vue"]]);export{C as default}; diff --git a/assets/first-automation_02-D3oodEl1.png b/assets/first-automation_02-D3oodEl1.png new file mode 100644 index 0000000000..88189148d6 Binary files /dev/null and b/assets/first-automation_02-D3oodEl1.png differ diff --git a/assets/first-automation_03-Cs4xo4aA.png b/assets/first-automation_03-Cs4xo4aA.png new file mode 100644 index 0000000000..bf4ba7daac Binary files /dev/null and b/assets/first-automation_03-Cs4xo4aA.png differ diff --git a/assets/first-automation_05-BBzXhkfO.png b/assets/first-automation_05-BBzXhkfO.png new file mode 100644 index 0000000000..104e8bbc4b Binary files /dev/null and b/assets/first-automation_05-BBzXhkfO.png differ diff --git a/assets/first-automation_05-BSXfHgTV.js b/assets/first-automation_05-BSXfHgTV.js new file mode 100644 index 0000000000..8678ae5c72 --- /dev/null +++ b/assets/first-automation_05-BSXfHgTV.js @@ -0,0 +1 @@ +const s="/node-red-contrib-home-assistant-websocket/assets/first-automation_05-BBzXhkfO.png";export{s as _}; diff --git a/assets/functions.html-B4SImbwx.js b/assets/functions.html-B4SImbwx.js new file mode 100644 index 0000000000..89cedb77d3 --- /dev/null +++ b/assets/functions.html-B4SImbwx.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-76287ba8","path":"/cookbook/jsonata/functions.html","title":"Other functions","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Reading entity state and entity attributes with $entity() and $prevEntity()","slug":"reading-entity-state-and-entity-attributes-with-entity-and-preventity","link":"#reading-entity-state-and-entity-attributes-with-entity-and-preventity","children":[]},{"level":3,"title":"Using $entities() to return one or all entities","slug":"using-entities-to-return-one-or-all-entities","link":"#using-entities-to-return-one-or-all-entities","children":[]},{"level":3,"title":"Using $areas(), $areaDevices and $areaEntities()","slug":"using-areas-areadevices-and-areaentities","link":"#using-areas-areadevices-and-areaentities","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"cookbook/jsonata/functions.md"}');export{t as data}; diff --git a/assets/functions.html-CmkTFp8c.js b/assets/functions.html-CmkTFp8c.js new file mode 100644 index 0000000000..25fc327b2b --- /dev/null +++ b/assets/functions.html-CmkTFp8c.js @@ -0,0 +1,8 @@ +import{_ as c,r as o,o as r,c as l,a as s,d as n,b as a,w as p,e}from"./app-DW3AHQOa.js";const i="/node-red-contrib-home-assistant-websocket/assets/jsonata_8_1-DHI1CMwN.png",k={},q=e('

    Other functions

    Several additional JSONata functions are provided for use within the WebSocket nodes. JSONata expressions are first 'prepared' then 'executed', and the preparation first stage is used to bind the expression to extra Node-RED or other functions. This means that these WebSocket functions can only be used within a WebSocket node.

    screenshot

    This example demonstrates the basic use of some of these functions.

    [{"id":"c3f7b442994c1a29","type":"group","z":"776c027950fc8c3f","name":"Using WebSocket functions to return entity, device, and area details","style":{"label":true,"color":"#000000"},"nodes":["578b1fe6b17d9053","9e2cc6208465cb53","24a0721c11a9dabf","0e27f1810d1f2726","25aa9320ec1b341f","87097a630683a0f3","2b079469d339ee68","6d7320ce7cf2d71b","4cf613030bdac458","4bba7af21fb76af8","80af7504e9450dd4"],"x":34,"y":2699,"w":732,"h":322},{"id":"578b1fe6b17d9053","type":"inject","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":2820,"wires":[["9e2cc6208465cb53"]]},{"id":"9e2cc6208465cb53","type":"ha-get-entities","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Entities with an attribute called \\"array\\"","server":"","version":1,"rules":[{"property":"","logic":"jsonata","value":"$entity().attributes.array!=[]","valueType":"jsonata"}],"outputType":"array","outputEmptyResults":true,"outputLocationType":"msg","outputLocation":"payload","outputResultsCount":1,"x":410,"y":2820,"wires":[["6d7320ce7cf2d71b"]]},{"id":"24a0721c11a9dabf","type":"api-current-state","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Entity attributes called \\"array\\"","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.date_time","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"$entities().*.attributes[$exists(array)]","valueType":"jsonata"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":380,"y":2900,"wires":[["4cf613030bdac458"]]},{"id":"0e27f1810d1f2726","type":"api-current-state","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Get Areas with Device and Entity Counts","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.time","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"$areas()^(name).{name: \\" Devices: \\" & $count($areaDevices(area_id)) & \\" Entities: \\" & $count($areaEntities(area_id))}~>$merge()","valueType":"jsonata"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":420,"y":2980,"wires":[["87097a630683a0f3"]]},{"id":"25aa9320ec1b341f","type":"inject","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":2980,"wires":[["0e27f1810d1f2726"]]},{"id":"87097a630683a0f3","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2980,"wires":[]},{"id":"2b079469d339ee68","type":"inject","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":2900,"wires":[["24a0721c11a9dabf"]]},{"id":"6d7320ce7cf2d71b","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2820,"wires":[]},{"id":"4cf613030bdac458","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2900,"wires":[]},{"id":"4bba7af21fb76af8","type":"server-state-changed","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Using $entity() and $prevEntity()","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"sensor.time","entityIdType":"exact","outputInitially":false,"stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\\"old\\": $prevEntity(), \\"new\\": $entity()}","valueType":"jsonata"}],"x":390,"y":2740,"wires":[["80af7504e9450dd4"]]},{"id":"80af7504e9450dd4","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2740,"wires":[]}]
    +

    Reading entity state and entity attributes with $entity() and $prevEntity()

    In nodes with output properties, a number of properties are typically set by default, or can be optionally set as:

    • msg.payload = 'entity state'
    • msg.data = 'entity'
    • msg.event = 'event data'
    • msg.topic = 'entity id'

    This provides useful message values in the flow following the node, however these values can be obtained within the node itself using the appropriate functions.

    The function $entity() returns an object containing the entity details, relating to the entity that is the subject of the node. This means that the output property selection options are equivalent to JSONata expressions:

    • 'entity' ~ $entity()
    • 'entity state' ~ $entity().state
    • 'entity id' ~ $entity().entity_id

    For the Events: nodes (Events: all and Events: state) the node triggers from an entity-change event, with $entity() returning the current (new) entity details, and the function $prevEntity() returning the previous (old) entity details.

    {"old": $prevEntity(), "new": $entity()}
    +
    `,13),y=s("strong",null,"The first example",-1),g=s("em",null,"Events: state",-1),d=s("code",null,"sensor.time",-1),m={href:"https://www.home-assistant.io/integrations/time_date/",target:"_blank",rel:"noopener noreferrer"},h=e(`

    The output msg.payload is set to a new JSONata expression, which creates a new object with the old and new entity details, just as the output property 'event data' would do, but permitting a more detailed JSONata expression to be executed if required.

    Using $entities() to return one or all entities

    The next two examples explore ways to obtain specific entities, and this code looks for all Home Assistant entities that have an attribute field called 'array'.

    $entity().attributes.array!=[]
    +

    In the first flow, a Get Entities node is used, with a JSONata expression used to filter the result, based on each entity having an attribute field called 'array' that is a non-empty JSON array. This will return the entire entity, and therefore the output will be an array of entities that have an 'attribute.array' field.

    $entities().*.attributes[$exists(array)]
    +

    In the second flow, a Current State node is used, with a valid subject entity. The return from the given entity itself is not required - the node is just being used as a vehicle in which to execute the $entities() function. When specifying a named entity such as $entities('sun.next_dawn') only that entity will be returned, otherwise an array of all entities in Home Assistant will be returned. This JSONata expression then matches all entities in the array, filtering out attributes fields where the object key 'array' exists.

    In contrast to the preceding flow, this will return just an array of the entity attributes. The JSONata code in this case can also be executed as and when required.

    Note: Where a number of entity state values or attributes are required at one point in a flow for collective processing, using JSONata in a Current State node can be highly effective. The alternatives are:

    • Several Current State nodes chained in sequence, with each writing the state or entity data to a different msg.field.
    • One Current State node executing a JSONata expression, collating various $entity() or $entities('sensor.name') functions to either place values into one object, or to perform the necessary computation at that point. Output from JSONata can be either a simple primitive, or an object with several fields.

    Using $areas(), $areaDevices and $areaEntities()

    Finally, a more complex JSONata expression that returns details about areas, devices, and entities.

    $areas()^(name).{
    +    name: " Devices: " & $count($areaDevices(area_id)) & " Entities: " & $count($areaEntities(area_id))
    +    } ~> $merge()
    +

    The JSONata above is just one long expression line (unnecessary new lines have been added just to make the expression easier to read). Evaluated left to right, it starts with the $areas() function:

    • Without a given area lookup value, this function returns an array of all areas in Home Assistant
      • which is then sorted alphabetically, by name
    • The result is an array, which is mapped (iterated over)
    • applying an {} object constructor for each array item
      • the object creates one key: value pair
      • the key is the area 'name' (this is a string)
      • the value is a constructed text string
    • The function $areaDevices(area_id) returns all devices in each area
      • using 'area_id' for the item area, and returning an array of devices
      • using $count() to count the number of devices in the returned array
    • The function $areaEntities(area_id) returns all entities in that area
      • returning an array, which is similarly counted
    • The resulting array of objects is then merged into one single object

    Also see:

    `,16);function f(b,v){const u=o("ExternalLinkIcon"),t=o("RouterLink");return r(),l("div",null,[q,s("p",null,[y,n(" uses an "),g,n(" node, with a basic "),d,n(" entity to facilitate triggering the node every minute. The "),s("a",m,[n("Time & Date Integration"),a(u)]),n(' should be added to the configuration file, and then the given time sensor will return the current local time. The entity state (as time) is "hh:mm" and therefore changes every 60 seconds.')]),h,s("ul",null,[s("li",null,[a(t,{to:"/guide/jsonata/"},{default:p(()=>[n("JSONata guide")]),_:1})]),s("li",null,[a(t,{to:"/guide/jsonata/jsonata-primer.html"},{default:p(()=>[n("JSONata primer")]),_:1})])])])}const x=c(k,[["render",f],["__file","functions.html.vue"]]);export{x as default}; diff --git a/assets/generate-token_01-DB9TrXpw.png b/assets/generate-token_01-DB9TrXpw.png new file mode 100644 index 0000000000..667fc8b7c0 Binary files /dev/null and b/assets/generate-token_01-DB9TrXpw.png differ diff --git a/assets/generate-token_02-k2eQmSik.png b/assets/generate-token_02-k2eQmSik.png new file mode 100644 index 0000000000..7154870288 Binary files /dev/null and b/assets/generate-token_02-k2eQmSik.png differ diff --git a/assets/get-entities.html-D6RrCGBK.js b/assets/get-entities.html-D6RrCGBK.js new file mode 100644 index 0000000000..6b5fdec556 --- /dev/null +++ b/assets/get-entities.html-D6RrCGBK.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-f5f1da26","path":"/node/get-entities.html","title":"Get Entities","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Search Criteria","slug":"search-criteria","link":"#search-criteria","children":[]},{"level":3,"title":"Property","slug":"property","link":"#property","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"payload","slug":"payload","link":"#payload","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"Array","slug":"array","link":"#array","children":[]},{"level":3,"title":"Count","slug":"count","link":"#count","children":[]},{"level":3,"title":"Random","slug":"random","link":"#random","children":[]},{"level":3,"title":"Split","slug":"split","link":"#split","children":[]}]},{"level":2,"title":"State Object Format","slug":"state-object-format","link":"#state-object-format","children":[{"level":3,"title":"entity_id","slug":"entity-id","link":"#entity-id","children":[]},{"level":3,"title":"state","slug":"state","link":"#state","children":[]},{"level":3,"title":"attributes","slug":"attributes","link":"#attributes","children":[]},{"level":3,"title":"last_changed","slug":"last-changed","link":"#last-changed","children":[]},{"level":3,"title":"timeSinceChangedMs","slug":"timesincechangedms","link":"#timesincechangedms","children":[]},{"level":3,"title":"last_updated","slug":"last-updated","link":"#last-updated","children":[]},{"level":3,"title":"context","slug":"context","link":"#context","children":[]}]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1662358213000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":5}]},"filePathRelative":"node/get-entities.md"}');export{e as data}; diff --git a/assets/get-entities.html-Dnp5j9U7.js b/assets/get-entities.html-Dnp5j9U7.js new file mode 100644 index 0000000000..75da3f4296 --- /dev/null +++ b/assets/get-entities.html-Dnp5j9U7.js @@ -0,0 +1,24 @@ +import{_ as r,r as o,o as l,c as k,b as a,w as e,a as s,d as n,e as u}from"./app-DW3AHQOa.js";const i="/node-red-contrib-home-assistant-websocket/assets/get-entities_03-C5epOs7g.png",y="/node-red-contrib-home-assistant-websocket/assets/get-entities_02-6WjKPZlv.png",d="/node-red-contrib-home-assistant-websocket/assets/get-entities_01-CNrrQzIG.png",g={},h=u(`

    Get Entities

    Get Entities based on search criteria

    Configuration

    Search Criteria

    All search criteria have to be true for an entity to be valid.

    Property

    Has autocompleted with all properties currently set on all loaded entities.

    Inputs

    payload

    • Type: Object

    Override config values by passing in a property with a valid value.

    • rules array
      • property string
      • logic string
      • value string
      • valueType string
    • outputType string
    • outputEmptyResults boolean
    • outputLocationType string
    • outputLocation string
    • outputResultscount number

    Outputs

    Array

    • Type: Array

    Sends an array of state objects from search criteria to the Output Location.

    Count

    • Type: number

    Return the total count of valid entities.

    Random

    • Type: Object|Array

    Return a random object or array from the available state objects to the Output Location. When One Max Results is selected it will return an object and when more than one is selected will always return an array of state objects.

    Split

    • Type: msg part

    Sends a message for each state object. In the same format as if the split node was used.

    State Object Format

    Sample output when the Output Type is an array:

    [
    +  {
    +    "entity_id": "light.kitchen",
    +    "state": "on",
    +    "attributes": {
    +      "brightness": 243,
    +      "friendly_name": "Kitchen Light",
    +      "supported_features": 33,
    +      "icon": "mdi:light-switch"
    +    },
    +    "last_changed": "2019-12-29T05:38:53.016984+00:00",
    +    "last_updated": "2019-12-29T05:38:53.016984+00:00",
    +    "context": {
    +      "id": "6c16e348494c42fb8c8e8bda92b20fb2",
    +      "parent_id": null,
    +      "user_id": null
    +    },
    +    "timeSinceChangedMs": 3466747
    +  }
    +]
    +

    entity_id

    • Type: string

    The entity to which this state belongs

    state

    • Type: string

    Main attribute state value, examples: 'on', 'off', 'home', 'open', 'closed', etc...

    attributes

    • Type: Object

    Supported attributes of state set by Home Assistant

    last_changed

    • Type: string

    ISO Date string of last time entity state changed

    timeSinceChangedMs

    • Type: number

    Milliseconds since last time entity state changed

    last_updated

    • Type: string

    ISO Date string of last time entity state was updated

    context

    • Type: Object

    Information on who/what changed the state of this object last.

    Examples

    `,50),m={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/get-entities.html#examples",target:"_blank",rel:"noopener noreferrer"},b=s("h4",{id:"example-1",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#example-1","aria-hidden":"true"},"#"),n(" Example 1")],-1),_=s("p",null,"You have a presence detection of some sort running in Home Assistant and you want to get a notification when you leave if any doors or windows are left open.",-1),f=s("p",null,[n("Using the "),s("code",null,"get entities"),n(" node here to get a possible list of entity ids [binary_sensor.front_door, binary_sensor.back_door, binary_sensor.front_window, binary_sensor.back_window] if their state is equal to "),s("code",null,"open"),n(". The entities are returned with the output "),s("code",null,"Split"),n(". This means that a message is sent for each valid entity. We then are using a template node to format the payload into the entity friendly name and joining them back into one payload using the "),s("code",null,"join"),n(" node.")],-1),x=s("p",null,[s("img",{src:i,alt:"screenshot"})],-1),w=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"dafa6c83.24e07"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"trigger-state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f24e6b8.eab548"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Left Home"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityid"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"device_tracker.jason"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfiltertype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"exact"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"constraints"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"9i2c9sz7d3e"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"this_entity"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetValue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous_state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyValue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"old_state.state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"comparatorType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"comparatorValueDatatype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"comparatorValue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"home"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3h3lghs8xsm"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"this_entity"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetValue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"current_state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyValue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"new_state.state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"comparatorType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"comparatorValueDatatype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"comparatorValue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"not_home"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"constraintsmustmatch"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"all"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"2"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"customoutputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputinitially"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"230"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"42dd6dce.c48ce4"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"42dd6dce.c48ce4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-get-entities"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f24e6b8.eab548"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"rules"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_id"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"logic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"includes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"binary_sensor.front_door,binary_sensor.back_door,binary_sensor.front_window,binary_sensor.back_window"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"logic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"open"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"split"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_empty_results"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_results_count"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"396"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"301b2b51.48b104"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"301b2b51.48b104"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"template"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f24e6b8.eab548"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Format Friendly Name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"field"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"fieldType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"format"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"handlebars"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"syntax"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"mustache"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"template"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{{payload.attributes.friendly_name}}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"600"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"8ed935f8.afbad8"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"8ed935f8.afbad8"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"join"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f24e6b8.eab548"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"custom"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"build"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"string"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"key"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"joiner"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'","'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"joinerType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"accumulate"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"timeout"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"count"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"reduceRight"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"reduceExp"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"reduceInit"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"reduceInitType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"reduceFixup"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"770"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"454131f7.c19f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"454131f7.c19f"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f24e6b8.eab548"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Notify"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service_domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"notify"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"push_jason"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{\\"message\\": \\"The {{payload}} are open.\\",\\"title\\": \\"Left Open\\"}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"json"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergecontext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"898"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1),v=s("h4",{id:"example-2",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#example-2","aria-hidden":"true"},"#"),n(" Example 2")],-1),T=s("p",null,"Sort of a Vacation or Away script to randomly turn on some lights around your home.",-1),j=s("p",null,[n("Using an "),s("code",null,"inject"),n(" node here but you could use your preference of timer node. The "),s("code",null,"get entities"),n(" node is randomly choosing one entity from the criteria where "),s("code",null,"entity_id starts with light."),n(".")],-1),q=s("p",null,[s("img",{src:y,alt:"screenshot"})],-1),O=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39342a95.8db3d6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c86782e1.cf429"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"date"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"252"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"e9038030.b79e4"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"e9038030.b79e4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-get-entities"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c86782e1.cf429"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"rules"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_id"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"logic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"starts_with"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"light."'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"random"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_empty_results"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_results_count"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"402"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2586f129.6136fe"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"58c67712.8aa4a8"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"delay"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c86782e1.cf429"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"pauseType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"random"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"timeout"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"5"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"timeoutUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"seconds"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"rate"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"nbRateUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"rateUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"second"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"randomFirst"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"20"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"randomLast"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"30"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"randomUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"minutes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"drop"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"732"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"986369ca.af3f48"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2586f129.6136fe"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c86782e1.cf429"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Turn on Light"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service_domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"light"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"turn_on"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{{payload.entity_id}}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"json"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergecontext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"562"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"58c67712.8aa4a8"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"986369ca.af3f48"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c86782e1.cf429"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Turn off Light"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service_domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"light"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"turn_off"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{{payload.entity_id}}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"json"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergecontext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"898"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1),z=s("hr",null,null,-1),C=s("h4",{id:"example-3",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#example-3","aria-hidden":"true"},"#"),n(" Example 3")],-1),I={href:"https://www.reddit.com/r/homeassistant/comments/a628cw/nodered_how_can_i_join_1_to_4_predefined_messages/",target:"_blank",rel:"noopener noreferrer"},D=s("p",null,[n("Here's my take on it using the "),s("code",null,"get entities"),n(" and a "),s("code",null,"function"),n(" node. Using the "),s("code",null,"Array"),n(" output option here.")],-1),A=s("p",null,[s("img",{src:d,alt:"screenshot"})],-1),S=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2bdd6fb7.15743"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"server-state-changed"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3c84cc55.8f02f4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"exposeToHomeAssistant"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfilter"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"binary_sensor.button_bedroom"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfiltertype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"substring"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputinitially"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haltifstate"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_compare"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_only_on_state_change"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"276"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"224"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"c2a9ffac.1e05d"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c2a9ffac.1e05d"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-get-entities"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3c84cc55.8f02f4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"rules"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_id"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"logic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"includes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"sensor.phon_charging,sensor.watch_charging,sensor.kaylas_phone_charging,lock.lock"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"logic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"includes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"no,unlocked"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"array"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_empty_results"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_results_count"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"550"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"224"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2950c181.1ef95e"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2950c181.1ef95e"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"function"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3c84cc55.8f02f4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"func"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"let lockFD = null;\\nlet PC = false;\\nlet WC = false;\\nlet KP = false;\\nlet FD = false;\\n\\nmsg.payload.forEach(entity => {\\n switch(entity.entity_id) {\\n case \\"sensor.phone_charging\\":\\n PC = true;\\n break;\\n case \\"sensor.watch_charging\\":\\n WC = true;\\n break;\\n case \\"sensor.kaylas_phone_charging\\":\\n KP = true;\\n break;\\n case \\"lock.lock\\":\\n FD = true;\\n lockFD = { payload: true };\\n break;\\n }\\n \\n});\\n\\nlet message = \\"Goodnight.\\";\\nif(PC && WC) {\\n message = `${message} Don’t forget to charge your phone and watch.`;\\n} else {\\n message = `${message} Don’t forget to charge your ${PC ? \'phone\' : \'watch\'}.`\\n}\\nif(KP) {\\n message = `${message} Remind Kayla to charge her phone${PC ? \' too\':\'\'}.`;\\n}\\nif(FD) {\\n message = `${message} The door is now locked.`\\n}\\nmsg.payload = message;\\nreturn [msg, lockFD];\\n"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"2"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"noerr"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"690"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"224"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"ca4a5643.9bf0d8"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"64374b0e.f72394"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ca4a5643.9bf0d8"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"cast-to-client"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3c84cc55.8f02f4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"url"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"contentType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"message"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"language"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"en"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ip"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"192.168.1.29"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"port"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"volume"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"40"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"874"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"224"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"64374b0e.f72394"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3c84cc55.8f02f4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"lock door"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service_domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"scene"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"turn_on"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"scene.lock_door"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"json"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergecontext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_location_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"844"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"272"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1),E=s("p",null,"Disclaimer: All these examples are untested but should give you a general idea of how to use it.",-1),V=s("h2",{id:"references",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#references","aria-hidden":"true"},"#"),n(" References")],-1),L={href:"https://home-assistant.io/docs/configuration/state_object/",target:"_blank",rel:"noopener noreferrer"};function P(F,R){const t=o("ExternalLinkIcon"),p=o("InfoPanelOnly"),c=o("DocsOnly");return l(),k("div",null,[h,a(p,null,{default:e(()=>[s("p",null,[s("a",m,[n("link"),a(t)])])]),_:1}),a(c,null,{default:e(()=>[b,_,f,x,w,v,T,j,q,O,z,C,s("p",null,[n("On Reddit the other day a user posted this "),s("a",I,[n("How can I join 1 to 4 pre-defined messages together based on 4 separate entity states?"),a(t)]),n(" (Their solution can be found in the post)")]),D,A,S,E]),_:1}),V,s("ul",null,[s("li",null,[s("a",L,[n("Home Assistant State Objects"),a(t)])])])])}const N=r(g,[["render",P],["__file","get-entities.html.vue"]]);export{N as default}; diff --git a/assets/get-entities_01-CNrrQzIG.png b/assets/get-entities_01-CNrrQzIG.png new file mode 100644 index 0000000000..590788214b Binary files /dev/null and b/assets/get-entities_01-CNrrQzIG.png differ diff --git a/assets/get-entities_02-6WjKPZlv.png b/assets/get-entities_02-6WjKPZlv.png new file mode 100644 index 0000000000..cb94c51a15 Binary files /dev/null and b/assets/get-entities_02-6WjKPZlv.png differ diff --git a/assets/get-entities_03-C5epOs7g.png b/assets/get-entities_03-C5epOs7g.png new file mode 100644 index 0000000000..dbbdf4b4ef Binary files /dev/null and b/assets/get-entities_03-C5epOs7g.png differ diff --git a/assets/get-history.html-D06ElvwU.js b/assets/get-history.html-D06ElvwU.js new file mode 100644 index 0000000000..d42200bd8f --- /dev/null +++ b/assets/get-history.html-D06ElvwU.js @@ -0,0 +1,45 @@ +import{_ as p,r as o,o as i,c as l,a,d as t,b as e,w as c,e as s}from"./app-DW3AHQOa.js";const d={},u=s('

    Get History

    Fetches history from Home Assistant (all history for the past day by default)

    Configuration

    Entity ID

    • Type: string

    The entity id to fetch history for. Can be a single entity id or a comma separated list of entity ids.

    Entity ID Type

    • Type: string
    • Values: == | regex

    The type of entity id matching to use. == will do an exact match, regex will use a regular expression to match the entity ids.

    Start Date

    • Type: string
    • Values: ISO Formattted Date
    • Default: 24 hours prior

    Date to start fetching history from. Will override the configuration if passed in. If relativetime is used this will be ignored.

    Also See:

    ',13),h={href:"https://en.wikipedia.org/wiki/ISO_8601",target:"_blank",rel:"noopener noreferrer"},k=s('

    End Date

    • Type: string
    • Values: ISO Formattted Date
    • Default: 24 hours from start date

    The end date to fetch history too. Will override the configuration if passed in. If relativetime is used this will be ignored.

    Also See:

    ',4),y={href:"https://en.wikipedia.org/wiki/ISO_8601",target:"_blank",rel:"noopener noreferrer"},f=s(`

    Use Relative Time

    • Type: boolean

    A checkbox to use relative time or not. If checked the startdate and enddate will be ignored and the relativetime will be used instead.

    In the Last

    • Type: string

    A time string that will be parsed the following keywords into time values.

    Example: 4h 30m = The last 4 hours and 30 minutes

    ms, milli, millisecond, milliseconds - will parse to milliseconds
    +s, sec, secs, second, seconds - will parse to seconds
    +m, min, mins, minute, minutes - will parse to minutes
    +h, hr, hrs, hour, hours - will parse to hours
    +d, day, days - will parse to days
    +w, week, weeks - will parse to weeks
    +mon, mth, mths, month, months - will parse to months
    +y, yr, yrs, year, years - will parse to years
    +

    Flatten Results

    Instead of returning the data from home assistant ( array for each entity_id ) return one flattened array of one item per history entry

    Output Types

    • Type: string
    • Values: array | split
    • Default: array

    The type of output to return. array will return an array of history objects. split will return an array of history objects for each entity id.

    Inputs

    All properties of msg.payload

    entityId

    • Type: string

    entityIdType

    • Type: equal | regex

    startDate

    • Type: string
    • Values: ISO Formattted Date

    endDate

    • Type: string
    • Values: ISO Formattted Date

    relativeTime

    • Type: string

    flatten

    • Type: boolean

    Outputs

    payload

    • Type: array

    The history returned by home-assistant, which is an array of arrays where each array entry contains history objects for one particular entity

    Example output of msg:

    {
    +  "payload": [
    +    {
    +      "attributes": {
    +        "friendly_name": "Kitchen Light",
    +        "icon": "mdi:light-switch",
    +      },
    +      "context": {
    +        "id": "850e510e36fb494c9abc79e01e897d54",
    +        "parent_id": null,
    +        "user_id": null
    +      },
    +      "entity_id": "light.kitchen_light",
    +      "last_changed": "2019-12-28T06:47:28.618000+00:00",
    +      "last_updated": "2019-12-28T06:47:28.618000+00:00",
    +      "state": "off"
    +    },
    +    {
    +      "attributes": {
    +        "brightness": 28,
    +        "friendly_name": "Kitchen Light",
    +        "icon": "mdi:light-switch",
    +      },
    +      "context": {
    +        "id": "4d4abe29f2bc43dab39101193f1fefe4",
    +        "parent_id": null,
    +        "user_id": null
    +      },
    +      "entity_id": "light.kitchen_light",
    +      "last_changed": "2019-12-28T07:48:11.514137+00:00",
    +      "last_updated": "2019-12-28T07:48:11.514137+00:00",
    +      "state": "on"
    +    },
    +    ...
    +  ]
    +}
    +

    Examples

    `,34),g=a("h2",{id:"references",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#references","aria-hidden":"true"},"#"),t(" References")],-1),m={href:"https://www.home-assistant.io/integrations/history",target:"_blank",rel:"noopener noreferrer"},q={href:"https://developers.home-assistant.io/docs/en/external_api_rest.html#get-apihistoryperiodlttimestamp",target:"_blank",rel:"noopener noreferrer"};function _(b,x){const n=o("ExternalLinkIcon"),r=o("RouterLink");return i(),l("div",null,[u,a("ul",null,[a("li",null,[a("a",h,[t("https://en.wikipedia.org/wiki/ISO_8601"),e(n)])])]),k,a("ul",null,[a("li",null,[a("a",y,[t("https://en.wikipedia.org/wiki/ISO_8601"),e(n)])])]),f,a("p",null,[e(r,{to:"/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html"},{default:c(()=>[t("Check if an entity was a certain state in the last 24 hours")]),_:1})]),g,a("ul",null,[a("li",null,[a("a",m,[t("Home Assistant History Component"),e(n)])]),a("li",null,[a("a",q,[t("Home Assistant API: /api/history/period"),e(n)])])])])}const T=p(d,[["render",_],["__file","get-history.html.vue"]]);export{T as default}; diff --git a/assets/get-history.html-TruWrGGx.js b/assets/get-history.html-TruWrGGx.js new file mode 100644 index 0000000000..750c73f3c9 --- /dev/null +++ b/assets/get-history.html-TruWrGGx.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-56e234f0","path":"/node/get-history.html","title":"Get History","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entity ID","slug":"entity-id","link":"#entity-id","children":[]},{"level":3,"title":"Entity ID Type","slug":"entity-id-type","link":"#entity-id-type","children":[]},{"level":3,"title":"Start Date","slug":"start-date","link":"#start-date","children":[]},{"level":3,"title":"End Date","slug":"end-date","link":"#end-date","children":[]},{"level":3,"title":"Use Relative Time","slug":"use-relative-time","link":"#use-relative-time","children":[]},{"level":3,"title":"In the Last","slug":"in-the-last","link":"#in-the-last","children":[]},{"level":3,"title":"Flatten Results","slug":"flatten-results","link":"#flatten-results","children":[]},{"level":3,"title":"Output Types","slug":"output-types","link":"#output-types","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"entityId","slug":"entityid","link":"#entityid","children":[]},{"level":3,"title":"entityIdType","slug":"entityidtype","link":"#entityidtype","children":[]},{"level":3,"title":"startDate","slug":"startdate","link":"#startdate","children":[]},{"level":3,"title":"endDate","slug":"enddate","link":"#enddate","children":[]},{"level":3,"title":"relativeTime","slug":"relativetime","link":"#relativetime","children":[]},{"level":3,"title":"flatten","slug":"flatten","link":"#flatten","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"payload","slug":"payload","link":"#payload","children":[]}]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1700417878000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":5}]},"filePathRelative":"node/get-history.md"}');export{e as data}; diff --git a/assets/get-state_changed-events-based-on-area.html-CwF3ERMA.js b/assets/get-state_changed-events-based-on-area.html-CwF3ERMA.js new file mode 100644 index 0000000000..3c472bbf46 --- /dev/null +++ b/assets/get-state_changed-events-based-on-area.html-CwF3ERMA.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7bcde729","path":"/cookbook/get-state_changed-events-based-on-area.html","title":"Get state_changed Events Based on Area","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/get-state_changed-events-based-on-area.md"}');export{e as data}; diff --git a/assets/get-state_changed-events-based-on-area.html-DbqIqKcr.js b/assets/get-state_changed-events-based-on-area.html-DbqIqKcr.js new file mode 100644 index 0000000000..ce5a50212b --- /dev/null +++ b/assets/get-state_changed-events-based-on-area.html-DbqIqKcr.js @@ -0,0 +1,2 @@ +import{_ as s,o as n,c as a,e as t}from"./app-DW3AHQOa.js";const p="/node-red-contrib-home-assistant-websocket/assets/get-state_changed-events-based-on-area_01-CutpOdT7.png",o={},e=t('

    Get state_changed Events Based on Area

    screenshot

    [{"id":"c964194d.7ad5e8","type":"ha-api","z":"ffbd7f06.4a014","name":"areas","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/area_registry/list\\"}","dataType":"json","location":"areas","locationType":"msg","responseType":"json","x":514,"y":944,"wires":[["4b011603.4c27f8"]]},{"id":"832ebec4.0d4a4","type":"inject","z":"ffbd7f06.4a014","name":"Manual Update","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":320,"y":944,"wires":[["c964194d.7ad5e8"]]},{"id":"4b011603.4c27f8","type":"ha-api","z":"ffbd7f06.4a014","name":"devices","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/device_registry/list\\"}","dataType":"json","location":"devices","locationType":"msg","responseType":"json","x":654,"y":944,"wires":[["4be8b708.430ec8"]]},{"id":"4be8b708.430ec8","type":"ha-api","z":"ffbd7f06.4a014","name":"entities","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/entity_registry/list\\"}","dataType":"json","location":"entities","locationType":"msg","responseType":"json","x":798,"y":944,"wires":[["59e18ea8.03287"]]},{"id":"2538006.71ef4","type":"debug","z":"ffbd7f06.4a014","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1144,"y":944,"wires":[]},{"id":"81c8e84.471e218","type":"server-events","z":"ffbd7f06.4a014","name":"","event_type":"state_changed","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":308,"y":1040,"wires":[["6e177280.669dec"]]},{"id":"59e18ea8.03287","type":"function","z":"ffbd7f06.4a014","name":"","func":"const entities = {};\\n\\nmsg.entities.forEach(e => {\\n    if(!e.device_id) return;\\n    \\n    const device = msg.devices.find(d => d.id === e.device_id);\\n    const area = msg.areas.find(a => a.area_id === device.area_id);\\n    if(area) {\\n        entities[e.entity_id] = {\\n            area_id: area.area_id,\\n            name: area.name\\n        };\\n    }\\n});\\n\\nmsg.payload = entities;\\nmsg.update = true;\\nreturn msg;","outputs":1,"noerr":0,"x":964,"y":944,"wires":[["2538006.71ef4","6e177280.669dec"]]},{"id":"6e177280.669dec","type":"function","z":"ffbd7f06.4a014","name":"set area","func":"if(msg.update) {\\n    node.status({fill:\\"green\\", shape: \\"dot\\", text: \\"Area Data Loaded\\", })\\n    context.set(\\"data\\", msg.payload);\\n    return;\\n}\\nconst data = context.get(\\"data\\");\\n\\nif(!data) {\\n    node.status({fill:\\"red\\", shape: \\"ring\\", text: \\"No Area Data\\", })\\n    return;\\n}\\n\\nconst area = data[msg.payload.entity_id];\\nif(!area) return;\\n\\nmsg.area = area.name.toLowerCase();     \\nnode.status({text: msg.area});\\n\\nreturn msg;","outputs":1,"noerr":0,"x":524,"y":1040,"wires":[["86100cd0.de8c5"]]},{"id":"582c98e0.5cd328","type":"debug","z":"ffbd7f06.4a014","name":"Kitchen","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":828,"y":1024,"wires":[]},{"id":"b60ead00.b4aaa","type":"debug","z":"ffbd7f06.4a014","name":"Bedroom","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":828,"y":1072,"wires":[]},{"id":"86100cd0.de8c5","type":"switch","z":"ffbd7f06.4a014","name":"","property":"area","propertyType":"msg","rules":[{"t":"eq","v":"kitchen","vt":"str"},{"t":"eq","v":"bedroom","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":656,"y":1040,"wires":[["582c98e0.5cd328"],["b60ead00.b4aaa"]]},{"id":"94d81549.f88148","type":"server-events","z":"ffbd7f06.4a014","name":"On Connect","event_type":"home_assistant_client","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":278,"y":896,"wires":[["72ef46c0.dbbce8"]]},{"id":"72ef46c0.dbbce8","type":"switch","z":"ffbd7f06.4a014","name":"connected","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"connected","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":470,"y":896,"wires":[["c964194d.7ad5e8"]]},{"id":"47aad143.f438c","type":"server-events","z":"ffbd7f06.4a014","name":"entity_registry_updated","event_type":"entity_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":308,"y":752,"wires":[["c7d0582b.715958"]]},{"id":"58d3bcdb.d39014","type":"server-events","z":"ffbd7f06.4a014","name":"device_registry_updated","event_type":"device_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":318,"y":800,"wires":[["c7d0582b.715958"]]},{"id":"8a9f192c.425718","type":"server-events","z":"ffbd7f06.4a014","name":"area_registry_updated","event_type":"area_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":308,"y":848,"wires":[["c7d0582b.715958"]]},{"id":"c7d0582b.715958","type":"trigger","z":"ffbd7f06.4a014","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","name":"Update at most every 10 secs","x":610,"y":800,"wires":[["c964194d.7ad5e8"]]}]
    +
    `,3),u=[e];function c(r,l){return n(),a("div",null,u)}const q=s(o,[["render",c],["__file","get-state_changed-events-based-on-area.html.vue"]]);export{q as default}; diff --git a/assets/get-state_changed-events-based-on-area_01-CutpOdT7.png b/assets/get-state_changed-events-based-on-area_01-CutpOdT7.png new file mode 100644 index 0000000000..80d29ba6e6 Binary files /dev/null and b/assets/get-state_changed-events-based-on-area_01-CutpOdT7.png differ diff --git a/assets/getting-started_03-B4ue_ZcX.png b/assets/getting-started_03-B4ue_ZcX.png new file mode 100644 index 0000000000..f8374b84e8 Binary files /dev/null and b/assets/getting-started_03-B4ue_ZcX.png differ diff --git a/assets/getting_started_02-7mfV03T6.png b/assets/getting_started_02-7mfV03T6.png new file mode 100644 index 0000000000..e7d6c705ca Binary files /dev/null and b/assets/getting_started_02-7mfV03T6.png differ diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled.html-BuFgBLlB.js b/assets/holiday-lights-scheduler-and-demo-mode-for-wled.html-BuFgBLlB.js new file mode 100644 index 0000000000..43d1e2057e --- /dev/null +++ b/assets/holiday-lights-scheduler-and-demo-mode-for-wled.html-BuFgBLlB.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-012b1d03","path":"/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.html","title":"Holiday lights scheduler and demo mode for WLED","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Version 1","slug":"version-1","link":"#version-1","children":[]},{"level":2,"title":"Requirements","slug":"requirements","link":"#requirements","children":[{"level":3,"title":"Integrations","slug":"integrations","link":"#integrations","children":[]},{"level":3,"title":"Nodes","slug":"nodes","link":"#nodes","children":[]}]},{"level":2,"title":"Setup","slug":"setup","link":"#setup","children":[{"level":3,"title":"WLED variables","slug":"wled-variables","link":"#wled-variables","children":[]},{"level":3,"title":"Setting date ranges up","slug":"setting-date-ranges-up","link":"#setting-date-ranges-up","children":[]},{"level":3,"title":"Home Assistant Entities","slug":"home-assistant-entities","link":"#home-assistant-entities","children":[]}]},{"level":2,"title":"Lovelace UI","slug":"lovelace-ui","link":"#lovelace-ui","children":[]},{"level":2,"title":"Things that could have been added but never got around to it","slug":"things-that-could-have-been-added-but-never-got-around-to-it","link":"#things-that-could-have-been-added-but-never-got-around-to-it","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":8}]},"filePathRelative":"cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.md"}');export{e as data}; diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled.html-BwE_uZSM.js b/assets/holiday-lights-scheduler-and-demo-mode-for-wled.html-BwE_uZSM.js new file mode 100644 index 0000000000..df9b116844 --- /dev/null +++ b/assets/holiday-lights-scheduler-and-demo-mode-for-wled.html-BwE_uZSM.js @@ -0,0 +1,90 @@ +import{_ as o,r as e,o as u,c,a as s,d as n,b as t,e as p}from"./app-DW3AHQOa.js";const r="/node-red-contrib-home-assistant-websocket/assets/holiday-lights-scheduler-and-demo-mode-for-wled_01-CHAwUUih.png",l="/node-red-contrib-home-assistant-websocket/assets/holiday-lights-scheduler-and-demo-mode-for-wled_03-D-JrQP6b.png",k="/node-red-contrib-home-assistant-websocket/assets/holiday-lights-scheduler-and-demo-mode-for-wled_08-BKy7okvm.png",q="/node-red-contrib-home-assistant-websocket/assets/holiday-lights-scheduler-and-demo-mode-for-wled_05-9II8TJDT.png",i="/node-red-contrib-home-assistant-websocket/assets/holiday-lights-scheduler-and-demo-mode-for-wled_06-FMERduQa.png",y="/node-red-contrib-home-assistant-websocket/assets/holiday-lights-scheduler-and-demo-mode-for-wled_02-DLPVHS6D.png",g={},d=s("h1",{id:"holiday-lights-scheduler-and-demo-mode-for-wled",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#holiday-lights-scheduler-and-demo-mode-for-wled","aria-hidden":"true"},"#"),n(" Holiday lights scheduler and demo mode for WLED")],-1),m={class:"custom-container tip"},f=s("p",{class:"custom-container-title"},"Questions and Discussion",-1),b={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket/discussions/306",target:"_blank",rel:"noopener noreferrer"},h={href:"https://github.com/Aircoookie/WLED",target:"_blank",rel:"noopener noreferrer"},w={href:"https://github.com/Aircoookie/WLED",target:"_blank",rel:"noopener noreferrer"},v=p('

    screenshot of flow

    Version 1

    [{"id":"886a465.91a0ab8","type":"switch","z":"894a6b3077af9604","name":"dark?","property":"dark","propertyType":"flow","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":240,"wires":[["5e38e1ee8665f5e7"],["90579358.a3dce"]]},{"id":"34cb332b.f8228c","type":"server-state-changed","z":"894a6b3077af9604","name":"Demo Mode","server":"","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_select.holiday_lights_demo_mode","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"","forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":294,"y":384,"wires":[["df0da821.aa74b8"],["91131276.4f322"]]},{"id":"90579358.a3dce","type":"api-call-service","z":"894a6b3077af9604","name":"turn off holiday lights","server":"","version":3,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"data"}],"queue":"last","x":692,"y":288,"wires":[[]]},{"id":"dc4b2af1.d366a8","type":"ha-wait-until","z":"894a6b3077af9604","name":"loop","server":"","version":0,"outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"60","timeoutType":"num","timeoutUnits":"minutes","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":false,"x":850,"y":240,"wires":[[],["5e38e1ee8665f5e7"]]},{"id":"59e25c2c.a3a514","type":"eztimer","z":"894a6b3077af9604","name":"","debug":false,"autoname":"sunset - 00:00","tag":"test1","suspended":false,"sendEventsOnSuspend":false,"latLongSource":"manual","latLongHaZone":"","lat":"","lon":"","timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onpropertytype":"flow","onproperty":"dark","onvaluetype":"bool","onvalue":"true","onoffset":"","onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"00:00","offduration":0,"offpropertytype":"flow","offproperty":"dark","offvaluetype":"bool","offvalue":"false","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"resend":false,"resendInterval":"1m","mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":304,"y":240,"wires":[["886a465.91a0ab8"]]},{"id":"f4ab62e2.10029","type":"api-call-service","z":"894a6b3077af9604","name":"turn on holiday lights","server":"","version":3,"debugenabled":false,"service_domain":"select","service":"select_option","entityId":"{{flow.wledHolidayLightsPresetEntityId}}","data":"{\\"option\\": payload}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"last","x":900,"y":192,"wires":[[]]},{"id":"98efb1f6.c85b8","type":"ha-wait-until","z":"894a6b3077af9604","name":"loop","server":"","version":0,"outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"$number($entities(\\"input_number.holiday_lights_demo_mode_delay\\").state)","timeoutType":"jsonata","timeoutUnits":"seconds","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":true,"x":1058,"y":432,"wires":[[],["91131276.4f322"]]},{"id":"91131276.4f322","type":"switch","z":"894a6b3077af9604","name":"which mode?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"cycle presets","vt":"str"},{"t":"eq","v":"cycle effects","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":470,"y":432,"wires":[["5adba3095728cdab"],["28fd29dc.96d306"]]},{"id":"333ed476.51a77c","type":"api-call-service","z":"894a6b3077af9604","name":"turn on preset","server":"","version":3,"debugenabled":false,"service_domain":"select","service":"select_option","entityId":"{{flow.wledHolidayLightsPresetEntityId}}","data":"{\\"option\\": name}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":880,"y":432,"wires":[["98efb1f6.c85b8","d0b9f667.79a8c8"]]},{"id":"fcf7dabd.b7a368","type":"api-call-service","z":"894a6b3077af9604","name":"turn on effect","server":"","version":3,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\\"effect\\": name}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":870,"y":480,"wires":[["98efb1f6.c85b8","d0b9f667.79a8c8"]]},{"id":"df0da821.aa74b8","type":"change","z":"894a6b3077af9604","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":384,"wires":[["886a465.91a0ab8","98efb1f6.c85b8"]]},{"id":"998c4f75.52cbf","type":"api-call-service","z":"894a6b3077af9604","name":"turn off demo mode","server":"","version":3,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.holiday_lights_demo_mode","data":"{\\"option\\": \\"off\\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":570,"y":528,"wires":[[]]},{"id":"5caeec35.01a114","type":"server-state-changed","z":"894a6b3077af9604","name":"Holiday Lights turned off?","server":"","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.wled","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":332,"y":528,"wires":[["998c4f75.52cbf"],[]]},{"id":"28fd29dc.96d306","type":"function","z":"894a6b3077af9604","name":"get next effect","func":"const states = global.get(\\"homeassistant\\").homeAssistant.states;\\nconst entityId = flow.get(\\"wledHolidayLightsEntityId\\");\\nconst effects = states[entityId].attributes.effect_list;\\nconst activeEffect = states[entityId].attributes.effect;\\nlet index = effects.findIndex(ele => ele === activeEffect);\\nindex = (index === -1 || index >= effects.length - 1) ? 0 : index + 1;\\n\\nnode.status({text: effects[index]});\\n\\nmsg.name = effects[index];\\n\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":672,"y":480,"wires":[["fcf7dabd.b7a368"]]},{"id":"d0b9f667.79a8c8","type":"ha-entity","z":"894a6b3077af9604","name":"current demo","server":"","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Holiday Lights Demo Current"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"name","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":1078,"y":480,"wires":[[]]},{"id":"9168ce00.dc7de","type":"comment","z":"894a6b3077af9604","name":"Scheduler","info":"","x":284,"y":192,"wires":[]},{"id":"241d097a.a3fe76","type":"comment","z":"894a6b3077af9604","name":"Demo Mode","info":"","x":294,"y":336,"wires":[]},{"id":"22f2928a.e2ae9e","type":"inject","z":"894a6b3077af9604","name":"Manual Start","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"dark","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":294,"y":288,"wires":[["5e38e1ee8665f5e7"]]},{"id":"9f8ca90550d41489","type":"inject","z":"894a6b3077af9604","name":"Setup","props":[{"p":"entityId","v":"light.holiday_lights","vt":"str"}],"repeat":"3600","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":284,"y":144,"wires":[["1047f2356f1e5203"]]},{"id":"1047f2356f1e5203","type":"change","z":"894a6b3077af9604","name":"set entity ids here","rules":[{"t":"set","p":"wledHolidayLightsEntityId","pt":"flow","to":"light.wled","tot":"str"},{"t":"set","p":"wledHolidayLightsPresetEntityId","pt":"flow","to":"select.wled_preset","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":144,"wires":[[]]},{"id":"5e38e1ee8665f5e7","type":"function","z":"894a6b3077af9604","name":"date ranges","func":"const now = new Date();\\nconst monthDay = getMonthDay(now);\\nconst states = global.get(\\"homeassistant\\").homeAssistant.states;\\nconst entityId = flow.get(\\"wledHolidayLightsEntityId\\");\\nconst presetId = flow.get(\\"wledHolidayLightsPresetEntityId\\");\\nconst christmasPresets = [\\n  \\"Christmas\\",\\n  \\"Christmas Candy Cane\\",\\n  \\"Christmas Classic\\",\\n  \\"Christmas Holly Jolly\\"\\n];\\n\\nlet updateInterval = 0; // in minutes\\nlet preset;\\n\\nswitch(true) {\\n// Winter \\n    case isToday(214):\\n      preset = \\"Valentine\\";\\n      break;\\n// President's Day changes every year, Veteran's Day & Flag Day always the same date\\n    case isToday(614): // 6/14 Flag Day\\n    case isToday(1111): // 11/11 Veterans Day\\n    case isToday(\\"President's Day\\"):\\n    case isToday(\\"Memorial Day\\"):\\n      preset = \\"Red White Blue\\";\\n      break;\\n    case isToday(317):\\n      preset = \\"St Patty\\";\\n      break;\\n    case isToday(\\"Easter\\"):\\n      preset = \\"Easter\\";\\n      break;\\n    case isToday(\\"Ash Wednesday\\", \\"Easter\\"):\\n      preset = \\"Spring\\";\\n      break;\\n// Spring\\n    case isToday(504):\\n      preset = \\"Star Wars\\";\\n      break;\\n    case isToday(505):\\n      preset = \\"Cinco de Mayo\\";\\n      break;\\n// Summer\\n    case isToday(704):\\n      preset = \\"Fireworks\\";\\n      break;\\n// Autumn\\n    case isToday(1014, 1031):\\n      preset = \\"Halloween\\";\\n      break;\\n    case isToday(\\"Thanksgiving Day\\"):\\n      preset = \\"Autumn\\";\\n      break;\\n    case isToday(1231):\\n      preset = \\"Fireworks White\\";\\n      break;\\n    case isToday(\\"Thanksgiving Day\\", 1231):\\n    case isToday(101, 106):\\n      preset = getRandomPreset(christmasPresets);\\n      updateInterval = 60;\\n      break;\\n    default:\\n      const seasons = {\\n        \\"winter\\": \\"Winter\\",\\n        \\"spring\\": \\"Spring\\",\\n        \\"summer\\": \\"Summer\\",\\n        \\"autumn\\": \\"Autumn\\"\\n      }\\n      const currentSeason = states[\\"sensor.season\\"].state;\\n      preset = seasons[currentSeason];\\n      break;\\n}\\n\\nnode.status({ text: preset});\\nmsg.payload = preset;\\nconst secondOutput = updateInterval ?  { payload: { timeout: updateInterval } } : { reset: true };\\n\\nreturn [msg, secondOutput];\\n\\nfunction isToday(start, end) {\\n  if (typeof start === \\"string\\") {\\n    start = getHolidayDate(now, start)\\n  }\\n  if (typeof end === \\"string\\") {\\n    end = getHolidayDate(now, end)\\n  }\\n  if (end === undefined) return monthDay === start;\\n\\n  return monthDay >= start && monthDay <= end;\\n}\\n\\nfunction getHolidayDate(date, holiday) {\\n    holiday = holiday.toLowerCase();\\n    // dates are formatted as month, week, day of the week\\n    // names should be lowercase\\n    const holidays = {\\n        \\"martin luther king day\\": [0,2,1],\\n        \\"president's day\\": [1,2,1],\\n        \\"daylight savings time begins\\": [2,1,0],\\n        \\"mother's day\\": [4,1,0],\\n        \\"memorial day\\": [4,-1,1],\\n        \\"father's day\\": [5,2,0],\\n        \\"labor day\\": [8,0,1],\\n        \\"columbus day\\": [9,1,1],\\n        \\"daylight savings time ends\\": [10,0,0],\\n        \\"thanksgiving day\\": [10,3,4]\\n    };\\n    let holidayDate;\\n    if(holiday === \\"easter\\") {\\n        holidayDate = getEasterDate(date);\\n    } else if (holiday === \\"ash wednesday\\") {\\n        const easter = getEasterDate(date);\\n        holidayDate = new Date(easter.getFullYear(), easter.getMonth(), (easter.getDate()-46));\\n    } else {\\n        const [month, week, day] = holidays[holiday];\\n        holidayDate = getDate(date.getFullYear(), month, week, day);\\n    }\\n    \\n    const monthDay = getMonthDay(holidayDate);\\n    \\n    return monthDay;\\n}\\n\\nfunction getMonthDay(date) {\\n    const monthString = String(date.getMonth() + 1).padStart(2, \\"0\\");\\n    const dayString = String(date.getDate()).padStart(2, \\"0\\");\\n    const monthDay = Number(`${monthString}${dayString}`);\\n    \\n    return monthDay;\\n}\\n\\nfunction getDate(year, month, week, day) {\\n    let firstDay = 1;\\n    if (week < 0) {\\n        month++;\\n        firstDay--;\\n    }\\n    const date = new Date(year, month, (week * 7) + firstDay);\\n    if (day < date.getDay()) {\\n        day += 7;\\n    }\\n    date.setDate(date.getDate() - date.getDay() + day);\\n    return date;\\n}\\n\\n/**\\n * Calculates Easter in the Gregorian/Western (Catholic and Protestant) calendar\\n * based on the algorithm by Oudin (1940) from http://www.tondering.dk/claus/cal/easter.php\\n * @returns {array} [int month, int day]\\n */\\nfunction getEasterDate(date) {\\n  const year = date.getFullYear();\\n  const f = Math.floor,\\n    // Golden Number - 1\\n    G = year % 19,\\n    C = f(year / 100),\\n    // related to Epact\\n    H = (C - f(C / 4) - f((8 * C + 13) / 25) + 19 * G + 15) % 30,\\n    // number of days from 21 March to the Paschal full moon\\n    I = H - f(H / 28) * (1 - f(29 / (H + 1)) * f((21 - G) / 11)),\\n    // weekday for the Paschal full moon\\n    J = (year + f(year / 4) + I + 2 - C + f(C / 4)) % 7,\\n    // number of days from 21 March to the Sunday on or before the Paschal full moon\\n    L = I - J,\\n    month = 3 + f((L + 40) / 44),\\n    day = L + 28 - 31 * f(month / 4);\\n\\n  return new Date(`${month}/${day}/${year}`);\\n}\\n\\nfunction getRandomPreset(list) {\\n  const activePreset = states[presetId].state;\\n  const filteredList = list.filter((e) => e !== activePreset);\\n  \\n  return filteredList[Math.floor(Math.random() * filteredList.length)];\\n}\\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":662,"y":240,"wires":[["f4ab62e2.10029"],["dc4b2af1.d366a8"]]},{"id":"e01d1bd31bd9e634","type":"comment","z":"894a6b3077af9604","name":"Change holiday dates in the \\"date ranges\\" node","info":"","x":404,"y":96,"wires":[]},{"id":"5adba3095728cdab","type":"function","z":"894a6b3077af9604","name":"get next preset","func":"const states = global.get(\\"homeassistant\\").homeAssistant.states;\\nconst presetId = flow.get(\\"wledHolidayLightsPresetEntityId\\");\\nconst presets = states[presetId].attributes.options;\\nconst activePreset = states[presetId].state;\\nlet index = presets.findIndex(ele => ele === activePreset);\\nindex = index === -1 || index >= presets.length - 1 ? 0 : index +1;\\nconst name = presets[index];\\n\\nnode.status({text: name });\\n\\nmsg.name = name;\\n\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":672,"y":432,"wires":[["333ed476.51a77c"]]}]\n
    ',3),_={class:"custom-container details"},x=s("summary",null,"version 0",-1),T={href:"https://home-assistant.io",target:"_blank",rel:"noopener noreferrer"},D={href:"https://github.com/Aircoookie/WLED",target:"_blank",rel:"noopener noreferrer"},I=p('
    [{"id":"eb756b3f.d770f8","type":"subflow","name":"Create HA Helpers","info":"","category":"","in":[{"x":84,"y":96,"wires":[{"id":"7f1493fc.1300fc"}]}],"out":[],"env":[{"name":"serverName","type":"str","value":"Home Assistant","ui":{"label":{"en-US":"HA Server Name"},"type":"input","opts":{"types":["str"]}}},{"name":"helpers","type":"json","value":"[]","ui":{"label":{"en-US":"Helpers"},"type":"input","opts":{"types":["json"]}}}],"color":"#DDAA99","status":{"x":246,"y":48,"wires":[{"id":"a66d5d93.8a5f","port":0}]}},{"id":"7f1493fc.1300fc","type":"function","z":"eb756b3f.d770f8","name":"process helpers","func":"const serverName = toCamelCase(env.get('serverName'));\\nconst haServer = global.get(\\"homeassistant\\")[serverName];\\nif(!haServer) {\\n    node.error(\\"Invalid HA server name\\");\\n    return;\\n}\\nconst states = haServer.states;\\nconst helpers = env.get(\\"helpers\\");\\n\\nhelpers.forEach(h => {\\n    const entityId = `${h.type}.${h.id}`;\\n    if(!states[entityId]) {\\n        const {id, type, ...data} = h;\\n        const apiData = {\\n            entity: h,\\n            payload: { \\n                data \\n            }\\n        };\\n        apiData.payload.data.type = `${type}/create`;\\n    \\n        node.send(apiData);\\n        node.status({text: `Creating ${entityId}`});\\n    }\\n});\\n\\nnode.done();\\n\\nfunction toCamelCase(str) {\\n    return str.replace(/(?:^\\\\w|[A-Z]|\\\\b\\\\w|\\\\s+)/g, (match, index) => {\\n        if (+match === 0) return '';\\n        return index === 0 ? match.toLowerCase() : match.toUpperCase();\\n    });\\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":224,"y":96,"wires":[["a4a0abd9.7576d8"]]},{"id":"a4a0abd9.7576d8","type":"ha-api","z":"eb756b3f.d770f8","name":"create helper","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":390,"y":96,"wires":[["b76d0c56.d54b9"]]},{"id":"388bb5c7.47346a","type":"ha-api","z":"eb756b3f.d770f8","name":"rename helper entity id","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\t   \\"type\\":\\"config/entity_registry/update\\",\\t   \\"entity_id\\": entity.type & \\".\\" & payload.id,\\t   \\"new_entity_id\\": entity.type & \\".\\" & entity.id\\t}","dataType":"jsonata","location":"payload","locationType":"msg","responseType":"json","x":788,"y":96,"wires":[[]]},{"id":"b76d0c56.d54b9","type":"switch","z":"eb756b3f.d770f8","name":"need to rename?","property":"payload.id","propertyType":"msg","rules":[{"t":"neq","v":"entity.id","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":96,"wires":[["388bb5c7.47346a","3e47440a.eee2cc"]]},{"id":"a66d5d93.8a5f","type":"status","z":"eb756b3f.d770f8","name":"","scope":["7f1493fc.1300fc","858d7015.518f4","3e47440a.eee2cc"],"x":124,"y":48,"wires":[[]]},{"id":"3e47440a.eee2cc","type":"function","z":"eb756b3f.d770f8","name":"rename status","func":"const oldEntityId = `${msg.entity.type}.${msg.payload.id}`;\\nconst newEntityId = `${msg.entity.type}.${msg.entity.id}`;\\n\\nnode.status({text: `Renaming ${oldEntityId} to ${newEntityId}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":768,"y":144,"wires":[[]]},{"id":"4762791a.4c5408","type":"function","z":"daf25abf.0203b8","name":"date ranges","func":"const now = new Date();\\nconst monthDay = getMonthDay(now);\\nconst { idLookup, nameLookup } = flow.get(\\"wledHolidayLightsPresets\\");\\nconst christmasPresets = [\\n  \\"Christmas\\",\\n  \\"Christmas Classic\\",\\n  \\"Christmas Holly Jolly\\",\\n  \\"Christmas Candy Cane\\"\\n];\\nconst states = global.get(\\"homeassistant\\").homeAssistant.states;\\nconst entityId = flow.get(\\"wledHolidayLightsEntityId\\");\\n\\nlet updateInterval = 0; // in minutes\\nlet preset;\\n\\nswitch(true) {\\n// Winter \\n    case isToday(214):\\n      preset = \\"Valentine\\";\\n      break;\\n// President's Day changes every year, Veteran's Day & Flag Day always the same date\\n    case isToday(614): // 6/14 Flag Day\\n    case isToday(1111): // 11/11 Veterans Day\\n    case isToday(\\"President's Day\\"):\\n    case isToday(\\"Memorial Day\\"):\\n      preset = \\"Red, White, and Blue\\";\\n      break;\\n    case isToday(317):\\n      preset = \\"St Patty\\";\\n      break;\\n    case isToday(\\"Easter\\"):\\n      preset = \\"Easter\\";\\n      break;\\n// Spring\\n    case isToday(504):\\n      preset = \\"Starwars\\";\\n      break;\\n    case isToday(505):\\n      preset = \\"Cinco de Mayo\\";\\n      break;\\n// Summer\\n    case isToday(704):\\n      preset = \\"Independence Day\\";\\n      break;\\n// Autumn\\n    case isToday(1017, 1031):\\n      preset = \\"Halloween\\";\\n      break;\\n    case isToday(\\"Thanksgiving Day\\"):\\n      preset = \\"Autumn\\";\\n      break;\\n    case isToday(1231):\\n      preset = \\"New Years\\";\\n      break;\\n    case isToday(\\"Thanksgiving Day\\", 1231):\\n    case isToday(101, 106):\\n      preset = getRandomPreset(christmasPresets);\\n      updateInterval = 60;\\n      break;\\n    default:\\n      const seasons = {\\n        \\"winter\\": \\"Winter\\",\\n        \\"spring\\": \\"Spring\\",\\n        \\"summer\\": \\"Summer\\",\\n        \\"autumn\\": \\"Autumn\\"\\n      }\\n      const currentSeason = states[\\"sensor.season\\"].state;\\n      preset = seasons[currentSeason];\\n      break;\\n}\\n\\nnode.status({ text: preset});\\nmsg.payload = nameLookup[preset];\\nconst secondOutput = updateInterval ?  { payload: { timeout: updateInterval } } : { reset: true };\\n\\nreturn [msg, secondOutput];\\n\\nfunction isToday(start, end) {\\n  if (typeof start === \\"string\\") {\\n    start = getHolidayDate(now, start)\\n  }\\n  if (typeof end === \\"string\\") {\\n    end = getHolidayDate(now, end)\\n  }\\n  if (end === undefined) return monthDay === start;\\n\\n  return monthDay >= start && monthDay <= end;\\n}\\n\\nfunction getHolidayDate(date, holiday) {\\n    holiday = holiday.toLowerCase();\\n    // dates are formatted as month, week, day of the week\\n    // names should be lowercase\\n    const holidays = {\\n        \\"martin luther king day\\": [0,2,1],\\n        \\"president's day\\": [1,2,1],\\n        \\"daylight savings time begins\\": [2,1,0],\\n        \\"mother's day\\": [4,1,0],\\n        \\"memorial day\\": [4,-1,1],\\n        \\"father's day\\": [5,2,0],\\n        \\"labor day\\": [8,0,1],\\n        \\"columbus day\\": [9,1,1],\\n        \\"daylight savings time ends\\": [10,0,0],\\n        \\"thanksgiving day\\": [10,3,4]\\n    };\\n    let holidayDate;\\n    if(holiday === \\"easter\\") {\\n        holidayDate = getEasterDate(date); \\n    } else {\\n        const [month, week, day] = holidays[holiday];\\n        holidayDate = getDate(date.getFullYear(), month, week, day);\\n    }\\n    \\n    const monthDay = getMonthDay(holidayDate);\\n    \\n    return monthDay;\\n}\\n\\nfunction getMonthDay(date) {\\n    const monthString = String(date.getMonth() + 1).padStart(2, \\"0\\");\\n    const dayString = String(date.getDate()).padStart(2, \\"0\\");\\n    const monthDay = Number(`${monthString}${dayString}`);\\n    \\n    return monthDay;\\n}\\n\\nfunction getDate(year, month, week, day) {\\n    let firstDay = 1;\\n    if (week < 0) {\\n        month++;\\n        firstDay--;\\n    }\\n    const date = new Date(year, month, (week * 7) + firstDay);\\n    if (day < date.getDay()) {\\n        day += 7;\\n    }\\n    date.setDate(date.getDate() - date.getDay() + day);\\n    return date;\\n}\\n\\n/**\\n * Calculates Easter in the Gregorian/Western (Catholic and Protestant) calendar\\n * based on the algorithm by Oudin (1940) from http://www.tondering.dk/claus/cal/easter.php\\n * @returns {array} [int month, int day]\\n */\\nfunction getEasterDate(date) {\\n  const year = date.getFullYear();\\n  const f = Math.floor,\\n    // Golden Number - 1\\n    G = year % 19,\\n    C = f(year / 100),\\n    // related to Epact\\n    H = (C - f(C / 4) - f((8 * C + 13) / 25) + 19 * G + 15) % 30,\\n    // number of days from 21 March to the Paschal full moon\\n    I = H - f(H / 28) * (1 - f(29 / (H + 1)) * f((21 - G) / 11)),\\n    // weekday for the Paschal full moon\\n    J = (year + f(year / 4) + I + 2 - C + f(C / 4)) % 7,\\n    // number of days from 21 March to the Sunday on or before the Paschal full moon\\n    L = I - J,\\n    month = 3 + f((L + 40) / 44),\\n    day = L + 28 - 31 * f(month / 4);\\n\\n  return new Date(`${month}/${day}/${year}`);\\n}\\n\\nfunction getRandomPreset(list) {\\n  const activePreset = states[entityId].attributes.preset;\\n  const presetName = idLookup[activePreset];\\n  const filteredList = list.filter((e) => e !== presetName);\\n  \\n  return filteredList[Math.floor(Math.random() * filteredList.length)];\\n}\\n","outputs":2,"noerr":0,"initialize":"","finalize":"","x":470,"y":272,"wires":[["91b62e9f.fe736","dece0bc.3c215f8"],["dc570e50.22a3a"]]},{"id":"c46d93f8.1fe18","type":"switch","z":"daf25abf.0203b8","name":"dark?","property":"dark","propertyType":"flow","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":306,"y":272,"wires":[["4762791a.4c5408"],["73710f8.1582bf"]]},{"id":"fe4f63d8.5312c","type":"server-state-changed","z":"daf25abf.0203b8","name":"Demo Mode","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_select.holiday_lights_demo_mode","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"","forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"x":102,"y":464,"wires":[["1a546dd7.2d8ef2"],["92c007de.c4a168"]]},{"id":"73710f8.1582bf","type":"api-call-service","z":"daf25abf.0203b8","name":"turn off holiday lights","server":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":500,"y":320,"wires":[[]]},{"id":"dc570e50.22a3a","type":"ha-wait-until","z":"daf25abf.0203b8","name":"loop","server":"","outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"60","timeoutType":"num","timeoutUnits":"minutes","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":false,"x":658,"y":272,"wires":[[],["4762791a.4c5408"]]},{"id":"f5422b5c.762798","type":"eztimer","z":"daf25abf.0203b8","name":"","debug":false,"autoname":"sunset - 00:00","tag":"test1","suspended":false,"sendEventsOnSuspend":false,"latLongSource":"manual","latLongHaZone":"zone.home","lat":"","lon":"","timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onpropertytype":"msg","onproperty":"dark","onvaluetype":"bool","onvalue":"true","onoffset":"","onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"00:00","offduration":0,"offpropertytype":"msg","offproperty":"dark","offvaluetype":"bool","offvalue":"false","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"resend":false,"resendInterval":"1m","mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":112,"y":272,"wires":[["c800976d.89af98"]]},{"id":"91b62e9f.fe736","type":"api-call-service","z":"daf25abf.0203b8","name":"turn on holiday lights","server":"","version":1,"debugenabled":false,"service_domain":"wled","service":"preset","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\\"preset\\": payload}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":708,"y":224,"wires":[[]]},{"id":"78b7479f.e79dd8","type":"function","z":"daf25abf.0203b8","name":"get preset","func":"// WLED Presets\\nconst { nameLookup } = flow.get(\\"wledHolidayLightsPresets\\");\\n\\nmsg.payload = nameLookup[msg.payload];\\n\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":668,"y":176,"wires":[["cc0fc459.d7f3a8"]]},{"id":"6a3ef206.84c5fc","type":"api-call-service","z":"daf25abf.0203b8","name":"populate HA dropdown with presets","server":"","version":1,"debugenabled":false,"service_domain":"input_select","service":"set_options","entityId":"input_select.holiday_lights_presets","data":"{\\"options\\": payload}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":748,"y":128,"wires":[["d7d3f0e8.9971d"]]},{"id":"a6b79bf.256d268","type":"inject","z":"daf25abf.0203b8","name":"Setup","props":[{"p":"entityId","v":"light.holiday_lights","vt":"str"},{"p":"WLED_IP","v":"","vt":"str"}],"repeat":"3600","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":108,"y":128,"wires":[["4b308915.771578"]]},{"id":"1538c003.e770a","type":"ha-wait-until","z":"daf25abf.0203b8","name":"loop","server":"","outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"$number($entities(\\"input_number.holiday_lights_demo_mode_delay\\").state)","timeoutType":"jsonata","timeoutUnits":"seconds","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":true,"x":866,"y":512,"wires":[[],["92c007de.c4a168"]]},{"id":"92c007de.c4a168","type":"switch","z":"daf25abf.0203b8","name":"which mode?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"cycle presets","vt":"str"},{"t":"eq","v":"cycle effects","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":278,"y":512,"wires":[["29bbe4ad.4de71c"],["7f2dc75.a04cf38"]]},{"id":"422a9fe2.d974c","type":"api-call-service","z":"daf25abf.0203b8","name":"turn on preset","server":"","version":1,"debugenabled":false,"service_domain":"wled","service":"preset","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\\"preset\\": preset}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":688,"y":512,"wires":[["1538c003.e770a","e132c6fa.e3da18"]]},{"id":"9755a99c.54ba18","type":"api-call-service","z":"daf25abf.0203b8","name":"turn on effect","server":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\\"effect\\": effect}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":678,"y":560,"wires":[["1538c003.e770a","e132c6fa.e3da18"]]},{"id":"1a546dd7.2d8ef2","type":"change","z":"daf25abf.0203b8","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"},{"t":"set","p":"payload","pt":"msg","to":"info","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":258,"y":464,"wires":[["1538c003.e770a","c46d93f8.1fe18"]]},{"id":"71da85fd.de44fc","type":"api-call-service","z":"daf25abf.0203b8","name":"turn off demo mode","server":"","version":1,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.holiday_lights_demo_mode","data":"{\\"option\\": \\"off\\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":378,"y":608,"wires":[[]]},{"id":"320d2444.2aa86c","type":"server-state-changed","z":"daf25abf.0203b8","name":"Holiday Lights turned off?","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.holiday_lights","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":140,"y":608,"wires":[["71da85fd.de44fc"],[]]},{"id":"7f2dc75.a04cf38","type":"function","z":"daf25abf.0203b8","name":"get next effect","func":"const states = global.get(\\"homeassistant\\").homeAssistant.states;\\nconst entityId = flow.get(\\"wledHolidayLightsEntityId\\");\\nconst effects = states[entityId].attributes.effect_list;\\nconst activeEffect = states[entityId].attributes.effect;\\nlet index = effects.findIndex(ele => ele === activeEffect);\\nindex = (index === -1 || index >= effects.length - 1) ? 0 : index + 1;\\n\\nnode.status({text: effects[index]});\\n\\nmsg.effect = msg.name = effects[index];\\n\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":560,"wires":[["9755a99c.54ba18"]]},{"id":"29bbe4ad.4de71c","type":"function","z":"daf25abf.0203b8","name":"get next preset","func":"const states = global.get(\\"homeassistant\\").homeAssistant.states;\\nconst entityId = flow.get(\\"wledHolidayLightsEntityId\\");\\nconst { idLookup, nameLookup } = flow.get(\\"wledHolidayLightsPresets\\");\\nconst keys = Object.keys(idLookup);\\nconst activePreset = states[entityId].attributes.preset;\\nlet index = keys.findIndex(ele => ele == activePreset);\\nindex = index === -1 || index >= keys.length - 1 ? 0 : index +1;\\nconst name = idLookup[keys[index]];\\n\\nnode.status({text: name });\\n\\nmsg.preset = keys[index];\\nmsg.name = name;\\n\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":512,"wires":[["422a9fe2.d974c"]]},{"id":"d89db901.9fd588","type":"function","z":"daf25abf.0203b8","name":"process data","func":"if(msg.statusCode !== 200) {\\n    node.status({fill: 'red', shape: 'dot', text: `Status Code: ${msg.statusCode}`})\\n    return;\\n}\\n\\nconst wledPresets = msg.payload;\\nconst idLookup = {};\\nconst nameLookup = {};\\n\\nfor(const key in wledPresets) {\\n    if(Object.keys(wledPresets[key]).length > 0) {\\n        const name = wledPresets[key].n;\\n        idLookup[key] = name;\\n        nameLookup[name] = key;\\n    }\\n}\\n\\nconst presets = {\\n    idLookup,\\n    nameLookup,\\n    names: Object.values(idLookup).sort()\\n};\\n\\nflow.set(\\"wledHolidayLightsPresets\\", presets);\\nflow.set(\\"wledHolidayLightsEntityId\\", msg.entityId);\\nnode.status({text: `${presets.names.length} Presets Processed`});\\n\\nmsg.payload = presets.names;\\n\\nreturn [msg, { payload: \\"disable\\" }];","outputs":2,"noerr":0,"initialize":"","finalize":"","x":470,"y":128,"wires":[["6a3ef206.84c5fc"],["539eea44.9b6524"]]},{"id":"d7d3f0e8.9971d","type":"change","z":"daf25abf.0203b8","name":"enable","rules":[{"t":"set","p":"payload","pt":"msg","to":"enable","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":962,"y":128,"wires":[["7c6317af.370198"]]},{"id":"539eea44.9b6524","type":"trigger-state","z":"daf25abf.0203b8","name":"Preset Selector","server":"","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"input_select.holiday_lights_presets","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","comparatorType":"is_not","comparatorValueDatatype":"prevEntity","comparatorValue":"state","propertyValue":"new_state.state"}],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":480,"y":176,"wires":[["78b7479f.e79dd8"],[]]},{"id":"e132c6fa.e3da18","type":"ha-entity","z":"daf25abf.0203b8","name":"current demo","server":"","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Holiday Lights Demo Current"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"name","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","x":886,"y":560,"wires":[[]]},{"id":"a3f0ee9.6fd551","type":"server-events","z":"daf25abf.0203b8","name":"HA Client Events","server":"","event_type":"home_assistant_client","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":112,"y":176,"wires":[["6c13e445.ca929c"]]},{"id":"6c13e445.ca929c","type":"function","z":"daf25abf.0203b8","name":"HA running?","func":"if(msg.payload !== \\"running\\") return;\\n\\nconst { names } = flow.get(\\"wledHolidayLightsPresets\\");\\n\\nmsg.payload = names;\\n\\nreturn [msg, { payload: \\"disable\\" }];","outputs":2,"noerr":0,"initialize":"","finalize":"","x":278,"y":176,"wires":[["6a3ef206.84c5fc"],["539eea44.9b6524"]]},{"id":"afc3f7e9.88ac98","type":"comment","z":"daf25abf.0203b8","name":"Setup","info":"","x":82,"y":32,"wires":[]},{"id":"5b75e78b.d9d608","type":"comment","z":"daf25abf.0203b8","name":"Scheduler","info":"","x":92,"y":224,"wires":[]},{"id":"cc0fc459.d7f3a8","type":"link out","z":"daf25abf.0203b8","name":"turn on holiday lights","links":["d830a00d.1d744"],"x":852,"y":176,"wires":[],"l":true},{"id":"d830a00d.1d744","type":"link in","z":"daf25abf.0203b8","name":"Holiday Lights On","links":["cc0fc459.d7f3a8"],"x":527,"y":224,"wires":[["91b62e9f.fe736"]]},{"id":"215b93f8.a1883c","type":"comment","z":"daf25abf.0203b8","name":"Demo Mode","info":"","x":102,"y":416,"wires":[]},{"id":"4b308915.771578","type":"http request","z":"daf25abf.0203b8","name":"get presets","method":"GET","ret":"obj","paytoqs":"ignore","url":"http://{{WLED_IP}}/presets.json","tls":"","persist":false,"proxy":"","authType":"","x":278,"y":128,"wires":[["d89db901.9fd588"]]},{"id":"7c6317af.370198","type":"delay","z":"daf25abf.0203b8","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1100,"y":128,"wires":[["539eea44.9b6524"]]},{"id":"aea9da7f.af56a8","type":"ha-entity","z":"daf25abf.0203b8","name":"current preset","server":"","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Holiday Lights Current Preset"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","x":480,"y":368,"wires":[[]]},{"id":"4b02330f.bc08fc","type":"function","z":"daf25abf.0203b8","name":"format","func":"const { idLookup } = flow.get(\\"wledHolidayLightsPresets\\");\\nconst id = msg.data.new_state.attributes.preset || 0;\\nconst presetName = idLookup[id] || \\"none\\";\\n\\nmsg.payload = msg.payload === \\"on\\" ? presetName : \\"none\\";\\n\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":258,"y":368,"wires":[["aea9da7f.af56a8"]]},{"id":"a3f37acd.911a88","type":"server-state-changed","z":"daf25abf.0203b8","name":"Preset Updated","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.holiday_lights","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":112,"y":368,"wires":[["4b02330f.bc08fc"]]},{"id":"dece0bc.3c215f8","type":"debug","z":"daf25abf.0203b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":752,"y":336,"wires":[]},{"id":"c800976d.89af98","type":"change","z":"daf25abf.0203b8","name":"","rules":[{"t":"set","p":"dark","pt":"flow","to":"dark","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":223,"y":272,"wires":[["c46d93f8.1fe18"]],"l":false},{"id":"b1ec00ad.8c8f7","type":"subflow:eb756b3f.d770f8","z":"daf25abf.0203b8","name":"","env":[{"name":"helpers","value":"[{\\"id\\":\\"holiday_lights_demo_mode_delay\\",\\"type\\":\\"input_number\\",\\"name\\":\\"Cycle Delay\\",\\"initial\\":30,\\"min\\":-5,\\"max\\":300,\\"step\\":5,\\"icon\\":\\"mdi:timer-sand\\"},{\\"id\\":\\"holiday_lights_demo_mode\\",\\"type\\":\\"input_select\\",\\"name\\":\\"Mode\\",\\"options\\":[\\"off\\",\\"cycle effects\\",\\"cycle presets\\"],\\"initial\\":\\"off\\",\\"icon\\":\\"mdi:animation\\"},{\\"id\\":\\"holiday_lights_presets\\",\\"type\\":\\"input_select\\",\\"name\\":\\"Presets\\",\\"options\\":[\\"none\\"],\\"icon\\":\\"mdi:animation\\"}]","type":"json"}],"x":346,"y":80,"wires":[]},{"id":"297d2a12.388f86","type":"inject","z":"daf25abf.0203b8","name":"Create HA elements","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":138,"y":80,"wires":[["b1ec00ad.8c8f7"]]}]\n
    ',1),L=s("h2",{id:"requirements",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#requirements","aria-hidden":"true"},"#"),n(" Requirements")],-1),S={href:"https://home-assistant.io",target:"_blank",rel:"noopener noreferrer"},z={href:"https://github.com/Aircoookie/WLED",target:"_blank",rel:"noopener noreferrer"},P=s("h3",{id:"integrations",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#integrations","aria-hidden":"true"},"#"),n(" Integrations")],-1),H={href:"https://www.home-assistant.io/integrations/season/",target:"_blank",rel:"noopener noreferrer"},E={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},C=s("em",null,"custom integration",-1),A={href:"https://github.com/Aircoookie/WLED",target:"_blank",rel:"noopener noreferrer"},U=s("p",null,"The two entity nodes will require the Node-RED custom integration but the flow will function fine without it. The UI just won't have the updated current preset and demo effect displayed.",-1),M=s("h3",{id:"nodes",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#nodes","aria-hidden":"true"},"#"),n(" Nodes")],-1),j={href:"https://flows.nodered.org/node/node-red-contrib-eztimer",target:"_blank",rel:"noopener noreferrer"},N=p('

    Setup

    The flow has been modified so that it should run pretty much out of the box after changing the entity id for the light and IP for the WLED controller.

    1. Setting up WLED variables
    2. Modifing holiday date ranges
    3. Creating Home Assistant entities

    WLED variables

    screenshot of a node that needs to be editted

    Edit the change node, set entity ids here, to edit the Home Assistant entity id of the holiday lights and the select entity for presets. The entity of your WLED light needs to be changed in two places.

    Setting date ranges up

    Holidays can be either a single day or a range of dates. If no holiday is defined for the current day it will default to the season preset WINTER, SPRING, SUMMER, and AUTUMN.

    screenshot of a node that needs to be editted

    In the date ranges node, a lot is going on but the main thing is the switch statement that determines which preset to use.

    The isToday function can take two arguments but only the first one is required which is the start date of the holiday. The second argument is the end date of the holiday. Both of the arguments can take a number in the format of MONTHDAY or a holiday name defined in the getHolidayDate function on line #92.

    Lines 16 - 72

    switch (true) {
    +  // Winter
    +  case isToday(214):
    +    preset = "Valentine";
    +    break;
    +  // President's Day changes every year, Veteran's Day & Flag Day always the same date
    +  case isToday(614): // 6/14 Flag Day
    +  case isToday(1111): // 11/11 Veterans Day
    +  case isToday("President's Day"):
    +  case isToday("Memorial Day"):
    +    preset = "Red, White, and Blue";
    +    break;
    +  case isToday(317):
    +    preset = "St Patty";
    +    break;
    +  case isToday("Easter"):
    +    preset = "Easter";
    +    break;
    +  // Spring
    +  case isToday(504):
    +    preset = "Starwars";
    +    break;
    +  case isToday(505):
    +    preset = "Cinco de Mayo";
    +    break;
    +  // Summer
    +  case isToday(704):
    +    preset = "Independence Day";
    +    break;
    +  // Autumn
    +  case isToday(1017, 1031):
    +    preset = "Halloween";
    +    break;
    +  case isToday("Thanksgiving Day"):
    +    preset = "Autumn";
    +    break;
    +  case isToday(1231):
    +    preset = "New Years";
    +    break;
    +  case isToday("Thanksgiving Day", 1231):
    +  case isToday(101, 106):
    +    const activePreset = states[entityId].attributes.preset;
    +    const presetName = idLookup[activePreset];
    +    preset = getRandomPreset(christmasPresets.filter((e) => e !== presetName));
    +    updateInterval = 60;
    +    break;
    +  default:
    +    const seasons = {
    +      winter: "Winter",
    +      spring: "Spring",
    +      summer: "Summer",
    +      autumn: "Autumn",
    +    };
    +    const currentSeason = states["sensor.season"].state;
    +    preset = seasons[currentSeason];
    +    break;
    +}
    +

    Home Assistant Entities

    `,14),W={href:"https://www.home-assistant.io/integrations/input_select/",target:"_blank",rel:"noopener noreferrer"},$={href:"https://www.home-assistant.io/integrations/input_number/",target:"_blank",rel:"noopener noreferrer"},F=s("code",null,"Configuration > Helpers",-1),O=p(`

    input_number.holiday_lights_demo_mode_delay

    input_number:
    +  holiday_lights_demo_mode_delay:
    +    name: Cycle Delay
    +    initial: 30
    +    min: -5
    +    max: 300
    +    step: 5
    +    icon: "mdi:timer-sand"
    +

    screenshot of lovelace ui

    input_select.holiday_lights_demo_mode

    input_select:
    +  holiday_lights_demo_mode:
    +    name: Mode
    +    options:
    +      - off
    +      - cycle effects
    +      - cycle presets
    +    initial: off
    +    icon: "mdi:animation"
    +

    screenshot of lovelace ui

    Lovelace UI

    screenshot of lovelace ui

    title: Holiday Lights
    +type: entities
    +entities:
    +  - entity: light.holiday_lights
    +  - entity: select.holiday_lights_presets
    +  - type: section
    +    label: Demo Mode
    +  - type: conditional
    +    conditions:
    +      - entity: input_select.holiday_lights_demo_mode
    +        state_not: "off"
    +    row:
    +      entity: sensor.holiday_lights_demo_current
    +  - entity: input_select.holiday_lights_demo_mode
    +  - entity: input_number.holiday_lights_demo_mode_delay
    +

    Things that could have been added but never got around to it

    • Previous and Next button in the demo UI
    `,11);function V(R,G){const a=e("ExternalLinkIcon");return u(),c("div",null,[d,s("div",m,[f,s("p",null,[n("Post questions and follow the discussion about this recipe "),s("a",b,[n("here"),t(a)])])]),s("p",null,[n("Here's a flow to control some outdoor house LEDs hooked up to an ESP8266 running "),s("a",h,[n("WLED"),t(a)]),n(".")]),s("p",null,[n("The holiday lights turn on each day at sunset and then off at midnight. It uses "),s("a",w,[n("WLED"),t(a)]),n(" presets based on the day or season. It has a demo mode that will cycle through all the defined presets or all the included effects.")]),v,s("details",_,[x,s("ul",null,[s("li",null,[s("a",T,[n("Home Assistant"),t(a)]),n(" v0.118+")]),s("li",null,[s("a",D,[n("WLED"),t(a)]),n(" v0.11+")])]),I]),L,s("ul",null,[s("li",null,[s("a",S,[n("Home Assistant"),t(a)]),n(" v2021.7+")]),s("li",null,[s("a",z,[n("WLED"),t(a)]),n(" v0.11+")])]),P,s("ul",null,[s("li",null,[s("a",H,[n("Season"),t(a)])]),s("li",null,[s("a",E,[n("Node-RED"),t(a)]),n(" - "),C])]),s("p",null,[n("The season integration is used to determine the current season and set a "),s("a",A,[n("WLED"),t(a)]),n(" preset if no other holiday range is defined.")]),U,M,s("ul",null,[s("li",null,[s("a",j,[n("eztimer"),t(a)])])]),N,s("p",null,[n("Three entities will need to be created in Home Assistant two "),s("a",W,[n("input_select"),t(a)]),n(" and an "),s("a",$,[n("input_number"),t(a)]),n(". The helpers configuration, "),F,n(", can be used or writing them in YAML.")]),O])}const B=o(g,[["render",V],["__file","holiday-lights-scheduler-and-demo-mode-for-wled.html.vue"]]);export{B as default}; diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled_01-CHAwUUih.png b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_01-CHAwUUih.png new file mode 100644 index 0000000000..5616a60251 Binary files /dev/null and b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_01-CHAwUUih.png differ diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled_02-DLPVHS6D.png b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_02-DLPVHS6D.png new file mode 100644 index 0000000000..344fbc2c77 Binary files /dev/null and b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_02-DLPVHS6D.png differ diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled_03-D-JrQP6b.png b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_03-D-JrQP6b.png new file mode 100644 index 0000000000..e4035c9f73 Binary files /dev/null and b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_03-D-JrQP6b.png differ diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled_05-9II8TJDT.png b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_05-9II8TJDT.png new file mode 100644 index 0000000000..e978664cc1 Binary files /dev/null and b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_05-9II8TJDT.png differ diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled_06-FMERduQa.png b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_06-FMERduQa.png new file mode 100644 index 0000000000..57af27765c Binary files /dev/null and b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_06-FMERduQa.png differ diff --git a/assets/holiday-lights-scheduler-and-demo-mode-for-wled_08-BKy7okvm.png b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_08-BKy7okvm.png new file mode 100644 index 0000000000..452fd8d585 Binary files /dev/null and b/assets/holiday-lights-scheduler-and-demo-mode-for-wled_08-BKy7okvm.png differ diff --git a/assets/index.html-B8GPYcQt.js b/assets/index.html-B8GPYcQt.js new file mode 100644 index 0000000000..a832422e5d --- /dev/null +++ b/assets/index.html-B8GPYcQt.js @@ -0,0 +1,5 @@ +import{_ as i,r as a,o as c,c as d,a as e,d as t,b as n,w as A,e as s}from"./app-DW3AHQOa.js";const l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbgAAABbCAYAAAABbZArAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA6uSURBVHhe7Z3xbxzFFcf7h6ECQSikBQQBV+UiZEUECSIgKHGK2B8wIiENBckWpC45CawgLNVRjGMVKg6ZhoZUgSqCCJ9wTJMSJFuJXYgbHBwbF17nzc7czs7N7e3d7dq+2e9Hekpud252b3f9Pn7jud1fEAAAAOAhEBwAAAAvgeAAAAB4CQQHAADASyA4D1hdXaW5uTmqVqt07tw5BAKB8DY4z3G+47zXDAiuy+GTPD09LU/48vKyWgoAAH7CeY7zHee9ZpKD4LocPtEcAABQJNLkPgiuy+FyHZUbAKBocN7j/JcEBNfl8Jg0AAAUkWb5D4LrciA4AEBRgeA8B4IDABQVCM5zIDgAQFGB4DwHggMAFBUIznMgOABAUelQcPNUCUrU09MTRamXguHPaVG1ABsLBAcAKCodCq5KZZbarn46Uj5C/bsi0e36wxmhvzSwJMV7gkp9+2pZ9FUWWwHtAsEBAIpKJoLrezdU03wliCq51JJTghPtg4rVGoLrmOQTPE9nJ47T8Ymz9edpepKOH5+kafUSAAC6jdwquPSSCwVXLrPMAoo5zhbcfIWCWP9me94X8bpqtJFVodrHuvYC2b9eJ/bBQ5OmEtzx4zRx1jpLEBwAoMvpXHClSBCNIllySnBCLtWyaG8OVZqCU3KLJGQPbSqR2a8Nqcn+dQdOeVoC9IA0gpucZJlNUMxxtuDmz9KEECHLMAyz/TRN8utpo42sCnm5q71A9q/XiX2ASQEAGdOh4IhmhnfVRJYUjSUXCU5LqTZU2WSIUg6JWkIzq7CY0BjuT7Y3txkh+7MXdjmpBCfkMj2ppaQwBafkFknIHtpUIrNfG1KT/esOnPK0BAgAAB3SseCIFunTgZSSE/Kof3iBJRspNVVJOQWnKzMVTQQX+7teTXBWH2YUVHBaSrWhyiZDlPNnJ+qEZlZhMaEx3J9sb24zQvZnLwQAgA7IQHBMOsmlEpygNlQZE1wkJS2tNBVckuA8c5mT9IITSKmpSsopOHPIUUQTwcX+rlcTnNWHGRAcACBDMhIckyy5dEOUmlBAQcCzMpXganKKaF9w4TZj6zylJcEJakOVMcFFUtLSSlPBJQkOLgMA5E2GgmPckks7ySSGrN74/YbgzOFKvb4twan/xyaV+Cm9VgWnZTUxIQSmBVeTU0T7ggu3GVsHAAA5kLHgmLjkUn9NwBacQA5VGlILX6tgUcUk1aLgBPb39nys6FoXnEBWb1yxGYIzhyv1+rYEp/4fm1QC6QEAsicHwTFCckf6qG+gmdxA3rQlOIEcqjSkFr5WwaKKSapFwQlkBaj7EwG5AdACq6u0dvq0egEakZPgwGah2QkGAHQfy4OD9P0tt9Dyk0/S/6qO4S8ggeA8B4IDwC9+/u47+u9tt0nB6bjZ308/XbmiWgANBOc5EBwAfvH9/v0xuem4fvvttPr66/Tz0pJqCSA4z4HgAPCLk8PDdO7BB52Sk3HPPbQ6OqpaFxsIznMgOAD8YklUaGNjY1Teu5em773XLTkRN3bsKPxEFAjOcyA4APxkdnaWjh07RiNPPEGzd97plByHnIjy1VfqXcUCgvMcCA4Av7lw4QL9cWCA/vLII/Qfa/KJGTwRhSeoFAkIznMgOAD8Z21tjT755BMafPFF+vuOHU7BydiypVATUSA4z6lWq7S8vKxeAQB85ubNm1SpVGgwCOjz7dvdkuPgiSjj4+pdfsJ5j/NfEhBclzM3NycDAFAcFhcXaXR0lN58+mm6tG2bW3Ii5EQUUfn5SJrcB8F1OaurqzQ9PS1PNCo5AIrF5cuX6ejRo/Tn3bvpypYtTslx+DQRhfMc5zvOe5z/koDgPIBPMp9wLtd5TBqBQBQr+H6vvxPV3Nj27bRw661OyXHM7ttH50+dcvbRKM5/8IFz+UYF5znOd83kxkBwAADgATwR5aOPPqIjBw7QPx56yCk4GaLSW3njjdQTUb5//PGunbQCwQEAgEfwF8Xfe+89+tP+/TR1331uyXGknIhydds2WurtlU846DYgOAAA8JCrV6/SyMgIHXvqKbq8datbciJ+2LkzcSLKv9RszR/27u06yUFwAADgMRcvXqShoSEaf/TR5Iko+/Y5J6L8u6cnavPcc2ppdwDBAQBAAeAJGkdeeok+6O2la7/8ZUxuZqy88krsjiim4PT6bgGCAwCAgsBfFOeJKIP9/clPLFATUXhI0hYch1zXBUBwAABQMPQTC3giStITC5bEuoUGN3ruhjulQHAAAFBQeCJKmicWNIofJydVT5sTCA4AAAoOP7Hg1VdfbfrEAjv4KeOb+VZgEBwAAACJ+cSCpIkoZrDkNuttwCA4AAAANW5ev04XnnnGKbOGsXUr/XT5suph8wDBAQAAkKydPk1LpZJbYk3i+vbt9NOVK6qnzQEE5wE/XrtGCyfH6WLwLH25sxeBQCBaiku//Q1928YkEzsW7r+fPvv447obJOcRU1NTTW+4DMF1OSy3rw8eoIXxd2hlblYtBQCAdPDfz77ds4fm7r7bKa1WY73uW8nPxGPJJQHBdTlcubHcAACgHfirAvzwVL6d16Hnn5cPUeXZlGfuuoum77jDKbFmsV73reRKLgkIrsvhYUlUbgCALOBH7vBDVHk25YnhN+n3v/4VvfDCC1QWwjrx2GP0t4cfll8MTzPDcj3uWwnBeQ6PnwMAQB7o/DI7O0vnz5+nDz/8UH4x/NChQzQYBPRaqSTvbcmP5XF9UTzv+1ZCcJ4DwQEA8iIpv/DfwPh2X3xvS34sD39R/CVRtfEQ51937pT3urzywAO53rcSgvMcCA4AkBfN8ostGL6ZMw9xnjlzRsrv6NGjUoB5AcF5DgQHAMiLVgW33kBwngPBAQDyokCCu0GzZ96mg3t6qdTTQz09Jerdc5CGT30t1oCNAoIDAORFMQR3Y4aG+0pCakJspV7avXu3jN4Si66HSn3DNNPEctVy2LYWQYXm1TrQPhAcACAvCiC4eaoELLcSBeMztKiWhizSzHggK7pSgrCk3MpV9SokFF6Z4ktBq0BwAIC8WB/BLdGld4fo8OEBGv1iSS1LR8eCWzzVLyuuPeONv0w8O75Htuk/FddfSJXKYp3lN0H98vlKEFZ3MgKq1IzJbctU0euDE3Qi6KEgaiBhaUbLwv5r/Rkb4u0ElUptff2+dQ9tC65alp/dPoZO5isUxM5HHHneUJED4B3rIbibM2M0cPiwEBxHa5LrUHCLonoTEigN0Kfqris3Zt6mPh6aLPXR23pccvVTGuBlIsnVK44rwHBdUgKsS5IyAesKT8nKklS8T26jk7Atz3AfdDIPRdo4YXcT7QkuPB7lsnmME4DgACgk+Qpuib4ce40GRj6jb/75liG5UfpStWhGh4JTYqklrxka7hWveRlH77BYwiiJNUyWVjUlIl41mXKKiCoyW1gCO+myENV+yoRrl2Wyfbh/PiXktgRXOxaO46ow/2YaCBHGBWeez0CIMuF4qm3Vqm8Ou62qJnXo/ak7Tw7R8n669j9sG/VpV6rhLzl6vaNPUeGH799Pg/vr31/E0QLQ/fT3hyNyZvCyRuQnuFBuLw+N0mj5ZUNyA/TmqfS3HtwkgjOIJR7V3kpGZjQUnNqmTjJmwjGTczwgOEZ+fnUw5bGysq5cVjs++txqCYTnopbc9blrdDz1+to2rPfHKnWBbK+2Jf8frdNSinaX+3Jdc/b1En9dd/6tfQivH2u7sc/H/cWPR7St+HUZ7nNcoABsFNVqVf4MmcHLGpGP4LTcxujkWwOqajscSu7qt6pNOjoUXBZDlI0wEoGZ1JzYSSQkSjxmwlEJym5sUJ+wupfWBWcdy7pj7zjWZhtbSILE4+k4t9H5Ca8B53l1rOf3yWHVaEGD8+y+XkLi14qG+479gmS+2f4MvF31eaN9NZDtw2Pk07UG/MCs4pKqNyZ7wbnlxn97a6Vy03QouAwmmTgSoiZKJEkJiWmwXieeSpRwwsXJScWnpNOy4IzkHBKvOGrHNHZwIik4j11dnwaJggvPq/5hi4U62ZF4uK24jrg/tS1e1+iakftp9SWR+2Nsx4iGgrOOUbRPqq2jL33NQ3Bgs2FWcUnVG5Ot4LKVG9Ox4MIf7vBrAn3DVatCW6TqcF+TrwmEyaHuh9xKfGFCMkVoSq2B4HTffLJiK8P2taQtMBONT0mnNcEZx6su1LHfAMHVn1cD3XdNbPwZuD/+1/2LUwz5C1b4GeX14Px8ceoFZ37u6FgwrrYmPl1rwB+4cmtWvTHZCU5NKBkYoqHXspEbk4HgBHl80dtR1dltorzROBHKBOJaJxOZ0Z+RZAoruEbJXR2r8Bg6jrX5PimM+LlLPJ6ObUZSCIVr/iJSD+9POEnFrJrkJBDXBdGAuKDc15LGKS39OQo8WgD8gSu3ZtUbk53gvqCRwyP0Ga3RN+/zd946lxuTjeAkuFXXZqQVwSUlWzOpx9vpqk9LypKSkmPDJJ4oOPnC6Juxpae3H0lJ7l+ipGyJxfsM399otMDavxrRfsTXhe81JW0ev6RjDsBmJ1vBCakNvU9X1y7RSVHFdSo3JkPBgc1IK4KzE3EMSzQyyXMy58Qvp8ybEgqTerhefQWgXcEJtLB02PtYJyRHn3UYQ5MyLGGZn4/DXO0WXLSfdau05HUYx6JOcFYFbK+vaw/ABpK54DKq3DQQnOe0IjgAAGiF7ASXDxCc50BwAIC8gODAhgLBAQDyAoIDGwoEBwDICwgObCgQHAAgLyA4sKFAcACAvIDgwIYCwQEA8gKCAxsKBAcAyAsIDmwoF4NnaWUumy9NAgCAhvMK55ckIDiQKwsnx2lh/B31CgAAsiFNboHgQK78eO0afX3wgLwYUckBADqF8wjnE84rnF+SmJqaosXF9E8BzRLeLm8/CQjOA/gi5N+0eDiBx8wRCASi3eA8wvmkmdyYlZUVKRmupNY7eLu8/SQgOAAAAF4CwQEAAPASCA4AAICXQHAAAAC8BIIDAADgJRAcAAAAL4HgAAAAeAjR/wFApNLoYF88mgAAAABJRU5ErkJggg==",h="/node-red-contrib-home-assistant-websocket/assets/getting-started_03-B4ue_ZcX.png",g="/node-red-contrib-home-assistant-websocket/assets/getting_started_02-7mfV03T6.png",p="/node-red-contrib-home-assistant-websocket/assets/generate-token_01-DB9TrXpw.png",u="/node-red-contrib-home-assistant-websocket/assets/generate-token_02-k2eQmSik.png",m={},k=e("h1",{id:"getting-started",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#getting-started","aria-hidden":"true"},"#"),t(" Getting Started")],-1),f=e("h2",{id:"prerequisites",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#prerequisites","aria-hidden":"true"},"#"),t(" Prerequisites")],-1),w={href:"https://nodered.org/docs/getting-started/installation",target:"_blank",rel:"noopener noreferrer"},B={href:"https://nodejs.org",target:"_blank",rel:"noopener noreferrer"},b={href:"https://nodered.org/",target:"_blank",rel:"noopener noreferrer"},C={href:"https://home-assistant.io",target:"_blank",rel:"noopener noreferrer"},v=e("h2",{id:"installation",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#installation","aria-hidden":"true"},"#"),t(" Installation")],-1),y=e("h3",{id:"using-the-palette-manager",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#using-the-palette-manager","aria-hidden":"true"},"#"),t(" Using the Palette Manager")],-1),Q={href:"https://nodered.org/docs/user-guide/editor/palette/manager",target:"_blank",rel:"noopener noreferrer"},S=s(`
    node-red-contrib-home-assistant-websocket
    +

    Using npm from the command line

    $ cd ~/.node-red
    +$ npm install node-red-contrib-home-assistant-websocket
    +# restart Node-RED
    +

    Home Assistant Add-on

    `,4),E={href:"https://github.com/hassio-addons/addon-node-red#readme",target:"_blank",rel:"noopener noreferrer"},P=s('

    Configuration

    Place an Events: all node onto the workspace and edit the node. Click on the pencil icon next to the Server field.

    screenshot

    Search for a local Home Assistant instance or manually fill in the Base Url.

    screenshot

    Enter an Access Token on the server config node then Add/Update the Server Config and Events: all nodes and deploy. After deploying a green box with a status message, i.e. connected, stated_changed, should appear below the Events: all node. If you see an open box with the status of connecting or disconnected you probably have incorrectly entered the base URL or access token.

    • Base Url is the web address and port you use to access the Home Assistant frontend (e.g., http://localhost:8123, http://192.198.x.x, and http://example.duckdns.org).

    • Access Token is generated in Home Assistant there are instructions below on how to generate one.

    TIP

    Changing the deploy type to Modified Flows or Modified Nodes will make it so when you deploy only the flows that you have modified will get reloaded. This helps if you have other flows on the workspace that you don't want to have reloaded everything time you change something else.

    screenshot

    TIP

    If you find that new entities added to Home Assistant are not showing up in the autocomplete results try unchecking Cache Autocomplete Results in the server config and restarting Node-RED.

    Generate Access Token

    WARNING

    The user used to create the access token must be in the administrator group for this package to function correctly.

    Goto your Home Assistant home page and in the bottom left corner click on the blue circle with the letter in it. In the screenshot below it's the "J".

    screenshot

    • Scroll down to the bottom of the page and it should look like the screenshot below and click on the Create Token Button
    • Give it a name, it can be anything you want to identify it
    • Copy the generated access token into Node-RED

    screenshot

    TIP

    Creating a separate Home Assistant user for Node-RED and using their access token will give you the ability to track which entities were changed by Node-RED.

    TIP

    Once you've configured the WebSocket connection using the Events: all node, this node should be removed for optimal NodeRed performance. Instead, prefer using the other node types provided by this package (Events: state, Trigger: state etc), or add an event type filter to the Events: all node to avoid overloading the websocket message queue.

    ',17);function U(H,N){const o=a("ExternalLinkIcon"),r=a("RouterLink");return c(),d("div",null,[k,f,e("p",null,[t("Have Node-RED installed and working, if you need to install Node-RED see "),e("a",w,[t("here"),n(o)]),t(".")]),e("ul",null,[e("li",null,[e("a",B,[t("Node.js"),n(o)]),t(" v14.0+")]),e("li",null,[e("a",b,[t("Node-RED"),n(o)]),t(" v3.0.0+")]),e("li",null,[e("a",C,[t("Home Assistant"),n(o)]),t(" v2021.3.0+")])]),v,y,e("p",null,[t("Search in the "),e("a",Q,[t("Palette Manager"),n(o)]),t(" for:")]),S,e("p",null,[t("The Community Home Assistant add-on ships with this set of nodes right out of the box and comes configured to connect to Home Assistant. No other information is needed and you're ready to start your "),n(r,{to:"/guide/first-automation.html"},{default:A(()=>[t("first automation")]),_:1}),t(".")]),e("p",null,[t("The add-on can be found here: "),e("a",E,[t("https://github.com/hassio-addons/addon-node-red#readme"),n(o)])]),P])}const I=i(m,[["render",U],["__file","index.html.vue"]]);export{I as default}; diff --git a/assets/index.html-BOJH-tw9.js b/assets/index.html-BOJH-tw9.js new file mode 100644 index 0000000000..a3d030d37e --- /dev/null +++ b/assets/index.html-BOJH-tw9.js @@ -0,0 +1 @@ +import{_ as s,r as a,o as r,c as d,a as o,d as t,b as e,w as l}from"./app-DW3AHQOa.js";const c="/node-red-contrib-home-assistant-websocket/assets/index_import_screenshot-B6IPVgb8.png",u={},h=o("h1",{id:"cookbook",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#cookbook","aria-hidden":"true"},"#"),t(" Cookbook")],-1),k=o("p",null,"Here is a collection of beginner to advanced flows and explanations to help you further educate yourself in the world of Home Automation with Node-RED.",-1),_=o("p",null,"All JSON exports are also available under the examples tab in the Node-RED import menu.",-1),f=o("p",null,[o("img",{src:c,alt:"screenshot"})],-1),m=o("p",null,[o("strong",null,"Also see:")],-1),g={href:"https://nodered.org/docs/user-guide/editor/workspace/import-export",target:"_blank",rel:"noopener noreferrer"};function b(p,w){const n=a("RouterLink"),i=a("ExternalLinkIcon");return r(),d("div",null,[h,k,o("ul",null,[o("li",null,[t("JSONata Examples "),o("ul",null,[o("li",null,[e(n,{to:"/cookbook/jsonata/call-service.html"},{default:l(()=>[t("Call Service node")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/jsonata/change-node.html"},{default:l(()=>[t("Change Node")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/jsonata/events-state.html"},{default:l(()=>[t("Events: state node")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/jsonata/functions.html"},{default:l(()=>[t("Functions")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/jsonata/sensor.html"},{default:l(()=>[t("Sensor Node")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/jsonata/switch-node.html"},{default:l(()=>[t("Switch Node")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/jsonata/trigger-state.html"},{default:l(()=>[t("Trigger state node")]),_:1})])])]),o("li",null,[e(n,{to:"/cookbook/motion-triggered-light.html"},{default:l(()=>[t("Motion Triggered Light")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/saving-and-restoring-states.html"},{default:l(()=>[t("Saving and Restoring States")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/get-state_changed-events-based-on-area.html"},{default:l(()=>[t("Get state_changed Events Based on Area")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/sun-events.html"},{default:l(()=>[t("Turn Light On/Off with Sunset/Sunrise")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/vacation-mode.html"},{default:l(()=>[t("Vacation Mode")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/expiration-date-monitor.html"},{default:l(()=>[t("Expiration Date Monitor")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/using-date-and-time-entities-to-trigger-flows.html"},{default:l(()=>[t("Using date and time entities to trigger flows")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html"},{default:l(()=>[t("Check if an entity was a certain state in the last 24 hours")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/starting-flow-after-home-assistant-restart.html"},{default:l(()=>[t("Starting flow after Home Assistant restart")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.html"},{default:l(()=>[t("Holiday lights scheduler and demo mode for WLED")]),_:1})]),o("li",null,[e(n,{to:"/cookbook/actionable-notifications-subflow-for-android.html"},{default:l(()=>[t("Actionable Notifications Subflow for Android")]),_:1})])]),_,f,m,o("ul",null,[o("li",null,[o("a",g,[t("Importing and Exporting Flows"),e(i)])])])])}const v=s(u,[["render",b],["__file","index.html.vue"]]);export{v as default}; diff --git a/assets/index.html-BhVmmYi-.js b/assets/index.html-BhVmmYi-.js new file mode 100644 index 0000000000..86a5681808 --- /dev/null +++ b/assets/index.html-BhVmmYi-.js @@ -0,0 +1 @@ +import{_ as d,r as i,o as h,c as r,a as e,d as t,b as n,w as s}from"./app-DW3AHQOa.js";const c={},l=e("h1",{id:"nodes",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#nodes","aria-hidden":"true"},"#"),t(" Nodes")],-1),_={id:"action",tabindex:"-1"},u=e("a",{class:"header-anchor",href:"#action","aria-hidden":"true"},"#",-1),f=e("p",null,[t("Sends a request to Home Assistant to perform an action e.g. "),e("code",null,"light.turn_on"),t(", "),e("code",null,"input_select.select_option"),t(", etc.")],-1),m={id:"api",tabindex:"-1"},p=e("a",{class:"header-anchor",href:"#api","aria-hidden":"true"},"#",-1),b=e("p",null,"Access all points of the WebSocket and HTTP API.",-1),g={id:"binary-sensor",tabindex:"-1"},v=e("a",{class:"header-anchor",href:"#binary-sensor","aria-hidden":"true"},"#",-1),x=e("p",null,"Creates a binary sensor entity in Home Assistant that is controlled from with Node-RED.",-1),w={id:"button",tabindex:"-1"},y=e("a",{class:"header-anchor",href:"#button","aria-hidden":"true"},"#",-1),A=e("p",null,"Creates a button in Home Assistant that triggers a flow in Node-RED",-1),C={id:"current-state",tabindex:"-1"},H=e("a",{class:"header-anchor",href:"#current-state","aria-hidden":"true"},"#",-1),k=e("p",null,"Fetches the last known state for any entity on input",-1),E={id:"device",tabindex:"-1"},S=e("a",{class:"header-anchor",href:"#device","aria-hidden":"true"},"#",-1),N=e("p",null,"Creates device automations and calls device actions",-1),T={id:"device-config",tabindex:"-1"},R=e("a",{class:"header-anchor",href:"#device-config","aria-hidden":"true"},"#",-1),D=e("p",null,"Configuration node for devices added to Home Assistant",-1),L={id:"entity",tabindex:"-1"},B=e("a",{class:"header-anchor",href:"#entity","aria-hidden":"true"},"#",-1),I=e("p",null,"Creates an entity in Home Assistant which can be manipulated from this node",-1),P={id:"entity-config",tabindex:"-1"},z=e("a",{class:"header-anchor",href:"#entity-config","aria-hidden":"true"},"#",-1),F=e("p",null,"Configuration node for the different entity type nodes",-1),O={id:"events-all",tabindex:"-1"},W=e("a",{class:"header-anchor",href:"#events-all","aria-hidden":"true"},"#",-1),G=e("p",null,"Listens for all types of events from home assistant with the ability to filter by event type",-1),V={id:"events-state",tabindex:"-1"},U=e("a",{class:"header-anchor",href:"#events-state","aria-hidden":"true"},"#",-1),q=e("p",null,"Listens for state changes of entities from Home Assistant.",-1),M={id:"fire-event",tabindex:"-1"},Z=e("a",{class:"header-anchor",href:"#fire-event","aria-hidden":"true"},"#",-1),j=e("p",null,"Fire an event on the event bus",-1),J={id:"get-entities",tabindex:"-1"},K=e("a",{class:"header-anchor",href:"#get-entities","aria-hidden":"true"},"#",-1),Q=e("p",null,"Get entities based on search criteria with 3 different output options",-1),X={id:"get-history",tabindex:"-1"},Y=e("a",{class:"header-anchor",href:"#get-history","aria-hidden":"true"},"#",-1),$=e("p",null,"Fetches HomeAssistant history on input",-1),ee={id:"number",tabindex:"-1"},te=e("a",{class:"header-anchor",href:"#number","aria-hidden":"true"},"#",-1),ne=e("p",null,"Creates a number in Home Assistant which can be manipulated from this node.",-1),oe={id:"poll-state",tabindex:"-1"},se=e("a",{class:"header-anchor",href:"#poll-state","aria-hidden":"true"},"#",-1),ae=e("p",null,"Outputs the state of an entity at regular intervals, optionally also at startup and every time the entity changes if desired",-1),ie={id:"render-template",tabindex:"-1"},de=e("a",{class:"header-anchor",href:"#render-template","aria-hidden":"true"},"#",-1),he=e("p",null,"Allows rendering of templates on input",-1),re={id:"select",tabindex:"-1"},ce=e("a",{class:"header-anchor",href:"#select","aria-hidden":"true"},"#",-1),le=e("p",null,"Creates a select entity in Home Assistant which can be manipulated from this node.",-1),_e={id:"sensor",tabindex:"-1"},ue=e("a",{class:"header-anchor",href:"#sensor","aria-hidden":"true"},"#",-1),fe=e("p",null,"Creates a sensor entity in Home Assistant that is controlled from with Node-RED.",-1),me={id:"sentence",tabindex:"-1"},pe=e("a",{class:"header-anchor",href:"#sentence","aria-hidden":"true"},"#",-1),be={href:"https://www.home-assistant.io/voice_control/",target:"_blank",rel:"noopener noreferrer"},ge={href:"https://www.home-assistant.io/integrations/conversation/",target:"_blank",rel:"noopener noreferrer"},ve={id:"server-config",tabindex:"-1"},xe=e("a",{class:"header-anchor",href:"#server-config","aria-hidden":"true"},"#",-1),we=e("p",null,"Home Assistant connection configuration",-1),ye={id:"switch",tabindex:"-1"},Ae=e("a",{class:"header-anchor",href:"#switch","aria-hidden":"true"},"#",-1),Ce=e("p",null,"Creates a switch entity in Home Assistant that is controlled from with Node-RED. Also allows a flow to be started from a service call.",-1),He={id:"tag",tabindex:"-1"},ke=e("a",{class:"header-anchor",href:"#tag","aria-hidden":"true"},"#",-1),Ee=e("p",null,"Outputs when Home Assistant receives a tag scanned event for a configured tag id",-1),Se={id:"text",tabindex:"-1"},Ne=e("a",{class:"header-anchor",href:"#text","aria-hidden":"true"},"#",-1),Te=e("p",null,"Creates a text entity in Home Assistant which can be manipulated from this node.",-1),Re={id:"time",tabindex:"-1"},De=e("a",{class:"header-anchor",href:"#time","aria-hidden":"true"},"#",-1),Le=e("p",null,"A node that can be scheduled to trigger at a future date and time from a Home Assistant entity",-1),Be={id:"trigger-state",tabindex:"-1"},Ie=e("a",{class:"header-anchor",href:"#trigger-state","aria-hidden":"true"},"#",-1),Pe=e("p",null,[t("Much like the "),e("code",null,"State Changed Node"),t(" however, provides some advanced functionality around common automation use cases")],-1),ze={id:"update-config",tabindex:"-1"},Fe=e("a",{class:"header-anchor",href:"#update-config","aria-hidden":"true"},"#",-1),Oe=e("p",null,"Allows updating of entities configuration in Home Assistant",-1),We={id:"wait-until",tabindex:"-1"},Ge=e("a",{class:"header-anchor",href:"#wait-until","aria-hidden":"true"},"#",-1),Ve=e("p",null,"When an input is received the node will wait until the condition is met or the timeout occurs then will pass on the last received message",-1),Ue={id:"webhook",tabindex:"-1"},qe=e("a",{class:"header-anchor",href:"#webhook","aria-hidden":"true"},"#",-1),Me=e("p",null,"Outputs the data received from the created webhook in Home Assistant",-1),Ze={id:"zone",tabindex:"-1"},je=e("a",{class:"header-anchor",href:"#zone","aria-hidden":"true"},"#",-1),Je=e("p",null,"Outputs when one of the configured entities enter or leaves one of the defined zones",-1);function Ke(Qe,Xe){const o=i("RouterLink"),a=i("ExternalLinkIcon");return h(),r("div",null,[l,e("h2",_,[u,t(),n(o,{to:"/node/action.html"},{default:s(()=>[t("Action")]),_:1})]),f,e("h2",m,[p,t(),n(o,{to:"/node/API.html"},{default:s(()=>[t("API")]),_:1})]),b,e("h2",g,[v,t(),n(o,{to:"/node/binary-sensor.html"},{default:s(()=>[t("Binary Sensor")]),_:1})]),x,e("h2",w,[y,t(),n(o,{to:"/node/button.html"},{default:s(()=>[t("Button")]),_:1})]),A,e("h2",C,[H,t(),n(o,{to:"/node/current-state.html"},{default:s(()=>[t("Current State")]),_:1})]),k,e("h2",E,[S,t(),n(o,{to:"/node/device.html"},{default:s(()=>[t("Device")]),_:1})]),N,e("h2",T,[R,t(),n(o,{to:"/node/device-config.html"},{default:s(()=>[t("Device Config")]),_:1})]),D,e("h2",L,[B,t(),n(o,{to:"/node/entity.html"},{default:s(()=>[t("Entity")]),_:1})]),I,e("h2",P,[z,t(),n(o,{to:"/node/entity-config.html"},{default:s(()=>[t("Entity Config")]),_:1})]),F,e("h2",O,[W,t(),n(o,{to:"/node/events-all.html"},{default:s(()=>[t("Events: all")]),_:1})]),G,e("h2",V,[U,t(),n(o,{to:"/node/events-state.html"},{default:s(()=>[t("Events: state")]),_:1})]),q,e("h2",M,[Z,t(),n(o,{to:"/node/fire-event.html"},{default:s(()=>[t("Fire Event")]),_:1})]),j,e("h2",J,[K,t(),n(o,{to:"/node/get-entities.html"},{default:s(()=>[t("Get Entities")]),_:1})]),Q,e("h2",X,[Y,t(),n(o,{to:"/node/get-history.html"},{default:s(()=>[t("Get History")]),_:1})]),$,e("h2",ee,[te,t(),n(o,{to:"/node/number.html"},{default:s(()=>[t("Number")]),_:1})]),ne,e("h2",oe,[se,t(),n(o,{to:"/node/poll-state.html"},{default:s(()=>[t("Poll State")]),_:1})]),ae,e("h2",ie,[de,t(),n(o,{to:"/node/render-template.html"},{default:s(()=>[t("Render Template")]),_:1})]),he,e("h2",re,[ce,t(),n(o,{to:"/node/select.html"},{default:s(()=>[t("Select")]),_:1})]),le,e("h2",_e,[ue,t(),n(o,{to:"/node/sensor.html"},{default:s(()=>[t("Sensor")]),_:1})]),fe,e("h2",me,[pe,t(),n(o,{to:"/node/sentence.html"},{default:s(()=>[t("Sentence")]),_:1})]),e("p",null,[t("A sentence trigger fires when "),e("a",be,[t("Assist"),n(a)]),t(" matches a sentence from a voice assistant using the default "),e("a",ge,[t("conversation agent"),n(a)]),t(".")]),e("h2",ve,[xe,t(),n(o,{to:"/node/config-server.html"},{default:s(()=>[t("Server Config")]),_:1})]),we,e("h2",ye,[Ae,t(),n(o,{to:"/node/switch.html"},{default:s(()=>[t("Switch")]),_:1})]),Ce,e("h2",He,[ke,t(),n(o,{to:"/node/tag.html"},{default:s(()=>[t("Tag")]),_:1})]),Ee,e("h2",Se,[Ne,t(),n(o,{to:"/node/text.html"},{default:s(()=>[t("Text")]),_:1})]),Te,e("h2",Re,[De,t(),n(o,{to:"/node/time.html"},{default:s(()=>[t("Time")]),_:1})]),Le,e("h2",Be,[Ie,t(),n(o,{to:"/node/trigger-state.html"},{default:s(()=>[t("Trigger: state")]),_:1})]),Pe,e("h2",ze,[Fe,t(),n(o,{to:"/node/update-config.html"},{default:s(()=>[t("Update Config")]),_:1})]),Oe,e("h2",We,[Ge,t(),n(o,{to:"/node/wait-until.html"},{default:s(()=>[t("Wait Until")]),_:1})]),Ve,e("h2",Ue,[qe,t(),n(o,{to:"/node/webhook.html"},{default:s(()=>[t("Webhook")]),_:1})]),Me,e("h2",Ze,[je,t(),n(o,{to:"/node/zone.html"},{default:s(()=>[t("Zone")]),_:1})]),Je])}const $e=d(c,[["render",Ke],["__file","index.html.vue"]]);export{$e as default}; diff --git a/assets/index.html-BqcXEfG9.js b/assets/index.html-BqcXEfG9.js new file mode 100644 index 0000000000..ee72d11804 --- /dev/null +++ b/assets/index.html-BqcXEfG9.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-e0a0c596","path":"/guide/jsonata/","title":"JSONata","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Examples of using JSONata in the Home Assistant Nodes:","slug":"examples-of-using-jsonata-in-the-home-assistant-nodes","link":"#examples-of-using-jsonata-in-the-home-assistant-nodes","children":[]},{"level":2,"title":"Home Assistant functions","slug":"home-assistant-functions","link":"#home-assistant-functions","children":[]},{"level":2,"title":"Exposed Lodash functions","slug":"exposed-lodash-functions","link":"#exposed-lodash-functions","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"guide/jsonata/index.md"}');export{e as data}; diff --git a/assets/index.html-Bw0kX1wh.js b/assets/index.html-Bw0kX1wh.js new file mode 100644 index 0000000000..a5a2d94ce7 --- /dev/null +++ b/assets/index.html-Bw0kX1wh.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-15051314","path":"/node/","title":"Nodes","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Action","slug":"action","link":"#action","children":[]},{"level":2,"title":"API","slug":"api","link":"#api","children":[]},{"level":2,"title":"Binary Sensor","slug":"binary-sensor","link":"#binary-sensor","children":[]},{"level":2,"title":"Button","slug":"button","link":"#button","children":[]},{"level":2,"title":"Current State","slug":"current-state","link":"#current-state","children":[]},{"level":2,"title":"Device","slug":"device","link":"#device","children":[]},{"level":2,"title":"Device Config","slug":"device-config","link":"#device-config","children":[]},{"level":2,"title":"Entity","slug":"entity","link":"#entity","children":[]},{"level":2,"title":"Entity Config","slug":"entity-config","link":"#entity-config","children":[]},{"level":2,"title":"Events: all","slug":"events-all","link":"#events-all","children":[]},{"level":2,"title":"Events: state","slug":"events-state","link":"#events-state","children":[]},{"level":2,"title":"Fire Event","slug":"fire-event","link":"#fire-event","children":[]},{"level":2,"title":"Get Entities","slug":"get-entities","link":"#get-entities","children":[]},{"level":2,"title":"Get History","slug":"get-history","link":"#get-history","children":[]},{"level":2,"title":"Number","slug":"number","link":"#number","children":[]},{"level":2,"title":"Poll State","slug":"poll-state","link":"#poll-state","children":[]},{"level":2,"title":"Render Template","slug":"render-template","link":"#render-template","children":[]},{"level":2,"title":"Select","slug":"select","link":"#select","children":[]},{"level":2,"title":"Sensor","slug":"sensor","link":"#sensor","children":[]},{"level":2,"title":"Sentence","slug":"sentence","link":"#sentence","children":[]},{"level":2,"title":"Server Config","slug":"server-config","link":"#server-config","children":[]},{"level":2,"title":"Switch","slug":"switch","link":"#switch","children":[]},{"level":2,"title":"Tag","slug":"tag","link":"#tag","children":[]},{"level":2,"title":"Text","slug":"text","link":"#text","children":[]},{"level":2,"title":"Time","slug":"time","link":"#time","children":[]},{"level":2,"title":"Trigger: state","slug":"trigger-state","link":"#trigger-state","children":[]},{"level":2,"title":"Update Config","slug":"update-config","link":"#update-config","children":[]},{"level":2,"title":"Wait Until","slug":"wait-until","link":"#wait-until","children":[]},{"level":2,"title":"Webhook","slug":"webhook","link":"#webhook","children":[]},{"level":2,"title":"Zone","slug":"zone","link":"#zone","children":[]}],"git":{"updatedTime":1722853970000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":14}]},"filePathRelative":"node/README.md"}');export{e as data}; diff --git a/assets/index.html-CDTosV2S.js b/assets/index.html-CDTosV2S.js new file mode 100644 index 0000000000..ade9636a43 --- /dev/null +++ b/assets/index.html-CDTosV2S.js @@ -0,0 +1 @@ +import{_ as r,r as i,o as d,c as u,a as e,b as n,w as a,d as t,e as l}from"./app-DW3AHQOa.js";const c={},h=l('

    JSONata

    JSONata is a functional declarative language, designed to work with JSON objects. It is built-in within Node-RED and is available in standard nodes where you see the J: expression option, for example in the Inject Node.

    • JSONata code is written as a line expression, which is evaluated and returns the result.
    • The expression is evaluated against a JSON object. In Node-RED this JSON is the top level message object. There is no need to use a leading 'msg.' therefore just payload will evaluate as the message payload value, and topic as the topic value.

    WARNING

    JSONata is very different to Mustache templates, and the use of {{msg.payload}} will not work as you might expect.

    In the Home Assistant nodes, JSONata can be used to set entity states, set output property values, generate UI parameters, or as conditional tests (both generating the test value, and as an evaluated predicate expression).

    Examples of using JSONata in the Home Assistant Nodes:

    ',6),p=e("ul",null,[e("li",null,"Increase light brightness with remote"),e("li",null,"Set A/C target temperature and hvac mode"),e("li",null,"Send 'lights on' notification when leaving home"),e("li",null,"Extract weather forecast details from call return")],-1),f=e("ul",null,[e("li",null,"Report difference between A/C current and target temperatures"),e("li",null,"Report if A/C been cooling for more than 2 hours before 17:00"),e("li",null,"Report if A/C unit is running outside of 'office hours'")],-1),m=e("ul",null,[e("li",null,"Motion detection start, and motion ending only before 08:30 and after 17:30"),e("li",null,"Switch just turned off, and has been on for less than three minutes"),e("li",null,"Motion detection only before dawn and after dusk, with dusk and dawn times output")],-1),_=e("ul",null,[e("li",null,"Every minute before and after sunset"),e("li",null,"Automation events just before, at, and just after sunset"),e("li",null,"Adjust light brightness from 0 to 100 percent over sunset")],-1),g=e("ul",null,[e("li",null,"Provide a sensor with a count of the number of lights that are on"),e("li",null,"Provide an attribute array (list) of the lights that are on"),e("li",null,"Since I last looked, list which lights have been turned on, or off")],-1),b=e("ul",null,[e("li",null,"Select flow routing depending on state 'last changed ms' period in minutes")],-1),v=e("ul",null,[e("li",null,"Calculate when, and for how long, I have not been at home in the past week")],-1),k=e("ul",null,[e("li",null,"Reading node entity states and attributes"),e("li",null,"Reading all Home Assistant entities"),e("li",null,"Reading Areas, Devices, and their Entities")],-1),w=l('

    Home Assistant functions

    There are several additional Home Assistant functions added for use in JSONata expressions, and these can only be used within the Home Assistant nodes.

    • $entity() returns the entity that triggered the node

    • $prevEntity() returns the previous state entity if the node is an event node

    • $areaDevices(areaId) returns all devices associated with a specific area ID.

    • $areaEntities(areaId) returns all entities associated with a specific area ID.

    • $areas(lookup) returns an area based on a provided lookup value, or all areas if no lookup value is provided. The lookup value can be an area ID, an entity ID, or a device ID.

    • $deviceEntities(device_id) returns all entities associated with a specific device.

    • $device(lookup) returns a device based on a provided lookup value. The lookup value can be an entity ID or a device name.

    • $entities() returns all entities in the cache

    • $entities(entity_id) returns a single entity from cache matching the given entity_id

    ',3),y={id:"exposed-lodash-functions",tabindex:"-1"},x=e("a",{class:"header-anchor",href:"#exposed-lodash-functions","aria-hidden":"true"},"#",-1),j={href:"https://lodash.com/",target:"_blank",rel:"noopener noreferrer"},N=e("code",null,"$sampleSize(collection, [n=1])",-1),S={href:"https://lodash.com/docs/#sampleSize",target:"_blank",rel:"noopener noreferrer"},I=e("p",null,"Gets n random elements at unique keys from collection up to the size of collection.",-1),A=e("code",null,"$randomNumber([lower=0], [upper=1], [floating])",-1),J={href:"https://lodash.com/docs/#random",target:"_blank",rel:"noopener noreferrer"},R=e("p",null,"Produces a random number between the inclusive lower and upper bounds. If only one argument is provided a number between 0 and the given number is returned. If floating is true, or either lower or upper are floats, a floating-point number is returned instead of an integer.",-1),E=e("p",null,[e("strong",null,"Also see:")],-1),O={href:"https://docs.jsonata.org",target:"_blank",rel:"noopener noreferrer"},$={href:"http://try.jsonata.org",target:"_blank",rel:"noopener noreferrer"};function D(C,H){const o=i("RouterLink"),s=i("ExternalLinkIcon");return d(),u("div",null,[h,e("ol",null,[e("li",null,[n(o,{to:"/cookbook/jsonata/call-service.html"},{default:a(()=>[t("Call a service using JSONata to build the data object")]),_:1}),p]),e("li",null,[n(o,{to:"/cookbook/jsonata/current-state.html"},{default:a(()=>[t("Read the current state or attribute value of an entity")]),_:1}),f]),e("li",null,[n(o,{to:"/cookbook/jsonata/events-state.html"},{default:a(()=>[t("Listen for entity state or attribute changes")]),_:1}),m]),e("li",null,[n(o,{to:"/cookbook/jsonata/trigger-state.html"},{default:a(()=>[t("Trigger a flow from state change conditions")]),_:1}),_]),e("li",null,[n(o,{to:"/cookbook/jsonata/sensor.html"},{default:a(()=>[t("Write state and attribute values to an HA sensor")]),_:1}),g]),e("li",null,[n(o,{to:"/cookbook/jsonata/switch-node.html"},{default:a(()=>[t("Route flow (switch node) based on computed outcomes")]),_:1}),b]),e("li",null,[n(o,{to:"/cookbook/jsonata/change-node.html"},{default:a(()=>[t("Read state history and process the return JSON (change node)")]),_:1}),v]),e("li",null,[n(o,{to:"/cookbook/jsonata/functions.html"},{default:a(()=>[t("Using the additional $entity() functions in JSONata")]),_:1}),k])]),w,e("h2",y,[x,t(" Exposed "),e("a",j,[t("Lodash"),n(s)]),t(" functions")]),e("ul",null,[e("li",null,[e("p",null,[N,t(),e("a",S,[t("https://lodash.com/docs/#sampleSize"),n(s)])]),I]),e("li",null,[e("p",null,[A,t(),e("a",J,[t("https://lodash.com/docs/#random"),n(s)])]),R])]),E,e("ul",null,[e("li",null,[e("a",O,[t("https://docs.jsonata.org"),n(s)])]),e("li",null,[e("a",$,[t("http://try.jsonata.org"),n(s)])])])])}const L=r(c,[["render",D],["__file","index.html.vue"]]);export{L as default}; diff --git a/assets/index.html-CWawZjlF.js b/assets/index.html-CWawZjlF.js new file mode 100644 index 0000000000..98a38afea0 --- /dev/null +++ b/assets/index.html-CWawZjlF.js @@ -0,0 +1 @@ +import{_ as o,r,o as t,c as a,b as s,e as d}from"./app-DW3AHQOa.js";const c={},l=d('

    Scrubber

    What does this do?

    • Makes your exported flow a little more friendly to other users
    • Clears all references to the Home Assistant server
    • Clears lat, lon, latitude, and longitude properties from all nodes
    ',3);function i(n,h){const e=r("scrubber");return t(),a("div",null,[l,s(e)])}const _=o(c,[["render",i],["__file","index.html.vue"]]);export{_ as default}; diff --git a/assets/index.html-CqxUbxbp.js b/assets/index.html-CqxUbxbp.js new file mode 100644 index 0000000000..4c1494d36f --- /dev/null +++ b/assets/index.html-CqxUbxbp.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-28c12b06","path":"/guide/custom_integration/","title":"Getting Started","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Installation","slug":"installation","link":"#installation","children":[]},{"level":2,"title":"Tip","slug":"tip","link":"#tip","children":[]}],"git":{"updatedTime":1689312073000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"guide/custom_integration/README.md"}');export{t as data}; diff --git a/assets/index.html-DEOTEIXH.js b/assets/index.html-DEOTEIXH.js new file mode 100644 index 0000000000..19b3669cbb --- /dev/null +++ b/assets/index.html-DEOTEIXH.js @@ -0,0 +1 @@ +import{_ as e,o as c,c as t}from"./app-DW3AHQOa.js";const n={};function _(o,r){return c(),t("div")}const a=e(n,[["render",_],["__file","index.html.vue"]]);export{a as default}; diff --git a/assets/index.html-DTszCqDu.js b/assets/index.html-DTszCqDu.js new file mode 100644 index 0000000000..0338e34a91 --- /dev/null +++ b/assets/index.html-DTszCqDu.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8daa1a0e","path":"/","title":"","lang":"en-US","frontmatter":{"home":true,"heroImage":null,"heroText":"Home Assistant nodes for Node-RED","tagline":"A collection of nodes to integrate Home Assistant Core with Node-RED","actionText":"Get Started →","actionLink":"/guide/"},"headers":[],"git":{"updatedTime":1621121322000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"README.md"}');export{e as data}; diff --git a/assets/index.html-DwBRaoZp.js b/assets/index.html-DwBRaoZp.js new file mode 100644 index 0000000000..8eb8d49c70 --- /dev/null +++ b/assets/index.html-DwBRaoZp.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-21070556","path":"/scrubber/","title":"Scrubber","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"What does this do?","slug":"what-does-this-do","link":"#what-does-this-do","children":[]}],"git":{"updatedTime":1609544135000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"scrubber/index.md"}');export{e as data}; diff --git a/assets/index.html-WMUoZnqy.js b/assets/index.html-WMUoZnqy.js new file mode 100644 index 0000000000..19e0c89b66 --- /dev/null +++ b/assets/index.html-WMUoZnqy.js @@ -0,0 +1 @@ +const o=JSON.parse('{"key":"v-0b911545","path":"/cookbook/","title":"Cookbook","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1707326986000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":14},{"name":"Chris Chisholm","email":"chisholm@blueworld.ca","commits":1}]},"filePathRelative":"cookbook/README.md"}');export{o as data}; diff --git a/assets/index.html-XbMl3aUj.js b/assets/index.html-XbMl3aUj.js new file mode 100644 index 0000000000..cd3977bd2e --- /dev/null +++ b/assets/index.html-XbMl3aUj.js @@ -0,0 +1 @@ +import{_ as r,r as s,o as i,c as o,a as e,d as t,b as a}from"./app-DW3AHQOa.js";const A="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbYAAABrCAYAAAAb3qc1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAgGSURBVHhe7d3BixvnGQfg/mGBJIfgSyCX7CGEQHKK8y/s5hD2kIChUHyM91DINZccvOhgl7bUNyPWbA6h7KGHQuoNrkmMsFOr+apPGq1GI438rbXdnXn3eeCFyDOaGfkd3p++sbP+XQKAQAQbAKEINgBCEWwAhCLYAAhFsAEQimADIBTBBkAogg2AUAQbAKEIto777cmT9OL27TT69NP0yxtvKKVU+Bp98kl6/uWXafz999UkPB/B1mH/OTxMv9y4sbbxSil1HerFN99UE7GcYOuo//74Y/r57bfXNloppa5TjYfDajKWEWwd9fMXX6xtsFJKXbf698cfV5OxjGDrqH+9995SY//y4YfpD7u7aX9/XymlwtbvP/88fXvz5tL8e/rmm9VkLCPYOqre1Fz3vvsuPX36tNoKENOzZ8/S0dHRygw8D8HWUc2mPn/+vNoCEF9zBp6HYOuobZoK0HfbzEDB1lHbNBWg77aZgYKto0qbOhqN0snJSRoOh+nhw4dKKdWryrMrz7A8y+pKZ+A6gq2jSpqab4R8U5yenqbxeFz9KkB/5NmVZ1ieZfVwK5mBbQRbR5U0NX/LyTcEQN/lWZZn2lzJDGwj2DqqpKn5G46VGhBBnmV5ps2VzMA2gq2jSpqan08DRFGfaSUzsI1g66iSpgo2IBLBFlxJUwUbEIlgC66kqYINiESwBVfSVMEGRCLYgitpqmADIhFswZU0VbABkVxSsD1Og92dtLOzrg7ScbVX0/GdyfY7bVu38/hwL+3sDiZXNnE6SHs7e2kQ8P9RLmmqYAMiudRgO3hUvewAwbYg2IBIuhNsOVwmQTPIq7S8kpus1FZWbI8OllZ79ePlffcOB+mgZftkj9q2vXRwZ32wra4SZ9e+dzjdc9n0fQdpkENyfuz5MSvT452dd1K1Y8+u+bi2mq1dQ7X/8nkbK9/GudYpaapgAyLpVrA1BvlSyExDrfbYsrHKmoXB4vV0RXa2/yzUzo5dnWvtim3teVoel86PcxZWy+eZXlM9fKpgnv8+NK95Hmhn17l0LasBu/T706KkqYINiORSg+1spXFWi6HeDKpsMbjXB+M0vKrBvjLkN4XVRPujyFk4zc9VP8eKjde8zvKxV/Zduc68f+0zrKzQattblDRVsAGRdGzF1hYSs0BYDcZJVcGwKdiWQmyuHhSNc+dj1VddrdddGGyz1ePimjcG29J1LoKreYxFLZ+/qaSpgg2IpFfBtun9KyGxRbAttuXztjyGzF4RbIswmh9j+XOcO9ian6FASVMFGxBJT4Jt9v76ny81bQq2aWAUP4rMqkA5nLyvfsymgmte/syvH2zrPkOJkqYKNiCSngTbxHSw17cvh93GYGvsO9s22b812KrjvWKVWBJsizCeva4f81zBNn9/c/9XhF1JUwUbEEl/gm2i+edM9RXc5mDLZqul2Xurv6K/IdiKVkivuubp9vk58+dfDqfzBVtW/wy5Xr2CK2mqYAMiuaRg66EcMvXQ6amSpgo2IBLB1iKvpjauMHuipKmCDYhEsDXNHx8GWK1lJU0VbEAkgi24kqYKNiASwRZcSVMFGxCJYAuupKmCDYhEsAVX0lTBBkQi2IIraapgAyIRbMGVNFWwAZEItuBKmjocDtN4PK5eAfRXnmV5ps2VzMA2gq2jSpp6cnKSTk/rP08MoJ/yLMszba5kBrYRbB1V0tTRaDT9hpNvCCs3oI/y7MozLM+yPNPmSmZgG8HWUaVNzTdC/paTb4r8fFoppfpUeXblGVYPtax0Bq4j2Dpqm6YC9N02M1CwddQ2TQXou21moGDrqJWm/vprtQUgvpUZeA6CraN+euutpaa+ePCg2gIQ229PnizNv1znIdg66tH77680VimlrmP948aNajKWEWwd9eevvlrbYKWUum71t88+qyZjGcHWUT/88EN68MEHa5uslFLXpf7+7rvpr/fuVZOxjGDrsLt376Zvb95M/3znnbUNV0qpqJX/nsGfPvoo/fHrr9PLly+rqVhGsHXc0dFRun37dtrf31dKqWtTt27dSvfv3z93qGWCDYBQBBsAoQg2AEIRbD3nhyArpfpcbT8EeRuCrcfyjZBvCv9sDdBXbf9szTYEW4/lbzn5hgDouzzL8ky7CIKtx/I3HCs1III8y/JMuwiCrcfy82mAKC5qpgm2HhNsQCSCDcEGhCLYEGxAKIINwQaEItgQbEAogg3BBoRyScH2OA12d9Le4ePqNV0i2IBIBBuCDQjlCoPtOB3s7KSded05rn49m+2/dtvpIO3tHKTB4d5i++5g8g5el2ADIrmiYNv0ugq1szBrvJ4GW337LCCtBl+fYAMiuZpge3QwWWkdTCJpjXXbpmG2lwb55/TW/7tyfKcedJyXYAMiuZJge5wfI7Y8Ply/La/KBNv/i2ADIhFsCDYglCsJNo8iu0WwAZFcTbCtvK6H02zbIqgarwXbhRNsQCRXFGxZ46/7Lz1+rMJsvq0eWoLtwgk2IJJLCja6TLABkQg2BBsQimBDsAGhCDYEGxCKYEOwAaEINgQbEIpgQ7ABoQg2BBsQimBDsAGhCDbScDhM4/G4egXQX3mW5Zl2EQRbj52cnKTT09rPKAPoqTzL8ky7CIKtx0aj0fQbTr4hrNyAPsqzK8+wPMvyTLsIgq3n8o2Qv+XkmyI/n1ZKqT5Vnl15hl1UqGWCDYBQBBsAoQg2AEIRbACEItgACEWwARCKYAMgFMEGQCAp/Q+4bDo1V84gbAAAAABJRU5ErkJggg==",d={},c=e("h1",{id:"getting-started",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#getting-started","aria-hidden":"true"},"#"),t(" Getting Started")],-1),l=e("h2",{id:"installation",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#installation","aria-hidden":"true"},"#"),t(" Installation")],-1),g={href:"https://hacs.xyz/",target:"_blank",rel:"noopener noreferrer"},h={href:"https://github.com/zachowj/hass-node-red/blob/master/README.md#installation",target:"_blank",rel:"noopener noreferrer"},b=e("h2",{id:"tip",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#tip","aria-hidden":"true"},"#"),t(" Tip")],-1),B=e("p",null,[t("Filling in the friendly name field in the entity config node before you first deploy will attempt to create it with that entity*id otherwise it will default to "),e("code",null,"sensor.nodered_"),t(". Where the random string is the node id in Node-RED. The entity id can be changed in Home Assistant after creating them in Node-RED.")],-1),p=e("p",null,[e("img",{src:A,alt:"image|455x88"})],-1);function m(f,K){const n=s("ExternalLinkIcon");return i(),o("div",null,[c,l,e("p",null,[t("Installation of custom integration can be done using "),e("a",g,[t("HACS"),a(n)]),t(" or manually, instruction can be found in the "),e("a",h,[t("README"),a(n)]),t(".")]),b,B,p])}const v=r(d,[["render",m],["__file","index.html.vue"]]);export{v as default}; diff --git a/assets/index.html-uF_24AQ3.js b/assets/index.html-uF_24AQ3.js new file mode 100644 index 0000000000..ff07670212 --- /dev/null +++ b/assets/index.html-uF_24AQ3.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-fffb8e28","path":"/guide/","title":"Getting Started","lang":"en-US","frontmatter":{"sidebarDepth":2},"headers":[{"level":2,"title":"Prerequisites","slug":"prerequisites","link":"#prerequisites","children":[]},{"level":2,"title":"Installation","slug":"installation","link":"#installation","children":[{"level":3,"title":"Using the Palette Manager","slug":"using-the-palette-manager","link":"#using-the-palette-manager","children":[]},{"level":3,"title":"Using npm from the command line","slug":"using-npm-from-the-command-line","link":"#using-npm-from-the-command-line","children":[]},{"level":3,"title":"Home Assistant Add-on","slug":"home-assistant-add-on","link":"#home-assistant-add-on","children":[]}]},{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Generate Access Token","slug":"generate-access-token","link":"#generate-access-token","children":[]}]}],"git":{"updatedTime":1675479918000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":11},{"name":"James Wright","email":"jameswr@google.com","commits":1}]},"filePathRelative":"guide/README.md"}');export{e as data}; diff --git a/assets/index_import_screenshot-B6IPVgb8.png b/assets/index_import_screenshot-B6IPVgb8.png new file mode 100644 index 0000000000..29875d3abd Binary files /dev/null and b/assets/index_import_screenshot-B6IPVgb8.png differ diff --git a/assets/jsonata-primer.html-DHSKk7gq.js b/assets/jsonata-primer.html-DHSKk7gq.js new file mode 100644 index 0000000000..1a7698c3a2 --- /dev/null +++ b/assets/jsonata-primer.html-DHSKk7gq.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-30bc7e2c","path":"/guide/jsonata/jsonata-primer.html","title":"JSONata primer","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"The mapping (iteration) operator .","slug":"the-mapping-iteration-operator","link":"#the-mapping-iteration-operator","children":[]},{"level":2,"title":"The filter (selection) operator [ ]","slug":"the-filter-selection-operator","link":"#the-filter-selection-operator","children":[]},{"level":2,"title":"The reduce (aggregation) operator { }","slug":"the-reduce-aggregation-operator","link":"#the-reduce-aggregation-operator","children":[]},{"level":2,"title":"The order-by (sort) operator ^( )","slug":"the-order-by-sort-operator","link":"#the-order-by-sort-operator","children":[]},{"level":2,"title":"Other Operators","slug":"other-operators","link":"#other-operators","children":[]},{"level":2,"title":"Variables","slug":"variables","link":"#variables","children":[]},{"level":2,"title":"Functions","slug":"functions","link":"#functions","children":[]},{"level":2,"title":"Code blocks","slug":"code-blocks","link":"#code-blocks","children":[]},{"level":2,"title":"How it works in practice","slug":"how-it-works-in-practice","link":"#how-it-works-in-practice","children":[]},{"level":2,"title":"Errors and error handling","slug":"errors-and-error-handling","link":"#errors-and-error-handling","children":[]},{"level":2,"title":"Writing JSONata code","slug":"writing-jsonata-code","link":"#writing-jsonata-code","children":[]},{"level":2,"title":"What JSONata cannot do","slug":"what-jsonata-cannot-do","link":"#what-jsonata-cannot-do","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"guide/jsonata/jsonata-primer.md"}');export{e as data}; diff --git a/assets/jsonata-primer.html-Nla_OrjS.js b/assets/jsonata-primer.html-Nla_OrjS.js new file mode 100644 index 0000000000..d1b166ba47 --- /dev/null +++ b/assets/jsonata-primer.html-Nla_OrjS.js @@ -0,0 +1,13 @@ +import{_ as r,r as i,o as s,c as d,a as t,d as e,b as o,e as n}from"./app-DW3AHQOa.js";const c={},l=t("h1",{id:"jsonata-primer",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#jsonata-primer","aria-hidden":"true"},"#"),e(" JSONata primer")],-1),h=t("em",null,"simple introduction",-1),u=t("em",null,"key aspects",-1),p={href:"https://docs.jsonata.org/overview",target:"_blank",rel:"noopener noreferrer"},m=n(`

    JSONata code can be written as either a single line expression, or as multiple line expressions in a code block ( ). Expressions are evaluated against a _JSON object. In Node-RED this object is the node input message.

    A single line expression is evaluated left to right by operator, and the result returned is the final evaluation.

    • Everything in JSONata is an expression and will be evaluated, returning the result
    • Literals are evaluated as themselves, but must be valid JSON (number, string, Boolean, null, array or object)
    • Object keys (fields) are evaluated as the key value, where found, thus payload will return the value contained in msg.payload
    • The primary use of JSONata is to evaluate a JSON path, such as msg.payload.foo.bar
    • Path operators are evaluated in a line expression by being applied to the top level message
      • . is the mapping (iteration) operator
      • [ ] is the filter (selection) operator
      • { } is the reduce (aggregation) operator
      • ^( ) is the sorting (ordering) operator

    Context: At the start of a line expression, the context is the entire top level message. Each path operator takes input from the current context, with the final result of each operation passed as output context to the next operator. Available context therefore changes as the evaluation proceeds. The current context at a specific point can be referred to using $. An additional operator $$ can be used to refer to the top level context at any point, and % can be used to refer to the parent context (back one level) but only where this is possible to determine.

    The mapping (iteration) operator .

    Syntax can be considered as <sequence-list> . <expression>.

    The current input-context on the left hand side of the operator is parsed as a sequence or ordered list of items (for an array this is a list of the array elements, for an object or for a primitive this is usually a singleton list). Each item in this list is taken in sequence as the evaluation-context, and evaluated by the expression formed from the right hand side of the operator. The result sequence is then collated into an output array (from an input list) or returned as a singleton (from an input singleton, or where the input sequence reduces to a singleton).

    As an example, $type(payload) returns the type of the message payload, however payload.$type($) returns an array of the type of each element within payload. For an array of numbers, this would be ["number", "number", "number"]. The right hand side, $type() is a JSONata function requiring a parameter. For many functions one or more parameters are optional, and where omitted they take the current (evaluation) context $ instead. In this case, the parameter is not optional, hence the use of $ for the immediate context (each array element in turn).

    Index operator #: Applied with the mapping operator, the # index operator can be used to capture the iteration index value for use later in the expression. The operator must be followed by a variable, for example $i, and this variable is made available for the remaining line expression. If payload is an array of three items, then payload#$i.($i+2) would return [2, 3, 4]. The use of () here is required since JSONata is left-associative and the parentheses are required to force the correct order of evaluation.

    Wildcards and array flattening: Within a path expression, * can be used to select all fields in an object, and ** is a descendant wildcard for any depth of nesting. Thus payload.**.time would return an array of the values of all nested time keys.

    The path expression may generate an array of arrays for the evaluation sequence list. In this case, the list will always first be flattened to just one array. This flattening also occurs for output when the result is an arrays of arrays.

    If payload is an array of objects then payload.$keys() returns an array, listing the keys names for each array object. For an array of nested objects, payload.**.$keys() returns a flattened array of all keys. To remove duplicates, the $distinct() function can be used, thus $distinct(payload.**.$keys()) returns an array of every key in message payload to any depth.

    The filter (selection) operator [ ]

    The [ ] operator has several applications.

    • If the operator encloses an integer, this acts as array index addressing, where payload[0] returns the first item in the array, [-1] the last item. Note that the index can be an integer, or any number expression that returns or rounds down to an integer.
    • If the operator encloses an array of integers, these act as a selection list, thus payload[0, -1] returns the first and last items from payload array.
    • Otherwise, where the operator encloses a predicate expression, this will map over the current context as a list, filtering only the list items where the predicate evaluates as true. For example payload[time<"12:00"] where time is a key value within payload object.
    • For the special range operator [a..b], such as [0..3] this syntax generates an array of integers between the two given integer values. Note that, as in all cases in JSONata, the defining integer values can be either literals, or expressions that evaluate to an integer. To generate an array of integers to be used as a filter requires [[a..b]].
    • Lastly, this operator acts as an array constructor. ["one", "two", "three"] is an array. The simple form [] may also be used at any point in a line expression to force singleton output to an array, as in payload.data[].

    JSONata does not inherently regard singleton values as fundamentally different to arrays. Although a singleton is a value without enclosing structure, path expressions that require an array input can accept a singleton, which is treated as an array of one item. In some situations, particularly with path input or output list flattening, it may be necessary to add an additional [] to the expression to ensure correct evaluation, and where an array of arrays is required in the result.

    No result means nothing is returned: One of the more unusual aspects of JSONata is the behaviour when an expression evaluates to no discernible result. Simply put, JSONata will neither return a value, nor null nor an error message where there is no result from an expression. Mistyping paylaod or requesting an array index payload[100] for an array of only 25 items will return nothing. This can make writing, testing and debugging JSONata code challenging, but it eliminates the need to code for exception conditions - declare what you want, and nothing else will be returned.

    The filter operator binds more strongly than the mapping operator. This means that payload.array[0] is returned as an array of the first items in each payload.array and not the first item in the payload.array array result. Use (payload.array)[0] to force evaluation in a different order.

    The reduce (aggregation) operator { }

    This operator can only be used once in an expression line, and should ideally be at the very end. Note that { } is a valid empty object, and {"key": "value"} is a one-field object as expected. Both the key as well as the value can be any expression, thus{last_updated: payload.state} will generate a valid object as long as last_updated results in a string value. Naturally values may be an valid JSON type, including objects and arrays.

    It is worth noting that in a key-value pair where the value is an expression that returns nothing, the key-value pair will not be returned in the result.

    Thus {"key": "value", "result": [1, 2][4]} will just return {"key": "value"}

    The order-by (sort) operator ^( )

    Applies to arrays, and will sort the array by one or more expressions, where the expression results in either a string or an number. Sorting is ascending < by default, but can be modified to descending >. Where payload is an array of objects, then payload^(>field, second) will sort the array, by the field value, in descending order, and for equal values, additionally by the second field in ascending order. To sort an array of primitives such as strings, use the context variable $. If payload is an object, $keys(payload)^($) returns an array of the object keys sorted into alphabetic order.

    Other Operators

    JSONata is built on JavaScript, so much of the syntax and basic functions will be familiar. The usual mathematical operators apply.

    Comparison operators are as expected, and also the in inclusion operator where "b" in ["a", "b", "c"] returns true.

    Boolean operators are the usual and and or, but not is provided as a function $not().

    String concatenation operator is &, which provides the only situation where type is cast. Numbers, Boolean, arrays and objects are all stringified as required. Hence payload & "" will turn an object to a stringified equivalent.

    Conditional testing is a ternary operator, syntax as <test expression> ? <true expression> : <false expression> which returns the result of either the true or false expression. False expression is optional, and if omitted a false test expression result will return nothing. Nested conditionals evaluate as expected although the use of parentheses can help visual clarity or to change order.

    Variables

    JSONata permits the use of variables, although some care needs to be exercised in their use. Variables are named as $name and assigned using $name:= <expression>. Scope is from first declaration when assigned, and lasts for the enclosing line, code block ( ), or nested blocks.

    Variables in JSONata are not values held in memory-allocated space but rather bindings. In effect this means that variables can only be assigned, then referred to. Once assigned, further references to the variable are replaced at evaluation with the originally evaluated value at assignment. In practice, this means that

    • The left hand side of := assignment can only be a variable $name, and therefore-
    • Variables cannot be modified, only re-assigned
    • The value of an assignment is the value assigned, thus $a:=3 returns 3

    Variable use should be avoided in single line expressions and only used in code blocks. Whilst expression lines are evaluated in order of the operators, left to right, JSONata execution is asynchronous and different parts of the expression may be prepared in any order. Any later reference to a variable in an expression may be evaluated prior to an earlier assignment in the same line. It also worth noting that, all variable and object field references are evaluated at the very start of statement execution. Nothing done during the expression execution can reliably update or change these values. For example: [$a:=3 .. $b:=6].{"result": $a:=$a+$b, "next": $a} may or may not work as expected.

    Functions

    JSONata has a wide range of inbuilt functions (see documentation) for manipulating:

    • strings
    • numbers
    • aggregation (sum, average)
    • arrays
    • objects
    • time (limited to date-time string <-> Unix millisecond)

    There are also several higher-order functions, such as $map() and $reduce() which apply a mapping function over an array, and similarly with result accumulation.

    Functions can be nested, so that

    $substringAfter($substringBefore("2024-01-10T10:32:14.0324","."),"T") returns just the time part of the string.

    The function chaining operator ~> allows for greater visual clarity

    $substringBefore("2024-01-10T10:32:14.0324",".") ~> $substringAfter("T").

    This works with the function chain passing the result as context, and subsequent functions permitting an optional parameter to be substituted by this context.

    Additional features: Regex is available in JSONata. The usual regex format /regular_expression/flags applies, and this can be used in the functions $match(), $contains(), $split() and $replace(). In addition, a regex expression can be used as a function.

    $join($entities().*[state = "on" and entity_id ~> /^light|^switch/].attributes.friendly_name, ", ")

    • $entities() returns an object containing all Home Assistant entities, each key being an entity id, and value being an object with details of that entity
    • .* maps over the object matching all keys, therefore returning an array of all entities
    • [] filters out the entities that match the predicate expression, using
      • state = "on" to match all entities with state 'on'
      • entity_id ~> /^light|^switch/ generates a function from the regex expression "match any string containing 'light' or 'switch'". Each entity_id is passed to this function, which
      • returns a Boolean true or false, and
      • when both parts of the predicate expression are true, the entity is selected (otherwise the entity is not returned in the result)
    • the result of this is an array of selected entities
    • the field attributes.friendly_name is picked out, resulting in an array of friendly names for all lights / switches left on
    • then the $join() function joins each item in the array, using ", " as the separator, and returning a string

    Note that the $entities() function is a special function added just to the WebSocket nodes.

    Note that entity id names are made up from a domain (platform / integration) and name, separated by .. This is potentially confusing as the object key becomes person.george. Where object keys contain spaces and special characters, the payload.'person.george' referencing syntax has to be used.

    User defined functions: User functions can be easily defined and assigned to a variable name using the syntax

    $fname:= function(arg){"Result Is " & arg}.

    Once defined the function can be called using $fname(parmValue) from later within the enclosing code block.

    Code blocks

    To breakout from the constraints of just a single line expression, JSONata permits the use of (expression; expression) code blocks. These start and end with ( ) and contain one or more line expressions terminated by ;. The return value of the block is the return of the execution result of the very last line.

    Using code blocks permits a much richer coding experience, allowing the use of variable and function definitions.

    How it works in practice

    The following expression takes an object in payload and re-sorts the object keys alphabetically.

    $keys(payload)^($).{$:$lookup($$.payload,$)}~>$merge()

    This works by

    • using $keys() to obtain an array of key name strings from the object in payload
      • sorting this array alphabetically
    • mapping over the sorted array of keys, creating a new object for each key
    • with the context (each key in the iteration) as the new object key
    • and using $lookup(object, key) to find the value of this key, as the new object value
      • where $$.payload refers back to the $$ top level context to reach payload, and $ the current context (the key in each iteration)
    • thus producing an result array with each new key:object pair (in the new order)
    • and then using $merge() to merge this array of objects back into one object

    The simplicity comes from the power of JSONata to map, filter, sort and aggregate, however compared to most procedural languages it is a new way of thinking. Since the JSON object and variables cannot be modified, there is the question of how to, for example, change just one element in an array. The expression $array[2]:=10 will return an error since the left hand side of assignment can only be a variable and not an expression. To achieve this requires a declaration of the new array, built as follows.

      (
    +    $array:=[1, 2, 3, 4, 5, 6];
    +    $newval:=10;
    +    $index:=2;
    +    $append($array[[0..$index-1]], $newval)~>$append($array[[$index+1..$count($array)]])
    +  )
    +

    Here we declare the result to be the first part of the array up to the new value, the new value, then the remainder of the array. You may note that $count($array) is incorrect being one greater than the end index, however as JSONata does not complain when accessing beyond the array length, this point can be relaxed.

    It is worth noting that it is not necessary to refer to the input JSON document. The following expression generates an array of 24 objects. ([1..24])#$pos.{"index": $, "hour": $formatInteger($pos, "09") & ":00"}

    Declarative functional programming for objects: Given an object in msg.payload, how then do we change just one field value, since payload.field:="new value" is not permitted? The answer is that we have to write a "function" that declares - that is, returns - the result we require, with the idea that JSONata expressions are functions applied to the input JSON object.

    The $spread() function takes a JSON object and returns an array of objects, each with a single key:value pair. The $merge() function reverses this, taking an array of objects and combining back into one object. A particular feature of this function is that, where key values are duplicated, the end result contains only the last such key to be found. Therefore, the approach to take is to spread the object, append the replacement key:value as an object to the end of this array, then to merge the array back together.

     (
    +   $object:={"first": 1, "second": 2, "third": 3};
    +   $replaceKey:= "second";
    +   $replaceVal:= 15;
    +   $spread($object) ~> $append({$replaceKey: $replaceVal}) ~> $merge()
    + )
    +
    `,67),g={href:"https://docs.jsonata.org/other-operators#-------transform",target:"_blank",rel:"noopener noreferrer"},f=t("code",null,'$object ~> | $ | {"second": 15} |',-1),y=n('

    Errors and error handling

    JSONata has minimal error management. Errors occur at compile time when editing due to incorrect syntax, and will show as red line box in the UI input field, as well as a red triangle on the node. Common reasons for this are missing:

    • & between string concatenation
    • : in conditional testing, or in object construction
    • ; line terminators

    Errors at run time are mostly limited to passing nothing or an incorrect type as parameter to a function. The $number() function accepts a string and returns a JSON number, but only where the input can be correctly parsed. JSON numbers must only contain numbers throughout. Passing "12,34a" will generate a fatal error, and the entire expression evaluation will be aborted.

    Where functions explicitly require an array, passing singletons will generate an error, and thus the use of [ ] to either construct arrays or cast singletons to an array may be required, for example $append(payload.array, [$additional]). Where necessary the use of $exits() to check for object fields, and the use of $type() can help.

    Writing JSONata code

    ',6),b=t("strong",null,"J: expression",-1),w={href:"https://try.jsonata.org",target:"_blank",rel:"noopener noreferrer"},x=n('

    If using the JSONata Exerciser website, use a debug node set to output the "complete message", copy this entire object and paste over the left hand side JSON input object (there is a useful formatter option). Test JSONata code can then be written in the top right hand window, and the result appears immediately below. Useful output messages indicate where there is an error in the input JSON, where no result is generated, or where an error has occurred.

    Note that there are special Node-RED functions, $env() is one, that can be tested in the Node-RED editor, but not in try JSONata. The WebSocket functions, such as $entity() cannot be tested in either editor.

    What JSONata cannot do

    JSONata can almost completely replace JavaScript in function nodes. However, the simplicity and power of the declarative language is at the expense of efficiency. Arrays and files with more than, say, 500 elements or lines will require significant CPU processing as to temporarily halt Node-RED and potentially Home Assistant. The main barrier to use is more likely to be the time and effort required to generate code, since it can be challenging to think in terms of a functional declaration, the outcome of which is the required result, rather than the more usual approach of designing and writing an algorithm to prescribe how to obtain the required result.

    Good luck.

    ',5);function v(q,$){const a=i("ExternalLinkIcon");return s(),d("div",null,[l,t("p",null,[e("This is a "),h,e(" highlighting the "),u,e(" of this language. Full details can be found at the online "),t("a",p,[e("JSONata documentation"),o(a)])]),m,t("p",null,[e("Deeply nested objects are much more complex, as the entire tree has to be unpicked and rebuilt in order. Fortunately there is a special function that can perform "),t("a",g,[e("transformation"),o(a)]),e(" on an object for us. "),f]),y,t("p",null,[e("JSONata can be directly entered into any node where the UI field entry type is "),b,e(". The Node-RED editor permits expansion of the simple box using the '...' field at the end of the line. This editor provides more space, the ability to select and insert JSONata functions from a pick list, a formatting option, and a tab for testing. However, this can be limited and the "),t("a",w,[e("try JSONata"),o(a)]),e(" website is easier to use.")]),x])}const j=r(c,[["render",v],["__file","jsonata-primer.html.vue"]]);export{j as default}; diff --git a/assets/jsonata_1_1-BOrSTtQg.png b/assets/jsonata_1_1-BOrSTtQg.png new file mode 100644 index 0000000000..9aff20120e Binary files /dev/null and b/assets/jsonata_1_1-BOrSTtQg.png differ diff --git a/assets/jsonata_2_1-AVzKzbZv.png b/assets/jsonata_2_1-AVzKzbZv.png new file mode 100644 index 0000000000..40584c6f97 Binary files /dev/null and b/assets/jsonata_2_1-AVzKzbZv.png differ diff --git a/assets/jsonata_3_1-DCTS43SR.png b/assets/jsonata_3_1-DCTS43SR.png new file mode 100644 index 0000000000..9e368550a9 Binary files /dev/null and b/assets/jsonata_3_1-DCTS43SR.png differ diff --git a/assets/jsonata_4_1-CfZXdRrw.png b/assets/jsonata_4_1-CfZXdRrw.png new file mode 100644 index 0000000000..3107378176 Binary files /dev/null and b/assets/jsonata_4_1-CfZXdRrw.png differ diff --git a/assets/jsonata_5_1-DmQtZ7mW.png b/assets/jsonata_5_1-DmQtZ7mW.png new file mode 100644 index 0000000000..b3e7127fa7 Binary files /dev/null and b/assets/jsonata_5_1-DmQtZ7mW.png differ diff --git a/assets/jsonata_6_1-Cc8tbBMr.png b/assets/jsonata_6_1-Cc8tbBMr.png new file mode 100644 index 0000000000..8b5872544b Binary files /dev/null and b/assets/jsonata_6_1-Cc8tbBMr.png differ diff --git a/assets/jsonata_6_2-CnhkdrfZ.png b/assets/jsonata_6_2-CnhkdrfZ.png new file mode 100644 index 0000000000..96a1937221 Binary files /dev/null and b/assets/jsonata_6_2-CnhkdrfZ.png differ diff --git a/assets/jsonata_7_1-BgEt8HOI.png b/assets/jsonata_7_1-BgEt8HOI.png new file mode 100644 index 0000000000..d8e3cff86b Binary files /dev/null and b/assets/jsonata_7_1-BgEt8HOI.png differ diff --git a/assets/jsonata_8_1-DHI1CMwN.png b/assets/jsonata_8_1-DHI1CMwN.png new file mode 100644 index 0000000000..dc5bc144e0 Binary files /dev/null and b/assets/jsonata_8_1-DHI1CMwN.png differ diff --git a/assets/jsonata_boolean-BjpZUFYr.png b/assets/jsonata_boolean-BjpZUFYr.png new file mode 100644 index 0000000000..076e13d06a Binary files /dev/null and b/assets/jsonata_boolean-BjpZUFYr.png differ diff --git a/assets/jsonata_boolean_example-DbjCVol3.png b/assets/jsonata_boolean_example-DbjCVol3.png new file mode 100644 index 0000000000..d4c7d9d317 Binary files /dev/null and b/assets/jsonata_boolean_example-DbjCVol3.png differ diff --git a/assets/jsonata_value_example-DJn_j-gH.png b/assets/jsonata_value_example-DJn_j-gH.png new file mode 100644 index 0000000000..c20d793089 Binary files /dev/null and b/assets/jsonata_value_example-DJn_j-gH.png differ diff --git a/assets/migration.html-BjOR_TVH.js b/assets/migration.html-BjOR_TVH.js new file mode 100644 index 0000000000..0913389dbf --- /dev/null +++ b/assets/migration.html-BjOR_TVH.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-d0112c92","path":"/guide/migration.html","title":"Migration","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Current-State Node Output","slug":"current-state-node-output","link":"#current-state-node-output","children":[]},{"level":2,"title":"Poll-State Node Output","slug":"poll-state-node-output","link":"#poll-state-node-output","children":[]}],"git":{"updatedTime":1577699988000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"guide/migration.md"}');export{t as data}; diff --git a/assets/migration.html-DHBQGdN5.js b/assets/migration.html-DHBQGdN5.js new file mode 100644 index 0000000000..03bf549f85 --- /dev/null +++ b/assets/migration.html-DHBQGdN5.js @@ -0,0 +1,33 @@ +import{_ as e,r as p,o as c,c as r,a as n,d as s,b as o,e as a}from"./app-DW3AHQOa.js";const u={},l=a('

    Migration

    Current-State Node Output

    Unchecking 'Override Topic' and 'Override Payload' doesn't work in node-red-contrib-home-assistant v0.3.2. It always overwrites msg.topic and msg.payload. If you have current-state nodes where you have unchecked the 'Override Payload' with node-red-contrib-home-assistant-websocket it will stop overriding payload and put the state object into msg.data

    Poll-State Node Output

    msg.payload.data moved to msg.data

    msg.payload becomes just the state of the state object msg.payload.data.state => msg.payload

    msg.payload.dateChanged removed

    msg.timeSinceChanged and msg.timeSinceChangedMs moved into msg.data

    ',8),i={href:"https://github.com/AYapejian/node-red-contrib-home-assistant",target:"_blank",rel:"noopener noreferrer"},d=a(`
    {
    +  "topic": "sun.sun",
    +  "payload": {
    +    "timeSinceChanged": "4 hours ago",
    +    "timeSinceChangedMs": 15342567,
    +    "dateChanged": "2018-10-11T14:21:01.004Z",
    +    "data": {
    +      "entity_id": "sun.sun",
    +      "state": "above_horizon",
    +      "attributes": { ... },
    +      "last_changed": "2018-10-11T14:21:01.004183+00:00",
    +      "last_updated": "2018-10-11T18:36:30.002985+00:00",
    +      "context": { ... }
    +    }
    +  },
    +  "_msgid": "345fd403.6e71ec"
    +}
    +
    `,1),k={href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket",target:"_blank",rel:"noopener noreferrer"},q=a(`
    {
    +  "topic": "sun.sun",
    +  "payload": "above_horizon",
    +  "data": {
    +    "entity_id": "sun.sun",
    +    "state": "above_horizon",
    +    "timeSinceChanged": "5 hours ago",
    +    "timeSinceChangedMs": 16236433
    +    "attributes": { ... },
    +    "last_changed": "2018-10-11T14:21:01.004183+00:00",
    +    "last_updated": "2018-10-11T18:51:30.002737+00:00",
    +    "context": { ... },
    +  },
    +  "_msgid": "5071255c.ad802c"
    +}
    +
    `,1);function h(g,m){const t=p("ExternalLinkIcon");return c(),r("div",null,[l,n("p",null,[n("a",i,[s("node-red-contrib-home-assistant"),o(t)]),s(" v0.3.2")]),d,n("p",null,[n("a",k,[s("node-red-contrib-home-assistant-websocket"),o(t)]),s(" v0.1.1")]),q])}const _=e(u,[["render",h],["__file","migration.html.vue"]]);export{_ as default}; diff --git a/assets/motion-triggered-light.html-BsdTkCoX.js b/assets/motion-triggered-light.html-BsdTkCoX.js new file mode 100644 index 0000000000..e5c1f16079 --- /dev/null +++ b/assets/motion-triggered-light.html-BsdTkCoX.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-cf275bea","path":"/cookbook/motion-triggered-light.html","title":"Motion Triggered Light","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Example 1","slug":"example-1","link":"#example-1","children":[]},{"level":2,"title":"Example 2","slug":"example-2","link":"#example-2","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"cookbook/motion-triggered-light.md"}');export{e as data}; diff --git a/assets/motion-triggered-light.html-Iz8Qowho.js b/assets/motion-triggered-light.html-Iz8Qowho.js new file mode 100644 index 0000000000..8190fb82e0 --- /dev/null +++ b/assets/motion-triggered-light.html-Iz8Qowho.js @@ -0,0 +1,3 @@ +import{_ as s,o as n,c as a,e as t}from"./app-DW3AHQOa.js";const p="/node-red-contrib-home-assistant-websocket/assets/motion-triggered-light_01-_ryc2wuv.png",o="/node-red-contrib-home-assistant-websocket/assets/motion-triggered-light_02-Cnf1c8VK.png",e={},u=t('

    Motion Triggered Light

    Example 1

    A motion sensor that always sends an on event when any motion is detected and continues sending an update on each detection. This example turns a light on when motion is detected and waits 5 minutes for no motion and turns off the light.

    screenshot

    [{"id":"20f6aead.8b5d52","type":"server-state-changed","z":"cf5fa59f.b4f528","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.motion","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":224,"y":1560,"wires":[["11c7e80d.388958"]]},{"id":"11c7e80d.388958","type":"trigger","z":"cf5fa59f.b4f528","name":"","op1":"{\\"service\\": \\"turn_on\\"}","op2":"{\\"service\\": \\"turn_off\\"}","op1type":"json","op2type":"json","duration":"5","extend":true,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":460,"y":1560,"wires":[["371465f9.46b39a"]]},{"id":"371465f9.46b39a","type":"api-call-service","z":"cf5fa59f.b4f528","name":"Kitchen Light","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.kitchen","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":652,"y":1560,"wires":[[]]}]
    +

    Example 2

    A motion sensor that only sends an on event once then an off event when motion is no longer detected.

    screenshot

    [{"id":"9e2a08f5.4634b8","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.motion","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":250,"y":1008,"wires":[["6a54b527.806bec"],["c066de8f.8a0e2"]]},{"id":"6a54b527.806bec","type":"api-call-service","z":"ffbd7f06.4a014","name":"Kitchen Light On","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.kitchen","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":666,"y":1008,"wires":[[]]},{"id":"c066de8f.8a0e2","type":"ha-wait-until","z":"ffbd7f06.4a014","name":"","outputs":2,"entityId":"sensor.motion","property":"state","comparator":"is","value":"on","valueType":"str","timeout":"5","timeoutUnits":"minutes","entityLocation":"","entityLocationType":"none","checkCurrentState":true,"blockInputOverrides":true,"x":476,"y":1056,"wires":[[],["28f00104.71e9de"]]},{"id":"28f00104.71e9de","type":"api-call-service","z":"ffbd7f06.4a014","name":"Kitchen Light Off","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.kitchen","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":656,"y":1056,"wires":[[]]}]
    +
    `,9),c=[u];function r(l,k){return n(),a("div",null,c)}const q=s(e,[["render",r],["__file","motion-triggered-light.html.vue"]]);export{q as default}; diff --git a/assets/motion-triggered-light_01-_ryc2wuv.png b/assets/motion-triggered-light_01-_ryc2wuv.png new file mode 100644 index 0000000000..9554782e34 Binary files /dev/null and b/assets/motion-triggered-light_01-_ryc2wuv.png differ diff --git a/assets/motion-triggered-light_02-Cnf1c8VK.png b/assets/motion-triggered-light_02-Cnf1c8VK.png new file mode 100644 index 0000000000..41979f8d8e Binary files /dev/null and b/assets/motion-triggered-light_02-Cnf1c8VK.png differ diff --git a/assets/mustache-templates.html-BLOVAawv.js b/assets/mustache-templates.html-BLOVAawv.js new file mode 100644 index 0000000000..3f1143b444 --- /dev/null +++ b/assets/mustache-templates.html-BLOVAawv.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4970f119","path":"/guide/mustache-templates.html","title":"Mustache Templates","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1577699988000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"guide/mustache-templates.md"}');export{e as data}; diff --git a/assets/mustache-templates.html-HaF7DCkI.js b/assets/mustache-templates.html-HaF7DCkI.js new file mode 100644 index 0000000000..e8134d03c9 --- /dev/null +++ b/assets/mustache-templates.html-HaF7DCkI.js @@ -0,0 +1 @@ +import{_ as e,o as t,c as a,e as o}from"./app-DW3AHQOa.js";const c={},s=o('

    Mustache Templates

    When using templates the top level is a property of the message object: msg.payload would be {{payload}}.

    You can access flow, global, and states contexts {{flow.foobar}} {{global.something}}. For the states context you can use {{entity.domain.entity_id}} to get the state or drill further down {{entity.light.kitchen.attributes.friendly_name}}.

    • {{entity.light.kitchen}} and {{entity.light.kitchen.state}} are equivalent

    By default, Mustache will replace certain characters with their HTML escape codes. To stop this happening, you can use triple braces: {{{payload}}}.

    WARNING

    Mustache templates work well with strings but if you're trying to insert a JSON object somewhere you're better off using a JSONata expression or doing with a function node and passing it in as an input.

    ',6),n=[s];function i(d,l){return t(),a("div",null,n)}const h=e(c,[["render",i],["__file","mustache-templates.html.vue"]]);export{h as default}; diff --git a/assets/number.html-CZ8kRhZm.js b/assets/number.html-CZ8kRhZm.js new file mode 100644 index 0000000000..b1622a058c --- /dev/null +++ b/assets/number.html-CZ8kRhZm.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0f75f8c8","path":"/node/number.html","title":"Number","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Mode","slug":"mode","link":"#mode","children":[]},{"level":3,"title":"Value","slug":"value","link":"#value","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"value","slug":"value-1","link":"#value-1","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]}],"git":{"updatedTime":1689466731000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/number.md"}');export{e as data}; diff --git a/assets/number.html-DsWqf7c6.js b/assets/number.html-DsWqf7c6.js new file mode 100644 index 0000000000..fb63f3fc2a --- /dev/null +++ b/assets/number.html-DsWqf7c6.js @@ -0,0 +1,2 @@ +import{_ as l,r as t,o as k,c as u,a as s,d as n,b as a,w as e,e as i}from"./app-DW3AHQOa.js";const y="/node-red-contrib-home-assistant-websocket/assets/number_01-DZfG5JQO.png",d={},g={class:"custom-container warning"},b=s("p",{class:"custom-container-title"},"WARNING",-1),m={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},f=s("h1",{id:"number",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#number","aria-hidden":"true"},"#"),n(" Number")],-1),h=s("p",null,"Creates a number in Home Assistant which can be manipulated from this node.",-1),v=s("h2",{id:"configuration",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),n(" Configuration")],-1),_={id:"mode",tabindex:"-1"},x=s("a",{class:"header-anchor",href:"#mode","aria-hidden":"true"},"#",-1),T=s("ul",null,[s("li",null,"Type: 'listen' | 'get' | 'set'")],-1),w=s("p",null,"The mode of the node",-1),z={id:"value",tabindex:"-1"},j=s("a",{class:"header-anchor",href:"#value","aria-hidden":"true"},"#",-1),C=i('
    • Type: number

    The value of the entity should be updated to

    Inputs

    properties of msg.payload

    value

    • Type: number

    The value of the entity should be updated to

    Outputs

    Value types:

    • value: The value of the entity
    • previous value: The previous value of the entity
    • config: The config properties of the node

    Examples

    ',11),V={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/number.html#examples",target:"_blank",rel:"noopener noreferrer"},I=s("h4",{id:"usage-example",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#usage-example","aria-hidden":"true"},"#"),n(" Usage example")],-1),P=s("p",null,[s("img",{src:y,alt:"screenshot"})],-1),N=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"cb8c6a0579380b1e"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"server-state-changed"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"4"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"exposeToHomeAssistant"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfilter"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"number.test_number"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfiltertype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"exact"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputinitially"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haltifstate"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_compare"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_only_on_state_change"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"for"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"num"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"minutes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateNull"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"eventData"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"228"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"304"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"a0978f86513bbea9"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"a0978f86513bbea9"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"event state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload.old_state.state & \\" : \\" & payload.new_state.state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"478"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"304"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c7b45a2c6c7215d6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-number"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4ddebbdb83b1cef1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"listen"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"142"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"085546d04890ecec"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"085546d04890ecec"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"number listen"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous & \\" : \\" & payload "'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"344"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"35fb409f4909de0e"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"146"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"112"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"61922b820eb9fd05"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"61922b820eb9fd05"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-number"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4ddebbdb83b1cef1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"$floor($random() * 1000) + 1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"314"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"112"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2021574156db4cfc"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6efeac97ac50f168"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"146"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"160"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2dd5c6c8df7810e4"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2dd5c6c8df7810e4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"5"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"number"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set_value"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"areaId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"number.test_number"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{\\"value\\": $floor($random() * 1000) + 1}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergeContext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"queue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"354"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"160"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2021574156db4cfc"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"number set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous & \\" : \\" & payload "'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"474"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"112"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"25481fa7cf1f5404"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"142"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"208"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"3ac7d1c0fbbabd14"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3ac7d1c0fbbabd14"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-number"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4ddebbdb83b1cef1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"$floor($random() * 1000) + 1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"310"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"208"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"697b6ee286987b0d"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"697b6ee286987b0d"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"531844fd6e8e6b59"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"number get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"470"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"208"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4ddebbdb83b1cef1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-entity-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"test number"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"number"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"test number"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_category"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_picture"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"device_class"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"data_size"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"unit_of_measurement"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"GiB"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"min_value"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"max_value"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1000"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"step_value"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"mode"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"box"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"resend"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugEnabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1);function D(B,O){const o=t("ExternalLinkIcon"),p=t("Badge"),c=t("InfoPanelOnly"),r=t("DocsOnly");return k(),u("div",null,[s("div",g,[b,s("p",null,[s("em",null,[n("Needs "),s("a",m,[n("Custom Integration"),a(o)]),n(" installed in Home Assistant for this node to function")])])]),f,h,v,s("h3",_,[x,n(" Mode "),a(p,{text:"required"})]),T,w,s("h3",z,[j,n(" Value "),a(p,{text:"required"})]),C,a(c,null,{default:e(()=>[s("p",null,[s("a",V,[n("link"),a(o)])])]),_:1}),a(r,null,{default:e(()=>[I,P,N]),_:1})])}const U=l(d,[["render",D],["__file","number.html.vue"]]);export{U as default}; diff --git a/assets/number_01-DZfG5JQO.png b/assets/number_01-DZfG5JQO.png new file mode 100644 index 0000000000..6368fd7c9b Binary files /dev/null and b/assets/number_01-DZfG5JQO.png differ diff --git a/assets/poll-state.html-BosF6sYi.js b/assets/poll-state.html-BosF6sYi.js new file mode 100644 index 0000000000..b155c261fa --- /dev/null +++ b/assets/poll-state.html-BosF6sYi.js @@ -0,0 +1 @@ +import{_ as d,r as n,o as l,c as h,a as e,d as t,b as a,w as c,e as i}from"./app-DW3AHQOa.js";const u={},p=e("h1",{id:"poll-state",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#poll-state","aria-hidden":"true"},"#"),t(" Poll State")],-1),f=e("p",null,"Polls for the state at regular intervals, optionally also outputting at the start and when the state changes. Useful for either alert for non-communicating devices (time since change > 1 day for example) or dashboard graphs with consistent interval charts",-1),m=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),_={id:"entity-id",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#entity-id","aria-hidden":"true"},"#",-1),b=i('

    The entity id of the entity to poll for.

    Update Interval

    • Type: number

    The amount of time between checking/sending updates.

    If State

    • Type: string

    If the conditional statement is evaluated as true send the message to the first output otherwise send it to the second output. If blank there will only be one output.

    Also see:

    ',8),y=i('

    State Type

    • Type: string

    Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

    Output Initially

    • Type: boolean

    Output once on startup/deploy then on each interval

    Expose to Home Assistant

    • Type: boolean
    ',8),x={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},T=i('

    Outputs

    topic

    • Type: string

    entity_id of changed entity

    payload

    • Type: object

    The last known state of the entity

    data.timeSinceChanged

    • Type: string

    Human readable format string of time since last updated, example "1 hour ago"

    data.timeSinceChangedMs

    • Type: number

    Number of milliseconds since last changed

    References

    ',14),v={href:"https://home-assistant.io/docs/configuration/state_object/",target:"_blank",rel:"noopener noreferrer"};function w(k,C){const s=n("Badge"),r=n("RouterLink"),o=n("ExternalLinkIcon");return l(),h("div",null,[p,f,m,e("h3",_,[g,t(" Entity ID "),a(s,{text:"required"})]),b,e("ul",null,[e("li",null,[a(r,{to:"/guide/conditionals.html"},{default:c(()=>[t("Conditionals")]),_:1})])]),y,e("p",null,[t("Creates a switch within Home Assistant to enable/disable this node. This feature requires "),e("a",x,[t("Node-RED custom integration"),a(o)]),t(" to be installed in Home Assistant")]),T,e("ul",null,[e("li",null,[e("a",v,[t("Home Assistant State Objects"),a(o)])])])])}const S=d(u,[["render",w],["__file","poll-state.html.vue"]]);export{S as default}; diff --git a/assets/poll-state.html-UM4aczzK.js b/assets/poll-state.html-UM4aczzK.js new file mode 100644 index 0000000000..013cfeb969 --- /dev/null +++ b/assets/poll-state.html-UM4aczzK.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4c846822","path":"/node/poll-state.html","title":"Poll State","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entity ID","slug":"entity-id","link":"#entity-id","children":[]},{"level":3,"title":"Update Interval","slug":"update-interval","link":"#update-interval","children":[]},{"level":3,"title":"If State","slug":"if-state","link":"#if-state","children":[]},{"level":3,"title":"State Type","slug":"state-type","link":"#state-type","children":[]},{"level":3,"title":"Output Initially","slug":"output-initially","link":"#output-initially","children":[]},{"level":3,"title":"Expose to Home Assistant","slug":"expose-to-home-assistant","link":"#expose-to-home-assistant","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"topic","slug":"topic","link":"#topic","children":[]},{"level":3,"title":"payload","slug":"payload","link":"#payload","children":[]},{"level":3,"title":"data.timeSinceChanged","slug":"data-timesincechanged","link":"#data-timesincechanged","children":[]},{"level":3,"title":"data.timeSinceChangedMs","slug":"data-timesincechangedms","link":"#data-timesincechangedms","children":[]}]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1662358213000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":4}]},"filePathRelative":"node/poll-state.md"}');export{e as data}; diff --git a/assets/render-template.html-C5DI6JF3.js b/assets/render-template.html-C5DI6JF3.js new file mode 100644 index 0000000000..e150d8c993 --- /dev/null +++ b/assets/render-template.html-C5DI6JF3.js @@ -0,0 +1 @@ +import{_ as n,r as i,o,c as d,a as e,d as t,b as r,e as l}from"./app-DW3AHQOa.js";const s={},c=l('

    Render Template

    Can either set the template in the node configuration or pass in the msg.template property of the incoming message. Passing template via msg.template will override the template string set in node configuration.

    NOTE:

    The node will output any Home Assistant API errors for catching with the 'catch-all' node

    Configuration

    template

    • Type: string

    Jinja template to be rendered, discarded if msg.template is provided via input msg

    Template Location

    Customizable location to output original template

    Results

    Customizable location to output rendered template

    Inputs

    template

    • Type: string

    Jinja template to be rendered

    Outputs

    template

    • Type: string

    The original template sent to Home Assistant for rendering

    payload

    • Type: string

    The rendered template

    References

    ',23),h={href:"https://home-assistant.io/docs/configuration/templating/",target:"_blank",rel:"noopener noreferrer"},p={href:"http://jinja.pocoo.org/docs/dev/templates/",target:"_blank",rel:"noopener noreferrer"};function u(m,f){const a=i("ExternalLinkIcon");return o(),d("div",null,[c,e("ul",null,[e("li",null,[e("a",h,[t("Home Assistant Template Docs"),r(a)])]),e("li",null,[e("a",p,[t("Jinja Docs"),r(a)])])])])}const _=n(s,[["render",u],["__file","render-template.html.vue"]]);export{_ as default}; diff --git a/assets/render-template.html-KPEunZUG.js b/assets/render-template.html-KPEunZUG.js new file mode 100644 index 0000000000..be84fc8365 --- /dev/null +++ b/assets/render-template.html-KPEunZUG.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-ba5fb488","path":"/node/render-template.html","title":"Render Template","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"template","slug":"template","link":"#template","children":[]},{"level":3,"title":"Template Location","slug":"template-location","link":"#template-location","children":[]},{"level":3,"title":"Results","slug":"results","link":"#results","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"template","slug":"template-1","link":"#template-1","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"template","slug":"template-2","link":"#template-2","children":[]},{"level":3,"title":"payload","slug":"payload","link":"#payload","children":[]}]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1662358213000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/render-template.md"}');export{e as data}; diff --git a/assets/saving-and-restoring-states.html-Bn4K2Zdu.js b/assets/saving-and-restoring-states.html-Bn4K2Zdu.js new file mode 100644 index 0000000000..ba8784e458 --- /dev/null +++ b/assets/saving-and-restoring-states.html-Bn4K2Zdu.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1dd3ec5e","path":"/cookbook/saving-and-restoring-states.html","title":"Saving and Restoring States","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Using Home Assistant scene creation","slug":"using-home-assistant-scene-creation","link":"#using-home-assistant-scene-creation","children":[]},{"level":2,"title":"Using the get entities node","slug":"using-the-get-entities-node","link":"#using-the-get-entities-node","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":5}]},"filePathRelative":"cookbook/saving-and-restoring-states.md"}');export{e as data}; diff --git a/assets/saving-and-restoring-states.html-DqoxYXhp.js b/assets/saving-and-restoring-states.html-DqoxYXhp.js new file mode 100644 index 0000000000..bb8de4677c --- /dev/null +++ b/assets/saving-and-restoring-states.html-DqoxYXhp.js @@ -0,0 +1,3 @@ +import{_ as e,r as n,o as u,c,a as s,d as a,b as t,w as r,e as l}from"./app-DW3AHQOa.js";const k="/node-red-contrib-home-assistant-websocket/assets/saving-and-restoring-states_04-RzhwF69v.png",q="/node-red-contrib-home-assistant-websocket/assets/saving-and-restoring-states_01-C9piafaU.png",i="/node-red-contrib-home-assistant-websocket/assets/saving-and-restoring-states_02-D1d1KEfC.png",y="/node-red-contrib-home-assistant-websocket/assets/saving-and-restoring-states_03-BUjd6VDW.png",g={},d=l('

    Saving and Restoring States

    Using Home Assistant scene creation

    Home Assistant added the ability to create scenes on the fly. This has reduced the work needed to be done in Node-RED to be able to restore entities to a previous state.

    screenshot

    [{"id":"44c8f86e.a64488","type":"trigger-state","z":"ffbd7f06.4a014","name":"Front Door Opened","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"sensor.front_door","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"id":"nqs49205fvp","targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"open"},{"id":"b6o1iwadls4","targetType":"this_entity","targetValue":"","propertyType":"previous_state","propertyValue":"old_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"closed"}],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":202,"y":1056,"wires":[["af046290.fdf2b"],[]]},{"id":"af046290.fdf2b","type":"api-call-service","z":"ffbd7f06.4a014","name":"Snapshot Entities","version":1,"debugenabled":false,"service_domain":"scene","service":"create","entityId":"","data":"{\\"scene_id\\":\\"before\\",\\"snapshot_entities\\":[\\"light.wled_master_bedroom_tv\\"]}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":410,"y":1056,"wires":[["7af76536.dfa6cc"]]},{"id":"7af76536.dfa6cc","type":"api-call-service","z":"ffbd7f06.4a014","name":"Change entities","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.wled_master_bedroom_tv","data":"{\\"rgb_color\\":[255,0,0],\\"brightness\\":128}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":608,"y":1056,"wires":[["c6f24589.9beb48"]]},{"id":"c6f24589.9beb48","type":"delay","z":"ffbd7f06.4a014","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":780,"y":1056,"wires":[["f762690.97b1198"]]},{"id":"f762690.97b1198","type":"api-call-service","z":"ffbd7f06.4a014","name":"Restore Entities State","version":1,"debugenabled":false,"service_domain":"scene","service":"turn_on","entityId":"scene.before","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":964,"y":1056,"wires":[[]]}]
    +

    Here are several examples using the get-entities node to get the states of several entities and then how to restore the entity states.

    Using the get entities node

    screenshot

    [{"id":"953f4576.faa588","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get States","rules":[{"property":"entity_id","logic":"is","value":"^(light|switch|climate)\\\\.+","valueType":"re"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":294,"y":80,"wires":[["2dab5a86.e54686"]]},{"id":"821d957.d510168","type":"inject","z":"6cb9e978.bf4588","name":"Store states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":118,"y":80,"wires":[["953f4576.faa588"]]},{"id":"5bc878cb.d80f08","type":"comment","z":"6cb9e978.bf4588","name":"How I would do store states","info":"","x":152,"y":32,"wires":[]},{"id":"2dab5a86.e54686","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const entities = msg.payload.map((e) => {\\n    const domain = e.entity_id.split('.')[0];\\n    const payload = {};\\n\\n    switch(domain) {\\n        case 'switch':\\n        case 'light':\\n            payload.domain = domain;\\n            payload.service = `turn_${e.state}`;\\n            payload.data = { entity_id: e.entity_id };    \\n            break;\\n        case 'climate':\\n            payload.domain = 'climate';\\n            payload.service = `set_temperature`;\\n            payload.data = {\\n                entity_id: e.entity_id,\\n                temperature: e.attributes.temperature,\\n                target_temp_low: e.attributes.min_temp,\\n                target_temp_high: e.attributes.max_temp,\\n                operation_mode: e.attributes.operation_mode\\n            };\\n            break;\\n    }\\n    return payload;\\n});\\n// Save the states\\nflow.set('savedStates', entities);\\n\\n// create a blank message object with out new payload\\nmsg = { payload: entities };\\nreturn msg;","outputs":1,"noerr":0,"x":480,"y":80,"wires":[["ceaf42e4.e245d"]]},{"id":"ceaf42e4.e245d","type":"debug","z":"6cb9e978.bf4588","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":646,"y":80,"wires":[]}]\n

    screenshot

    [{"id":"f14f56e1.4d9a28","type":"inject","z":"6cb9e978.bf4588","name":"Store states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":118,"y":256,"wires":[["3790fc30.12b354","18d6f55.537770b","94a3c52.9fa9738"]]},{"id":"18d6f55.537770b","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Switches","rules":[{"property":"entity_id","logic":"starts_with","value":"switch","valueType":"str"},{"property":"state","logic":"includes","value":"on,off","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":256,"wires":[["19e85c0e.f4d1d4"]]},{"id":"94a3c52.9fa9738","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Lights","rules":[{"property":"entity_id","logic":"starts_with","value":"light","valueType":"str"},{"property":"state","logic":"includes","value":"on,off","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":208,"wires":[["19e85c0e.f4d1d4"]]},{"id":"297ff244.47ca4e","type":"comment","z":"6cb9e978.bf4588","name":"Easier to follow version","info":"","x":132,"y":160,"wires":[]},{"id":"3790fc30.12b354","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Climate","rules":[{"property":"entity_id","logic":"starts_with","value":"climate","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":304,"wires":[["36705576.17a42a"]]},{"id":"19e85c0e.f4d1d4","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const payload = {};\\npayload.domain = msg.payload.entity_id.split('.')[0];\\npayload.service = `turn_${msg.payload.state}`;\\npayload.data = { entity_id: msg.payload.entity_id };\\n\\n// create a blank message object with out new payload\\nmsg = { payload: payload };\\nreturn msg;","outputs":1,"noerr":0,"x":476,"y":256,"wires":[["2b7e0299.1ce7ae"]]},{"id":"36705576.17a42a","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const payloads = [];\\nconst payload = {};\\npayload.domain = 'climate';\\npayload.service = `set_temperature`;\\npayload.data = {\\n    entity_id: msg.payload.entity_id,\\n    temperature: msg.payload.attributes.temperature,\\n    target_temp_low: msg.payload.attributes.min_temp,\\n    target_temp_high: msg.payload.attributes.max_temp,\\n    operation_mode: msg.payload.attributes.operation_mode\\n};\\n\\n// create a blank message object with out new payload\\nmsg = { payload: payload };\\nreturn msg;","outputs":1,"noerr":0,"x":476,"y":304,"wires":[["2b7e0299.1ce7ae"]]},{"id":"e254a879.41d408","type":"comment","z":"6cb9e978.bf4588","name":"function nodes could be replaced with a change nodes","info":"","x":596,"y":208,"wires":[]},{"id":"2b7e0299.1ce7ae","type":"join","z":"6cb9e978.bf4588","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\\\n","joinerType":"str","accumulate":false,"timeout":"5","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":654,"y":256,"wires":[["b3db19bf.61d8e8"]]},{"id":"472ff71c.c342c8","type":"debug","z":"6cb9e978.bf4588","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1026,"y":256,"wires":[]},{"id":"b3db19bf.61d8e8","type":"change","z":"6cb9e978.bf4588","name":"","rules":[{"t":"set","p":"savedStates","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":832,"y":256,"wires":[["472ff71c.c342c8"]]}]\n

    screenshot

    [{"id":"ab90e938.1eff18","type":"inject","z":"3c84cc55.8f02f4","name":"Restore states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":294,"y":656,"wires":[["a5a0930.ed3ae7"]]},{"id":"a5a0930.ed3ae7","type":"change","z":"3c84cc55.8f02f4","name":"Get Saved States","rules":[{"t":"set","p":"payload","pt":"msg","to":"savedStates","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":656,"wires":[["6247c7cf.5cb858"]]},{"id":"8f420c5d.82373","type":"debug","z":"3c84cc55.8f02f4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":998,"y":656,"wires":[]},{"id":"6247c7cf.5cb858","type":"split","z":"3c84cc55.8f02f4","name":"","splt":"\\\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":658,"y":656,"wires":[["719b7b39.cbf0e4"]]},{"id":"719b7b39.cbf0e4","type":"api-call-service","z":"3c84cc55.8f02f4","name":"Restore State","version":"1","debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":816,"y":656,"wires":[["8f420c5d.82373"]]}]
    +

    As you can see in the above examples the switch and light domains are just saving and restoring the state, on/off. But what if some users wanted to also save and restore the brightness level or not. The climate domain is saving and restoring more than just the state.

    Also see:

    `,15),b={href:"https://www.home-assistant.io/integrations/scene/#creating-scenes-on-the-fly",target:"_blank",rel:"noopener noreferrer"};function m(f,_){const p=n("ExternalLinkIcon"),o=n("RouterLink");return u(),c("div",null,[d,s("ul",null,[s("li",null,[s("a",b,[a("Scenes in Home Assistant docs"),t(p)])]),s("li",null,[t(o,{to:"/node/get-entities.html"},{default:r(()=>[a("get-entities node")]),_:1})])])])}const v=e(g,[["render",m],["__file","saving-and-restoring-states.html.vue"]]);export{v as default}; diff --git a/assets/saving-and-restoring-states_01-C9piafaU.png b/assets/saving-and-restoring-states_01-C9piafaU.png new file mode 100644 index 0000000000..5d9c6369d6 Binary files /dev/null and b/assets/saving-and-restoring-states_01-C9piafaU.png differ diff --git a/assets/saving-and-restoring-states_02-D1d1KEfC.png b/assets/saving-and-restoring-states_02-D1d1KEfC.png new file mode 100644 index 0000000000..0764a95344 Binary files /dev/null and b/assets/saving-and-restoring-states_02-D1d1KEfC.png differ diff --git a/assets/saving-and-restoring-states_03-BUjd6VDW.png b/assets/saving-and-restoring-states_03-BUjd6VDW.png new file mode 100644 index 0000000000..e1f0b89436 Binary files /dev/null and b/assets/saving-and-restoring-states_03-BUjd6VDW.png differ diff --git a/assets/saving-and-restoring-states_04-RzhwF69v.png b/assets/saving-and-restoring-states_04-RzhwF69v.png new file mode 100644 index 0000000000..4648020836 Binary files /dev/null and b/assets/saving-and-restoring-states_04-RzhwF69v.png differ diff --git a/assets/select.html-BejfjQRf.js b/assets/select.html-BejfjQRf.js new file mode 100644 index 0000000000..0b76a61811 --- /dev/null +++ b/assets/select.html-BejfjQRf.js @@ -0,0 +1,2 @@ +import{_ as l,r as t,o as k,c as u,a as s,d as n,b as a,w as e,e as i}from"./app-DW3AHQOa.js";const y="/node-red-contrib-home-assistant-websocket/assets/select_01-CmUrvZyA.png",g={},d={class:"custom-container warning"},b=s("p",{class:"custom-container-title"},"WARNING",-1),m={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},f=s("h1",{id:"select",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#select","aria-hidden":"true"},"#"),n(" Select")],-1),h=s("p",null,"Creates a select entity in Home Assistant which can be manipulated from this node.",-1),v=s("h2",{id:"configuration",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),n(" Configuration")],-1),_={id:"mode",tabindex:"-1"},x=s("a",{class:"header-anchor",href:"#mode","aria-hidden":"true"},"#",-1),T=s("ul",null,[s("li",null,"Type: 'listen' | 'get' | 'set'")],-1),$=s("p",null,"The mode of the node",-1),w={id:"value",tabindex:"-1"},C=s("a",{class:"header-anchor",href:"#value","aria-hidden":"true"},"#",-1),z=i('
    • Type: string

    A string to the set current value of the select entity

    Inputs

    properties of msg.payload

    Value

    • Type: string

    The string of the text entity should be updated to

    Outputs

    Value types:

    • value: The text string of the entity
    • previous value: The previous text string of the entity
    • config: The config properties of the node

    Examples

    ',11),j={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/select.html#examples",target:"_blank",rel:"noopener noreferrer"},V=s("h4",{id:"usage-example",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#usage-example","aria-hidden":"true"},"#"),n(" Usage example")],-1),P=s("p",null,[s("img",{src:y,alt:"screenshot"})],-1),I=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4321a3f756b4e04b"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"be77e3a6884158eb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"listen"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"94"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"61e5b7c1daa37965"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"a8c7a4ebf79bc26a"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"be77e3a6884158eb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"290"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"416"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"61e5b7c1daa37965"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select in"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue& \\" : \\" & payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"388"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1c519ae737aa6361"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"invalid option"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"invalid option!!!!"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"134"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"416"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"a8c7a4ebf79bc26a"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"e0feb133879bf8aa"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"114"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"320"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"3c6ef2defe605b5e"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"3c6ef2defe605b5e"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"5"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select_next"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"areaId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"select.test_select"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergeContext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"queue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"330"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"320"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"dee53ca19e7262f9"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"server-state-changed"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"4"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"exposeToHomeAssistant"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfilter"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select.test_select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfiltertype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"exact"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputinitially"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haltifstate"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_compare"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_only_on_state_change"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"for"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"num"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"minutes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateNull"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entityState"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"data"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"eventData"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"triggerId"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"174"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"b592f430a286d9d3"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"b592f430a286d9d3"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"event state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"data.old_state.state & \\" : \\" & payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"398"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"8425ced98c4ef688"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"be77e3a6884158eb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"542"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"368"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"7668a7159575359b"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ece11ecf7eeedf69"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"114"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"368"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2944cc4f94c015fa"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7668a7159575359b"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select out"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue& \\" : \\" & payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"684"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"368"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2944cc4f94c015fa"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-current-state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"random option"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"3"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_compare"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entity_id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select.test_select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"blockInputOverrides"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"( \\t $c := $entity().state;\\t $a := function($acc, $val){$c = $val ? $acc : $append($acc, $val)};\\t $r := $shuffle($entity().attributes.options);\\t$reduce($r, $a, [])[0]\\t)"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"for"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"num"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"minutes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"override_topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"override_payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entity_location"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"data"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"override_data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"320"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"368"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"8425ced98c4ef688"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1ebc7b227317b6c0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-update-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"be77e3a6884158eb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"320"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"560"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"8ea8951f4193e413"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1,2,3"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{\\"options\\": [\\"1\\",\\"2\\",\\"3\\"]}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"json"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"110"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"560"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"1ebc7b227317b6c0"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2b4b5b649e5a03b5"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"random strings"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"(\\t $charSet := [\\t \\"a\\",\\t \\"b\\",\\t \\"c\\",\\t \\"d\\",\\t \\"e\\",\\t \\"f\\",\\t \\"g\\",\\t \\"h\\",\\t \\"i\\",\\t \\"j\\",\\t \\"k\\",\\t \\"l\\",\\t \\"m\\",\\t \\"n\\",\\t \\"o\\",\\t \\"p\\",\\t \\"q\\",\\t \\"r\\",\\t \\"s\\",\\t \\"t\\",\\t \\"u\\",\\t \\"v\\",\\t \\"w\\",\\t \\"x\\",\\t \\"y\\",\\t \\"z\\",\\t \\"A\\",\\t \\"B\\",\\t \\"C\\",\\t \\"D\\",\\t \\"E\\",\\t \\"F\\",\\t \\"G\\",\\t \\"H\\",\\t \\"I\\",\\t \\"J\\",\\t \\"K\\",\\t \\"L\\",\\t \\"M\\",\\t \\"N\\",\\t \\"O\\",\\t \\"P\\",\\t \\"Q\\",\\t \\"R\\",\\t \\"S\\",\\t \\"T\\",\\t \\"U\\",\\t \\"V\\",\\t \\"W\\",\\t \\"X\\",\\t \\"Y\\",\\t \\"Z\\",\\t \\"0\\",\\t \\"1\\",\\t \\"2\\",\\t \\"3\\",\\t \\"4\\",\\t \\"5\\",\\t \\"6\\",\\t \\"7\\",\\t \\"8\\",\\t \\"9\\",\\t \\"!\\",\\t \\"-\\"\\t]; \\t $randomChar := function(){\\t (\\t $randomCharChosen := $floor($random()* $count($charSet));\\t $charSet[$randomCharChosen]; \\t )\\t };\\t \\t\\t{\\t \\"options\\": [\\t $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\\t $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\\t $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\\t $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\\t $reduce([0..10],function($v,$i){( $v & $randomChar();)})\\t ]\\t}\\t)"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"140"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"608"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"1ebc7b227317b6c0"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"a5d80ae6c463f4b8"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"comment"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"dynamically set options"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"info"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"148"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"512"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"a0d398b3cdb34f01"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"be77e3a6884158eb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"290"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"464"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"a7d33552113d6890"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"486e85c613ec63f5"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"114"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"464"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"a0d398b3cdb34f01"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"a7d33552113d6890"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489afaacb01df108"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"432"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"464"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"be77e3a6884158eb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-entity-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"test select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"select"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"test select"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_category"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_picture"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"options"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"def"'),s("span",{class:"token punctuation"},","),s("span",{class:"token string"},'"abc"'),s("span",{class:"token punctuation"},","),s("span",{class:"token string"},'"132"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"resend"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugEnabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1);function S(D,N){const o=t("ExternalLinkIcon"),p=t("Badge"),c=t("InfoPanelOnly"),r=t("DocsOnly");return k(),u("div",null,[s("div",d,[b,s("p",null,[s("em",null,[n("Needs "),s("a",m,[n("Custom Integration"),a(o)]),n(" installed in Home Assistant for this node to function")])])]),f,h,v,s("h3",_,[x,n(" Mode "),a(p,{text:"required"})]),T,$,s("h3",w,[C,n(" value "),a(p,{text:"required"})]),z,a(c,null,{default:e(()=>[s("p",null,[s("a",j,[n("link"),a(o)])])]),_:1}),a(r,null,{default:e(()=>[V,P,I]),_:1})])}const A=l(g,[["render",S],["__file","select.html.vue"]]);export{A as default}; diff --git a/assets/select.html-Ca9oVm0u.js b/assets/select.html-Ca9oVm0u.js new file mode 100644 index 0000000000..7a07060b8e --- /dev/null +++ b/assets/select.html-Ca9oVm0u.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4dbc7c6e","path":"/node/select.html","title":"Select","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Mode","slug":"mode","link":"#mode","children":[]},{"level":3,"title":"value","slug":"value","link":"#value","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"Value","slug":"value-1","link":"#value-1","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]}],"git":{"updatedTime":1689466731000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/select.md"}');export{e as data}; diff --git a/assets/select_01-CmUrvZyA.png b/assets/select_01-CmUrvZyA.png new file mode 100644 index 0000000000..b9c16a2148 Binary files /dev/null and b/assets/select_01-CmUrvZyA.png differ diff --git a/assets/sensor.html-BYmlIVNO.js b/assets/sensor.html-BYmlIVNO.js new file mode 100644 index 0000000000..d99d4c42ce --- /dev/null +++ b/assets/sensor.html-BYmlIVNO.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-18acdc11","path":"/cookbook/jsonata/sensor.html","title":"Sensor","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Setting the sensor state value","slug":"setting-the-sensor-state-value","link":"#setting-the-sensor-state-value","children":[]},{"level":3,"title":"Setting an attribute value","slug":"setting-an-attribute-value","link":"#setting-an-attribute-value","children":[]},{"level":3,"title":"Responding to state changes using JSONata","slug":"responding-to-state-changes-using-jsonata","link":"#responding-to-state-changes-using-jsonata","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/jsonata/sensor.md"}');export{t as data}; diff --git a/assets/sensor.html-Cb1LErrD.js b/assets/sensor.html-Cb1LErrD.js new file mode 100644 index 0000000000..79622623e8 --- /dev/null +++ b/assets/sensor.html-Cb1LErrD.js @@ -0,0 +1,13 @@ +import{_ as p,r as e,o as u,c,a as s,b as a,w as t,d as o,e as r}from"./app-DW3AHQOa.js";const l="/node-red-contrib-home-assistant-websocket/assets/jsonata_5_1-DmQtZ7mW.png",k={},i=r('

    Sensor

    Using the WebSocket nodes provides many ways to read events and entity states from Home Assistant into Node-RED. Sending data the other way requires the use of the Entity nodes.

    There are several, but they all work in much the same way, and this example will use the Sensor node to create an entity sensor in Home Asisstant, and then to update the sensor state value as well as add an attribute value.

    screenshot

    Here is an example, showing how to use JSONata to set state value, and attribute value settings for an entity-sensor node.

    [{"id":"c14460fdc14a24a0","type":"group","z":"1cc7d2e94a4815fe","name":"Sensor node - set state and attribute values","style":{"label":true,"color":"#000000"},"nodes":["ba71e67aa0d06f02","4c7a952705afe4a0","e06208fe5410cfb5","23dfef724e706db3","a6d8e76c9ca8af97","fbbda709b5a50be7"],"x":214,"y":219,"w":912,"h":222},{"id":"ba71e67aa0d06f02","type":"inject","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Manual Trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":340,"y":260,"wires":[["4c7a952705afe4a0"]]},{"id":"4c7a952705afe4a0","type":"ha-sensor","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"How many lights are on","entityConfig":"02814df043c7111b","version":0,"state":"$entities().*[state = \\"on\\" and entity_id ~> /^light|^switch/] ~> $count()","stateType":"jsonata","attributes":[{"property":"lights_table","value":"$entities().*[state = \\"on\\" and entity_id ~> /^light|^switch/].{\\"name\\": attributes.friendly_name, \\"lastChange\\": last_changed}","valueType":"jsonata"},{"property":"time","value":"","valueType":"date"}],"inputOverride":"allow","outputProperties":[],"x":610,"y":260,"wires":[[]],"server":""},{"id":"e06208fe5410cfb5","type":"server-state-changed","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"sensor.lights_on_count","entityIdType":"exact","outputInitially":false,"stateType":"num","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"table","propertyType":"msg","value":"$entity().attributes.lights_table","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"changes","propertyType":"msg","value":"(\\t    $old:=$prevEntity().attributes.lights_table;\\t    $new:=$entity().attributes.lights_table;\\t    {\\"on\\": $new[$not(name in $old.name)],\\t    \\"off\\": $old[$not(name in $new.name)]}\\t)","valueType":"jsonata"}],"x":630,"y":340,"wires":[["23dfef724e706db3","a6d8e76c9ca8af97","fbbda709b5a50be7"]]},{"id":"23dfef724e706db3","type":"debug","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Count of lights on","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":990,"y":280,"wires":[]},{"id":"a6d8e76c9ca8af97","type":"debug","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Array table","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"table","targetType":"msg","statusVal":"payload","statusType":"auto","x":970,"y":340,"wires":[]},{"id":"fbbda709b5a50be7","type":"debug","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Changes","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"changes","targetType":"msg","statusVal":"changes","statusType":"auto","x":960,"y":400,"wires":[]},{"id":"02814df043c7111b","type":"ha-entity-config","server":"","deviceConfig":"","name":"SC LS On Count","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"LS On Count"},{"property":"icon","value":""},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false}]
    +

    Setting the sensor state value

    Example: Provide a sensor with the count of lights that are on.

    Once a new entity has been registered with Home Assistant, the entity state value can be updated by passing a message with the new value. Commonly msg.payload is used, however it is possible to use a JSONata expression to generate the new state value.

    $entities().*[state = "on" and entity_id ~> /^light|^switch/] ~> $count()
    +

    Here the $entities() function is used to return all entities, and select those that have "light" or "switch" in the 'entity id', and have an "on" state. This will return an array of entities, which can be counted to obtain the total number of switches or lights that are on.

    Setting an attribute value

    Example: Provide a list of the lights that are on.

    The entity state value can only be a JSON primitive value, such as a number or string, and objects and arrays can only be passed using the entity attributes.

    $entities().*[state = "on" and entity_id ~> /^light|^switch/].{
    +    "name": attributes.friendly_name,
    +    "lastChange": last_changed}
    +

    The JSONata expression here first returns a similar array of lights and switches, but from this then builds an array of objects. Each object contains the friendly name and last changed timestamp for each light or switch. This array is set into an attribute value of the sensor entity.

    Responding to state changes using JSONata

    Example: Since I last looked, which lights have been turned on, or off?

    In addition to the node above, the example also includes an Event: state node which responds to state changes in the above sensor update.

    (
    +    $old:=$prevEntity().attributes.lights_table;
    +    $new:=$entity().attributes.lights_table;
    +    {"on": $new[$not(name in $old.name)],
    +     "off": $old[$not(name in $new.name)]
    +    }
    +)
    +

    In an Event node, the $entity() function returns the current or new entity details, and the $prevEntity() function the previous or old entity details. The JSONata here picks out the sensor attribute and compares the array of lights & switches from before and after the state change. From this, an object with an array list of lights or switches that have been turned on, and those turned off, is provided.

    Note: In this example the Sensor node is updated on demand. The state value of the associated Home Assistant entity, which is a count of the number of lights or switches that are on, will only be updated when the Sensor node is triggered. The Events: state node is responding to changes in the sensor node state value, which will only happen when the sensor node is updated, and not when a light or switch is turned on or off.

    Also see:

    `,23);function q(y,g){const n=e("RouterLink");return u(),c("div",null,[i,s("ul",null,[s("li",null,[a(n,{to:"/guide/jsonata/"},{default:t(()=>[o("JSONata guide")]),_:1})]),s("li",null,[a(n,{to:"/guide/jsonata/jsonata-primer.html"},{default:t(()=>[o("JSONata primer")]),_:1})])])])}const h=p(k,[["render",q],["__file","sensor.html.vue"]]);export{h as default}; diff --git a/assets/sensor.html-CesHJDlf.js b/assets/sensor.html-CesHJDlf.js new file mode 100644 index 0000000000..9a2c9d12fc --- /dev/null +++ b/assets/sensor.html-CesHJDlf.js @@ -0,0 +1 @@ +import{_ as i,r as a,o as r,c as d,a as e,d as t,b as n,e as c}from"./app-DW3AHQOa.js";const h={},l={class:"custom-container warning"},u=e("p",{class:"custom-container-title"},"WARNING",-1),p={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},b=e("h1",{id:"sensor",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#sensor","aria-hidden":"true"},"#"),t(" Sensor")],-1),_=e("p",null,"Creates a sensor in Home Assistant which can be manipulated from this node.",-1),m=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),f={id:"state",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#state","aria-hidden":"true"},"#",-1),x=c('
    • Type: string | number | boolean

    The state the entity should be updated to

    To set the Home Assistant state to Unknown, send a state with a js expression null.

    Attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    Input Override

    • Type: string
    • Values: accept | merge | block

    Determine how input values will be handled. When merge is selected the message object values will override the configuration values.

    Resend state and attributes

    • Type: boolean

    When creating the entity in Home Assistant this will also send the last updated state and attributes then node sent to Home Assistant

    Inputs

    properties of msg.payload

    state

    • Type: string | number | boolean

    The state the entity should be updated to

    attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    ',20);function y(v,T){const s=a("ExternalLinkIcon"),o=a("Badge");return r(),d("div",null,[e("div",l,[u,e("p",null,[e("em",null,[t("Needs "),e("a",p,[t("Custom Integration"),n(s)]),t(" installed in Home Assistant for this node to function")])])]),b,_,m,e("h3",f,[g,t(" State "),n(o,{text:"required"})]),x])}const w=i(h,[["render",y],["__file","sensor.html.vue"]]);export{w as default}; diff --git a/assets/sensor.html-DnVsLR7L.js b/assets/sensor.html-DnVsLR7L.js new file mode 100644 index 0000000000..f1b6f95e93 --- /dev/null +++ b/assets/sensor.html-DnVsLR7L.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-275c29cb","path":"/node/sensor.html","title":"Sensor","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"State","slug":"state","link":"#state","children":[]},{"level":3,"title":"Attributes","slug":"attributes","link":"#attributes","children":[]},{"level":3,"title":"Input Override","slug":"input-override","link":"#input-override","children":[]},{"level":3,"title":"Resend state and attributes","slug":"resend-state-and-attributes","link":"#resend-state-and-attributes","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"state","slug":"state-1","link":"#state-1","children":[]},{"level":3,"title":"attributes","slug":"attributes-1","link":"#attributes-1","children":[]}]}],"git":{"updatedTime":1721424946000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":6},{"name":"Mikko Tervala","email":"miksu103@gmail.com","commits":1}]},"filePathRelative":"node/sensor.md"}');export{t as data}; diff --git a/assets/sentence.html-DrsbxzcE.js b/assets/sentence.html-DrsbxzcE.js new file mode 100644 index 0000000000..daa190a94c --- /dev/null +++ b/assets/sentence.html-DrsbxzcE.js @@ -0,0 +1,2 @@ +import{_ as r,r as o,o as l,c as k,a as s,d as n,b as a,w as e,e as u}from"./app-DW3AHQOa.js";const i="/node-red-contrib-home-assistant-websocket/assets/sentence_01-v9OGWJZ4.png",y={},d=s("h1",{id:"sentence",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#sentence","aria-hidden":"true"},"#"),n(" Sentence")],-1),g={href:"https://www.home-assistant.io/voice_control/",target:"_blank",rel:"noopener noreferrer"},b={href:"https://www.home-assistant.io/integrations/conversation/",target:"_blank",rel:"noopener noreferrer"},h={href:"https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger",target:"_blank",rel:"noopener noreferrer"},m={class:"custom-container warning"},f=s("p",{class:"custom-container-title"},"WARNING",-1),_={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},w=s("h2",{id:"configuration",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),n(" Configuration")],-1),x=s("h3",{id:"sentences",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#sentences","aria-hidden":"true"},"#"),n(" Sentences")],-1),v=s("ul",null,[s("li",null,[n("Type: "),s("code",null,"string")])],-1),T={href:"https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger",target:"_blank",rel:"noopener noreferrer"},j=u('

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • trigger id: sentence that triggered the flow
    • config: config properties of the node

    Examples

    ',7),I={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/sentence.html#examples",target:"_blank",rel:"noopener noreferrer"},z=s("p",null,[s("img",{src:i,alt:"screenshot"})],-1),A=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2f10cb78ab2f486f"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"true"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"full"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"382"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"384"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"5c563c29d19f4aab"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-sentence"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"sentences"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},`"[it's ]party time"`),s("span",{class:"token punctuation"},","),s("span",{class:"token string"},'"happy (new year|birthday)"'),s("span",{class:"token punctuation"},","),s("span",{class:"token string"},'"hello world"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"triggerId"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"triggerId"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"sentences"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"sentences"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"config"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"176"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"384"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2f10cb78ab2f486f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4868b36e0e57db4f"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"process sentence"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"5"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"conversation"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"process"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"areaId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'" {\\"text\\": payload}\\t"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergeContext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"queue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"422"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"336"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0bd711e6ab321cf9"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"happy new year"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"200"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"336"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"4868b36e0e57db4f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7b19f1bcd79bf7ea"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"happy birthday"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"204"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"288"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"4868b36e0e57db4f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fdec3314ea56130d"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"party time"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"184"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"4868b36e0e57db4f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"92aa9c7e046ebba3"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},`"it's party time"`),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"198"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"4868b36e0e57db4f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4c1ecc1396d9eddf"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"39a6dba4b503e011"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"hello world"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"188"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"144"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"4868b36e0e57db4f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1);function D(N,C){const t=o("ExternalLinkIcon"),p=o("InfoPanelOnly"),c=o("DocsOnly");return l(),k("div",null,[d,s("p",null,[n("A sentence trigger fires when "),s("a",g,[n("Assist"),a(t)]),n(" matches a sentence from a voice assistant using the default "),s("a",b,[n("conversation agent"),a(t)]),n(".")]),s("p",null,[n("Sentences are allowed to use some basic template syntax. Check Home Assistant "),s("a",h,[n("documentation"),a(t)]),n(" for more information.")]),s("div",m,[f,s("p",null,[s("em",null,[n("Needs "),s("a",_,[n("Custom Integration"),a(t)]),n(" installed in Home Assistant for this node to function")])])]),w,x,v,s("p",null,[n("A list of sentences to match. Sentences are allowed to use some basic template syntax. Check Home Assistant "),s("a",T,[n("documentation"),a(t)]),n(" for more information.")]),j,a(p,null,{default:e(()=>[s("p",null,[s("a",I,[n("link"),a(t)])])]),_:1}),a(c,null,{default:e(()=>[z,A]),_:1})])}const O=r(y,[["render",D],["__file","sentence.html.vue"]]);export{O as default}; diff --git a/assets/sentence.html-spCQS_3K.js b/assets/sentence.html-spCQS_3K.js new file mode 100644 index 0000000000..d8210f6c4e --- /dev/null +++ b/assets/sentence.html-spCQS_3K.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-35c07dc2","path":"/node/sentence.html","title":"Sentence","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Sentences","slug":"sentences","link":"#sentences","children":[]},{"level":3,"title":"Expose as","slug":"expose-as","link":"#expose-as","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]}],"git":{"updatedTime":1691178120000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"node/sentence.md"}');export{e as data}; diff --git a/assets/sentence_01-v9OGWJZ4.png b/assets/sentence_01-v9OGWJZ4.png new file mode 100644 index 0000000000..d25670cf05 Binary files /dev/null and b/assets/sentence_01-v9OGWJZ4.png differ diff --git a/assets/starting-flow-after-home-assistant-restart.html-CNeWpRUR.js b/assets/starting-flow-after-home-assistant-restart.html-CNeWpRUR.js new file mode 100644 index 0000000000..3f32a74016 --- /dev/null +++ b/assets/starting-flow-after-home-assistant-restart.html-CNeWpRUR.js @@ -0,0 +1,15 @@ +import{_ as s,o as n,c as a,e as t}from"./app-DW3AHQOa.js";const p="/node-red-contrib-home-assistant-websocket/assets/starting-flow-after-home-assistant-restart_01-BIAF8zjW.png",o="/node-red-contrib-home-assistant-websocket/assets/starting-flow-after-home-assistant-restart_02-BFoj2Y9h.png",e={},u=t('

    Starting a flow after a Home Assistant restart

    Use a Home Assistant automation to set an input boolean to on then from Node-RED check if that input boolean is on after a successful connection or at any time it changes to on.

    screenshot

    [{"id":"fb5296f3c4de2a23","type":"subflow","name":"Create HA Helpers","info":"","category":"HA Actions","in":[{"x":84,"y":96,"wires":[{"id":"fc18bdbb57e2fd63"}]}],"out":[],"env":[{"name":"serverName","type":"str","value":"Home Assistant","ui":{"label":{"en-US":"HA Server Name"},"type":"input","opts":{"types":["str"]}}},{"name":"helpers","type":"json","value":"[]","ui":{"label":{"en-US":"Helpers"},"type":"input","opts":{"types":["json"]}}}],"meta":{},"color":"#46B1EF","status":{"x":246,"y":48,"wires":[{"id":"ea6dc8ad6d9ece17","port":0}]}},{"id":"fc18bdbb57e2fd63","type":"function","z":"fb5296f3c4de2a23","name":"process helpers","func":"const serverName = toCamelCase(env.get('serverName'));\\nconst haServer = global.get(\\"homeassistant\\")[serverName];\\nif(!haServer) {\\n    node.error(\\"Invalid HA server name\\");\\n    return;\\n}\\nconst states = haServer.states;\\nconst helpers = env.get(\\"helpers\\");\\n\\nhelpers.forEach(h => {\\n    const entityId = `${h.type}.${h.id}`;\\n    if(!states[entityId]) {\\n        const {id, type, ...data} = h;\\n        const apiData = {\\n            entity: h,\\n            payload: { \\n                data \\n            }\\n        };\\n        apiData.payload.data.type = `${type}/create`;\\n    \\n        node.send(apiData);\\n        node.status({text: `Creating ${entityId}`});\\n    }\\n});\\n\\nnode.done();\\n\\nfunction toCamelCase(str) {\\n    return str.replace(/(?:^\\\\w|[A-Z]|\\\\b\\\\w|\\\\s+)/g, (match, index) => {\\n        if (+match === 0) return '';\\n        return index === 0 ? match.toLowerCase() : match.toUpperCase();\\n    });\\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":224,"y":96,"wires":[["2b8e82c6d93d38e5"]]},{"id":"2b8e82c6d93d38e5","type":"ha-api","z":"fb5296f3c4de2a23","name":"create helper","server":"","version":1,"debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"","dataType":"json","responseType":"json","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"x":390,"y":96,"wires":[["767624d22ee0c819"]]},{"id":"372232586f5e138f","type":"ha-api","z":"fb5296f3c4de2a23","name":"rename helper entity id","server":"","version":1,"debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\t   \\"type\\":\\"config/entity_registry/update\\",\\t   \\"entity_id\\": entity.type & \\".\\" & payload.id,\\t   \\"new_entity_id\\": entity.type & \\".\\" & entity.id\\t}","dataType":"jsonata","responseType":"json","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"x":788,"y":96,"wires":[[]]},{"id":"767624d22ee0c819","type":"switch","z":"fb5296f3c4de2a23","name":"need to rename?","property":"payload.id","propertyType":"msg","rules":[{"t":"neq","v":"entity.id","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":96,"wires":[["372232586f5e138f","815fe31e9d239e53"]]},{"id":"ea6dc8ad6d9ece17","type":"status","z":"fb5296f3c4de2a23","name":"","scope":["fc18bdbb57e2fd63","815fe31e9d239e53"],"x":124,"y":48,"wires":[[]]},{"id":"815fe31e9d239e53","type":"function","z":"fb5296f3c4de2a23","name":"rename status","func":"const oldEntityId = `${msg.entity.type}.${msg.payload.id}`;\\nconst newEntityId = `${msg.entity.type}.${msg.entity.id}`;\\n\\nnode.status({text: `Renaming ${oldEntityId} to ${newEntityId}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":768,"y":144,"wires":[[]]},{"id":"4a91394f75614da1","type":"server-events","z":"8e0ea5b84a1a9a3a","name":"","server":"","version":1,"event_type":"home_assistant_client","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"}],"x":200,"y":320,"wires":[["95e9d47ed2be5007"]]},{"id":"95e9d47ed2be5007","type":"switch","z":"8e0ea5b84a1a9a3a","name":"running?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"running","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":412,"y":320,"wires":[["4b7a32290de02cf7"]]},{"id":"648dd9ac108befdc","type":"api-call-service","z":"8e0ea5b84a1a9a3a","name":"","server":"","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.home_assistant_restarted","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":808,"y":320,"wires":[["3754cbf709193071"]]},{"id":"4b7a32290de02cf7","type":"api-current-state","z":"8e0ea5b84a1a9a3a","name":"has restarted?","server":"","version":2,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.home_assistant_restarted","state_type":"str","blockInputOverrides":false,"outputProperties":[],"x":576,"y":320,"wires":[["648dd9ac108befdc"],[]]},{"id":"f89ae68a99bb4e65","type":"server-state-changed","z":"8e0ea5b84a1a9a3a","name":"restarted?","server":"","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.home_assistant_restarted","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[],"x":588,"y":368,"wires":[["648dd9ac108befdc"],[]]},{"id":"b5993f580d9eb5b8","type":"comment","z":"8e0ea5b84a1a9a3a","name":"Home Assistant Restarted","info":"","x":190,"y":224,"wires":[]},{"id":"3754cbf709193071","type":"link out","z":"8e0ea5b84a1a9a3a","name":"Home Assistant Restarted","links":["c67631f89e6451f4"],"x":1070,"y":320,"wires":[],"l":true},{"id":"c67631f89e6451f4","type":"link in","z":"8e0ea5b84a1a9a3a","name":"Home Assistant Restarted","links":["3754cbf709193071"],"x":190,"y":416,"wires":[["33ccbe3fca679b80"]],"l":true},{"id":"33ccbe3fca679b80","type":"debug","z":"8e0ea5b84a1a9a3a","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":412,"y":416,"wires":[]},{"id":"bcfea616e335904d","type":"inject","z":"8e0ea5b84a1a9a3a","name":"Click to create","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":166,"y":272,"wires":[["447721875af4431a","5a92fd8241edd308"]]},{"id":"447721875af4431a","type":"ha-api","z":"8e0ea5b84a1a9a3a","name":"HA automation","server":"","version":1,"debugenabled":false,"protocol":"http","method":"post","path":"/api/config/automation/config/nrrestartnotification","data":"{\\t   \\"alias\\": \\"Home Assistant Restart\\",\\t   \\"description\\": \\"\\",\\t   \\"trigger\\": [\\t       {\\t           \\"platform\\": \\"homeassistant\\",\\t           \\"event\\": \\"start\\"       \\t       }    \\t   ],\\t   \\"condition\\": [],\\t   \\"action\\": [\\t       {\\t           \\"service\\": \\"input_boolean.turn_on\\",\\t           \\"data\\": {\\t               \\"entity_id\\": \\"input_boolean.home_assistant_restarted\\"       \\t            }\\t       }    \\t   ],\\t   \\"mode\\": \\"single\\" \\t}","dataType":"jsonata","responseType":"json","outputProperties":[],"x":432,"y":224,"wires":[[]]},{"id":"5a92fd8241edd308","type":"subflow:fb5296f3c4de2a23","z":"8e0ea5b84a1a9a3a","name":"","env":[{"name":"helpers","value":"[{\\"id\\":\\"home_assistant_restarted\\",\\"type\\":\\"input_boolean\\",\\"name\\":\\"Home Assistant Restarted\\",\\"icon\\":\\"mdi:restart-alert\\"}]","type":"json"}],"x":442,"y":272,"wires":[]}]\n

    TIP

    The input boolean and automation can be created directly from Node-RED using the inject node found in the exported flow.

    Create an input boolean using the Helpers menu (Configuration -> Helpers)

    screenshot

    input_boolean:
    +  home_assistant_restarted:
    +    name: Home Assistant Restarted
    +

    Create the Home Assistant automation

    alias: Home Assistant Restart
    +description: ""
    +trigger:
    +  - platform: homeassistant
    +    event: start
    +condition: []
    +action:
    +  - service: input_boolean.turn_on
    +    data: {}
    +    entity_id: input_boolean.home_assistant_restarted
    +mode: single
    +
    `,10),c=[u];function r(l,k){return n(),a("div",null,c)}const i=s(e,[["render",r],["__file","starting-flow-after-home-assistant-restart.html.vue"]]);export{i as default}; diff --git a/assets/starting-flow-after-home-assistant-restart.html-DKAjP2bd.js b/assets/starting-flow-after-home-assistant-restart.html-DKAjP2bd.js new file mode 100644 index 0000000000..c5cfa6722e --- /dev/null +++ b/assets/starting-flow-after-home-assistant-restart.html-DKAjP2bd.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-97152f42","path":"/cookbook/starting-flow-after-home-assistant-restart.html","title":"Starting a flow after a Home Assistant restart","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Create an input boolean using the Helpers menu (Configuration -> Helpers)","slug":"create-an-input-boolean-using-the-helpers-menu-configuration-helpers","link":"#create-an-input-boolean-using-the-helpers-menu-configuration-helpers","children":[]},{"level":2,"title":"Create the Home Assistant automation","slug":"create-the-home-assistant-automation","link":"#create-the-home-assistant-automation","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"cookbook/starting-flow-after-home-assistant-restart.md"}');export{e as data}; diff --git a/assets/starting-flow-after-home-assistant-restart_01-BIAF8zjW.png b/assets/starting-flow-after-home-assistant-restart_01-BIAF8zjW.png new file mode 100644 index 0000000000..7cd95122e6 Binary files /dev/null and b/assets/starting-flow-after-home-assistant-restart_01-BIAF8zjW.png differ diff --git a/assets/starting-flow-after-home-assistant-restart_02-BFoj2Y9h.png b/assets/starting-flow-after-home-assistant-restart_02-BFoj2Y9h.png new file mode 100644 index 0000000000..fe2a0ae109 Binary files /dev/null and b/assets/starting-flow-after-home-assistant-restart_02-BFoj2Y9h.png differ diff --git a/assets/style-B3iS_lJd.css b/assets/style-B3iS_lJd.css new file mode 100644 index 0000000000..65216fe426 --- /dev/null +++ b/assets/style-B3iS_lJd.css @@ -0,0 +1 @@ +:root{--back-to-top-z-index: 5;--back-to-top-color: #3eaf7c;--back-to-top-color-hover: #71cda3}.back-to-top{cursor:pointer;position:fixed;bottom:2rem;right:2.5rem;width:2rem;height:1.2rem;background-color:var(--back-to-top-color);-webkit-mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;z-index:var(--back-to-top-z-index)}.back-to-top:hover{background-color:var(--back-to-top-color-hover)}@media (max-width: 959px){.back-to-top{display:none}}@media print{.back-to-top{display:none}}.back-to-top-enter-active,.back-to-top-leave-active{transition:opacity .3s}.back-to-top-enter-from,.back-to-top-leave-to{opacity:0}:root{--external-link-icon-color: #aaa}.external-link-icon{position:relative;display:inline-block;color:var(--external-link-icon-color);vertical-align:middle;top:-1px}@media print{.external-link-icon{display:none}}.external-link-icon-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}:root{--medium-zoom-z-index: 100;--medium-zoom-bg-color: #ffffff;--medium-zoom-opacity: 1}.medium-zoom-overlay{background-color:var(--medium-zoom-bg-color)!important;z-index:var(--medium-zoom-z-index)}.medium-zoom-overlay~img{z-index:calc(var(--medium-zoom-z-index) + 1)}.medium-zoom--opened .medium-zoom-overlay{opacity:var(--medium-zoom-opacity)}:root{--nprogress-color: #29d;--nprogress-z-index: 1031}#nprogress{pointer-events:none}#nprogress .bar{background:var(--nprogress-color);position:fixed;z-index:var(--nprogress-z-index);top:0;left:0;width:100%;height:2px}:root{--c-brand: #3eaf7c;--c-brand-light: #4abf8a;--c-bg: #ffffff;--c-bg-light: #f3f4f5;--c-bg-lighter: #eeeeee;--c-bg-dark: #ebebec;--c-bg-darker: #e6e6e6;--c-bg-navbar: var(--c-bg);--c-bg-sidebar: var(--c-bg);--c-bg-arrow: #cccccc;--c-text: #2c3e50;--c-text-accent: var(--c-brand);--c-text-light: #3a5169;--c-text-lighter: #4e6e8e;--c-text-lightest: #6a8bad;--c-text-quote: #999999;--c-border: #eaecef;--c-border-dark: #dfe2e5;--c-tip: #42b983;--c-tip-bg: var(--c-bg-light);--c-tip-title: var(--c-text);--c-tip-text: var(--c-text);--c-tip-text-accent: var(--c-text-accent);--c-warning: #ffc310;--c-warning-bg: #fffae3;--c-warning-bg-light: #fff3ba;--c-warning-bg-lighter: #fff0b0;--c-warning-border-dark: #f7dc91;--c-warning-details-bg: #fff5ca;--c-warning-title: #f1b300;--c-warning-text: #746000;--c-warning-text-accent: #edb100;--c-warning-text-light: #c1971c;--c-warning-text-quote: #ccab49;--c-danger: #f11e37;--c-danger-bg: #ffe0e0;--c-danger-bg-light: #ffcfde;--c-danger-bg-lighter: #ffc9c9;--c-danger-border-dark: #f1abab;--c-danger-details-bg: #ffd4d4;--c-danger-title: #ed1e2c;--c-danger-text: #660000;--c-danger-text-accent: #bd1a1a;--c-danger-text-light: #b5474d;--c-danger-text-quote: #c15b5b;--c-details-bg: #eeeeee;--c-badge-tip: var(--c-tip);--c-badge-warning: #ecc808;--c-badge-warning-text: var(--c-bg);--c-badge-danger: #dc2626;--c-badge-danger-text: var(--c-bg);--t-color: .3s ease;--t-transform: .3s ease;--code-bg-color: #282c34;--code-hl-bg-color: rgba(0, 0, 0, .66);--code-ln-color: #9e9e9e;--code-ln-wrapper-width: 3.5rem;--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--font-family-code: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;--navbar-height: 3.6rem;--navbar-padding-v: .7rem;--navbar-padding-h: 1.5rem;--sidebar-width: 20rem;--sidebar-width-mobile: calc(var(--sidebar-width) * .82);--content-width: 740px;--homepage-width: 960px}.back-to-top{--back-to-top-color: var(--c-brand);--back-to-top-color-hover: var(--c-brand-light)}.DocSearch{--docsearch-primary-color: var(--c-brand);--docsearch-text-color: var(--c-text);--docsearch-highlight-color: var(--c-brand);--docsearch-muted-color: var(--c-text-quote);--docsearch-container-background: rgba(9, 10, 17, .8);--docsearch-modal-background: var(--c-bg-light);--docsearch-searchbox-background: var(--c-bg-lighter);--docsearch-searchbox-focus-background: var(--c-bg);--docsearch-searchbox-shadow: inset 0 0 0 2px var(--c-brand);--docsearch-hit-color: var(--c-text-light);--docsearch-hit-active-color: var(--c-bg);--docsearch-hit-background: var(--c-bg);--docsearch-hit-shadow: 0 1px 3px 0 var(--c-border-dark);--docsearch-footer-background: var(--c-bg)}.external-link-icon{--external-link-icon-color: var(--c-text-quote)}.medium-zoom-overlay{--medium-zoom-bg-color: var(--c-bg)}#nprogress{--nprogress-color: var(--c-brand)}.pwa-popup{--pwa-popup-text-color: var(--c-text);--pwa-popup-bg-color: var(--c-bg);--pwa-popup-border-color: var(--c-brand);--pwa-popup-shadow: 0 4px 16px var(--c-brand);--pwa-popup-btn-text-color: var(--c-bg);--pwa-popup-btn-bg-color: var(--c-brand);--pwa-popup-btn-hover-bg-color: var(--c-brand-light)}.search-box{--search-bg-color: var(--c-bg);--search-accent-color: var(--c-brand);--search-text-color: var(--c-text);--search-border-color: var(--c-border);--search-item-text-color: var(--c-text-lighter);--search-item-focus-bg-color: var(--c-bg-light)}html.dark{--c-brand: #3aa675;--c-brand-light: #349469;--c-bg: #22272e;--c-bg-light: #2b313a;--c-bg-lighter: #262c34;--c-bg-dark: #343b44;--c-bg-darker: #37404c;--c-text: #adbac7;--c-text-light: #96a7b7;--c-text-lighter: #8b9eb0;--c-text-lightest: #8094a8;--c-border: #3e4c5a;--c-border-dark: #34404c;--c-tip: #318a62;--c-warning: #e0ad15;--c-warning-bg: #2d2f2d;--c-warning-bg-light: #423e2a;--c-warning-bg-lighter: #44442f;--c-warning-border-dark: #957c35;--c-warning-details-bg: #39392d;--c-warning-title: #fdca31;--c-warning-text: #d8d96d;--c-warning-text-accent: #ffbf00;--c-warning-text-light: #ddb84b;--c-warning-text-quote: #ccab49;--c-danger: #fc1e38;--c-danger-bg: #39232c;--c-danger-bg-light: #4b2b35;--c-danger-bg-lighter: #553040;--c-danger-border-dark: #a25151;--c-danger-details-bg: #482936;--c-danger-title: #fc2d3b;--c-danger-text: #ea9ca0;--c-danger-text-accent: #fd3636;--c-danger-text-light: #d9777c;--c-danger-text-quote: #d56b6b;--c-details-bg: #323843;--c-badge-warning: var(--c-warning);--c-badge-warning-text: #3c2e05;--c-badge-danger: var(--c-danger);--c-badge-danger-text: #401416;--code-hl-bg-color: #363b46}html.dark .DocSearch{--docsearch-logo-color: var(--c-text);--docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309;--docsearch-key-shadow: inset 0 -2px 0 0 #282d55, inset 0 0 1px 1px #51577d, 0 2px 2px 0 rgba(3, 4, 9, .3);--docsearch-key-gradient: linear-gradient(-225deg, #444950, #1c1e21);--docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, .5), 0 -4px 8px 0 rgba(0, 0, 0, .2)}html,body{padding:0;margin:0;background-color:var(--c-bg);transition:background-color var(--t-color)}html.dark{color-scheme:dark}html{font-size:16px}body{font-family:var(--font-family);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:1rem;color:var(--c-text)}a{font-weight:500;color:var(--c-text-accent);text-decoration:none;overflow-wrap:break-word}p a code{font-weight:400;color:var(--c-text-accent)}kbd{font-family:var(--font-family-code);color:var(--c-text);background:var(--c-bg-lighter);border:solid .15rem var(--c-border-dark);border-bottom:solid .25rem var(--c-border-dark);border-radius:.15rem;padding:0 .15em}code{font-family:var(--font-family-code);color:var(--c-text-lighter);padding:.25rem .5rem;margin:0;font-size:.85em;background-color:var(--c-bg-light);border-radius:3px;overflow-wrap:break-word;transition:background-color var(--t-color)}blockquote{font-size:1rem;color:var(--c-text-quote);border-left:.2rem solid var(--c-border-dark);margin:1rem 0;padding:.25rem 0 .25rem 1rem;overflow-wrap:break-word}blockquote>p{margin:0}ul,ol{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25;overflow-wrap:break-word}h1:focus-visible,h2:focus-visible,h3:focus-visible,h4:focus-visible,h5:focus-visible,h6:focus-visible{outline:none}h1:hover .header-anchor,h2:hover .header-anchor,h3:hover .header-anchor,h4:hover .header-anchor,h5:hover .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color)}h3{font-size:1.35rem}h4{font-size:1.15rem}h5{font-size:1.05rem}h6{font-size:1rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}@media print{a.header-anchor{display:none}}a.header-anchor:hover{text-decoration:none}a.header-anchor:focus-visible{opacity:1}@media print{a[href^="http://"]:after,a[href^="https://"]:after{content:" (" attr(href) ") "}}p,ul,ol{line-height:1.7;overflow-wrap:break-word}hr{border:0;border-top:1px solid var(--c-border)}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto;transition:border-color var(--t-color)}tr{border-top:1px solid var(--c-border-dark);transition:border-color var(--t-color)}tr:nth-child(2n){background-color:var(--c-bg-light);transition:background-color var(--t-color)}tr:nth-child(2n) code{background-color:var(--c-bg-dark)}th,td{padding:.6em 1em;border:1px solid var(--c-border-dark);transition:border-color var(--t-color)}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:6px solid var(--c-bg-arrow)}.arrow.down{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid var(--c-bg-arrow)}.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:6px solid var(--c-bg-arrow)}.arrow.left{border-top:4px solid transparent;border-bottom:4px solid transparent;border-right:6px solid var(--c-bg-arrow)}.badge{display:inline-block;font-size:14px;font-weight:600;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:var(--c-bg);vertical-align:top;transition:color var(--t-color),background-color var(--t-color)}.badge.tip{background-color:var(--c-badge-tip)}.badge.warning{background-color:var(--c-badge-warning);color:var(--c-badge-warning-text)}.badge.danger{background-color:var(--c-badge-danger);color:var(--c-badge-danger-text)}.badge+.badge{margin-left:5px}code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:var(--font-family-code);font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999}.token.punctuation{color:#ccc}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#ec5975}.token.function-name{color:#6196cc}.token.boolean,.token.number,.token.function{color:#f08d49}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699}.token.operator,.token.entity,.token.url{color:#67cdcc}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.375;padding:1.3rem 1.5rem;margin:.85rem 0;border-radius:6px;overflow:auto}.theme-default-content pre code,.theme-default-content pre[class*=language-] code{color:#fff;padding:0;background-color:transparent!important;border-radius:0;overflow-wrap:unset;-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.theme-default-content .line-number{font-family:var(--font-family-code)}div[class*=language-]{position:relative;background-color:var(--code-bg-color);border-radius:6px}div[class*=language-]:before{content:attr(data-ext);position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:var(--code-ln-color)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent!important;position:relative;z-index:1}div[class*=language-] .highlight-lines{-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.375}div[class*=language-] .highlight-lines .highlight-line{background-color:var(--code-hl-bg-color)}div[class*=language-]:not(.line-numbers-mode) .line-numbers{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line:before{content:" ";position:absolute;z-index:2;left:0;top:0;display:block;width:var(--code-ln-wrapper-width);height:100%}div[class*=language-].line-numbers-mode pre{margin-left:var(--code-ln-wrapper-width);padding-left:1rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers{position:absolute;top:0;width:var(--code-ln-wrapper-width);text-align:center;color:var(--code-ln-color);padding-top:1.25rem;line-height:1.375;counter-reset:line-number}div[class*=language-].line-numbers-mode .line-numbers .line-number{position:relative;z-index:3;-webkit-user-select:none;-moz-user-select:none;user-select:none;height:1.375em}div[class*=language-].line-numbers-mode .line-numbers .line-number:before{counter-increment:line-number;content:counter(line-number);font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;top:0;left:0;width:var(--code-ln-wrapper-width);height:100%;border-radius:6px 0 0 6px;border-right:1px solid var(--code-hl-bg-color)}@media (max-width: 419px){.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}.code-group__nav{margin-top:.85rem;margin-bottom:calc(-1.7rem - 6px);padding-bottom:calc(1.7rem - 6px);padding-left:10px;padding-top:10px;border-top-left-radius:6px;border-top-right-radius:6px;background-color:var(--code-bg-color)}.code-group__ul{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.code-group__nav-tab{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:#ffffffe6;font-weight:600}.code-group__nav-tab:focus{outline:none}.code-group__nav-tab:focus-visible{outline:1px solid rgba(255,255,255,.9)}.code-group__nav-tab-active{border-bottom:var(--c-brand) 1px solid}@media (max-width: 419px){.code-group__nav{margin-left:-1.5rem;margin-right:-1.5rem;border-radius:0}}.code-group-item{display:none}.code-group-item__active{display:block}.code-group-item>pre{background-color:orange}.custom-container{transition:color var(--t-color),border-color var(--t-color),background-color var(--t-color)}.custom-container .custom-container-title{font-weight:600}.custom-container .custom-container-title:not(:only-child){margin-bottom:-.4rem}.custom-container.tip,.custom-container.warning,.custom-container.danger{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-container.tip{border-color:var(--c-tip);background-color:var(--c-tip-bg);color:var(--c-tip-text)}.custom-container.tip .custom-container-title{color:var(--c-tip-title)}.custom-container.tip a{color:var(--c-tip-text-accent)}.custom-container.tip code{background-color:var(--c-bg-dark)}.custom-container.warning{border-color:var(--c-warning);background-color:var(--c-warning-bg);color:var(--c-warning-text)}.custom-container.warning .custom-container-title{color:var(--c-warning-title)}.custom-container.warning a{color:var(--c-warning-text-accent)}.custom-container.warning blockquote{border-left-color:var(--c-warning-border-dark);color:var(--c-warning-text-quote)}.custom-container.warning code{color:var(--c-warning-text-light);background-color:var(--c-warning-bg-light)}.custom-container.warning details{background-color:var(--c-warning-details-bg)}.custom-container.warning details code{background-color:var(--c-warning-bg-lighter)}.custom-container.warning .external-link-icon{--external-link-icon-color: var(--c-warning-text-quote)}.custom-container.danger{border-color:var(--c-danger);background-color:var(--c-danger-bg);color:var(--c-danger-text)}.custom-container.danger .custom-container-title{color:var(--c-danger-title)}.custom-container.danger a{color:var(--c-danger-text-accent)}.custom-container.danger blockquote{border-left-color:var(--c-danger-border-dark);color:var(--c-danger-text-quote)}.custom-container.danger code{color:var(--c-danger-text-light);background-color:var(--c-danger-bg-light)}.custom-container.danger details{background-color:var(--c-danger-details-bg)}.custom-container.danger details code{background-color:var(--c-danger-bg-lighter)}.custom-container.danger .external-link-icon{--external-link-icon-color: var(--c-danger-text-quote)}.custom-container.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:var(--c-details-bg)}.custom-container.details code{background-color:var(--c-bg-darker)}.custom-container.details h4{margin-top:0}.custom-container.details figure:last-child,.custom-container.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-container.details summary{outline:none;cursor:pointer}.home{padding:var(--navbar-height) 2rem 0;max-width:var(--homepage-width);margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.8rem auto}.home .hero .actions{display:flex;flex-wrap:wrap;gap:1rem;justify-content:center}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:var(--c-text-lightest)}.home .hero .action-button{display:inline-block;font-size:1.2rem;padding:.8rem 1.6rem;border-width:2px;border-style:solid;border-radius:4px;transition:background-color var(--t-color);box-sizing:border-box}.home .hero .action-button.primary{color:var(--c-bg);background-color:var(--c-brand);border-color:var(--c-brand)}.home .hero .action-button.primary:hover{background-color:var(--c-brand-light)}.home .hero .action-button.secondary{color:var(--c-brand);background-color:var(--c-bg);border-color:var(--c-brand)}.home .hero .action-button.secondary:hover{color:var(--c-bg);background-color:var(--c-brand-light)}.home .features{border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:var(--c-text-light)}.home .feature p{color:var(--c-text-lighter)}.home .theme-default-content{padding:0;margin:0}.home .footer{padding:2.5rem;border-top:1px solid var(--c-border);text-align:center;color:var(--c-text-lighter);transition:border-color var(--t-color)}@media (max-width: 719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width: 419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.page{padding-top:var(--navbar-height);padding-left:var(--sidebar-width)}.navbar{position:fixed;z-index:20;top:0;left:0;right:0;height:var(--navbar-height);box-sizing:border-box;border-bottom:1px solid var(--c-border);background-color:var(--c-bg-navbar);transition:background-color var(--t-color),border-color var(--t-color)}.sidebar{font-size:16px;width:var(--sidebar-width);position:fixed;z-index:10;margin:0;top:var(--navbar-height);left:0;bottom:0;box-sizing:border-box;border-right:1px solid var(--c-border);overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--c-brand) var(--c-border);background-color:var(--c-bg-sidebar);transition:transform var(--t-transform),background-color var(--t-color),border-color var(--t-color)}.sidebar::-webkit-scrollbar{width:7px}.sidebar::-webkit-scrollbar-track{background-color:var(--c-border)}.sidebar::-webkit-scrollbar-thumb{background-color:var(--c-brand)}.sidebar-mask{position:fixed;z-index:9;top:0;left:0;width:100vw;height:100vh;display:none}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1){transform:rotate(45deg) translate3d(5.5px,5.5px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(2){transform:scale3d(0,1,1)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform:rotate(-45deg) translate3d(6px,-6px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1),.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform-origin:center}.theme-container.no-navbar .theme-default-content h1,.theme-container.no-navbar .theme-default-content h2,.theme-container.no-navbar .theme-default-content h3,.theme-container.no-navbar .theme-default-content h4,.theme-container.no-navbar .theme-default-content h5,.theme-container.no-navbar .theme-default-content h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .page{padding-top:0}.theme-container.no-navbar .sidebar{top:0}.theme-container.no-sidebar .sidebar{display:none}@media (max-width: 719px){.theme-container.no-sidebar .sidebar{display:block}}.theme-container.no-sidebar .page{padding-left:0}.theme-default-content a:hover{text-decoration:underline}.theme-default-content img{max-width:100%}.theme-default-content h1,.theme-default-content h2,.theme-default-content h3,.theme-default-content h4,.theme-default-content h5,.theme-default-content h6{margin-top:calc(.5rem - var(--navbar-height));padding-top:calc(1rem + var(--navbar-height));margin-bottom:0}.theme-default-content h1:first-child,.theme-default-content h2:first-child,.theme-default-content h3:first-child,.theme-default-content h4:first-child,.theme-default-content h5:first-child,.theme-default-content h6:first-child{margin-bottom:1rem}.theme-default-content h1:first-child+p,.theme-default-content h1:first-child+pre,.theme-default-content h1:first-child+.custom-container,.theme-default-content h2:first-child+p,.theme-default-content h2:first-child+pre,.theme-default-content h2:first-child+.custom-container,.theme-default-content h3:first-child+p,.theme-default-content h3:first-child+pre,.theme-default-content h3:first-child+.custom-container,.theme-default-content h4:first-child+p,.theme-default-content h4:first-child+pre,.theme-default-content h4:first-child+.custom-container,.theme-default-content h5:first-child+p,.theme-default-content h5:first-child+pre,.theme-default-content h5:first-child+.custom-container,.theme-default-content h6:first-child+p,.theme-default-content h6:first-child+pre,.theme-default-content h6:first-child+.custom-container{margin-top:2rem}@media (max-width: 959px){.sidebar{font-size:15px;width:var(--sidebar-width-mobile)}.page{padding-left:var(--sidebar-width-mobile)}}@media (max-width: 719px){.sidebar{top:0;padding-top:var(--navbar-height);transform:translate(-100%)}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translate(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width: 419px){h1{font-size:1.9rem}}.navbar{--navbar-line-height: calc( var(--navbar-height) - 2 * var(--navbar-padding-v) );padding:var(--navbar-padding-v) var(--navbar-padding-h);line-height:var(--navbar-line-height)}.navbar .logo{height:var(--navbar-line-height);margin-right:var(--navbar-padding-v);vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:var(--c-text);position:relative}.navbar .navbar-items-wrapper{display:flex;position:absolute;box-sizing:border-box;top:var(--navbar-padding-v);right:var(--navbar-padding-h);height:var(--navbar-line-height);padding-left:var(--navbar-padding-h);white-space:nowrap;font-size:.9rem}.navbar .navbar-items-wrapper .search-box{flex:0 0 auto;vertical-align:top}@media screen and (max-width: 719px){.navbar{padding-left:4rem}.navbar .site-name{display:block;width:calc(100vw - 11rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.navbar .can-hide{display:none}}.navbar-items{display:inline-block}@media print{.navbar-items{display:none}}.navbar-items a{display:inline-block;line-height:1.4rem;color:inherit}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text)}.navbar-items .navbar-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:var(--navbar-line-height)}.navbar-items .navbar-item:first-child{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:-2px;border-bottom:2px solid var(--c-text-accent)}@media (max-width: 719px){.navbar-items .navbar-item{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:0;border-bottom:none}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text-accent)}}.toggle-sidebar-button{position:absolute;top:.6rem;left:1rem;display:none;padding:.6rem;cursor:pointer}.toggle-sidebar-button .icon{display:flex;flex-direction:column;justify-content:center;align-items:center;width:1.25rem;height:1.25rem;cursor:inherit}.toggle-sidebar-button .icon span{display:inline-block;width:100%;height:2px;border-radius:2px;background-color:var(--c-text);transition:transform var(--t-transform)}.toggle-sidebar-button .icon span:nth-child(2){margin:6px 0}@media screen and (max-width: 719px){.toggle-sidebar-button{display:block}}.toggle-color-mode-button{display:flex;margin:auto;margin-left:1rem;border:0;background:none;color:var(--c-text);opacity:.8;cursor:pointer}@media print{.toggle-color-mode-button{display:none}}.toggle-color-mode-button:hover{opacity:1}.toggle-color-mode-button .icon{width:1.25rem;height:1.25rem}.DocSearch{transition:background-color var(--t-color)}.navbar-dropdown-wrapper{cursor:pointer}.navbar-dropdown-wrapper .navbar-dropdown-title,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:var(--c-text)}.navbar-dropdown-wrapper .navbar-dropdown-title:hover,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{border-color:transparent}.navbar-dropdown-wrapper .navbar-dropdown-title .arrow,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:none;font-weight:600;font-size:inherit}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item{color:inherit;line-height:1.7rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{margin:.45rem 0 0;border-top:1px solid var(--c-border);padding:1rem 0 .45rem;font-size:.9rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>span{padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a{font-weight:inherit}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a.router-link-active:after{display:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper{padding:0;list-style:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper .navbar-dropdown-subitem{font-size:.9em}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a:hover,.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid var(--c-text-accent);border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item:first-child .navbar-dropdown-subtitle{margin-top:0;padding-top:0;border-top:0}.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title-mobile{margin-bottom:.5rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:none}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:block}.navbar-dropdown-wrapper.mobile .navbar-dropdown{transition:height .1s ease-out;overflow:hidden}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{border-top:0;margin-top:0;padding-top:0;padding-bottom:0}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle,.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item>a{font-size:15px;line-height:2rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem{font-size:14px;padding-left:1rem}.navbar-dropdown-wrapper:not(.mobile){height:1.8rem}.navbar-dropdown-wrapper:not(.mobile):hover .navbar-dropdown,.navbar-dropdown-wrapper:not(.mobile).open .navbar-dropdown{display:block!important}.navbar-dropdown-wrapper:not(.mobile).open:blur{display:none}.navbar-dropdown-wrapper:not(.mobile) .navbar-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:var(--c-bg-navbar);padding:.6rem 0;border:1px solid var(--c-border);border-bottom-color:var(--c-border-dark);text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}.page{padding-bottom:2rem;display:block}.page .theme-default-content{max-width:var(--content-width);margin:0 auto;padding:2rem 2.5rem;padding-top:0}@media (max-width: 959px){.page .theme-default-content{padding:2rem}}@media (max-width: 419px){.page .theme-default-content{padding:1.5rem}}.page-meta{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem;overflow:auto}@media (max-width: 959px){.page-meta{padding:2rem}}@media (max-width: 419px){.page-meta{padding:1.5rem}}.page-meta .meta-item{cursor:default;margin-top:.8rem}.page-meta .meta-item .meta-item-label{font-weight:500;color:var(--c-text-lighter)}.page-meta .meta-item .meta-item-info{font-weight:400;color:var(--c-text-quote)}.page-meta .edit-link{display:inline-block;margin-right:.25rem}@media print{.page-meta .edit-link{display:none}}.page-meta .last-updated{float:right}@media (max-width: 719px){.page-meta .last-updated{font-size:.8em;float:none}.page-meta .contributors{font-size:.8em}}.page-nav{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem 2rem;padding-bottom:0}@media (max-width: 959px){.page-nav{padding:2rem}}@media (max-width: 419px){.page-nav{padding:1.5rem}}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding-top:1rem;overflow:auto}.page-nav .prev a:before{content:"←"}.page-nav .next{float:right}.page-nav .next a:after{content:"→"}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .navbar-items{display:none;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color);padding:.5rem 0 .75rem}.sidebar .navbar-items a{font-weight:600}.sidebar .navbar-items .navbar-item{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar .sidebar-items{padding:1.5rem 0}@media (max-width: 719px){.sidebar .navbar-items{display:block}.sidebar .navbar-items .navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar .sidebar-items{padding:1rem 0}}.sidebar-item{cursor:default;border-left:.25rem solid transparent;color:var(--c-text)}.sidebar-item:focus-visible{outline-width:1px;outline-offset:-1px}.sidebar-item.active:not(p.sidebar-heading){font-weight:600;color:var(--c-text-accent);border-left-color:var(--c-text-accent)}.sidebar-item.sidebar-heading{transition:color .15s ease;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0}.sidebar-item.sidebar-heading+.sidebar-item-children{transition:height .1s ease-out;overflow:hidden;margin-bottom:.75rem}.sidebar-item.collapsible{cursor:pointer}.sidebar-item.collapsible .arrow{position:relative;top:-.12em;left:.5em}.sidebar-item:not(.sidebar-heading){font-size:1em;font-weight:400;display:inline-block;margin:0;padding:.35rem 1rem .35rem 2rem;line-height:1.4;width:100%;box-sizing:border-box}.sidebar-item:not(.sidebar-heading)+.sidebar-item-children{padding-left:1rem;font-size:.95em}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading){padding:.25rem 1rem .25rem 1.75rem}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading).active{font-weight:500;border-left-color:transparent}a.sidebar-heading+.sidebar-item-children .sidebar-item:not(.sidebar-heading).active{border-left-color:transparent}a.sidebar-item{cursor:pointer}a.sidebar-item:hover{color:var(--c-text-accent)}.table-of-contents .badge{vertical-align:middle}.dropdown-enter-from,.dropdown-leave-to{height:0!important}.fade-slide-y-enter-active{transition:all .2s ease}.fade-slide-y-leave-active{transition:all .2s cubic-bezier(1,.5,.8,1)}.fade-slide-y-enter-from,.fade-slide-y-leave-to{transform:translateY(10px);opacity:0}html.dark{--box-shadow: #0f0e0d;--card-shadow: rgba(0, 0, 0, .3);--black: #fff;--dark-grey: #999;--light-grey: #666;--white: #000;--grey3: #bbb;--grey12: #333;--grey14: #111}:root{--vp-bg: var(--c-bg, #fff);--vp-bgl: var(--c-bg-light, #f3f4f5);--vp-bglt: var(--c-bg-lighter, #eeeeee);--vp-c: var(--c-text, #2c3e50);--vp-cl: var(--c-text-light, #3a5169);--vp-clt: var(--c-text-lighter, #4e6e8e);--vp-brc: var(--c-border, #eaecef);--vp-brcd: var(--c-border-dark, #dfe2e5);--vp-tc: var(--c-brand, #3eaf7c);--vp-tcl: var(--c-brand-light, #4abf8a);--vp-ct: var(--t-color, .3s ease);--vp-tt: var(--t-transform, .3s ease);--box-shadow: #f0f1f2;--card-shadow: rgba(0, 0, 0, .15);--black: #000;--dark-grey: #666;--light-grey: #999;--white: #fff;--grey3: #333;--grey12: #bbb;--grey14: #eee}:root{--balloon-border-radius: 2px;--balloon-color: rgba(16, 16, 16, .95);--balloon-text-color: #fff;--balloon-font-size: 12px;--balloon-move: 4px}button[aria-label][data-balloon-pos]{overflow:visible}[aria-label][data-balloon-pos]{position:relative;cursor:pointer}[aria-label][data-balloon-pos]:after{opacity:0;pointer-events:none;transition:all .18s ease-out .18s;text-indent:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-weight:400;font-style:normal;text-shadow:none;font-size:var(--balloon-font-size);background:var(--balloon-color);border-radius:2px;color:var(--balloon-text-color);border-radius:var(--balloon-border-radius);content:attr(aria-label);padding:.5em 1em;position:absolute;white-space:nowrap;z-index:10}[aria-label][data-balloon-pos]:before{width:0;height:0;border:5px solid transparent;border-top-color:var(--balloon-color);opacity:0;pointer-events:none;transition:all .18s ease-out .18s;content:"";position:absolute;z-index:10}[aria-label][data-balloon-pos]:hover:before,[aria-label][data-balloon-pos]:hover:after,[aria-label][data-balloon-pos][data-balloon-visible]:before,[aria-label][data-balloon-pos][data-balloon-visible]:after,[aria-label][data-balloon-pos]:not([data-balloon-nofocus]):focus:before,[aria-label][data-balloon-pos]:not([data-balloon-nofocus]):focus:after{opacity:1;pointer-events:none}[aria-label][data-balloon-pos].font-awesome:after{font-family:FontAwesome,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif}[aria-label][data-balloon-pos][data-balloon-break]:after{white-space:pre}[aria-label][data-balloon-pos][data-balloon-break][data-balloon-length]:after{white-space:pre-line;word-break:break-word}[aria-label][data-balloon-pos][data-balloon-blunt]:before,[aria-label][data-balloon-pos][data-balloon-blunt]:after{transition:none}[aria-label][data-balloon-pos][data-balloon-pos=up]:hover:after,[aria-label][data-balloon-pos][data-balloon-pos=up][data-balloon-visible]:after,[aria-label][data-balloon-pos][data-balloon-pos=down]:hover:after,[aria-label][data-balloon-pos][data-balloon-pos=down][data-balloon-visible]:after{transform:translate(-50%)}[aria-label][data-balloon-pos][data-balloon-pos=up]:hover:before,[aria-label][data-balloon-pos][data-balloon-pos=up][data-balloon-visible]:before,[aria-label][data-balloon-pos][data-balloon-pos=down]:hover:before,[aria-label][data-balloon-pos][data-balloon-pos=down][data-balloon-visible]:before{transform:translate(-50%)}[aria-label][data-balloon-pos][data-balloon-pos*=-left]:after{left:0}[aria-label][data-balloon-pos][data-balloon-pos*=-left]:before{left:5px}[aria-label][data-balloon-pos][data-balloon-pos*=-right]:after{right:0}[aria-label][data-balloon-pos][data-balloon-pos*=-right]:before{right:5px}[aria-label][data-balloon-pos][data-balloon-po*=-left]:hover:after,[aria-label][data-balloon-pos][data-balloon-po*=-left][data-balloon-visible]:after,[aria-label][data-balloon-pos][data-balloon-pos*=-right]:hover:after,[aria-label][data-balloon-pos][data-balloon-pos*=-right][data-balloon-visible]:after{transform:translate(0)}[aria-label][data-balloon-pos][data-balloon-po*=-left]:hover:before,[aria-label][data-balloon-pos][data-balloon-po*=-left][data-balloon-visible]:before,[aria-label][data-balloon-pos][data-balloon-pos*=-right]:hover:before,[aria-label][data-balloon-pos][data-balloon-pos*=-right][data-balloon-visible]:before{transform:translate(0)}[aria-label][data-balloon-pos][data-balloon-pos^=up]:before,[aria-label][data-balloon-pos][data-balloon-pos^=up]:after{bottom:100%;transform-origin:top;transform:translateY(var(--balloon-move))}[aria-label][data-balloon-pos][data-balloon-pos^=up]:after{margin-bottom:10px}[aria-label][data-balloon-pos][data-balloon-pos=up]:before,[aria-label][data-balloon-pos][data-balloon-pos=up]:after{left:50%;transform:translate(-50%,var(--balloon-move))}[aria-label][data-balloon-pos][data-balloon-pos^=down]:before,[aria-label][data-balloon-pos][data-balloon-pos^=down]:after{top:100%;transform:translateY(calc(var(--balloon-move) * -1))}[aria-label][data-balloon-pos][data-balloon-pos^=down]:after{margin-top:10px}[aria-label][data-balloon-pos][data-balloon-pos^=down]:before{width:0;height:0;border:5px solid transparent;border-bottom-color:var(--balloon-color)}[aria-label][data-balloon-pos][data-balloon-pos=down]:after,[aria-label][data-balloon-pos][data-balloon-pos=down]:before{left:50%;transform:translate(-50%,calc(var(--balloon-move) * -1))}[aria-label][data-balloon-pos][data-balloon-pos=left]:hover:after,[aria-label][data-balloon-pos][data-balloon-pos=left][data-balloon-visible]:after,[aria-label][data-balloon-pos][data-balloon-pos=right]:hover:after,[aria-label][data-balloon-pos][data-balloon-pos=right][data-balloon-visible]:after{transform:translateY(-50%)}[aria-label][data-balloon-pos][data-balloon-pos=left]:hover:before,[aria-label][data-balloon-pos][data-balloon-pos=left][data-balloon-visible]:before,[aria-label][data-balloon-pos][data-balloon-pos=right]:hover:before,[aria-label][data-balloon-pos][data-balloon-pos=right][data-balloon-visible]:before{transform:translateY(-50%)}[aria-label][data-balloon-pos][data-balloon-pos=left]:after,[aria-label][data-balloon-pos][data-balloon-pos=left]:before{right:100%;top:50%;transform:translate(var(--balloon-move),-50%)}[aria-label][data-balloon-pos][data-balloon-pos=left]:after{margin-right:10px}[aria-label][data-balloon-pos][data-balloon-pos=left]:before{width:0;height:0;border:5px solid transparent;border-left-color:var(--balloon-color)}[aria-label][data-balloon-pos][data-balloon-pos=right]:after,[aria-label][data-balloon-pos][data-balloon-pos=right]:before{left:100%;top:50%;transform:translate(calc(var(--balloon-move) * -1),-50%)}[aria-label][data-balloon-pos][data-balloon-pos=right]:after{margin-left:10px}[aria-label][data-balloon-pos][data-balloon-pos=right]:before{width:0;height:0;border:5px solid transparent;border-right-color:var(--balloon-color)}[aria-label][data-balloon-pos][data-balloon-length]:after{white-space:normal}[aria-label][data-balloon-pos][data-balloon-length=small]:after{width:80px}[aria-label][data-balloon-pos][data-balloon-length=medium]:after{width:150px}[aria-label][data-balloon-pos][data-balloon-length=large]:after{width:260px}[aria-label][data-balloon-pos][data-balloon-length=xlarge]:after{width:380px}@media screen and (max-width: 768px){[aria-label][data-balloon-pos][data-balloon-length=xlarge]:after{width:90vw}}[aria-label][data-balloon-pos][data-balloon-length=fit]:after{width:100%}:root{--copy-icon: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2'/%3E%3C/svg%3E");--copied-icon: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m-6 9 2 2 4-4'/%3E%3C/svg%3E")}div[class*=language-]>button.copy-code-button{border-width:0;background:transparent;position:absolute;outline:none;cursor:pointer}@media print{div[class*=language-]>button.copy-code-button{display:none}}div[class*=language-]>button.copy-code-button .copy-icon{background:currentcolor;-webkit-mask-image:var(--copy-icon);mask-image:var(--copy-icon);-webkit-mask-position:50%;mask-position:50%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:1em;mask-size:1em}div[class*=language-]>button.copy-code-button:not(.fancy){border-width:0;background:transparent;cursor:pointer;position:absolute;top:.5em;right:.5em;z-index:5;width:2.5rem;height:2.5rem;padding:0;border-radius:.5rem;opacity:0;transition:opacity .4s}div[class*=language-]>button.copy-code-button:not(.fancy):hover,div[class*=language-]>button.copy-code-button:not(.fancy).copied{background:var(--code-hl-bg-color, rgba(0, 0, 0, .66))}div[class*=language-]>button.copy-code-button:not(.fancy):focus,div[class*=language-]>button.copy-code-button:not(.fancy).copied{opacity:1}div[class*=language-]>button.copy-code-button:not(.fancy).copied:after{content:attr(data-copied);position:absolute;top:0;right:calc(100% + .25rem);display:block;height:1.25rem;padding:.625rem;border-radius:.5rem;background:var(--code-hl-bg-color, rgba(0, 0, 0, .66));color:var(--code-ln-color, #9e9e9e);font-weight:500;line-height:1.25rem;white-space:nowrap}div[class*=language-]>button.copy-code-button:not(.fancy) .copy-icon{width:1.25rem;height:1.25rem;padding:.625rem;color:var(--code-ln-color, #9e9e9e);font-size:1.25rem}div[class*=language-]>button.copy-code-button.fancy{right:-14px;bottom:-14px;z-index:5;width:2rem;height:2rem;padding:7px 8px;border-radius:50%;background:#339af0;color:#fff}@media (max-width: 419px){div[class*=language-]>button.copy-code-button.fancy{right:0;bottom:0;width:28px;height:28px;border-radius:50% 10% 0}}div[class*=language-]>button.copy-code-button.fancy:hover{background:#228be6}div[class*=language-]>button.copy-code-button.fancy .copy-icon{width:100%;height:100%;color:#fff;font-size:1.25rem}@media (max-width: 419px){div[class*=language-]>button.copy-code-button.fancy .copy-icon{position:relative;top:2px;left:2px}}div[class*=language-]>button.copy-code-button.copied .copy-icon{-webkit-mask-image:var(--copied-icon);mask-image:var(--copied-icon)}div[class*=language-]:hover:before{display:none}div[class*=language-]:hover>button.copy-code-button:not(.fancy){opacity:1}:root{--search-bg-color: #ffffff;--search-accent-color: #3eaf7c;--search-text-color: #2c3e50;--search-border-color: #eaecef;--search-item-text-color: #5d81a5;--search-item-focus-bg-color: #f3f4f5;--search-input-width: 8rem;--search-result-width: 20rem}.search-box{display:inline-block;position:relative;margin-left:1rem}@media print{.search-box{display:none}}.search-box input{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:text;width:var(--search-input-width);height:2rem;color:var(--search-text-color);display:inline-block;border:1px solid var(--search-border-color);border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all ease .3s;background:var(--search-bg-color) url("data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='13'%3e%3cg%20stroke-width='2'%20stroke='%23aaa'%20fill='none'%3e%3cpath%20d='M11.29%2011.71l-4-4'/%3e%3ccircle%20cx='5'%20cy='5'%20r='4'/%3e%3c/g%3e%3c/svg%3e") .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:var(--search-accent-color)}.search-box .suggestions{background:var(--search-bg-color);width:var(--search-result-width);position:absolute;top:2rem;right:0;border:1px solid var(--search-border-color);border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion.focus{background-color:var(--search-item-focus-bg-color)}.search-box .suggestion.focus a{color:var(--search-accent-color)}.search-box .suggestion a{white-space:normal;color:var(--search-item-text-color)}.search-box .suggestion .page-title{font-weight:600}.search-box .suggestion .page-header{font-size:.9em;margin-left:.25em}@media (max-width: 719px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (max-width: 419px){.search-box input:focus{width:8rem}.search-box .suggestions{width:calc(100vw - 4rem);right:-.5rem}}textarea[data-v-0157be62]{width:100%;height:10em;border-color:var(--c-brand)}button[data-v-0157be62]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:16px!important;border-radius:4px;vertical-align:middle;line-height:20px;box-sizing:border-box;border:1px solid #ccc;text-align:center;cursor:pointer;padding:6px 14px;border-color:var(--c-brand);color:#fff;background:var(--c-brand);margin:12px 0}button[data-v-0157be62]:hover{background-color:var(--c-brand-light)}.fade-leave-active[data-v-0157be62]{transition:opacity .7s}.fade-leave-to[data-v-0157be62]{opacity:0}span.error[data-v-0157be62],span.copied[data-v-0157be62]{font-weight:600;display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:6px;color:#fff}.error[data-v-0157be62]{background-color:var(--c-danger)}.copied[data-v-0157be62]{background-color:var(--c-warning)}.popup[data-v-0157be62]{margin-left:10px} diff --git a/assets/sun-events.html-BgsSnipk.js b/assets/sun-events.html-BgsSnipk.js new file mode 100644 index 0000000000..41ca3270d3 --- /dev/null +++ b/assets/sun-events.html-BgsSnipk.js @@ -0,0 +1,4 @@ +import{_ as t}from"./first-automation_05-BSXfHgTV.js";import{_ as p,r as o,o as e,c as u,a as s,d as c,b as r,e as n}from"./app-DW3AHQOa.js";const l="/node-red-contrib-home-assistant-websocket/assets/sun-events_01-DNarsWH0.png",k="/node-red-contrib-home-assistant-websocket/assets/sun-events_02-BCghkTWZ.png",q={},i=n('

    Turn Light On/Off with Sunset/Sunrise

    Option 1

    screenshot

    [{"id":"b74ada49.d7e408","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sun.sun","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"above_horizon","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":244,"y":784,"wires":[["1f467cbb.0c3983"],["da5ff3e0.cbb2a"]]},{"id":"1f467cbb.0c3983","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":784,"wires":[[]]},{"id":"da5ff3e0.cbb2a","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":832,"wires":[[]]}]
    +

    Option 2

    screenshot

    [{"id":"74a64f80.d2302","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sun.sun","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"above_horizon","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":404,"y":832,"wires":[["ccb2f059.1d384"],["4a84490d.9930a8"]]},{"id":"ccb2f059.1d384","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":794,"y":832,"wires":[[]]},{"id":"4a84490d.9930a8","type":"change","z":"ffbd7f06.4a014","name":"turn on","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\\"service\\": \\"turn_on\\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":604,"y":880,"wires":[["ccb2f059.1d384"]]}]
    +

    Option 3

    Required Nodes

    `,9),y={href:"https://flows.nodered.org/node/node-red-contrib-eztimer",target:"_blank",rel:"noopener noreferrer"},g=n('

    screenshot

    [{"id":"ccb2f059.1d384","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"{{payload}}","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":644,"y":832,"wires":[[]]},{"id":"1a6cb307.d3168d","type":"eztimer","z":"ffbd7f06.4a014","name":"","autoname":"sunset - sunrise","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onproperty":"payload","onvaluetype":"str","onvalue":"turn_on","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"1","offtimesun":"sunrise","offtimetod":"dusk","offduration":"00:01:00","offproperty":"payload","offvaluetype":"str","offvalue":"turn_off","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":288,"y":832,"wires":[["ccb2f059.1d384"]]}]
    +
    `,2);function d(f,b){const a=o("ExternalLinkIcon");return e(),u("div",null,[i,s("ul",null,[s("li",null,[s("a",y,[c("node-red-contrib-eztimer"),r(a)])])]),g])}const _=p(q,[["render",d],["__file","sun-events.html.vue"]]);export{_ as default}; diff --git a/assets/sun-events.html-DbAS3TBD.js b/assets/sun-events.html-DbAS3TBD.js new file mode 100644 index 0000000000..539c606cfe --- /dev/null +++ b/assets/sun-events.html-DbAS3TBD.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-a932050c","path":"/cookbook/sun-events.html","title":"Turn Light On/Off with Sunset/Sunrise","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Option 1","slug":"option-1","link":"#option-1","children":[]},{"level":2,"title":"Option 2","slug":"option-2","link":"#option-2","children":[]},{"level":2,"title":"Option 3","slug":"option-3","link":"#option-3","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"cookbook/sun-events.md"}');export{t as data}; diff --git a/assets/sun-events_01-DNarsWH0.png b/assets/sun-events_01-DNarsWH0.png new file mode 100644 index 0000000000..60d3afae04 Binary files /dev/null and b/assets/sun-events_01-DNarsWH0.png differ diff --git a/assets/sun-events_02-BCghkTWZ.png b/assets/sun-events_02-BCghkTWZ.png new file mode 100644 index 0000000000..0413eb19e4 Binary files /dev/null and b/assets/sun-events_02-BCghkTWZ.png differ diff --git a/assets/switch-node.html-CHtn4s3S.js b/assets/switch-node.html-CHtn4s3S.js new file mode 100644 index 0000000000..beef5371a2 --- /dev/null +++ b/assets/switch-node.html-CHtn4s3S.js @@ -0,0 +1,5 @@ +import{_ as p,r as e,o as u,c,a as s,b as a,w as t,d as o,e as r}from"./app-DW3AHQOa.js";const l="/node-red-contrib-home-assistant-websocket/assets/jsonata_6_1-Cc8tbBMr.png",k="/node-red-contrib-home-assistant-websocket/assets/jsonata_6_2-CnhkdrfZ.png",i={},q=r('

    Switch node

    The Switch node and the Change node are standard Node-RED nodes that provide conditional routing (selection) and data manipulation respectively for flow messages. Many of the WebSocket nodes, when using JSONata, can provide some output property data manipulation, and a few nodes also offer simple binary output message routing. However, much more can be achieved using JSONata in Switch and Change nodes in combination with the WebSocket nodes.

    screenshot

    This example shows how to use JSONata within the standard Switch node.

    [{"id":"fcb0d3b1b8ed3478","type":"group","z":"776c027950fc8c3f","name":"Switch node - selection routing based on entity details","style":{"label":true,"color":"#000000"},"nodes":["7f01d6eef386f743","84b7ac3a7e469780","60331de530222f6f","e253c6a934a17919","76bb91be0ae4c7b4","52713f1b7157f1f0"],"x":34,"y":2159,"w":852,"h":262},{"id":"7f01d6eef386f743","type":"poll-state","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"","server":"","version":3,"exposeAsEntityConfig":"","updateInterval":"10","updateIntervalType":"num","updateIntervalUnits":"seconds","outputInitially":false,"outputOnChanged":true,"entityId":"switch.t1","stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputs":1,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":150,"y":2240,"wires":[["84b7ac3a7e469780"]]},{"id":"84b7ac3a7e469780","type":"switch","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"","property":"$round(data.timeSinceChangedMs/60000,0)","propertyType":"jsonata","rules":[{"t":"btwn","v":"2","vt":"num","v2":"3","v2t":"num"},{"t":"gt","v":"data.state=\\"on\\" ? 4 : 1","vt":"jsonata"},{"t":"jsonata_exp","v":"data.timeSinceChangedMs < 60000","vt":"jsonata"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":350,"y":2240,"wires":[["60331de530222f6f"],["e253c6a934a17919"],["76bb91be0ae4c7b4"],["52713f1b7157f1f0"]]},{"id":"60331de530222f6f","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Last changed between 2 and 3 minutes ago","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\\"Is \\" & payload & \\" for \\" & $round(data.timeSinceChangedMs/60000, 0) & \\" minutes\\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":670,"y":2200,"wires":[]},{"id":"e253c6a934a17919","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"If on > 4 mins or if off > 1 mins","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\\"Is \\" & payload & \\" for \\" & $round(data.timeSinceChangedMs/60000, 0) & \\" minutes\\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":630,"y":2260,"wires":[]},{"id":"76bb91be0ae4c7b4","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Changed state < 1 minute ago","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\\"Is \\" & payload & \\" for \\" & $round(data.timeSinceChangedMs/60000, 0) & \\" minutes\\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":630,"y":2320,"wires":[]},{"id":"52713f1b7157f1f0","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Otherwise","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\\"Is \\" & payload & \\" for \\" & $round(data.timeSinceChangedMs/60000, 0) & \\" minutes\\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":560,"y":2380,"wires":[]}]
    +

    Using JSONata in switch routing

    A Poll State node has been set up to return the entity state of a light switch every 10 seconds. This will return the entity state ("on" or "off") as the msg.payload value. It will also return the fuller entity state details in msg.data, which includes the 'timeSinceChangedMs' field.

    JSONata for the routing property

    $round(data.timeSinceChangedMs/60000,0)
    +

    The routing rules will test against the given property. By default this would be the value held in msg.payload. Using a JSONata expression here allows for a computation on the time since changed field to convert this to minutes. Rounding is also being used, so 31 to 89 seconds would become 1 minute.

    Note that the JSONata expression has access to the full incoming message. The value required was output from the Poll State node within the output property msg.data field, and this has to be used here since the $entity() functions are not available outside of the WebSocket nodes.

    screenshot

    JSONata for the rule value

    1. In the first rule, the rule values to test against are given as literals.

    2. In the second rule, the rule test value is provided by a JSONata expression. This will return either 4, if the light state is "on", or 1 if the light state is "off".

    data.state="on" ? 4 : 1
    +

    Note that 'payload' contains the state value and could have been used rather than 'data.state'. Where the output of a WebSocket node is used later in the flow for routing or processing, care should be taken to generate the most appropriate output. For example, rather than generate the Property match value here, this JSONata expression could be used in the Poll State node to provide minutes since last changed in the output msg.payload directly.

    JSONata expression for the routing match

    1. In the third rule, the evaluation Property is not used. The test condition is the Boolean result of a JSONata expression. The routing path is taken only if the JSONata expression evaluates as true.
    data.timeSinceChangedMs < 60000
    +

    The example is simplistic, however it shows that any incoming message property can be used within the expression.

    Note that, since the $entities() function is not available in a Switch node, to obtain other entity values, JSONata can be used in the preceding Poll State node to generate an output property, for example by setting msg.time to $entities('sensor.time').state to provide 'time' as an available value for use in the Switch node.

    1. For completeness in these notes, a last rule of 'Otherwise' has been included, and the matching rules set to 'checking all rules'. This will mean that more than one of the first three rules may match at the same time, but that the last route is only taken when no other rule matches.

    JSONata expression in the Debug node

    The Debug nodes also contain JSONata as a further demonstration of how versatile and applicable this language can be.

    Also see:

    `,25);function g(d,y){const n=e("RouterLink");return u(),c("div",null,[q,s("ul",null,[s("li",null,[a(n,{to:"/guide/jsonata/"},{default:t(()=>[o("JSONata guide")]),_:1})]),s("li",null,[a(n,{to:"/guide/jsonata/jsonata-primer.html"},{default:t(()=>[o("JSONata primer")]),_:1})])])])}const m=p(i,[["render",g],["__file","switch-node.html.vue"]]);export{m as default}; diff --git a/assets/switch-node.html-CMVtiJEI.js b/assets/switch-node.html-CMVtiJEI.js new file mode 100644 index 0000000000..76a17dfae4 --- /dev/null +++ b/assets/switch-node.html-CMVtiJEI.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3bf2614c","path":"/cookbook/jsonata/switch-node.html","title":"Switch node","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Using JSONata in switch routing","slug":"using-jsonata-in-switch-routing","link":"#using-jsonata-in-switch-routing","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/jsonata/switch-node.md"}');export{t as data}; diff --git a/assets/switch.html-BDSO4KRT.js b/assets/switch.html-BDSO4KRT.js new file mode 100644 index 0000000000..f850eeab12 --- /dev/null +++ b/assets/switch.html-BDSO4KRT.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4b35e291","path":"/node/switch.html","title":"Switch","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Enable input","slug":"enable-input","link":"#enable-input","children":[]},{"level":3,"title":"Output on state change","slug":"output-on-state-change","link":"#output-on-state-change","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"msg.enable","slug":"msg-enable","link":"#msg-enable","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]}],"git":{"updatedTime":1662369628000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"node/switch.md"}');export{e as data}; diff --git a/assets/switch.html-BsSKqMFL.js b/assets/switch.html-BsSKqMFL.js new file mode 100644 index 0000000000..b10f5a9e3e --- /dev/null +++ b/assets/switch.html-BsSKqMFL.js @@ -0,0 +1,2 @@ +import{_ as r,r as t,o as l,c as k,a as s,d as n,b as a,w as p,e as u}from"./app-DW3AHQOa.js";const i="/node-red-contrib-home-assistant-websocket/assets/switch_usage-BysMPBbE.png",y={},g={class:"custom-container warning"},b=s("p",{class:"custom-container-title"},"WARNING",-1),d={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},h=u('

    Switch

    Creates a switch in Home Assistant which can be manipulated from this node.

    Configuration

    Enable input

    Input is disabled by default. It can be enabled by checking this option.

    Output on state change

    • Type: boolean

    When the state of the switch changes it will output to the top if the switch is on or to the bottom if it is in the off position.

    Inputs

    msg.enable

    • Type: boolean

    Set to true to turn on the switch and false to turn it off. If the message has a property enable defined and set to a boolean the node will not have any output.

    Outputs

    Status Color

    • Green/Red: output from the node was due to input to the node
    • Blue: output from the node was due to the state of the node changing
    • Yellow: state of node changed but no output

    Examples

    ',16),m={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/switch.html#examples",target:"_blank",rel:"noopener noreferrer"},f=s("h4",{id:"usage-example",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#usage-example","aria-hidden":"true"},"#"),n(" Usage example")],-1),v=s("p",null,[s("img",{src:i,alt:"screenshot"})],-1),w=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fab7baeb7be8c516"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"on b"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"434"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1072"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"85438e0d960024f9"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"5"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"nodered"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"trigger"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"areaId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"switch.switch_test"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{\\"payload\\": \\"i am the payload\\"}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergeContext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"queue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"320"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1216"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"026d576cab2ba685"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"date"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"132"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1216"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"85438e0d960024f9"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ecc4cf9f7bed0a46"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"off b"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"434"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1120"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"489165f36ed911cf"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"5"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"switch"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"toggle"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"areaId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"switch.switch_test"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergeContext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"queue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"326"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"832"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7e026638397d33b7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"toggle switch state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"date"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"150"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"832"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"489165f36ed911cf"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"aa7e8ed024dab3c8"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"server-state-changed"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"4"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"exposeToHomeAssistant"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfilter"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"switch.switch_test"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfiltertype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"exact"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputinitially"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haltifstate"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_compare"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_only_on_state_change"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"for"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"num"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"minutes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateNull"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"204"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"784"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"657d91f04b24f723"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"date"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"132"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1120"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"b85c010f7e098b73"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"baac3eb05828d07e"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"enable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"enable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"v"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"true"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bool"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"126"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1024"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"b85c010f7e098b73"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"051cdb052c6f99db"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"disable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"enable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"v"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"false"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bool"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"126"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1072"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"b85c010f7e098b73"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"b85c010f7e098b73"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-switch"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"2"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"9236992af61f2695"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"enableInput"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputOnStateChange"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"state change"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entityState"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"data"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"$entity()"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"294"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1072"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"fab7baeb7be8c516"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"ecc4cf9f7bed0a46"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6c90e6c00caee078"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"on a"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"434"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"928"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"b57fa2a7ad97b2eb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"off a"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"434"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"976"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"238e849949f437e6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"date"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"132"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"976"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"a6736ba07743d64e"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"74d43743ff8f07b3"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"enable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"enable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"v"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"true"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bool"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"118"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"880"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"a6736ba07743d64e"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"d1d4b53d44caeb92"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"disable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"enable"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"v"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"false"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bool"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"122"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"928"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"a6736ba07743d64e"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"a6736ba07743d64e"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-switch"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"2"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"9236992af61f2695"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"enableInput"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputOnStateChange"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"state change"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entityState"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"$entity().state = true ? \\"on\\" : \\"off\\""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"294"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"928"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"6c90e6c00caee078"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"b57fa2a7ad97b2eb"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1f28cd07093de4bf"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"comment"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"outputs on state change"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"info"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"344"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"880"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bc15274098491edc"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"comment"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"does not output on state change"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"info"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"374"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1024"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7d848a75391906d1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"comment"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c84b6e0a642a4bce"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"use nodered.trigger service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"info"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"350"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1168"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"9236992af61f2695"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-entity-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"e120e5718cc68a9a"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"_ADD_"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"switch test"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"switch"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"switch test"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_category"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"device_class"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"switch"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"resend"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1);function _(x,T){const o=t("ExternalLinkIcon"),e=t("InfoPanelOnly"),c=t("DocsOnly");return l(),k("div",null,[s("div",g,[b,s("p",null,[s("em",null,[n("Needs "),s("a",d,[n("Custom Integration"),a(o)]),n(" installed in Home Assistant for this node to function")])])]),h,a(e,null,{default:p(()=>[s("p",null,[s("a",m,[n("link"),a(o)])])]),_:1}),a(c,null,{default:p(()=>[f,v,w]),_:1})])}const I=r(y,[["render",_],["__file","switch.html.vue"]]);export{I as default}; diff --git a/assets/switch_usage-BysMPBbE.png b/assets/switch_usage-BysMPBbE.png new file mode 100644 index 0000000000..cf52e14a5c Binary files /dev/null and b/assets/switch_usage-BysMPBbE.png differ diff --git a/assets/tag.html-Bt41HB9x.js b/assets/tag.html-Bt41HB9x.js new file mode 100644 index 0000000000..e0dc5add66 --- /dev/null +++ b/assets/tag.html-Bt41HB9x.js @@ -0,0 +1 @@ +import{_ as e,o as t,c as a,e as d}from"./app-DW3AHQOa.js";const i={},n=d('

    Tag

    Sends an output when Home Assistant receives a tag scanned event for a configured tag id.

    Configuration

    Tags

    • Type: array

    An array of tag ids to monitor for tag scanned events.

    Devices

    • Type: array

    An array of device ids to check when a configured tag is scanned.

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • event data: full event object
    • tag id: tag id of the tag that was scanned.
    • config: config properties of the node

    event object

    • Type: object
    FieldDescription
    device_idID of the device that scanned the tag
    tag_idID of the tag that was scanned
    tag_nameHome Assistant name of the tag that was scanned
    user_idHome Assistant user ID on device that scanned the tag
    ',18),o=[n];function s(r,c){return t(),a("div",null,o)}const l=e(i,[["render",s],["__file","tag.html.vue"]]);export{l as default}; diff --git a/assets/tag.html-CUfdOsmM.js b/assets/tag.html-CUfdOsmM.js new file mode 100644 index 0000000000..468b147118 --- /dev/null +++ b/assets/tag.html-CUfdOsmM.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8d481eda","path":"/node/tag.html","title":"Tag","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Tags","slug":"tags","link":"#tags","children":[]},{"level":3,"title":"Devices","slug":"devices","link":"#devices","children":[]},{"level":3,"title":"Expose as","slug":"expose-as","link":"#expose-as","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"event object","slug":"event-object","link":"#event-object","children":[]}]}],"git":{"updatedTime":1690420418000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":5}]},"filePathRelative":"node/tag.md"}');export{e as data}; diff --git a/assets/text.html-CoRz7I1B.js b/assets/text.html-CoRz7I1B.js new file mode 100644 index 0000000000..5886fc5905 --- /dev/null +++ b/assets/text.html-CoRz7I1B.js @@ -0,0 +1,2 @@ +import{_ as l,r as t,o as k,c as u,a as s,d as n,b as a,w as e,e as i}from"./app-DW3AHQOa.js";const y="/node-red-contrib-home-assistant-websocket/assets/text_01-D7Qj4SJH.png",g={},d={class:"custom-container warning"},b=s("p",{class:"custom-container-title"},"WARNING",-1),m={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},f=s("h1",{id:"text",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#text","aria-hidden":"true"},"#"),n(" Text")],-1),h=s("p",null,"Creates a text entity in Home Assistant which can be manipulated from this node.",-1),v=s("h2",{id:"configuration",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),n(" Configuration")],-1),_={id:"mode",tabindex:"-1"},x=s("a",{class:"header-anchor",href:"#mode","aria-hidden":"true"},"#",-1),T=s("ul",null,[s("li",null,"Type: 'listen' | 'get' | 'set'")],-1),w=s("p",null,"The mode of the node",-1),z={id:"text-1",tabindex:"-1"},j=s("a",{class:"header-anchor",href:"#text-1","aria-hidden":"true"},"#",-1),C=i('
    • Type: string

    The string of the entity should be updated to

    Inputs

    properties of msg.payload

    Text

    • Type: string

    The string of the text entity should be updated to

    Outputs

    Value types:

    • value: The text string of the entity
    • previous value: The previous text string of the entity
    • config: The config properties of the node

    Examples

    ',11),V={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/text.html#examples",target:"_blank",rel:"noopener noreferrer"},I=s("h4",{id:"usage-example",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#usage-example","aria-hidden":"true"},"#"),n(" Usage example")],-1),P=s("p",null,[s("img",{src:y,alt:"screenshot"})],-1),S=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"dfc9e6f2b6ed5571"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"114"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"112"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"87c9fa353286db95"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"87c9fa353286db95"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"function"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"random string"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"func"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg.payload = Math.random().toString(36).substring(2, 10);\\n\\nreturn msg;"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"noerr"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"initialize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"finalize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"libs"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"296"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"112"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"f2a130d21700183b"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"871c3d4514b6adf5"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"text listen"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous & \\" : \\" & payload "'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"276"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"208"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"19ba2e97602e8052"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-text"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"541bfa3ffd06ec54"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"listen"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"118"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"208"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"871c3d4514b6adf5"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"f2a130d21700183b"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-text"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"541bfa3ffd06ec54"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"458"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"112"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"abf17eb28388908a"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"abf17eb28388908a"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"text set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous & \\" : \\" & payload "'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"628"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"112"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"cfdda78a4cc69c43"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"server-state-changed"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"4"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"exposeToHomeAssistant"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfilter"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"text.test_text"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfiltertype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"exact"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputinitially"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haltifstate"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_compare"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_only_on_state_change"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"for"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"num"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"minutes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateNull"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entityState"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"eventData"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"184"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"ad7370fad9297783"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ad7370fad9297783"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"event state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous.old_state.state & \\" : \\" & payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"422"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"256"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2a2de323bc72c720"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"114"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"64"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"f888cc8fd9e941d4"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c29c8b6386defada"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"5"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"text"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set_value"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"areaId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"text.test_text"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{\\"value\\": payload }"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergeContext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"queue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"488"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"64"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"f888cc8fd9e941d4"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"function"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"random string"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"func"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg.payload = Math.random().toString(36).substring(2, 10);\\n\\nreturn msg;"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"noerr"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"initialize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"finalize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"libs"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"296"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"64"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"c29c8b6386defada"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"834d55ad3daf03df"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"114"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"160"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"9fba568d70b10862"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"9fba568d70b10862"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-text"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"541bfa3ffd06ec54"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"458"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"160"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"c2cfe2d328d54aa3"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"c2cfe2d328d54aa3"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"22cd01e6b12bd120"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"text get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previous & \\" : \\" & payload "'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"628"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"160"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"541bfa3ffd06ec54"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-entity-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"test text"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"text"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"test text"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_category"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_picture"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"mode"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"text"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"min_length"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"max_length"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"pattern"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"resend"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugEnabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1);function N(D,U){const o=t("ExternalLinkIcon"),p=t("Badge"),c=t("InfoPanelOnly"),r=t("DocsOnly");return k(),u("div",null,[s("div",d,[b,s("p",null,[s("em",null,[n("Needs "),s("a",m,[n("Custom Integration"),a(o)]),n(" installed in Home Assistant for this node to function")])])]),f,h,v,s("h3",_,[x,n(" Mode "),a(p,{text:"required"})]),T,w,s("h3",z,[j,n(" Text "),a(p,{text:"required"})]),C,a(c,null,{default:e(()=>[s("p",null,[s("a",V,[n("link"),a(o)])])]),_:1}),a(r,null,{default:e(()=>[I,P,S]),_:1})])}const B=l(g,[["render",N],["__file","text.html.vue"]]);export{B as default}; diff --git a/assets/text.html-DGk7Mgec.js b/assets/text.html-DGk7Mgec.js new file mode 100644 index 0000000000..eef7ab70f7 --- /dev/null +++ b/assets/text.html-DGk7Mgec.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-092d5338","path":"/node/text.html","title":"Text","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Mode","slug":"mode","link":"#mode","children":[]},{"level":3,"title":"Text","slug":"text-1","link":"#text-1","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"Text","slug":"text-2","link":"#text-2","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]}],"git":{"updatedTime":1689466731000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/text.md"}');export{e as data}; diff --git a/assets/text_01-D7Qj4SJH.png b/assets/text_01-D7Qj4SJH.png new file mode 100644 index 0000000000..0bdf752dbb Binary files /dev/null and b/assets/text_01-D7Qj4SJH.png differ diff --git a/assets/time-entity.html-D25rrN03.js b/assets/time-entity.html-D25rrN03.js new file mode 100644 index 0000000000..e3fa3b31a1 --- /dev/null +++ b/assets/time-entity.html-D25rrN03.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4de356ea","path":"/node/time-entity.html","title":"Time","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Mode","slug":"mode","link":"#mode","children":[]},{"level":3,"title":"Value","slug":"value","link":"#value","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"value","slug":"value-1","link":"#value-1","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]}],"git":{"updatedTime":1689556943000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":1}]},"filePathRelative":"node/time-entity.md"}');export{e as data}; diff --git a/assets/time-entity.html-Dqh-2uOd.js b/assets/time-entity.html-Dqh-2uOd.js new file mode 100644 index 0000000000..30bc869f29 --- /dev/null +++ b/assets/time-entity.html-Dqh-2uOd.js @@ -0,0 +1,2 @@ +import{_ as l,r as t,o as k,c as u,a as s,d as n,b as a,w as e,e as i}from"./app-DW3AHQOa.js";const y="/node-red-contrib-home-assistant-websocket/assets/time_entity_01-Brx2iLlv.png",g={},d={class:"custom-container warning"},f=s("p",{class:"custom-container-title"},"WARNING",-1),m={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},b=s("h1",{id:"time",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#time","aria-hidden":"true"},"#"),n(" Time")],-1),h=s("p",null,"Creates a time entity in Home Assistant which can be manipulated from this node or Home Assistant.",-1),v=s("h2",{id:"configuration",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),n(" Configuration")],-1),_={id:"mode",tabindex:"-1"},x=s("a",{class:"header-anchor",href:"#mode","aria-hidden":"true"},"#",-1),T=s("ul",null,[s("li",null,"Type: 'listen' | 'get' | 'set'")],-1),w=s("p",null,"The mode of the node",-1),z={id:"value",tabindex:"-1"},H=s("a",{class:"header-anchor",href:"#value","aria-hidden":"true"},"#",-1),M=i('
    • Type: string
    • Format: HH:mm:ss | HH:mm

    The value of the entity should be updated to

    Inputs

    properties of msg.payload

    value

    • Type: string
    • Format: HH:mm:ss | HH:mm

    The value of the entity should be updated to

    Outputs

    Value types:

    • value: The value of the entity
    • previous value: The previous value of the entity
    • config: The config properties of the node

    Examples

    ',11),S={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/time-entity.html#examples",target:"_blank",rel:"noopener noreferrer"},V=s("h4",{id:"usage-example",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#usage-example","aria-hidden":"true"},"#"),n(" Usage example")],-1),j=s("p",null,[s("img",{src:y,alt:"screenshot"})],-1),C=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"5a3098079cfdd280"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"server-state-changed"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"4"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"exposeToHomeAssistant"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfilter"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time.time_test"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityidfiltertype"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"exact"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputinitially"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haltifstate"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"halt_if_compare"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"is"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"output_only_on_state_change"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"for"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"num"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"forUnits"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"minutes"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateNull"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignorePrevStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnknown"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"ignoreCurrentStateUnavailable"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"eventData"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"216"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"624"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"af4b36c8422aec66"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"af4b36c8422aec66"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"event state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload.old_state.state & \\" : \\" & payload.new_state.state"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"522"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"624"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2f80e30a8dc150d8"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time listen"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue & \\" : \\" & payload "'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"508"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"576"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1a40e5a4d0f530d2"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"154"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"336"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"621d17a1e3fbb9a5"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4c727df1bc583e44"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"api-call-service"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"5"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"domain"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"service"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set_value"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"areaId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityId"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"time.time_test"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"data"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"{\\"time\\": payload}"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"dataType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mergeContext"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mustacheAltTags"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"queue"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"none"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"528"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"480"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"2a4a0d5fc9bb8d86"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue & \\" : \\" & payload "'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"636"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"336"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"f3b9c9fb22295113"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"154"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"528"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"d5731b07e4893926"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"276afdfb58fe76f1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"debug"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"active"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tosidebar"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"console"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"tostatus"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"complete"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"targetType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusVal"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"statusType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"auto"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"508"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"528"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"8954ce09cca90f63"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-time-entity"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"listen time"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fa434795e5d1be74"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"listen"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"156"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"576"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2f80e30a8dc150d8"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"d5731b07e4893926"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-time-entity"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"get time"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fa434795e5d1be74"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"get"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"290"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"528"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"276afdfb58fe76f1"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fa09042625445217"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-time-entity"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set time"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugenabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fa434795e5d1be74"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"set"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"value"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"propertyType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"msg"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"valueType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"previousValue"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"494"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"336"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"2a4a0d5fc9bb8d86"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"458c8d233a9d18af"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"155"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"288"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"74d5dc5ff4d3c0cb"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"9c23cc9f504fa4a1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link in"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"HH:MM:SS"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"156"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"7e92542f4ff33de0"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"l"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"cd50b5472f373ad6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link in"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"HH:MM"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"146"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"801e1e33127e8d4c"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"l"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"true"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7e92542f4ff33de0"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"function"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"generate time HH:MM:SS"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"func"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},"\"const randomHour = Math.floor(Math.random() * 24);\\nconst randomMinute = Math.floor(Math.random() * 60);\\nconst randomSecond = Math.floor(Math.random() * 60);\\n\\nmsg.payload = `${randomHour}:${randomMinute\\n .toString()\\n .padStart(2, '0')}:${randomSecond.toString().padStart(2, '0')}`;\\n\\n\\nreturn msg;\""),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"noerr"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"initialize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"finalize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"libs"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"351"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"1b78615c029b6dab"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"801e1e33127e8d4c"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"function"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"generate time HH:MM"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"func"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},"\"const randomHour = Math.floor(Math.random() * 24);\\nconst randomMinute = Math.floor(Math.random() * 60);\\n\\nmsg.payload = `${randomHour}:${randomMinute\\n .toString()\\n .padStart(2, '0')}`;\\n\\n\\nreturn msg;\""),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputs"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"noerr"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"initialize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"finalize"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"libs"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"341"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"cc16260a68095e77"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"1b78615c029b6dab"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link out"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link out 1"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"return"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"519"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"cc16260a68095e77"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link out"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link out 2"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"mode"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"return"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"519"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"74d5dc5ff4d3c0cb"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link call"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"9c23cc9f504fa4a1"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"linkType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"static"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"timeout"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"30"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"310"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"288"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"fa09042625445217"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"621d17a1e3fbb9a5"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link call"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"cd50b5472f373ad6"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"linkType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"static"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"timeout"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"30"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"300"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"336"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"fa09042625445217"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"decebfa96ff2b375"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"154"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"480"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"5e44eb1c1de80d82"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"34e9926f8d967e47"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"154"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"432"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"e711fd4eb0f21d6f"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"e711fd4eb0f21d6f"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link call"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"9c23cc9f504fa4a1"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"linkType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"static"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"timeout"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"30"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"310"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"432"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"4c727df1bc583e44"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"5e44eb1c1de80d82"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"link call"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"links"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"cd50b5472f373ad6"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"linkType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"static"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"timeout"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"30"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"300"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"480"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"4c727df1bc583e44"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"861b8a79994a76cd"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"7f704f92ee3c3f87"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"invalid"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"invalid"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"153"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"384"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"fa09042625445217"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fa434795e5d1be74"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-entity-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"65bf2a1a7e89a8d9"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time test"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"time test"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_category"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_picture"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"resend"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugEnabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"65bf2a1a7e89a8d9"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-device-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"test device"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"hwVersion"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"manufacturer"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Node-RED"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"model"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"swVersion"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1);function D(I,P){const o=t("ExternalLinkIcon"),p=t("Badge"),c=t("InfoPanelOnly"),r=t("DocsOnly");return k(),u("div",null,[s("div",d,[f,s("p",null,[s("em",null,[n("Needs "),s("a",m,[n("Custom Integration"),a(o)]),n(" installed in Home Assistant for this node to function")])])]),b,h,v,s("h3",_,[x,n(" Mode "),a(p,{text:"required"})]),T,w,s("h3",z,[H,n(" Value "),a(p,{text:"required"})]),M,a(c,null,{default:e(()=>[s("p",null,[s("a",S,[n("link"),a(o)])])]),_:1}),a(r,null,{default:e(()=>[V,j,C]),_:1})])}const E=l(g,[["render",D],["__file","time-entity.html.vue"]]);export{E as default}; diff --git a/assets/time.html-B0UXqkE9.js b/assets/time.html-B0UXqkE9.js new file mode 100644 index 0000000000..317a2d97ab --- /dev/null +++ b/assets/time.html-B0UXqkE9.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4934c998","path":"/node/time.html","title":"Time","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entity Id","slug":"entity-id","link":"#entity-id","children":[]},{"level":3,"title":"Property","slug":"property","link":"#property","children":[]},{"level":3,"title":"Offset","slug":"offset","link":"#offset","children":[]},{"level":3,"title":"Randomize time within the offset","slug":"randomize-time-within-the-offset","link":"#randomize-time-within-the-offset","children":[]},{"level":3,"title":"Payload","slug":"payload","link":"#payload","children":[]},{"level":3,"title":"Repeat Daily","slug":"repeat-daily","link":"#repeat-daily","children":[]},{"level":3,"title":"Expose as","slug":"expose-as","link":"#expose-as","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"topic","slug":"topic","link":"#topic","children":[]},{"level":3,"title":"payload","slug":"payload-1","link":"#payload-1","children":[]},{"level":3,"title":"data","slug":"data","link":"#data","children":[]}]}],"git":{"updatedTime":1700515926000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":4},{"name":"t1diotac","email":"87152403+t1diotac@users.noreply.github.com","commits":1}]},"filePathRelative":"node/time.md"}');export{e as data}; diff --git a/assets/time.html-DSURmXX5.js b/assets/time.html-DSURmXX5.js new file mode 100644 index 0000000000..1b95ede98c --- /dev/null +++ b/assets/time.html-DSURmXX5.js @@ -0,0 +1 @@ +import{_ as e,o as t,c as a,e as i}from"./app-DW3AHQOa.js";const d={},o=i('

    Time

    A node that can be scheduled to trigger at a future date and time from a Home Assistant entity.

    Configuration

    Entity Id

    • Type: string

    A Home Assistant entity to be used when scheduling the node.

    Property

    • Type: string

    Which property of the entity object to use to schedule the node.

    example properties:

    • entity_id
    • state
    • attributes.date
    • last_updated

    example values for the property:

    • 2020-12-31T02:47:54.837Z
    • 1609382842709
    • 13:40
    • 23:59:02

    Offset

    • Type: number

    A negative or positive number that will be added to the scheduled time.

    Randomize time within the offset

    • Type: boolean

    When selected the time to trigger will be random selected from the scheduled time to the +/- offset.

    Payload

    • Type: string | number | boolean | object

    The payload is fully customizable. The default will be a JSONata expression that outputs the entity state.

    Repeat Daily

    • Type: boolean

    If selected the node will only use the time portion of the date string to schedule the node and will trigger at that time each day. Otherwise, the node will only trigger once at the given day and time.

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    topic

    • Type: string

    The entity id in the configuration.

    payload

    • Type: string | number | boolean | object

    data

    • Type: object

    The entity object of the entity in the configuration.

    ',37),l=[o];function h(n,r){return t(),a("div",null,l)}const s=e(d,[["render",h],["__file","time.html.vue"]]);export{s as default}; diff --git a/assets/time_entity_01-Brx2iLlv.png b/assets/time_entity_01-Brx2iLlv.png new file mode 100644 index 0000000000..67f7de0e1a Binary files /dev/null and b/assets/time_entity_01-Brx2iLlv.png differ diff --git a/assets/trigger-state.html-3KwTutxw.js b/assets/trigger-state.html-3KwTutxw.js new file mode 100644 index 0000000000..bde735dcef --- /dev/null +++ b/assets/trigger-state.html-3KwTutxw.js @@ -0,0 +1,10 @@ +import{_ as c,r as n,o as l,c as h,a as e,d as t,b as a,w as s,f as u,e as i}from"./app-DW3AHQOa.js";const p={},g=e("h1",{id:"trigger-state",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trigger-state","aria-hidden":"true"},"#"),t(" Trigger: state")],-1),b=e("p",null,[t("An advanced version of the "),e("code",null,"events: state"),t(" node")],-1),f=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),m={id:"entity",tabindex:"-1"},_=e("a",{class:"header-anchor",href:"#entity","aria-hidden":"true"},"#",-1),y=i('
    • Type: string

      The entity ID is used to listen for state changes. This can be a entity ID, regex, or a substring. If a regex or substring is used, the node will listen for all entities that match.

    Example:

    • light.kitchen (entity) listens for state changes of the light.kitchen entity
    • ^light.* (regex) listens for state changes of all entities that start with light.
    • light (substring) listens for state changes of all entities that contain light in the entity ID

    State Type

    • Type: string
    • Values: string|number|boolean
    • Default: string

    Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

    Conditions

    This node has two default outputs "allowed" and "blocked". If all the conditions are true the default message will be sent to the "allowed" output otherwise, it will be sent to the "blocked" output.

    See Also:

    ',9),x=i(`

    Custom Outputs

    All the above conditions need to be true for any custom outputs to be sent, having zero conditions is a valid option. Each custom output can send the default message or a custom message. Also, each one can have its constraint on whether or not to be sent.

    Output on connect

    • Type: boolean

    Output once on startup/deployment.

    Enable input

    • Type: boolean

    Enable the input to be used to send a message to the node.

    Output debug information

    • Type: boolean

    Output debug information to the debug tab.

    Expose to Home Assistant

    • Type: boolean

    Expose the node to Home Assistant.

    Input

    Input is disabled by default. It can be enabled using the Enable Input option. Input can be used to enable/disable the node or for testing.

    Enable / Disable

    • Type: string

    If the incoming payload or message is a string and equal to enable or disable then set the node accordingly. Saves over restarts.

    Output

    topic

    • Type: string

    The entity_id that triggered the node

    payload

    • Type: string

    The state as sent by home assistant

    data

    • Type: object

    The original home assistant event containing entity_id new_state and old_state properties

    Testing

    To test automation without having to manually change the state in home assistant send an input payload as an object which contains entity_id, new_state, and old_state properties. This will trigger the node as if the event came from Home Assistant.

    {
    +  "entity_id": "test_entity",
    +  "old_state": {
    +    "state": "on"
    +  },
    +  "new_state": {
    +    "state": "off"
    +  }
    +}
    +

    References

    `,33),k={href:"https://home-assistant.io/docs/configuration/state_object",target:"_blank",rel:"noopener noreferrer"};function q(v,T){const o=n("RouterLink"),d=n("Badge"),r=n("ExternalLinkIcon");return l(),h("div",null,[g,e("p",null,[t("Much like the "),a(o,{to:"/node/events-state.html"},{default:s(()=>[t("events: state")]),_:1}),t(" however, provides some advanced functionality around common automation use cases.")]),b,u(" TODO: Needs a total rework "),f,e("h3",m,[_,t(" Entity "),a(d,{text:"required"})]),y,e("ul",null,[e("li",null,[a(o,{to:"/guide/conditionals.html"},{default:s(()=>[t("Conditionals")]),_:1})])]),x,e("ul",null,[e("li",null,[e("a",k,[t("HA State Object"),a(r)])])])])}const I=c(p,[["render",q],["__file","trigger-state.html.vue"]]);export{I as default}; diff --git a/assets/trigger-state.html-DGjipkAb.js b/assets/trigger-state.html-DGjipkAb.js new file mode 100644 index 0000000000..e4a12e9718 --- /dev/null +++ b/assets/trigger-state.html-DGjipkAb.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-e2ca69aa","path":"/cookbook/jsonata/trigger-state.html","title":"Trigger: state","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Using JSONata to set a condition value","slug":"using-jsonata-to-set-a-condition-value","link":"#using-jsonata-to-set-a-condition-value","children":[]},{"level":3,"title":"Using JSONata to create a custom message","slug":"using-jsonata-to-create-a-custom-message","link":"#using-jsonata-to-create-a-custom-message","children":[]}],"git":{"updatedTime":1719788083000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":2}]},"filePathRelative":"cookbook/jsonata/trigger-state.md"}');export{t as data}; diff --git a/assets/trigger-state.html-DOz_296k.js b/assets/trigger-state.html-DOz_296k.js new file mode 100644 index 0000000000..4334511b60 --- /dev/null +++ b/assets/trigger-state.html-DOz_296k.js @@ -0,0 +1,46 @@ +import{_ as p,r as e,o as u,c,a as s,b as a,w as t,d as o,e as r}from"./app-DW3AHQOa.js";const l="/node-red-contrib-home-assistant-websocket/assets/jsonata_4_1-CfZXdRrw.png",k={},i=r('

    Trigger: state

    The Trigger: state node is very similar to the Events: state node. It will trigger when a given entity state changes, but unlike the Events: state, the Trigger: state node has the opportunity to add conditions using UI fields to construct complex tests. This removes much of the need to manage conditional tests using JSONata.

    JSONata can be used in several places within this node. However real practical use is quite limited. Although the Trigger node has extensive conditional testing included as UI setting, it does not have access to the $entity() or $entities() function in the conditions. The example given here is rather simplistic and contrived to demonstrate that JSONata can be used, rather than focusing on a genuinue or realistic use-case.

    screenshot

    Example: Respond every five minutes during the hour before and hour after sunset.

    [{"id":"3a2face9747195a7","type":"group","z":"776c027950fc8c3f","name":"Trigger: state node - respond to state changes","style":{"label":true,"color":"#000000"},"nodes":["320b22abb5a9ea96","da88972398c7ed97","c2d9f44ffe436dcc","2144de490d4257d7","94ceadbce4b45cdf","79b056d9779ec8f1","360fe19e1e203539","247cbab5f584ea63","0509fc220ff7735e","8fc293f5015dd3d5"],"x":34,"y":1359,"w":872,"h":302},{"id":"320b22abb5a9ea96","type":"inject","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Testing","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\\t   \\"entity_id\\": \\"sensor.time_utc\\",\\t   \\"old_state\\": {\\"state\\": \\"16:49\\"},\\t   \\"new_state\\": {\\"state\\": \\"16:50\\"}\\t}","payloadType":"jsonata","x":130,"y":1400,"wires":[["da88972398c7ed97"]]},{"id":"da88972398c7ed97","type":"trigger-state","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Actions around sunset","server":"","version":4,"inputs":1,"outputs":3,"exposeAsEntityConfig":"","entityId":"sensor.time_utc","entityIdType":"exact","debugEnabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"includes","comparatorValueDatatype":"jsonata","comparatorValue":"(\\t/* UTC sunrise & sunset to 5 mins, month average (London UK) */\\t/* Jan-Dec, Feb-Nov, Mar-Oct, Apr-Sep, May-Aug, Jun-Jly      */\\t    $times:=[[\\"07:55\\", \\"16:20\\"],\\t             [\\"07:15\\", \\"16:45\\"],\\t             [\\"06:00\\", \\"17:35\\"],\\t             [\\"05:15\\", \\"18:30\\"],\\t             [\\"04:30\\", \\"19:30\\"],\\t             [\\"04:05\\", \\"20:05\\"]];\\t\\t/* get this month (Jan=0), lookup sun-times table, return sun rise-set for this month */\\t    $mtable:=[0..11].$min([$, $abs($-11)]);\\t    $mindex:=$now('[M]').$number()-1;\\t\\t/* get sunset and build array of condition test-times around this */\\t    $sunset:=($times[$mtable[$mindex]])[1];\\t    $h:=$number($substringBefore($sunset, \\":\\"));\\t    $m:=$number($substringAfter($sunset, \\":\\"));\\t\\t/* for span period mins, generate array of times and select every nth */\\t    $span:=60;\\t    $nth:=5;\\t\\t    $t:=$h*60+$m-$span;\\t    ([$t..$t+$span*2])#$i.(\\t        $h:=$floor($/60);\\t        $m:=$%60;\\t        $i%$nth=0 ? $formatInteger($h,'99') & \\":\\" & $formatInteger($m, '99');\\t    )\\t)"}],"customOutputs":[{"messageType":"custom","messageValue":"(\\t    $sunset:=$entities('sensor.sun_next_setting').state;\\t    $togo:= ($toMillis($sunset)-$millis())/60000~>$floor();\\t    $toset:= $togo < 180 ? $togo : $togo-1440;\\t    $x:= $toset-25;\\t    $pc:= $x<0 and $x>-55 ? $min([$abs($x)*2, 100]) : null;\\t\\t    {\\"topic\\": \\"Minutes to Sunset\\",\\t     \\"payload\\": $toset,\\t     \\"time\\": $entities('sensor.time').state,\\t     \\"sunset\\": $sunset,\\t     \\"percent\\": $pc\\t    }\\t)","messageValueType":"jsonata","comparatorPropertyType":"always","comparatorPropertyValue":"","comparatorType":"is","comparatorValue":"","comparatorValueDataType":"jsonata"}],"outputInitially":false,"stateType":"str","enableInput":true,"x":300,"y":1440,"wires":[["c2d9f44ffe436dcc"],[],["2144de490d4257d7","247cbab5f584ea63"]]},{"id":"c2d9f44ffe436dcc","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Every 5 mins around sunset","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":580,"y":1400,"wires":[]},{"id":"2144de490d4257d7","type":"switch","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Sunset Actions","property":"payload","propertyType":"msg","rules":[{"t":"btwn","v":"0","vt":"num","v2":"4","v2t":"num"},{"t":"btwn","v":"10","vt":"num","v2":"14","v2t":"num"},{"t":"btwn","v":"0","vt":"num","v2":"-30","v2t":"num"},{"t":"else"}],"checkall":"false","repair":false,"outputs":4,"x":540,"y":1480,"wires":[["94ceadbce4b45cdf"],["79b056d9779ec8f1"],["360fe19e1e203539"],[]]},{"id":"94ceadbce4b45cdf","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"At Sunset","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":780,"y":1440,"wires":[]},{"id":"79b056d9779ec8f1","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Just Before","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":790,"y":1500,"wires":[]},{"id":"360fe19e1e203539","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Just After","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":780,"y":1560,"wires":[]},{"id":"247cbab5f584ea63","type":"change","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Brightness 0-100% over 50 min","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\\t    \\"domain\\": \\"homeassistant\\",\\t    \\"service\\": \\"turn_on\\",\\t    \\"target\\": {\\t        \\"entity_id\\": [\\"light.front_door\\", \\"switch.hall_light\\"]\\t        },\\t    \\"data\\": {\\t        \\"brightness_pct\\": percent\\t    }\\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":1620,"wires":[["8fc293f5015dd3d5"]]},{"id":"0509fc220ff7735e","type":"api-call-service","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"","server":"","version":5,"debugenabled":false,"domain":"homeassistant","service":"turn_on","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":760,"y":1620,"wires":[[]]},{"id":"8fc293f5015dd3d5","type":"switch","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Not null","property":"payload.data.brightness_pct","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":540,"y":1620,"wires":[["0509fc220ff7735e"]]}]
    +

    Sunrise and sunset times are often critical to running automations, and Home Assistant has inbuilt entities that provide the next dawn, sunrise, dusk, and sunset times. In order to be able to respond to multiple events during the period both before and after sunset, it is necessary to trigger at a more regular interval, not just on the sun-events, and then to test for required times or periods before and after sunset.

    The Trigger: state node can be set to use the sensor.time_utc entity as the subject of the node. This sensor holds UTC time as "hh:mm", and will change every minute, thus triggering a state change at regular 60 second intervals. We can add conditions to test the time against an expected period around sunset, and to generate a customised output that includes given periods or times before or after sunset. Combined with a Switch node this permits multiple tests and multiple automation events to be actioned.

    Using JSONata to set a condition value

    Here JSONata is used to generate an array of times of interest. When the trigger entity state, UTC time "hh:mm", is included in the calculated array, the condition is met and a message will be output.

    Since JSONata does not have access to the $entities() function in this particular UI field, the code here is used to generate a period of interest based on hard-coded sunrise and sunset times according to the current month. This is not ideal, but does demonstrate how JSONata can be used to easily generate and manipulate various JSON structures.

    (
    +/* UTC sunrise & sunset to 5 mins, month average (London UK) */
    +/* Jan-Dec, Feb-Nov, Mar-Oct, Apr-Sep, May-Aug, Jun-Jly      */
    +    $times:=[["07:55", "16:20"],
    +             ["07:15", "16:45"],
    +             ["06:00", "17:35"],
    +             ["05:15", "18:30"],
    +             ["04:30", "19:30"],
    +             ["04:05", "20:05"]];
    +
    +/* get this month (Jan=0), lookup sun-times table, return sun rise-set for this month */
    +    $mtable:=[0..11].$min([$, $abs($-11)]);
    +    $mindex:=$now('[M]').$number()-1;
    +
    +/* get sunset and build array of condition test-times around this */
    +    $sunset:=($times[$mtable[$mindex]])[1];
    +    $h:=$number($substringBefore($sunset, ":"));
    +    $m:=$number($substringAfter($sunset, ":"));
    +
    +/* for span period mins, generate array of times and select every nth */
    +    $span:=60;
    +    $nth:=5;
    +
    +    $t:=$h*60+$m-$span;
    +    ([$t..$t+$span*2])#$i.(
    +        $h:=$floor($/60);
    +        $m:=$%60;
    +        $i%$nth=0 ? $formatInteger($h,'99') & ":" & $formatInteger($m, '99');
    +    )
    +)
    +

    This code uses the current month to lookup a given sunset time, and then to generate an array of times either side of expected sunset, using a given span in minutes, and then picking out every five minutes only.

    The figures provided are examples, based on UTC times (DST ignored) for location London, UK and estimate an average sunrise and sunset time for each calendar month. Since sun events can move by up to one hour from start to end of a month, a span of at least 30 minutes is required to successfully include events across the entire month.

    Using JSONata to create a custom message

    The output properties on successful trigger include a default message and a default payload, which includes the basic event details for the trigger entity. It is possible to set the output as a customised payload, which replaces msg.payload with specific output, or as a customised message, which replaces the entire message with a generated object.

    (
    +    $sunset:=$entities('sensor.sun_next_setting').state;
    +    $togo:= ($toMillis($sunset)-$millis())/60000~>$floor();
    +    $toset:= $togo < 180 ? $togo : $togo-1440;
    +    $x:= $toset-25;
    +    $pc:= $x<0 and $x>-55 ? $min([$abs($x)*2, 100]) : null;
    +
    +    {"topic": "Minutes to Sunset",
    +     "payload": $toset,
    +     "time": $entities('sensor.time').state,
    +     "sunset": $sunset,
    +     "percent": $pc
    +    }
    +)
    +

    The $entities() function is available in JSONata in the output properties UI field, which means that both current time and sunset time can be obtained and compared. This allows some simple JSONata code to generate a complete message object, including msg.topic and msg.payload with the exact minutes to the next sunset correctly calculated.

    For automation, all that is required is a following Switch node set to route on a message property, for example msg.payload as minutes to next sunset between 0 and 4 (based on a five minute trigger interval) so as to be able to run an automation just as sunset is about to take place (with a five minute discrimination).

    As a further example, the JSONata output calculates a percentage value going from 0 to 100 over the period 25 minutes before to 25 minutes after sunset, with the percentage value set to 'null' outside this time. The Change node following also uses JSONata to create the entire Service Call node input settings, to turn on a group of lights in an timed-incremental fashion.

    Also see:

    `,21);function q(g,y){const n=e("RouterLink");return u(),c("div",null,[i,s("ul",null,[s("li",null,[a(n,{to:"/guide/jsonata/"},{default:t(()=>[o("JSONata guide")]),_:1})]),s("li",null,[a(n,{to:"/guide/jsonata/jsonata-primer.html"},{default:t(()=>[o("JSONata primer")]),_:1})])])])}const m=p(k,[["render",q],["__file","trigger-state.html.vue"]]);export{m as default}; diff --git a/assets/trigger-state.html-NF29hhpB.js b/assets/trigger-state.html-NF29hhpB.js new file mode 100644 index 0000000000..c7e4b2595c --- /dev/null +++ b/assets/trigger-state.html-NF29hhpB.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-bdb50f9e","path":"/node/trigger-state.html","title":"Trigger: state","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entity","slug":"entity","link":"#entity","children":[]},{"level":3,"title":"State Type","slug":"state-type","link":"#state-type","children":[]},{"level":3,"title":"Conditions","slug":"conditions","link":"#conditions","children":[]},{"level":3,"title":"Custom Outputs","slug":"custom-outputs","link":"#custom-outputs","children":[]},{"level":3,"title":"Output on connect","slug":"output-on-connect","link":"#output-on-connect","children":[]},{"level":3,"title":"Enable input","slug":"enable-input","link":"#enable-input","children":[]},{"level":3,"title":"Output debug information","slug":"output-debug-information","link":"#output-debug-information","children":[]},{"level":3,"title":"Expose to Home Assistant","slug":"expose-to-home-assistant","link":"#expose-to-home-assistant","children":[]}]},{"level":2,"title":"Input","slug":"input","link":"#input","children":[{"level":3,"title":"Enable / Disable","slug":"enable-disable","link":"#enable-disable","children":[]}]},{"level":2,"title":"Output","slug":"output","link":"#output","children":[{"level":3,"title":"topic","slug":"topic","link":"#topic","children":[]},{"level":3,"title":"payload","slug":"payload","link":"#payload","children":[]},{"level":3,"title":"data","slug":"data","link":"#data","children":[]}]},{"level":2,"title":"Testing","slug":"testing","link":"#testing","children":[]},{"level":2,"title":"References","slug":"references","link":"#references","children":[]}],"git":{"updatedTime":1722856632000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":10},{"name":"Mauricio Bonani","email":"bonanitech@gmail.com","commits":1}]},"filePathRelative":"node/trigger-state.md"}');export{e as data}; diff --git a/assets/update-config.html-BbAjktc_.js b/assets/update-config.html-BbAjktc_.js new file mode 100644 index 0000000000..d8adc2fa03 --- /dev/null +++ b/assets/update-config.html-BbAjktc_.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-eda05c32","path":"/node/update-config.html","title":"Update Config","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Name","slug":"name","link":"#name","children":[]},{"level":3,"title":"Server","slug":"server","link":"#server","children":[]},{"level":3,"title":"Entity Config","slug":"entity-config","link":"#entity-config","children":[]}]},{"level":2,"title":"Inputs","slug":"inputs","link":"#inputs","children":[{"level":3,"title":"Example input","slug":"example-input","link":"#example-input","children":[]},{"level":3,"title":"id","slug":"id","link":"#id","children":[]},{"level":3,"title":"icon","slug":"icon","link":"#icon","children":[]},{"level":3,"title":"name","slug":"name-1","link":"#name-1","children":[]},{"level":3,"title":"entityPicture","slug":"entitypicture","link":"#entitypicture","children":[]}]},{"level":2,"title":"Examples","slug":"examples","link":"#examples","children":[]}],"git":{"updatedTime":1678660828000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":4}]},"filePathRelative":"node/update-config.md"}');export{e as data}; diff --git a/assets/update-config.html-Ctl76Lel.js b/assets/update-config.html-Ctl76Lel.js new file mode 100644 index 0000000000..207e8a71e7 --- /dev/null +++ b/assets/update-config.html-Ctl76Lel.js @@ -0,0 +1,8 @@ +import{_ as k,r as t,o as u,c as i,a as s,d as n,b as a,w as o,e}from"./app-DW3AHQOa.js";const y="/node-red-contrib-home-assistant-websocket/assets/update_config_use01-BXE5av9O.png",d={},g=e('

    Update Config

    This node allows you to update the Home Assistant configuration of a node from within a flow. This is useful if you want to change the configuration of a node based on the state of an entity or some other event.

    Configuration

    Name

    • Type: string

    A name for the node.

    Server

    • Type: string
    ',8),h=s("h3",{id:"entity-config",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#entity-config","aria-hidden":"true"},"#"),n(" Entity Config")],-1),f=s("ul",null,[s("li",null,[n("Type: "),s("code",null,"string")])],-1),m=s("code",null,"payload.id",-1),b=e(`

    Inputs

    All properties must be under msg.payload and will be ignored if not.

    Example input

    Example of the msg.payload object.

    {
    +  "id": "d9d27ac6b4ebf78f",
    +  "icon": "mdi:lightbulb",
    +  "name": "My Light",
    +  "entityPicture": "/local/images/my_light.png"
    +}
    +

    id

    • Type: string

    The node id of an entity config.

    icon

    • Type: string

    The icon to use for the entity.

    name

    • Type: string

    The friendly name to use for the entity.

    entityPicture

    • Type: string

    The entity picture to use for the entity.

    Examples

    `,18),_={href:"https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/update-config.html#examples",target:"_blank",rel:"noopener noreferrer"},v=s("h4",{id:"usage-example",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#usage-example","aria-hidden":"true"},"#"),n(" Usage example")],-1),x=s("p",null,[s("img",{src:y,alt:"screenshot"})],-1),T=s("div",{class:"language-json","data-ext":"json"},[s("pre",{class:"language-json"},[s("code",null,[s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"f74eb5b7233cf386"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0cd8900387d67b70"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"date"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"828"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"f01a6d954835e535"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"f01a6d954835e535"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-sensor"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0cd8900387d67b70"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"example one"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"e4293de95073f8cd"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"$round($random() * 100, 0)"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"stateType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"attributes"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputOverride"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"allow"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1002"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"192"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"fa343985973ac02b"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-update-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0cd8900387d67b70"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"d18ff4919779da55"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1016"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"288"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"d9d27ac6b4ebf78f"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0cd8900387d67b70"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"override id"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},`"(\\t $icons := [\\t 'mdi:home-assistant',\\t 'mdi:home',\\t 'mdi:home-outline',\\t 'mdi:home-variant',\\t 'mdi:home-variant-outline',\\t 'mdi:home-city'\\t ];\\t $simpsons := [\\t \\"homer\\",\\t \\"marge\\",\\t \\"bart\\",\\t \\"lisa\\",\\t \\"maggie\\"\\t ];\\t $character := $shuffle($simpsons)[0];\\t {\\t \\"name\\": $character,\\t \\"id\\": \\"e4293de95073f8cd\\",\\t \\"icon\\": $shuffle($icons)[0],\\t \\"entityPicture\\": \\"/local/\\" & $character & \\".png\\"\\t }\\t)"`),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"828"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"336"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"fa343985973ac02b"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"4171499cb42d4c08"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0cd8900387d67b70"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"use default id"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"(\\t $simpsons := [\\"homer\\", \\"marge\\", \\"bart\\", \\"lisa\\", \\"maggie\\"];\\t {\\"name\\": $shuffle($simpsons)[0] ,\\"icon\\":\\"\\"}\\t)"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"834"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"288"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"fa343985973ac02b"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"94e86f1c0b4f113d"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-sensor"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0cd8900387d67b70"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"example two"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"d18ff4919779da55"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"state"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"$round($random() * 100, 0)"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"stateType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"jsonata"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"attributes"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"inputOverride"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"allow"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"outputProperties"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"1002"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0d31aa0621b4fe6f"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"inject"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"z"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"0cd8900387d67b70"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"props"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"payload"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"p"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"topic"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"vt"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"str"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"repeat"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"crontab"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"once"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"onceDelay"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"0.1"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"topic"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payload"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"payloadType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"date"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"x"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"828"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"y"'),s("span",{class:"token operator"},":"),s("span",{class:"token number"},"240"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"wires"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"["),s("span",{class:"token string"},'"94e86f1c0b4f113d"'),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"e4293de95073f8cd"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-entity-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"example one"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"sensor"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Node-RED example one"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_category"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_picture"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"device_class"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"unit_of_measurement"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"state_class"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"resend"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugEnabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"id"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"d18ff4919779da55"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"type"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"ha-entity-config"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"server"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"bf5874816710d0c7"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"deviceConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"name"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"example two"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"version"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"6"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"entityType"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"sensor"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"haConfig"'),s("span",{class:"token operator"},":"),s("span",{class:"token punctuation"},"["),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"name"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"Node-RED example one"'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"icon"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_category"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"entity_picture"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"device_class"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"unit_of_measurement"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"‎ "'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},","),s("span",{class:"token punctuation"},"{"),s("span",{class:"token property"},'"property"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'"state_class"'),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"value"'),s("span",{class:"token operator"},":"),s("span",{class:"token string"},'""'),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"resend"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},","),s("span",{class:"token property"},'"debugEnabled"'),s("span",{class:"token operator"},":"),s("span",{class:"token boolean"},"false"),s("span",{class:"token punctuation"},"}"),s("span",{class:"token punctuation"},"]"),n(` +`)])])],-1);function w(j,q){const p=t("RouterLink"),c=t("ExternalLinkIcon"),r=t("InfoPanelOnly"),l=t("DocsOnly");return u(),i("div",null,[g,s("p",null,[n("The node id of a "),a(p,{to:"/node/config-server.html"},{default:o(()=>[n("Server Config")]),_:1}),n(" node.")]),h,f,s("p",null,[n("The node id of an "),a(p,{to:"/node/entity-config.html"},{default:o(()=>[n("entity config")]),_:1}),n(". This can be overridden by the "),m,n(" property on the msg object.")]),b,a(r,null,{default:o(()=>[s("p",null,[s("a",_,[n("link"),a(c)])])]),_:1}),a(l,null,{default:o(()=>[v,x,T]),_:1}),n(" ``` ")])}const C=k(d,[["render",w],["__file","update-config.html.vue"]]);export{C as default}; diff --git a/assets/update_config_use01-BXE5av9O.png b/assets/update_config_use01-BXE5av9O.png new file mode 100644 index 0000000000..a8c7add039 Binary files /dev/null and b/assets/update_config_use01-BXE5av9O.png differ diff --git a/assets/using-date-and-time-entities-to-trigger-flows.html-BMs5a4o1.js b/assets/using-date-and-time-entities-to-trigger-flows.html-BMs5a4o1.js new file mode 100644 index 0000000000..634d06b070 --- /dev/null +++ b/assets/using-date-and-time-entities-to-trigger-flows.html-BMs5a4o1.js @@ -0,0 +1,6 @@ +import{_ as u,r as o,o as c,c as r,a as n,d as s,b as t,w as l,e as a}from"./app-DW3AHQOa.js";const k="/node-red-contrib-home-assistant-websocket/assets/using-date-and-time-entities-to-trigger-flows_01-Bs8pdEv6.png",q="/node-red-contrib-home-assistant-websocket/assets/using-date-and-time-entities-to-trigger-flows_02-9ivWXXCe.png",i="/node-red-contrib-home-assistant-websocket/assets/using-date-and-time-entities-to-trigger-flows_04-DMd9Dm05.png",y="/node-red-contrib-home-assistant-websocket/assets/using-date-and-time-entities-to-trigger-flows_03-DsUrMQlD.png",g={},d=n("h1",{id:"using-date-and-time-entities-to-trigger-flows",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#using-date-and-time-entities-to-trigger-flows","aria-hidden":"true"},"#"),s(" Using Date and Time entities to trigger flows")],-1),m=n("h2",{id:"using-the-time-node",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#using-the-time-node","aria-hidden":"true"},"#"),s(" Using the time node")],-1),b=a(`
  • Home Assistant Companion app next alarm sensor

    [{"id":"f8329c.6b39dd68","type":"ha-time","z":"93fe35bb.4fb688","name":"","server":"","version":0,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityId":"sensor.pixel_next_alarm","property":"state","offset":0,"offsetType":"num","offsetUnits":"minutes","randomOffset":false,"repeatDaily":false,"payload":"$entity().state","payloadType":"jsonata","debugenabled":true,"x":262,"y":864,"wires":[["513ebdd1.58be64"]]},{"id":"513ebdd1.58be64","type":"debug","z":"93fe35bb.4fb688","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":492,"y":864,"wires":[]}]
    +
  • `,1),f={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},h=a(`
    [{"id":"ff4c2fea.d7d15","type":"ha-time","z":"93fe35bb.4fb688","name":"","server":"","version":0,"exposeToHomeAssistant":true,"haConfig":[{"property":"name","value":"Enable next alarm"},{"property":"icon","value":""}],"entityId":"sensor.pixel_next_alarm","property":"state","offset":"$entities(\\"input_number.offset\\").state","offsetType":"jsonata","offsetUnits":"minutes","randomOffset":false,"repeatDaily":true,"payload":"$entity().state","payloadType":"jsonata","debugenabled":false,"x":216,"y":1184,"wires":[["fceff1c.3c74f1"]]},{"id":"fceff1c.3c74f1","type":"debug","z":"93fe35bb.4fb688","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":444,"y":1184,"wires":[]}]
    +
    `,1),_=a(`
  • Daily alarm using Datetime Entity

    [{"id":"68a7a591.c05a1c","type":"ha-time","z":"93fe35bb.4fb688","name":"","server":"","version":0,"exposeToHomeAssistant":true,"haConfig":[{"property":"name","value":"Alarm enabled"},{"property":"icon","value":""}],"entityId":"input_datetime.alarm","property":"state","offset":0,"offsetType":"num","offsetUnits":"minutes","randomOffset":false,"repeatDaily":true,"payload":"$entity().state","payloadType":"jsonata","debugenabled":false,"x":238,"y":1488,"wires":[["96f4596a.01bed8"]]},{"id":"96f4596a.01bed8","type":"debug","z":"93fe35bb.4fb688","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":444,"y":1488,"wires":[]}]
    +
  • `,1),v=a('

    Home Assistant Companion app next alarm sensor

    WARNING

    Home Assistant Companion app sets the entity's name based on its selected language. Eg. next_alarm must be changed in prossimo_allarme if the app is used in Italian (and vice versa)

    Here's a basic example of using the Home Assistant Companion app next alarm sensor.

    screenshot

    [{"id":"71576a68.4c7494","type":"server-state-changed","z":"56b1c979.b2c618","name":"Next Alarm","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.pixel_next_alarm","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"unavailable","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"x":236,"y":1456,"wires":[["17ff4332.e9872d"],["ffa8ad2e.133d4"]]},{"id":"ffa8ad2e.133d4","type":"change","z":"56b1c979.b2c618","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":386,"y":1504,"wires":[["664bcf1c.d25e8"]]},{"id":"17ff4332.e9872d","type":"function","z":"56b1c979.b2c618","name":"time difference","func":"const now = Date.now();\\nconst alarm = new Date(msg.payload);\\n\\nconst timeDifference = alarm - now;\\n\\nmsg.delay = timeDifference;\\n\\n// Reset the delay node before setting the new delay\\nreturn [[{reset: true},msg]];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":416,"y":1456,"wires":[["664bcf1c.d25e8"]]},{"id":"664bcf1c.d25e8","type":"delay","z":"56b1c979.b2c618","name":"wait until time","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":608,"y":1456,"wires":[["42742068.3eb4f"]]},{"id":"42742068.3eb4f","type":"debug","z":"56b1c979.b2c618","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":780,"y":1456,"wires":[]}]
    +

    Adding an offset and on/off switch

    Using the Helpers section under Configuration in Home Assistant add an input_boolean and input_number with a min of -90 and a max of 90.

    In this example they are input_number.offset and input_boolean.next_alarm_enabled. The offset will be plus or minus minutes to the alarm. The delay node will get updated when either the alarm sensor gets updated, the input boolean gets toggled, or the offset changes.

    `,8),w={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},x=n("code",null,"input_boolean",-1),T=a('

    screenshot

    [{"id":"8a005b30.a70028","type":"change","z":"56b1c979.b2c618","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":1616,"wires":[["7443b388.3997bc"]]},{"id":"7443b388.3997bc","type":"delay","z":"56b1c979.b2c618","name":"wait until time","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1008,"y":1568,"wires":[["944beed4.7ca6c"]]},{"id":"944beed4.7ca6c","type":"debug","z":"56b1c979.b2c618","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1180,"y":1568,"wires":[]},{"id":"902c18e0.b83f08","type":"api-current-state","z":"56b1c979.b2c618","name":"enabled?","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.next_alarm_enabled","state_type":"str","state_location":"","override_payload":"none","entity_location":"","override_data":"none","blockInputOverrides":false,"x":300,"y":1568,"wires":[["819e7961.c0c5b8"],["8a005b30.a70028"]]},{"id":"88557318.dcb9","type":"function","z":"56b1c979.b2c618","name":"add offset","func":"const now = Date.now();\\nconst alarm = new Date(msg.alarm);\\nconst offset = msg.offset * 60000;\\nconst timeDifference = alarm.getTime() + offset;\\nconst delay = timeDifference - now;\\n\\nif(delay < 0) {\\n    node.status({fill: 'red', text: 'Alarm in the past'});\\n    node.error(\\"Alarm in the past.\\");\\n    return {reset: true};\\n}\\n\\nnode.status({});\\nmsg.delay = delay\\n\\n// Reset the delay node before setting the new delay\\nreturn [[{reset: true},msg]];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":828,"y":1568,"wires":[["7443b388.3997bc"]]},{"id":"5f5d428e.e8ed8c","type":"api-current-state","z":"56b1c979.b2c618","name":"get offset","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_number.offset","state_type":"str","state_location":"offset","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":684,"y":1568,"wires":[["88557318.dcb9"]]},{"id":"6e621173.6634d","type":"server-state-changed","z":"56b1c979.b2c618","name":"Update Alarm","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.offset, input_boolean.next_alarm_enabled, sensor.pixel_next_alarm","entityidfiltertype":"substring","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":150,"y":1568,"wires":[["902c18e0.b83f08"]]},{"id":"819e7961.c0c5b8","type":"api-current-state","z":"56b1c979.b2c618","name":"get alarm time","version":1,"outputs":2,"halt_if":"unavailable","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"sensor.pixel_next_alarm","state_type":"str","state_location":"alarm","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":480,"y":1568,"wires":[["5f5d428e.e8ed8c"],["8a005b30.a70028"]]}]
    +

    WARNING

    Delay nodes can have a max timeout of around 24.8 days greater than that and weird things will happen.

    Managing alarm from multiple phones

    If more than one phone in the house has the app installed and you want it to be triggered from any of the alarms this is the way to go and it's working perfectly even with just one phone.

    It needs the same couple of helpers for each phone and the same consideration made above for the input_boolean is still valid.

    This flow was developed and tested with a Pixel 2 XL and the companion app in Italian so you'll have to change all the references to the phone and the entities.

    screenshot

    [{"id":"c68594981cf4df93","type":"server-state-changed","z":"e1f44cc40f36d3a0","name":"Update Alarm","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"_prossimo_allarme_offset, _prossimo_allarme_enabled, _prossimo_allarme","entityidfiltertype":"substring","outputinitially":true,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":130,"y":1000,"wires":[["bd2261de4c7422c2"]]},{"id":"bd2261de4c7422c2","type":"function","z":"e1f44cc40f36d3a0","name":"Save values","func":"const [, phone] = msg.topic.match(/\\\\.(.+)_prossimo_allarme/);\\nconst key = `alarm['${phone}']`;\\nconst fullKey = `alarm['${phone}']['${msg.topic}']`\\nflow.set(fullKey, msg.payload);\\nconst alarmPhone = flow.get(key);\\nif (Object.keys(alarmPhone).length === 3) {\\n    const alarmRaw = alarmPhone[`sensor.${phone}_prossimo_allarme`];\\n    const enabled = alarmPhone[`input_boolean.${phone}_prossimo_allarme_enabled`] === 'on';\\n    if ( enabled && alarmRaw !== \\"unavailable\\") {\\n        const now = Date.now();\\n        const alarm = new Date(alarmRaw);\\n        const offset = alarmPhone[`input_number.${phone}_prossimo_allarme_offset`] * 60000;\\n        const timeDifference = alarm.getTime() + offset;\\n        const delay = timeDifference - now;\\n\\n        if (delay < 0) {\\n            node.status({ fill: 'red', text: 'Offset put alarm in the past' });\\n            node.warn(\\"Offset put alarm in the past.\\");\\n            return { reset: true };\\n        }\\n\\n        node.status({});\\n        msg = {\\n            topic: phone,\\n            delay,\\n            payload: alarm\\n        };\\n\\n        // Reset the delay node before setting the new delay\\n        return [[{ reset: true }, msg]];\\n    } else {\\n        return { reset: true };\\n    }\\n}\\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":1000,"wires":[["31a1b9a97061185e"]]},{"id":"31a1b9a97061185e","type":"delay","z":"e1f44cc40f36d3a0","name":"wait until time","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":520,"y":1000,"wires":[["35675e2e29e54de6"]]},{"id":"764b91777c83fd57","type":"debug","z":"e1f44cc40f36d3a0","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":320,"y":1080,"wires":[]},{"id":"35675e2e29e54de6","type":"switch","z":"e1f44cc40f36d3a0","name":"Phone","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"pixel_2_xl","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":690,"y":1000,"wires":[["b2992c1a93db3836"]]},{"id":"b2992c1a93db3836","type":"link out","z":"e1f44cc40f36d3a0","name":"Pixel 2 XL","mode":"link","links":["2a280002119b6339"],"x":795,"y":1000,"wires":[]},{"id":"2a280002119b6339","type":"link in","z":"e1f44cc40f36d3a0","name":"Alarm Pixel 2 XL","links":["b2992c1a93db3836"],"x":175,"y":1080,"wires":[["764b91777c83fd57"]]}]\n

    Daily alarm using Datetime Entity

    screenshot

    [{"id":"2672831b.1236ac","type":"inject","z":"ffbd7f06.4a014","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":342,"y":1808,"wires":[["ef533324.d135d"]]},{"id":"8b6ea5bc.5f2478","type":"api-current-state","z":"ffbd7f06.4a014","name":"alarm","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_datetime.alarm","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":628,"y":1808,"wires":[["aedf33ed.0ca28"]]},{"id":"d3ec7afe.0c2968","type":"debug","z":"ffbd7f06.4a014","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":1808,"wires":[]},{"id":"aedf33ed.0ca28","type":"function","z":"ffbd7f06.4a014","name":"now?","func":"const now = new Date();\\nconst hours = now.getHours().toString().padStart(2,'0');\\nconst minutes = now.getMinutes().toString().padStart(2,'0');\\nconst time = `${hours}:${minutes}`;\\n// Remove seconds\\nconst alarm = msg.payload.split(\\":\\").splice(0,2).join(\\":\\");\\n\\nif(time === alarm) {\\n    return msg;\\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":756,"y":1808,"wires":[["d3ec7afe.0c2968"]]},{"id":"ef533324.d135d","type":"api-current-state","z":"ffbd7f06.4a014","name":"enabled?","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.alarm_enabled","state_type":"str","state_location":"","override_payload":"none","entity_location":"","override_data":"none","blockInputOverrides":false,"x":492,"y":1808,"wires":[["8b6ea5bc.5f2478"],[]]}]\n

    An offset can also be added as shown in the next alarm sensor example.

    ',13);function z(j,D){const e=o("RouterLink"),p=o("ExternalLinkIcon");return c(),r("div",null,[d,n("p",null,[s("There is now a "),t(e,{to:"/node/time.html"},{default:l(()=>[s("time")]),_:1}),s(" node that simplifies the example flows below into one node.")]),m,n("ul",null,[b,n("li",null,[n("p",null,[s("Adding an offset and on/off switch by exposing the node the Home Assistant using the "),n("a",f,[s("custom component"),t(p)]),s(".")]),h]),_]),v,n("p",null,[s("If the "),n("a",w,[s("Node-RED custom component"),t(p)]),s(" is installed in Home Assistant there is no need for the "),x,s(" as the event state node can be exposed to Home Assistant as the toggle switch.")]),T])}const U=u(g,[["render",z],["__file","using-date-and-time-entities-to-trigger-flows.html.vue"]]);export{U as default}; diff --git a/assets/using-date-and-time-entities-to-trigger-flows.html-D1R0f_8A.js b/assets/using-date-and-time-entities-to-trigger-flows.html-D1R0f_8A.js new file mode 100644 index 0000000000..f5eb51a6a6 --- /dev/null +++ b/assets/using-date-and-time-entities-to-trigger-flows.html-D1R0f_8A.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-5c086d70","path":"/cookbook/using-date-and-time-entities-to-trigger-flows.html","title":"Using Date and Time entities to trigger flows","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Using the time node","slug":"using-the-time-node","link":"#using-the-time-node","children":[]},{"level":2,"title":"Home Assistant Companion app next alarm sensor","slug":"home-assistant-companion-app-next-alarm-sensor","link":"#home-assistant-companion-app-next-alarm-sensor","children":[{"level":3,"title":"Adding an offset and on/off switch","slug":"adding-an-offset-and-on-off-switch","link":"#adding-an-offset-and-on-off-switch","children":[]},{"level":3,"title":"Managing alarm from multiple phones","slug":"managing-alarm-from-multiple-phones","link":"#managing-alarm-from-multiple-phones","children":[]}]},{"level":2,"title":"Daily alarm using Datetime Entity","slug":"daily-alarm-using-datetime-entity","link":"#daily-alarm-using-datetime-entity","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":5},{"name":"Federico Granata","email":"3602209+Edo78@users.noreply.github.com","commits":1},{"name":"Mauricio Bonani","email":"bonanitech@gmail.com","commits":1}]},"filePathRelative":"cookbook/using-date-and-time-entities-to-trigger-flows.md"}');export{e as data}; diff --git a/assets/using-date-and-time-entities-to-trigger-flows_01-Bs8pdEv6.png b/assets/using-date-and-time-entities-to-trigger-flows_01-Bs8pdEv6.png new file mode 100644 index 0000000000..f65908a6d0 Binary files /dev/null and b/assets/using-date-and-time-entities-to-trigger-flows_01-Bs8pdEv6.png differ diff --git a/assets/using-date-and-time-entities-to-trigger-flows_02-9ivWXXCe.png b/assets/using-date-and-time-entities-to-trigger-flows_02-9ivWXXCe.png new file mode 100644 index 0000000000..9623eae150 Binary files /dev/null and b/assets/using-date-and-time-entities-to-trigger-flows_02-9ivWXXCe.png differ diff --git a/assets/using-date-and-time-entities-to-trigger-flows_03-DsUrMQlD.png b/assets/using-date-and-time-entities-to-trigger-flows_03-DsUrMQlD.png new file mode 100644 index 0000000000..808d2b141d Binary files /dev/null and b/assets/using-date-and-time-entities-to-trigger-flows_03-DsUrMQlD.png differ diff --git a/assets/using-date-and-time-entities-to-trigger-flows_04-DMd9Dm05.png b/assets/using-date-and-time-entities-to-trigger-flows_04-DMd9Dm05.png new file mode 100644 index 0000000000..28e835a542 Binary files /dev/null and b/assets/using-date-and-time-entities-to-trigger-flows_04-DMd9Dm05.png differ diff --git a/assets/vacation-mode.html-B2l6IzlV.js b/assets/vacation-mode.html-B2l6IzlV.js new file mode 100644 index 0000000000..cd617c0943 --- /dev/null +++ b/assets/vacation-mode.html-B2l6IzlV.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-77a2982b","path":"/cookbook/vacation-mode.html","title":"Vacation Mode","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Step 1","slug":"step-1","link":"#step-1","children":[]},{"level":2,"title":"Step 2","slug":"step-2","link":"#step-2","children":[]},{"level":2,"title":"Step 3","slug":"step-3","link":"#step-3","children":[]},{"level":2,"title":"Step 4","slug":"step-4","link":"#step-4","children":[]}],"git":{"updatedTime":1647350454000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":4}]},"filePathRelative":"cookbook/vacation-mode.md"}');export{e as data}; diff --git a/assets/vacation-mode.html-B7J9q-nz.js b/assets/vacation-mode.html-B7J9q-nz.js new file mode 100644 index 0000000000..bb500b49b2 --- /dev/null +++ b/assets/vacation-mode.html-B7J9q-nz.js @@ -0,0 +1,14 @@ +import{_ as t,r as p,o,c as e,a as s,b as u,w as c,d as r,e as n}from"./app-DW3AHQOa.js";const l="/node-red-contrib-home-assistant-websocket/assets/vacation-mode_01-3u-aevgN.png",k="/node-red-contrib-home-assistant-websocket/assets/vacation-mode_02-lxgo11VL.png",q="/node-red-contrib-home-assistant-websocket/assets/vacation-mode_03-DVtSIIvI.png",i="/node-red-contrib-home-assistant-websocket/assets/vacation-mode_04-CQ-MFwKC.png",y={},g=n('

    Vacation Mode

    Four steps to adding a vacation mode to your home and having lights turn on and off at random intervals. It also automatically prompts you with a notification about turning on vacation mode if you have been gone longer than 24 hours.

    screenshot

    Full Export

    [{"id":"eb756b3f.d770f8","type":"subflow","name":"Create HA Helpers","info":"","category":"","in":[{"x":84,"y":96,"wires":[{"id":"7f1493fc.1300fc"}]}],"out":[],"env":[{"name":"serverName","type":"str","value":"Home Assistant","ui":{"label":{"en-US":"HA Server Name"},"type":"input","opts":{"types":["str"]}}},{"name":"helpers","type":"json","value":"[]","ui":{"label":{"en-US":"Helpers"},"type":"input","opts":{"types":["json"]}}}],"color":"#DDAA99","status":{"x":246,"y":48,"wires":[{"id":"a66d5d93.8a5f","port":0}]}},{"id":"7f1493fc.1300fc","type":"function","z":"eb756b3f.d770f8","name":"process helpers","func":"const serverName = toCamelCase(env.get('serverName'));\\nconst haServer = global.get(\\"homeassistant\\")[serverName];\\nif(!haServer) {\\n    node.error(\\"Invalid HA server name\\");\\n    return;\\n}\\nconst states = haServer.states;\\nconst helpers = env.get(\\"helpers\\");\\n\\nhelpers.forEach(h => {\\n    const entityId = `${h.type}.${h.id}`;\\n    if(!states[entityId]) {\\n        const {id, type, ...data} = h;\\n        const apiData = {\\n            entity: h,\\n            payload: { \\n                data \\n            }\\n        };\\n        apiData.payload.data.type = `${type}/create`;\\n    \\n        node.send(apiData);\\n        node.status({text: `Creating ${entityId}`});\\n    }\\n});\\n\\nnode.done();\\n\\nfunction toCamelCase(str) {\\n    return str.replace(/(?:^\\\\w|[A-Z]|\\\\b\\\\w|\\\\s+)/g, (match, index) => {\\n        if (+match === 0) return '';\\n        return index === 0 ? match.toLowerCase() : match.toUpperCase();\\n    });\\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":224,"y":96,"wires":[["a4a0abd9.7576d8"]]},{"id":"a4a0abd9.7576d8","type":"ha-api","z":"eb756b3f.d770f8","name":"create helper","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":390,"y":96,"wires":[["b76d0c56.d54b9"]]},{"id":"388bb5c7.47346a","type":"ha-api","z":"eb756b3f.d770f8","name":"rename helper entity id","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\t   \\"type\\":\\"config/entity_registry/update\\",\\t   \\"entity_id\\": entity.type & \\".\\" & payload.id,\\t   \\"new_entity_id\\": entity.type & \\".\\" & entity.id\\t}","dataType":"jsonata","location":"payload","locationType":"msg","responseType":"json","x":788,"y":96,"wires":[[]]},{"id":"b76d0c56.d54b9","type":"switch","z":"eb756b3f.d770f8","name":"need to rename?","property":"payload.id","propertyType":"msg","rules":[{"t":"neq","v":"entity.id","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":96,"wires":[["388bb5c7.47346a","3e47440a.eee2cc"]]},{"id":"a66d5d93.8a5f","type":"status","z":"eb756b3f.d770f8","name":"","scope":["7f1493fc.1300fc","3e47440a.eee2cc"],"x":124,"y":48,"wires":[[]]},{"id":"3e47440a.eee2cc","type":"function","z":"eb756b3f.d770f8","name":"rename status","func":"const oldEntityId = `${msg.entity.type}.${msg.payload.id}`;\\nconst newEntityId = `${msg.entity.type}.${msg.entity.id}`;\\n\\nnode.status({text: `Renaming ${oldEntityId} to ${newEntityId}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":768,"y":144,"wires":[[]]},{"id":"fda663f6.59a56","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"e9b697a.fc03268"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"57c0c58d.ffa1bc","port":0}]},{"x":1172,"y":176,"wires":[{"id":"57c0c58d.ffa1bc","port":1}]},{"x":1172,"y":224,"wires":[{"id":"57c0c58d.ffa1bc","port":2}]},{"x":964,"y":240,"wires":[{"id":"c3389099.bc489","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"d847d277.d448c","port":0}]}},{"id":"b4512e6b.640d9","type":"function","z":"fda663f6.59a56","name":"create service call","func":"const actions = [];\\n[1,2,3].forEach(i => {\\n    const name = `action${i}`\\n    const id = flow.get(`${name}Id`);\\n    const title = env.get(`${name}Title`);\\n    const uri = env.get(`${name}Uri`);\\n    const action = uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\\n    \\n    actions.push({\\n        action,\\n        title,\\n        uri\\n    });\\n});\\n\\nmsg._originalPayload = msg.payload;\\nflow.set('latestMessage', msg);\\n\\nconst services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            title: env.get('title'),\\n            message: env.get('message'),\\n            data: {\\n                tag: flow.get('notificationTag'),\\n                actions,\\n                color: env.get(\\"color\\"),\\n                group: env.get(\\"group\\"),\\n                sticky: env.get(\\"sticky\\"),\\n                timeout: env.get(\\"timeout\\"),\\n                icon: env.get(\\"icon\\")\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\\n\\n[1,2,3].forEach(i => {\\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\\n})\\n\\n\\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["7a427ca2.c030e4"]]},{"id":"57c0c58d.ffa1bc","type":"switch","z":"fda663f6.59a56","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"d847d277.d448c","type":"status","z":"fda663f6.59a56","name":"","scope":["b4512e6b.640d9","c3389099.bc489","7955d8e6.b10888","7a427ca2.c030e4"],"x":124,"y":272,"wires":[[]]},{"id":"c3389099.bc489","type":"function","z":"fda663f6.59a56","name":"build message","func":"const latestMessage = flow.get('latestMessage');\\nconst event = msg.payload.event;\\n\\nlatestMessage.eventData = msg.payload;\\nlatestMessage.payload = latestMessage._originalPayload;\\ndelete latestMessage._originalPayload;\\n\\nif(env.get('userInfo')) {\\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\\n    latestMessage.userData = userData;\\n}\\n\\nif(msg.event_type === 'mobile_app_notification_cleared') {\\n    node.status({\\n        text: `cleared at: ${getPrettyDate()}`,\\n        shape: 'dot',\\n        fill: 'blue'\\n    });\\n    \\n    return [null, latestMessage];\\n}\\n\\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\\nnode.status({\\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\\n    shape: 'dot',\\n    fill: 'green'\\n});\\n\\nreturn latestMessage;\\n\\n\\nfunction getPrettyDate() {\\n    return new Date().toLocaleDateString('en-US', {\\n        month: 'short',\\n        day: 'numeric',\\n        hour12: false,\\n        hour: 'numeric',\\n        minute: 'numeric',\\n    });\\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["57c0c58d.ffa1bc"],[]]},{"id":"f814cdc6.def07","type":"switch","z":"fda663f6.59a56","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["4db9b8d.0c14a48"]]},{"id":"7596669d.feb668","type":"ha-api","z":"fda663f6.59a56","name":"get user info","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/auth/list\\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["c3389099.bc489"]]},{"id":"b745e475.d6cdf8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_cleared","server":"","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["f814cdc6.def07"]]},{"id":"4db9b8d.0c14a48","type":"switch","z":"fda663f6.59a56","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["7596669d.feb668"],["c3389099.bc489"]]},{"id":"e9b697a.fc03268","type":"switch","z":"fda663f6.59a56","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["b4512e6b.640d9"],["7955d8e6.b10888"]],"l":false},{"id":"7955d8e6.b10888","type":"function","z":"fda663f6.59a56","name":"create clear notification","func":"const services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            message: \\"clear_notification\\",\\n            data: {\\n                tag: flow.get('notificationTag'),\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["7a427ca2.c030e4"]]},{"id":"520a884c.35f9c8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_action","server":"","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["f814cdc6.def07"]]},{"id":"7a427ca2.c030e4","type":"api-call-service","z":"fda663f6.59a56","name":"","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"aa02fa4a.a35548","type":"inject","z":"9530fd91.600e2","name":"","repeat":"","crontab":"*/6 16-23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":118,"y":336,"wires":[["7e966ac8.609524"]]},{"id":"cfa1b8e4.8d4a08","type":"time-range-switch","z":"9530fd91.600e2","name":"","startTime":"sunset","endTime":"23:59","startOffset":0,"endOffset":0,"x":496,"y":336,"wires":[["c7efc558.da1bc8"],[]]},{"id":"a41f4d83.d45c4","type":"ha-get-entities","z":"9530fd91.600e2","server":"","name":"","rules":[{"property":"entity_id","logic":"in_group","value":"group.vacation_lights","valueType":"str"},{"property":"state","logic":"is","value":"off","valueType":"str"}],"output_type":"random","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":806,"y":336,"wires":[["f3897d20.fffee"]]},{"id":"c7efc558.da1bc8","type":"function","z":"9530fd91.600e2","name":"25%","func":"const random = Math.round(Math.random() * 100);\\n\\nif(random < 75) {\\n    node.status({fill: \\"red\\", text: random});\\n    return;\\n}\\n\\nnode.status({fill: \\"green\\", text: random});\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":658,"y":336,"wires":[["a41f4d83.d45c4"]]},{"id":"f3897d20.fffee","type":"api-call-service","z":"9530fd91.600e2","name":"turn on","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":956,"y":336,"wires":[["20fce293.98ce8e"]]},{"id":"20fce293.98ce8e","type":"delay","z":"9530fd91.600e2","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"5","randomLast":"36","randomUnits":"minutes","drop":false,"x":1100,"y":336,"wires":[["3d851328.fb1b8c"]]},{"id":"3d851328.fb1b8c","type":"api-call-service","z":"9530fd91.600e2","name":"turn off","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_off","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1234,"y":336,"wires":[[]]},{"id":"7e966ac8.609524","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":298,"y":336,"wires":[[],["cfa1b8e4.8d4a08"]]},{"id":"22f34ec4.9d3a22","type":"comment","z":"9530fd91.600e2","name":"Vacation Lights","info":"","x":112,"y":288,"wires":[]},{"id":"7003285c.a3a8c8","type":"api-call-service","z":"9530fd91.600e2","name":"turn on vacation mode","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":788,"y":192,"wires":[["4971bda0.0758f4"]]},{"id":"4971bda0.0758f4","type":"api-call-service","z":"9530fd91.600e2","name":"notify jason","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_jason","entityId":"","data":"{\\"title\\":\\"Vacation Mode\\",\\"message\\":\\"Vacation Mode has been enabled.\\"}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":982,"y":192,"wires":[[]]},{"id":"bf80cebf.58bcc","type":"server-state-changed","z":"9530fd91.600e2","name":"home/away","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"1","forType":"num","forUnits":"days","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":102,"y":192,"wires":[["7d414deb.904f64"],["c81cbf7d.abe22"]]},{"id":"c81cbf7d.abe22","type":"api-call-service","z":"9530fd91.600e2","name":"vacation mode off","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":314,"y":240,"wires":[[]]},{"id":"7d414deb.904f64","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":314,"y":192,"wires":[["dca703ed.f3222"],[]]},{"id":"dca703ed.f3222","type":"subflow:fda663f6.59a56","z":"9530fd91.600e2","name":"turn on vacation mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been aways for 24 hours. Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":542,"y":208,"wires":[["7003285c.a3a8c8"],[],[],[]]},{"id":"d4a03a04.6c78f8","type":"subflow:eb756b3f.d770f8","z":"9530fd91.600e2","name":"create input_boolean","env":[{"name":"helpers","value":"[{\\"id\\":\\"vacation_mode\\",\\"type\\":\\"input_boolean\\",\\"name\\":\\"Vacation Mode\\",\\"icon\\":\\"mdi:beach\\"}]","type":"json"}],"x":292,"y":96,"wires":[]},{"id":"f3d6f382.70bfe","type":"inject","z":"9530fd91.600e2","name":"Click me to","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":108,"y":96,"wires":[["d4a03a04.6c78f8"]]},{"id":"4a22094b.635368","type":"comment","z":"9530fd91.600e2","name":"Setup","info":"","x":82,"y":48,"wires":[]},{"id":"7ce57cf8.cad134","type":"comment","z":"9530fd91.600e2","name":"Actionable notification to turn on vacation mode","info":"","x":212,"y":144,"wires":[]}]\n

    Step 1

    Create an input boolean in Home Assistant that will control if the house is in vacation mode.

    screenshot

    or via the helpers menu in the Home Assistant UI or add it manually in YAML

    input_boolean:
    +  vacation_mode:
    +    name: Vacation Mode
    +    icon: mdi:beach
    +

    Step 2

    Create a flow that will automatically change the vacation mode to off if we come home. Secondly will send our phone an actionable notification for android asking if we want to turn on vacation mode if we have been gone longer than 24 hours.

    screenshot

    [{"id":"fda663f6.59a56","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"e9b697a.fc03268"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"57c0c58d.ffa1bc","port":0}]},{"x":1172,"y":176,"wires":[{"id":"57c0c58d.ffa1bc","port":1}]},{"x":1172,"y":224,"wires":[{"id":"57c0c58d.ffa1bc","port":2}]},{"x":964,"y":240,"wires":[{"id":"c3389099.bc489","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"d847d277.d448c","port":0}]}},{"id":"b4512e6b.640d9","type":"function","z":"fda663f6.59a56","name":"create service call","func":"const actions = [];\\n[1,2,3].forEach(i => {\\n    const name = `action${i}`\\n    const id = flow.get(`${name}Id`);\\n    const title = env.get(`${name}Title`);\\n    const uri = env.get(`${name}Uri`);\\n    const action = uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\\n    \\n    actions.push({\\n        action,\\n        title,\\n        uri\\n    });\\n});\\n\\nmsg._originalPayload = msg.payload;\\nflow.set('latestMessage', msg);\\n\\nconst services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            title: env.get('title'),\\n            message: env.get('message'),\\n            data: {\\n                tag: flow.get('notificationTag'),\\n                actions,\\n                color: env.get(\\"color\\"),\\n                group: env.get(\\"group\\"),\\n                sticky: env.get(\\"sticky\\"),\\n                timeout: env.get(\\"timeout\\"),\\n                icon: env.get(\\"icon\\")\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\\n\\n[1,2,3].forEach(i => {\\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\\n})\\n\\n\\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["7a427ca2.c030e4"]]},{"id":"57c0c58d.ffa1bc","type":"switch","z":"fda663f6.59a56","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"d847d277.d448c","type":"status","z":"fda663f6.59a56","name":"","scope":["b4512e6b.640d9","c3389099.bc489","7955d8e6.b10888","7a427ca2.c030e4"],"x":124,"y":272,"wires":[[]]},{"id":"c3389099.bc489","type":"function","z":"fda663f6.59a56","name":"build message","func":"const latestMessage = flow.get('latestMessage');\\nconst event = msg.payload.event;\\n\\nlatestMessage.eventData = msg.payload;\\nlatestMessage.payload = latestMessage._originalPayload;\\ndelete latestMessage._originalPayload;\\n\\nif(env.get('userInfo')) {\\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\\n    latestMessage.userData = userData;\\n}\\n\\nif(msg.event_type === 'mobile_app_notification_cleared') {\\n    node.status({\\n        text: `cleared at: ${getPrettyDate()}`,\\n        shape: 'dot',\\n        fill: 'blue'\\n    });\\n    \\n    return [null, latestMessage];\\n}\\n\\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\\nnode.status({\\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\\n    shape: 'dot',\\n    fill: 'green'\\n});\\n\\nreturn latestMessage;\\n\\n\\nfunction getPrettyDate() {\\n    return new Date().toLocaleDateString('en-US', {\\n        month: 'short',\\n        day: 'numeric',\\n        hour12: false,\\n        hour: 'numeric',\\n        minute: 'numeric',\\n    });\\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["57c0c58d.ffa1bc"],[]]},{"id":"f814cdc6.def07","type":"switch","z":"fda663f6.59a56","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["4db9b8d.0c14a48"]]},{"id":"7596669d.feb668","type":"ha-api","z":"fda663f6.59a56","name":"get user info","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\\"type\\": \\"config/auth/list\\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["c3389099.bc489"]]},{"id":"b745e475.d6cdf8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_cleared","server":"","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["f814cdc6.def07"]]},{"id":"4db9b8d.0c14a48","type":"switch","z":"fda663f6.59a56","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["7596669d.feb668"],["c3389099.bc489"]]},{"id":"e9b697a.fc03268","type":"switch","z":"fda663f6.59a56","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["b4512e6b.640d9"],["7955d8e6.b10888"]],"l":false},{"id":"7955d8e6.b10888","type":"function","z":"fda663f6.59a56","name":"create clear notification","func":"const services = env.get('service');\\nif(!services) {\\n    node.status({\\n        text: 'no services defined',\\n        shape: 'ring',\\n        fill: 'red'\\n    });\\n    return;    \\n}\\n\\nservices.trim().split(/,\\\\s*/).forEach(service => {\\n    if(!service) return;\\n    \\n    msg.payload = {\\n        service,\\n        data: {\\n            message: \\"clear_notification\\",\\n            data: {\\n                tag: flow.get('notificationTag'),\\n            }\\n        }\\n    };\\n    node.send(msg);\\n});\\n\\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["7a427ca2.c030e4"]]},{"id":"520a884c.35f9c8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_action","server":"","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["f814cdc6.def07"]]},{"id":"7a427ca2.c030e4","type":"api-call-service","z":"fda663f6.59a56","name":"","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"7003285c.a3a8c8","type":"api-call-service","z":"9530fd91.600e2","name":"turn on vacation mode","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":788,"y":192,"wires":[["4971bda0.0758f4"]]},{"id":"4971bda0.0758f4","type":"api-call-service","z":"9530fd91.600e2","name":"notify jason","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_jason","entityId":"","data":"{\\"title\\":\\"Vacation Mode\\",\\"message\\":\\"Vacation Mode has been enabled.\\"}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":982,"y":192,"wires":[[]]},{"id":"bf80cebf.58bcc","type":"server-state-changed","z":"9530fd91.600e2","name":"home/away","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"1","forType":"num","forUnits":"days","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":102,"y":192,"wires":[["7d414deb.904f64"],["c81cbf7d.abe22"]]},{"id":"c81cbf7d.abe22","type":"api-call-service","z":"9530fd91.600e2","name":"vacation mode off","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":314,"y":240,"wires":[[]]},{"id":"7d414deb.904f64","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":314,"y":192,"wires":[["dca703ed.f3222"],[]]},{"id":"dca703ed.f3222","type":"subflow:fda663f6.59a56","z":"9530fd91.600e2","name":"turn on vacation mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been aways for 24 hours. Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":542,"y":208,"wires":[["7003285c.a3a8c8"],[],[],[]]},{"id":"7ce57cf8.cad134","type":"comment","z":"9530fd91.600e2","name":"Actionable notification to turn on vacation mode","info":"","x":212,"y":144,"wires":[]}]\n

    Also See

    ',15),d=n(`

    Step 3

    Set up a group of lights and switches in Home Assistant that you want to turn on and off while vacation mode is active. This can be done without creating a group in Home Assistant by modifying the get-entities node in the below flow to entity_id in light.night_light,light.kitchen,switch.bedroom_light,switch.laundry_room.

    group:
    +  vacation_lights:
    +    name: Vacation Lights
    +    entities:
    +      - light.night_light
    +      - light.kitchen
    +      - switch.bedroom_light
    +      - switch.laundry_room
    +

    Step 4

    This flow will run between sunset and midnight turning lights on and off at random intervals if vacation mode is enabled.

    screenshot

    [{"id":"aa02fa4a.a35548","type":"inject","z":"9530fd91.600e2","name":"","repeat":"","crontab":"*/6 16-23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":118,"y":336,"wires":[["7e966ac8.609524"]]},{"id":"cfa1b8e4.8d4a08","type":"time-range-switch","z":"9530fd91.600e2","name":"","startTime":"sunset","endTime":"23:59","startOffset":0,"endOffset":0,"x":496,"y":336,"wires":[["c7efc558.da1bc8"],[]]},{"id":"a41f4d83.d45c4","type":"ha-get-entities","z":"9530fd91.600e2","server":"","name":"","rules":[{"property":"entity_id","logic":"in_group","value":"group.vacation_lights","valueType":"str"},{"property":"state","logic":"is","value":"off","valueType":"str"}],"output_type":"random","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":806,"y":336,"wires":[["f3897d20.fffee"]]},{"id":"c7efc558.da1bc8","type":"function","z":"9530fd91.600e2","name":"25%","func":"const random = Math.round(Math.random() * 100);\\n\\nif(random < 75) {\\n    node.status({fill: \\"red\\", text: random});\\n    return;\\n}\\n\\nnode.status({fill: \\"green\\", text: random});\\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":658,"y":336,"wires":[["a41f4d83.d45c4"]]},{"id":"f3897d20.fffee","type":"api-call-service","z":"9530fd91.600e2","name":"turn on","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":956,"y":336,"wires":[["20fce293.98ce8e"]]},{"id":"20fce293.98ce8e","type":"delay","z":"9530fd91.600e2","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"5","randomLast":"36","randomUnits":"minutes","drop":false,"x":1100,"y":336,"wires":[["3d851328.fb1b8c"]]},{"id":"3d851328.fb1b8c","type":"api-call-service","z":"9530fd91.600e2","name":"turn off","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_off","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1234,"y":336,"wires":[[]]},{"id":"7e966ac8.609524","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":298,"y":336,"wires":[[],["cfa1b8e4.8d4a08"]]},{"id":"22f34ec4.9d3a22","type":"comment","z":"9530fd91.600e2","name":"Vacation Lights","info":"","x":112,"y":288,"wires":[]}]
    +
    `,7);function m(b,f){const a=p("RouterLink");return o(),e("div",null,[g,s("ul",null,[s("li",null,[u(a,{to:"/cookbook/actionable-notifications-subflow-for-android.html"},{default:c(()=>[r("Actionable notifactions subflow for android")]),_:1})])]),d])}const _=t(y,[["render",m],["__file","vacation-mode.html.vue"]]);export{_ as default}; diff --git a/assets/vacation-mode_01-3u-aevgN.png b/assets/vacation-mode_01-3u-aevgN.png new file mode 100644 index 0000000000..1cfac3d84b Binary files /dev/null and b/assets/vacation-mode_01-3u-aevgN.png differ diff --git a/assets/vacation-mode_02-lxgo11VL.png b/assets/vacation-mode_02-lxgo11VL.png new file mode 100644 index 0000000000..9e28fa27c8 Binary files /dev/null and b/assets/vacation-mode_02-lxgo11VL.png differ diff --git a/assets/vacation-mode_03-DVtSIIvI.png b/assets/vacation-mode_03-DVtSIIvI.png new file mode 100644 index 0000000000..d64edcbdf1 Binary files /dev/null and b/assets/vacation-mode_03-DVtSIIvI.png differ diff --git a/assets/vacation-mode_04-CQ-MFwKC.png b/assets/vacation-mode_04-CQ-MFwKC.png new file mode 100644 index 0000000000..0baa93dc38 Binary files /dev/null and b/assets/vacation-mode_04-CQ-MFwKC.png differ diff --git a/assets/wait-until.html-BbqRjVUv.js b/assets/wait-until.html-BbqRjVUv.js new file mode 100644 index 0000000000..5f20ed8cad --- /dev/null +++ b/assets/wait-until.html-BbqRjVUv.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-77b94402","path":"/node/wait-until.html","title":"Wait Until","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entities","slug":"entities","link":"#entities","children":[]},{"level":3,"title":"Wait Until","slug":"wait-until-1","link":"#wait-until-1","children":[]},{"level":3,"title":"Timeout","slug":"timeout","link":"#timeout","children":[]},{"level":3,"title":"Check against the current state","slug":"check-against-the-current-state","link":"#check-against-the-current-state","children":[]}]},{"level":2,"title":"Input","slug":"input","link":"#input","children":[{"level":3,"title":"reset","slug":"reset","link":"#reset","children":[]},{"level":3,"title":"payload","slug":"payload","link":"#payload","children":[]},{"level":3,"title":"Example","slug":"example","link":"#example","children":[]}]},{"level":2,"title":"Output","slug":"output","link":"#output","children":[]}],"git":{"updatedTime":1723350678000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":9}]},"filePathRelative":"node/wait-until.md"}');export{t as data}; diff --git a/assets/wait-until.html-CgFxsoz7.js b/assets/wait-until.html-CgFxsoz7.js new file mode 100644 index 0000000000..289a6e1291 --- /dev/null +++ b/assets/wait-until.html-CgFxsoz7.js @@ -0,0 +1,15 @@ +import{_ as p,r as s,o as c,c as l,a as t,d as e,b as n,w as r,e as o}from"./app-DW3AHQOa.js";const u={},d=t("h1",{id:"wait-until",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#wait-until","aria-hidden":"true"},"#"),e(" Wait Until")],-1),h=t("p",null,"When an input is received the node will wait until the condition is met or the timeout occurs then will pass on the last received message. Any new input will reset the timeout timer.",-1),k=t("h2",{id:"configuration",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),e(" Configuration")],-1),g={id:"entities",tabindex:"-1"},m=t("a",{class:"header-anchor",href:"#entities","aria-hidden":"true"},"#",-1),f=t("li",null,[e("Type: "),t("code",null,"string")],-1),y=o('

    A list of entities to wait for the condition to be met. The node will wait for any of the entities to meet the condition. If the entity is not found it will be ignored.

    The types that can be used are: entity id, substring, and regex.

    Examples

    • light.living_room - Will wait for the entity with the id light.living_room
    • motion - Will wait for any entity that has motion in the entity id
    • ^light\\..* - Will wait for any entity that starts with light.
    ',4),q={id:"wait-until-1",tabindex:"-1"},_=t("a",{class:"header-anchor",href:"#wait-until-1","aria-hidden":"true"},"#",-1),b=o(`
    • Type: string

    The property field will be checked against the value field using the comparator.

    Timeout

    • Type: number

    The amount of time to wait for the condition to become true before deactivating the node and passing the message object to the second output. If the timeout is equal to zero the node will wait indefinitely for the condition to be met.

    WARNING

    If using a Node-RED global or flow context variable in the timeout field it will not update the timeout value if the context value changes after the node has been deployed.

    Check against the current state

    • Type: boolean

    When an input is received it will check the comparator against the current state instead of waiting for a state change.

    INFO

    This is only available when there is only one entity selected

    Input

    reset

    If the received message has this property set to any value the node will be set to inactive and the timeout cleared.

    payload

    • Type: object

    Example

    {
    +  "entities": {
    +    "entity": ["light.living_room", "light.bedroom"],
    +    "substring": ["light."],
    +    "regex": ["light.*"]
    +  },
    +  "property": "state",
    +  "comparator": "is",
    +  "value": "on",
    +  "valueType": "str",
    +  "timeout": 10,
    +  "timeoutUnits": "seconds",
    +  "checkCurrentState": false
    +}
    +

    Output

    Value types:

    • entity: entity data of the triggered entity. Will be undefined if multiple entities are selected and the timeout occurs.
    • config: config properties of the node
    `,20);function w(x,v){const a=s("Badge"),i=s("RouterLink");return c(),l("div",null,[d,h,k,t("h3",g,[m,e(" Entities "),n(a,{text:"required"})]),t("ul",null,[f,t("li",null,[e("Accepts "),n(i,{to:"/guide/mustache-templates.html"},{default:r(()=>[e("Mustache Templates")]),_:1}),e(" only for entity type")])]),y,t("h3",q,[_,e(" Wait Until "),n(a,{text:"required"})]),b])}const W=p(u,[["render",w],["__file","wait-until.html.vue"]]);export{W as default}; diff --git a/assets/webhook.html-CQCZ7xuU.js b/assets/webhook.html-CQCZ7xuU.js new file mode 100644 index 0000000000..04e850f6c5 --- /dev/null +++ b/assets/webhook.html-CQCZ7xuU.js @@ -0,0 +1 @@ +import{_ as n,r as i,o as d,c as r,a as e,d as t,b as o,e as c}from"./app-DW3AHQOa.js";const h={},l=e("h1",{id:"webhook",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#webhook","aria-hidden":"true"},"#"),t(" Webhook")],-1),u=e("p",null,"Outputs the data received from the created webhook in Home Assistant",-1),_={class:"custom-container warning"},p=e("p",{class:"custom-container-title"},"WARNING",-1),f={href:"https://github.com/zachowj/hass-node-red",target:"_blank",rel:"noopener noreferrer"},m=e("h2",{id:"configuration",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#"),t(" Configuration")],-1),b={id:"id",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#id","aria-hidden":"true"},"#",-1),w=e("ul",null,[e("li",null,[t("Type: "),e("code",null,"string")])],-1),x=e("p",null,"A string to be used for the webhook URL in Home Assistant.",-1),k={id:"allowed-methods",tabindex:"-1"},y=e("a",{class:"header-anchor",href:"#allowed-methods","aria-hidden":"true"},"#",-1),A=c('
    • Type: list

    A list of allowed methods that Home Assistant will accept for the webhook. At least one method must be selected.

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • received data: The parsed body from the webhook request
    • trigger id: webhook id
    • headers: entity state of the triggered entity
    • params: Query string parameters
    • config: config properties of the node
    ',8);function N(v,T){const a=i("ExternalLinkIcon"),s=i("Badge");return d(),r("div",null,[l,u,e("div",_,[p,e("p",null,[e("em",null,[t("Needs "),e("a",f,[t("Custom Integration"),o(a)]),t(" installed in Home Assistant for this node to function")])])]),m,e("h3",b,[g,t(" ID "),o(s,{text:"required"})]),w,x,e("h3",k,[y,t(" Allowed Methods "),o(s,{text:"required"})]),A])}const E=n(h,[["render",N],["__file","webhook.html.vue"]]);export{E as default}; diff --git a/assets/webhook.html-FcIF4iwS.js b/assets/webhook.html-FcIF4iwS.js new file mode 100644 index 0000000000..4d9c2214da --- /dev/null +++ b/assets/webhook.html-FcIF4iwS.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-52885c54","path":"/node/webhook.html","title":"Webhook","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"ID","slug":"id","link":"#id","children":[]},{"level":3,"title":"Allowed Methods","slug":"allowed-methods","link":"#allowed-methods","children":[]},{"level":3,"title":"Expose as","slug":"expose-as","link":"#expose-as","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[]}],"git":{"updatedTime":1691168201000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":6}]},"filePathRelative":"node/webhook.md"}');export{e as data}; diff --git a/assets/zone.html-B_JK36d1.js b/assets/zone.html-B_JK36d1.js new file mode 100644 index 0000000000..5e36e4b162 --- /dev/null +++ b/assets/zone.html-B_JK36d1.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-66fcac19","path":"/node/zone.html","title":"Zone","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Configuration","slug":"configuration","link":"#configuration","children":[{"level":3,"title":"Entities","slug":"entities","link":"#entities","children":[]},{"level":3,"title":"Event","slug":"event","link":"#event","children":[]},{"level":3,"title":"Zones","slug":"zones","link":"#zones","children":[]}]},{"level":2,"title":"Outputs","slug":"outputs","link":"#outputs","children":[{"level":3,"title":"topic","slug":"topic","link":"#topic","children":[]},{"level":3,"title":"payload","slug":"payload","link":"#payload","children":[]},{"level":3,"title":"data","slug":"data","link":"#data","children":[]},{"level":3,"title":"zones","slug":"zones-1","link":"#zones-1","children":[]}]}],"git":{"updatedTime":1662358213000,"contributors":[{"name":"Jason","email":"37859597+zachowj@users.noreply.github.com","commits":3}]},"filePathRelative":"node/zone.md"}');export{e as data}; diff --git a/assets/zone.html-CJBJZBw6.js b/assets/zone.html-CJBJZBw6.js new file mode 100644 index 0000000000..2b1bf00fbb --- /dev/null +++ b/assets/zone.html-CJBJZBw6.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as t,e as i}from"./app-DW3AHQOa.js";const n={},r=i('

    Zone

    Outputs when one of the configured entities enter or leaves one of the defined zones.

    Configuration

    Entities

    • Type: array

    An array of entity ids to monitor for zone changes.

    Event

    • Type: string

    Set when to check an entity. Either entering or leaving a zone.

    Zones

    • Type: array

    An array of zone ids to check when a configured entity updates.

    Outputs

    topic

    • Type: string

    The entity id of the device/person that triggered the update.

    payload

    • Type: string

    The state of the device/person entity that triggered the update.

    data

    • Type: object

    The entity object of the device/person that triggered the update.

    zones

    • Type: array

    An array of zone entities where the device/person entity entered/left after an update of location.

    ',25),o=[r];function d(h,c){return a(),t("div",null,o)}const l=e(n,[["render",d],["__file","zone.html.vue"]]);export{l as default}; diff --git a/cookbook/actionable-notifications-subflow-for-android.html b/cookbook/actionable-notifications-subflow-for-android.html new file mode 100644 index 0000000000..3bc5ff2a04 --- /dev/null +++ b/cookbook/actionable-notifications-subflow-for-android.html @@ -0,0 +1,39 @@ + + + + + + + + + Actionable Notifications Subflow for Android | node-red-contrib-home-assistant-websocket + + + + + +

    Actionable Notifications Subflow for Android

    Questions and Discussion

    Post questions and follow the discussion about this recipe hereopen in new window

    screenshot

    v1.0.0 - Requires Nodejs v12

    Changes

    • Any setting can be set or overwritten using msg.actionable to pass a notification object into the node.
    [{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"Android actionable notification v1.0.0\n\n[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"HA Actions","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1188,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1188,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1188,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"mobile_app_jason","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"meta":{},"color":"#46B1EF","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"icon":"font-awesome/fa-mobile-phone","status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"msg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nconst actions = [1, 2, 3].reduce((acc, i) => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = getActionProperty(i, \"title\") ?? env.get(`${name}Title`);\n    const uri = getActionProperty(i, \"uri\") ?? env.get(`${name}Uri`);\n    const action = uri.length ? 'URI' : title ? id : undefined;\n\n    acc.push({ action, title, uri });\n\n    return acc;\n}, []);\n\nconst tag = flow.get('notificationTag');\nconst data = mergeDeep({\n        title: env.get('title'),\n        message: env.get('message'),\n        data: {\n            tag,\n            color: env.get(\"color\"),\n            group: env.get(\"group\"),\n            sticky: env.get(\"sticky\"),\n            timeout: env.get(\"timeout\"),\n            icon: env.get(\"icon\")\n        },\n    },    \n    msg.actionable,    \n    {data: {actions}},\n);\n\nif(tag !== data?.data?.tag) {\n    flow.set('notificationTag', data?.data?.tag);\n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data,\n    };\n    node.send(msg);\n});\n\nnode.done();\n\nfunction getActionProperty(index, prop) {\n    const i = index - 1;\n\n    return msg?.actionable?.data?.actions?.[i]?.[prop];\n}\n\n/**\n * Simple object check.\n * @param item\n * @returns {boolean}\n */\nfunction isObject(item) {\n    return (item && typeof item === 'object' && !Array.isArray(item));\n}\n\n/**\n * Deep merge two objects.\n * @param target\n * @param sources\n */\nfunction mergeDeep(target, ...sources) {\n    if (!sources.length) return target;\n    const source = sources.shift();\n\n    if (isObject(target) && isObject(source)) {\n        for (const key in source) {\n            if (isObject(source[key])) {\n                if (!target[key]) Object.assign(target, { [key]: {} });\n                mergeDeep(target[key], source[key]);\n            } else {\n                Object.assign(target, { [key]: source[key] });\n            }\n        }\n    }\n\n    return mergeDeep(target, ...sources);\n}\n","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","libs":[],"x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\ndelete latestMessage.actionable;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","server":"","version":1,"debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","responseType":"json","outputProperties":[{"property":"userData","propertyType":"msg","value":"","valueType":"results"}],"x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","server":"","version":1,"event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.status({text: \"cleared\"});\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","server":"","version":1,"event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"},{"property":"event_type","propertyType":"msg","value":"$outputData(\"eventData\").event_type","valueType":"jsonata"}],"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","server":"","version":4,"debugenabled":false,"domain":"notify","target":{"areaId":[],"deviceId":[],"entityId":[]},"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"all","x":550,"y":80,"wires":[[]]},{"id":"8a2ecff38edf7efd","type":"subflow:6dc0247c.d7210c","z":"a38123c1.2fd3f","name":"","x":516,"y":544,"wires":[[],[],[],[]]}]
    +
    Old versions

    v0.0.0

    [{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]}]
    +
    OptionsDescriptionDocumentation
    Notify ServiceCan take multiple services as a comma delimited list e.g.: mobile_app_username, mobile_app_username2
    TitleTop line of textlinkopen in new window
    MessageSecond line of text accepts HTML tagslinkopen in new window
    Action TitleThe button titlelinkopen in new window
    Action URIlovelace dashboard, https:// or app://. If URI is defined no action is returned to Node-REDlinkopen in new window
    User InfoWill resolve user info in Node-RED and place it in msg.userData
    StickySet whether to dismiss the notification upon selecting it or notlinkopen in new window
    Groupstringlinkopen in new window
    ColorColor name or the hex codelinkopen in new window
    TimeoutHow long a notification will be shown on a users device before being removed automaticallylinkopen in new window
    IconPath to iconlinkopen in new window

    Any setting can be set or overwritten using msg.actionable to pass a notification object into the node.

    Demo flow

    screenshot

    [{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"581acb2a.792564","type":"subflow:6dc0247c.d7210c","z":"31cdc.c18e83244","name":"","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"testing actionable notification","type":"str"},{"name":"action1Title","value":"action one","type":"str"},{"name":"action2Title","value":"open HA","type":"str"},{"name":"action2Uri","value":"/lovelace/0","type":"str"},{"name":"action3Title","value":"action three","type":"str"},{"name":"userInfo","type":"bool","value":"true"},{"name":"group","value":"","type":"str"}],"x":436,"y":1136,"wires":[["d2b46240.6de89"],["a63fb7bc.64af88"],["2f4904b8.568d3c"],["75334c15.956694"]]},{"id":"aa8e9e73.4957f","type":"inject","z":"31cdc.c18e83244","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"abc","payload":"default payload","payloadType":"str","x":202,"y":1136,"wires":[["581acb2a.792564"]]},{"id":"d2b46240.6de89","type":"debug","z":"31cdc.c18e83244","name":"action1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1088,"wires":[]},{"id":"a63fb7bc.64af88","type":"debug","z":"31cdc.c18e83244","name":"action2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1120,"wires":[]},{"id":"2f4904b8.568d3c","type":"debug","z":"31cdc.c18e83244","name":"action3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1152,"wires":[]},{"id":"75334c15.956694","type":"debug","z":"31cdc.c18e83244","name":"cleared","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":652,"y":1184,"wires":[]},{"id":"81797230.4299e","type":"inject","z":"31cdc.c18e83244","name":"clear_notification","props":[{"p":"clear_notification","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":208,"y":1184,"wires":[["581acb2a.792564"]]}]
    +

    Use Case 1: Get a notification when garage door is left open with ability to ignore the alert for an amount of time

    screenshot

    [{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"bec57b08.0a8f08","type":"time-range-switch","z":"31cdc.c18e83244","name":"","lat":"","lon":"","startTime":"sunsetStart","endTime":"6:00","startOffset":"-15","endOffset":0,"x":474,"y":1552,"wires":[["1b96dc9e.4f1fe3"],[]]},{"id":"31d5412.74a31be","type":"poll-state","z":"31cdc.c18e83244","name":"garage door open?","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"30","updateIntervalUnits":"seconds","outputinitially":true,"outputonchanged":true,"entity_id":"cover.garage_door","state_type":"str","halt_if":"open","halt_if_type":"str","halt_if_compare":"is","outputs":2,"x":122,"y":1584,"wires":[["6566fa4.a832004"],["5485b497.b4d90c"]]},{"id":"765bef97.90e0e","type":"throttle","z":"31cdc.c18e83244","name":"Once / 30 mins","throttleType":"time","timeLimit":"15","timeLimitType":"minutes","countLimit":0,"blockSize":0,"locked":false,"x":848,"y":1600,"wires":[["587bab85.857fe4"]]},{"id":"587bab85.857fe4","type":"subflow:6dc0247c.d7210c","z":"31cdc.c18e83244","name":"close garage door?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Garage Door","type":"str"},{"name":"message","value":"Garage Door is Open","type":"str"},{"name":"action1Title","value":"Close Door","type":"str"},{"name":"action2Title","value":"Ignore 1 hour","type":"str"},{"name":"action3Title","value":"Ignore 2 hours","type":"str"},{"name":"group","value":"","type":"str"}],"x":1050,"y":1600,"wires":[["e85a9609.74ddd8"],["8c90dfc.28f2f2"],["df484d95.35a35"],["13c8aaf9.466e05"]],"icon":"font-awesome/fa-car"},{"id":"e85a9609.74ddd8","type":"api-call-service","z":"31cdc.c18e83244","name":"close garage door","version":1,"debugenabled":false,"service_domain":"cover","service":"close_cover","entityId":"cover.garage_door","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1258,"y":1552,"wires":[[]]},{"id":"1d0b3f5b.37aab1","type":"api-current-state","z":"31cdc.c18e83244","name":"not home?","version":1,"outputs":2,"halt_if":"home","halt_if_type":"num","halt_if_compare":"is_not","override_topic":false,"entity_id":"person.jason","state_type":"str","state_location":"","override_payload":"none","entity_location":"","override_data":"none","blockInputOverrides":false,"x":662,"y":1600,"wires":[["765bef97.90e0e"],[]]},{"id":"8c90dfc.28f2f2","type":"change","z":"31cdc.c18e83244","name":"","rules":[{"t":"set","p":"ignore","pt":"msg","to":"60","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1183,"y":1600,"wires":[["88fd9ca4.3ea69"]],"l":false},{"id":"df484d95.35a35","type":"change","z":"31cdc.c18e83244","name":"","rules":[{"t":"set","p":"ignore","pt":"msg","to":"120","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1183,"y":1632,"wires":[["88fd9ca4.3ea69"]],"l":false},{"id":"6566fa4.a832004","type":"function","z":"31cdc.c18e83244","name":"ignore?","func":"if(msg.ignore) {\n    const timeout = Date.now() + msg.ignore * 60000;\n    const d = new Date(timeout);\n    context.set('timeout', timeout)\n    node.status({text: `Ignoring until ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`, fill: \"red\"});\n    return;\n}\n\nconst timeout = context.get('timeout') || 0;\n\nif(timeout > Date.now()) return;\n\nnode.status({});\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":300,"y":1584,"wires":[["bec57b08.0a8f08","8f5a5cc3.fb235"]]},{"id":"88fd9ca4.3ea69","type":"link out","z":"31cdc.c18e83244","name":"Ignore","links":["9e5e4c22.4d925"],"x":1298,"y":1600,"wires":[],"l":true},{"id":"9e5e4c22.4d925","type":"link in","z":"31cdc.c18e83244","name":"","links":["88fd9ca4.3ea69"],"x":191,"y":1536,"wires":[["6566fa4.a832004"]]},{"id":"13c8aaf9.466e05","type":"change","z":"31cdc.c18e83244","name":"","rules":[{"t":"set","p":"ignore","pt":"msg","to":"30","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1183,"y":1664,"wires":[["88fd9ca4.3ea69"]],"l":false},{"id":"8f5a5cc3.fb235","type":"trigger","z":"31cdc.c18e83244","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"2","extend":false,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":454,"y":1600,"wires":[["1d0b3f5b.37aab1"]]},{"id":"5485b497.b4d90c","type":"change","z":"31cdc.c18e83244","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":1632,"wires":[["8f5a5cc3.fb235","1b96dc9e.4f1fe3"]]},{"id":"1b96dc9e.4f1fe3","type":"trigger","z":"31cdc.c18e83244","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"15","extend":false,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":662,"y":1552,"wires":[["765bef97.90e0e"]]}]
    +

    Required Nodes

    Use Case 2: Ask if vacation mode should be turned on after being away for 24 hours

    screenshot

    [{"id":"6dc0247c.d7210c","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"9d85d137.fe487"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"974bd48d.c253e8","port":0}]},{"x":1172,"y":176,"wires":[{"id":"974bd48d.c253e8","port":1}]},{"x":1172,"y":224,"wires":[{"id":"974bd48d.c253e8","port":2}]},{"x":964,"y":240,"wires":[{"id":"5bc7345c.07b1cc","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"204dbcfc.144ae4","port":0}]}},{"id":"f9e57204.71076","type":"function","z":"6dc0247c.d7210c","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = !!uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["368c9723.5876f8"]]},{"id":"974bd48d.c253e8","type":"switch","z":"6dc0247c.d7210c","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"204dbcfc.144ae4","type":"status","z":"6dc0247c.d7210c","name":"","scope":["f9e57204.71076","5bc7345c.07b1cc","a622c92a.2d9898","368c9723.5876f8"],"x":124,"y":272,"wires":[[]]},{"id":"5bc7345c.07b1cc","type":"function","z":"6dc0247c.d7210c","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["974bd48d.c253e8"],[]]},{"id":"8d3bdc0c.37493","type":"switch","z":"6dc0247c.d7210c","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["83ad2004.d04d"]]},{"id":"271e4479.b9249c","type":"ha-api","z":"6dc0247c.d7210c","name":"get user info","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["5bc7345c.07b1cc"]]},{"id":"3618f055.6909a","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_cleared","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["8d3bdc0c.37493"]]},{"id":"83ad2004.d04d","type":"switch","z":"6dc0247c.d7210c","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["271e4479.b9249c"],["5bc7345c.07b1cc"]]},{"id":"9d85d137.fe487","type":"switch","z":"6dc0247c.d7210c","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["f9e57204.71076"],["a622c92a.2d9898"]],"l":false},{"id":"a622c92a.2d9898","type":"function","z":"6dc0247c.d7210c","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["368c9723.5876f8"]]},{"id":"9bfe567c.3d10c8","type":"server-events","z":"6dc0247c.d7210c","name":"mobile_app_notification_action","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["8d3bdc0c.37493"]]},{"id":"368c9723.5876f8","type":"api-call-service","z":"6dc0247c.d7210c","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"b35b9988.72c6d8","type":"server-state-changed","z":"f6d789f6.6b5388","name":"Away?","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"24","forType":"num","forUnits":"hours","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":290,"y":256,"wires":[["4587eb7f.fb86a4"],[]]},{"id":"4587eb7f.fb86a4","type":"api-current-state","z":"f6d789f6.6b5388","name":"Vacation mode off?","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":458,"y":256,"wires":[["e5d8423c.2ccfe"],[]]},{"id":"be568091.56bbb","type":"api-call-service","z":"f6d789f6.6b5388","name":"Turn On Vacation Mode","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":942,"y":256,"wires":[[]]},{"id":"e5d8423c.2ccfe","type":"subflow:6dc0247c.d7210c","z":"f6d789f6.6b5388","name":"Turn on Vacation Mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been away for 24 hours.<br>Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":686,"y":272,"wires":[["be568091.56bbb"],[],[],[]]}]
    +

    Also see:

    + + + diff --git a/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html b/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html new file mode 100644 index 0000000000..4f140a8d76 --- /dev/null +++ b/cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html @@ -0,0 +1,36 @@ + + + + + + + + + Check if an entity was a certain state in the last 24 hours | node-red-contrib-home-assistant-websocket + + + + + +

    Check if an entity was a certain state in the last 24 hours

    Use the get-history to get a list of state changes for the last 24 hours. Filter them using a switch node looking for a given state and then count the remaining to see if the entity was in that state during the time frame.

    screenshot

    [{"id":"3f683250.b26f1e","type":"inject","z":"ffbd7f06.4a014","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":236,"y":1008,"wires":[["e60a02e6.d2afc"]]},{"id":"aa3e26cd.152828","type":"debug","z":"ffbd7f06.4a014","name":"do something","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":976,"y":1008,"wires":[]},{"id":"e60a02e6.d2afc","type":"api-get-history","z":"ffbd7f06.4a014","name":"","startdate":"","enddate":"","entityid":"light.kitchen_light","entityidtype":"is","useRelativeTime":true,"relativeTime":"24 hours","flatten":true,"output_type":"split","output_location_type":"msg","output_location":"payload","x":380,"y":1008,"wires":[["b162effa.fc78f"]]},{"id":"b162effa.fc78f","type":"switch","z":"ffbd7f06.4a014","name":"on?","property":"payload.state","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":true,"outputs":1,"x":530,"y":1008,"wires":[["e4b98b67.bde238"]]},{"id":"e4b98b67.bde238","type":"join","z":"ffbd7f06.4a014","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":658,"y":1008,"wires":[["fff04d54.5615e"]]},{"id":"fff04d54.5615e","type":"switch","z":"ffbd7f06.4a014","name":"count > 0","property":"payload.length","propertyType":"msg","rules":[{"t":"gt","v":"0","vt":"num"}],"checkall":"true","repair":true,"outputs":1,"x":796,"y":1008,"wires":[["aa3e26cd.152828"]]}]
    +

    Here's the same example but using a function node.

    screenshot

    [{"id":"f79cd7b0.604f98","type":"inject","z":"ffbd7f06.4a014","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":332,"y":1200,"wires":[["753a1de3.091fa4"]]},{"id":"753a1de3.091fa4","type":"api-get-history","z":"ffbd7f06.4a014","name":"","startdate":"","enddate":"","entityid":"light.kitchen_light","entityidtype":"is","useRelativeTime":true,"relativeTime":"24 hours","flatten":true,"output_type":"array","output_location_type":"msg","output_location":"payload","x":476,"y":1200,"wires":[["389b5575.43217a"]]},{"id":"389b5575.43217a","type":"function","z":"ffbd7f06.4a014","name":"check state","func":"const state = \"on\";\nconst filtered = msg.payload.filter((entity) => entity.state === state);\n\nif(filtered.length > 0) {\n    msg.payload = filtered;\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":644,"y":1200,"wires":[["6a582450.883bdc"]]},{"id":"6a582450.883bdc","type":"debug","z":"ffbd7f06.4a014","name":"do something","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":832,"y":1200,"wires":[]}]
    +
    + + + diff --git a/cookbook/expiration-date-monitor.html b/cookbook/expiration-date-monitor.html new file mode 100644 index 0000000000..38a331dcee --- /dev/null +++ b/cookbook/expiration-date-monitor.html @@ -0,0 +1,54 @@ + + + + + + + + + Expiration Date Monitor with notification | node-red-contrib-home-assistant-websocket + + + + + +

    Expiration Date Monitor with notification

    Originally posted hereopen in new window on the Home Assistant Forums.

    Here's a demo showing how to build a system to track the expiration date of items in the pantry. Using the Home Assistant Shopping Listopen in new window as a way to input and update a list of items and their expiration date.

    The format of the name in the shopping list would be [item] : [expiration date] with a colon separating the item name from the expiration date.

    Home Assistant stuff

    First, you would have to activate the shopping list in the config. https://www.home-assistant.io/integrations/shopping_list/open in new window

    # Example configuration.yaml entry
    +shopping_list:
    +

    There's already a lovelace card for the shopping list. I also added an input_number to dynamically control the expiration window to check.

    # Example configuration.yaml entry
    +input_number:
    +  pantry_expiration:
    +    name: Pantry Expiration Window
    +    initial: 90
    +    min: 30
    +    max: 120
    +    step: 1
    +    unit_of_measurement: days
    +    icon: mdi:calendar-clock
    +

    Simple Lovelace config

    image|498x346

    type: vertical-stack
    +cards:
    +  - title: Pantry Items
    +    type: shopping-list
    +  - type: entities
    +    entities:
    +      - input_number.pantry_expiration
    +

    Node-RED stuff

    You can set the inject node to fire at a set time each day or every other day whatever fits your needs.

    image|690x93

    [{"id":"e78bbe2c.9141","type":"inject","z":"56b1c979.b2c618","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":284,"y":1056,"wires":[["720213f9.9bb8fc"]]},{"id":"adeab5ee.bc4098","type":"ha-api","z":"56b1c979.b2c618","name":"Get Items","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"shopping_list/items\"}","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":652,"y":1056,"wires":[["236e3cd6.fab7d4"]]},{"id":"236e3cd6.fab7d4","type":"function","z":"56b1c979.b2c618","name":"do the stuff","func":"const items = msg.payload;\n\nif (items.length === 0) return;\n\nconst expItems = [];\n\n// Current timestamp + expiration days in milliseconds\nconst expireWindow = Date.now() + msg.expDays * 8.64e7;\n\nitems.forEach(i => {\n  // If the name doesn't contain the split character don't process\n  // If complete set to true in the shopping list don't process\n  if (!i.name.includes(\":\") || i.complete === true) return;\n\n  // Split the name and remove white spaces\n  const [name, exp] = i.name.split(\":\").map(x => x.trim());\n\n  // check for valid date\n  const expiredDate = Date.parse(exp);\n  if (isNaN(expiredDate) || expiredDate > expireWindow) return;\n  \n  // Add item to expired list\n  expItems.push({ \n      name, \n      exp, \n      inThePast: expiredDate < Date.now()\n  });\n});\n\n// If array is empty nothing to report\nif (expItems.length === 0) return;\n\nmsg.payload = expItems;\n\nreturn msg;\n","outputs":1,"noerr":0,"x":822,"y":1056,"wires":[["4270d967.43cc08"]]},{"id":"720213f9.9bb8fc","type":"api-current-state","z":"56b1c979.b2c618","name":"Get expiration window","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_number.pantry_expiration","state_type":"num","state_location":"expDays","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":468,"y":1056,"wires":[["adeab5ee.bc4098"]]},{"id":"4270d967.43cc08","type":"split","z":"56b1c979.b2c618","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":290,"y":1120,"wires":[["e1f6793d.9be5f8"]]},{"id":"3d3871cd.cb442e","type":"join","z":"56b1c979.b2c618","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":674,"y":1120,"wires":[["ddffd5ea.ebd528"]]},{"id":"e1f6793d.9be5f8","type":"moment","z":"56b1c979.b2c618","name":"pretty","topic":"","input":"payload.exp","inputType":"msg","inTz":"America/Los_Angeles","adjAmount":0,"adjType":"days","adjDir":"add","format":"timeAgo","locale":"en_US","output":"payload.pretty","outputType":"msg","outTz":"America/Los_Angeles","x":418,"y":1120,"wires":[["c96d522b.7cfbb"]]},{"id":"c96d522b.7cfbb","type":"function","z":"56b1c979.b2c618","name":"format","func":"const d = msg.payload;\nmsg.payload = `${d.name} expire${d.inThePast ? 'd' : 's'} ${d.pretty}`;\nreturn msg;","outputs":1,"noerr":0,"x":544,"y":1120,"wires":[["3d3871cd.cb442e"]]},{"id":"ddffd5ea.ebd528","type":"api-call-service","z":"56b1c979.b2c618","name":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_phone","entityId":"","data":"{\t    \"title\": \"Pantry Items Expiring:\",\t    \"message\": $join(payload, \"\\n\")\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":882,"y":1120,"wires":[[]]}]
    +

    image|551x297

    There's a lot more polish that could go into this such as being notified if the date entered in the shopping list is invalid or doesn't have a date at all. Sort the expired list so that the closest to expiring is at the top.

    + + + diff --git a/cookbook/get-state_changed-events-based-on-area.html b/cookbook/get-state_changed-events-based-on-area.html new file mode 100644 index 0000000000..702d4e73cc --- /dev/null +++ b/cookbook/get-state_changed-events-based-on-area.html @@ -0,0 +1,35 @@ + + + + + + + + + Get state_changed Events Based on Area | node-red-contrib-home-assistant-websocket + + + + + +

    Get state_changed Events Based on Area

    screenshot

    [{"id":"c964194d.7ad5e8","type":"ha-api","z":"ffbd7f06.4a014","name":"areas","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/area_registry/list\"}","dataType":"json","location":"areas","locationType":"msg","responseType":"json","x":514,"y":944,"wires":[["4b011603.4c27f8"]]},{"id":"832ebec4.0d4a4","type":"inject","z":"ffbd7f06.4a014","name":"Manual Update","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":320,"y":944,"wires":[["c964194d.7ad5e8"]]},{"id":"4b011603.4c27f8","type":"ha-api","z":"ffbd7f06.4a014","name":"devices","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/device_registry/list\"}","dataType":"json","location":"devices","locationType":"msg","responseType":"json","x":654,"y":944,"wires":[["4be8b708.430ec8"]]},{"id":"4be8b708.430ec8","type":"ha-api","z":"ffbd7f06.4a014","name":"entities","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/entity_registry/list\"}","dataType":"json","location":"entities","locationType":"msg","responseType":"json","x":798,"y":944,"wires":[["59e18ea8.03287"]]},{"id":"2538006.71ef4","type":"debug","z":"ffbd7f06.4a014","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1144,"y":944,"wires":[]},{"id":"81c8e84.471e218","type":"server-events","z":"ffbd7f06.4a014","name":"","event_type":"state_changed","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":308,"y":1040,"wires":[["6e177280.669dec"]]},{"id":"59e18ea8.03287","type":"function","z":"ffbd7f06.4a014","name":"","func":"const entities = {};\n\nmsg.entities.forEach(e => {\n    if(!e.device_id) return;\n    \n    const device = msg.devices.find(d => d.id === e.device_id);\n    const area = msg.areas.find(a => a.area_id === device.area_id);\n    if(area) {\n        entities[e.entity_id] = {\n            area_id: area.area_id,\n            name: area.name\n        };\n    }\n});\n\nmsg.payload = entities;\nmsg.update = true;\nreturn msg;","outputs":1,"noerr":0,"x":964,"y":944,"wires":[["2538006.71ef4","6e177280.669dec"]]},{"id":"6e177280.669dec","type":"function","z":"ffbd7f06.4a014","name":"set area","func":"if(msg.update) {\n    node.status({fill:\"green\", shape: \"dot\", text: \"Area Data Loaded\", })\n    context.set(\"data\", msg.payload);\n    return;\n}\nconst data = context.get(\"data\");\n\nif(!data) {\n    node.status({fill:\"red\", shape: \"ring\", text: \"No Area Data\", })\n    return;\n}\n\nconst area = data[msg.payload.entity_id];\nif(!area) return;\n\nmsg.area = area.name.toLowerCase();     \nnode.status({text: msg.area});\n\nreturn msg;","outputs":1,"noerr":0,"x":524,"y":1040,"wires":[["86100cd0.de8c5"]]},{"id":"582c98e0.5cd328","type":"debug","z":"ffbd7f06.4a014","name":"Kitchen","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":828,"y":1024,"wires":[]},{"id":"b60ead00.b4aaa","type":"debug","z":"ffbd7f06.4a014","name":"Bedroom","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":828,"y":1072,"wires":[]},{"id":"86100cd0.de8c5","type":"switch","z":"ffbd7f06.4a014","name":"","property":"area","propertyType":"msg","rules":[{"t":"eq","v":"kitchen","vt":"str"},{"t":"eq","v":"bedroom","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":656,"y":1040,"wires":[["582c98e0.5cd328"],["b60ead00.b4aaa"]]},{"id":"94d81549.f88148","type":"server-events","z":"ffbd7f06.4a014","name":"On Connect","event_type":"home_assistant_client","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":278,"y":896,"wires":[["72ef46c0.dbbce8"]]},{"id":"72ef46c0.dbbce8","type":"switch","z":"ffbd7f06.4a014","name":"connected","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"connected","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":470,"y":896,"wires":[["c964194d.7ad5e8"]]},{"id":"47aad143.f438c","type":"server-events","z":"ffbd7f06.4a014","name":"entity_registry_updated","event_type":"entity_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":308,"y":752,"wires":[["c7d0582b.715958"]]},{"id":"58d3bcdb.d39014","type":"server-events","z":"ffbd7f06.4a014","name":"device_registry_updated","event_type":"device_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":318,"y":800,"wires":[["c7d0582b.715958"]]},{"id":"8a9f192c.425718","type":"server-events","z":"ffbd7f06.4a014","name":"area_registry_updated","event_type":"area_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"x":308,"y":848,"wires":[["c7d0582b.715958"]]},{"id":"c7d0582b.715958","type":"trigger","z":"ffbd7f06.4a014","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","name":"Update at most every 10 secs","x":610,"y":800,"wires":[["c964194d.7ad5e8"]]}]
    +
    + + + diff --git a/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.html b/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.html new file mode 100644 index 0000000000..5e1894e80f --- /dev/null +++ b/cookbook/holiday-lights-scheduler-and-demo-mode-for-wled.html @@ -0,0 +1,125 @@ + + + + + + + + + Holiday lights scheduler and demo mode for WLED | node-red-contrib-home-assistant-websocket + + + + + +

    Holiday lights scheduler and demo mode for WLED

    Questions and Discussion

    Post questions and follow the discussion about this recipe hereopen in new window

    Here's a flow to control some outdoor house LEDs hooked up to an ESP8266 running WLEDopen in new window.

    The holiday lights turn on each day at sunset and then off at midnight. It uses WLEDopen in new window presets based on the day or season. It has a demo mode that will cycle through all the defined presets or all the included effects.

    screenshot of flow

    Version 1

    [{"id":"886a465.91a0ab8","type":"switch","z":"894a6b3077af9604","name":"dark?","property":"dark","propertyType":"flow","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":240,"wires":[["5e38e1ee8665f5e7"],["90579358.a3dce"]]},{"id":"34cb332b.f8228c","type":"server-state-changed","z":"894a6b3077af9604","name":"Demo Mode","server":"","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_select.holiday_lights_demo_mode","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"","forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":294,"y":384,"wires":[["df0da821.aa74b8"],["91131276.4f322"]]},{"id":"90579358.a3dce","type":"api-call-service","z":"894a6b3077af9604","name":"turn off holiday lights","server":"","version":3,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"data"}],"queue":"last","x":692,"y":288,"wires":[[]]},{"id":"dc4b2af1.d366a8","type":"ha-wait-until","z":"894a6b3077af9604","name":"loop","server":"","version":0,"outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"60","timeoutType":"num","timeoutUnits":"minutes","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":false,"x":850,"y":240,"wires":[[],["5e38e1ee8665f5e7"]]},{"id":"59e25c2c.a3a514","type":"eztimer","z":"894a6b3077af9604","name":"","debug":false,"autoname":"sunset - 00:00","tag":"test1","suspended":false,"sendEventsOnSuspend":false,"latLongSource":"manual","latLongHaZone":"","lat":"","lon":"","timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onpropertytype":"flow","onproperty":"dark","onvaluetype":"bool","onvalue":"true","onoffset":"","onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"00:00","offduration":0,"offpropertytype":"flow","offproperty":"dark","offvaluetype":"bool","offvalue":"false","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"resend":false,"resendInterval":"1m","mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":304,"y":240,"wires":[["886a465.91a0ab8"]]},{"id":"f4ab62e2.10029","type":"api-call-service","z":"894a6b3077af9604","name":"turn on holiday lights","server":"","version":3,"debugenabled":false,"service_domain":"select","service":"select_option","entityId":"{{flow.wledHolidayLightsPresetEntityId}}","data":"{\"option\": payload}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"last","x":900,"y":192,"wires":[[]]},{"id":"98efb1f6.c85b8","type":"ha-wait-until","z":"894a6b3077af9604","name":"loop","server":"","version":0,"outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"$number($entities(\"input_number.holiday_lights_demo_mode_delay\").state)","timeoutType":"jsonata","timeoutUnits":"seconds","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":true,"x":1058,"y":432,"wires":[[],["91131276.4f322"]]},{"id":"91131276.4f322","type":"switch","z":"894a6b3077af9604","name":"which mode?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"cycle presets","vt":"str"},{"t":"eq","v":"cycle effects","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":470,"y":432,"wires":[["5adba3095728cdab"],["28fd29dc.96d306"]]},{"id":"333ed476.51a77c","type":"api-call-service","z":"894a6b3077af9604","name":"turn on preset","server":"","version":3,"debugenabled":false,"service_domain":"select","service":"select_option","entityId":"{{flow.wledHolidayLightsPresetEntityId}}","data":"{\"option\": name}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":880,"y":432,"wires":[["98efb1f6.c85b8","d0b9f667.79a8c8"]]},{"id":"fcf7dabd.b7a368","type":"api-call-service","z":"894a6b3077af9604","name":"turn on effect","server":"","version":3,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\"effect\": name}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":870,"y":480,"wires":[["98efb1f6.c85b8","d0b9f667.79a8c8"]]},{"id":"df0da821.aa74b8","type":"change","z":"894a6b3077af9604","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":384,"wires":[["886a465.91a0ab8","98efb1f6.c85b8"]]},{"id":"998c4f75.52cbf","type":"api-call-service","z":"894a6b3077af9604","name":"turn off demo mode","server":"","version":3,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.holiday_lights_demo_mode","data":"{\"option\": \"off\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":570,"y":528,"wires":[[]]},{"id":"5caeec35.01a114","type":"server-state-changed","z":"894a6b3077af9604","name":"Holiday Lights turned off?","server":"","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.wled","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":332,"y":528,"wires":[["998c4f75.52cbf"],[]]},{"id":"28fd29dc.96d306","type":"function","z":"894a6b3077af9604","name":"get next effect","func":"const states = global.get(\"homeassistant\").homeAssistant.states;\nconst entityId = flow.get(\"wledHolidayLightsEntityId\");\nconst effects = states[entityId].attributes.effect_list;\nconst activeEffect = states[entityId].attributes.effect;\nlet index = effects.findIndex(ele => ele === activeEffect);\nindex = (index === -1 || index >= effects.length - 1) ? 0 : index + 1;\n\nnode.status({text: effects[index]});\n\nmsg.name = effects[index];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":672,"y":480,"wires":[["fcf7dabd.b7a368"]]},{"id":"d0b9f667.79a8c8","type":"ha-entity","z":"894a6b3077af9604","name":"current demo","server":"","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Holiday Lights Demo Current"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"name","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":1078,"y":480,"wires":[[]]},{"id":"9168ce00.dc7de","type":"comment","z":"894a6b3077af9604","name":"Scheduler","info":"","x":284,"y":192,"wires":[]},{"id":"241d097a.a3fe76","type":"comment","z":"894a6b3077af9604","name":"Demo Mode","info":"","x":294,"y":336,"wires":[]},{"id":"22f2928a.e2ae9e","type":"inject","z":"894a6b3077af9604","name":"Manual Start","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"dark","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":294,"y":288,"wires":[["5e38e1ee8665f5e7"]]},{"id":"9f8ca90550d41489","type":"inject","z":"894a6b3077af9604","name":"Setup","props":[{"p":"entityId","v":"light.holiday_lights","vt":"str"}],"repeat":"3600","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":284,"y":144,"wires":[["1047f2356f1e5203"]]},{"id":"1047f2356f1e5203","type":"change","z":"894a6b3077af9604","name":"set entity ids here","rules":[{"t":"set","p":"wledHolidayLightsEntityId","pt":"flow","to":"light.wled","tot":"str"},{"t":"set","p":"wledHolidayLightsPresetEntityId","pt":"flow","to":"select.wled_preset","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":144,"wires":[[]]},{"id":"5e38e1ee8665f5e7","type":"function","z":"894a6b3077af9604","name":"date ranges","func":"const now = new Date();\nconst monthDay = getMonthDay(now);\nconst states = global.get(\"homeassistant\").homeAssistant.states;\nconst entityId = flow.get(\"wledHolidayLightsEntityId\");\nconst presetId = flow.get(\"wledHolidayLightsPresetEntityId\");\nconst christmasPresets = [\n  \"Christmas\",\n  \"Christmas Candy Cane\",\n  \"Christmas Classic\",\n  \"Christmas Holly Jolly\"\n];\n\nlet updateInterval = 0; // in minutes\nlet preset;\n\nswitch(true) {\n// Winter \n    case isToday(214):\n      preset = \"Valentine\";\n      break;\n// President's Day changes every year, Veteran's Day & Flag Day always the same date\n    case isToday(614): // 6/14 Flag Day\n    case isToday(1111): // 11/11 Veterans Day\n    case isToday(\"President's Day\"):\n    case isToday(\"Memorial Day\"):\n      preset = \"Red White Blue\";\n      break;\n    case isToday(317):\n      preset = \"St Patty\";\n      break;\n    case isToday(\"Easter\"):\n      preset = \"Easter\";\n      break;\n    case isToday(\"Ash Wednesday\", \"Easter\"):\n      preset = \"Spring\";\n      break;\n// Spring\n    case isToday(504):\n      preset = \"Star Wars\";\n      break;\n    case isToday(505):\n      preset = \"Cinco de Mayo\";\n      break;\n// Summer\n    case isToday(704):\n      preset = \"Fireworks\";\n      break;\n// Autumn\n    case isToday(1014, 1031):\n      preset = \"Halloween\";\n      break;\n    case isToday(\"Thanksgiving Day\"):\n      preset = \"Autumn\";\n      break;\n    case isToday(1231):\n      preset = \"Fireworks White\";\n      break;\n    case isToday(\"Thanksgiving Day\", 1231):\n    case isToday(101, 106):\n      preset = getRandomPreset(christmasPresets);\n      updateInterval = 60;\n      break;\n    default:\n      const seasons = {\n        \"winter\": \"Winter\",\n        \"spring\": \"Spring\",\n        \"summer\": \"Summer\",\n        \"autumn\": \"Autumn\"\n      }\n      const currentSeason = states[\"sensor.season\"].state;\n      preset = seasons[currentSeason];\n      break;\n}\n\nnode.status({ text: preset});\nmsg.payload = preset;\nconst secondOutput = updateInterval ?  { payload: { timeout: updateInterval } } : { reset: true };\n\nreturn [msg, secondOutput];\n\nfunction isToday(start, end) {\n  if (typeof start === \"string\") {\n    start = getHolidayDate(now, start)\n  }\n  if (typeof end === \"string\") {\n    end = getHolidayDate(now, end)\n  }\n  if (end === undefined) return monthDay === start;\n\n  return monthDay >= start && monthDay <= end;\n}\n\nfunction getHolidayDate(date, holiday) {\n    holiday = holiday.toLowerCase();\n    // dates are formatted as month, week, day of the week\n    // names should be lowercase\n    const holidays = {\n        \"martin luther king day\": [0,2,1],\n        \"president's day\": [1,2,1],\n        \"daylight savings time begins\": [2,1,0],\n        \"mother's day\": [4,1,0],\n        \"memorial day\": [4,-1,1],\n        \"father's day\": [5,2,0],\n        \"labor day\": [8,0,1],\n        \"columbus day\": [9,1,1],\n        \"daylight savings time ends\": [10,0,0],\n        \"thanksgiving day\": [10,3,4]\n    };\n    let holidayDate;\n    if(holiday === \"easter\") {\n        holidayDate = getEasterDate(date);\n    } else if (holiday === \"ash wednesday\") {\n        const easter = getEasterDate(date);\n        holidayDate = new Date(easter.getFullYear(), easter.getMonth(), (easter.getDate()-46));\n    } else {\n        const [month, week, day] = holidays[holiday];\n        holidayDate = getDate(date.getFullYear(), month, week, day);\n    }\n    \n    const monthDay = getMonthDay(holidayDate);\n    \n    return monthDay;\n}\n\nfunction getMonthDay(date) {\n    const monthString = String(date.getMonth() + 1).padStart(2, \"0\");\n    const dayString = String(date.getDate()).padStart(2, \"0\");\n    const monthDay = Number(`${monthString}${dayString}`);\n    \n    return monthDay;\n}\n\nfunction getDate(year, month, week, day) {\n    let firstDay = 1;\n    if (week < 0) {\n        month++;\n        firstDay--;\n    }\n    const date = new Date(year, month, (week * 7) + firstDay);\n    if (day < date.getDay()) {\n        day += 7;\n    }\n    date.setDate(date.getDate() - date.getDay() + day);\n    return date;\n}\n\n/**\n * Calculates Easter in the Gregorian/Western (Catholic and Protestant) calendar\n * based on the algorithm by Oudin (1940) from http://www.tondering.dk/claus/cal/easter.php\n * @returns {array} [int month, int day]\n */\nfunction getEasterDate(date) {\n  const year = date.getFullYear();\n  const f = Math.floor,\n    // Golden Number - 1\n    G = year % 19,\n    C = f(year / 100),\n    // related to Epact\n    H = (C - f(C / 4) - f((8 * C + 13) / 25) + 19 * G + 15) % 30,\n    // number of days from 21 March to the Paschal full moon\n    I = H - f(H / 28) * (1 - f(29 / (H + 1)) * f((21 - G) / 11)),\n    // weekday for the Paschal full moon\n    J = (year + f(year / 4) + I + 2 - C + f(C / 4)) % 7,\n    // number of days from 21 March to the Sunday on or before the Paschal full moon\n    L = I - J,\n    month = 3 + f((L + 40) / 44),\n    day = L + 28 - 31 * f(month / 4);\n\n  return new Date(`${month}/${day}/${year}`);\n}\n\nfunction getRandomPreset(list) {\n  const activePreset = states[presetId].state;\n  const filteredList = list.filter((e) => e !== activePreset);\n  \n  return filteredList[Math.floor(Math.random() * filteredList.length)];\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":662,"y":240,"wires":[["f4ab62e2.10029"],["dc4b2af1.d366a8"]]},{"id":"e01d1bd31bd9e634","type":"comment","z":"894a6b3077af9604","name":"Change holiday dates in the \"date ranges\" node","info":"","x":404,"y":96,"wires":[]},{"id":"5adba3095728cdab","type":"function","z":"894a6b3077af9604","name":"get next preset","func":"const states = global.get(\"homeassistant\").homeAssistant.states;\nconst presetId = flow.get(\"wledHolidayLightsPresetEntityId\");\nconst presets = states[presetId].attributes.options;\nconst activePreset = states[presetId].state;\nlet index = presets.findIndex(ele => ele === activePreset);\nindex = index === -1 || index >= presets.length - 1 ? 0 : index +1;\nconst name = presets[index];\n\nnode.status({text: name });\n\nmsg.name = name;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":672,"y":432,"wires":[["333ed476.51a77c"]]}]
    +
    version 0
    [{"id":"eb756b3f.d770f8","type":"subflow","name":"Create HA Helpers","info":"","category":"","in":[{"x":84,"y":96,"wires":[{"id":"7f1493fc.1300fc"}]}],"out":[],"env":[{"name":"serverName","type":"str","value":"Home Assistant","ui":{"label":{"en-US":"HA Server Name"},"type":"input","opts":{"types":["str"]}}},{"name":"helpers","type":"json","value":"[]","ui":{"label":{"en-US":"Helpers"},"type":"input","opts":{"types":["json"]}}}],"color":"#DDAA99","status":{"x":246,"y":48,"wires":[{"id":"a66d5d93.8a5f","port":0}]}},{"id":"7f1493fc.1300fc","type":"function","z":"eb756b3f.d770f8","name":"process helpers","func":"const serverName = toCamelCase(env.get('serverName'));\nconst haServer = global.get(\"homeassistant\")[serverName];\nif(!haServer) {\n    node.error(\"Invalid HA server name\");\n    return;\n}\nconst states = haServer.states;\nconst helpers = env.get(\"helpers\");\n\nhelpers.forEach(h => {\n    const entityId = `${h.type}.${h.id}`;\n    if(!states[entityId]) {\n        const {id, type, ...data} = h;\n        const apiData = {\n            entity: h,\n            payload: { \n                data \n            }\n        };\n        apiData.payload.data.type = `${type}/create`;\n    \n        node.send(apiData);\n        node.status({text: `Creating ${entityId}`});\n    }\n});\n\nnode.done();\n\nfunction toCamelCase(str) {\n    return str.replace(/(?:^\\w|[A-Z]|\\b\\w|\\s+)/g, (match, index) => {\n        if (+match === 0) return '';\n        return index === 0 ? match.toLowerCase() : match.toUpperCase();\n    });\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":224,"y":96,"wires":[["a4a0abd9.7576d8"]]},{"id":"a4a0abd9.7576d8","type":"ha-api","z":"eb756b3f.d770f8","name":"create helper","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":390,"y":96,"wires":[["b76d0c56.d54b9"]]},{"id":"388bb5c7.47346a","type":"ha-api","z":"eb756b3f.d770f8","name":"rename helper entity id","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\t   \"type\":\"config/entity_registry/update\",\t   \"entity_id\": entity.type & \".\" & payload.id,\t   \"new_entity_id\": entity.type & \".\" & entity.id\t}","dataType":"jsonata","location":"payload","locationType":"msg","responseType":"json","x":788,"y":96,"wires":[[]]},{"id":"b76d0c56.d54b9","type":"switch","z":"eb756b3f.d770f8","name":"need to rename?","property":"payload.id","propertyType":"msg","rules":[{"t":"neq","v":"entity.id","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":96,"wires":[["388bb5c7.47346a","3e47440a.eee2cc"]]},{"id":"a66d5d93.8a5f","type":"status","z":"eb756b3f.d770f8","name":"","scope":["7f1493fc.1300fc","858d7015.518f4","3e47440a.eee2cc"],"x":124,"y":48,"wires":[[]]},{"id":"3e47440a.eee2cc","type":"function","z":"eb756b3f.d770f8","name":"rename status","func":"const oldEntityId = `${msg.entity.type}.${msg.payload.id}`;\nconst newEntityId = `${msg.entity.type}.${msg.entity.id}`;\n\nnode.status({text: `Renaming ${oldEntityId} to ${newEntityId}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":768,"y":144,"wires":[[]]},{"id":"4762791a.4c5408","type":"function","z":"daf25abf.0203b8","name":"date ranges","func":"const now = new Date();\nconst monthDay = getMonthDay(now);\nconst { idLookup, nameLookup } = flow.get(\"wledHolidayLightsPresets\");\nconst christmasPresets = [\n  \"Christmas\",\n  \"Christmas Classic\",\n  \"Christmas Holly Jolly\",\n  \"Christmas Candy Cane\"\n];\nconst states = global.get(\"homeassistant\").homeAssistant.states;\nconst entityId = flow.get(\"wledHolidayLightsEntityId\");\n\nlet updateInterval = 0; // in minutes\nlet preset;\n\nswitch(true) {\n// Winter \n    case isToday(214):\n      preset = \"Valentine\";\n      break;\n// President's Day changes every year, Veteran's Day & Flag Day always the same date\n    case isToday(614): // 6/14 Flag Day\n    case isToday(1111): // 11/11 Veterans Day\n    case isToday(\"President's Day\"):\n    case isToday(\"Memorial Day\"):\n      preset = \"Red, White, and Blue\";\n      break;\n    case isToday(317):\n      preset = \"St Patty\";\n      break;\n    case isToday(\"Easter\"):\n      preset = \"Easter\";\n      break;\n// Spring\n    case isToday(504):\n      preset = \"Starwars\";\n      break;\n    case isToday(505):\n      preset = \"Cinco de Mayo\";\n      break;\n// Summer\n    case isToday(704):\n      preset = \"Independence Day\";\n      break;\n// Autumn\n    case isToday(1017, 1031):\n      preset = \"Halloween\";\n      break;\n    case isToday(\"Thanksgiving Day\"):\n      preset = \"Autumn\";\n      break;\n    case isToday(1231):\n      preset = \"New Years\";\n      break;\n    case isToday(\"Thanksgiving Day\", 1231):\n    case isToday(101, 106):\n      preset = getRandomPreset(christmasPresets);\n      updateInterval = 60;\n      break;\n    default:\n      const seasons = {\n        \"winter\": \"Winter\",\n        \"spring\": \"Spring\",\n        \"summer\": \"Summer\",\n        \"autumn\": \"Autumn\"\n      }\n      const currentSeason = states[\"sensor.season\"].state;\n      preset = seasons[currentSeason];\n      break;\n}\n\nnode.status({ text: preset});\nmsg.payload = nameLookup[preset];\nconst secondOutput = updateInterval ?  { payload: { timeout: updateInterval } } : { reset: true };\n\nreturn [msg, secondOutput];\n\nfunction isToday(start, end) {\n  if (typeof start === \"string\") {\n    start = getHolidayDate(now, start)\n  }\n  if (typeof end === \"string\") {\n    end = getHolidayDate(now, end)\n  }\n  if (end === undefined) return monthDay === start;\n\n  return monthDay >= start && monthDay <= end;\n}\n\nfunction getHolidayDate(date, holiday) {\n    holiday = holiday.toLowerCase();\n    // dates are formatted as month, week, day of the week\n    // names should be lowercase\n    const holidays = {\n        \"martin luther king day\": [0,2,1],\n        \"president's day\": [1,2,1],\n        \"daylight savings time begins\": [2,1,0],\n        \"mother's day\": [4,1,0],\n        \"memorial day\": [4,-1,1],\n        \"father's day\": [5,2,0],\n        \"labor day\": [8,0,1],\n        \"columbus day\": [9,1,1],\n        \"daylight savings time ends\": [10,0,0],\n        \"thanksgiving day\": [10,3,4]\n    };\n    let holidayDate;\n    if(holiday === \"easter\") {\n        holidayDate = getEasterDate(date); \n    } else {\n        const [month, week, day] = holidays[holiday];\n        holidayDate = getDate(date.getFullYear(), month, week, day);\n    }\n    \n    const monthDay = getMonthDay(holidayDate);\n    \n    return monthDay;\n}\n\nfunction getMonthDay(date) {\n    const monthString = String(date.getMonth() + 1).padStart(2, \"0\");\n    const dayString = String(date.getDate()).padStart(2, \"0\");\n    const monthDay = Number(`${monthString}${dayString}`);\n    \n    return monthDay;\n}\n\nfunction getDate(year, month, week, day) {\n    let firstDay = 1;\n    if (week < 0) {\n        month++;\n        firstDay--;\n    }\n    const date = new Date(year, month, (week * 7) + firstDay);\n    if (day < date.getDay()) {\n        day += 7;\n    }\n    date.setDate(date.getDate() - date.getDay() + day);\n    return date;\n}\n\n/**\n * Calculates Easter in the Gregorian/Western (Catholic and Protestant) calendar\n * based on the algorithm by Oudin (1940) from http://www.tondering.dk/claus/cal/easter.php\n * @returns {array} [int month, int day]\n */\nfunction getEasterDate(date) {\n  const year = date.getFullYear();\n  const f = Math.floor,\n    // Golden Number - 1\n    G = year % 19,\n    C = f(year / 100),\n    // related to Epact\n    H = (C - f(C / 4) - f((8 * C + 13) / 25) + 19 * G + 15) % 30,\n    // number of days from 21 March to the Paschal full moon\n    I = H - f(H / 28) * (1 - f(29 / (H + 1)) * f((21 - G) / 11)),\n    // weekday for the Paschal full moon\n    J = (year + f(year / 4) + I + 2 - C + f(C / 4)) % 7,\n    // number of days from 21 March to the Sunday on or before the Paschal full moon\n    L = I - J,\n    month = 3 + f((L + 40) / 44),\n    day = L + 28 - 31 * f(month / 4);\n\n  return new Date(`${month}/${day}/${year}`);\n}\n\nfunction getRandomPreset(list) {\n  const activePreset = states[entityId].attributes.preset;\n  const presetName = idLookup[activePreset];\n  const filteredList = list.filter((e) => e !== presetName);\n  \n  return filteredList[Math.floor(Math.random() * filteredList.length)];\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","x":470,"y":272,"wires":[["91b62e9f.fe736","dece0bc.3c215f8"],["dc570e50.22a3a"]]},{"id":"c46d93f8.1fe18","type":"switch","z":"daf25abf.0203b8","name":"dark?","property":"dark","propertyType":"flow","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":306,"y":272,"wires":[["4762791a.4c5408"],["73710f8.1582bf"]]},{"id":"fe4f63d8.5312c","type":"server-state-changed","z":"daf25abf.0203b8","name":"Demo Mode","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_select.holiday_lights_demo_mode","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"","forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"x":102,"y":464,"wires":[["1a546dd7.2d8ef2"],["92c007de.c4a168"]]},{"id":"73710f8.1582bf","type":"api-call-service","z":"daf25abf.0203b8","name":"turn off holiday lights","server":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":500,"y":320,"wires":[[]]},{"id":"dc570e50.22a3a","type":"ha-wait-until","z":"daf25abf.0203b8","name":"loop","server":"","outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"60","timeoutType":"num","timeoutUnits":"minutes","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":false,"x":658,"y":272,"wires":[[],["4762791a.4c5408"]]},{"id":"f5422b5c.762798","type":"eztimer","z":"daf25abf.0203b8","name":"","debug":false,"autoname":"sunset - 00:00","tag":"test1","suspended":false,"sendEventsOnSuspend":false,"latLongSource":"manual","latLongHaZone":"zone.home","lat":"","lon":"","timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onpropertytype":"msg","onproperty":"dark","onvaluetype":"bool","onvalue":"true","onoffset":"","onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"00:00","offduration":0,"offpropertytype":"msg","offproperty":"dark","offvaluetype":"bool","offvalue":"false","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"resend":false,"resendInterval":"1m","mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":112,"y":272,"wires":[["c800976d.89af98"]]},{"id":"91b62e9f.fe736","type":"api-call-service","z":"daf25abf.0203b8","name":"turn on holiday lights","server":"","version":1,"debugenabled":false,"service_domain":"wled","service":"preset","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\"preset\": payload}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":708,"y":224,"wires":[[]]},{"id":"78b7479f.e79dd8","type":"function","z":"daf25abf.0203b8","name":"get preset","func":"// WLED Presets\nconst { nameLookup } = flow.get(\"wledHolidayLightsPresets\");\n\nmsg.payload = nameLookup[msg.payload];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":668,"y":176,"wires":[["cc0fc459.d7f3a8"]]},{"id":"6a3ef206.84c5fc","type":"api-call-service","z":"daf25abf.0203b8","name":"populate HA dropdown with presets","server":"","version":1,"debugenabled":false,"service_domain":"input_select","service":"set_options","entityId":"input_select.holiday_lights_presets","data":"{\"options\": payload}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":748,"y":128,"wires":[["d7d3f0e8.9971d"]]},{"id":"a6b79bf.256d268","type":"inject","z":"daf25abf.0203b8","name":"Setup","props":[{"p":"entityId","v":"light.holiday_lights","vt":"str"},{"p":"WLED_IP","v":"","vt":"str"}],"repeat":"3600","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":108,"y":128,"wires":[["4b308915.771578"]]},{"id":"1538c003.e770a","type":"ha-wait-until","z":"daf25abf.0203b8","name":"loop","server":"","outputs":2,"entityId":"{{flow.wledHolidayLightsEntityId}}","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"$number($entities(\"input_number.holiday_lights_demo_mode_delay\").state)","timeoutType":"jsonata","timeoutUnits":"seconds","entityLocation":"","entityLocationType":"none","checkCurrentState":false,"blockInputOverrides":true,"x":866,"y":512,"wires":[[],["92c007de.c4a168"]]},{"id":"92c007de.c4a168","type":"switch","z":"daf25abf.0203b8","name":"which mode?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"cycle presets","vt":"str"},{"t":"eq","v":"cycle effects","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":278,"y":512,"wires":[["29bbe4ad.4de71c"],["7f2dc75.a04cf38"]]},{"id":"422a9fe2.d974c","type":"api-call-service","z":"daf25abf.0203b8","name":"turn on preset","server":"","version":1,"debugenabled":false,"service_domain":"wled","service":"preset","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\"preset\": preset}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":688,"y":512,"wires":[["1538c003.e770a","e132c6fa.e3da18"]]},{"id":"9755a99c.54ba18","type":"api-call-service","z":"daf25abf.0203b8","name":"turn on effect","server":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"{{flow.wledHolidayLightsEntityId}}","data":"{\"effect\": effect}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":678,"y":560,"wires":[["1538c003.e770a","e132c6fa.e3da18"]]},{"id":"1a546dd7.2d8ef2","type":"change","z":"daf25abf.0203b8","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"},{"t":"set","p":"payload","pt":"msg","to":"info","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":258,"y":464,"wires":[["1538c003.e770a","c46d93f8.1fe18"]]},{"id":"71da85fd.de44fc","type":"api-call-service","z":"daf25abf.0203b8","name":"turn off demo mode","server":"","version":1,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.holiday_lights_demo_mode","data":"{\"option\": \"off\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":378,"y":608,"wires":[[]]},{"id":"320d2444.2aa86c","type":"server-state-changed","z":"daf25abf.0203b8","name":"Holiday Lights turned off?","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.holiday_lights","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"off","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":140,"y":608,"wires":[["71da85fd.de44fc"],[]]},{"id":"7f2dc75.a04cf38","type":"function","z":"daf25abf.0203b8","name":"get next effect","func":"const states = global.get(\"homeassistant\").homeAssistant.states;\nconst entityId = flow.get(\"wledHolidayLightsEntityId\");\nconst effects = states[entityId].attributes.effect_list;\nconst activeEffect = states[entityId].attributes.effect;\nlet index = effects.findIndex(ele => ele === activeEffect);\nindex = (index === -1 || index >= effects.length - 1) ? 0 : index + 1;\n\nnode.status({text: effects[index]});\n\nmsg.effect = msg.name = effects[index];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":560,"wires":[["9755a99c.54ba18"]]},{"id":"29bbe4ad.4de71c","type":"function","z":"daf25abf.0203b8","name":"get next preset","func":"const states = global.get(\"homeassistant\").homeAssistant.states;\nconst entityId = flow.get(\"wledHolidayLightsEntityId\");\nconst { idLookup, nameLookup } = flow.get(\"wledHolidayLightsPresets\");\nconst keys = Object.keys(idLookup);\nconst activePreset = states[entityId].attributes.preset;\nlet index = keys.findIndex(ele => ele == activePreset);\nindex = index === -1 || index >= keys.length - 1 ? 0 : index +1;\nconst name = idLookup[keys[index]];\n\nnode.status({text: name });\n\nmsg.preset = keys[index];\nmsg.name = name;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":512,"wires":[["422a9fe2.d974c"]]},{"id":"d89db901.9fd588","type":"function","z":"daf25abf.0203b8","name":"process data","func":"if(msg.statusCode !== 200) {\n    node.status({fill: 'red', shape: 'dot', text: `Status Code: ${msg.statusCode}`})\n    return;\n}\n\nconst wledPresets = msg.payload;\nconst idLookup = {};\nconst nameLookup = {};\n\nfor(const key in wledPresets) {\n    if(Object.keys(wledPresets[key]).length > 0) {\n        const name = wledPresets[key].n;\n        idLookup[key] = name;\n        nameLookup[name] = key;\n    }\n}\n\nconst presets = {\n    idLookup,\n    nameLookup,\n    names: Object.values(idLookup).sort()\n};\n\nflow.set(\"wledHolidayLightsPresets\", presets);\nflow.set(\"wledHolidayLightsEntityId\", msg.entityId);\nnode.status({text: `${presets.names.length} Presets Processed`});\n\nmsg.payload = presets.names;\n\nreturn [msg, { payload: \"disable\" }];","outputs":2,"noerr":0,"initialize":"","finalize":"","x":470,"y":128,"wires":[["6a3ef206.84c5fc"],["539eea44.9b6524"]]},{"id":"d7d3f0e8.9971d","type":"change","z":"daf25abf.0203b8","name":"enable","rules":[{"t":"set","p":"payload","pt":"msg","to":"enable","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":962,"y":128,"wires":[["7c6317af.370198"]]},{"id":"539eea44.9b6524","type":"trigger-state","z":"daf25abf.0203b8","name":"Preset Selector","server":"","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"input_select.holiday_lights_presets","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","comparatorType":"is_not","comparatorValueDatatype":"prevEntity","comparatorValue":"state","propertyValue":"new_state.state"}],"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":480,"y":176,"wires":[["78b7479f.e79dd8"],[]]},{"id":"e132c6fa.e3da18","type":"ha-entity","z":"daf25abf.0203b8","name":"current demo","server":"","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Holiday Lights Demo Current"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"name","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","x":886,"y":560,"wires":[[]]},{"id":"a3f0ee9.6fd551","type":"server-events","z":"daf25abf.0203b8","name":"HA Client Events","server":"","event_type":"home_assistant_client","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":112,"y":176,"wires":[["6c13e445.ca929c"]]},{"id":"6c13e445.ca929c","type":"function","z":"daf25abf.0203b8","name":"HA running?","func":"if(msg.payload !== \"running\") return;\n\nconst { names } = flow.get(\"wledHolidayLightsPresets\");\n\nmsg.payload = names;\n\nreturn [msg, { payload: \"disable\" }];","outputs":2,"noerr":0,"initialize":"","finalize":"","x":278,"y":176,"wires":[["6a3ef206.84c5fc"],["539eea44.9b6524"]]},{"id":"afc3f7e9.88ac98","type":"comment","z":"daf25abf.0203b8","name":"Setup","info":"","x":82,"y":32,"wires":[]},{"id":"5b75e78b.d9d608","type":"comment","z":"daf25abf.0203b8","name":"Scheduler","info":"","x":92,"y":224,"wires":[]},{"id":"cc0fc459.d7f3a8","type":"link out","z":"daf25abf.0203b8","name":"turn on holiday lights","links":["d830a00d.1d744"],"x":852,"y":176,"wires":[],"l":true},{"id":"d830a00d.1d744","type":"link in","z":"daf25abf.0203b8","name":"Holiday Lights On","links":["cc0fc459.d7f3a8"],"x":527,"y":224,"wires":[["91b62e9f.fe736"]]},{"id":"215b93f8.a1883c","type":"comment","z":"daf25abf.0203b8","name":"Demo Mode","info":"","x":102,"y":416,"wires":[]},{"id":"4b308915.771578","type":"http request","z":"daf25abf.0203b8","name":"get presets","method":"GET","ret":"obj","paytoqs":"ignore","url":"http://{{WLED_IP}}/presets.json","tls":"","persist":false,"proxy":"","authType":"","x":278,"y":128,"wires":[["d89db901.9fd588"]]},{"id":"7c6317af.370198","type":"delay","z":"daf25abf.0203b8","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1100,"y":128,"wires":[["539eea44.9b6524"]]},{"id":"aea9da7f.af56a8","type":"ha-entity","z":"daf25abf.0203b8","name":"current preset","server":"","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Holiday Lights Current Preset"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","x":480,"y":368,"wires":[[]]},{"id":"4b02330f.bc08fc","type":"function","z":"daf25abf.0203b8","name":"format","func":"const { idLookup } = flow.get(\"wledHolidayLightsPresets\");\nconst id = msg.data.new_state.attributes.preset || 0;\nconst presetName = idLookup[id] || \"none\";\n\nmsg.payload = msg.payload === \"on\" ? presetName : \"none\";\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":258,"y":368,"wires":[["aea9da7f.af56a8"]]},{"id":"a3f37acd.911a88","type":"server-state-changed","z":"daf25abf.0203b8","name":"Preset Updated","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"light.holiday_lights","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":112,"y":368,"wires":[["4b02330f.bc08fc"]]},{"id":"dece0bc.3c215f8","type":"debug","z":"daf25abf.0203b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":752,"y":336,"wires":[]},{"id":"c800976d.89af98","type":"change","z":"daf25abf.0203b8","name":"","rules":[{"t":"set","p":"dark","pt":"flow","to":"dark","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":223,"y":272,"wires":[["c46d93f8.1fe18"]],"l":false},{"id":"b1ec00ad.8c8f7","type":"subflow:eb756b3f.d770f8","z":"daf25abf.0203b8","name":"","env":[{"name":"helpers","value":"[{\"id\":\"holiday_lights_demo_mode_delay\",\"type\":\"input_number\",\"name\":\"Cycle Delay\",\"initial\":30,\"min\":-5,\"max\":300,\"step\":5,\"icon\":\"mdi:timer-sand\"},{\"id\":\"holiday_lights_demo_mode\",\"type\":\"input_select\",\"name\":\"Mode\",\"options\":[\"off\",\"cycle effects\",\"cycle presets\"],\"initial\":\"off\",\"icon\":\"mdi:animation\"},{\"id\":\"holiday_lights_presets\",\"type\":\"input_select\",\"name\":\"Presets\",\"options\":[\"none\"],\"icon\":\"mdi:animation\"}]","type":"json"}],"x":346,"y":80,"wires":[]},{"id":"297d2a12.388f86","type":"inject","z":"daf25abf.0203b8","name":"Create HA elements","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":138,"y":80,"wires":[["b1ec00ad.8c8f7"]]}]
    +

    Requirements

    Integrations

    The season integration is used to determine the current season and set a WLEDopen in new window preset if no other holiday range is defined.

    The two entity nodes will require the Node-RED custom integration but the flow will function fine without it. The UI just won't have the updated current preset and demo effect displayed.

    Nodes

    Setup

    The flow has been modified so that it should run pretty much out of the box after changing the entity id for the light and IP for the WLED controller.

    1. Setting up WLED variables
    2. Modifing holiday date ranges
    3. Creating Home Assistant entities

    WLED variables

    screenshot of a node that needs to be editted

    Edit the change node, set entity ids here, to edit the Home Assistant entity id of the holiday lights and the select entity for presets. The entity of your WLED light needs to be changed in two places.

    Setting date ranges up

    Holidays can be either a single day or a range of dates. If no holiday is defined for the current day it will default to the season preset WINTER, SPRING, SUMMER, and AUTUMN.

    screenshot of a node that needs to be editted

    In the date ranges node, a lot is going on but the main thing is the switch statement that determines which preset to use.

    The isToday function can take two arguments but only the first one is required which is the start date of the holiday. The second argument is the end date of the holiday. Both of the arguments can take a number in the format of MONTHDAY or a holiday name defined in the getHolidayDate function on line #92.

    Lines 16 - 72

    switch (true) {
    +  // Winter
    +  case isToday(214):
    +    preset = "Valentine";
    +    break;
    +  // President's Day changes every year, Veteran's Day & Flag Day always the same date
    +  case isToday(614): // 6/14 Flag Day
    +  case isToday(1111): // 11/11 Veterans Day
    +  case isToday("President's Day"):
    +  case isToday("Memorial Day"):
    +    preset = "Red, White, and Blue";
    +    break;
    +  case isToday(317):
    +    preset = "St Patty";
    +    break;
    +  case isToday("Easter"):
    +    preset = "Easter";
    +    break;
    +  // Spring
    +  case isToday(504):
    +    preset = "Starwars";
    +    break;
    +  case isToday(505):
    +    preset = "Cinco de Mayo";
    +    break;
    +  // Summer
    +  case isToday(704):
    +    preset = "Independence Day";
    +    break;
    +  // Autumn
    +  case isToday(1017, 1031):
    +    preset = "Halloween";
    +    break;
    +  case isToday("Thanksgiving Day"):
    +    preset = "Autumn";
    +    break;
    +  case isToday(1231):
    +    preset = "New Years";
    +    break;
    +  case isToday("Thanksgiving Day", 1231):
    +  case isToday(101, 106):
    +    const activePreset = states[entityId].attributes.preset;
    +    const presetName = idLookup[activePreset];
    +    preset = getRandomPreset(christmasPresets.filter((e) => e !== presetName));
    +    updateInterval = 60;
    +    break;
    +  default:
    +    const seasons = {
    +      winter: "Winter",
    +      spring: "Spring",
    +      summer: "Summer",
    +      autumn: "Autumn",
    +    };
    +    const currentSeason = states["sensor.season"].state;
    +    preset = seasons[currentSeason];
    +    break;
    +}
    +

    Home Assistant Entities

    Three entities will need to be created in Home Assistant two input_selectopen in new window and an input_numberopen in new window. The helpers configuration, Configuration > Helpers, can be used or writing them in YAML.

    input_number.holiday_lights_demo_mode_delay

    input_number:
    +  holiday_lights_demo_mode_delay:
    +    name: Cycle Delay
    +    initial: 30
    +    min: -5
    +    max: 300
    +    step: 5
    +    icon: "mdi:timer-sand"
    +

    screenshot of lovelace ui

    input_select.holiday_lights_demo_mode

    input_select:
    +  holiday_lights_demo_mode:
    +    name: Mode
    +    options:
    +      - off
    +      - cycle effects
    +      - cycle presets
    +    initial: off
    +    icon: "mdi:animation"
    +

    screenshot of lovelace ui

    Lovelace UI

    screenshot of lovelace ui

    title: Holiday Lights
    +type: entities
    +entities:
    +  - entity: light.holiday_lights
    +  - entity: select.holiday_lights_presets
    +  - type: section
    +    label: Demo Mode
    +  - type: conditional
    +    conditions:
    +      - entity: input_select.holiday_lights_demo_mode
    +        state_not: "off"
    +    row:
    +      entity: sensor.holiday_lights_demo_current
    +  - entity: input_select.holiday_lights_demo_mode
    +  - entity: input_number.holiday_lights_demo_mode_delay
    +

    Things that could have been added but never got around to it

    • Previous and Next button in the demo UI
    + + + diff --git a/cookbook/index.html b/cookbook/index.html new file mode 100644 index 0000000000..62d577a2bb --- /dev/null +++ b/cookbook/index.html @@ -0,0 +1,34 @@ + + + + + + + + + Cookbook | node-red-contrib-home-assistant-websocket + + + + + +
    + + + diff --git a/cookbook/jsonata/call-service.html b/cookbook/jsonata/call-service.html new file mode 100644 index 0000000000..4633daafde --- /dev/null +++ b/cookbook/jsonata/call-service.html @@ -0,0 +1,71 @@ + + + + + + + + + Call Service | node-red-contrib-home-assistant-websocket + + + + + +

    Call Service

    Integrations in Home Assistant provide service calls that can be used, for example, to set target temperature on heaters and air-conditioning units. All service calls can be found and tested within Home Assistant Developer toolbox, and it is also useful to check the integration documentation to identify exactly what is required for a successful service call.

    All service calls require:

    • a domain (integration platform) such as 'climate'
    • a service call within this domain, such as 'set_temperature'
    • a target entity or entities (or area or device containing entities) to apply the service to
    • a JSON data object, containing any additional required and optional parameters

    The data object will vary, depending on the integration and service call, from an empty object {} to something much more complex. Constructing this data object correctly is key to a successful service call, and JSONata rather than mustache templating should ideally be used to achieve this.

    Note: The data field used in a service call must be a valid JSON object.

    • Mustache templates are delimited with {{msg.payload}}. Although acceptable in most JSON input fields, this is invalid syntax in JSONata expressions and must not be used.
    • Home Assistant configuration uses YAML constructs, containing space-tabulation for objects and '-' for arrays. This format is incompatible with both JSON and JSONata, but YAML constructs can be converted to JSON.
    • The WebSocket nodes Data UI field option typically offers two input methods:
      • {} for JSON - this must be strict JSON formed with all literals and string keys. Mustache templates may work successfully in simple strings. JSONata will not work here. The JSON option cannot accept anything other than literals and Mustache templates.
      • J: for JSONata (expression) - this must evaluate to strict JSON, but can be formed with expressions in both the object keys (evaluating as strings) and the object values. In JSONata, literals evaluate as themselves, so the JSONata option can accept a JSON literal construct.

    Passing variables to WebSocket nodes in summary

    JSONata in Node-RED nodes accesses the incoming message as a JSON object. Thus msg.payload is referenced just as payload and is evaluated as the value of that key. The leading 'msg.' is not required, and {{ payload }} is invalid JSONata syntax.

    Node-RED typically uses msg.payload to pass values between nodes, however any field can be used. Most WebSocket nodes have output properties that default to set msg.data to the entity details, and therefore in the flow following (not in) the node, data.state will typically provide the state value of the entity that was the subject of the preceding WebSocket node.

    Within the WebSocket node itself, the entity data is accessed using the special JSONata $entity() function, hence $entity().state would be used. In a similar manner, the $entities() function can reference any Home Assistant entity, and $entities('sensor.date_time').state would return the state value of the given date_time sensor.

    In JSONata, as well as using message fields or the entity functions, Node-RED provides functions to access environment variables using $env('ENV_NAME'). Global context can be read using $globalContext(name[, store]) and flow context likewise as $flowContext(name[, store]).

    JSONata and the Call Service node

    For Node-RED flows with a Call Service node there are three locations where the Data object can be defined.

    • Directly in the Call Service node UI 'Data' field, using the JSONata option.
    • In a preceding Change node, passing the Service Call settings in a msg.payload object.
    • In a flow trigger node, such as Events: state node, generated as an output msg.payload object.

    There are advantages and drawbacks to each approach, and personal choice as well as the particular case and need will influence your flow design.

    screenshot

    Here are three examples, each using JSONata to set the required Data object, and one example of using JSONata to process service call return data.

    [{"id":"0050317002075c30","type":"group","z":"776c027950fc8c3f","name":"Call Service node - build a data object / process call return","style":{"label":true,"color":"#000000"},"nodes":["a67d69634829a418","86cbf80d.5a9cf8","8aad6643.9ee7a8","897a31873370f8cb","3bbb02bc34fb543a","6601ecbcd16c5aa3","fe24231bb58e259d","b0b87dc3a978e67e","8602b67dfe66a5e3","fe9baddadc8fea32","fd65cb1e1c933b3a","0acd153a39f25184","be9ef2598f33324a","8446a03e6d2b76a3","3c75c1ae78ed9894","9fc179c38d22f267","c84c9a405862bb69","f0d2bc4cc11a7608"],"x":34,"y":39,"w":1212,"h":442},{"id":"a67d69634829a418","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"","server":"","version":5,"debugenabled":false,"domain":"climate","service":"set_temperature","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1030,"y":220,"wires":[[]]},{"id":"86cbf80d.5a9cf8","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"","server":"","version":5,"debugenabled":false,"domain":"light","service":"turn_on","areaId":[],"deviceId":[],"entityId":["light.kitchen"],"data":"{\"brightness\": $min([$entities(\"light.kitchen\").attributes.brightness + $number($entities(\"input_number.brightness\").state), 255])}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"data"}],"queue":"none","output_location":"payload","output_location_type":"msg","x":730,"y":120,"wires":[[]]},{"id":"8aad6643.9ee7a8","type":"server-state-changed","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Remote Button","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"sensor.button","entityIdType":"exact","outputInitially":false,"stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":520,"y":120,"wires":[["86cbf80d.5a9cf8"]]},{"id":"897a31873370f8cb","type":"server-state-changed","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Input Number (Temp)","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"input_number.help_temp_number","entityIdType":"exact","outputInitially":false,"stateType":"num","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":540,"y":220,"wires":[["fe24231bb58e259d"]]},{"id":"3bbb02bc34fb543a","type":"inject","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Manual Test","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":530,"y":80,"wires":[["86cbf80d.5a9cf8"]]},{"id":"6601ecbcd16c5aa3","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1a - JSONata builds object in Call Service node \\n Increase light brightness with remote","info":"","x":240,"y":100,"wires":[]},{"id":"fe24231bb58e259d","type":"change","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Service Call Settings","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"target\": {\"entity_id\": $globalContext(\"AClist\")},\t   \"data\": {\t       \"temperature\": payload,\t       \"hvac_mode\": payload>20 ? \"heat\" : \"cool\"\t   }\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":220,"wires":[["a67d69634829a418"]]},{"id":"b0b87dc3a978e67e","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Send notification","server":"","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_geoff_phone","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":790,"y":300,"wires":[[]]},{"id":"8602b67dfe66a5e3","type":"server-state-changed","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Last person to leave","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"person.","entityIdType":"substring","outputInitially":false,"stateType":"str","ifState":"\"home\" in $entities().*[$substringBefore(entity_id,\".\")=\"person\"].state","ifStateType":"jsonata","ifStateOperator":"jsonata","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\t    \"data\": {\t        \"message\": \"The \" & $join($entities().*[state = \"on\" and entity_id ~> /^light|^switch/].attributes.friendly_name, \", \") & \" are on.\",\t        \"title\": \"Things Left On \" & $entity().attributes.friendly_name\t    }\t}","valueType":"jsonata"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":530,"y":300,"wires":[[],["b0b87dc3a978e67e"]]},{"id":"fe9baddadc8fea32","type":"api-call-service","z":"776c027950fc8c3f","g":"0050317002075c30","name":"","server":"","version":5,"debugenabled":false,"domain":"weather","service":"get_forecasts","areaId":[],"deviceId":[],"entityId":["weather.forecast_home"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"results","propertyType":"msg","value":"","valueType":"results"}],"queue":"none","x":360,"y":440,"wires":[["8446a03e6d2b76a3"]]},{"id":"fd65cb1e1c933b3a","type":"inject","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Set Forecast type","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"data\": {\"type\": \"hourly\"}}","payloadType":"jsonata","x":160,"y":440,"wires":[["fe9baddadc8fea32"]]},{"id":"0acd153a39f25184","type":"debug","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Start Hour","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"$substringAfter(payload.time,\"T\")~>$substringBefore(\"+\")","targetType":"jsonata","statusVal":"$substringAfter(payload.time,\"T\")~>$substringBefore(\"+\")","statusType":"auto","x":1130,"y":440,"wires":[]},{"id":"be9ef2598f33324a","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1d - JSONata extracts details from service call return \\n using Inject, Change, and Debug nodes","info":"","x":250,"y":380,"wires":[]},{"id":"8446a03e6d2b76a3","type":"change","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Extract forecast time and arrays of hourly temp, cloud, and rain","rules":[{"t":"set","p":"payload","pt":"msg","to":"results.*.forecast{\t   \"time\": $[0].datetime,\t   \"temp\": $.temperature,\t   \"cloud\": $.cloud_coverage,\t   \"rain\": $.precipitation\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":440,"wires":[["0acd153a39f25184","3c75c1ae78ed9894"]]},{"id":"3c75c1ae78ed9894","type":"debug","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1120,"y":400,"wires":[]},{"id":"9fc179c38d22f267","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1b - JSONata builds object in Change Node \\n Set a/c target temperature and mode","info":"","x":230,"y":200,"wires":[]},{"id":"c84c9a405862bb69","type":"comment","z":"776c027950fc8c3f","g":"0050317002075c30","name":"1c - JSONata builds object in Event: State node \\n Send notification when leaving home","info":"","x":240,"y":300,"wires":[]},{"id":"f0d2bc4cc11a7608","type":"inject","z":"776c027950fc8c3f","g":"0050317002075c30","name":"Turn Off","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\t   \"domain\": \"homeassistant\",\t   \"service\": \"turn_off\",\t   \"target\": {\t       \"area_id\": [\"bedroom\"]\t   },\t   \"data\": {} \t}","payloadType":"jsonata","x":820,"y":180,"wires":[["a67d69634829a418"]]}]
    +

    Setting the Data field

    Settings a data property from a Home Assistant entity

    Example: A Call Service node that sets the target temperature of a climate entity to the current temperature of a sensor entity.

    {
    +  "temperature": $entities("sensor.living_room_temperature").state
    +}
    +

    Setting a data property from a Home Assistant entity with a calculation

    Here the state of a sensor entity is read, converted to a number, and then increased by 3.

    WARNING

    States from Home Assistant are always strings, and so any calculations must be converted to a number first.

    {
    +  "temperature": $number($entities("sensor.living_room_temperature").state) + 3
    +}
    +

    Increase lights brightness with remote

    Example: A remote with a button that when clicked increases the brightness of a given light by an amount that is set from an input_number inside Home Assistant.

    JSONata expression in the Call Service node UI Data field. Nothing special is required as input to this node as all the settings are completed within the node itself.

    {
    +  "brightness": $min([
    +    $entities("light.kitchen").attributes.brightness +
    +      $number($entities("input_number.brightness").state),
    +    255
    +  ])
    +}
    +

    Setting target temperature on air-conditioning unit

    Example: Set the target temperature (and mode) for air-conditioning unit from the input msg.payload value.

    Here a Change node is used to build the msg.payload object required to set the Call Service node parameters, including the nested data field. In a Change node, the special WebSocket $entity() and $entities() functions are not available, however we can still perform a read from global context using the Node-RED $globalContext() function. These Node-RED functions can be used to bring in values from context and environment variables.

    {
    +   "target": {"entity_id": $globalContext("AClist")},
    +   "data": {
    +       "temperature": payload,
    +       "hvac_mode": payload>20 ? "heat" : "cool"
    +   }
    +}
    +

    The Call Service node can accept from one to all of the UI parameters in msg.payload, and where given these each take precedence over any UI settings. Default settings can therefore be set in the UI, and can then be over-riden by the input message, including when using settings from Inject nodes as shown in the example.

    Notification of lights left on when leaving home

    Example: Get notified when lights or switches are left on when you leave.

    This example uses JSONata in two places in the Events: state node. The state value test is a JSONata expression that must return true for the node to output a message (upper output). This code selects an array of all entity states for entities starting with 'person', and will return true if this array contains one or more with state "home". The expression will therefore only return false when no-one is home, and we can use the lower (condition fail) output rather than using the JSONata $not() function to look for 'not home'.

    "home" in $entities().*[$substringBefore(entity_id,".")="person"].state
    +

    JSONata is also then used in the output properties to create the required object for a notification service call. It uses $entities().* with a filter looking for those with "light" or "switch" in the entity_id and state "on", then selecting the friendly_name, and joining all those found into a string list in the message.

    The message title uses $entity().attributes.friendly_name to add the name of the person who just left home to the message title.

    {
    +    "data": {
    +        "message": "The " &
    +          $join($entities().*[state = "on" and entity_id ~>
    +          /^light|^switch/].attributes.friendly_name, ", ") &
    +          " are on.",
    +        "title": "Things Left On " & $entity().attributes.friendly_name
    +    }
    +}
    +

    In this example all the parameter setup is performed in the Events: state node, so the Call Service node can accept all the required parameters just from the input msg.payload object.

    Processing a service call return

    Home Assistant service calls can provide data returned as a result of the call, and JSONata is an ideal tool to manage any resulting JSON object and array structures. This example uses JSONata to extract and manipulate weather forecasts, providing a summary in a modified format.

    Example: The forecast service call now returns an array of forecasts. JSONata is used to iterate over all forecasts, returning an new object for each, with a time and arrays for temperature, cloud coverage, and precipitation only.

    results.*.forecast{
    +   "time": $[0].datetime,
    +   "temp": $.temperature,
    +   "cloud": $.cloud_coverage,
    +   "rain": $.precipitation
    +}
    +

    Also see:

    + + + diff --git a/cookbook/jsonata/change-node.html b/cookbook/jsonata/change-node.html new file mode 100644 index 0000000000..b92d585884 --- /dev/null +++ b/cookbook/jsonata/change-node.html @@ -0,0 +1,93 @@ + + + + + + + + + Change node | node-red-contrib-home-assistant-websocket + + + + + +

    Change node

    Using JSONata for more complex tasks:

    Many automations can be coded using a simple JSONata expression at some convenient point in the flow, often directly within one of the WebSocket nodes. Where the data involved is a more complex structure, then JSONata is a powerful tool for manipulating JSON objects and arrays. Almost all computation can be achieved using JSONata in a Change node in place of using a Function node.

    Read a person state history for the past week

    Since Home Assistant stores state history for 10 days by default, it is possible to read historic state records. The Get History node can do this for any given entity, and using relative time it is easy to obtain an array of past state-change events.

    There are no opportunities to use JSONata within the Get History node itself, however JSONata can be used both to setup the node parameters and to manipulate the returned array. In this example, JSONata is used extensively to:

    • set the input parameters for the time period required
    • read the current entity state for 'now' and the given entity ID
    • add an 'event' for 'now' and an 'event' for the start history-period time
    • calculate the time interval between successive state changes to create 'event-periods'
    • filter out any event periods less than, say, 50 minutes or for state 'unknown'
    • compact any now sequential equal-state events into one longer period

    This returns a filtered array of entity states, with the time that state period started and the time it ended, and the duration in minutes. The requirement for extensive data processing here is due to the way 'person' sensors report, giving rise to short periods of 'unknown' or 'away' because Wi-Fi signal or a smart phone has gone 'off-line'.

    screenshot

    [{"id":"1997b594da7d37b1","type":"group","z":"776c027950fc8c3f","name":"Process history data using JSONata in a change node","style":{"label":true,"color":"#000000"},"nodes":["bd6511844a39ca08","3d87bbb92fa35243","9a3ca494edc54a30","3a4534cdc46ae67d","891ee0da3deec2c1","27f0ecf4ea3dc24f","d5dc0b522463577a"],"x":34,"y":2499,"w":1312,"h":122},{"id":"bd6511844a39ca08","type":"api-current-state","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Get current state","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"person.george","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"payload ~> |$|{\"entityId\": $entity().entity_id}|","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":350,"y":2540,"wires":[["9a3ca494edc54a30"]]},{"id":"3d87bbb92fa35243","type":"inject","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Set parameters","props":[{"p":"payload"},{"p":"startAt","v":"$fromMillis($millis()-(7*24*60*60000))","vt":"jsonata"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"relativeTime\": \"1 week\"\t}","payloadType":"jsonata","x":160,"y":2540,"wires":[["bd6511844a39ca08"]]},{"id":"9a3ca494edc54a30","type":"api-get-history","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Read history","server":"","version":1,"startDate":"","endDate":"","entityId":"","entityIdType":"equals","useRelativeTime":true,"relativeTime":"","flatten":true,"outputType":"array","outputLocationType":"msg","outputLocation":"payload","x":530,"y":2540,"wires":[["3a4534cdc46ae67d"]]},{"id":"3a4534cdc46ae67d","type":"change","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Get filtered state periods","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t/* FILTER parameters */\t    $fMins:=50;\t\t/* get current state from entity 'data', and set the 'last_changed' to now */\t    $first:= data~>|$|{\"last_changed\": $now()}|;\t\t/* add this to far end of history payload array, then sort by reverse time order */\t    $x:=$append(payload, $first)^(>last_changed,>last_updated);\t\t/* copy the oldest state value, and add in as the first record at start of history */\t/* we now have a 'now' and 'start of history' record, even if payload was empty    */    \t    $x:=$append($x,{\"state\": $x[0].state, \"last_changed\": startAt});\t\t/* create array of state changes, with how long they have been in that state */\t/* remove any zero periods and unknown states FILTER OUT AS REQUIRED         */\t    $events:=$x#$i.(\t        $prior:= $i>0 ? $x[$i-1] : {\"first\": $now()};\t        {\"index\": $i,\t         \"state\": state,\t         \"from\": last_changed,\t         \"upto\": $prior.last_changed,\t         \"dmins\": ($toMillis($prior.last_changed)-$toMillis(last_changed))/60000~>$round(0)\t        }\t    )[dmins>$fMins and state!=\"unknown\"];\t\t/* merge consecutive records with the same state into one longer period */\t/* get each event position as 'start - middle - end' or 'only'          */\t\t    $temp:=$events#$v.(\t        $back:= $v<1 ? false : state = $events[$v-1].state;\t        $next:= state = $events[$v+1].state;\t        $position:=( $back ? ($next ? \"middle\" : \"end\") : ($next ? \"start\" : \"only\") );\t        $~>|$|{\"index\": $v, \"position\": $position}|\t    );\t\t/* get start and end indexes, and zip into a sequence array of [start, end]  */\t/* map this array of sequences to an array of objects, one for each sequence */\t/* where the object is the combination of a run of the same state value      */\t\t    $chain:=$zip($temp[position=\"start\"].index, $temp[position=\"end\"].index);\t\t    $array:=$map($chain, function($item) {(\t        $recA:=$events[$item[0]];\t        $recB:=$events[$item[1]];\t        {\"state\": $recA.state,\t        \"from\": $recB.from,\t        \"upto\":  $recA.upto,\t        \"dmins\": ($toMillis($recA.upto)-$toMillis($recB.from))/60000~>$round(0),\t        \"position\": \"merged\"}\t        )\t    });\t\t/* combine the 'only' single events with the now-merged sequences, and sort by time */\t    $append($temp[position=\"only\"], $array)^(>from);\t\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":2540,"wires":[["891ee0da3deec2c1","27f0ecf4ea3dc24f"]]},{"id":"891ee0da3deec2c1","type":"debug","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"State History Events","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1200,"y":2540,"wires":[]},{"id":"27f0ecf4ea3dc24f","type":"change","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"When 'not home' during the day","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[state=\"not_home\" and ($substringBefore(from,\"T\") = $substringBefore(upto,\"T\") ) ]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":2580,"wires":[["d5dc0b522463577a"]]},{"id":"d5dc0b522463577a","type":"debug","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Out during the day","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1190,"y":2580,"wires":[]}]
    +
    (
    +/* FILTER parameters */
    +    $fMins:=50;
    +
    +/* get current state from entity 'data', and set the 'last_changed' to now */
    +    $first:= data~>|$|{"last_changed": $now()}|;
    +
    +/* add this to far end of history payload array, then sort by reverse time order */
    +    $x:=$append(payload, $first)^(>last_changed,>last_updated);
    +
    +/* copy the oldest state value, and add in as the first record at start of history */
    +/* we now have a 'now' and 'start of history' record, even if payload was empty    */
    +    $x:=$append($x,{"state": $x[0].state, "last_changed": startAt});
    +
    +/* create array of state changes, with how long they have been in that state */
    +/* remove any zero periods and unknown states FILTER OUT AS REQUIRED         */
    +    $events:=$x#$i.(
    +        $prior:= $i>0 ? $x[$i-1] : {"first": $now()};
    +        {"index": $i,
    +         "state": state,
    +         "from": last_changed,
    +         "upto": $prior.last_changed,
    +         "dmins": ($toMillis($prior.last_changed)-$toMillis(last_changed))/60000~>$round(0)
    +        }
    +    )[dmins>$fMins and state!="unknown"];
    +
    +/* merge consecutive records with the same state into one longer period */
    +/* get each event position as 'start - middle - end' or 'only'          */
    +
    +    $temp:=$events#$v.(
    +        $back:= $v<1 ? false : state = $events[$v-1].state;
    +        $next:= state = $events[$v+1].state;
    +        $position:=( $back ? ($next ? "middle" : "end") : ($next ? "start" : "only") );
    +        $~>|$|{"index": $v, "position": $position}|
    +    );
    +
    +/* get start and end indexes, and zip into a sequence array of [start, end]  */
    +/* map this array of sequences to an array of objects, one for each sequence */
    +/* where the object is the combination of a run of the same state value      */
    +
    +    $chain:=$zip($temp[position="start"].index, $temp[position="end"].index);
    +
    +    $array:=$map($chain, function($item) {(
    +        $recA:=$events[$item[0]];
    +        $recB:=$events[$item[1]];
    +        {"state": $recA.state,
    +        "from": $recB.from,
    +        "upto":  $recA.upto,
    +        "dmins": ($toMillis($recA.upto)-$toMillis($recB.from))/60000~>$round(0),
    +        "position": "merged"}
    +        )
    +    });
    +
    +/* combine the 'only' single events with the now-merged sequences, and sort by time */
    +    $append($temp[position="only"], $array)^(>from);
    +
    +)
    +

    Notes:

    The Inject node uses JSONata to initially create msg.payload as a data object, setting the relative time parameter for the Get History node, and also setting the timestamp for the effective start of this time period.

    The Current State node uses JSONata in the output to retain msg.payload and also merge in the entityId using $entity().entity_id. This now sets msg.payload with the required input parameters for the Get History node (which therefore requires no UI settings). Full entity details are also captured in msg.data as usual.

    ::: caution This example code has been tested but person sensors can go 'off line' for long periods and the exact nature of the output data should be checked by experimentation. :::

    Report only those periods when 'not home' during the day

    Once state history has been manipulated like this into an event-array, it is easy to ask questions, such as "how many times has this person been away this week?"

    The question "when was this person away during the day?" for example, can be answered by filtering the state event array, to look for 'not home' and for the event period (both start and end) to be entirely on the same date.

    payload[state="not_home" and ($substringBefore(from,"T") = $substringBefore(upto,"T") ) ]
    +

    Note on history records:

    In asking for the history for the past 24 hours, the Get History node will return an array of all state change events that occurred within that time period. If the current state has been unchanged for the entire period requested, then an empty array will be returned.

    To address this, the JSONata code here first adds a record for 'now' with the current state. The code then finds the oldest state (which may well be the current 'now' state just added) and adds that as a record for 'the start of the time period requested' at that state. This ensures that the returned history event array is topped and tailed. The minimum state event array will therefore be one entry from start of history request to now, at the current state.

    Also see:

    + + + diff --git a/cookbook/jsonata/current-state.html b/cookbook/jsonata/current-state.html new file mode 100644 index 0000000000..6badcc8bbf --- /dev/null +++ b/cookbook/jsonata/current-state.html @@ -0,0 +1,47 @@ + + + + + + + + + Current State | node-red-contrib-home-assistant-websocket + + + + + +

    Current State

    The Current State node has several opportunities to use JSONata. This example demonstrates all of these, using a node to fetch the current state of a climate air-conditioning unit.

    The default output values for this node include setting msg.payload to the state (which for an A/C unit will be "off", "heat", "cool" or more, depending on the integration) as well as msg.data to the entire entity data object. This holds values for the last changed timestamp as well as attributes such as the friendly name and other integration dependent settings.

    screenshot

    Here are three examples, showing how to use JSONata to build output properties, to perform If-State conditional tests, and to provide calculated values for UI settings.

    [{"id":"d0f1fad3bf96a090","type":"group","z":"776c027950fc8c3f","name":"Current State node - read the state of an entity","style":{"label":true,"color":"#000000"},"nodes":["6394700dfd39838f","8388eb36d3e25254","852c05cf8c7cae73","a3e69091339a457c","11fc322e343cbd9c","6ac52ef3e9010615","63fa3b7423417fe4","a29810da49f1efd4","4f8197db85d55fb5","fd6d41b2f67b85e0","36912490ae36c0db","f84772ea62e6e7ba","6244f42dd53b7e1f","bc6cd64ba0266d97"],"x":34,"y":499,"w":1012,"h":382},{"id":"6394700dfd39838f","type":"api-current-state","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"climate.bedroom_aircon","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"(\t    $att:=$entity().attributes;\t    $diff:=$att.temperature-$att.current_temperature;\t    ($diff>0 ? \"Heating\" : \"Cooling\") & \" by \" & $abs($diff) & \" degrees required\"\t)","valueType":"jsonata"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":430,"y":580,"wires":[["852c05cf8c7cae73"]]},{"id":"8388eb36d3e25254","type":"inject","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":580,"wires":[["6394700dfd39838f"]]},{"id":"852c05cf8c7cae73","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Output Text","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":770,"y":580,"wires":[]},{"id":"a3e69091339a457c","type":"comment","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"2a - JSONata builds output in current state node","info":"","x":240,"y":540,"wires":[]},{"id":"11fc322e343cbd9c","type":"api-current-state","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"","server":"","version":3,"outputs":2,"halt_if":"$entities('sensor.time').state < \"17:00\" ? \"cool\" : \"off\"","halt_if_type":"jsonata","halt_if_compare":"is","entity_id":"climate.bedroom_aircon","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"}],"for":"$entity().state = \"off\" ? 0 : 2","forType":"jsonata","forUnits":"hours","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":430,"y":700,"wires":[["63fa3b7423417fe4"],["a29810da49f1efd4"]]},{"id":"6ac52ef3e9010615","type":"inject","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":700,"wires":[["11fc322e343cbd9c"]]},{"id":"63fa3b7423417fe4","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Cooling for 2+ hours before 17:00, or Off","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":840,"y":680,"wires":[]},{"id":"a29810da49f1efd4","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"otherwise","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":700,"y":740,"wires":[]},{"id":"4f8197db85d55fb5","type":"comment","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"2b - JSONata builds conditional test value, and UI parameter","info":"","x":280,"y":660,"wires":[]},{"id":"fd6d41b2f67b85e0","type":"comment","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"2c - JSONata builds conditional Boolean","info":"","x":220,"y":780,"wires":[]},{"id":"36912490ae36c0db","type":"api-current-state","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"","server":"","version":3,"outputs":2,"halt_if":"(\t    $state:=$entity().state;\t    $time:=$entities('sensor.time').state;\t    ($time<=\"09:00\" or $time>=\"17:00\") and ($state=\"heat\" or $state=\"cool\")\t)","halt_if_type":"jsonata","halt_if_compare":"jsonata","entity_id":"climate.bedroom_aircon","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entity"}],"for":"$substringAfter($now(),\"T\")>\"10:00\" ? 20 : 10","forType":"jsonata","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":430,"y":820,"wires":[["6244f42dd53b7e1f"],["bc6cd64ba0266d97"]]},{"id":"f84772ea62e6e7ba","type":"inject","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":820,"wires":[["36912490ae36c0db"]]},{"id":"6244f42dd53b7e1f","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"On outside of office hours","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload.state","targetType":"msg","statusVal":"payload.state","statusType":"auto","x":850,"y":800,"wires":[]},{"id":"bc6cd64ba0266d97","type":"debug","z":"776c027950fc8c3f","g":"d0f1fad3bf96a090","name":"otherwise","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload.state","targetType":"msg","statusVal":"payload.state","statusType":"auto","x":680,"y":840,"wires":[]}]
    +

    Creating output properties

    Example: Report the difference between room temperature and target temperature for an air-conditioning unit.

    In the first example we are looking to retrieve the current state and attributes from an air-conditioning unit, and output a text message describing the difference between current and target temperature. The A/C unit current temperature (read only) and the A/C unit target temperature (can be set with a service call) are located in the entity attributes. These are both numbers, so it is very easy to calculate the difference.

    Note: The default value msg.data is set only for the output message, and therefore msg.data.state would be used to obtain the entity state in nodes further along the flow, but $entity().state is used to obtain the entity state in JSONata expressions inside the node. When using JSONata to build an output message property, there is no requirement to retain the default output property settings for msg.data unless this is specifically required later in the flow.

    (
    +    $att:=$entity().attributes;
    +    $diff:=$att.temperature-$att.current_temperature;
    +    ($diff>0 ? "Heating" : "Cooling") & " by " & $abs($diff) & " degrees required"
    +)
    +

    Providing a conditional test value (JSONata expression as a value)

    Example: Output only where the A/C unit has been cooling for two hours and the local time is before 17:00, or when the unit is off.

    The Current State node provides for a state value test opportunity, which if set can be used to direct the message output one of two ways, depending whether the entity state passes or fails the test. When the If State option is chosen with a conditional (not JSONata) the condition expects a value to test against. In this example, using JSONata on the right hand side will return the value of the evaluated expression ("cool" before 17:00 and "off" otherwise) to be tested against the current state value and using the chosen conditional operator.

    screenshot

    $entities('sensor.time').state < "17:00" ? "cool" : "off"
    +

    Generating UI field setting values

    The Current State node also allows for a For, or duration of state test, and here JSONata is again being used to return either '0' when the state is "off" or '2' (hours) when the state is not "off". This complex arrangement will together test for the A/C unit being either immediately off after 17:00, or in cooling mode for at least two hours before 17:00.

    $entity().state = "off" ? 0 : 2
    +

    Note that here the use of $entity().state returns the current state of the node's subject entity, and that $entities('sensor.time').state returns the state of another specified entity. The Time & Date Integrationopen in new window should be added to the configuration file, and then the time sensor will return the current local time. This is useful for local-time condition testing, whereas the time_utc sensor will return UTC-time which is more useful with Home Assistant timestamps.

    Conditional test (JSONata expression as a Boolean result)

    Example: Report the air-conditioning unit being on outside of office hours.

    When the If State option is chosen with JSONata (not a conditional) then the right hand side must be a JSONata expression that returns a Boolean value of either true or false. When true the If State test is successful (the message is output from the top exit) when false the test fails (the message is output from the lower exit).

    screenshot

    In this example the JSONata expression is a code block, obtaining the node subject entity state and separate entity local time as in the previous example, but now combining both into one predicate expression. If the local time is outside 09:00 to 17:00 and the state is either heat or cool, then the expression will return true.

    (
    +    $state:=$entity().state;
    +    $time:=$entities('sensor.time').state;
    +    ($time<="09:00" or $time>="17:00") and ($state="heat" or $state="cool")
    +)
    +

    JSONata used at this point can be extensive, with a combination of entity states or attributes and Boolean logic as required. The use of OR to combine various states can only be more easily achieved in this way.

    Also see:

    + + + diff --git a/cookbook/jsonata/events-state.html b/cookbook/jsonata/events-state.html new file mode 100644 index 0000000000..5064935c85 --- /dev/null +++ b/cookbook/jsonata/events-state.html @@ -0,0 +1,83 @@ + + + + + + + + + Events: state | node-red-contrib-home-assistant-websocket + + + + + +

    Events: state

    The Events: state node receives state change events for one or more entities, and will output a message in response. The message output can be optionally controlled by a test condition on the state value, and also by a test on the length of time the state remains at that value. Both the state test condition and the state time duration can use JSONata. This node can also provide output message properties, again with the ability to use JSONata.

    screenshot

    Here are three examples, showing how to use JSONata to perform If-State conditional tests, and to build output properties.

    [{"id":"35b892e153bb5bc0","type":"group","z":"776c027950fc8c3f","name":"Events: state node - respond to state changes","style":{"label":true,"color":"#000000"},"nodes":["445466367c412014","e27b6ee2807af2eb","4583560d5089575d","24ed76ccd4da5975","266eadf86abd6481","27857c0c670e452b","e2ba71699db68b1a","1d9b8adce4f77e4e","a9b23a3911f5ef89"],"x":34,"y":919,"w":592,"h":342},{"id":"445466367c412014","type":"comment","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"3a - JSONata builds conditional test value","info":"","x":220,"y":960,"wires":[]},{"id":"e27b6ee2807af2eb","type":"server-state-changed","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Switch was on for less than 3 minutes","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"switch\\.[a-z][0-9]","entityIdType":"regex","outputInitially":false,"stateType":"str","ifState":"(\t    $new:=$entity();\t    $old:=$prevEntity();\t    $mins:=($toMillis($new.last_changed)-$toMillis($old.last_changed))/60000~>$round(0);\t    $new.state=\"off\" and $old.state=\"on\" and $mins<3\t)","ifStateType":"jsonata","ifStateOperator":"jsonata","outputOnlyOnStateChange":false,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"\"Device \" & $entity().attributes.friendly_name & \" has been on for less than 3 minutes\"","valueType":"jsonata"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":230,"y":1140,"wires":[["4583560d5089575d"],[]]},{"id":"4583560d5089575d","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Flow trigger","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"topic","targetType":"msg","statusVal":"payload","statusType":"auto","x":490,"y":1140,"wires":[]},{"id":"24ed76ccd4da5975","type":"server-state-changed","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Motion between dawn and dusk","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"motion","entityIdType":"substring","outputInitially":false,"stateType":"str","ifState":"(\t    $ismotion:= $entity().state=\"on\";\t\t    $dawn:=$entities('sensor.sun_next_dawn').state;\t    $dusk:=$entities('sensor.sun_next_dusk').state;\t    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(\",\");\t\t    $isdawn:= $date=$substringBefore($dawn,\"T\");\t    $isdusk:= $date!=$substringBefore($dusk,\"T\");\t    \t    $ismotion and ($isdawn or $isdusk)\t)","ifStateType":"jsonata","ifStateOperator":"jsonata","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"(\t    $ismotion:= $entity().state=\"on\";\t\t    $dawn:=$entities('sensor.sun_next_dawn').state;\t    $dusk:=$entities('sensor.sun_next_dusk').state;\t    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(\",\");\t\t    $isdawn:= $date=$substringBefore($dawn,\"T\");\t    $isdusk:= $date!=$substringBefore($dusk,\"T\");\t    \t    $fire:= $ismotion and ($isdawn or $isdusk);\t\t    {\"motion\": $ismotion,\t    \"dawn\": $dawn,\t    \"dusk\": $dusk,\t    \"date\": $date,\t    \"isdawn\": $isdawn,\t    \"isdusk\": $isdusk,\t    \"fire\": $fire\t    }\t)","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":210,"y":1220,"wires":[["266eadf86abd6481"],[]]},{"id":"266eadf86abd6481","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Dawn or Dusk","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload.isdawn ? \"Before Dawn\" : payload.isdusk ? \"After Dusk\"","statusType":"jsonata","x":500,"y":1220,"wires":[]},{"id":"27857c0c670e452b","type":"server-state-changed","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"","server":"","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"motion","entityIdType":"substring","outputInitially":false,"stateType":"str","ifState":"(\t    $time:=$entities('sensor.time').state;\t    $append([\"on\"], $time<\"08:30\" or $time>\"17:30\" ? [\"off\"]);\t)    ","ifStateType":"jsonata","ifStateOperator":"includes","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":240,"y":1020,"wires":[["1d9b8adce4f77e4e"],["e2ba71699db68b1a"]]},{"id":"e2ba71699db68b1a","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Condition false","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":500,"y":1040,"wires":[]},{"id":"1d9b8adce4f77e4e","type":"debug","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"Condition true","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload=\"on\" ? \"Motion at \" & $now('[H]:[m]') : \"end\"","statusType":"jsonata","x":500,"y":980,"wires":[]},{"id":"a9b23a3911f5ef89","type":"comment","z":"776c027950fc8c3f","g":"35b892e153bb5bc0","name":"3b - JSONata builds conditional Boolean","info":"","x":220,"y":1100,"wires":[]}]
    +

    Providing a conditional test value (JSONata expression as a value)

    Example: Respond to motion events for both "on" (start of motion detection) all day, and also "off" (end of motion detection) but only outside of 08:30 to 17:30.

    (
    +    $time:=$entities('sensor.time').state;
    +    $append(["on"], $time<"08:30" or $time>"17:30" ? ["off"]);
    +)
    +

    When the If State option is chosen with a conditional (not JSONata) the condition expects a value to test against. The result of the JSONata expression is the final line in the code block. This creates an array containing just ["on"] or if the time is before 08:30 or after 17:30, an array of ["on", "off"]. The motion sensor entity state will be compared with this array value using the inclusive condition 'in'.

    screenshot

    This JSONata uses the Date-Time integration sensor to obtain the local time. The Time & Date Integrationopen in new window should be added to the configuration file, and then the time sensor will return the current local time.

    Conditional test (JSONata expression as a Boolean result)

    Example: Switch has just been turned off, and was previously on for less than three minutes.

    When the If State option is chosen with JSONata (not a conditional) then the right hand side must be a JSONata expression that returns a Boolean value of either true or false. When true the "If State" test is successful (the message is output from the top exit) when false the test fails (the message is output from the lower exit).

    screenshot

    (
    +    $new:=$entity();
    +    $old:=$prevEntity();
    +    $mins:=($toMillis($new.last_changed)-$toMillis($old.last_changed))/60000~>$round(0);
    +    $new.state="off" and $old.state="on" and $mins<3
    +)
    +
    +

    In all the WebSocket nodes, the $entity() function will return an object for the entity that is the subject of the node. For the Event: nodes, the $entity() return is for the current or new state, and an additional $prevEntity() function will return a similar object for the previous state. Use of both functions allows JSONata expressions to work with and compare the triggering state change.

    Example: Motion has been detected before dawn or after dusk.

    Here JSONata is again used to generate a Boolean result for the If State test. The expression return is the final line in the code block, which tests for motion and either before dawn or after dusk. The use of 'or' here is an example of how JSONata can extend logic testing since the Trigger state node conditions can only group conditions as AND logic.

    (
    +    $ismotion:= $entity().state="on";
    +
    +    $dawn:=$entities('sensor.sun_next_dawn').state;
    +    $dusk:=$entities('sensor.sun_next_dusk').state;
    +    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(",");
    +
    +    $isdawn:= $date=$substringBefore($dawn,"T");
    +    $isdusk:= $date!=$substringBefore($dusk,"T");
    +
    +    $ismotion and ($isdawn or $isdusk)
    +)
    +

    The Sun integration in Home Assistant provides 'nextdawn' and 'next_dusk' sensors, with a date-time string value in UTC. Since the _next dawn will be for today before dawn, but will be for tomorrow after dawn, and similarly the next dusk will be for today before dusk, but for tomorrow after dusk, it is possible to compare just the date parts of the UTC timestamps, so as to determine if the current time is before or after either dawn or dusk.

    Creating output properties

    To extend this last example, JSONata is used to generate an output object. Note that there is no internal connection between the two JSONata expressions, so all the values have to be recalculated as required.

    (
    +    $ismotion:= $entity().state="on";
    +
    +    $dawn:=$entities('sensor.sun_next_dawn').state;
    +    $dusk:=$entities('sensor.sun_next_dusk').state;
    +    $date:=$entities('sensor.date_time_utc').state~>$substringBefore(",");
    +
    +    $isdawn:= $date=$substringBefore($dawn,"T");
    +    $isdusk:= $date!=$substringBefore($dusk,"T");
    +
    +    $fire:= $ismotion and ($isdawn or $isdusk);
    +
    +    {"motion": $ismotion,
    +    "dawn": $dawn,
    +    "dusk": $dusk,
    +    "date": $date,
    +    "isdawn": $isdawn,
    +    "isdusk": $isdusk,
    +    "fire": $fire
    +    }
    +)
    +
    +

    OR conditional for the Events: state node

    The Trigger: state node is great if you have several conditions you want to check for but it doesn't allow use of OR conditions. Using a JSONata expression with an Event: state node will allow you to fill this gap.

    Example: Motion sensor at the front door triggers, and have a text to speech notification be sent if at least one person is home.

    $entity().state = "on" and (
    +   $entities("person.person1").state = "home" or $entities("person.person2").state = "home"
    +)
    +

    Also see:

    + + + diff --git a/cookbook/jsonata/functions.html b/cookbook/jsonata/functions.html new file mode 100644 index 0000000000..ec6c07a4a1 --- /dev/null +++ b/cookbook/jsonata/functions.html @@ -0,0 +1,41 @@ + + + + + + + + + Other functions | node-red-contrib-home-assistant-websocket + + + + + +

    Other functions

    Several additional JSONata functions are provided for use within the WebSocket nodes. JSONata expressions are first 'prepared' then 'executed', and the preparation first stage is used to bind the expression to extra Node-RED or other functions. This means that these WebSocket functions can only be used within a WebSocket node.

    screenshot

    This example demonstrates the basic use of some of these functions.

    [{"id":"c3f7b442994c1a29","type":"group","z":"776c027950fc8c3f","name":"Using WebSocket functions to return entity, device, and area details","style":{"label":true,"color":"#000000"},"nodes":["578b1fe6b17d9053","9e2cc6208465cb53","24a0721c11a9dabf","0e27f1810d1f2726","25aa9320ec1b341f","87097a630683a0f3","2b079469d339ee68","6d7320ce7cf2d71b","4cf613030bdac458","4bba7af21fb76af8","80af7504e9450dd4"],"x":34,"y":2699,"w":732,"h":322},{"id":"578b1fe6b17d9053","type":"inject","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":2820,"wires":[["9e2cc6208465cb53"]]},{"id":"9e2cc6208465cb53","type":"ha-get-entities","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Entities with an attribute called \"array\"","server":"","version":1,"rules":[{"property":"","logic":"jsonata","value":"$entity().attributes.array!=[]","valueType":"jsonata"}],"outputType":"array","outputEmptyResults":true,"outputLocationType":"msg","outputLocation":"payload","outputResultsCount":1,"x":410,"y":2820,"wires":[["6d7320ce7cf2d71b"]]},{"id":"24a0721c11a9dabf","type":"api-current-state","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Entity attributes called \"array\"","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.date_time","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"$entities().*.attributes[$exists(array)]","valueType":"jsonata"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":380,"y":2900,"wires":[["4cf613030bdac458"]]},{"id":"0e27f1810d1f2726","type":"api-current-state","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Get Areas with Device and Entity Counts","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.time","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"$areas()^(name).{name: \" Devices: \" & $count($areaDevices(area_id)) & \" Entities: \" & $count($areaEntities(area_id))}~>$merge()","valueType":"jsonata"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":420,"y":2980,"wires":[["87097a630683a0f3"]]},{"id":"25aa9320ec1b341f","type":"inject","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":2980,"wires":[["0e27f1810d1f2726"]]},{"id":"87097a630683a0f3","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2980,"wires":[]},{"id":"2b079469d339ee68","type":"inject","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Manual trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":2900,"wires":[["24a0721c11a9dabf"]]},{"id":"6d7320ce7cf2d71b","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2820,"wires":[]},{"id":"4cf613030bdac458","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2900,"wires":[]},{"id":"4bba7af21fb76af8","type":"server-state-changed","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Using $entity() and $prevEntity()","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"sensor.time","entityIdType":"exact","outputInitially":false,"stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{\"old\": $prevEntity(), \"new\": $entity()}","valueType":"jsonata"}],"x":390,"y":2740,"wires":[["80af7504e9450dd4"]]},{"id":"80af7504e9450dd4","type":"debug","z":"776c027950fc8c3f","g":"c3f7b442994c1a29","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":2740,"wires":[]}]
    +

    Reading entity state and entity attributes with $entity() and $prevEntity()

    In nodes with output properties, a number of properties are typically set by default, or can be optionally set as:

    • msg.payload = 'entity state'
    • msg.data = 'entity'
    • msg.event = 'event data'
    • msg.topic = 'entity id'

    This provides useful message values in the flow following the node, however these values can be obtained within the node itself using the appropriate functions.

    The function $entity() returns an object containing the entity details, relating to the entity that is the subject of the node. This means that the output property selection options are equivalent to JSONata expressions:

    • 'entity' ~ $entity()
    • 'entity state' ~ $entity().state
    • 'entity id' ~ $entity().entity_id

    For the Events: nodes (Events: all and Events: state) the node triggers from an entity-change event, with $entity() returning the current (new) entity details, and the function $prevEntity() returning the previous (old) entity details.

    {"old": $prevEntity(), "new": $entity()}
    +

    The first example uses an Events: state node, with a basic sensor.time entity to facilitate triggering the node every minute. The Time & Date Integrationopen in new window should be added to the configuration file, and then the given time sensor will return the current local time. The entity state (as time) is "hh:mm" and therefore changes every 60 seconds.

    The output msg.payload is set to a new JSONata expression, which creates a new object with the old and new entity details, just as the output property 'event data' would do, but permitting a more detailed JSONata expression to be executed if required.

    Using $entities() to return one or all entities

    The next two examples explore ways to obtain specific entities, and this code looks for all Home Assistant entities that have an attribute field called 'array'.

    $entity().attributes.array!=[]
    +

    In the first flow, a Get Entities node is used, with a JSONata expression used to filter the result, based on each entity having an attribute field called 'array' that is a non-empty JSON array. This will return the entire entity, and therefore the output will be an array of entities that have an 'attribute.array' field.

    $entities().*.attributes[$exists(array)]
    +

    In the second flow, a Current State node is used, with a valid subject entity. The return from the given entity itself is not required - the node is just being used as a vehicle in which to execute the $entities() function. When specifying a named entity such as $entities('sun.next_dawn') only that entity will be returned, otherwise an array of all entities in Home Assistant will be returned. This JSONata expression then matches all entities in the array, filtering out attributes fields where the object key 'array' exists.

    In contrast to the preceding flow, this will return just an array of the entity attributes. The JSONata code in this case can also be executed as and when required.

    Note: Where a number of entity state values or attributes are required at one point in a flow for collective processing, using JSONata in a Current State node can be highly effective. The alternatives are:

    • Several Current State nodes chained in sequence, with each writing the state or entity data to a different msg.field.
    • One Current State node executing a JSONata expression, collating various $entity() or $entities('sensor.name') functions to either place values into one object, or to perform the necessary computation at that point. Output from JSONata can be either a simple primitive, or an object with several fields.

    Using $areas(), $areaDevices and $areaEntities()

    Finally, a more complex JSONata expression that returns details about areas, devices, and entities.

    $areas()^(name).{
    +    name: " Devices: " & $count($areaDevices(area_id)) & " Entities: " & $count($areaEntities(area_id))
    +    } ~> $merge()
    +

    The JSONata above is just one long expression line (unnecessary new lines have been added just to make the expression easier to read). Evaluated left to right, it starts with the $areas() function:

    • Without a given area lookup value, this function returns an array of all areas in Home Assistant
      • which is then sorted alphabetically, by name
    • The result is an array, which is mapped (iterated over)
    • applying an {} object constructor for each array item
      • the object creates one key: value pair
      • the key is the area 'name' (this is a string)
      • the value is a constructed text string
    • The function $areaDevices(area_id) returns all devices in each area
      • using 'area_id' for the item area, and returning an array of devices
      • using $count() to count the number of devices in the returned array
    • The function $areaEntities(area_id) returns all entities in that area
      • returning an array, which is similarly counted
    • The resulting array of objects is then merged into one single object

    Also see:

    + + + diff --git a/cookbook/jsonata/sensor.html b/cookbook/jsonata/sensor.html new file mode 100644 index 0000000000..c25008eb4b --- /dev/null +++ b/cookbook/jsonata/sensor.html @@ -0,0 +1,46 @@ + + + + + + + + + Sensor | node-red-contrib-home-assistant-websocket + + + + + +

    Sensor

    Using the WebSocket nodes provides many ways to read events and entity states from Home Assistant into Node-RED. Sending data the other way requires the use of the Entity nodes.

    There are several, but they all work in much the same way, and this example will use the Sensor node to create an entity sensor in Home Asisstant, and then to update the sensor state value as well as add an attribute value.

    screenshot

    Here is an example, showing how to use JSONata to set state value, and attribute value settings for an entity-sensor node.

    [{"id":"c14460fdc14a24a0","type":"group","z":"1cc7d2e94a4815fe","name":"Sensor node - set state and attribute values","style":{"label":true,"color":"#000000"},"nodes":["ba71e67aa0d06f02","4c7a952705afe4a0","e06208fe5410cfb5","23dfef724e706db3","a6d8e76c9ca8af97","fbbda709b5a50be7"],"x":214,"y":219,"w":912,"h":222},{"id":"ba71e67aa0d06f02","type":"inject","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Manual Trigger","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":340,"y":260,"wires":[["4c7a952705afe4a0"]]},{"id":"4c7a952705afe4a0","type":"ha-sensor","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"How many lights are on","entityConfig":"02814df043c7111b","version":0,"state":"$entities().*[state = \"on\" and entity_id ~> /^light|^switch/] ~> $count()","stateType":"jsonata","attributes":[{"property":"lights_table","value":"$entities().*[state = \"on\" and entity_id ~> /^light|^switch/].{\"name\": attributes.friendly_name, \"lastChange\": last_changed}","valueType":"jsonata"},{"property":"time","value":"","valueType":"date"}],"inputOverride":"allow","outputProperties":[],"x":610,"y":260,"wires":[[]],"server":""},{"id":"e06208fe5410cfb5","type":"server-state-changed","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"","server":"","version":5,"outputs":1,"exposeAsEntityConfig":"","entityId":"sensor.lights_on_count","entityIdType":"exact","outputInitially":false,"stateType":"num","ifState":"","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"table","propertyType":"msg","value":"$entity().attributes.lights_table","valueType":"jsonata"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"changes","propertyType":"msg","value":"(\t    $old:=$prevEntity().attributes.lights_table;\t    $new:=$entity().attributes.lights_table;\t    {\"on\": $new[$not(name in $old.name)],\t    \"off\": $old[$not(name in $new.name)]}\t)","valueType":"jsonata"}],"x":630,"y":340,"wires":[["23dfef724e706db3","a6d8e76c9ca8af97","fbbda709b5a50be7"]]},{"id":"23dfef724e706db3","type":"debug","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Count of lights on","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":990,"y":280,"wires":[]},{"id":"a6d8e76c9ca8af97","type":"debug","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Array table","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"table","targetType":"msg","statusVal":"payload","statusType":"auto","x":970,"y":340,"wires":[]},{"id":"fbbda709b5a50be7","type":"debug","z":"1cc7d2e94a4815fe","g":"c14460fdc14a24a0","name":"Changes","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"changes","targetType":"msg","statusVal":"changes","statusType":"auto","x":960,"y":400,"wires":[]},{"id":"02814df043c7111b","type":"ha-entity-config","server":"","deviceConfig":"","name":"SC LS On Count","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"LS On Count"},{"property":"icon","value":""},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false}]
    +

    Setting the sensor state value

    Example: Provide a sensor with the count of lights that are on.

    Once a new entity has been registered with Home Assistant, the entity state value can be updated by passing a message with the new value. Commonly msg.payload is used, however it is possible to use a JSONata expression to generate the new state value.

    $entities().*[state = "on" and entity_id ~> /^light|^switch/] ~> $count()
    +

    Here the $entities() function is used to return all entities, and select those that have "light" or "switch" in the 'entity id', and have an "on" state. This will return an array of entities, which can be counted to obtain the total number of switches or lights that are on.

    Setting an attribute value

    Example: Provide a list of the lights that are on.

    The entity state value can only be a JSON primitive value, such as a number or string, and objects and arrays can only be passed using the entity attributes.

    $entities().*[state = "on" and entity_id ~> /^light|^switch/].{
    +    "name": attributes.friendly_name,
    +    "lastChange": last_changed}
    +

    The JSONata expression here first returns a similar array of lights and switches, but from this then builds an array of objects. Each object contains the friendly name and last changed timestamp for each light or switch. This array is set into an attribute value of the sensor entity.

    Responding to state changes using JSONata

    Example: Since I last looked, which lights have been turned on, or off?

    In addition to the node above, the example also includes an Event: state node which responds to state changes in the above sensor update.

    (
    +    $old:=$prevEntity().attributes.lights_table;
    +    $new:=$entity().attributes.lights_table;
    +    {"on": $new[$not(name in $old.name)],
    +     "off": $old[$not(name in $new.name)]
    +    }
    +)
    +

    In an Event node, the $entity() function returns the current or new entity details, and the $prevEntity() function the previous or old entity details. The JSONata here picks out the sensor attribute and compares the array of lights & switches from before and after the state change. From this, an object with an array list of lights or switches that have been turned on, and those turned off, is provided.

    Note: In this example the Sensor node is updated on demand. The state value of the associated Home Assistant entity, which is a count of the number of lights or switches that are on, will only be updated when the Sensor node is triggered. The Events: state node is responding to changes in the sensor node state value, which will only happen when the sensor node is updated, and not when a light or switch is turned on or off.

    Also see:

    + + + diff --git a/cookbook/jsonata/switch-node.html b/cookbook/jsonata/switch-node.html new file mode 100644 index 0000000000..88cf67e96b --- /dev/null +++ b/cookbook/jsonata/switch-node.html @@ -0,0 +1,38 @@ + + + + + + + + + Switch node | node-red-contrib-home-assistant-websocket + + + + + +

    Switch node

    The Switch node and the Change node are standard Node-RED nodes that provide conditional routing (selection) and data manipulation respectively for flow messages. Many of the WebSocket nodes, when using JSONata, can provide some output property data manipulation, and a few nodes also offer simple binary output message routing. However, much more can be achieved using JSONata in Switch and Change nodes in combination with the WebSocket nodes.

    screenshot

    This example shows how to use JSONata within the standard Switch node.

    [{"id":"fcb0d3b1b8ed3478","type":"group","z":"776c027950fc8c3f","name":"Switch node - selection routing based on entity details","style":{"label":true,"color":"#000000"},"nodes":["7f01d6eef386f743","84b7ac3a7e469780","60331de530222f6f","e253c6a934a17919","76bb91be0ae4c7b4","52713f1b7157f1f0"],"x":34,"y":2159,"w":852,"h":262},{"id":"7f01d6eef386f743","type":"poll-state","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"","server":"","version":3,"exposeAsEntityConfig":"","updateInterval":"10","updateIntervalType":"num","updateIntervalUnits":"seconds","outputInitially":false,"outputOnChanged":true,"entityId":"switch.t1","stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputs":1,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":150,"y":2240,"wires":[["84b7ac3a7e469780"]]},{"id":"84b7ac3a7e469780","type":"switch","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"","property":"$round(data.timeSinceChangedMs/60000,0)","propertyType":"jsonata","rules":[{"t":"btwn","v":"2","vt":"num","v2":"3","v2t":"num"},{"t":"gt","v":"data.state=\"on\" ? 4 : 1","vt":"jsonata"},{"t":"jsonata_exp","v":"data.timeSinceChangedMs < 60000","vt":"jsonata"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":350,"y":2240,"wires":[["60331de530222f6f"],["e253c6a934a17919"],["76bb91be0ae4c7b4"],["52713f1b7157f1f0"]]},{"id":"60331de530222f6f","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Last changed between 2 and 3 minutes ago","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":670,"y":2200,"wires":[]},{"id":"e253c6a934a17919","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"If on > 4 mins or if off > 1 mins","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":630,"y":2260,"wires":[]},{"id":"76bb91be0ae4c7b4","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Changed state < 1 minute ago","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":630,"y":2320,"wires":[]},{"id":"52713f1b7157f1f0","type":"debug","z":"776c027950fc8c3f","g":"fcb0d3b1b8ed3478","name":"Otherwise","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"\"Is \" & payload & \" for \" & $round(data.timeSinceChangedMs/60000, 0) & \" minutes\"","targetType":"jsonata","statusVal":"payload","statusType":"auto","x":560,"y":2380,"wires":[]}]
    +

    Using JSONata in switch routing

    A Poll State node has been set up to return the entity state of a light switch every 10 seconds. This will return the entity state ("on" or "off") as the msg.payload value. It will also return the fuller entity state details in msg.data, which includes the 'timeSinceChangedMs' field.

    JSONata for the routing property

    $round(data.timeSinceChangedMs/60000,0)
    +

    The routing rules will test against the given property. By default this would be the value held in msg.payload. Using a JSONata expression here allows for a computation on the time since changed field to convert this to minutes. Rounding is also being used, so 31 to 89 seconds would become 1 minute.

    Note that the JSONata expression has access to the full incoming message. The value required was output from the Poll State node within the output property msg.data field, and this has to be used here since the $entity() functions are not available outside of the WebSocket nodes.

    screenshot

    JSONata for the rule value

    1. In the first rule, the rule values to test against are given as literals.

    2. In the second rule, the rule test value is provided by a JSONata expression. This will return either 4, if the light state is "on", or 1 if the light state is "off".

    data.state="on" ? 4 : 1
    +

    Note that 'payload' contains the state value and could have been used rather than 'data.state'. Where the output of a WebSocket node is used later in the flow for routing or processing, care should be taken to generate the most appropriate output. For example, rather than generate the Property match value here, this JSONata expression could be used in the Poll State node to provide minutes since last changed in the output msg.payload directly.

    JSONata expression for the routing match

    1. In the third rule, the evaluation Property is not used. The test condition is the Boolean result of a JSONata expression. The routing path is taken only if the JSONata expression evaluates as true.
    data.timeSinceChangedMs < 60000
    +

    The example is simplistic, however it shows that any incoming message property can be used within the expression.

    Note that, since the $entities() function is not available in a Switch node, to obtain other entity values, JSONata can be used in the preceding Poll State node to generate an output property, for example by setting msg.time to $entities('sensor.time').state to provide 'time' as an available value for use in the Switch node.

    1. For completeness in these notes, a last rule of 'Otherwise' has been included, and the matching rules set to 'checking all rules'. This will mean that more than one of the first three rules may match at the same time, but that the last route is only taken when no other rule matches.

    JSONata expression in the Debug node

    The Debug nodes also contain JSONata as a further demonstration of how versatile and applicable this language can be.

    Also see:

    + + + diff --git a/cookbook/jsonata/trigger-state.html b/cookbook/jsonata/trigger-state.html new file mode 100644 index 0000000000..82adf0b776 --- /dev/null +++ b/cookbook/jsonata/trigger-state.html @@ -0,0 +1,79 @@ + + + + + + + + + Trigger: state | node-red-contrib-home-assistant-websocket + + + + + +

    Trigger: state

    The Trigger: state node is very similar to the Events: state node. It will trigger when a given entity state changes, but unlike the Events: state, the Trigger: state node has the opportunity to add conditions using UI fields to construct complex tests. This removes much of the need to manage conditional tests using JSONata.

    JSONata can be used in several places within this node. However real practical use is quite limited. Although the Trigger node has extensive conditional testing included as UI setting, it does not have access to the $entity() or $entities() function in the conditions. The example given here is rather simplistic and contrived to demonstrate that JSONata can be used, rather than focusing on a genuinue or realistic use-case.

    screenshot

    Example: Respond every five minutes during the hour before and hour after sunset.

    [{"id":"3a2face9747195a7","type":"group","z":"776c027950fc8c3f","name":"Trigger: state node - respond to state changes","style":{"label":true,"color":"#000000"},"nodes":["320b22abb5a9ea96","da88972398c7ed97","c2d9f44ffe436dcc","2144de490d4257d7","94ceadbce4b45cdf","79b056d9779ec8f1","360fe19e1e203539","247cbab5f584ea63","0509fc220ff7735e","8fc293f5015dd3d5"],"x":34,"y":1359,"w":872,"h":302},{"id":"320b22abb5a9ea96","type":"inject","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Testing","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\t   \"entity_id\": \"sensor.time_utc\",\t   \"old_state\": {\"state\": \"16:49\"},\t   \"new_state\": {\"state\": \"16:50\"}\t}","payloadType":"jsonata","x":130,"y":1400,"wires":[["da88972398c7ed97"]]},{"id":"da88972398c7ed97","type":"trigger-state","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Actions around sunset","server":"","version":4,"inputs":1,"outputs":3,"exposeAsEntityConfig":"","entityId":"sensor.time_utc","entityIdType":"exact","debugEnabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"includes","comparatorValueDatatype":"jsonata","comparatorValue":"(\t/* UTC sunrise & sunset to 5 mins, month average (London UK) */\t/* Jan-Dec, Feb-Nov, Mar-Oct, Apr-Sep, May-Aug, Jun-Jly      */\t    $times:=[[\"07:55\", \"16:20\"],\t             [\"07:15\", \"16:45\"],\t             [\"06:00\", \"17:35\"],\t             [\"05:15\", \"18:30\"],\t             [\"04:30\", \"19:30\"],\t             [\"04:05\", \"20:05\"]];\t\t/* get this month (Jan=0), lookup sun-times table, return sun rise-set for this month */\t    $mtable:=[0..11].$min([$, $abs($-11)]);\t    $mindex:=$now('[M]').$number()-1;\t\t/* get sunset and build array of condition test-times around this */\t    $sunset:=($times[$mtable[$mindex]])[1];\t    $h:=$number($substringBefore($sunset, \":\"));\t    $m:=$number($substringAfter($sunset, \":\"));\t\t/* for span period mins, generate array of times and select every nth */\t    $span:=60;\t    $nth:=5;\t\t    $t:=$h*60+$m-$span;\t    ([$t..$t+$span*2])#$i.(\t        $h:=$floor($/60);\t        $m:=$%60;\t        $i%$nth=0 ? $formatInteger($h,'99') & \":\" & $formatInteger($m, '99');\t    )\t)"}],"customOutputs":[{"messageType":"custom","messageValue":"(\t    $sunset:=$entities('sensor.sun_next_setting').state;\t    $togo:= ($toMillis($sunset)-$millis())/60000~>$floor();\t    $toset:= $togo < 180 ? $togo : $togo-1440;\t    $x:= $toset-25;\t    $pc:= $x<0 and $x>-55 ? $min([$abs($x)*2, 100]) : null;\t\t    {\"topic\": \"Minutes to Sunset\",\t     \"payload\": $toset,\t     \"time\": $entities('sensor.time').state,\t     \"sunset\": $sunset,\t     \"percent\": $pc\t    }\t)","messageValueType":"jsonata","comparatorPropertyType":"always","comparatorPropertyValue":"","comparatorType":"is","comparatorValue":"","comparatorValueDataType":"jsonata"}],"outputInitially":false,"stateType":"str","enableInput":true,"x":300,"y":1440,"wires":[["c2d9f44ffe436dcc"],[],["2144de490d4257d7","247cbab5f584ea63"]]},{"id":"c2d9f44ffe436dcc","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Every 5 mins around sunset","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":580,"y":1400,"wires":[]},{"id":"2144de490d4257d7","type":"switch","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Sunset Actions","property":"payload","propertyType":"msg","rules":[{"t":"btwn","v":"0","vt":"num","v2":"4","v2t":"num"},{"t":"btwn","v":"10","vt":"num","v2":"14","v2t":"num"},{"t":"btwn","v":"0","vt":"num","v2":"-30","v2t":"num"},{"t":"else"}],"checkall":"false","repair":false,"outputs":4,"x":540,"y":1480,"wires":[["94ceadbce4b45cdf"],["79b056d9779ec8f1"],["360fe19e1e203539"],[]]},{"id":"94ceadbce4b45cdf","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"At Sunset","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":780,"y":1440,"wires":[]},{"id":"79b056d9779ec8f1","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Just Before","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":790,"y":1500,"wires":[]},{"id":"360fe19e1e203539","type":"debug","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Just After","active":false,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":780,"y":1560,"wires":[]},{"id":"247cbab5f584ea63","type":"change","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Brightness 0-100% over 50 min","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t    \"domain\": \"homeassistant\",\t    \"service\": \"turn_on\",\t    \"target\": {\t        \"entity_id\": [\"light.front_door\", \"switch.hall_light\"]\t        },\t    \"data\": {\t        \"brightness_pct\": percent\t    }\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":1620,"wires":[["8fc293f5015dd3d5"]]},{"id":"0509fc220ff7735e","type":"api-call-service","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"","server":"","version":5,"debugenabled":false,"domain":"homeassistant","service":"turn_on","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":760,"y":1620,"wires":[[]]},{"id":"8fc293f5015dd3d5","type":"switch","z":"776c027950fc8c3f","g":"3a2face9747195a7","name":"Not null","property":"payload.data.brightness_pct","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","repair":false,"outputs":1,"x":540,"y":1620,"wires":[["0509fc220ff7735e"]]}]
    +

    Sunrise and sunset times are often critical to running automations, and Home Assistant has inbuilt entities that provide the next dawn, sunrise, dusk, and sunset times. In order to be able to respond to multiple events during the period both before and after sunset, it is necessary to trigger at a more regular interval, not just on the sun-events, and then to test for required times or periods before and after sunset.

    The Trigger: state node can be set to use the sensor.time_utc entity as the subject of the node. This sensor holds UTC time as "hh:mm", and will change every minute, thus triggering a state change at regular 60 second intervals. We can add conditions to test the time against an expected period around sunset, and to generate a customised output that includes given periods or times before or after sunset. Combined with a Switch node this permits multiple tests and multiple automation events to be actioned.

    Using JSONata to set a condition value

    Here JSONata is used to generate an array of times of interest. When the trigger entity state, UTC time "hh:mm", is included in the calculated array, the condition is met and a message will be output.

    Since JSONata does not have access to the $entities() function in this particular UI field, the code here is used to generate a period of interest based on hard-coded sunrise and sunset times according to the current month. This is not ideal, but does demonstrate how JSONata can be used to easily generate and manipulate various JSON structures.

    (
    +/* UTC sunrise & sunset to 5 mins, month average (London UK) */
    +/* Jan-Dec, Feb-Nov, Mar-Oct, Apr-Sep, May-Aug, Jun-Jly      */
    +    $times:=[["07:55", "16:20"],
    +             ["07:15", "16:45"],
    +             ["06:00", "17:35"],
    +             ["05:15", "18:30"],
    +             ["04:30", "19:30"],
    +             ["04:05", "20:05"]];
    +
    +/* get this month (Jan=0), lookup sun-times table, return sun rise-set for this month */
    +    $mtable:=[0..11].$min([$, $abs($-11)]);
    +    $mindex:=$now('[M]').$number()-1;
    +
    +/* get sunset and build array of condition test-times around this */
    +    $sunset:=($times[$mtable[$mindex]])[1];
    +    $h:=$number($substringBefore($sunset, ":"));
    +    $m:=$number($substringAfter($sunset, ":"));
    +
    +/* for span period mins, generate array of times and select every nth */
    +    $span:=60;
    +    $nth:=5;
    +
    +    $t:=$h*60+$m-$span;
    +    ([$t..$t+$span*2])#$i.(
    +        $h:=$floor($/60);
    +        $m:=$%60;
    +        $i%$nth=0 ? $formatInteger($h,'99') & ":" & $formatInteger($m, '99');
    +    )
    +)
    +

    This code uses the current month to lookup a given sunset time, and then to generate an array of times either side of expected sunset, using a given span in minutes, and then picking out every five minutes only.

    The figures provided are examples, based on UTC times (DST ignored) for location London, UK and estimate an average sunrise and sunset time for each calendar month. Since sun events can move by up to one hour from start to end of a month, a span of at least 30 minutes is required to successfully include events across the entire month.

    Using JSONata to create a custom message

    The output properties on successful trigger include a default message and a default payload, which includes the basic event details for the trigger entity. It is possible to set the output as a customised payload, which replaces msg.payload with specific output, or as a customised message, which replaces the entire message with a generated object.

    (
    +    $sunset:=$entities('sensor.sun_next_setting').state;
    +    $togo:= ($toMillis($sunset)-$millis())/60000~>$floor();
    +    $toset:= $togo < 180 ? $togo : $togo-1440;
    +    $x:= $toset-25;
    +    $pc:= $x<0 and $x>-55 ? $min([$abs($x)*2, 100]) : null;
    +
    +    {"topic": "Minutes to Sunset",
    +     "payload": $toset,
    +     "time": $entities('sensor.time').state,
    +     "sunset": $sunset,
    +     "percent": $pc
    +    }
    +)
    +

    The $entities() function is available in JSONata in the output properties UI field, which means that both current time and sunset time can be obtained and compared. This allows some simple JSONata code to generate a complete message object, including msg.topic and msg.payload with the exact minutes to the next sunset correctly calculated.

    For automation, all that is required is a following Switch node set to route on a message property, for example msg.payload as minutes to next sunset between 0 and 4 (based on a five minute trigger interval) so as to be able to run an automation just as sunset is about to take place (with a five minute discrimination).

    As a further example, the JSONata output calculates a percentage value going from 0 to 100 over the period 25 minutes before to 25 minutes after sunset, with the percentage value set to 'null' outside this time. The Change node following also uses JSONata to create the entire Service Call node input settings, to turn on a group of lights in an timed-incremental fashion.

    Also see:

    + + + diff --git a/cookbook/motion-triggered-light.html b/cookbook/motion-triggered-light.html new file mode 100644 index 0000000000..652736eb6f --- /dev/null +++ b/cookbook/motion-triggered-light.html @@ -0,0 +1,36 @@ + + + + + + + + + Motion Triggered Light | node-red-contrib-home-assistant-websocket + + + + + +

    Motion Triggered Light

    Example 1

    A motion sensor that always sends an on event when any motion is detected and continues sending an update on each detection. This example turns a light on when motion is detected and waits 5 minutes for no motion and turns off the light.

    screenshot

    [{"id":"20f6aead.8b5d52","type":"server-state-changed","z":"cf5fa59f.b4f528","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.motion","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":224,"y":1560,"wires":[["11c7e80d.388958"]]},{"id":"11c7e80d.388958","type":"trigger","z":"cf5fa59f.b4f528","name":"","op1":"{\"service\": \"turn_on\"}","op2":"{\"service\": \"turn_off\"}","op1type":"json","op2type":"json","duration":"5","extend":true,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":460,"y":1560,"wires":[["371465f9.46b39a"]]},{"id":"371465f9.46b39a","type":"api-call-service","z":"cf5fa59f.b4f528","name":"Kitchen Light","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.kitchen","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":652,"y":1560,"wires":[[]]}]
    +

    Example 2

    A motion sensor that only sends an on event once then an off event when motion is no longer detected.

    screenshot

    [{"id":"9e2a08f5.4634b8","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.motion","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":250,"y":1008,"wires":[["6a54b527.806bec"],["c066de8f.8a0e2"]]},{"id":"6a54b527.806bec","type":"api-call-service","z":"ffbd7f06.4a014","name":"Kitchen Light On","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.kitchen","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":666,"y":1008,"wires":[[]]},{"id":"c066de8f.8a0e2","type":"ha-wait-until","z":"ffbd7f06.4a014","name":"","outputs":2,"entityId":"sensor.motion","property":"state","comparator":"is","value":"on","valueType":"str","timeout":"5","timeoutUnits":"minutes","entityLocation":"","entityLocationType":"none","checkCurrentState":true,"blockInputOverrides":true,"x":476,"y":1056,"wires":[[],["28f00104.71e9de"]]},{"id":"28f00104.71e9de","type":"api-call-service","z":"ffbd7f06.4a014","name":"Kitchen Light Off","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.kitchen","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":656,"y":1056,"wires":[[]]}]
    +
    + + + diff --git a/cookbook/saving-and-restoring-states.html b/cookbook/saving-and-restoring-states.html new file mode 100644 index 0000000000..1c31c7f4b1 --- /dev/null +++ b/cookbook/saving-and-restoring-states.html @@ -0,0 +1,38 @@ + + + + + + + + + Saving and Restoring States | node-red-contrib-home-assistant-websocket + + + + + +

    Saving and Restoring States

    Using Home Assistant scene creation

    Home Assistant added the ability to create scenes on the fly. This has reduced the work needed to be done in Node-RED to be able to restore entities to a previous state.

    screenshot

    [{"id":"44c8f86e.a64488","type":"trigger-state","z":"ffbd7f06.4a014","name":"Front Door Opened","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"sensor.front_door","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"id":"nqs49205fvp","targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"open"},{"id":"b6o1iwadls4","targetType":"this_entity","targetValue":"","propertyType":"previous_state","propertyValue":"old_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"closed"}],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":202,"y":1056,"wires":[["af046290.fdf2b"],[]]},{"id":"af046290.fdf2b","type":"api-call-service","z":"ffbd7f06.4a014","name":"Snapshot Entities","version":1,"debugenabled":false,"service_domain":"scene","service":"create","entityId":"","data":"{\"scene_id\":\"before\",\"snapshot_entities\":[\"light.wled_master_bedroom_tv\"]}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":410,"y":1056,"wires":[["7af76536.dfa6cc"]]},{"id":"7af76536.dfa6cc","type":"api-call-service","z":"ffbd7f06.4a014","name":"Change entities","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.wled_master_bedroom_tv","data":"{\"rgb_color\":[255,0,0],\"brightness\":128}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":608,"y":1056,"wires":[["c6f24589.9beb48"]]},{"id":"c6f24589.9beb48","type":"delay","z":"ffbd7f06.4a014","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":780,"y":1056,"wires":[["f762690.97b1198"]]},{"id":"f762690.97b1198","type":"api-call-service","z":"ffbd7f06.4a014","name":"Restore Entities State","version":1,"debugenabled":false,"service_domain":"scene","service":"turn_on","entityId":"scene.before","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":964,"y":1056,"wires":[[]]}]
    +

    Here are several examples using the get-entities node to get the states of several entities and then how to restore the entity states.

    Using the get entities node

    screenshot

    [{"id":"953f4576.faa588","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get States","rules":[{"property":"entity_id","logic":"is","value":"^(light|switch|climate)\\.+","valueType":"re"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":294,"y":80,"wires":[["2dab5a86.e54686"]]},{"id":"821d957.d510168","type":"inject","z":"6cb9e978.bf4588","name":"Store states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":118,"y":80,"wires":[["953f4576.faa588"]]},{"id":"5bc878cb.d80f08","type":"comment","z":"6cb9e978.bf4588","name":"How I would do store states","info":"","x":152,"y":32,"wires":[]},{"id":"2dab5a86.e54686","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const entities = msg.payload.map((e) => {\n    const domain = e.entity_id.split('.')[0];\n    const payload = {};\n\n    switch(domain) {\n        case 'switch':\n        case 'light':\n            payload.domain = domain;\n            payload.service = `turn_${e.state}`;\n            payload.data = { entity_id: e.entity_id };    \n            break;\n        case 'climate':\n            payload.domain = 'climate';\n            payload.service = `set_temperature`;\n            payload.data = {\n                entity_id: e.entity_id,\n                temperature: e.attributes.temperature,\n                target_temp_low: e.attributes.min_temp,\n                target_temp_high: e.attributes.max_temp,\n                operation_mode: e.attributes.operation_mode\n            };\n            break;\n    }\n    return payload;\n});\n// Save the states\nflow.set('savedStates', entities);\n\n// create a blank message object with out new payload\nmsg = { payload: entities };\nreturn msg;","outputs":1,"noerr":0,"x":480,"y":80,"wires":[["ceaf42e4.e245d"]]},{"id":"ceaf42e4.e245d","type":"debug","z":"6cb9e978.bf4588","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":646,"y":80,"wires":[]}]
    +

    screenshot

    [{"id":"f14f56e1.4d9a28","type":"inject","z":"6cb9e978.bf4588","name":"Store states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":118,"y":256,"wires":[["3790fc30.12b354","18d6f55.537770b","94a3c52.9fa9738"]]},{"id":"18d6f55.537770b","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Switches","rules":[{"property":"entity_id","logic":"starts_with","value":"switch","valueType":"str"},{"property":"state","logic":"includes","value":"on,off","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":256,"wires":[["19e85c0e.f4d1d4"]]},{"id":"94a3c52.9fa9738","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Lights","rules":[{"property":"entity_id","logic":"starts_with","value":"light","valueType":"str"},{"property":"state","logic":"includes","value":"on,off","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":208,"wires":[["19e85c0e.f4d1d4"]]},{"id":"297ff244.47ca4e","type":"comment","z":"6cb9e978.bf4588","name":"Easier to follow version","info":"","x":132,"y":160,"wires":[]},{"id":"3790fc30.12b354","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Climate","rules":[{"property":"entity_id","logic":"starts_with","value":"climate","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":304,"wires":[["36705576.17a42a"]]},{"id":"19e85c0e.f4d1d4","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const payload = {};\npayload.domain = msg.payload.entity_id.split('.')[0];\npayload.service = `turn_${msg.payload.state}`;\npayload.data = { entity_id: msg.payload.entity_id };\n\n// create a blank message object with out new payload\nmsg = { payload: payload };\nreturn msg;","outputs":1,"noerr":0,"x":476,"y":256,"wires":[["2b7e0299.1ce7ae"]]},{"id":"36705576.17a42a","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const payloads = [];\nconst payload = {};\npayload.domain = 'climate';\npayload.service = `set_temperature`;\npayload.data = {\n    entity_id: msg.payload.entity_id,\n    temperature: msg.payload.attributes.temperature,\n    target_temp_low: msg.payload.attributes.min_temp,\n    target_temp_high: msg.payload.attributes.max_temp,\n    operation_mode: msg.payload.attributes.operation_mode\n};\n\n// create a blank message object with out new payload\nmsg = { payload: payload };\nreturn msg;","outputs":1,"noerr":0,"x":476,"y":304,"wires":[["2b7e0299.1ce7ae"]]},{"id":"e254a879.41d408","type":"comment","z":"6cb9e978.bf4588","name":"function nodes could be replaced with a change nodes","info":"","x":596,"y":208,"wires":[]},{"id":"2b7e0299.1ce7ae","type":"join","z":"6cb9e978.bf4588","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"5","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":654,"y":256,"wires":[["b3db19bf.61d8e8"]]},{"id":"472ff71c.c342c8","type":"debug","z":"6cb9e978.bf4588","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1026,"y":256,"wires":[]},{"id":"b3db19bf.61d8e8","type":"change","z":"6cb9e978.bf4588","name":"","rules":[{"t":"set","p":"savedStates","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":832,"y":256,"wires":[["472ff71c.c342c8"]]}]
    +

    screenshot

    [{"id":"ab90e938.1eff18","type":"inject","z":"3c84cc55.8f02f4","name":"Restore states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":294,"y":656,"wires":[["a5a0930.ed3ae7"]]},{"id":"a5a0930.ed3ae7","type":"change","z":"3c84cc55.8f02f4","name":"Get Saved States","rules":[{"t":"set","p":"payload","pt":"msg","to":"savedStates","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":656,"wires":[["6247c7cf.5cb858"]]},{"id":"8f420c5d.82373","type":"debug","z":"3c84cc55.8f02f4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":998,"y":656,"wires":[]},{"id":"6247c7cf.5cb858","type":"split","z":"3c84cc55.8f02f4","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":658,"y":656,"wires":[["719b7b39.cbf0e4"]]},{"id":"719b7b39.cbf0e4","type":"api-call-service","z":"3c84cc55.8f02f4","name":"Restore State","version":"1","debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":816,"y":656,"wires":[["8f420c5d.82373"]]}]
    +

    As you can see in the above examples the switch and light domains are just saving and restoring the state, on/off. But what if some users wanted to also save and restore the brightness level or not. The climate domain is saving and restoring more than just the state.

    Also see:

    + + + diff --git a/cookbook/starting-flow-after-home-assistant-restart.html b/cookbook/starting-flow-after-home-assistant-restart.html new file mode 100644 index 0000000000..3969f3f97b --- /dev/null +++ b/cookbook/starting-flow-after-home-assistant-restart.html @@ -0,0 +1,49 @@ + + + + + + + + + Starting a flow after a Home Assistant restart | node-red-contrib-home-assistant-websocket + + + + + +

    Starting a flow after a Home Assistant restart

    Use a Home Assistant automation to set an input boolean to on then from Node-RED check if that input boolean is on after a successful connection or at any time it changes to on.

    screenshot

    [{"id":"fb5296f3c4de2a23","type":"subflow","name":"Create HA Helpers","info":"","category":"HA Actions","in":[{"x":84,"y":96,"wires":[{"id":"fc18bdbb57e2fd63"}]}],"out":[],"env":[{"name":"serverName","type":"str","value":"Home Assistant","ui":{"label":{"en-US":"HA Server Name"},"type":"input","opts":{"types":["str"]}}},{"name":"helpers","type":"json","value":"[]","ui":{"label":{"en-US":"Helpers"},"type":"input","opts":{"types":["json"]}}}],"meta":{},"color":"#46B1EF","status":{"x":246,"y":48,"wires":[{"id":"ea6dc8ad6d9ece17","port":0}]}},{"id":"fc18bdbb57e2fd63","type":"function","z":"fb5296f3c4de2a23","name":"process helpers","func":"const serverName = toCamelCase(env.get('serverName'));\nconst haServer = global.get(\"homeassistant\")[serverName];\nif(!haServer) {\n    node.error(\"Invalid HA server name\");\n    return;\n}\nconst states = haServer.states;\nconst helpers = env.get(\"helpers\");\n\nhelpers.forEach(h => {\n    const entityId = `${h.type}.${h.id}`;\n    if(!states[entityId]) {\n        const {id, type, ...data} = h;\n        const apiData = {\n            entity: h,\n            payload: { \n                data \n            }\n        };\n        apiData.payload.data.type = `${type}/create`;\n    \n        node.send(apiData);\n        node.status({text: `Creating ${entityId}`});\n    }\n});\n\nnode.done();\n\nfunction toCamelCase(str) {\n    return str.replace(/(?:^\\w|[A-Z]|\\b\\w|\\s+)/g, (match, index) => {\n        if (+match === 0) return '';\n        return index === 0 ? match.toLowerCase() : match.toUpperCase();\n    });\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":224,"y":96,"wires":[["2b8e82c6d93d38e5"]]},{"id":"2b8e82c6d93d38e5","type":"ha-api","z":"fb5296f3c4de2a23","name":"create helper","server":"","version":1,"debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"","dataType":"json","responseType":"json","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"x":390,"y":96,"wires":[["767624d22ee0c819"]]},{"id":"372232586f5e138f","type":"ha-api","z":"fb5296f3c4de2a23","name":"rename helper entity id","server":"","version":1,"debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\t   \"type\":\"config/entity_registry/update\",\t   \"entity_id\": entity.type & \".\" & payload.id,\t   \"new_entity_id\": entity.type & \".\" & entity.id\t}","dataType":"jsonata","responseType":"json","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"x":788,"y":96,"wires":[[]]},{"id":"767624d22ee0c819","type":"switch","z":"fb5296f3c4de2a23","name":"need to rename?","property":"payload.id","propertyType":"msg","rules":[{"t":"neq","v":"entity.id","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":96,"wires":[["372232586f5e138f","815fe31e9d239e53"]]},{"id":"ea6dc8ad6d9ece17","type":"status","z":"fb5296f3c4de2a23","name":"","scope":["fc18bdbb57e2fd63","815fe31e9d239e53"],"x":124,"y":48,"wires":[[]]},{"id":"815fe31e9d239e53","type":"function","z":"fb5296f3c4de2a23","name":"rename status","func":"const oldEntityId = `${msg.entity.type}.${msg.payload.id}`;\nconst newEntityId = `${msg.entity.type}.${msg.entity.id}`;\n\nnode.status({text: `Renaming ${oldEntityId} to ${newEntityId}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":768,"y":144,"wires":[[]]},{"id":"4a91394f75614da1","type":"server-events","z":"8e0ea5b84a1a9a3a","name":"","server":"","version":1,"event_type":"home_assistant_client","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"}],"x":200,"y":320,"wires":[["95e9d47ed2be5007"]]},{"id":"95e9d47ed2be5007","type":"switch","z":"8e0ea5b84a1a9a3a","name":"running?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"running","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":412,"y":320,"wires":[["4b7a32290de02cf7"]]},{"id":"648dd9ac108befdc","type":"api-call-service","z":"8e0ea5b84a1a9a3a","name":"","server":"","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.home_assistant_restarted","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":808,"y":320,"wires":[["3754cbf709193071"]]},{"id":"4b7a32290de02cf7","type":"api-current-state","z":"8e0ea5b84a1a9a3a","name":"has restarted?","server":"","version":2,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.home_assistant_restarted","state_type":"str","blockInputOverrides":false,"outputProperties":[],"x":576,"y":320,"wires":[["648dd9ac108befdc"],[]]},{"id":"f89ae68a99bb4e65","type":"server-state-changed","z":"8e0ea5b84a1a9a3a","name":"restarted?","server":"","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.home_assistant_restarted","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[],"x":588,"y":368,"wires":[["648dd9ac108befdc"],[]]},{"id":"b5993f580d9eb5b8","type":"comment","z":"8e0ea5b84a1a9a3a","name":"Home Assistant Restarted","info":"","x":190,"y":224,"wires":[]},{"id":"3754cbf709193071","type":"link out","z":"8e0ea5b84a1a9a3a","name":"Home Assistant Restarted","links":["c67631f89e6451f4"],"x":1070,"y":320,"wires":[],"l":true},{"id":"c67631f89e6451f4","type":"link in","z":"8e0ea5b84a1a9a3a","name":"Home Assistant Restarted","links":["3754cbf709193071"],"x":190,"y":416,"wires":[["33ccbe3fca679b80"]],"l":true},{"id":"33ccbe3fca679b80","type":"debug","z":"8e0ea5b84a1a9a3a","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":412,"y":416,"wires":[]},{"id":"bcfea616e335904d","type":"inject","z":"8e0ea5b84a1a9a3a","name":"Click to create","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":166,"y":272,"wires":[["447721875af4431a","5a92fd8241edd308"]]},{"id":"447721875af4431a","type":"ha-api","z":"8e0ea5b84a1a9a3a","name":"HA automation","server":"","version":1,"debugenabled":false,"protocol":"http","method":"post","path":"/api/config/automation/config/nrrestartnotification","data":"{\t   \"alias\": \"Home Assistant Restart\",\t   \"description\": \"\",\t   \"trigger\": [\t       {\t           \"platform\": \"homeassistant\",\t           \"event\": \"start\"       \t       }    \t   ],\t   \"condition\": [],\t   \"action\": [\t       {\t           \"service\": \"input_boolean.turn_on\",\t           \"data\": {\t               \"entity_id\": \"input_boolean.home_assistant_restarted\"       \t            }\t       }    \t   ],\t   \"mode\": \"single\" \t}","dataType":"jsonata","responseType":"json","outputProperties":[],"x":432,"y":224,"wires":[[]]},{"id":"5a92fd8241edd308","type":"subflow:fb5296f3c4de2a23","z":"8e0ea5b84a1a9a3a","name":"","env":[{"name":"helpers","value":"[{\"id\":\"home_assistant_restarted\",\"type\":\"input_boolean\",\"name\":\"Home Assistant Restarted\",\"icon\":\"mdi:restart-alert\"}]","type":"json"}],"x":442,"y":272,"wires":[]}]
    +

    TIP

    The input boolean and automation can be created directly from Node-RED using the inject node found in the exported flow.

    Create an input boolean using the Helpers menu (Configuration -> Helpers)

    screenshot

    input_boolean:
    +  home_assistant_restarted:
    +    name: Home Assistant Restarted
    +

    Create the Home Assistant automation

    alias: Home Assistant Restart
    +description: ""
    +trigger:
    +  - platform: homeassistant
    +    event: start
    +condition: []
    +action:
    +  - service: input_boolean.turn_on
    +    data: {}
    +    entity_id: input_boolean.home_assistant_restarted
    +mode: single
    +
    + + + diff --git a/cookbook/sun-events.html b/cookbook/sun-events.html new file mode 100644 index 0000000000..7bcbafb06d --- /dev/null +++ b/cookbook/sun-events.html @@ -0,0 +1,37 @@ + + + + + + + + + Turn Light On/Off with Sunset/Sunrise | node-red-contrib-home-assistant-websocket + + + + + +

    Turn Light On/Off with Sunset/Sunrise

    Option 1

    screenshot

    [{"id":"b74ada49.d7e408","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sun.sun","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"above_horizon","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":244,"y":784,"wires":[["1f467cbb.0c3983"],["da5ff3e0.cbb2a"]]},{"id":"1f467cbb.0c3983","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":784,"wires":[[]]},{"id":"da5ff3e0.cbb2a","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":832,"wires":[[]]}]
    +

    Option 2

    screenshot

    [{"id":"74a64f80.d2302","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sun.sun","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"above_horizon","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":404,"y":832,"wires":[["ccb2f059.1d384"],["4a84490d.9930a8"]]},{"id":"ccb2f059.1d384","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":794,"y":832,"wires":[[]]},{"id":"4a84490d.9930a8","type":"change","z":"ffbd7f06.4a014","name":"turn on","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"service\": \"turn_on\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":604,"y":880,"wires":[["ccb2f059.1d384"]]}]
    +

    Option 3

    Required Nodes

    screenshot

    [{"id":"ccb2f059.1d384","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"{{payload}}","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":644,"y":832,"wires":[[]]},{"id":"1a6cb307.d3168d","type":"eztimer","z":"ffbd7f06.4a014","name":"","autoname":"sunset - sunrise","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onproperty":"payload","onvaluetype":"str","onvalue":"turn_on","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"1","offtimesun":"sunrise","offtimetod":"dusk","offduration":"00:01:00","offproperty":"payload","offvaluetype":"str","offvalue":"turn_off","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":288,"y":832,"wires":[["ccb2f059.1d384"]]}]
    +
    + + + diff --git a/cookbook/using-date-and-time-entities-to-trigger-flows.html b/cookbook/using-date-and-time-entities-to-trigger-flows.html new file mode 100644 index 0000000000..d8161d544e --- /dev/null +++ b/cookbook/using-date-and-time-entities-to-trigger-flows.html @@ -0,0 +1,41 @@ + + + + + + + + + Using Date and Time entities to trigger flows | node-red-contrib-home-assistant-websocket + + + + + +

    Using Date and Time entities to trigger flows

    There is now a time node that simplifies the example flows below into one node.

    Using the time node

    • Home Assistant Companion app next alarm sensor

      [{"id":"f8329c.6b39dd68","type":"ha-time","z":"93fe35bb.4fb688","name":"","server":"","version":0,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityId":"sensor.pixel_next_alarm","property":"state","offset":0,"offsetType":"num","offsetUnits":"minutes","randomOffset":false,"repeatDaily":false,"payload":"$entity().state","payloadType":"jsonata","debugenabled":true,"x":262,"y":864,"wires":[["513ebdd1.58be64"]]},{"id":"513ebdd1.58be64","type":"debug","z":"93fe35bb.4fb688","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":492,"y":864,"wires":[]}]
      +
    • Adding an offset and on/off switch by exposing the node the Home Assistant using the custom componentopen in new window.

      [{"id":"ff4c2fea.d7d15","type":"ha-time","z":"93fe35bb.4fb688","name":"","server":"","version":0,"exposeToHomeAssistant":true,"haConfig":[{"property":"name","value":"Enable next alarm"},{"property":"icon","value":""}],"entityId":"sensor.pixel_next_alarm","property":"state","offset":"$entities(\"input_number.offset\").state","offsetType":"jsonata","offsetUnits":"minutes","randomOffset":false,"repeatDaily":true,"payload":"$entity().state","payloadType":"jsonata","debugenabled":false,"x":216,"y":1184,"wires":[["fceff1c.3c74f1"]]},{"id":"fceff1c.3c74f1","type":"debug","z":"93fe35bb.4fb688","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":444,"y":1184,"wires":[]}]
      +
    • Daily alarm using Datetime Entity

      [{"id":"68a7a591.c05a1c","type":"ha-time","z":"93fe35bb.4fb688","name":"","server":"","version":0,"exposeToHomeAssistant":true,"haConfig":[{"property":"name","value":"Alarm enabled"},{"property":"icon","value":""}],"entityId":"input_datetime.alarm","property":"state","offset":0,"offsetType":"num","offsetUnits":"minutes","randomOffset":false,"repeatDaily":true,"payload":"$entity().state","payloadType":"jsonata","debugenabled":false,"x":238,"y":1488,"wires":[["96f4596a.01bed8"]]},{"id":"96f4596a.01bed8","type":"debug","z":"93fe35bb.4fb688","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":444,"y":1488,"wires":[]}]
      +

    Home Assistant Companion app next alarm sensor

    WARNING

    Home Assistant Companion app sets the entity's name based on its selected language. Eg. next_alarm must be changed in prossimo_allarme if the app is used in Italian (and vice versa)

    Here's a basic example of using the Home Assistant Companion app next alarm sensor.

    screenshot

    [{"id":"71576a68.4c7494","type":"server-state-changed","z":"56b1c979.b2c618","name":"Next Alarm","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.pixel_next_alarm","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"unavailable","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"x":236,"y":1456,"wires":[["17ff4332.e9872d"],["ffa8ad2e.133d4"]]},{"id":"ffa8ad2e.133d4","type":"change","z":"56b1c979.b2c618","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":386,"y":1504,"wires":[["664bcf1c.d25e8"]]},{"id":"17ff4332.e9872d","type":"function","z":"56b1c979.b2c618","name":"time difference","func":"const now = Date.now();\nconst alarm = new Date(msg.payload);\n\nconst timeDifference = alarm - now;\n\nmsg.delay = timeDifference;\n\n// Reset the delay node before setting the new delay\nreturn [[{reset: true},msg]];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":416,"y":1456,"wires":[["664bcf1c.d25e8"]]},{"id":"664bcf1c.d25e8","type":"delay","z":"56b1c979.b2c618","name":"wait until time","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":608,"y":1456,"wires":[["42742068.3eb4f"]]},{"id":"42742068.3eb4f","type":"debug","z":"56b1c979.b2c618","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":780,"y":1456,"wires":[]}]
    +

    Adding an offset and on/off switch

    Using the Helpers section under Configuration in Home Assistant add an input_boolean and input_number with a min of -90 and a max of 90.

    In this example they are input_number.offset and input_boolean.next_alarm_enabled. The offset will be plus or minus minutes to the alarm. The delay node will get updated when either the alarm sensor gets updated, the input boolean gets toggled, or the offset changes.

    If the Node-RED custom componentopen in new window is installed in Home Assistant there is no need for the input_boolean as the event state node can be exposed to Home Assistant as the toggle switch.

    screenshot

    [{"id":"8a005b30.a70028","type":"change","z":"56b1c979.b2c618","name":"reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":1616,"wires":[["7443b388.3997bc"]]},{"id":"7443b388.3997bc","type":"delay","z":"56b1c979.b2c618","name":"wait until time","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1008,"y":1568,"wires":[["944beed4.7ca6c"]]},{"id":"944beed4.7ca6c","type":"debug","z":"56b1c979.b2c618","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1180,"y":1568,"wires":[]},{"id":"902c18e0.b83f08","type":"api-current-state","z":"56b1c979.b2c618","name":"enabled?","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.next_alarm_enabled","state_type":"str","state_location":"","override_payload":"none","entity_location":"","override_data":"none","blockInputOverrides":false,"x":300,"y":1568,"wires":[["819e7961.c0c5b8"],["8a005b30.a70028"]]},{"id":"88557318.dcb9","type":"function","z":"56b1c979.b2c618","name":"add offset","func":"const now = Date.now();\nconst alarm = new Date(msg.alarm);\nconst offset = msg.offset * 60000;\nconst timeDifference = alarm.getTime() + offset;\nconst delay = timeDifference - now;\n\nif(delay < 0) {\n    node.status({fill: 'red', text: 'Alarm in the past'});\n    node.error(\"Alarm in the past.\");\n    return {reset: true};\n}\n\nnode.status({});\nmsg.delay = delay\n\n// Reset the delay node before setting the new delay\nreturn [[{reset: true},msg]];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":828,"y":1568,"wires":[["7443b388.3997bc"]]},{"id":"5f5d428e.e8ed8c","type":"api-current-state","z":"56b1c979.b2c618","name":"get offset","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_number.offset","state_type":"str","state_location":"offset","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":684,"y":1568,"wires":[["88557318.dcb9"]]},{"id":"6e621173.6634d","type":"server-state-changed","z":"56b1c979.b2c618","name":"Update Alarm","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_number.offset, input_boolean.next_alarm_enabled, sensor.pixel_next_alarm","entityidfiltertype":"substring","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"x":150,"y":1568,"wires":[["902c18e0.b83f08"]]},{"id":"819e7961.c0c5b8","type":"api-current-state","z":"56b1c979.b2c618","name":"get alarm time","version":1,"outputs":2,"halt_if":"unavailable","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"sensor.pixel_next_alarm","state_type":"str","state_location":"alarm","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":480,"y":1568,"wires":[["5f5d428e.e8ed8c"],["8a005b30.a70028"]]}]
    +

    WARNING

    Delay nodes can have a max timeout of around 24.8 days greater than that and weird things will happen.

    Managing alarm from multiple phones

    If more than one phone in the house has the app installed and you want it to be triggered from any of the alarms this is the way to go and it's working perfectly even with just one phone.

    It needs the same couple of helpers for each phone and the same consideration made above for the input_boolean is still valid.

    This flow was developed and tested with a Pixel 2 XL and the companion app in Italian so you'll have to change all the references to the phone and the entities.

    screenshot

    [{"id":"c68594981cf4df93","type":"server-state-changed","z":"e1f44cc40f36d3a0","name":"Update Alarm","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"_prossimo_allarme_offset, _prossimo_allarme_enabled, _prossimo_allarme","entityidfiltertype":"substring","outputinitially":true,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":130,"y":1000,"wires":[["bd2261de4c7422c2"]]},{"id":"bd2261de4c7422c2","type":"function","z":"e1f44cc40f36d3a0","name":"Save values","func":"const [, phone] = msg.topic.match(/\\.(.+)_prossimo_allarme/);\nconst key = `alarm['${phone}']`;\nconst fullKey = `alarm['${phone}']['${msg.topic}']`\nflow.set(fullKey, msg.payload);\nconst alarmPhone = flow.get(key);\nif (Object.keys(alarmPhone).length === 3) {\n    const alarmRaw = alarmPhone[`sensor.${phone}_prossimo_allarme`];\n    const enabled = alarmPhone[`input_boolean.${phone}_prossimo_allarme_enabled`] === 'on';\n    if ( enabled && alarmRaw !== \"unavailable\") {\n        const now = Date.now();\n        const alarm = new Date(alarmRaw);\n        const offset = alarmPhone[`input_number.${phone}_prossimo_allarme_offset`] * 60000;\n        const timeDifference = alarm.getTime() + offset;\n        const delay = timeDifference - now;\n\n        if (delay < 0) {\n            node.status({ fill: 'red', text: 'Offset put alarm in the past' });\n            node.warn(\"Offset put alarm in the past.\");\n            return { reset: true };\n        }\n\n        node.status({});\n        msg = {\n            topic: phone,\n            delay,\n            payload: alarm\n        };\n\n        // Reset the delay node before setting the new delay\n        return [[{ reset: true }, msg]];\n    } else {\n        return { reset: true };\n    }\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":1000,"wires":[["31a1b9a97061185e"]]},{"id":"31a1b9a97061185e","type":"delay","z":"e1f44cc40f36d3a0","name":"wait until time","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":520,"y":1000,"wires":[["35675e2e29e54de6"]]},{"id":"764b91777c83fd57","type":"debug","z":"e1f44cc40f36d3a0","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":320,"y":1080,"wires":[]},{"id":"35675e2e29e54de6","type":"switch","z":"e1f44cc40f36d3a0","name":"Phone","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"pixel_2_xl","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":690,"y":1000,"wires":[["b2992c1a93db3836"]]},{"id":"b2992c1a93db3836","type":"link out","z":"e1f44cc40f36d3a0","name":"Pixel 2 XL","mode":"link","links":["2a280002119b6339"],"x":795,"y":1000,"wires":[]},{"id":"2a280002119b6339","type":"link in","z":"e1f44cc40f36d3a0","name":"Alarm Pixel 2 XL","links":["b2992c1a93db3836"],"x":175,"y":1080,"wires":[["764b91777c83fd57"]]}]
    +

    Daily alarm using Datetime Entity

    screenshot

    [{"id":"2672831b.1236ac","type":"inject","z":"ffbd7f06.4a014","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":342,"y":1808,"wires":[["ef533324.d135d"]]},{"id":"8b6ea5bc.5f2478","type":"api-current-state","z":"ffbd7f06.4a014","name":"alarm","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_datetime.alarm","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"","override_data":"none","blockInputOverrides":false,"x":628,"y":1808,"wires":[["aedf33ed.0ca28"]]},{"id":"d3ec7afe.0c2968","type":"debug","z":"ffbd7f06.4a014","name":"do stuff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":1808,"wires":[]},{"id":"aedf33ed.0ca28","type":"function","z":"ffbd7f06.4a014","name":"now?","func":"const now = new Date();\nconst hours = now.getHours().toString().padStart(2,'0');\nconst minutes = now.getMinutes().toString().padStart(2,'0');\nconst time = `${hours}:${minutes}`;\n// Remove seconds\nconst alarm = msg.payload.split(\":\").splice(0,2).join(\":\");\n\nif(time === alarm) {\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":756,"y":1808,"wires":[["d3ec7afe.0c2968"]]},{"id":"ef533324.d135d","type":"api-current-state","z":"ffbd7f06.4a014","name":"enabled?","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.alarm_enabled","state_type":"str","state_location":"","override_payload":"none","entity_location":"","override_data":"none","blockInputOverrides":false,"x":492,"y":1808,"wires":[["8b6ea5bc.5f2478"],[]]}]
    +

    An offset can also be added as shown in the next alarm sensor example.

    + + + diff --git a/cookbook/vacation-mode.html b/cookbook/vacation-mode.html new file mode 100644 index 0000000000..d3f811e511 --- /dev/null +++ b/cookbook/vacation-mode.html @@ -0,0 +1,49 @@ + + + + + + + + + Vacation Mode | node-red-contrib-home-assistant-websocket + + + + + +

    Vacation Mode

    Four steps to adding a vacation mode to your home and having lights turn on and off at random intervals. It also automatically prompts you with a notification about turning on vacation mode if you have been gone longer than 24 hours.

    screenshot

    Full Export

    [{"id":"eb756b3f.d770f8","type":"subflow","name":"Create HA Helpers","info":"","category":"","in":[{"x":84,"y":96,"wires":[{"id":"7f1493fc.1300fc"}]}],"out":[],"env":[{"name":"serverName","type":"str","value":"Home Assistant","ui":{"label":{"en-US":"HA Server Name"},"type":"input","opts":{"types":["str"]}}},{"name":"helpers","type":"json","value":"[]","ui":{"label":{"en-US":"Helpers"},"type":"input","opts":{"types":["json"]}}}],"color":"#DDAA99","status":{"x":246,"y":48,"wires":[{"id":"a66d5d93.8a5f","port":0}]}},{"id":"7f1493fc.1300fc","type":"function","z":"eb756b3f.d770f8","name":"process helpers","func":"const serverName = toCamelCase(env.get('serverName'));\nconst haServer = global.get(\"homeassistant\")[serverName];\nif(!haServer) {\n    node.error(\"Invalid HA server name\");\n    return;\n}\nconst states = haServer.states;\nconst helpers = env.get(\"helpers\");\n\nhelpers.forEach(h => {\n    const entityId = `${h.type}.${h.id}`;\n    if(!states[entityId]) {\n        const {id, type, ...data} = h;\n        const apiData = {\n            entity: h,\n            payload: { \n                data \n            }\n        };\n        apiData.payload.data.type = `${type}/create`;\n    \n        node.send(apiData);\n        node.status({text: `Creating ${entityId}`});\n    }\n});\n\nnode.done();\n\nfunction toCamelCase(str) {\n    return str.replace(/(?:^\\w|[A-Z]|\\b\\w|\\s+)/g, (match, index) => {\n        if (+match === 0) return '';\n        return index === 0 ? match.toLowerCase() : match.toUpperCase();\n    });\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":224,"y":96,"wires":[["a4a0abd9.7576d8"]]},{"id":"a4a0abd9.7576d8","type":"ha-api","z":"eb756b3f.d770f8","name":"create helper","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":390,"y":96,"wires":[["b76d0c56.d54b9"]]},{"id":"388bb5c7.47346a","type":"ha-api","z":"eb756b3f.d770f8","name":"rename helper entity id","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\t   \"type\":\"config/entity_registry/update\",\t   \"entity_id\": entity.type & \".\" & payload.id,\t   \"new_entity_id\": entity.type & \".\" & entity.id\t}","dataType":"jsonata","location":"payload","locationType":"msg","responseType":"json","x":788,"y":96,"wires":[[]]},{"id":"b76d0c56.d54b9","type":"switch","z":"eb756b3f.d770f8","name":"need to rename?","property":"payload.id","propertyType":"msg","rules":[{"t":"neq","v":"entity.id","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":96,"wires":[["388bb5c7.47346a","3e47440a.eee2cc"]]},{"id":"a66d5d93.8a5f","type":"status","z":"eb756b3f.d770f8","name":"","scope":["7f1493fc.1300fc","3e47440a.eee2cc"],"x":124,"y":48,"wires":[[]]},{"id":"3e47440a.eee2cc","type":"function","z":"eb756b3f.d770f8","name":"rename status","func":"const oldEntityId = `${msg.entity.type}.${msg.payload.id}`;\nconst newEntityId = `${msg.entity.type}.${msg.entity.id}`;\n\nnode.status({text: `Renaming ${oldEntityId} to ${newEntityId}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":768,"y":144,"wires":[[]]},{"id":"fda663f6.59a56","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"e9b697a.fc03268"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"57c0c58d.ffa1bc","port":0}]},{"x":1172,"y":176,"wires":[{"id":"57c0c58d.ffa1bc","port":1}]},{"x":1172,"y":224,"wires":[{"id":"57c0c58d.ffa1bc","port":2}]},{"x":964,"y":240,"wires":[{"id":"c3389099.bc489","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"d847d277.d448c","port":0}]}},{"id":"b4512e6b.640d9","type":"function","z":"fda663f6.59a56","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["7a427ca2.c030e4"]]},{"id":"57c0c58d.ffa1bc","type":"switch","z":"fda663f6.59a56","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"d847d277.d448c","type":"status","z":"fda663f6.59a56","name":"","scope":["b4512e6b.640d9","c3389099.bc489","7955d8e6.b10888","7a427ca2.c030e4"],"x":124,"y":272,"wires":[[]]},{"id":"c3389099.bc489","type":"function","z":"fda663f6.59a56","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["57c0c58d.ffa1bc"],[]]},{"id":"f814cdc6.def07","type":"switch","z":"fda663f6.59a56","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["4db9b8d.0c14a48"]]},{"id":"7596669d.feb668","type":"ha-api","z":"fda663f6.59a56","name":"get user info","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["c3389099.bc489"]]},{"id":"b745e475.d6cdf8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_cleared","server":"","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["f814cdc6.def07"]]},{"id":"4db9b8d.0c14a48","type":"switch","z":"fda663f6.59a56","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["7596669d.feb668"],["c3389099.bc489"]]},{"id":"e9b697a.fc03268","type":"switch","z":"fda663f6.59a56","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["b4512e6b.640d9"],["7955d8e6.b10888"]],"l":false},{"id":"7955d8e6.b10888","type":"function","z":"fda663f6.59a56","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["7a427ca2.c030e4"]]},{"id":"520a884c.35f9c8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_action","server":"","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["f814cdc6.def07"]]},{"id":"7a427ca2.c030e4","type":"api-call-service","z":"fda663f6.59a56","name":"","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"aa02fa4a.a35548","type":"inject","z":"9530fd91.600e2","name":"","repeat":"","crontab":"*/6 16-23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":118,"y":336,"wires":[["7e966ac8.609524"]]},{"id":"cfa1b8e4.8d4a08","type":"time-range-switch","z":"9530fd91.600e2","name":"","startTime":"sunset","endTime":"23:59","startOffset":0,"endOffset":0,"x":496,"y":336,"wires":[["c7efc558.da1bc8"],[]]},{"id":"a41f4d83.d45c4","type":"ha-get-entities","z":"9530fd91.600e2","server":"","name":"","rules":[{"property":"entity_id","logic":"in_group","value":"group.vacation_lights","valueType":"str"},{"property":"state","logic":"is","value":"off","valueType":"str"}],"output_type":"random","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":806,"y":336,"wires":[["f3897d20.fffee"]]},{"id":"c7efc558.da1bc8","type":"function","z":"9530fd91.600e2","name":"25%","func":"const random = Math.round(Math.random() * 100);\n\nif(random < 75) {\n    node.status({fill: \"red\", text: random});\n    return;\n}\n\nnode.status({fill: \"green\", text: random});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":658,"y":336,"wires":[["a41f4d83.d45c4"]]},{"id":"f3897d20.fffee","type":"api-call-service","z":"9530fd91.600e2","name":"turn on","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":956,"y":336,"wires":[["20fce293.98ce8e"]]},{"id":"20fce293.98ce8e","type":"delay","z":"9530fd91.600e2","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"5","randomLast":"36","randomUnits":"minutes","drop":false,"x":1100,"y":336,"wires":[["3d851328.fb1b8c"]]},{"id":"3d851328.fb1b8c","type":"api-call-service","z":"9530fd91.600e2","name":"turn off","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_off","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1234,"y":336,"wires":[[]]},{"id":"7e966ac8.609524","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":298,"y":336,"wires":[[],["cfa1b8e4.8d4a08"]]},{"id":"22f34ec4.9d3a22","type":"comment","z":"9530fd91.600e2","name":"Vacation Lights","info":"","x":112,"y":288,"wires":[]},{"id":"7003285c.a3a8c8","type":"api-call-service","z":"9530fd91.600e2","name":"turn on vacation mode","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":788,"y":192,"wires":[["4971bda0.0758f4"]]},{"id":"4971bda0.0758f4","type":"api-call-service","z":"9530fd91.600e2","name":"notify jason","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_jason","entityId":"","data":"{\"title\":\"Vacation Mode\",\"message\":\"Vacation Mode has been enabled.\"}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":982,"y":192,"wires":[[]]},{"id":"bf80cebf.58bcc","type":"server-state-changed","z":"9530fd91.600e2","name":"home/away","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"1","forType":"num","forUnits":"days","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":102,"y":192,"wires":[["7d414deb.904f64"],["c81cbf7d.abe22"]]},{"id":"c81cbf7d.abe22","type":"api-call-service","z":"9530fd91.600e2","name":"vacation mode off","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":314,"y":240,"wires":[[]]},{"id":"7d414deb.904f64","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":314,"y":192,"wires":[["dca703ed.f3222"],[]]},{"id":"dca703ed.f3222","type":"subflow:fda663f6.59a56","z":"9530fd91.600e2","name":"turn on vacation mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been aways for 24 hours. Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":542,"y":208,"wires":[["7003285c.a3a8c8"],[],[],[]]},{"id":"d4a03a04.6c78f8","type":"subflow:eb756b3f.d770f8","z":"9530fd91.600e2","name":"create input_boolean","env":[{"name":"helpers","value":"[{\"id\":\"vacation_mode\",\"type\":\"input_boolean\",\"name\":\"Vacation Mode\",\"icon\":\"mdi:beach\"}]","type":"json"}],"x":292,"y":96,"wires":[]},{"id":"f3d6f382.70bfe","type":"inject","z":"9530fd91.600e2","name":"Click me to","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":108,"y":96,"wires":[["d4a03a04.6c78f8"]]},{"id":"4a22094b.635368","type":"comment","z":"9530fd91.600e2","name":"Setup","info":"","x":82,"y":48,"wires":[]},{"id":"7ce57cf8.cad134","type":"comment","z":"9530fd91.600e2","name":"Actionable notification to turn on vacation mode","info":"","x":212,"y":144,"wires":[]}]
    +

    Step 1

    Create an input boolean in Home Assistant that will control if the house is in vacation mode.

    screenshot

    or via the helpers menu in the Home Assistant UI or add it manually in YAML

    input_boolean:
    +  vacation_mode:
    +    name: Vacation Mode
    +    icon: mdi:beach
    +

    Step 2

    Create a flow that will automatically change the vacation mode to off if we come home. Secondly will send our phone an actionable notification for android asking if we want to turn on vacation mode if we have been gone longer than 24 hours.

    screenshot

    [{"id":"fda663f6.59a56","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"e9b697a.fc03268"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"57c0c58d.ffa1bc","port":0}]},{"x":1172,"y":176,"wires":[{"id":"57c0c58d.ffa1bc","port":1}]},{"x":1172,"y":224,"wires":[{"id":"57c0c58d.ffa1bc","port":2}]},{"x":964,"y":240,"wires":[{"id":"c3389099.bc489","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"d847d277.d448c","port":0}]}},{"id":"b4512e6b.640d9","type":"function","z":"fda663f6.59a56","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["7a427ca2.c030e4"]]},{"id":"57c0c58d.ffa1bc","type":"switch","z":"fda663f6.59a56","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"d847d277.d448c","type":"status","z":"fda663f6.59a56","name":"","scope":["b4512e6b.640d9","c3389099.bc489","7955d8e6.b10888","7a427ca2.c030e4"],"x":124,"y":272,"wires":[[]]},{"id":"c3389099.bc489","type":"function","z":"fda663f6.59a56","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["57c0c58d.ffa1bc"],[]]},{"id":"f814cdc6.def07","type":"switch","z":"fda663f6.59a56","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["4db9b8d.0c14a48"]]},{"id":"7596669d.feb668","type":"ha-api","z":"fda663f6.59a56","name":"get user info","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["c3389099.bc489"]]},{"id":"b745e475.d6cdf8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_cleared","server":"","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["f814cdc6.def07"]]},{"id":"4db9b8d.0c14a48","type":"switch","z":"fda663f6.59a56","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["7596669d.feb668"],["c3389099.bc489"]]},{"id":"e9b697a.fc03268","type":"switch","z":"fda663f6.59a56","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["b4512e6b.640d9"],["7955d8e6.b10888"]],"l":false},{"id":"7955d8e6.b10888","type":"function","z":"fda663f6.59a56","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["7a427ca2.c030e4"]]},{"id":"520a884c.35f9c8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_action","server":"","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["f814cdc6.def07"]]},{"id":"7a427ca2.c030e4","type":"api-call-service","z":"fda663f6.59a56","name":"","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"7003285c.a3a8c8","type":"api-call-service","z":"9530fd91.600e2","name":"turn on vacation mode","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":788,"y":192,"wires":[["4971bda0.0758f4"]]},{"id":"4971bda0.0758f4","type":"api-call-service","z":"9530fd91.600e2","name":"notify jason","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_jason","entityId":"","data":"{\"title\":\"Vacation Mode\",\"message\":\"Vacation Mode has been enabled.\"}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":982,"y":192,"wires":[[]]},{"id":"bf80cebf.58bcc","type":"server-state-changed","z":"9530fd91.600e2","name":"home/away","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"1","forType":"num","forUnits":"days","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":102,"y":192,"wires":[["7d414deb.904f64"],["c81cbf7d.abe22"]]},{"id":"c81cbf7d.abe22","type":"api-call-service","z":"9530fd91.600e2","name":"vacation mode off","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":314,"y":240,"wires":[[]]},{"id":"7d414deb.904f64","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":314,"y":192,"wires":[["dca703ed.f3222"],[]]},{"id":"dca703ed.f3222","type":"subflow:fda663f6.59a56","z":"9530fd91.600e2","name":"turn on vacation mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been aways for 24 hours. Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":542,"y":208,"wires":[["7003285c.a3a8c8"],[],[],[]]},{"id":"7ce57cf8.cad134","type":"comment","z":"9530fd91.600e2","name":"Actionable notification to turn on vacation mode","info":"","x":212,"y":144,"wires":[]}]
    +

    Also See

    Step 3

    Set up a group of lights and switches in Home Assistant that you want to turn on and off while vacation mode is active. This can be done without creating a group in Home Assistant by modifying the get-entities node in the below flow to entity_id in light.night_light,light.kitchen,switch.bedroom_light,switch.laundry_room.

    group:
    +  vacation_lights:
    +    name: Vacation Lights
    +    entities:
    +      - light.night_light
    +      - light.kitchen
    +      - switch.bedroom_light
    +      - switch.laundry_room
    +

    Step 4

    This flow will run between sunset and midnight turning lights on and off at random intervals if vacation mode is enabled.

    screenshot

    [{"id":"aa02fa4a.a35548","type":"inject","z":"9530fd91.600e2","name":"","repeat":"","crontab":"*/6 16-23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":118,"y":336,"wires":[["7e966ac8.609524"]]},{"id":"cfa1b8e4.8d4a08","type":"time-range-switch","z":"9530fd91.600e2","name":"","startTime":"sunset","endTime":"23:59","startOffset":0,"endOffset":0,"x":496,"y":336,"wires":[["c7efc558.da1bc8"],[]]},{"id":"a41f4d83.d45c4","type":"ha-get-entities","z":"9530fd91.600e2","server":"","name":"","rules":[{"property":"entity_id","logic":"in_group","value":"group.vacation_lights","valueType":"str"},{"property":"state","logic":"is","value":"off","valueType":"str"}],"output_type":"random","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":806,"y":336,"wires":[["f3897d20.fffee"]]},{"id":"c7efc558.da1bc8","type":"function","z":"9530fd91.600e2","name":"25%","func":"const random = Math.round(Math.random() * 100);\n\nif(random < 75) {\n    node.status({fill: \"red\", text: random});\n    return;\n}\n\nnode.status({fill: \"green\", text: random});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":658,"y":336,"wires":[["a41f4d83.d45c4"]]},{"id":"f3897d20.fffee","type":"api-call-service","z":"9530fd91.600e2","name":"turn on","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":956,"y":336,"wires":[["20fce293.98ce8e"]]},{"id":"20fce293.98ce8e","type":"delay","z":"9530fd91.600e2","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"5","randomLast":"36","randomUnits":"minutes","drop":false,"x":1100,"y":336,"wires":[["3d851328.fb1b8c"]]},{"id":"3d851328.fb1b8c","type":"api-call-service","z":"9530fd91.600e2","name":"turn off","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_off","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1234,"y":336,"wires":[[]]},{"id":"7e966ac8.609524","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":298,"y":336,"wires":[[],["cfa1b8e4.8d4a08"]]},{"id":"22f34ec4.9d3a22","type":"comment","z":"9530fd91.600e2","name":"Vacation Lights","info":"","x":112,"y":288,"wires":[]}]
    +
    + + + diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000..0735548fb6 Binary files /dev/null and b/favicon.ico differ diff --git a/guide/action.html b/guide/action.html new file mode 100644 index 0000000000..7d6262f6cd --- /dev/null +++ b/guide/action.html @@ -0,0 +1,45 @@ + + + + + + + + + Action Tips and Tricks | node-red-contrib-home-assistant-websocket + + + + + +

    Action Tips and Tricks

    Homeassistant Domain

    The homeassisant domain can be used with different domains of entities with certain services.

    Here's an example of using the homeassistant domain to turn off some lights, switches, and everything that can be turned off in the laundry room in a single service call. This can save you from having to have multiple action nodes.

    screenshot of a action node using homeassistant domain

    Using Mustache Templates

    Mustache templates can be used in the domain, service, and entity id fields. This is useful if you want to set the service based on msg.payload or any other message property.

    Here's an example using eztimeropen in new window to set the output of the node to on or off. Then use that in the action node for which service to use.

    screenshot of flow

    screenshot of the action node

    [{"id":"522c54b8de855062","type":"api-call-service","z":"a38123c1.2fd3f","name":"","server":"","version":4,"debugenabled":false,"domain":"homeassistant","service":"turn_{{payload}}","target":{"areaId":["75a88dfa58844f8aad752dde5bc51fc7"],"deviceId":[],"entityId":["light.front_porch","light.garage","light.kitchen"]},"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":526,"y":672,"wires":[[]]},{"id":"cca91c6fe47d7fa0","type":"eztimer","z":"a38123c1.2fd3f","name":"","debug":false,"autoname":"sunset - dawn","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"latLongSource":"manual","latLongHaZone":"","lat":"","lon":"","timerType":"1","startupMessage":true,"ontype":"1","ontimesun":"sunset","ontimetod":"17:00","onpropertytype":"msg","onproperty":"payload","onvaluetype":"str","onvalue":"on","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"1","offtimesun":"dawn","offtimetod":"dusk","offduration":"00:01:00","offpropertytype":"msg","offproperty":"payload","offvaluetype":"str","offvalue":"off","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"resend":false,"resendInterval":"0s","mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":272,"y":672,"wires":[["522c54b8de855062"]]}]
    +

    Mustache templates are also accepted in the data field when their type is set to JSON.

    Also see:

    Targets

    The target fields allow you to target areas, devices, and/or entities. Any combination can be used when they are available, some services don't accept areas and devices.

    Mustache templates and environment variables can be used inside each target list.

    Data Field

    TIP

    It's recommended to use the JSONata expression, J: Expression, for the data field as it has several advantages over JSON.

    • Handles quotes based on the type of variable
    • Allows the insertion of more complex variables such as arrays and object
    • Mathematical operations are permitted

    Inserting a message property into a string

    Sending a TTS message when a door is opened

    screenshot of flow

    screenshot of the action node

    { "message": "The " & data.attributes.friendly_name & " has been opened." }
    +
    [{"id":"cd1f9610a73addbc","type":"server-state-changed","z":"a38123c1.2fd3f","name":"","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor\\..+_door$","entityidfiltertype":"regex","outputinitially":false,"state_type":"str","haltifstate":"open","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":338,"y":560,"wires":[["4e016826f6497b79"],[]]},{"id":"4e016826f6497b79","type":"api-call-service","z":"a38123c1.2fd3f","name":"send tts","server":"","version":4,"debugenabled":false,"domain":"tts","service":"google_translate_say","target":{"areaId":[],"deviceId":[],"entityId":["all"]},"data":"{\"message\": \"The \" & data.attributes.friendly_name & \" has been opened.\"}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","output_location":"","output_location_type":"none","x":570,"y":560,"wires":[[]]}]
    +

    Getting a property value of a Home Assistant entity

    There's a custom function in JSONata inside Home Assistant nodes that allows the fetching of any property of an HA entity.

    • $entities() returns all entities in the cache
    • $entities("entity_id") returns a single entity from the cache matching the passed in entity_id

    Example of getting the friendly name of an entity

    { "message": "The " & $entities("binary_sensor.front_door").attributes.friendly_name & " has been opened." }
    +

    Example of getting friendly names of all the lights and switches with an on state

    {
    +     "message": "The " & $join($entities().*[state = "on" and entity_id ~> /^light|^switch/].attributes.friendly_name, ", ") & " are on.",
    +     "title": "Left On"
    +}
    +

    Doing arithmetic

    Home Assistant states are represented as strings so to be able to do arithmetic on them in JSONata they will need to be cast to a number first use $number()open in new window. Most attributes of entities are in their correct state but it never hurts to be safe and cast them as a number.

    $number($entities("sensor.kitchen_lux").state)

    Adding 3 to the current temperature of a climate entity

    screenshot of action node

    { "temperature": $entities("climate.thermostat").attributes.temperature + 3 }
    +

    Create a comma-delimited entity id list

    Example of getting a list of lights from the get-entities node and then creating an entity id list to turn them off. The entity id field is left blank in this example as it is defined in the data field.

    screenshot of flow

    screenshot of action node

    { "entity_id": $join(payload.entity_id, ",") }
    +
    [{"id":"80c20ba2.f09cd8","type":"ha-get-entities","z":"f731b121.0463a","server":"","name":"get lights that are on","rules":[{"property":"entity_id","logic":"starts_with","value":"light.","valueType":"str"},{"property":"state","logic":"is","value":"on","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":468,"y":528,"wires":[["cafbf446.080928"]]},{"id":"cafbf446.080928","type":"api-call-service","z":"f731b121.0463a","name":"turn them off","server":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"","data":"{\"entity_id\": $join(payload.entity_id,\",\")}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":662,"y":528,"wires":[[]]},{"id":"39666758.cee048","type":"inject","z":"f731b121.0463a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":284,"y":528,"wires":[["80c20ba2.f09cd8"]]}]
    +

    Also see:

    + + + diff --git a/guide/conditionals.html b/guide/conditionals.html new file mode 100644 index 0000000000..a5b73201fd --- /dev/null +++ b/guide/conditionals.html @@ -0,0 +1,34 @@ + + + + + + + + + Conditionals | node-red-contrib-home-assistant-websocket + + + + + +

    Conditionals

    Rules

    is and is not

    < and <= and > and >=

    in and not in

    The value is expected to be a comma-separated list of items.

    JSONata

    When this is selected as a rule it expects a boolean to be returned by the value.

    starts with

    in group

    Value Types

    string and number and boolean and regular expression and JSONata expression

    Evaluates and returns the value as the selected type.

    msg and flow and global

    Reference to the different contexts of Node-RED.

    entity and prevEntity

    Reference the entity that triggered the node.

    • entity is the current state entity
    • prevEntity is the previous state entity
    + + + diff --git a/guide/custom_integration/exposed-nodes.html b/guide/custom_integration/exposed-nodes.html new file mode 100644 index 0000000000..f0226ec3ca --- /dev/null +++ b/guide/custom_integration/exposed-nodes.html @@ -0,0 +1,34 @@ + + + + + + + + + Exposed Nodes | node-red-contrib-home-assistant-websocket + + + + + +

    Exposed Nodes

    Available to all event nodes

    Events: all, events: state, trigger: state, and poll state nodes will have the option to be exposed to Home Assistant, and when enabled, it will show up in Home Assistant as a switch. Turning on and off these switches will disable/enable the nodes in Node-RED. This should help people who find themselves having to make input_booleans in HA to enable/disable flows. This is a much cleaner way to do it.

    Trigger an exposed event node from a service call nodered.trigger

    Exposed nodes can be triggered from a service call. The service call is nodered.trigger and it takes the following data properties:

    entity_id

    • Required

    The entity_id of the exposed node to trigger. This is the entity_id of the node in Home Assistant. For example, if the entity_id of the node in Home Assistant is switch.my_node, then the entity_id to use in the service call is switch.my_node.

    output_path

    • Optional
    • Defaults to 0
    • Can be a comma separated list of output paths

    The output path of the node to send the message through. When this value is set to 0, the message will be sent through all output paths. If this value is set to 1, the message will be sent through the first output path. When this value is set to 2, the message will be sent through the second output path, and so on.

    message

    • Required

    The message the triggered node will output. This can be any valid JSON object. For example, if the message is { "payload": "hello world" }, then the message will be sent to the node as msg.payload with the value of hello world.

    + + + diff --git a/guide/custom_integration/index.html b/guide/custom_integration/index.html new file mode 100644 index 0000000000..0e56ae3748 --- /dev/null +++ b/guide/custom_integration/index.html @@ -0,0 +1,34 @@ + + + + + + + + + Getting Started | node-red-contrib-home-assistant-websocket + + + + + +

    Getting Started

    Installation

    Installation of custom integration can be done using HACSopen in new window or manually, instruction can be found in the READMEopen in new window.

    Tip

    Filling in the friendly name field in the entity config node before you first deploy will attempt to create it with that entity*id otherwise it will default to sensor.nodered_<node id>. Where the random string is the node id in Node-RED. The entity id can be changed in Home Assistant after creating them in Node-RED.

    image|455x88

    + + + diff --git a/guide/development.html b/guide/development.html new file mode 100644 index 0000000000..356a3bd4fd --- /dev/null +++ b/guide/development.html @@ -0,0 +1,44 @@ + + + + + + + + + Development | node-red-contrib-home-assistant-websocket + + + + + +

    Development

    Also see CONTRIBUTING.mdopen in new window.

    Environment setup

    Here are the steps to successfully setup your development environment to contribute to this project

    Setup using the VS Code dev container

    This will set up a docker container with all the required tools and dependencies to get started.

    1. Go to the Node-RED Home Assistantopen in new window repository and fork it.

    2. Clone your forked repository to your local machine.

      git clone https://github.com/<GITHUB_USER_NAME>/node-red-contrib-home-assistant-websocket
      +
    3. Open the project in VS Code.

    4. Install the Remote - Containersopen in new window extension.

    5. Click the green button in the lower-left corner of the window that says "Reopen in Container".

    6. Wait for the container to build and start.

    7. Open a terminal in VS Code and run npm run dev to start the development server.

    Setup locally

    1. Go to the Node-RED Home Assistantopen in new window repository and fork it.

    2. Clone your forked repository to your local machine.

      git clone https://github.com/zachowj/node-red-contrib-home-assistant-websocket
      +
    3. create an npm link to your forked project. This will also build this project's dependencies.

      cd node-red-contrib-home-assistant-websocket
      +npm link
      +
    4. Installopen in new window Node-RED on localhost, assuming we install it on ~/dev directory (you can install it in another location as you wish)

      cd ~/dev/node-red
      +npm install -g --unsafe-perm node-red
      +
    5. Install your fork project into local Node-RED using npm link:

      cd ~/dev/node-red
      +npm link node-red-contrib-home-assistant-websocket
      +
    6. Starting Node-RED on localhost

      cd ~/dev/node_modules/node-red
      +npm run dev
      +

    Accessing

    After running npm run dev Node-RED will be running on ports 1880 and 3000. You can access the development server at http://localhost:1880 or http://localhost:3000 either port can be used. On port 3000 browser-sync is running and will reload the browser when changes are made to the editor source code.

    Linting

    This project uses ESLintopen in new window and Prettieropen in new window to lint and format the code. You can run npm run lint to lint the code.

    Testing

    1. Run npm run test to run the tests.
    + + + diff --git a/guide/diagnostics.html b/guide/diagnostics.html new file mode 100644 index 0000000000..9896e8e4e8 --- /dev/null +++ b/guide/diagnostics.html @@ -0,0 +1,35 @@ + + + + + + + + + Diagnostics Information | node-red-contrib-home-assistant-websocket + + + + + +

    Diagnostics Information

    Overview

    To assist with troubleshooting, a button has been added to the Node-RED editor that will run a diagnostics flow and copy the output to the clipboard. This output can then be pasted into a GitHub issue or a support forum.

    Note

    Before version 0.62.0, the diagnostics flow was a separate flow that had to be imported into Node-RED. This flow is still available and can be found here.

    screenshot of buton location

    gif for finding button

    Before version 0.62.0

    The supplied diagnostics flow serves as a valuable tool for collecting data about the runtime and the system environment. This flow can be importedopen in new window into Node-RED and run. By doing so, it compiles crucial information regarding the runtime and the system environment, enabling users to easily share this data when addressing issues.

    Flow

    screenshot

    [{"id":"83159f9ffc81a5fd","type":"inject","z":"a3f996b014aea8a5","name":"get environment info","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":226,"y":608,"wires":[["11f9ee4206596633"]]},{"id":"607c82ab3a273e93","type":"debug","z":"a3f996b014aea8a5","name":"copy info from debug tab","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":582,"y":608,"wires":[]},{"id":"11f9ee4206596633","type":"http request","z":"a3f996b014aea8a5","name":"fetch","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://localhost:1880/homeassistant/diagnostics","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":390,"y":608,"wires":[["607c82ab3a273e93"]]}]
    +

    This flow can also be imported directly from the examples section in Node-RED.

    Usage

    1. Import the flow into Node-RED.

    2. Deploy the flow.

    3. Click the Inject node to run the flow.

    screenshot of debug window

    1. Copy the output from the Debug tab.

    screenshot of debug window

    1. Paste the output into a GitHub issue or a support ticket.
    + + + diff --git a/guide/documentation.html b/guide/documentation.html new file mode 100644 index 0000000000..074b0f3248 --- /dev/null +++ b/guide/documentation.html @@ -0,0 +1,36 @@ + + + + + + + + + Documentation | node-red-contrib-home-assistant-websocket + + + + + +

    Documentation

    The documentation is built with VuePress v2open in new window. The pages are written in Markdown and are located in the docs directory.

    Small changes

    If you want to make small changes to the documentation, you can do so directly in the GitHub web interface. Just navigate to the file you want to change and click the pencil icon in the top right corner.

    There is a link on the bottom of each page to edit the file directly in the GitHub web interface.

    Local development

    If you want to make larger changes to the documentation, you can clone the repository.

    Developing with Visual Studio Code and Docker

    1. Install Visual Studio Codeopen in new window.

    2. Install the Remote - Containersopen in new window extension.

    3. Go to the Node-RED Home Assistantopen in new window repository and fork it.

    4. Clone your forked repository to your local machine.

      git clone https://github.com/<GITHUB_USER_NAME>/node-red-contrib-home-assistant-websocket
      +
    5. Open the repository in Visual Studio Code.

    6. Click on the green "Open a Remote Window" button in the bottom left corner and select "Reopen in Container".

    7. Open a terminal in Visual Studio Code and run npm install --save-dev to install the dependencies.

    8. Run npm run docs:dev to start the development server.

    Manual environment

    1. Install Node.jsopen in new window.

    2. Go to the Node-RED Home Assistantopen in new window repository and fork it.

    3. Clone your forked repository to your local machine.

      git clone https://github.com/<GITHUB_USER_NAME>/node-red-contrib-home-assistant-websocket
      +
    4. Open the repository in your favorite editor.

    5. Run npm install --save-dev to install the dependencies.

    6. Run npm run docs:dev to start the development server.

    + + + diff --git a/guide/first-automation.html b/guide/first-automation.html new file mode 100644 index 0000000000..c34156b296 --- /dev/null +++ b/guide/first-automation.html @@ -0,0 +1,35 @@ + + + + + + + + + First Automation | node-red-contrib-home-assistant-websocket + + + + + +

    First Automation

    For your first automation, we'll start simple and set up an automation to turn on and off a light when the sun comes up and goes down.

    This example will use the state, below_horizon/above_horizon, of the sun.sun entity from Home Assistant to trigger the light.

    Events: state

    Place an Events: state node onto the workspace and double click on it to edit.

    screenshot

    Entity ID

    We'll add sun.sun to the Entity ID field and leave the entity id filter type to Exact as we only want to match one entity.

    If State

    If State is a conditional that will be checked against the state of the entity when it triggers the node. If the condition is found to be true the message will be sent out the top output and if found to be false it will be sent out the bottom output. If no conditional value is set there will only be one output and all messages will flow through it.

    For this example we will set the If State to above_horizon.

    screenshot

    Call Service

    Now that the trigger is set up it's time to set up the action. Most communication done with Home Assistant will come in the forms of services calls using the Call Service Node.

    Drag two Call Service nodes onto the workspace and connect them to each of the outputs from the Events: state node.

    screenshot

    Since we made the conditional in the Events: state node if state is equal to above_horizon the top output will be the action to turn off the light and the bottom output will be the action to turn on the light.

    The three fields that are relevant for this example are: Domain, Service, and Entity Id. Domain is going to be light, Service is going to be turn_off, and Entity Id is going to be light.front_porch. The Second Call Service node will be the same except the Service is going to be turn_on.

    screenshot

    Complete Automation

    At this point, you can deploy and should have your first working automation in Node-RED.

    screenshot

    [{"id":"b74ada49.d7e408","type":"server-state-changed","z":"ffbd7f06.4a014","name":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sun.sun","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"above_horizon","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":244,"y":784,"wires":[["1f467cbb.0c3983"],["da5ff3e0.cbb2a"]]},{"id":"1f467cbb.0c3983","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":784,"wires":[[]]},{"id":"da5ff3e0.cbb2a","type":"api-call-service","z":"ffbd7f06.4a014","name":"","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.front_porch","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":474,"y":832,"wires":[[]]}]
    +

    Also see:

    + + + diff --git a/guide/index.html b/guide/index.html new file mode 100644 index 0000000000..d9aa94b237 --- /dev/null +++ b/guide/index.html @@ -0,0 +1,38 @@ + + + + + + + + + Getting Started | node-red-contrib-home-assistant-websocket + + + + + +

    Getting Started

    Prerequisites

    Have Node-RED installed and working, if you need to install Node-RED see hereopen in new window.

    Installation

    Using the Palette Manager

    Search in the Palette Manageropen in new window for:

    node-red-contrib-home-assistant-websocket
    +

    Using npm from the command line

    $ cd ~/.node-red
    +$ npm install node-red-contrib-home-assistant-websocket
    +# restart Node-RED
    +

    Home Assistant Add-on

    The Community Home Assistant add-on ships with this set of nodes right out of the box and comes configured to connect to Home Assistant. No other information is needed and you're ready to start your first automation.

    The add-on can be found here: https://github.com/hassio-addons/addon-node-red#readmeopen in new window

    Configuration

    Place an Events: all node onto the workspace and edit the node. Click on the pencil icon next to the Server field.

    screenshot

    Search for a local Home Assistant instance or manually fill in the Base Url.

    screenshot

    Enter an Access Token on the server config node then Add/Update the Server Config and Events: all nodes and deploy. After deploying a green box with a status message, i.e. connected, stated_changed, should appear below the Events: all node. If you see an open box with the status of connecting or disconnected you probably have incorrectly entered the base URL or access token.

    • Base Url is the web address and port you use to access the Home Assistant frontend (e.g., http://localhost:8123, http://192.198.x.x, and http://example.duckdns.org).

    • Access Token is generated in Home Assistant there are instructions below on how to generate one.

    TIP

    Changing the deploy type to Modified Flows or Modified Nodes will make it so when you deploy only the flows that you have modified will get reloaded. This helps if you have other flows on the workspace that you don't want to have reloaded everything time you change something else.

    screenshot

    TIP

    If you find that new entities added to Home Assistant are not showing up in the autocomplete results try unchecking Cache Autocomplete Results in the server config and restarting Node-RED.

    Generate Access Token

    WARNING

    The user used to create the access token must be in the administrator group for this package to function correctly.

    Goto your Home Assistant home page and in the bottom left corner click on the blue circle with the letter in it. In the screenshot below it's the "J".

    screenshot

    • Scroll down to the bottom of the page and it should look like the screenshot below and click on the Create Token Button
    • Give it a name, it can be anything you want to identify it
    • Copy the generated access token into Node-RED

    screenshot

    TIP

    Creating a separate Home Assistant user for Node-RED and using their access token will give you the ability to track which entities were changed by Node-RED.

    TIP

    Once you've configured the WebSocket connection using the Events: all node, this node should be removed for optimal NodeRed performance. Instead, prefer using the other node types provided by this package (Events: state, Trigger: state etc), or add an event type filter to the Events: all node to avoid overloading the websocket message queue.

    + + + diff --git a/guide/jsonata/index.html b/guide/jsonata/index.html new file mode 100644 index 0000000000..605954fd90 --- /dev/null +++ b/guide/jsonata/index.html @@ -0,0 +1,34 @@ + + + + + + + + + JSONata | node-red-contrib-home-assistant-websocket + + + + + +

    JSONata

    JSONata is a functional declarative language, designed to work with JSON objects. It is built-in within Node-RED and is available in standard nodes where you see the J: expression option, for example in the Inject Node.

    • JSONata code is written as a line expression, which is evaluated and returns the result.
    • The expression is evaluated against a JSON object. In Node-RED this JSON is the top level message object. There is no need to use a leading 'msg.' therefore just payload will evaluate as the message payload value, and topic as the topic value.

    WARNING

    JSONata is very different to Mustache templates, and the use of {{msg.payload}} will not work as you might expect.

    In the Home Assistant nodes, JSONata can be used to set entity states, set output property values, generate UI parameters, or as conditional tests (both generating the test value, and as an evaluated predicate expression).

    Examples of using JSONata in the Home Assistant Nodes:

    1. Call a service using JSONata to build the data object
      • Increase light brightness with remote
      • Set A/C target temperature and hvac mode
      • Send 'lights on' notification when leaving home
      • Extract weather forecast details from call return
    2. Read the current state or attribute value of an entity
      • Report difference between A/C current and target temperatures
      • Report if A/C been cooling for more than 2 hours before 17:00
      • Report if A/C unit is running outside of 'office hours'
    3. Listen for entity state or attribute changes
      • Motion detection start, and motion ending only before 08:30 and after 17:30
      • Switch just turned off, and has been on for less than three minutes
      • Motion detection only before dawn and after dusk, with dusk and dawn times output
    4. Trigger a flow from state change conditions
      • Every minute before and after sunset
      • Automation events just before, at, and just after sunset
      • Adjust light brightness from 0 to 100 percent over sunset
    5. Write state and attribute values to an HA sensor
      • Provide a sensor with a count of the number of lights that are on
      • Provide an attribute array (list) of the lights that are on
      • Since I last looked, list which lights have been turned on, or off
    6. Route flow (switch node) based on computed outcomes
      • Select flow routing depending on state 'last changed ms' period in minutes
    7. Read state history and process the return JSON (change node)
      • Calculate when, and for how long, I have not been at home in the past week
    8. Using the additional $entity() functions in JSONata
      • Reading node entity states and attributes
      • Reading all Home Assistant entities
      • Reading Areas, Devices, and their Entities

    Home Assistant functions

    There are several additional Home Assistant functions added for use in JSONata expressions, and these can only be used within the Home Assistant nodes.

    • $entity() returns the entity that triggered the node

    • $prevEntity() returns the previous state entity if the node is an event node

    • $areaDevices(areaId) returns all devices associated with a specific area ID.

    • $areaEntities(areaId) returns all entities associated with a specific area ID.

    • $areas(lookup) returns an area based on a provided lookup value, or all areas if no lookup value is provided. The lookup value can be an area ID, an entity ID, or a device ID.

    • $deviceEntities(device_id) returns all entities associated with a specific device.

    • $device(lookup) returns a device based on a provided lookup value. The lookup value can be an entity ID or a device name.

    • $entities() returns all entities in the cache

    • $entities(entity_id) returns a single entity from cache matching the given entity_id

    Exposed Lodashopen in new window functions

    • $sampleSize(collection, [n=1]) https://lodash.com/docs/#sampleSizeopen in new window

      Gets n random elements at unique keys from collection up to the size of collection.

    • $randomNumber([lower=0], [upper=1], [floating]) https://lodash.com/docs/#randomopen in new window

      Produces a random number between the inclusive lower and upper bounds. If only one argument is provided a number between 0 and the given number is returned. If floating is true, or either lower or upper are floats, a floating-point number is returned instead of an integer.

    Also see:

    + + + diff --git a/guide/jsonata/jsonata-primer.html b/guide/jsonata/jsonata-primer.html new file mode 100644 index 0000000000..d81f43d755 --- /dev/null +++ b/guide/jsonata/jsonata-primer.html @@ -0,0 +1,46 @@ + + + + + + + + + JSONata primer | node-red-contrib-home-assistant-websocket + + + + + +

    JSONata primer

    This is a simple introduction highlighting the key aspects of this language. Full details can be found at the online JSONata documentationopen in new window

    JSONata code can be written as either a single line expression, or as multiple line expressions in a code block ( ). Expressions are evaluated against a _JSON object. In Node-RED this object is the node input message.

    A single line expression is evaluated left to right by operator, and the result returned is the final evaluation.

    • Everything in JSONata is an expression and will be evaluated, returning the result
    • Literals are evaluated as themselves, but must be valid JSON (number, string, Boolean, null, array or object)
    • Object keys (fields) are evaluated as the key value, where found, thus payload will return the value contained in msg.payload
    • The primary use of JSONata is to evaluate a JSON path, such as msg.payload.foo.bar
    • Path operators are evaluated in a line expression by being applied to the top level message
      • . is the mapping (iteration) operator
      • [ ] is the filter (selection) operator
      • { } is the reduce (aggregation) operator
      • ^( ) is the sorting (ordering) operator

    Context: At the start of a line expression, the context is the entire top level message. Each path operator takes input from the current context, with the final result of each operation passed as output context to the next operator. Available context therefore changes as the evaluation proceeds. The current context at a specific point can be referred to using $. An additional operator $$ can be used to refer to the top level context at any point, and % can be used to refer to the parent context (back one level) but only where this is possible to determine.

    The mapping (iteration) operator .

    Syntax can be considered as <sequence-list> . <expression>.

    The current input-context on the left hand side of the operator is parsed as a sequence or ordered list of items (for an array this is a list of the array elements, for an object or for a primitive this is usually a singleton list). Each item in this list is taken in sequence as the evaluation-context, and evaluated by the expression formed from the right hand side of the operator. The result sequence is then collated into an output array (from an input list) or returned as a singleton (from an input singleton, or where the input sequence reduces to a singleton).

    As an example, $type(payload) returns the type of the message payload, however payload.$type($) returns an array of the type of each element within payload. For an array of numbers, this would be ["number", "number", "number"]. The right hand side, $type() is a JSONata function requiring a parameter. For many functions one or more parameters are optional, and where omitted they take the current (evaluation) context $ instead. In this case, the parameter is not optional, hence the use of $ for the immediate context (each array element in turn).

    Index operator #: Applied with the mapping operator, the # index operator can be used to capture the iteration index value for use later in the expression. The operator must be followed by a variable, for example $i, and this variable is made available for the remaining line expression. If payload is an array of three items, then payload#$i.($i+2) would return [2, 3, 4]. The use of () here is required since JSONata is left-associative and the parentheses are required to force the correct order of evaluation.

    Wildcards and array flattening: Within a path expression, * can be used to select all fields in an object, and ** is a descendant wildcard for any depth of nesting. Thus payload.**.time would return an array of the values of all nested time keys.

    The path expression may generate an array of arrays for the evaluation sequence list. In this case, the list will always first be flattened to just one array. This flattening also occurs for output when the result is an arrays of arrays.

    If payload is an array of objects then payload.$keys() returns an array, listing the keys names for each array object. For an array of nested objects, payload.**.$keys() returns a flattened array of all keys. To remove duplicates, the $distinct() function can be used, thus $distinct(payload.**.$keys()) returns an array of every key in message payload to any depth.

    The filter (selection) operator [ ]

    The [ ] operator has several applications.

    • If the operator encloses an integer, this acts as array index addressing, where payload[0] returns the first item in the array, [-1] the last item. Note that the index can be an integer, or any number expression that returns or rounds down to an integer.
    • If the operator encloses an array of integers, these act as a selection list, thus payload[0, -1] returns the first and last items from payload array.
    • Otherwise, where the operator encloses a predicate expression, this will map over the current context as a list, filtering only the list items where the predicate evaluates as true. For example payload[time<"12:00"] where time is a key value within payload object.
    • For the special range operator [a..b], such as [0..3] this syntax generates an array of integers between the two given integer values. Note that, as in all cases in JSONata, the defining integer values can be either literals, or expressions that evaluate to an integer. To generate an array of integers to be used as a filter requires [[a..b]].
    • Lastly, this operator acts as an array constructor. ["one", "two", "three"] is an array. The simple form [] may also be used at any point in a line expression to force singleton output to an array, as in payload.data[].

    JSONata does not inherently regard singleton values as fundamentally different to arrays. Although a singleton is a value without enclosing structure, path expressions that require an array input can accept a singleton, which is treated as an array of one item. In some situations, particularly with path input or output list flattening, it may be necessary to add an additional [] to the expression to ensure correct evaluation, and where an array of arrays is required in the result.

    No result means nothing is returned: One of the more unusual aspects of JSONata is the behaviour when an expression evaluates to no discernible result. Simply put, JSONata will neither return a value, nor null nor an error message where there is no result from an expression. Mistyping paylaod or requesting an array index payload[100] for an array of only 25 items will return nothing. This can make writing, testing and debugging JSONata code challenging, but it eliminates the need to code for exception conditions - declare what you want, and nothing else will be returned.

    The filter operator binds more strongly than the mapping operator. This means that payload.array[0] is returned as an array of the first items in each payload.array and not the first item in the payload.array array result. Use (payload.array)[0] to force evaluation in a different order.

    The reduce (aggregation) operator { }

    This operator can only be used once in an expression line, and should ideally be at the very end. Note that { } is a valid empty object, and {"key": "value"} is a one-field object as expected. Both the key as well as the value can be any expression, thus{last_updated: payload.state} will generate a valid object as long as last_updated results in a string value. Naturally values may be an valid JSON type, including objects and arrays.

    It is worth noting that in a key-value pair where the value is an expression that returns nothing, the key-value pair will not be returned in the result.

    Thus {"key": "value", "result": [1, 2][4]} will just return {"key": "value"}

    The order-by (sort) operator ^( )

    Applies to arrays, and will sort the array by one or more expressions, where the expression results in either a string or an number. Sorting is ascending < by default, but can be modified to descending >. Where payload is an array of objects, then payload^(>field, second) will sort the array, by the field value, in descending order, and for equal values, additionally by the second field in ascending order. To sort an array of primitives such as strings, use the context variable $. If payload is an object, $keys(payload)^($) returns an array of the object keys sorted into alphabetic order.

    Other Operators

    JSONata is built on JavaScript, so much of the syntax and basic functions will be familiar. The usual mathematical operators apply.

    Comparison operators are as expected, and also the in inclusion operator where "b" in ["a", "b", "c"] returns true.

    Boolean operators are the usual and and or, but not is provided as a function $not().

    String concatenation operator is &, which provides the only situation where type is cast. Numbers, Boolean, arrays and objects are all stringified as required. Hence payload & "" will turn an object to a stringified equivalent.

    Conditional testing is a ternary operator, syntax as <test expression> ? <true expression> : <false expression> which returns the result of either the true or false expression. False expression is optional, and if omitted a false test expression result will return nothing. Nested conditionals evaluate as expected although the use of parentheses can help visual clarity or to change order.

    Variables

    JSONata permits the use of variables, although some care needs to be exercised in their use. Variables are named as $name and assigned using $name:= <expression>. Scope is from first declaration when assigned, and lasts for the enclosing line, code block ( ), or nested blocks.

    Variables in JSONata are not values held in memory-allocated space but rather bindings. In effect this means that variables can only be assigned, then referred to. Once assigned, further references to the variable are replaced at evaluation with the originally evaluated value at assignment. In practice, this means that

    • The left hand side of := assignment can only be a variable $name, and therefore-
    • Variables cannot be modified, only re-assigned
    • The value of an assignment is the value assigned, thus $a:=3 returns 3

    Variable use should be avoided in single line expressions and only used in code blocks. Whilst expression lines are evaluated in order of the operators, left to right, JSONata execution is asynchronous and different parts of the expression may be prepared in any order. Any later reference to a variable in an expression may be evaluated prior to an earlier assignment in the same line. It also worth noting that, all variable and object field references are evaluated at the very start of statement execution. Nothing done during the expression execution can reliably update or change these values. For example: [$a:=3 .. $b:=6].{"result": $a:=$a+$b, "next": $a} may or may not work as expected.

    Functions

    JSONata has a wide range of inbuilt functions (see documentation) for manipulating:

    • strings
    • numbers
    • aggregation (sum, average)
    • arrays
    • objects
    • time (limited to date-time string <-> Unix millisecond)

    There are also several higher-order functions, such as $map() and $reduce() which apply a mapping function over an array, and similarly with result accumulation.

    Functions can be nested, so that

    $substringAfter($substringBefore("2024-01-10T10:32:14.0324","."),"T") returns just the time part of the string.

    The function chaining operator ~> allows for greater visual clarity

    $substringBefore("2024-01-10T10:32:14.0324",".") ~> $substringAfter("T").

    This works with the function chain passing the result as context, and subsequent functions permitting an optional parameter to be substituted by this context.

    Additional features: Regex is available in JSONata. The usual regex format /regular_expression/flags applies, and this can be used in the functions $match(), $contains(), $split() and $replace(). In addition, a regex expression can be used as a function.

    $join($entities().*[state = "on" and entity_id ~> /^light|^switch/].attributes.friendly_name, ", ")

    • $entities() returns an object containing all Home Assistant entities, each key being an entity id, and value being an object with details of that entity
    • .* maps over the object matching all keys, therefore returning an array of all entities
    • [] filters out the entities that match the predicate expression, using
      • state = "on" to match all entities with state 'on'
      • entity_id ~> /^light|^switch/ generates a function from the regex expression "match any string containing 'light' or 'switch'". Each entity_id is passed to this function, which
      • returns a Boolean true or false, and
      • when both parts of the predicate expression are true, the entity is selected (otherwise the entity is not returned in the result)
    • the result of this is an array of selected entities
    • the field attributes.friendly_name is picked out, resulting in an array of friendly names for all lights / switches left on
    • then the $join() function joins each item in the array, using ", " as the separator, and returning a string

    Note that the $entities() function is a special function added just to the WebSocket nodes.

    Note that entity id names are made up from a domain (platform / integration) and name, separated by .. This is potentially confusing as the object key becomes person.george. Where object keys contain spaces and special characters, the payload.'person.george' referencing syntax has to be used.

    User defined functions: User functions can be easily defined and assigned to a variable name using the syntax

    $fname:= function(arg){"Result Is " & arg}.

    Once defined the function can be called using $fname(parmValue) from later within the enclosing code block.

    Code blocks

    To breakout from the constraints of just a single line expression, JSONata permits the use of (expression; expression) code blocks. These start and end with ( ) and contain one or more line expressions terminated by ;. The return value of the block is the return of the execution result of the very last line.

    Using code blocks permits a much richer coding experience, allowing the use of variable and function definitions.

    How it works in practice

    The following expression takes an object in payload and re-sorts the object keys alphabetically.

    $keys(payload)^($).{$:$lookup($$.payload,$)}~>$merge()

    This works by

    • using $keys() to obtain an array of key name strings from the object in payload
      • sorting this array alphabetically
    • mapping over the sorted array of keys, creating a new object for each key
    • with the context (each key in the iteration) as the new object key
    • and using $lookup(object, key) to find the value of this key, as the new object value
      • where $$.payload refers back to the $$ top level context to reach payload, and $ the current context (the key in each iteration)
    • thus producing an result array with each new key:object pair (in the new order)
    • and then using $merge() to merge this array of objects back into one object

    The simplicity comes from the power of JSONata to map, filter, sort and aggregate, however compared to most procedural languages it is a new way of thinking. Since the JSON object and variables cannot be modified, there is the question of how to, for example, change just one element in an array. The expression $array[2]:=10 will return an error since the left hand side of assignment can only be a variable and not an expression. To achieve this requires a declaration of the new array, built as follows.

      (
    +    $array:=[1, 2, 3, 4, 5, 6];
    +    $newval:=10;
    +    $index:=2;
    +    $append($array[[0..$index-1]], $newval)~>$append($array[[$index+1..$count($array)]])
    +  )
    +

    Here we declare the result to be the first part of the array up to the new value, the new value, then the remainder of the array. You may note that $count($array) is incorrect being one greater than the end index, however as JSONata does not complain when accessing beyond the array length, this point can be relaxed.

    It is worth noting that it is not necessary to refer to the input JSON document. The following expression generates an array of 24 objects. ([1..24])#$pos.{"index": $, "hour": $formatInteger($pos, "09") & ":00"}

    Declarative functional programming for objects: Given an object in msg.payload, how then do we change just one field value, since payload.field:="new value" is not permitted? The answer is that we have to write a "function" that declares - that is, returns - the result we require, with the idea that JSONata expressions are functions applied to the input JSON object.

    The $spread() function takes a JSON object and returns an array of objects, each with a single key:value pair. The $merge() function reverses this, taking an array of objects and combining back into one object. A particular feature of this function is that, where key values are duplicated, the end result contains only the last such key to be found. Therefore, the approach to take is to spread the object, append the replacement key:value as an object to the end of this array, then to merge the array back together.

     (
    +   $object:={"first": 1, "second": 2, "third": 3};
    +   $replaceKey:= "second";
    +   $replaceVal:= 15;
    +   $spread($object) ~> $append({$replaceKey: $replaceVal}) ~> $merge()
    + )
    +

    Deeply nested objects are much more complex, as the entire tree has to be unpicked and rebuilt in order. Fortunately there is a special function that can perform transformationopen in new window on an object for us. $object ~> | $ | {"second": 15} |

    Errors and error handling

    JSONata has minimal error management. Errors occur at compile time when editing due to incorrect syntax, and will show as red line box in the UI input field, as well as a red triangle on the node. Common reasons for this are missing:

    • & between string concatenation
    • : in conditional testing, or in object construction
    • ; line terminators

    Errors at run time are mostly limited to passing nothing or an incorrect type as parameter to a function. The $number() function accepts a string and returns a JSON number, but only where the input can be correctly parsed. JSON numbers must only contain numbers throughout. Passing "12,34a" will generate a fatal error, and the entire expression evaluation will be aborted.

    Where functions explicitly require an array, passing singletons will generate an error, and thus the use of [ ] to either construct arrays or cast singletons to an array may be required, for example $append(payload.array, [$additional]). Where necessary the use of $exits() to check for object fields, and the use of $type() can help.

    Writing JSONata code

    JSONata can be directly entered into any node where the UI field entry type is J: expression. The Node-RED editor permits expansion of the simple box using the '...' field at the end of the line. This editor provides more space, the ability to select and insert JSONata functions from a pick list, a formatting option, and a tab for testing. However, this can be limited and the try JSONataopen in new window website is easier to use.

    If using the JSONata Exerciser website, use a debug node set to output the "complete message", copy this entire object and paste over the left hand side JSON input object (there is a useful formatter option). Test JSONata code can then be written in the top right hand window, and the result appears immediately below. Useful output messages indicate where there is an error in the input JSON, where no result is generated, or where an error has occurred.

    Note that there are special Node-RED functions, $env() is one, that can be tested in the Node-RED editor, but not in try JSONata. The WebSocket functions, such as $entity() cannot be tested in either editor.

    What JSONata cannot do

    JSONata can almost completely replace JavaScript in function nodes. However, the simplicity and power of the declarative language is at the expense of efficiency. Arrays and files with more than, say, 500 elements or lines will require significant CPU processing as to temporarily halt Node-RED and potentially Home Assistant. The main barrier to use is more likely to be the time and effort required to generate code, since it can be challenging to think in terms of a functional declaration, the outcome of which is the required result, rather than the more usual approach of designing and writing an algorithm to prescribe how to obtain the required result.

    Good luck.

    + + + diff --git a/guide/migration.html b/guide/migration.html new file mode 100644 index 0000000000..74d9c8d822 --- /dev/null +++ b/guide/migration.html @@ -0,0 +1,66 @@ + + + + + + + + + Migration | node-red-contrib-home-assistant-websocket + + + + + +

    Migration

    Current-State Node Output

    Unchecking 'Override Topic' and 'Override Payload' doesn't work in node-red-contrib-home-assistant v0.3.2. It always overwrites msg.topic and msg.payload. If you have current-state nodes where you have unchecked the 'Override Payload' with node-red-contrib-home-assistant-websocket it will stop overriding payload and put the state object into msg.data

    Poll-State Node Output

    msg.payload.data moved to msg.data

    msg.payload becomes just the state of the state object msg.payload.data.state => msg.payload

    msg.payload.dateChanged removed

    msg.timeSinceChanged and msg.timeSinceChangedMs moved into msg.data

    node-red-contrib-home-assistantopen in new window v0.3.2

    {
    +  "topic": "sun.sun",
    +  "payload": {
    +    "timeSinceChanged": "4 hours ago",
    +    "timeSinceChangedMs": 15342567,
    +    "dateChanged": "2018-10-11T14:21:01.004Z",
    +    "data": {
    +      "entity_id": "sun.sun",
    +      "state": "above_horizon",
    +      "attributes": { ... },
    +      "last_changed": "2018-10-11T14:21:01.004183+00:00",
    +      "last_updated": "2018-10-11T18:36:30.002985+00:00",
    +      "context": { ... }
    +    }
    +  },
    +  "_msgid": "345fd403.6e71ec"
    +}
    +

    node-red-contrib-home-assistant-websocketopen in new window v0.1.1

    {
    +  "topic": "sun.sun",
    +  "payload": "above_horizon",
    +  "data": {
    +    "entity_id": "sun.sun",
    +    "state": "above_horizon",
    +    "timeSinceChanged": "5 hours ago",
    +    "timeSinceChangedMs": 16236433
    +    "attributes": { ... },
    +    "last_changed": "2018-10-11T14:21:01.004183+00:00",
    +    "last_updated": "2018-10-11T18:51:30.002737+00:00",
    +    "context": { ... },
    +  },
    +  "_msgid": "5071255c.ad802c"
    +}
    +
    + + + diff --git a/guide/mustache-templates.html b/guide/mustache-templates.html new file mode 100644 index 0000000000..11c93da9d2 --- /dev/null +++ b/guide/mustache-templates.html @@ -0,0 +1,34 @@ + + + + + + + + + Mustache Templates | node-red-contrib-home-assistant-websocket + + + + + +

    Mustache Templates

    When using templates the top level is a property of the message object: msg.payload would be {{payload}}.

    You can access flow, global, and states contexts {{flow.foobar}} {{global.something}}. For the states context you can use {{entity.domain.entity_id}} to get the state or drill further down {{entity.light.kitchen.attributes.friendly_name}}.

    • {{entity.light.kitchen}} and {{entity.light.kitchen.state}} are equivalent

    By default, Mustache will replace certain characters with their HTML escape codes. To stop this happening, you can use triple braces: {{{payload}}}.

    WARNING

    Mustache templates work well with strings but if you're trying to insert a JSON object somewhere you're better off using a JSONata expression or doing with a function node and passing it in as an input.

    + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000000..c97d0cf8c3 --- /dev/null +++ b/index.html @@ -0,0 +1,34 @@ + + + + + + + + + node-red-contrib-home-assistant-websocket + + + + + + + + + diff --git a/node/API.html b/node/API.html new file mode 100644 index 0000000000..9b3b7cb0ae --- /dev/null +++ b/node/API.html @@ -0,0 +1,34 @@ + + + + + + + + + API | node-red-contrib-home-assistant-websocket + + + + + +

    API

    Config

    Protocol required

    • Type: string
    • Values: websocket|http
    • Default: websocket

    Protocol to use to access Home Assistant API.

    Method

    • Type: string
    • Values: get|post

    Type of method to use to access the HTTP endpoint.

    Path

    URL of the API endpoint.

    Params

    A JSON object with key/value pairs that will be converted into URL parameters.

    Data

    JSON Object to send for WebSocket requests and HTTP posts.

    Results

    • Type: string

      Location to save the API results.

    Input

    All properties need to be under msg.payload.

    protocol

    • Type: string
    • Values: websocket|http

    Overrides or sets the protocol property of the config.

    method

    • Type: string
    • Values: get|post

    Overrides or sets the method property of the config.

    path

    • Type: string

    Overrides or sets the path property of the config.

    data

    • Type: Object|string

    Overrides or sets the data/params property of the config.

    location

    • Type: string

    Overrides or sets the results property of the config.

    locationType

    • Type: string
    • Values: msg|flow|global

    Overrides or sets the results type property of the config.

    Output

    Value types:

    • results: results of the API request
    • config: config properties of the node

    References

    + + + diff --git a/node/action.html b/node/action.html new file mode 100644 index 0000000000..a29dde473e --- /dev/null +++ b/node/action.html @@ -0,0 +1,47 @@ + + + + + + + + + Action | node-red-contrib-home-assistant-websocket + + + + + +

    Action

    Sends a request to Home Assistant to perform an action e.g. light.turn_on, input_select.select_option, etc.

    Configuration

    Action required

    Action to perform

    Floor

    A list of floor ids that will be used as targets for the action

    Area

    A list of area ids that will be used as targets for the action

    Custom ids can be inserted into the list by adding a # at the end of the id

    Device

    A list of device ids that will be used as targets for the action

    Custom ids can be inserted into the list by adding a # at the end of the id

    Entity

    A list of entity ids that will be used as targets for the action

    Label

    A list of label ids that will be used as targets for the action

    Data

    JSON object to pass along.

    Merge Context

    • Type: string

    If defined will attempt to merge the global and flow context variable into the config

    Alternative Template Tags

    • Type: boolean

    Will change the tags used for the mustache template to <% and %>

    Queue

    • Type: none | first | all | last

    Will store the first, last, or all messages received while disconnected from Home Assistant and send them once connected again

    Input

    All properties need to be under msg.payload.

    Sample input

    {
    +    "action": "homeassistant.turn_on",
    +    "target": {
    +        "floor_id": ["first_floor"],
    +        "area_id": ["kitchen"],
    +        "device_id": ["8932894082930482903"],
    +        "entity_id": ["light.kitchen", "switch.garage_light"],
    +        "label_id": ["outdoor_lights"]
    +    }
    +    "data": {
    +        "brightness_pct": 50
    +    }
    +}
    +

    Merging

    If the incoming message has a payload property with action set it will override any config values if set.

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

    If the node has a property value in its config for Merge Context then the flow and global contexts will be checked for this property which should be an object that will also be merged into the data payload.

    Merge Resolution

    As seen above the data property has a lot going on in the way of data merging, in the end, all of these are optional and the rightmost will win if a property exists in multiple objects

    Config Data, Global Data, Flow Data, Payload Data ( payload data property always wins if provided )

    action

    • Type: string

    Action to call

    data

    • Type: JSON Object

    Data to send with the action

    target

    • Type: JSON Object with floor_id, area_id, device_id, entity_id, and label_id as array properties

    Targets of the action

    Output

    Value types:

    • config: config properties of the node
    • results: response from Home Assistant
    • sent data: data sent to Home Assistant

    References

    + + + diff --git a/node/binary-sensor.html b/node/binary-sensor.html new file mode 100644 index 0000000000..f9755e02eb --- /dev/null +++ b/node/binary-sensor.html @@ -0,0 +1,34 @@ + + + + + + + + + Binary Sensor | node-red-contrib-home-assistant-websocket + + + + + +

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Binary Sensor

    Creates a binary sensor in Home Assistant which can be manipulated from this node.

    Configuration

    State required

    • Type: boolean

    The state of the entity should be updated to

    To set the Home Assistant state to Unknown, send a state with a js expression null.

    Attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    Input Override

    • Type: string
    • Values: accept | merge | block

    Determine how input values will be handled. When merge is selected the message object values will override the configuration values.

    Inputs

    properties of msg.payload

    state

    • Type: string | number | boolean

    The value of the entity state will be updated.

    attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    + + + diff --git a/node/button.html b/node/button.html new file mode 100644 index 0000000000..567e5ffb6c --- /dev/null +++ b/node/button.html @@ -0,0 +1,34 @@ + + + + + + + + + Button | node-red-contrib-home-assistant-websocket + + + + + + + + + diff --git a/node/config-server.html b/node/config-server.html new file mode 100644 index 0000000000..bd354f54cd --- /dev/null +++ b/node/config-server.html @@ -0,0 +1,38 @@ + + + + + + + + + Server Config | node-red-contrib-home-assistant-websocket + + + + + +

    Server Config

    Home Assistant connection configuration

    Config

    Name

    • Type: string

    Label for this configuration, see details below for implications

    Using the Home Assistant Add-on

    • Type: boolean

    If you're running Node-RED as a Hass.io Add-on check this. No other information is needed.

    Base URL

    • Type: string

    The base URL and port of the Home Assistant instance can be reached at, for example: http://192.168.0.100:8123 or https://homeassistant.mysite.com

    Access Token

    • Type: string

    Long-lived Access Token used to contact the API

    Unauthorized SSL Certificates

    • Type: boolean

    This will allow you to use self-signed certificates. Only use this if you know what you're doing.

    State Boolean

    • Type: string | delimited

    A list of strings, not case sensitive, delimited by vertical pipe, |, that will return true for State Type Boolean.

    Enable Heartbeat

    • Type: boolean

    Heartbeat will send a ping message using the websocket connection to Home Assistant every X seconds. If a pong response is not received within 5 seconds Node-RED will attempt to reconnect to Home Assistant.

    Heartbeat Interval

    • Type: number

    The interval at which the ping message is sent to Home Assistant. The minimum value is 10 seconds.

    Enable Global Context Store

    • Type: boolean

    If enabled, the global context store will be used to store the Home Assistant connection, state, and service information. This allows you to use the information in other nodes using context functions.

    Example below

    UI Settings

    Cache Autocomplete Results

    Enables the caching of the JSON autocomplete requests. Enabling or disabling this may require a restart of Node-RED for it to take effect.

    ID Selector Display

    Which text to show in the selector after the id has been chosen.

    Status Date Format

    Separator

    A string that will appear in the status of an event node between the state and date string.

    Other options

    The other options are directly from DateTimeFormat Optionsopen in new window.

    Details

    Every node requires a configuration attached to define how to contact Home Assistant, which is this config node's main purpose.

    Context

    Each config node will also make some data available in the global context, the Name value in this node is used as, camelcase, and the namespace for those values

    Currently states, services, and events is made available in the global context. states is always set to all available states at startup and updated whenever state changes occur so it should be always up to date. services and events is only updated on initial deploy.

    Context Example

    Say we have a config node with the name Home Assistant, with an entity set up in Home Assistant as switch.my_switch. This state would be available within function nodes and you could fetch using something like the below code

    const haCtx = global.get("homeassistant");
    +const configCtx = haCtx.homeAssistant;
    +const entityState = configCtx.states["switch.my_switch"];
    +return entityState.state === "on" ? true : false;
    +

    Connection Issues

    Communication with Home Assistant is accomplished via a combination of WebSocket and the REST API if you are having trouble communicating with home assistant make sure you can access the API outside of node-red, but from the same server node-red is running on, using a REST client, curl, or any number of other methods to validate the connection

    References

    Home Assistant REST APIopen in new window

    + + + diff --git a/node/current-state.html b/node/current-state.html new file mode 100644 index 0000000000..e7732b2ae3 --- /dev/null +++ b/node/current-state.html @@ -0,0 +1,34 @@ + + + + + + + + + Current State | node-red-contrib-home-assistant-websocket + + + + + +

    Current State

    Returns the current state of an entity. Useful for using conditional logic to automation flows.

    Configuration

    Entity ID required

    The id of the entity to return.

    If State

    • Type: string

    If the conditional statement is evaluated as true send the message to the first output otherwise send it to the second output. If blank there will only be one output.

    Also see:

    For

    • Type: number

    The amount of time the entity state needs to have been constant for the "If state" to be true

    State Type

    • Type: string
    • Values: string|number|boolean
    • Default: string

    Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

    Block Input Overrides

    • Type: boolean
    • Default: false

    Stop msg.payload values from overriding local config

    Inputs

    payload.entityId

    • Type : string

      Overrides or sets the entity id for which the current state is being fetched

    Outputs

    Value types:

    • entity: full entity object
    • entity id: entity id of the triggered entity
    • entity state: entity state of the triggered entity
    • config: config properties of the node

    References

    + + + diff --git a/node/device-config.html b/node/device-config.html new file mode 100644 index 0000000000..1c655f8baf --- /dev/null +++ b/node/device-config.html @@ -0,0 +1,34 @@ + + + + + + + + + Device Config | node-red-contrib-home-assistant-websocket + + + + + + + + + diff --git a/node/device.html b/node/device.html new file mode 100644 index 0000000000..573c0847fb --- /dev/null +++ b/node/device.html @@ -0,0 +1,34 @@ + + + + + + + + + Device | node-red-contrib-home-assistant-websocket + + + + + +

    Device

    Configuration

    Type

    • Type: string
    • Values: trigger | action

    Device

    • Type: string

    Id of the device

    Trigger

    • Type: object

    Home Assistant object of the trigger

    Action

    • Type: object

    Home Assistant object of the action

    Capabilities

    • Type: object

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • config: config properties of the node
    • device id: device id that triggered the node
    • event data: event data received from Home Assistant
    • sent data: data sent to Home Assistant
    + + + diff --git a/node/entity-config.html b/node/entity-config.html new file mode 100644 index 0000000000..0f3fe1834f --- /dev/null +++ b/node/entity-config.html @@ -0,0 +1,34 @@ + + + + + + + + + Entity Config | node-red-contrib-home-assistant-websocket + + + + + +

    Entity Config

    Home Assistant entity config

    Configuration

    Name

    • Type: string

    The name of the entity that will show in Node-RED

    Device

    A list of devices the entity can be associated with. This is used to group entities together in the UI.

    Caveat

    If the entity has already been registered with Home Assistant when no device was selected. The device will not be added to the Home Assistant until after Home Assistant has been restarted.

    Type required

    • Type: string
    • Values: binary_sensor|button|sensor|switch

    Resend state and attributes

    • Type: boolean

    When the entity in Home Assistant is created the state and attributes will also be set. This is only applicable with certain entities nodes.

    Other Properties

    Configuration options are available for the selected entities

    https://developers.home-assistant.io/docs/core/entityopen in new window

    + + + diff --git a/node/entity.html b/node/entity.html new file mode 100644 index 0000000000..c2adf6b519 --- /dev/null +++ b/node/entity.html @@ -0,0 +1,34 @@ + + + + + + + + + Entity | node-red-contrib-home-assistant-websocket + + + + + +

    DEPRECATED

    This node has been deprecated in favor of the individual entity nodes. The individual entity nodes can be used in subflows and added to devices.

    Entity

    Creates an entity in Home Assistant which can be manipulated from this node.

    binary sensor, sensor, and switch

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Configuration

    Type required

    • Type: string
    • Values binary_sensor|sensor|switch
    • Default: sensor

    The state the entity should be updated to

    Home Assistant Config

    • Type: Object

    Configuration options available for the selected entity

    WARNING

    Entity nodes will not work in a subflow due to the way they register themselves with Home Assistant. After a Node-RED restart, a new entity will be created in Home Assistant.

    Sensor Configuration

    State required

    • Type: string | number | boolean

    The state the entity should be updated to

    Attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    Input Override

    • Type: string
    • Values: accept | merge | block

    Determine how input values will be handled. When merge is selected the message object values will override the configuration values.

    Resend state and attributes

    • Type: boolean

    When creating the entity in Home Assistant this will also send the last updated state and attributes then node sent to Home Assistant

    Switch Configuration

    Output on state change

    • Type: boolean

    When the state of the switch changes it will output to the top if the switch is on or to the bottom if it is in the off position.

    Payload

    • Type: str | num | bool | JSONata | timestamp

    Customizable output set to msg.payload if Output on state change is enabled.

    Sensors Inputs

    properties of msg.payload

    state

    • Type: string | number | boolean

    The state the entity should be updated to

    attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    Switch Inputs

    msg.enable

    • Type: boolean

    Set to true to turn on the switch and false to turn off. If the message has a property enable set to the type boolean the node will not have any output.

    Outputs

    Status Color

    • Green/Red: output from the node was due to input to the node
    • Blue: output from the node was due to the state of the node changing
    • Yellow: state of node changed but no output
    + + + diff --git a/node/events-all.html b/node/events-all.html new file mode 100644 index 0000000000..680da7b70c --- /dev/null +++ b/node/events-all.html @@ -0,0 +1,34 @@ + + + + + + + + + Events: all | node-red-contrib-home-assistant-websocket + + + + + +

    Events: all

    Listens for all types of events from Home Assistant with the ability to filter by event type.

    Configuration

    Name

    • Type: string

    the name of the node

    Event Type

    • Type: string

    filter by event type or leave blank for all events

    DANGER

    Leaving this empty will listen for all events from Home Assistant which may overload the WebSocket message queue.

    GitHub Issue #153open in new window

    Event data

    • Type: json

    A JSON object that will be compared to the event data. If this JSON is a subset of the event data object, the event will be emitted.

    Output only after Home Assistant is running

    • Type: boolean

    What until Home Assistant has reported its state as running before outputting events. Client events will always output.

    Expose as

    • Type: entity config

    Creates a switch within Home Assistant to enable/disable this node. This feature requires Node-RED custom integrationopen in new window to be installed in Home Assistant

    Outputs

    Value types:

    • event data: event received from Home Assistant
    • config: config properties of the node

    Client Events

    Use home_assistant_client as the event type to receive events from the Websocket client.

    Events sent from the client:

    • connecting - when trying to connect to HA
    • connected - after the authorization has been accepted
    • disconnected - when the socket stops attempting to connect or disconnected after having been connected
    • error - when a disconnect happens of the WebSocket with an error
    • states_loaded - the first time all states are loaded from HA
    • services_loaded - the first time all services are loaded from HA
    • running - when HA is in a running state and states have been loaded
    + + + diff --git a/node/events-calendar.html b/node/events-calendar.html new file mode 100644 index 0000000000..6cb9a961c4 --- /dev/null +++ b/node/events-calendar.html @@ -0,0 +1,34 @@ + + + + + + + + + Events: calendar | node-red-contrib-home-assistant-websocket + + + + + +

    Events: calendar

    Outputs calendar item events similar to the calendar automation in Home Assistant

    Configuration:

    Entity ID required

    • Type: string

    The entity_id for the calendar that contains triggerable calendar items.

    Relative To required

    • Type: start | end
    • Default: start

    Whether to trigger an event at the start or end of each matching calendar item.

    Offset required

    • Type: number
    • Default: 0 seconds

    A negative or positive amount of time to allow the event to be triggered before or after the calendar item's start/end time.

    Conditions

    This node has two default outputs "allowed" and "blocked". If all the conditions are true the calendar item will be sent to the output.

    See Also:

    Expose to Home Assistant

    • Type: boolean

    Creates a switch within Home Assistant to enable/disable this node. This feature requires Node-RED custom integrationopen in new window to be installed in Home Assistant

    Outputs

    Value types:

    • calendar item: the calendar item object as provided by the Home Assistant API
    + + + diff --git a/node/events-state.html b/node/events-state.html new file mode 100644 index 0000000000..e4e665cd7f --- /dev/null +++ b/node/events-state.html @@ -0,0 +1,34 @@ + + + + + + + + + Events: state | node-red-contrib-home-assistant-websocket + + + + + +

    Events: state

    Listens for state changes of entities from Home Assistant.

    Configuration:

    Entity required

    • Type: string

    The entity ID is used to listen for state changes. This can be a entity ID, regex, or a substring. If a regex or substring is used, the node will listen for all entities that match.

    Example:

    • light.kitchen (entity) listens for state changes of the light.kitchen entity
    • ^light.* (regex) listens for state changes of all entities that start with light.
    • light (substring) listens for state changes of all entities that contain light in the entity ID

    If State

    • Type: string

    If the conditional is evaluated as true send the message to the first output otherwise send it to the second output. If blank there will only be one output.

    Also see:

    For

    • Type: number

    An amount of time an entity's state needs to be in that state before triggering.

    WARNING

    Output on Connect state changes will not start a timer.

    State Type

    • Type: string
    • Values: string|number|boolean
    • Default: string

    Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

    Ignore state change event

    • Type: boolean

    A list of possible states that will be ignored.

    Output on Connect

    • Type: boolean

    Output once on startup/deploy

    Expose to Home Assistant

    • Type: boolean

    Creates a switch within Home Assistant to enable/disable this node. This feature requires Node-RED custom integrationopen in new window to be installed in Home Assistant

    Outputs

    Value types:

    • event data: full event object
    • entity id: entity id of the triggered entity
    • entity state: entity state of the triggered entity
    • config: config properties of the node
    + + + diff --git a/node/fire-event.html b/node/fire-event.html new file mode 100644 index 0000000000..44033b5ff4 --- /dev/null +++ b/node/fire-event.html @@ -0,0 +1,34 @@ + + + + + + + + + Fire Event | node-red-contrib-home-assistant-websocket + + + + + +

    Fire Event

    Fire an event to Home Assistants event bus

    Configuration

    Event required

    • Type: string

    Event name to fire

    data

    • Type: Object

    JSON object to pass along

    Inputs

    If the incoming message has a payload property with event set it will override any config values if set. 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. If the node has a property value in its config for Merge Context then the flow and global contexts will be checked for this property which should be an object that will also be merged into the data payload.

    payload.event

    • Type: string

    Event to fire

    payload.data

    • Type: Object

    Event data to send

    Outputs

    payload.event_type

    • Type: string

    Event Type that was fired

    payload.data

    • Type: Object

    The event data sent if one was used

    References

    Home Assistant Eventsopen in new window

    + + + diff --git a/node/get-entities.html b/node/get-entities.html new file mode 100644 index 0000000000..2b26fa433d --- /dev/null +++ b/node/get-entities.html @@ -0,0 +1,57 @@ + + + + + + + + + Get Entities | node-red-contrib-home-assistant-websocket + + + + + +

    Get Entities

    Get Entities based on search criteria

    Configuration

    Search Criteria

    All search criteria have to be true for an entity to be valid.

    Property

    Has autocompleted with all properties currently set on all loaded entities.

    Inputs

    payload

    • Type: Object

    Override config values by passing in a property with a valid value.

    • rules array
      • property string
      • logic string
      • value string
      • valueType string
    • outputType string
    • outputEmptyResults boolean
    • outputLocationType string
    • outputLocation string
    • outputResultscount number

    Outputs

    Array

    • Type: Array

    Sends an array of state objects from search criteria to the Output Location.

    Count

    • Type: number

    Return the total count of valid entities.

    Random

    • Type: Object|Array

    Return a random object or array from the available state objects to the Output Location. When One Max Results is selected it will return an object and when more than one is selected will always return an array of state objects.

    Split

    • Type: msg part

    Sends a message for each state object. In the same format as if the split node was used.

    State Object Format

    Sample output when the Output Type is an array:

    [
    +  {
    +    "entity_id": "light.kitchen",
    +    "state": "on",
    +    "attributes": {
    +      "brightness": 243,
    +      "friendly_name": "Kitchen Light",
    +      "supported_features": 33,
    +      "icon": "mdi:light-switch"
    +    },
    +    "last_changed": "2019-12-29T05:38:53.016984+00:00",
    +    "last_updated": "2019-12-29T05:38:53.016984+00:00",
    +    "context": {
    +      "id": "6c16e348494c42fb8c8e8bda92b20fb2",
    +      "parent_id": null,
    +      "user_id": null
    +    },
    +    "timeSinceChangedMs": 3466747
    +  }
    +]
    +

    entity_id

    • Type: string

    The entity to which this state belongs

    state

    • Type: string

    Main attribute state value, examples: 'on', 'off', 'home', 'open', 'closed', etc...

    attributes

    • Type: Object

    Supported attributes of state set by Home Assistant

    last_changed

    • Type: string

    ISO Date string of last time entity state changed

    timeSinceChangedMs

    • Type: number

    Milliseconds since last time entity state changed

    last_updated

    • Type: string

    ISO Date string of last time entity state was updated

    context

    • Type: Object

    Information on who/what changed the state of this object last.

    Examples

    Example 1

    You have a presence detection of some sort running in Home Assistant and you want to get a notification when you leave if any doors or windows are left open.

    Using the get entities node here to get a possible list of entity ids [binary_sensor.front_door, binary_sensor.back_door, binary_sensor.front_window, binary_sensor.back_window] if their state is equal to open. The entities are returned with the output Split. This means that a message is sent for each valid entity. We then are using a template node to format the payload into the entity friendly name and joining them back into one payload using the join node.

    screenshot

    [{"id":"dafa6c83.24e07","type":"trigger-state","z":"7f24e6b8.eab548","name":"Left Home","entityid":"device_tracker.jason","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"id":"9i2c9sz7d3e","targetType":"this_entity","targetValue":"","propertyType":"previous_state","propertyValue":"old_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"home"},{"id":"3h3lghs8xsm","targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"not_home"}],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":230,"y":192,"wires":[["42dd6dce.c48ce4"],[]]},{"id":"42dd6dce.c48ce4","type":"ha-get-entities","z":"7f24e6b8.eab548","name":"","rules":[{"property":"entity_id","logic":"includes","value":"binary_sensor.front_door,binary_sensor.back_door,binary_sensor.front_window,binary_sensor.back_window","valueType":"str"},{"property":"state","logic":"is","value":"open","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":396,"y":192,"wires":[["301b2b51.48b104"]]},{"id":"301b2b51.48b104","type":"template","z":"7f24e6b8.eab548","name":"Format Friendly Name","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{payload.attributes.friendly_name}}","output":"str","x":600,"y":192,"wires":[["8ed935f8.afbad8"]]},{"id":"8ed935f8.afbad8","type":"join","z":"7f24e6b8.eab548","name":"","mode":"custom","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":",","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":770,"y":192,"wires":[["454131f7.c19f"]]},{"id":"454131f7.c19f","type":"api-call-service","z":"7f24e6b8.eab548","name":"Notify","version":1,"debugenabled":false,"service_domain":"notify","service":"push_jason","entityId":"","data":"{\"message\": \"The {{payload}} are open.\",\"title\": \"Left Open\"}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":898,"y":192,"wires":[[]]}]
    +

    Example 2

    Sort of a Vacation or Away script to randomly turn on some lights around your home.

    Using an inject node here but you could use your preference of timer node. The get entities node is randomly choosing one entity from the criteria where entity_id starts with light..

    screenshot

    [{"id":"39342a95.8db3d6","type":"inject","z":"c86782e1.cf429","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":252,"y":256,"wires":[["e9038030.b79e4"]]},{"id":"e9038030.b79e4","type":"ha-get-entities","z":"c86782e1.cf429","name":"","rules":[{"property":"entity_id","logic":"starts_with","value":"light.","valueType":"str"}],"output_type":"random","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":402,"y":256,"wires":[["2586f129.6136fe"]]},{"id":"58c67712.8aa4a8","type":"delay","z":"c86782e1.cf429","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"20","randomLast":"30","randomUnits":"minutes","drop":false,"x":732,"y":256,"wires":[["986369ca.af3f48"]]},{"id":"2586f129.6136fe","type":"api-call-service","z":"c86782e1.cf429","name":"Turn on Light","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":562,"y":256,"wires":[["58c67712.8aa4a8"]]},{"id":"986369ca.af3f48","type":"api-call-service","z":"c86782e1.cf429","name":"Turn off Light","version":"1","debugenabled":false,"service_domain":"light","service":"turn_off","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":898,"y":256,"wires":[[]]}]
    +

    Example 3

    On Reddit the other day a user posted this How can I join 1 to 4 pre-defined messages together based on 4 separate entity states?open in new window (Their solution can be found in the post)

    Here's my take on it using the get entities and a function node. Using the Array output option here.

    screenshot

    [{"id":"2bdd6fb7.15743","type":"server-state-changed","z":"3c84cc55.8f02f4","name":"","version":"1","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"binary_sensor.button_bedroom","entityidfiltertype":"substring","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"x":276,"y":224,"wires":[["c2a9ffac.1e05d"]]},{"id":"c2a9ffac.1e05d","type":"ha-get-entities","z":"3c84cc55.8f02f4","name":"","rules":[{"property":"entity_id","logic":"includes","value":"sensor.phon_charging,sensor.watch_charging,sensor.kaylas_phone_charging,lock.lock","valueType":"str"},{"property":"state","logic":"includes","value":"no,unlocked","valueType":"str"}],"output_type":"array","output_empty_results":true,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":550,"y":224,"wires":[["2950c181.1ef95e"]]},{"id":"2950c181.1ef95e","type":"function","z":"3c84cc55.8f02f4","name":"","func":"let lockFD = null;\nlet PC = false;\nlet WC = false;\nlet KP = false;\nlet FD = false;\n\nmsg.payload.forEach(entity => {\n    switch(entity.entity_id) {\n        case \"sensor.phone_charging\":\n            PC = true;\n            break;\n        case \"sensor.watch_charging\":\n            WC = true;\n            break;\n        case \"sensor.kaylas_phone_charging\":\n            KP = true;\n            break;\n        case \"lock.lock\":\n            FD = true;\n            lockFD = { payload: true };\n            break;\n    }\n    \n});\n\nlet message = \"Goodnight.\";\nif(PC && WC) {\n    message = `${message} Don’t forget to charge your phone and watch.`;\n} else {\n    message = `${message} Don’t forget to charge your ${PC ? 'phone' : 'watch'}.`\n}\nif(KP) {\n    message = `${message} Remind Kayla to charge her phone${PC ? ' too':''}.`;\n}\nif(FD) {\n    message = `${message} The door is now locked.`\n}\nmsg.payload = message;\nreturn [msg, lockFD];\n","outputs":2,"noerr":0,"x":690,"y":224,"wires":[["ca4a5643.9bf0d8"],["64374b0e.f72394"]]},{"id":"ca4a5643.9bf0d8","type":"cast-to-client","z":"3c84cc55.8f02f4","name":"","url":"","contentType":"","message":"","language":"en","ip":"192.168.1.29","port":"","volume":"40","x":874,"y":224,"wires":[[]]},{"id":"64374b0e.f72394","type":"api-call-service","z":"3c84cc55.8f02f4","name":"lock door","version":"1","debugenabled":false,"service_domain":"scene","service":"turn_on","entityId":"scene.lock_door","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":844,"y":272,"wires":[[]]}]
    +

    Disclaimer: All these examples are untested but should give you a general idea of how to use it.

    References

    + + + diff --git a/node/get-history.html b/node/get-history.html new file mode 100644 index 0000000000..327f6db425 --- /dev/null +++ b/node/get-history.html @@ -0,0 +1,78 @@ + + + + + + + + + Get History | node-red-contrib-home-assistant-websocket + + + + + +

    Get History

    Fetches history from Home Assistant (all history for the past day by default)

    Configuration

    Entity ID

    • Type: string

    The entity id to fetch history for. Can be a single entity id or a comma separated list of entity ids.

    Entity ID Type

    • Type: string
    • Values: == | regex

    The type of entity id matching to use. == will do an exact match, regex will use a regular expression to match the entity ids.

    Start Date

    • Type: string
    • Values: ISO Formattted Date
    • Default: 24 hours prior

    Date to start fetching history from. Will override the configuration if passed in. If relativetime is used this will be ignored.

    Also See:

    End Date

    • Type: string
    • Values: ISO Formattted Date
    • Default: 24 hours from start date

    The end date to fetch history too. Will override the configuration if passed in. If relativetime is used this will be ignored.

    Also See:

    Use Relative Time

    • Type: boolean

    A checkbox to use relative time or not. If checked the startdate and enddate will be ignored and the relativetime will be used instead.

    In the Last

    • Type: string

    A time string that will be parsed the following keywords into time values.

    Example: 4h 30m = The last 4 hours and 30 minutes

    ms, milli, millisecond, milliseconds - will parse to milliseconds
    +s, sec, secs, second, seconds - will parse to seconds
    +m, min, mins, minute, minutes - will parse to minutes
    +h, hr, hrs, hour, hours - will parse to hours
    +d, day, days - will parse to days
    +w, week, weeks - will parse to weeks
    +mon, mth, mths, month, months - will parse to months
    +y, yr, yrs, year, years - will parse to years
    +

    Flatten Results

    Instead of returning the data from home assistant ( array for each entity_id ) return one flattened array of one item per history entry

    Output Types

    • Type: string
    • Values: array | split
    • Default: array

    The type of output to return. array will return an array of history objects. split will return an array of history objects for each entity id.

    Inputs

    All properties of msg.payload

    entityId

    • Type: string

    entityIdType

    • Type: equal | regex

    startDate

    • Type: string
    • Values: ISO Formattted Date

    endDate

    • Type: string
    • Values: ISO Formattted Date

    relativeTime

    • Type: string

    flatten

    • Type: boolean

    Outputs

    payload

    • Type: array

    The history returned by home-assistant, which is an array of arrays where each array entry contains history objects for one particular entity

    Example output of msg:

    {
    +  "payload": [
    +    {
    +      "attributes": {
    +        "friendly_name": "Kitchen Light",
    +        "icon": "mdi:light-switch",
    +      },
    +      "context": {
    +        "id": "850e510e36fb494c9abc79e01e897d54",
    +        "parent_id": null,
    +        "user_id": null
    +      },
    +      "entity_id": "light.kitchen_light",
    +      "last_changed": "2019-12-28T06:47:28.618000+00:00",
    +      "last_updated": "2019-12-28T06:47:28.618000+00:00",
    +      "state": "off"
    +    },
    +    {
    +      "attributes": {
    +        "brightness": 28,
    +        "friendly_name": "Kitchen Light",
    +        "icon": "mdi:light-switch",
    +      },
    +      "context": {
    +        "id": "4d4abe29f2bc43dab39101193f1fefe4",
    +        "parent_id": null,
    +        "user_id": null
    +      },
    +      "entity_id": "light.kitchen_light",
    +      "last_changed": "2019-12-28T07:48:11.514137+00:00",
    +      "last_updated": "2019-12-28T07:48:11.514137+00:00",
    +      "state": "on"
    +    },
    +    ...
    +  ]
    +}
    +

    Examples

    Check if an entity was a certain state in the last 24 hours

    References

    + + + diff --git a/node/index.html b/node/index.html new file mode 100644 index 0000000000..137a722df6 --- /dev/null +++ b/node/index.html @@ -0,0 +1,34 @@ + + + + + + + + + Nodes | node-red-contrib-home-assistant-websocket + + + + + +

    Nodes

    Action

    Sends a request to Home Assistant to perform an action e.g. light.turn_on, input_select.select_option, etc.

    API

    Access all points of the WebSocket and HTTP API.

    Binary Sensor

    Creates a binary sensor entity in Home Assistant that is controlled from with Node-RED.

    Button

    Creates a button in Home Assistant that triggers a flow in Node-RED

    Current State

    Fetches the last known state for any entity on input

    Device

    Creates device automations and calls device actions

    Device Config

    Configuration node for devices added to Home Assistant

    Entity

    Creates an entity in Home Assistant which can be manipulated from this node

    Entity Config

    Configuration node for the different entity type nodes

    Events: all

    Listens for all types of events from home assistant with the ability to filter by event type

    Events: state

    Listens for state changes of entities from Home Assistant.

    Fire Event

    Fire an event on the event bus

    Get Entities

    Get entities based on search criteria with 3 different output options

    Get History

    Fetches HomeAssistant history on input

    Number

    Creates a number in Home Assistant which can be manipulated from this node.

    Poll State

    Outputs the state of an entity at regular intervals, optionally also at startup and every time the entity changes if desired

    Render Template

    Allows rendering of templates on input

    Select

    Creates a select entity in Home Assistant which can be manipulated from this node.

    Sensor

    Creates a sensor entity in Home Assistant that is controlled from with Node-RED.

    Sentence

    A sentence trigger fires when Assistopen in new window matches a sentence from a voice assistant using the default conversation agentopen in new window.

    Server Config

    Home Assistant connection configuration

    Switch

    Creates a switch entity in Home Assistant that is controlled from with Node-RED. Also allows a flow to be started from a service call.

    Tag

    Outputs when Home Assistant receives a tag scanned event for a configured tag id

    Text

    Creates a text entity in Home Assistant which can be manipulated from this node.

    Time

    A node that can be scheduled to trigger at a future date and time from a Home Assistant entity

    Trigger: state

    Much like the State Changed Node however, provides some advanced functionality around common automation use cases

    Update Config

    Allows updating of entities configuration in Home Assistant

    Wait Until

    When an input is received the node will wait until the condition is met or the timeout occurs then will pass on the last received message

    Webhook

    Outputs the data received from the created webhook in Home Assistant

    Zone

    Outputs when one of the configured entities enter or leaves one of the defined zones

    + + + diff --git a/node/number.html b/node/number.html new file mode 100644 index 0000000000..33907fbe08 --- /dev/null +++ b/node/number.html @@ -0,0 +1,35 @@ + + + + + + + + + Number | node-red-contrib-home-assistant-websocket + + + + + +

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Number

    Creates a number in Home Assistant which can be manipulated from this node.

    Configuration

    Mode required

    • Type: 'listen' | 'get' | 'set'

    The mode of the node

    Value required

    • Type: number

    The value of the entity should be updated to

    Inputs

    properties of msg.payload

    value

    • Type: number

    The value of the entity should be updated to

    Outputs

    Value types:

    • value: The value of the entity
    • previous value: The previous value of the entity
    • config: The config properties of the node

    Examples

    Usage example

    screenshot

    [{"id":"cb8c6a0579380b1e","type":"server-state-changed","z":"531844fd6e8e6b59","name":"","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"number.test_number","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"}],"x":228,"y":304,"wires":[["a0978f86513bbea9"]]},{"id":"a0978f86513bbea9","type":"debug","z":"531844fd6e8e6b59","name":"event state","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.old_state.state & \" : \" & payload.new_state.state","targetType":"jsonata","statusVal":"","statusType":"auto","x":478,"y":304,"wires":[]},{"id":"c7b45a2c6c7215d6","type":"ha-number","z":"531844fd6e8e6b59","name":"","version":1,"debugenabled":false,"inputs":0,"outputs":1,"entityConfig":"4ddebbdb83b1cef1","mode":"listen","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previous","propertyType":"msg","value":"","valueType":"previousValue"}],"x":142,"y":256,"wires":[["085546d04890ecec"]]},{"id":"085546d04890ecec","type":"debug","z":"531844fd6e8e6b59","name":"number listen","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previous & \" : \" & payload ","targetType":"jsonata","statusVal":"","statusType":"auto","x":344,"y":256,"wires":[]},{"id":"35fb409f4909de0e","type":"inject","z":"531844fd6e8e6b59","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":146,"y":112,"wires":[["61922b820eb9fd05"]]},{"id":"61922b820eb9fd05","type":"ha-number","z":"531844fd6e8e6b59","name":"","version":1,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"4ddebbdb83b1cef1","mode":"set","value":"$floor($random() * 1000) + 1","valueType":"jsonata","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previous","propertyType":"msg","value":"","valueType":"previousValue"}],"x":314,"y":112,"wires":[["2021574156db4cfc"]]},{"id":"6efeac97ac50f168","type":"inject","z":"531844fd6e8e6b59","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":146,"y":160,"wires":[["2dd5c6c8df7810e4"]]},{"id":"2dd5c6c8df7810e4","type":"api-call-service","z":"531844fd6e8e6b59","name":"","server":"","version":5,"debugenabled":false,"domain":"number","service":"set_value","areaId":[],"deviceId":[],"entityId":["number.test_number"],"data":"{\"value\": $floor($random() * 1000) + 1}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":354,"y":160,"wires":[[]]},{"id":"2021574156db4cfc","type":"debug","z":"531844fd6e8e6b59","name":"number set","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previous & \" : \" & payload ","targetType":"jsonata","statusVal":"","statusType":"auto","x":474,"y":112,"wires":[]},{"id":"25481fa7cf1f5404","type":"inject","z":"531844fd6e8e6b59","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":142,"y":208,"wires":[["3ac7d1c0fbbabd14"]]},{"id":"3ac7d1c0fbbabd14","type":"ha-number","z":"531844fd6e8e6b59","name":"","version":1,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"4ddebbdb83b1cef1","mode":"get","value":"$floor($random() * 1000) + 1","valueType":"jsonata","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"}],"x":310,"y":208,"wires":[["697b6ee286987b0d"]]},{"id":"697b6ee286987b0d","type":"debug","z":"531844fd6e8e6b59","name":"number get","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":470,"y":208,"wires":[]},{"id":"4ddebbdb83b1cef1","type":"ha-entity-config","server":"bf5874816710d0c7","deviceConfig":"","name":"test number","version":"6","entityType":"number","haConfig":[{"property":"name","value":"test number"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":"data_size"},{"property":"unit_of_measurement","value":"GiB"},{"property":"min_value","value":1},{"property":"max_value","value":1000},{"property":"step_value","value":1},{"property":"mode","value":"box"}],"resend":false,"debugEnabled":false}]
    +
    + + + diff --git a/node/poll-state.html b/node/poll-state.html new file mode 100644 index 0000000000..b3e9ac4120 --- /dev/null +++ b/node/poll-state.html @@ -0,0 +1,34 @@ + + + + + + + + + Poll State | node-red-contrib-home-assistant-websocket + + + + + +

    Poll State

    Polls for the state at regular intervals, optionally also outputting at the start and when the state changes. Useful for either alert for non-communicating devices (time since change > 1 day for example) or dashboard graphs with consistent interval charts

    Configuration

    Entity ID required

    The entity id of the entity to poll for.

    Update Interval

    • Type: number

    The amount of time between checking/sending updates.

    If State

    • Type: string

    If the conditional statement is evaluated as true send the message to the first output otherwise send it to the second output. If blank there will only be one output.

    Also see:

    State Type

    • Type: string

    Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

    Output Initially

    • Type: boolean

    Output once on startup/deploy then on each interval

    Expose to Home Assistant

    • Type: boolean

    Creates a switch within Home Assistant to enable/disable this node. This feature requires Node-RED custom integrationopen in new window to be installed in Home Assistant

    Outputs

    topic

    • Type: string

    entity_id of changed entity

    payload

    • Type: object

    The last known state of the entity

    data.timeSinceChanged

    • Type: string

    Human readable format string of time since last updated, example "1 hour ago"

    data.timeSinceChangedMs

    • Type: number

    Number of milliseconds since last changed

    References

    + + + diff --git a/node/render-template.html b/node/render-template.html new file mode 100644 index 0000000000..cb1752654d --- /dev/null +++ b/node/render-template.html @@ -0,0 +1,34 @@ + + + + + + + + + Render Template | node-red-contrib-home-assistant-websocket + + + + + +

    Render Template

    Can either set the template in the node configuration or pass in the msg.template property of the incoming message. Passing template via msg.template will override the template string set in node configuration.

    NOTE:

    The node will output any Home Assistant API errors for catching with the 'catch-all' node

    Configuration

    template

    • Type: string

    Jinja template to be rendered, discarded if msg.template is provided via input msg

    Template Location

    Customizable location to output original template

    Results

    Customizable location to output rendered template

    Inputs

    template

    • Type: string

    Jinja template to be rendered

    Outputs

    template

    • Type: string

    The original template sent to Home Assistant for rendering

    payload

    • Type: string

    The rendered template

    References

    + + + diff --git a/node/select.html b/node/select.html new file mode 100644 index 0000000000..2e73b63d38 --- /dev/null +++ b/node/select.html @@ -0,0 +1,35 @@ + + + + + + + + + Select | node-red-contrib-home-assistant-websocket + + + + + +

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Select

    Creates a select entity in Home Assistant which can be manipulated from this node.

    Configuration

    Mode required

    • Type: 'listen' | 'get' | 'set'

    The mode of the node

    value required

    • Type: string

    A string to the set current value of the select entity

    Inputs

    properties of msg.payload

    Value

    • Type: string

    The string of the text entity should be updated to

    Outputs

    Value types:

    • value: The text string of the entity
    • previous value: The previous text string of the entity
    • config: The config properties of the node

    Examples

    Usage example

    screenshot

    [{"id":"4321a3f756b4e04b","type":"ha-select","z":"489afaacb01df108","name":"","version":1,"debugenabled":false,"inputs":0,"outputs":1,"entityConfig":"be77e3a6884158eb","mode":"listen","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previousValue","propertyType":"msg","value":"","valueType":"previousValue"}],"x":94,"y":192,"wires":[["61e5b7c1daa37965"]]},{"id":"a8c7a4ebf79bc26a","type":"ha-select","z":"489afaacb01df108","name":"","version":1,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"be77e3a6884158eb","mode":"set","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previousValue","propertyType":"msg","value":"","valueType":"previousValue"}],"x":290,"y":416,"wires":[[]]},{"id":"61e5b7c1daa37965","type":"debug","z":"489afaacb01df108","name":"select in","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previousValue& \" : \" & payload","targetType":"jsonata","statusVal":"","statusType":"auto","x":388,"y":192,"wires":[]},{"id":"1c519ae737aa6361","type":"inject","z":"489afaacb01df108","name":"invalid option","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"invalid option!!!!","payloadType":"str","x":134,"y":416,"wires":[["a8c7a4ebf79bc26a"]]},{"id":"e0feb133879bf8aa","type":"inject","z":"489afaacb01df108","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":114,"y":320,"wires":[["3c6ef2defe605b5e"]]},{"id":"3c6ef2defe605b5e","type":"api-call-service","z":"489afaacb01df108","name":"","server":"","version":5,"debugenabled":false,"domain":"select","service":"select_next","areaId":[],"deviceId":[],"entityId":["select.test_select"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":330,"y":320,"wires":[[]]},{"id":"dee53ca19e7262f9","type":"server-state-changed","z":"489afaacb01df108","name":"","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"select.test_select","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":174,"y":240,"wires":[["b592f430a286d9d3"]]},{"id":"b592f430a286d9d3","type":"debug","z":"489afaacb01df108","name":"event state","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"data.old_state.state & \" : \" & payload","targetType":"jsonata","statusVal":"","statusType":"auto","x":398,"y":240,"wires":[]},{"id":"8425ced98c4ef688","type":"ha-select","z":"489afaacb01df108","name":"","version":1,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"be77e3a6884158eb","mode":"set","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previousValue","propertyType":"msg","value":"","valueType":"previousValue"}],"x":542,"y":368,"wires":[["7668a7159575359b"]]},{"id":"ece11ecf7eeedf69","type":"inject","z":"489afaacb01df108","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":114,"y":368,"wires":[["2944cc4f94c015fa"]]},{"id":"7668a7159575359b","type":"debug","z":"489afaacb01df108","name":"select out","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previousValue& \" : \" & payload","targetType":"jsonata","statusVal":"","statusType":"auto","x":684,"y":368,"wires":[]},{"id":"2944cc4f94c015fa","type":"api-current-state","z":"489afaacb01df108","name":"random option","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"select.test_select","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"( \t  $c := $entity().state;\t  $a := function($acc, $val){$c = $val ? $acc : $append($acc, $val)};\t  $r := $shuffle($entity().attributes.options);\t$reduce($r, $a, [])[0]\t)","valueType":"jsonata"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":320,"y":368,"wires":[["8425ced98c4ef688"]]},{"id":"1ebc7b227317b6c0","type":"ha-update-config","z":"489afaacb01df108","name":"","server":"bf5874816710d0c7","entityConfig":"be77e3a6884158eb","version":0,"outputProperties":[],"x":320,"y":560,"wires":[[]]},{"id":"8ea8951f4193e413","type":"inject","z":"489afaacb01df108","name":"1,2,3","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"options\": [\"1\",\"2\",\"3\"]}","payloadType":"json","x":110,"y":560,"wires":[["1ebc7b227317b6c0"]]},{"id":"2b4b5b649e5a03b5","type":"inject","z":"489afaacb01df108","name":"random strings","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"(\t  $charSet := [\t    \"a\",\t    \"b\",\t    \"c\",\t    \"d\",\t    \"e\",\t    \"f\",\t    \"g\",\t    \"h\",\t    \"i\",\t    \"j\",\t    \"k\",\t    \"l\",\t    \"m\",\t    \"n\",\t    \"o\",\t    \"p\",\t    \"q\",\t    \"r\",\t    \"s\",\t    \"t\",\t    \"u\",\t    \"v\",\t    \"w\",\t    \"x\",\t    \"y\",\t    \"z\",\t    \"A\",\t    \"B\",\t    \"C\",\t    \"D\",\t    \"E\",\t    \"F\",\t    \"G\",\t    \"H\",\t    \"I\",\t    \"J\",\t    \"K\",\t    \"L\",\t    \"M\",\t    \"N\",\t    \"O\",\t    \"P\",\t    \"Q\",\t    \"R\",\t    \"S\",\t    \"T\",\t    \"U\",\t    \"V\",\t    \"W\",\t    \"X\",\t    \"Y\",\t    \"Z\",\t    \"0\",\t    \"1\",\t    \"2\",\t    \"3\",\t    \"4\",\t    \"5\",\t    \"6\",\t    \"7\",\t    \"8\",\t    \"9\",\t    \"!\",\t    \"-\"\t];  \t  $randomChar := function(){\t      (\t          $randomCharChosen := $floor($random()* $count($charSet));\t          $charSet[$randomCharChosen];        \t      )\t  };\t \t\t{\t    \"options\": [\t        $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\t        $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\t        $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\t        $reduce([0..10],function($v,$i){( $v & $randomChar();)}),\t        $reduce([0..10],function($v,$i){( $v & $randomChar();)})\t    ]\t}\t)","payloadType":"jsonata","x":140,"y":608,"wires":[["1ebc7b227317b6c0"]]},{"id":"a5d80ae6c463f4b8","type":"comment","z":"489afaacb01df108","name":"dynamically set options","info":"","x":148,"y":512,"wires":[]},{"id":"a0d398b3cdb34f01","type":"ha-select","z":"489afaacb01df108","name":"","version":1,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"be77e3a6884158eb","mode":"get","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"}],"x":290,"y":464,"wires":[["a7d33552113d6890"]]},{"id":"486e85c613ec63f5","type":"inject","z":"489afaacb01df108","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":114,"y":464,"wires":[["a0d398b3cdb34f01"]]},{"id":"a7d33552113d6890","type":"debug","z":"489afaacb01df108","name":"select get","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":432,"y":464,"wires":[]},{"id":"be77e3a6884158eb","type":"ha-entity-config","server":"bf5874816710d0c7","deviceConfig":"","name":"test select","version":"6","entityType":"select","haConfig":[{"property":"name","value":"test select"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"options","value":["def","abc","132"]}],"resend":false,"debugEnabled":false}]
    +
    + + + diff --git a/node/sensor.html b/node/sensor.html new file mode 100644 index 0000000000..6553803fbd --- /dev/null +++ b/node/sensor.html @@ -0,0 +1,34 @@ + + + + + + + + + Sensor | node-red-contrib-home-assistant-websocket + + + + + +

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Sensor

    Creates a sensor in Home Assistant which can be manipulated from this node.

    Configuration

    State required

    • Type: string | number | boolean

    The state the entity should be updated to

    To set the Home Assistant state to Unknown, send a state with a js expression null.

    Attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    Input Override

    • Type: string
    • Values: accept | merge | block

    Determine how input values will be handled. When merge is selected the message object values will override the configuration values.

    Resend state and attributes

    • Type: boolean

    When creating the entity in Home Assistant this will also send the last updated state and attributes then node sent to Home Assistant

    Inputs

    properties of msg.payload

    state

    • Type: string | number | boolean

    The state the entity should be updated to

    attributes

    • Type: Object

    Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]

    + + + diff --git a/node/sentence.html b/node/sentence.html new file mode 100644 index 0000000000..73b38fc5db --- /dev/null +++ b/node/sentence.html @@ -0,0 +1,35 @@ + + + + + + + + + Sentence | node-red-contrib-home-assistant-websocket + + + + + +

    Sentence

    A sentence trigger fires when Assistopen in new window matches a sentence from a voice assistant using the default conversation agentopen in new window.

    Sentences are allowed to use some basic template syntax. Check Home Assistant documentationopen in new window for more information.

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Configuration

    Sentences

    • Type: string

    A list of sentences to match. Sentences are allowed to use some basic template syntax. Check Home Assistant documentationopen in new window for more information.

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • trigger id: sentence that triggered the flow
    • config: config properties of the node

    Examples

    screenshot

    [{"id":"2f10cb78ab2f486f","type":"debug","z":"39a6dba4b503e011","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"msg","x":382,"y":384,"wires":[]},{"id":"5c563c29d19f4aab","type":"ha-sentence","z":"39a6dba4b503e011","name":"","server":"bf5874816710d0c7","version":0,"outputs":1,"sentences":["[it's ]party time","happy (new year|birthday)","hello world"],"outputProperties":[{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"payload","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"sentences","propertyType":"msg","value":"sentences","valueType":"config"}],"x":176,"y":384,"wires":[["2f10cb78ab2f486f"]]},{"id":"4868b36e0e57db4f","type":"api-call-service","z":"39a6dba4b503e011","name":"process sentence","server":"","version":5,"debugenabled":false,"domain":"conversation","service":"process","areaId":[],"deviceId":[],"entityId":[],"data":"   {\"text\": payload}\t","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":422,"y":336,"wires":[[]]},{"id":"0bd711e6ab321cf9","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"happy new year","payloadType":"str","x":200,"y":336,"wires":[["4868b36e0e57db4f"]]},{"id":"7b19f1bcd79bf7ea","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"happy birthday","payloadType":"str","x":204,"y":288,"wires":[["4868b36e0e57db4f"]]},{"id":"fdec3314ea56130d","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"party time","payloadType":"str","x":184,"y":240,"wires":[["4868b36e0e57db4f"]]},{"id":"92aa9c7e046ebba3","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"it's party time","payloadType":"str","x":198,"y":192,"wires":[["4868b36e0e57db4f"]]},{"id":"4c1ecc1396d9eddf","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"hello world","payloadType":"str","x":188,"y":144,"wires":[["4868b36e0e57db4f"]]}]
    +
    + + + diff --git a/node/switch.html b/node/switch.html new file mode 100644 index 0000000000..9c04c77653 --- /dev/null +++ b/node/switch.html @@ -0,0 +1,35 @@ + + + + + + + + + Switch | node-red-contrib-home-assistant-websocket + + + + + +

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Switch

    Creates a switch in Home Assistant which can be manipulated from this node.

    Configuration

    Enable input

    Input is disabled by default. It can be enabled by checking this option.

    Output on state change

    • Type: boolean

    When the state of the switch changes it will output to the top if the switch is on or to the bottom if it is in the off position.

    Inputs

    msg.enable

    • Type: boolean

    Set to true to turn on the switch and false to turn it off. If the message has a property enable defined and set to a boolean the node will not have any output.

    Outputs

    Status Color

    • Green/Red: output from the node was due to input to the node
    • Blue: output from the node was due to the state of the node changing
    • Yellow: state of node changed but no output

    Examples

    Usage example

    screenshot

    [{"id":"fab7baeb7be8c516","type":"debug","z":"c84b6e0a642a4bce","name":"on b","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":434,"y":1072,"wires":[]},{"id":"85438e0d960024f9","type":"api-call-service","z":"c84b6e0a642a4bce","name":"","server":"","version":5,"debugenabled":false,"domain":"nodered","service":"trigger","areaId":[],"deviceId":[],"entityId":["switch.switch_test"],"data":"{\"payload\": \"i am the payload\"}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":320,"y":1216,"wires":[[]]},{"id":"026d576cab2ba685","type":"inject","z":"c84b6e0a642a4bce","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":132,"y":1216,"wires":[["85438e0d960024f9"]]},{"id":"ecc4cf9f7bed0a46","type":"debug","z":"c84b6e0a642a4bce","name":"off b","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":434,"y":1120,"wires":[]},{"id":"489165f36ed911cf","type":"api-call-service","z":"c84b6e0a642a4bce","name":"","server":"","version":5,"debugenabled":false,"domain":"switch","service":"toggle","areaId":[],"deviceId":[],"entityId":["switch.switch_test"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":326,"y":832,"wires":[[]]},{"id":"7e026638397d33b7","type":"inject","z":"c84b6e0a642a4bce","name":"toggle switch state","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":832,"wires":[["489165f36ed911cf"]]},{"id":"aa7e8ed024dab3c8","type":"server-state-changed","z":"c84b6e0a642a4bce","name":"","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"switch.switch_test","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[],"x":204,"y":784,"wires":[[]]},{"id":"657d91f04b24f723","type":"inject","z":"c84b6e0a642a4bce","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":132,"y":1120,"wires":[["b85c010f7e098b73"]]},{"id":"baac3eb05828d07e","type":"inject","z":"c84b6e0a642a4bce","name":"enable","props":[{"p":"enable","v":"true","vt":"bool"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":126,"y":1024,"wires":[["b85c010f7e098b73"]]},{"id":"051cdb052c6f99db","type":"inject","z":"c84b6e0a642a4bce","name":"disable","props":[{"p":"enable","v":"false","vt":"bool"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":126,"y":1072,"wires":[["b85c010f7e098b73"]]},{"id":"b85c010f7e098b73","type":"ha-switch","z":"c84b6e0a642a4bce","name":"","version":0,"debugenabled":false,"inputs":1,"outputs":2,"entityConfig":"9236992af61f2695","enableInput":true,"outputOnStateChange":false,"outputProperties":[{"property":"topic","propertyType":"msg","value":"state change","valueType":"str"},{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"$entity()","valueType":"jsonata"}],"x":294,"y":1072,"wires":[["fab7baeb7be8c516"],["ecc4cf9f7bed0a46"]]},{"id":"6c90e6c00caee078","type":"debug","z":"c84b6e0a642a4bce","name":"on a","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":434,"y":928,"wires":[]},{"id":"b57fa2a7ad97b2eb","type":"debug","z":"c84b6e0a642a4bce","name":"off a","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":434,"y":976,"wires":[]},{"id":"238e849949f437e6","type":"inject","z":"c84b6e0a642a4bce","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":132,"y":976,"wires":[["a6736ba07743d64e"]]},{"id":"74d43743ff8f07b3","type":"inject","z":"c84b6e0a642a4bce","name":"enable","props":[{"p":"enable","v":"true","vt":"bool"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":118,"y":880,"wires":[["a6736ba07743d64e"]]},{"id":"d1d4b53d44caeb92","type":"inject","z":"c84b6e0a642a4bce","name":"disable","props":[{"p":"enable","v":"false","vt":"bool"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":122,"y":928,"wires":[["a6736ba07743d64e"]]},{"id":"a6736ba07743d64e","type":"ha-switch","z":"c84b6e0a642a4bce","name":"","version":0,"debugenabled":false,"inputs":1,"outputs":2,"entityConfig":"9236992af61f2695","enableInput":true,"outputOnStateChange":true,"outputProperties":[{"property":"topic","propertyType":"msg","value":"state change","valueType":"str"},{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"state","propertyType":"msg","value":"$entity().state = true ? \"on\" : \"off\"","valueType":"jsonata"}],"x":294,"y":928,"wires":[["6c90e6c00caee078"],["b57fa2a7ad97b2eb"]]},{"id":"1f28cd07093de4bf","type":"comment","z":"c84b6e0a642a4bce","name":"outputs on state change","info":"","x":344,"y":880,"wires":[]},{"id":"bc15274098491edc","type":"comment","z":"c84b6e0a642a4bce","name":"does not output on state change","info":"","x":374,"y":1024,"wires":[]},{"id":"7d848a75391906d1","type":"comment","z":"c84b6e0a642a4bce","name":"use nodered.trigger service","info":"","x":350,"y":1168,"wires":[]},{"id":"9236992af61f2695","type":"ha-entity-config","server":"e120e5718cc68a9a","deviceConfig":"_ADD_","name":"switch test","version":"6","entityType":"switch","haConfig":[{"property":"name","value":"switch test"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":"switch"}],"resend":false}]
    +
    + + + diff --git a/node/tag.html b/node/tag.html new file mode 100644 index 0000000000..ad5ab41511 --- /dev/null +++ b/node/tag.html @@ -0,0 +1,34 @@ + + + + + + + + + Tag | node-red-contrib-home-assistant-websocket + + + + + +

    Tag

    Sends an output when Home Assistant receives a tag scanned event for a configured tag id.

    Configuration

    Tags

    • Type: array

    An array of tag ids to monitor for tag scanned events.

    Devices

    • Type: array

    An array of device ids to check when a configured tag is scanned.

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • event data: full event object
    • tag id: tag id of the tag that was scanned.
    • config: config properties of the node

    event object

    • Type: object
    FieldDescription
    device_idID of the device that scanned the tag
    tag_idID of the tag that was scanned
    tag_nameHome Assistant name of the tag that was scanned
    user_idHome Assistant user ID on device that scanned the tag
    + + + diff --git a/node/text.html b/node/text.html new file mode 100644 index 0000000000..5895c3a60e --- /dev/null +++ b/node/text.html @@ -0,0 +1,35 @@ + + + + + + + + + Text | node-red-contrib-home-assistant-websocket + + + + + +

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Text

    Creates a text entity in Home Assistant which can be manipulated from this node.

    Configuration

    Mode required

    • Type: 'listen' | 'get' | 'set'

    The mode of the node

    Text required

    • Type: string

    The string of the entity should be updated to

    Inputs

    properties of msg.payload

    Text

    • Type: string

    The string of the text entity should be updated to

    Outputs

    Value types:

    • value: The text string of the entity
    • previous value: The previous text string of the entity
    • config: The config properties of the node

    Examples

    Usage example

    screenshot

    [{"id":"dfc9e6f2b6ed5571","type":"inject","z":"22cd01e6b12bd120","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":114,"y":112,"wires":[["87c9fa353286db95"]]},{"id":"87c9fa353286db95","type":"function","z":"22cd01e6b12bd120","name":"random string","func":"msg.payload = Math.random().toString(36).substring(2, 10);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":296,"y":112,"wires":[["f2a130d21700183b"]]},{"id":"871c3d4514b6adf5","type":"debug","z":"22cd01e6b12bd120","name":"text listen","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previous & \" : \" & payload ","targetType":"jsonata","statusVal":"","statusType":"auto","x":276,"y":208,"wires":[]},{"id":"19ba2e97602e8052","type":"ha-text","z":"22cd01e6b12bd120","name":"","version":1,"debugenabled":false,"inputs":0,"outputs":1,"entityConfig":"541bfa3ffd06ec54","mode":"listen","value":"","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previous","propertyType":"msg","value":"","valueType":"previousValue"}],"x":118,"y":208,"wires":[["871c3d4514b6adf5"]]},{"id":"f2a130d21700183b","type":"ha-text","z":"22cd01e6b12bd120","name":"","version":1,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"541bfa3ffd06ec54","mode":"set","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previous","propertyType":"msg","value":"","valueType":"previousValue"}],"x":458,"y":112,"wires":[["abf17eb28388908a"]]},{"id":"abf17eb28388908a","type":"debug","z":"22cd01e6b12bd120","name":"text set","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previous & \" : \" & payload ","targetType":"jsonata","statusVal":"","statusType":"auto","x":628,"y":112,"wires":[]},{"id":"cfdda78a4cc69c43","type":"server-state-changed","z":"22cd01e6b12bd120","name":"","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"text.test_text","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"previous","propertyType":"msg","value":"","valueType":"eventData"}],"x":184,"y":256,"wires":[["ad7370fad9297783"]]},{"id":"ad7370fad9297783","type":"debug","z":"22cd01e6b12bd120","name":"event state","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previous.old_state.state & \" : \" & payload","targetType":"jsonata","statusVal":"","statusType":"auto","x":422,"y":256,"wires":[]},{"id":"2a2de323bc72c720","type":"inject","z":"22cd01e6b12bd120","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":114,"y":64,"wires":[["f888cc8fd9e941d4"]]},{"id":"c29c8b6386defada","type":"api-call-service","z":"22cd01e6b12bd120","name":"","server":"","version":5,"debugenabled":false,"domain":"text","service":"set_value","areaId":[],"deviceId":[],"entityId":["text.test_text"],"data":"{\"value\": payload }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":488,"y":64,"wires":[[]]},{"id":"f888cc8fd9e941d4","type":"function","z":"22cd01e6b12bd120","name":"random string","func":"msg.payload = Math.random().toString(36).substring(2, 10);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":296,"y":64,"wires":[["c29c8b6386defada"]]},{"id":"834d55ad3daf03df","type":"inject","z":"22cd01e6b12bd120","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":114,"y":160,"wires":[["9fba568d70b10862"]]},{"id":"9fba568d70b10862","type":"ha-text","z":"22cd01e6b12bd120","name":"","version":1,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"541bfa3ffd06ec54","mode":"get","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previous","propertyType":"msg","value":"","valueType":"previousValue"}],"x":458,"y":160,"wires":[["c2cfe2d328d54aa3"]]},{"id":"c2cfe2d328d54aa3","type":"debug","z":"22cd01e6b12bd120","name":"text get","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previous & \" : \" & payload ","targetType":"jsonata","statusVal":"","statusType":"auto","x":628,"y":160,"wires":[]},{"id":"541bfa3ffd06ec54","type":"ha-entity-config","server":"bf5874816710d0c7","deviceConfig":"","name":"test text","version":"6","entityType":"text","haConfig":[{"property":"name","value":"test text"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"mode","value":"text"},{"property":"min_length","value":""},{"property":"max_length","value":""},{"property":"pattern","value":""}],"resend":false,"debugEnabled":false}]
    +
    + + + diff --git a/node/time-entity.html b/node/time-entity.html new file mode 100644 index 0000000000..4ea391a08e --- /dev/null +++ b/node/time-entity.html @@ -0,0 +1,35 @@ + + + + + + + + + Time | node-red-contrib-home-assistant-websocket + + + + + +

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Time

    Creates a time entity in Home Assistant which can be manipulated from this node or Home Assistant.

    Configuration

    Mode required

    • Type: 'listen' | 'get' | 'set'

    The mode of the node

    Value required

    • Type: string
    • Format: HH:mm:ss | HH:mm

    The value of the entity should be updated to

    Inputs

    properties of msg.payload

    value

    • Type: string
    • Format: HH:mm:ss | HH:mm

    The value of the entity should be updated to

    Outputs

    Value types:

    • value: The value of the entity
    • previous value: The previous value of the entity
    • config: The config properties of the node

    Examples

    Usage example

    screenshot

    [{"id":"5a3098079cfdd280","type":"server-state-changed","z":"7f704f92ee3c3f87","name":"","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"time.time_test","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"eventData"}],"x":216,"y":624,"wires":[["af4b36c8422aec66"]]},{"id":"af4b36c8422aec66","type":"debug","z":"7f704f92ee3c3f87","name":"event state","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.old_state.state & \" : \" & payload.new_state.state","targetType":"jsonata","statusVal":"","statusType":"auto","x":522,"y":624,"wires":[]},{"id":"2f80e30a8dc150d8","type":"debug","z":"7f704f92ee3c3f87","name":"time listen","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previousValue & \" : \" & payload ","targetType":"jsonata","statusVal":"","statusType":"auto","x":508,"y":576,"wires":[]},{"id":"1a40e5a4d0f530d2","type":"inject","z":"7f704f92ee3c3f87","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":154,"y":336,"wires":[["621d17a1e3fbb9a5"]]},{"id":"4c727df1bc583e44","type":"api-call-service","z":"7f704f92ee3c3f87","name":"","server":"","version":5,"debugenabled":false,"domain":"time","service":"set_value","areaId":[],"deviceId":[],"entityId":["time.time_test"],"data":"{\"time\": payload}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":528,"y":480,"wires":[[]]},{"id":"2a4a0d5fc9bb8d86","type":"debug","z":"7f704f92ee3c3f87","name":"time set","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"previousValue & \" : \" & payload ","targetType":"jsonata","statusVal":"","statusType":"auto","x":636,"y":336,"wires":[]},{"id":"f3b9c9fb22295113","type":"inject","z":"7f704f92ee3c3f87","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":154,"y":528,"wires":[["d5731b07e4893926"]]},{"id":"276afdfb58fe76f1","type":"debug","z":"7f704f92ee3c3f87","name":"time get","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":508,"y":528,"wires":[]},{"id":"8954ce09cca90f63","type":"ha-time-entity","z":"7f704f92ee3c3f87","name":"listen time","version":0,"debugenabled":false,"inputs":0,"outputs":1,"entityConfig":"fa434795e5d1be74","mode":"listen","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previousValue","propertyType":"msg","value":"","valueType":"previousValue"}],"x":156,"y":576,"wires":[["2f80e30a8dc150d8"]]},{"id":"d5731b07e4893926","type":"ha-time-entity","z":"7f704f92ee3c3f87","name":"get time","version":0,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"fa434795e5d1be74","mode":"get","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"}],"x":290,"y":528,"wires":[["276afdfb58fe76f1"]]},{"id":"fa09042625445217","type":"ha-time-entity","z":"7f704f92ee3c3f87","name":"set time","version":0,"debugenabled":false,"inputs":1,"outputs":1,"entityConfig":"fa434795e5d1be74","mode":"set","value":"payload","valueType":"msg","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"value"},{"property":"previousValue","propertyType":"msg","value":"","valueType":"previousValue"}],"x":494,"y":336,"wires":[["2a4a0d5fc9bb8d86"]]},{"id":"458c8d233a9d18af","type":"inject","z":"7f704f92ee3c3f87","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":155,"y":288,"wires":[["74d5dc5ff4d3c0cb"]]},{"id":"9c23cc9f504fa4a1","type":"link in","z":"7f704f92ee3c3f87","name":"HH:MM:SS","links":[],"x":156,"y":192,"wires":[["7e92542f4ff33de0"]],"l":true},{"id":"cd50b5472f373ad6","type":"link in","z":"7f704f92ee3c3f87","name":"HH:MM","links":[],"x":146,"y":240,"wires":[["801e1e33127e8d4c"]],"l":true},{"id":"7e92542f4ff33de0","type":"function","z":"7f704f92ee3c3f87","name":"generate time HH:MM:SS","func":"const randomHour = Math.floor(Math.random() * 24);\nconst randomMinute = Math.floor(Math.random() * 60);\nconst randomSecond = Math.floor(Math.random() * 60);\n\nmsg.payload = `${randomHour}:${randomMinute\n    .toString()\n    .padStart(2, '0')}:${randomSecond.toString().padStart(2, '0')}`;\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":351,"y":192,"wires":[["1b78615c029b6dab"]]},{"id":"801e1e33127e8d4c","type":"function","z":"7f704f92ee3c3f87","name":"generate time HH:MM","func":"const randomHour = Math.floor(Math.random() * 24);\nconst randomMinute = Math.floor(Math.random() * 60);\n\nmsg.payload = `${randomHour}:${randomMinute\n    .toString()\n    .padStart(2, '0')}`;\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":341,"y":240,"wires":[["cc16260a68095e77"]]},{"id":"1b78615c029b6dab","type":"link out","z":"7f704f92ee3c3f87","name":"link out 1","mode":"return","links":[],"x":519,"y":192,"wires":[]},{"id":"cc16260a68095e77","type":"link out","z":"7f704f92ee3c3f87","name":"link out 2","mode":"return","links":[],"x":519,"y":240,"wires":[]},{"id":"74d5dc5ff4d3c0cb","type":"link call","z":"7f704f92ee3c3f87","name":"","links":["9c23cc9f504fa4a1"],"linkType":"static","timeout":"30","x":310,"y":288,"wires":[["fa09042625445217"]]},{"id":"621d17a1e3fbb9a5","type":"link call","z":"7f704f92ee3c3f87","name":"","links":["cd50b5472f373ad6"],"linkType":"static","timeout":"30","x":300,"y":336,"wires":[["fa09042625445217"]]},{"id":"decebfa96ff2b375","type":"inject","z":"7f704f92ee3c3f87","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":154,"y":480,"wires":[["5e44eb1c1de80d82"]]},{"id":"34e9926f8d967e47","type":"inject","z":"7f704f92ee3c3f87","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":154,"y":432,"wires":[["e711fd4eb0f21d6f"]]},{"id":"e711fd4eb0f21d6f","type":"link call","z":"7f704f92ee3c3f87","name":"","links":["9c23cc9f504fa4a1"],"linkType":"static","timeout":"30","x":310,"y":432,"wires":[["4c727df1bc583e44"]]},{"id":"5e44eb1c1de80d82","type":"link call","z":"7f704f92ee3c3f87","name":"","links":["cd50b5472f373ad6"],"linkType":"static","timeout":"30","x":300,"y":480,"wires":[["4c727df1bc583e44"]]},{"id":"861b8a79994a76cd","type":"inject","z":"7f704f92ee3c3f87","name":"invalid","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"invalid","payloadType":"str","x":153,"y":384,"wires":[["fa09042625445217"]]},{"id":"fa434795e5d1be74","type":"ha-entity-config","server":"bf5874816710d0c7","deviceConfig":"65bf2a1a7e89a8d9","name":"time test","version":"6","entityType":"time","haConfig":[{"property":"name","value":"time test"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""}],"resend":false,"debugEnabled":false},{"id":"65bf2a1a7e89a8d9","type":"ha-device-config","name":"test device","hwVersion":"","manufacturer":"Node-RED","model":"","swVersion":""}]
    +
    + + + diff --git a/node/time.html b/node/time.html new file mode 100644 index 0000000000..a3f5f3b3ed --- /dev/null +++ b/node/time.html @@ -0,0 +1,34 @@ + + + + + + + + + Time | node-red-contrib-home-assistant-websocket + + + + + +

    Time

    A node that can be scheduled to trigger at a future date and time from a Home Assistant entity.

    Configuration

    Entity Id

    • Type: string

    A Home Assistant entity to be used when scheduling the node.

    Property

    • Type: string

    Which property of the entity object to use to schedule the node.

    example properties:

    • entity_id
    • state
    • attributes.date
    • last_updated

    example values for the property:

    • 2020-12-31T02:47:54.837Z
    • 1609382842709
    • 13:40
    • 23:59:02

    Offset

    • Type: number

    A negative or positive number that will be added to the scheduled time.

    Randomize time within the offset

    • Type: boolean

    When selected the time to trigger will be random selected from the scheduled time to the +/- offset.

    Payload

    • Type: string | number | boolean | object

    The payload is fully customizable. The default will be a JSONata expression that outputs the entity state.

    Repeat Daily

    • Type: boolean

    If selected the node will only use the time portion of the date string to schedule the node and will trigger at that time each day. Otherwise, the node will only trigger once at the given day and time.

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    topic

    • Type: string

    The entity id in the configuration.

    payload

    • Type: string | number | boolean | object

    data

    • Type: object

    The entity object of the entity in the configuration.

    + + + diff --git a/node/trigger-state.html b/node/trigger-state.html new file mode 100644 index 0000000000..9c5d8f7bf0 --- /dev/null +++ b/node/trigger-state.html @@ -0,0 +1,43 @@ + + + + + + + + + Trigger: state | node-red-contrib-home-assistant-websocket + + + + + +

    Trigger: state

    Much like the events: state however, provides some advanced functionality around common automation use cases.

    An advanced version of the events: state node

    Configuration

    Entity required

    • Type: string

      The entity ID is used to listen for state changes. This can be a entity ID, regex, or a substring. If a regex or substring is used, the node will listen for all entities that match.

    Example:

    • light.kitchen (entity) listens for state changes of the light.kitchen entity
    • ^light.* (regex) listens for state changes of all entities that start with light.
    • light (substring) listens for state changes of all entities that contain light in the entity ID

    State Type

    • Type: string
    • Values: string|number|boolean
    • Default: string

    Convert the state of the entity to the selected type. Boolean will be converted to true based on if the string is equal by default to (y|yes|true|on|home|open). Original value stored in msg.data.original_state

    Conditions

    This node has two default outputs "allowed" and "blocked". If all the conditions are true the default message will be sent to the "allowed" output otherwise, it will be sent to the "blocked" output.

    See Also:

    Custom Outputs

    All the above conditions need to be true for any custom outputs to be sent, having zero conditions is a valid option. Each custom output can send the default message or a custom message. Also, each one can have its constraint on whether or not to be sent.

    Output on connect

    • Type: boolean

    Output once on startup/deployment.

    Enable input

    • Type: boolean

    Enable the input to be used to send a message to the node.

    Output debug information

    • Type: boolean

    Output debug information to the debug tab.

    Expose to Home Assistant

    • Type: boolean

    Expose the node to Home Assistant.

    Input

    Input is disabled by default. It can be enabled using the Enable Input option. Input can be used to enable/disable the node or for testing.

    Enable / Disable

    • Type: string

    If the incoming payload or message is a string and equal to enable or disable then set the node accordingly. Saves over restarts.

    Output

    topic

    • Type: string

    The entity_id that triggered the node

    payload

    • Type: string

    The state as sent by home assistant

    data

    • Type: object

    The original home assistant event containing entity_id new_state and old_state properties

    Testing

    To test automation without having to manually change the state in home assistant send an input payload as an object which contains entity_id, new_state, and old_state properties. This will trigger the node as if the event came from Home Assistant.

    {
    +  "entity_id": "test_entity",
    +  "old_state": {
    +    "state": "on"
    +  },
    +  "new_state": {
    +    "state": "off"
    +  }
    +}
    +

    References

    + + + diff --git a/node/update-config.html b/node/update-config.html new file mode 100644 index 0000000000..2aff2fd465 --- /dev/null +++ b/node/update-config.html @@ -0,0 +1,41 @@ + + + + + + + + + Update Config | node-red-contrib-home-assistant-websocket + + + + + +

    Update Config

    This node allows you to update the Home Assistant configuration of a node from within a flow. This is useful if you want to change the configuration of a node based on the state of an entity or some other event.

    Configuration

    Name

    • Type: string

    A name for the node.

    Server

    • Type: string

    The node id of a Server Config node.

    Entity Config

    • Type: string

    The node id of an entity config. This can be overridden by the payload.id property on the msg object.

    Inputs

    All properties must be under msg.payload and will be ignored if not.

    Example input

    Example of the msg.payload object.

    {
    +  "id": "d9d27ac6b4ebf78f",
    +  "icon": "mdi:lightbulb",
    +  "name": "My Light",
    +  "entityPicture": "/local/images/my_light.png"
    +}
    +

    id

    • Type: string

    The node id of an entity config.

    icon

    • Type: string

    The icon to use for the entity.

    name

    • Type: string

    The friendly name to use for the entity.

    entityPicture

    • Type: string

    The entity picture to use for the entity.

    Examples

    Usage example

    screenshot

    [{"id":"f74eb5b7233cf386","type":"inject","z":"0cd8900387d67b70","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":828,"y":192,"wires":[["f01a6d954835e535"]]},{"id":"f01a6d954835e535","type":"ha-sensor","z":"0cd8900387d67b70","name":"example one","entityConfig":"e4293de95073f8cd","version":0,"state":"$round($random() * 100, 0)","stateType":"jsonata","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1002,"y":192,"wires":[[]]},{"id":"fa343985973ac02b","type":"ha-update-config","z":"0cd8900387d67b70","name":"","server":"bf5874816710d0c7","entityConfig":"d18ff4919779da55","version":0,"outputProperties":[],"x":1016,"y":288,"wires":[[]]},{"id":"d9d27ac6b4ebf78f","type":"inject","z":"0cd8900387d67b70","name":"override id","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"(\t   $icons := [\t       'mdi:home-assistant',\t       'mdi:home',\t       'mdi:home-outline',\t       'mdi:home-variant',\t       'mdi:home-variant-outline',\t       'mdi:home-city'\t       ];\t   $simpsons := [\t       \"homer\",\t       \"marge\",\t       \"bart\",\t       \"lisa\",\t       \"maggie\"\t   ];\t   $character := $shuffle($simpsons)[0];\t   {\t       \"name\": $character,\t       \"id\": \"e4293de95073f8cd\",\t       \"icon\": $shuffle($icons)[0],\t        \"entityPicture\": \"/local/\" & $character & \".png\"\t       }\t)","payloadType":"jsonata","x":828,"y":336,"wires":[["fa343985973ac02b"]]},{"id":"4171499cb42d4c08","type":"inject","z":"0cd8900387d67b70","name":"use default id","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"(\t    $simpsons := [\"homer\", \"marge\", \"bart\", \"lisa\", \"maggie\"];\t    {\"name\": $shuffle($simpsons)[0] ,\"icon\":\"\"}\t)","payloadType":"jsonata","x":834,"y":288,"wires":[["fa343985973ac02b"]]},{"id":"94e86f1c0b4f113d","type":"ha-sensor","z":"0cd8900387d67b70","name":"example two","entityConfig":"d18ff4919779da55","version":0,"state":"$round($random() * 100, 0)","stateType":"jsonata","attributes":[],"inputOverride":"allow","outputProperties":[],"x":1002,"y":240,"wires":[[]]},{"id":"0d31aa0621b4fe6f","type":"inject","z":"0cd8900387d67b70","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":828,"y":240,"wires":[["94e86f1c0b4f113d"]]},{"id":"e4293de95073f8cd","type":"ha-entity-config","server":"bf5874816710d0c7","deviceConfig":"","name":"example one","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"Node-RED example one"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false},{"id":"d18ff4919779da55","type":"ha-entity-config","server":"bf5874816710d0c7","deviceConfig":"","name":"example two","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"Node-RED example one"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":"‎ "},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false}]
    +
    ```
    + + + diff --git a/node/wait-until.html b/node/wait-until.html new file mode 100644 index 0000000000..ded5c3d55e --- /dev/null +++ b/node/wait-until.html @@ -0,0 +1,48 @@ + + + + + + + + + Wait Until | node-red-contrib-home-assistant-websocket + + + + + +

    Wait Until

    When an input is received the node will wait until the condition is met or the timeout occurs then will pass on the last received message. Any new input will reset the timeout timer.

    Configuration

    Entities required

    A list of entities to wait for the condition to be met. The node will wait for any of the entities to meet the condition. If the entity is not found it will be ignored.

    The types that can be used are: entity id, substring, and regex.

    Examples

    • light.living_room - Will wait for the entity with the id light.living_room
    • motion - Will wait for any entity that has motion in the entity id
    • ^light\..* - Will wait for any entity that starts with light.

    Wait Until required

    • Type: string

    The property field will be checked against the value field using the comparator.

    Timeout

    • Type: number

    The amount of time to wait for the condition to become true before deactivating the node and passing the message object to the second output. If the timeout is equal to zero the node will wait indefinitely for the condition to be met.

    WARNING

    If using a Node-RED global or flow context variable in the timeout field it will not update the timeout value if the context value changes after the node has been deployed.

    Check against the current state

    • Type: boolean

    When an input is received it will check the comparator against the current state instead of waiting for a state change.

    INFO

    This is only available when there is only one entity selected

    Input

    reset

    If the received message has this property set to any value the node will be set to inactive and the timeout cleared.

    payload

    • Type: object

    Example

    {
    +  "entities": {
    +    "entity": ["light.living_room", "light.bedroom"],
    +    "substring": ["light."],
    +    "regex": ["light.*"]
    +  },
    +  "property": "state",
    +  "comparator": "is",
    +  "value": "on",
    +  "valueType": "str",
    +  "timeout": 10,
    +  "timeoutUnits": "seconds",
    +  "checkCurrentState": false
    +}
    +

    Output

    Value types:

    • entity: entity data of the triggered entity. Will be undefined if multiple entities are selected and the timeout occurs.
    • config: config properties of the node
    + + + diff --git a/node/webhook.html b/node/webhook.html new file mode 100644 index 0000000000..3951b85cc5 --- /dev/null +++ b/node/webhook.html @@ -0,0 +1,34 @@ + + + + + + + + + Webhook | node-red-contrib-home-assistant-websocket + + + + + +

    Webhook

    Outputs the data received from the created webhook in Home Assistant

    WARNING

    Needs Custom Integrationopen in new window installed in Home Assistant for this node to function

    Configuration

    ID required

    • Type: string

    A string to be used for the webhook URL in Home Assistant.

    Allowed Methods required

    • Type: list

    A list of allowed methods that Home Assistant will accept for the webhook. At least one method must be selected.

    Expose as

    • Type: string

    When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED.

    Outputs

    Value types:

    • received data: The parsed body from the webhook request
    • trigger id: webhook id
    • headers: entity state of the triggered entity
    • params: Query string parameters
    • config: config properties of the node
    + + + diff --git a/node/zone.html b/node/zone.html new file mode 100644 index 0000000000..71fdca9f5d --- /dev/null +++ b/node/zone.html @@ -0,0 +1,34 @@ + + + + + + + + + Zone | node-red-contrib-home-assistant-websocket + + + + + +

    Zone

    Outputs when one of the configured entities enter or leaves one of the defined zones.

    Configuration

    Entities

    • Type: array

    An array of entity ids to monitor for zone changes.

    Event

    • Type: string

    Set when to check an entity. Either entering or leaving a zone.

    Zones

    • Type: array

    An array of zone ids to check when a configured entity updates.

    Outputs

    topic

    • Type: string

    The entity id of the device/person that triggered the update.

    payload

    • Type: string

    The state of the device/person entity that triggered the update.

    data

    • Type: object

    The entity object of the device/person that triggered the update.

    zones

    • Type: array

    An array of zone entities where the device/person entity entered/left after an update of location.

    + + + diff --git a/scrubber/index.html b/scrubber/index.html new file mode 100644 index 0000000000..e7f9a3eb36 --- /dev/null +++ b/scrubber/index.html @@ -0,0 +1,34 @@ + + + + + + + + + Scrubber | node-red-contrib-home-assistant-websocket + + + + + +

    Scrubber

    What does this do?

    • Makes your exported flow a little more friendly to other users
    • Clears all references to the Home Assistant server
    • Clears lat, lon, latitude, and longitude properties from all nodes

    + + +