node-red-contrib-home-assistant-websocket
Version:
Node-RED integration with Home Assistant through websocket and REST API
345 lines • 309 kB
HTML
<link rel="stylesheet" href="resources/node-red-contrib-home-assistant-websocket/virtual-select.v1.0.44.min.css">
<script src="resources/node-red-contrib-home-assistant-websocket/virtual-select.v1.0.44.min.js"></script>
<script src="resources/node-red-contrib-home-assistant-websocket/handlebars.min-v4.7.8.js"></script>
<style>#version-update{margin-bottom:1em;padding:.5em}#version-update p{margin:0}#version-update strong{padding-right:5px}#version-update a,#version-update a:hover{color:var(--red-ui-primary-text-color)}.home-assistant .form-row.checkbox-option input{display:inline-block;margin-left:105px;margin-right:5px;vertical-align:top;width:auto}.home-assistant .form-row.checkbox-option label{width:auto}.home-assistant .form-row.checkbox-option-left input{display:inline-block;margin-right:5px;vertical-align:top;width:auto}.home-assistant .form-row.checkbox-option-left label{margin-right:20px;width:auto}.home-assistant .form-row.add-spacer{border-bottom:1px solid var(--red-ui-primary-text-color)}.home-assistant .form-row>select{width:70%}.home-assistant .form-row .ha-multi-item-row{display:inline-flex;gap:10px;width:70%}.home-assistant .form-row .ha-multi-item-row select{width:auto}.home-assistant .form-row .ha-multi-item-row .red-ui-typedInput-container{flex:1;width:auto}.home-assistant .editable-list-row{margin-bottom:4px}.home-assistant li span.property-type{color:var(--red-ui-primary-text-color);float:right;font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:11px;font-style:italic}.home-assistant .ha-alert-box,.home-assistant .ha-alpha-box,.home-assistant .ha-beta-box{border-radius:4px;margin-bottom:10px;padding:10px}.home-assistant .ha-alpha-box{background-color:#e78bb9;color:#702323}.home-assistant .ha-beta-box{background-color:#7d7;color:#853e3d}#constraint-list{min-width:446px}#constraint-list input{width:65%}#output-list input{width:62%}#clearIfState{margin-left:2px;position:absolute}.ha-node-label-legacy{fill:#fdfd96}.home-assistant-custom-block .custom-block-title{font-weight:600}.home-assistant-custom-block.danger,.home-assistant-custom-block.tip,.home-assistant-custom-block.warning{border-left-style:solid;border-left-width:.5rem;margin:1rem 0;padding:.1rem 1.5rem}.home-assistant-custom-block.tip{background-color:#f3f5f7;border-color:#42b983;color:#2c3e50}.home-assistant-custom-block.tip a{color:#3eaf7c}.home-assistant-custom-block.warning{background-color:#fff6c6;border-color:#e7c000;color:#6b5900}.home-assistant-custom-block.warning .custom-block-title{color:#b29400}.home-assistant-custom-block.warning a{color:#2c3e50}.home-assistant-custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.home-assistant-custom-block.danger .custom-block-title{color:#900}.home-assistant-custom-block.danger a{color:#2c3e50}.home-assisant-badge{border-radius:3px;color:#fff;display:inline-block;font-size:12px;height:16px;line-height:16px;padding:0 6px}.home-assisant-badge,.home-assisant-badge.green,.home-assisant-badge.tip{background-color:#42b983}.home-assisant-badge.error{background-color:#da5961}.home-assisant-badge.warn,.home-assisant-badge.warning,.home-assisant-badge.yellow{background-color:#e7c000}.home-assisant-badge+.home-assisant-badge{margin-left:5px}#upgrade-ha-node{background:#41bdf5;border:0;color:#eee;display:inline-block;font-size:14px;line-height:22px;margin:0;padding:4px 12px;text-decoration:none}.ui-autocomplete .ui-menu-item-wrapper .sublabel{color:var(--red-ui-secondary-text-color);font-size:smaller;margin:4px 0}.ha-entity-selector{align-items:flex-end;display:inline-flex;gap:10px;width:70%}.ha-entity-selector>input[type=text]{flex:1}.ha-entity-selector .select2-container{flex:1;width:auto}.ha-entity-selector .select2-container .select2-search--inline .select2-search__field{height:22px}#node-input-entityIdFilterType,#node-input-entityIdType,#node-input-entityidfiltertype{width:auto}.home-assistant .ha-entity-search-row{align-items:baseline;display:flex;margin-bottom:10px}.home-assistant .ha-entity-search-row label{display:inline;width:auto}.home-assistant .ha-entity-search-row input{background-color:var(--red-ui-form-input-background);border:1px solid var(--red-ui-form-input-border-color);border-radius:4px;box-sizing:border-box;color:var(--red-ui-primary-text-color);display:inline-block;flex:1;font-size:14px;height:34px;line-height:20px;margin-bottom:10px;margin-left:10px;padding:6px;vertical-align:middle}.home-assistant .ha-entity-search-row input:focus{border-color:var(--red-ui-form-input-border-color-focus);outline:0}.home-assistant .ha-entity-search-row ul{list-style:none;margin:0;overflow:hidden;overflow-y:auto;padding:0}.id-selector>li{padding-top:0}.id-selector>li .id-selector-row{font-size:.8em}.id-selector>li .id-selector-wrapper{display:flex;flex-direction:row}.red-ui-editableList-container li:last-child{border-bottom:none}#red-ui-header li.ha-notification{display:inline-block;height:100%;padding:0 10px;vertical-align:middle}#red-ui-header li.ha-notification svg{display:inline-block;line-height:1;vertical-align:middle}#red-ui-header li.ha-notification #notification-issues{color:var(--red-ui-text-color-warning);cursor:pointer;display:inline-block;padding-left:.3125rem}#red-ui-header li.ha-notification #notification-issues:hover{color:var(--red-ui-debug-message-border-warning)}#red-ui-header li.ha-notification #notification-issues .ha-issue-count{display:inline-block;font-size:1.5rem;line-height:1;vertical-align:middle}#red-ui-header li.ha-notification #notification-issues i{display:inline-block;font-size:1.25rem;line-height:1;padding-top:.125rem;vertical-align:middle}.home-assistant-sidebar-container{height:100%;position:relative}.home-assistant-sidebar-container .home-assistant-sidebar-stack{bottom:0;left:0;overflow-y:auto;position:absolute;right:0;top:0}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-list-filter{display:flex;justify-content:center;padding:10px}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-list{list-style:none;margin:0;padding:0}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-list-row{color:var(--red-ui-primary-text-color);display:flex;font-size:12px;justify-content:space-between;line-height:8px;margin-left:2px;padding-bottom:1px}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-list-row-name{cursor:pointer;flex:1;overflow:hidden;padding:10px;text-overflow:ellipsis;white-space:nowrap}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-list-row-count{background-color:var(--red-ui-node-icon-background-color);color:var(--red-ui-node-port-label-color);cursor:pointer;padding:10px;text-align:center;width:3ch}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-list li:nth-child(2n){background-color:var(--red-ui-form-input-background-disabled)}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list{list-style:none;margin:0;padding:0}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list-row{align-items:center;background-color:#41bdf5;color:var(--red-ui-node-label-color);display:flex;justify-content:space-between;margin:0 5px;padding:5px}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list-row span{flex:2;font-size:.9em;overflow:hidden;padding-left:5px;text-align:left;text-overflow:ellipsis;white-space:nowrap}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list-row button{margin-left:5px}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list-row .ha-hidden-issue i.fa-eye{display:inline-block}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list-row .ha-hidden-issue i.fa-eye-slash{display:none}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list.ha-show-hidden .ha-hidden{display:block}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list.ha-show-hidden .ha-hidden .ha-issues-list-row{background-color:var(--red-ui-list-item-background-disabled)!important;color:var(--red-ui-secondary-text-color)}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list.ha-show-hidden .ha-hidden .ha-hidden-issue i.fa-eye{display:none!important}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list.ha-show-hidden .ha-hidden .ha-hidden-issue i.fa-eye-slash{display:inline-block!important}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list .ha-hidden{display:none}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list ul{list-style:disc;margin:0 5px 0 20px;padding:3px 0}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list ul li{color:var(--red-ui-secondary-text-color);font-size:12px}.home-assistant-sidebar-container .home-assistant-sidebar-stack .ha-issues-list .ha-icon{background-position:50%;background-repeat:no-repeat;background-size:cover;color:#fff;font-size:1.3333333em;height:20px;width:20px}#home-assistant-stack-container{height:100%;position:relative}#ha-issue-header{align-items:start;display:flex;padding:5px}#ha-issue-header input{margin-right:5px}#ha-social-bar{align-items:center;border-bottom:1px dashed var(--red-ui-primary-border-color);display:flex;font-size:.9em;justify-content:right;margin-bottom:8px;padding-bottom:2px}#ha-social-bar a{cursor:pointer;line-height:10px}#ha-social-bar span{padding:0 5px}.vscomp-wrapper{color:var(--red-ui-form-text-color);font-family:var(--red-ui-primary-font)}.vscomp-wrapper.focused .vscomp-toggle-button,.vscomp-wrapper:focus .vscomp-toggle-button{border-color:var(--red-ui-form-input-focus-color);box-shadow:none;outline:0;outline:thin dotted\9}.vscomp-wrapper .vscomp-toggle-button{background-color:var(--red-ui-form-input-background);border-color:var(--red-ui-form-input-border-color);border-radius:4px;height:34px;vertical-align:middle}.vscomp-wrapper .vscomp-value{color:var(--red-ui-primary-text-color)}.vscomp-wrapper .vscomp-arrow:after{border-bottom-color:var(--red-ui-form-text-color);border-right-color:var(--red-ui-form-text-color)}.vscomp-wrapper .vscomp-clear-icon:after,.vscomp-wrapper .vscomp-clear-icon:before{background-color:var(--red-ui-form-text-color)}.vscomp-wrapper .vscomp-clear-icon:hover:after,.vscomp-wrapper .vscomp-clear-icon:hover:before{background:var(--red-ui-form-input-background)}.vscomp-wrapper .vscomp-clear-button:hover{background:var(--red-ui-form-text-color)}.vscomp-wrapper .vscomp-clear-button:hover .vscomp-clear-icon:after,.vscomp-wrapper .vscomp-clear-button:hover .vscomp-clear-icon:before,.vscomp-wrapper .vscomp-dropbox{background-color:var(--red-ui-form-input-background)}.vscomp-wrapper .vscomp-dropbox{border:1px solid var(--red-ui-primary-border-color)}.vscomp-wrapper .vscomp-option.selected{background-color:var(--red-ui-secondary-background-selected)}.vscomp-wrapper .vscomp-option.focused{background-color:var(--red-ui-secondary-background-hover)}.vscomp-wrapper .vscomp-option .vscomp-option-description{color:var(--red-ui-form-placeholder-color);font-size:11px}.vscomp-wrapper .vscomp-search-container{border-bottom-color:var(--red-ui-form-input-border-color)}.vscomp-wrapper .vscomp-search-container>label.vscomp-search-label{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.vscomp-wrapper .vscomp-search-container>input.vscomp-search-input{background-color:transparent;border:0;color:inherit;font-size:15px;height:38px;padding:10px 0;width:calc(100% - 30px)}.vscomp-wrapper .pop-comp-wrapper{background-color:var(--red-ui-form-input-background);color:var(--red-ui-form-text-color)}div.property-selector{display:grid;grid-template-columns:120px 1fr;grid-template-rows:repeat(2,1fr);grid-column-gap:5px;grid-row-gap:5px;align-items:center}div.property-selector input,div.property-selector select{width:100%}div.property-selector .property-label{grid-area:1/1/2/2}div.property-selector .input-property{grid-area:1/2/2/3}div.property-selector .input-logic{grid-area:2/1/3/2;width:auto}div.property-selector .input-value-wrapper{grid-area:2/2/3/3}#ha-action{margin-left:4px}.home-assistant .form-row.status-options div{display:flex;margin-top:12px}.home-assistant .form-row.status-options div .spacer{display:inline-block;width:100px}.home-assistant .form-row.status-options div input,.home-assistant .form-row.status-options div select{flex:1}.home-assistant.ha-config-server-editor{margin:0!important}.deviceExtra>label{text-transform:capitalize}.deviceExtra>input[type=checkbox]{width:auto}.deviceExtra .range-row{align-items:center;display:inline-flex;width:70%}.deviceExtra .range-row input[type=checkbox]{width:auto}.deviceExtra .range-row input[type=range]{flex-grow:1;margin:0 10px}.deviceExtra .range-row input[type=text]{text-align:center;width:calc(3ch + 14px)}#ha-device{margin-left:4px}#haConfig label{margin-bottom:0;text-transform:none;width:100%}#haConfig span{display:inline-block;margin-right:5px;width:40%}#haConfig input[type=text]{margin-left:10px;width:55%}.home-assistant ul.ha-ignore-state{list-style:none;margin-left:105px}.home-assistant ul.ha-ignore-state li input{display:inline-block;margin-right:5px;vertical-align:top;width:auto}.home-assistant ul.ha-ignore-state li label{width:auto}#update-tag-list{margin-bottom:4px}#no-tags-found{display:none}#days-of-the-week{margin-left:30px}#days-of-the-week input{display:inline-block;margin-right:5px;vertical-align:top;width:auto}#days-of-the-week label{width:auto}</style>
<script type="text/html" data-template-name="api-call-service"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-action.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-action.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label data-i18n="ha-action.label.action"></label><div id="ha-action"></div></div><div class="form-row"><ol id="target-list"></ol></div><div class="form-row"><label for="node-input-data" data-i18n="ha-action.label.data"></label> <input type="text" id="node-input-data" style="width:70%"> <input type="hidden" id="node-input-dataType"></div><div class="form-row checkbox-option" id="mustacheAltTags"><input type="checkbox" id="node-input-mustacheAltTags"> <label for="node-input-mustacheAltTags" data-i18n="ha-action.label.alternate_tags"></label></div><div class="form-row"><label for="node-input-mergeContext" data-i18n="ha-action.label.merge_context"></label> <input type="text" id="node-input-mergeContext" placeholder="lightOptions"></div><div class="form-row"><label for="node-input-queue" data-i18n="ha-action.label.queue"></label> <select type="text" id="node-input-queue"><option value="none" data-i18n="ha-action.label.queue_option.queue_none"></option><option value="first" data-i18n="ha-action.label.queue_option.queue_first"></option><option value="all" data-i18n="ha-action.label.queue_option.queue_all"></option><option value="last" data-i18n="ha-action.label.queue_option.queue_last"></option></select></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-debugenabled"> <label for="node-input-debugenabled" data-i18n="ha-action.label.show_debug"></label></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-blockInputOverrides"> <label for="node-input-blockInputOverrides" data-i18n="ha-action.label.block_input_overrides"></label></div><div id="service-data-desc" class="form-row"><button id="example-data" style="float:right" class="red-ui-button red-ui-button-small" data-i18n="ha-action.label.load_example_data"></button><h4><span data-i18n="ha-action.label.action"></span>: <span class="title"></span></h4><div class="unknown-service" data-i18n="ha-action.label.unknown_action"></div><div class="known-service"><p class="service-description"></p><table id="service-data-table" class="red-ui-info-table"><thead><tr><th>Property</th><th>Desc</th><th>Example</th></tr></thead><tbody></tbody></table></div></div></script>
<script type="text/html" data-template-name="ha-api"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-api.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-api.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-protocol" data-i18n="ha-api.label.protocol"></label> <select type="text" id="node-input-protocol" style="width:70%"><option value="websocket" data-i18n="ha-api.label.protocol_option.websocket"></option><option value="http" data-i18n="ha-api.label.protocol_option.http"></option></select></div><div class="form-row http"><label for="node-input-method" data-i18n="ha-api.label.method"></label> <select type="text" id="node-input-method" style="width:70%"><option value="get" data-i18n="ha-api.label.method_option.get"></option><option value="post" data-i18n="ha-api.label.method_option.post"></option><option value="put" data-i18n="ha-api.label.method_option.put"></option><option value="delete" data-i18n="ha-api.label.method_option.delete"></option></select></div><div class="form-row http"><label for="node-input-path" data-i18n="ha-api.label.path"></label> <input type="text" id="node-input-path" placeholder="config"></div><div class="form-row"><label id="data-label" for="node-input-data" data-i18n="ha-api.label.data"></label> <input type="text" id="node-input-data" style="width:70%"> <input type="hidden" id="node-input-dataType"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row http"><label for="node-input-responseType" data-i18n="ha-api.label.response_type"></label> <select id="node-input-responseType" style="width:70%"><option value="text" data-i18n="ha-api.label.response_type_option.text"></option><option value="arraybuffer" data-i18n="ha-api.label.response_type_option.arraybuffer"></option><option value="json" data-i18n="ha-api.label.response_type_option.json"></option></select></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-debugenabled"> <label for="node-input-debugenabled" data-i18n="ha-api.label.show_debug"></label></div></script>
<script type="text/html" data-template-name="ha-binary-sensor"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-binary-sensor.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-binary-sensor.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><label for="node-input-state"><span data-i18n="ha-binary-sensor.label.state"></span></label> <input type="text" id="node-input-state" style="width:70%"> <input type="hidden" id="node-input-stateType"></div><div class="form-row"><ol id="attributes"></ol></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row"><label for="node-input-inputOverride"><span data-i18n="ha-binary-sensor.label.input_override"></span></label> <select id="node-input-inputOverride" style="width:68%"><option value="allow" data-i18n="ha-binary-sensor.label.input_override_option.allow"></option><option value="merge" data-i18n="ha-binary-sensor.label.input_override_option.merge"></option><option value="block" data-i18n="ha-binary-sensor.label.input_override_option.block"></option></select></div></script>
<script type="text/html" data-template-name="ha-button"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-button.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-button.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><ol id="custom-outputs"></ol></div></script>
<script type="text/html" data-template-name="server"><input type="hidden" id="node-input-version"><div id="ha-server-settings"><h3 data-i18n="config-server.label.connection_settings"></h3><div><div class="form-row"><label for="node-config-input-name" data-i18n="config-server.label.name"></label> <input type="text" id="node-config-input-name"></div><div class="form-row checkbox-option"><input type="checkbox" id="node-config-input-addon"> <label for="node-config-input-addon" data-i18n="config-server.label.using_add_on"></label></div><div class="form-row addon checkbox-option"><input type="checkbox" id="node-config-input-connectionDelay"> <label for="node-config-input-connectionDelay" data-i18n="config-server.label.delay_connection_attempts"></label></div><div id="server-info"><div class="form-row"><label for="node-config-input-host" data-i18n="config-server.label.base_url"></label><div style="width:70%;display:inline-flex"><input type="text" id="node-config-input-host" placeholder="http://localhost:8123" style="flex-grow:1"> <a id="discoverInstances" class="red-ui-button" style="margin-left:10px"><i class="fa fa-search"></i></a></div></div><div class="form-row"><label id="access-token-label" for="node-config-input-access_token" data-i18n="config-server.label.access_token"></label> <input type="text" id="node-config-input-access_token" placeholder="access token"></div><div class="form-row checkbox-option"><input type="checkbox" id="accept_unauthorized_certs"> <label for="accept_unauthorized_certs" data-i18n="config-server.label.accept_all_certs"></label></div></div><div class="form-row checkbox-option"><input type="checkbox" id="node-config-input-heartbeat"> <label for="node-config-input-heartbeat" data-i18n="config-server.label.enable_heartbeat"></label></div><div class="form-row" id="heartbeatIntervalRow"><label for="node-config-input-heartbeatInterval" data-i18n="config-server.label.heartbeat_interval"></label><div style="vertical-align:text-bottom;width:70%;display:inline-block"><input type="number" id="node-config-input-heartbeatInterval" style="width:30%" min="10"> <span data-i18n="config-server.label.seconds"></span></div></div></div><h3 data-i18n="config-server.label.config_settings"></h3><div><div class="form-row"><div id="ha-boolean-list"></div></div><div class="form-row checkbox-option"><input type="checkbox" id="node-config-input-enableGlobalContextStore"> <label for="node-config-input-enableGlobalContextStore" data-i18n="config-server.label.enable_global_context_store"></label></div></div><h3 data-i18n="config-server.label.ui_settings"></h3><div><div class="form-row checkbox-option"><input type="checkbox" id="node-config-input-cacheJson"> <label for="node-config-input-cacheJson" data-i18n="config-server.label.cache_autocomplete_results"></label></div><div class="form-row"><span data-i18n="config-server.label.id_selector"></span></div><div class="form-row"><label for="node-config-input-areaSelector" data-i18n="config-server.label.area_selector"></label> <select id="node-config-input-areaSelector"><option value="id" data-i18n="config-server.label.selector_option.id"></option><option value="friendlyName" data-i18n="config-server.label.selector_option.friendly_name"></option></select></div><div class="form-row"><label for="node-config-input-deviceSelector" data-i18n="config-server.label.device_selector"></label> <select id="node-config-input-deviceSelector"><option value="id" data-i18n="config-server.label.selector_option.id"></option><option value="friendlyName" data-i18n="config-server.label.selector_option.friendly_name"></option></select></div><div class="form-row"><label for="node-config-input-entitySelector" data-i18n="config-server.label.entity_selector"></label> <select id="node-config-input-entitySelector"><option value="id" data-i18n="config-server.label.selector_option.id"></option><option value="friendlyName" data-i18n="config-server.label.selector_option.friendly_name"></option></select></div><div class="form-row"><span data-i18n="config-server.label.status_title"></span></div><div class="form-row"><label data-i18n="config-server.label.separator"></label> <input id="node-config-input-statusSeparator" type="text"></div><div class="form-row"><label data-i18n="config-server.label.year"></label> <select id="node-config-input-statusYear"><option value="hidden" data-i18n="config-server.label.date_option.hidden"></option><option value="numeric" data-i18n="config-server.label.date_option.numeric"></option><option value="2-digit" data-i18n="config-server.label.date_option.two_digit"></option></select></div><div class="form-row"><label data-i18n="config-server.label.month"></label> <select id="node-config-input-statusMonth"><option value="hidden" data-i18n="config-server.label.date_option.hidden"></option><option value="numeric" data-i18n="config-server.label.date_option.numeric"></option><option value="2-digit" data-i18n="config-server.label.date_option.two_digit"></option><option value="long" data-i18n="config-server.label.date_option.long"></option><option value="short" data-i18n="config-server.label.date_option.short"></option></select></div><div class="form-row"><label data-i18n="config-server.label.day"></label> <select id="node-config-input-statusDay"><option value="hidden" data-i18n="config-server.label.date_option.hidden"></option><option value="numeric" data-i18n="config-server.label.date_option.numeric"></option><option value="2-digit" data-i18n="config-server.label.date_option.two_digit"></option></select></div><div class="form-row"><label data-i18n="config-server.label.hour_cycle"></label> <select id="node-config-input-statusHourCycle"><option value="default" data-i18n="config-server.label.hour_cycle_option.default"></option><option value="h12" data-i18n="config-server.label.hour_cycle_option.12_hour_format"></option><option value="h23" data-i18n="config-server.label.hour_cycle_option.24_hour_format"></option></select></div><div class="form-row"><label data-i18n="config-server.label.time_format"></label> <select id="node-config-input-statusTimeFormat"><option value="h:m" data-i18n="config-server.label.time_format_option.hour_min"></option><option value="h:m:s" data-i18n="config-server.label.time_format_option.hour_min_sec"></option><option value="h:m:s.ms" data-i18n="config-server.label.time_format_option.hour_min_sec_ms"></option></select></div></div></div></script>
<script type="text/html" data-template-name="api-current-state"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-outputs"><div class="form-row"><label for="node-input-name" data-i18n="api-current-state.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="api-current-state.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-entity_id" data-i18n="api-current-state.label.entity_id"></label> <input type="text" id="node-input-entity_id"></div><div class="form-row"><label for="node-input-halt_if_compare" data-i18n="api-current-state.label.if_state"></label> <select type="text" id="node-input-halt_if_compare" style="width:20%"><option value="is" data-i18n="api-current-state.label.if_state_option.is"></option><option value="is_not" data-i18n="api-current-state.label.if_state_option.is_not"></option><option value="lt" data-i18n="api-current-state.label.if_state_option.less_than"></option><option value="lte" data-i18n="api-current-state.label.if_state_option.less_than_or_equal_to"></option><option value="gt" data-i18n="api-current-state.label.if_state_option.greater_than"></option><option value="gte" data-i18n="api-current-state.label.if_state_option.greater_than_or_equal_to"></option><option value="includes" data-i18n="api-current-state.label.if_state_option.includes"></option><option value="does_not_include" data-i18n="api-current-state.label.if_state_option.does_not_include"></option><option value="jsonata" data-i18n="api-current-state.label.if_state_option.jsonata"></option></select> <input type="text" id="node-input-halt_if" style="width:50%"> <input type="hidden" id="node-input-halt_if_type"></div><div class="form-row" id="for-row"><label for="node-input-for" data-i18n="api-current-state.label.for"></label> <input type="text" id="node-input-for" style="width:45%"> <input type="hidden" id="node-input-forType"> <select id="node-input-forUnits" style="width:25%"><option value="milliseconds" data-i18n="api-current-state.label.for_option.milliseconds"></option><option value="seconds" data-i18n="api-current-state.label.for_option.seconds"></option><option value="minutes" data-i18n="api-current-state.label.for_option.minutes"></option><option value="hours" data-i18n="api-current-state.label.for_option.hours"></option><option value="days" data-i18n="api-current-state.label.for_option.days"></option></select></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-blockInputOverrides"> <label for="node-input-blockInputOverrides" data-i18n="api-current-state.label.block_input_overrides"></label></div></script>
<script type="text/html" data-template-name="ha-device"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-device.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-device.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-deviceType"><span data-i18n="ha-device.label.type"></span></label> <select id="node-input-deviceType" style="width:70%"><option value="trigger" data-i18n="ha-device.label.trigger"></option><option value="action" data-i18n="ha-device.label.action"></option></select></div><div class="form-row"><label for="node-input-device" data-i18n="ha-device.label.device"></label><div id="ha-device"></div></div><div class="form-row"><label for="event" data-i18n="ha-device.label.trigger" style="text-transform:capitalize"></label> <select id="event" style="width:70%" disabled="disabled"></select></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-device-config"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-config-input-name" data-i18n="ha-device-config.label.name"></label> <input type="text" id="node-config-input-name"></div><div class="form-row"><label for="node-config-input-manufacturer" data-i18n="ha-device-config.label.manufacturer"></label> <input type="text" id="node-config-input-manufacturer"></div><div class="form-row"><label for="node-config-input-model" data-i18n="ha-device-config.label.model"></label> <input type="text" id="node-config-input-model"></div><div class="form-row"><label for="node-config-input-swVersion" data-i18n="ha-device-config.label.sw_version"></label> <input type="text" id="node-config-input-swVersion"></div><div class="form-row"><label for="node-config-input-hwVersion" data-i18n="ha-device-config.label.hw_version"></label> <input type="text" id="node-config-input-hwVersion"></div></script>
<script type="text/html" data-template-name="ha-entity">This node has been deperacated in favor of the indivdual entity nodes.</script>
<script type="text/html" data-template-name="ha-entity-config"><input type="hidden" id="node-config-input-version"><div class="form-row"><label for="node-config-input-name"><span data-i18n="ha-entity-config.label.name"></span></label> <input type="text" id="node-config-input-name"></div><div class="form-row"><label for="node-config-input-server"><span data-i18n="ha-entity-config.label.server"></span></label> <input type="text" id="node-config-input-server"></div><div class="form-row"><label for="node-config-input-deviceConfig"><span data-i18n="ha-entity-config.label.device"></span></label> <input type="text" id="node-config-input-deviceConfig"></div><div class="form-row"><label for="node-config-input-entityType"><span data-i18n="ha-entity-config.label.type"></span></label> <select id="node-config-input-entityType" style="width:70%"><option value="binary_sensor" data-i18n="ha-entity-config.label.type_option.binary_sensor"></option><option value="button" data-i18n="ha-entity-config.label.type_option.button"></option><option value="number" data-i18n="ha-entity-config.label.type_option.number"></option><option value="select" data-i18n="ha-entity-config.label.type_option.select"></option><option value="sensor" data-i18n="ha-entity-config.label.type_option.sensor"></option><option value="switch" data-i18n="ha-entity-config.label.type_option.switch"></option><option value="text" data-i18n="ha-entity-config.label.type_option.text"></option><option value="time" data-i18n="ha-entity-config.label.type_option.time"></option></select></div><hr><div id="ha-config-rows"></div><div id="resend-row" class="form-row ha-optional-row checkbox-option"><input type="checkbox" id="node-config-input-resend"> <label for="node-config-input-resend"><span data-i18n="ha-entity-config.label.resend"></span></label></div><div class="form-row checkbox-option"><input type="checkbox" id="node-config-input-debugEnabled"> <label for="node-config-input-debugEnabled"><span data-i18n="ha-entity-config.label.show_debug"></span></label></div></script>
<script type="text/html" data-template-name="server-events"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="server-events.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="server-events.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-eventType" data-i18n="server-events.label.event_type"></label> <input type="text" id="node-input-eventType" data-i18n="[placeholder]server-events.placeholder.all_events"></div><div id="eventAlert" class="ui-state-error ha-alert-box"><strong data-i18n="server-events.alert"></strong>: <span data-i18n="server-events.alert_message"></span></div><div class="form-row"><label for="node-input-eventData" data-i18n="server-events.label.event_data"></label> <input type="text" id="node-input-eventData" style="width:70%"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-waitForRunning"> <label for="node-input-waitForRunning" data-i18n="server-events.label.output_only_after_running"></label></div></script>
<script type="text/html" data-template-name="ha-events-calendar"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-events-calendar.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-events-calendar.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-entityId"><span data-i18n="ha-events-calendar.label.entityId"></span></label> <input type="text" id="node-input-entityId"></div><div class="form-row"><label for="node-input-eventType" data-i18n="ha-events-calendar.label.eventType"></label> <select type="text" id="node-input-eventType"><option value="start" data-i18n="ha-events-calendar.label.start"></option><option value="end" data-i18n="ha-events-calendar.label.end"></option></select></div><div class="form-row"><label for="node-input-offset" data-i18n="ha-events-calendar.label.offset"></label> <input type="text" id="node-input-offset" style="width:43%"> <input type="hidden" id="node-input-offsetType"> <select id="node-input-offsetUnits" style="width:27%"><option value="seconds" data-i18n="ha-events-calendar.label.seconds"></option><option value="minutes" data-i18n="ha-events-calendar.label.minutes"></option><option value="hours" data-i18n="ha-events-calendar.label.hours"></option></select></div><div class="form-row"><label for="node-input-filter" data-i18n="ha-events-calendar.label.filter"></label> <input type="text" id="node-input-filter"> <input type="hidden" id="node-input-filterType"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="server-state-changed"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-outputs"><div class="form-row"><label for="node-input-name" data-i18n="server-state-changed.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="server-state-changed.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><div id="entity-list"></div></div><div class="form-row"><label for="node-input-ifState" data-i18n="server-state-changed.label.if_state"></label> <select id="node-input-ifStateOperator" style="width:20%"><option value="is" data-i18n="server-state-changed.label.if_state_option.is"></option><option value="is_not" data-i18n="server-state-changed.label.if_state_option.is_not"></option><option value="lt" data-i18n="server-state-changed.label.if_state_option.less_than"></option><option value="lte" data-i18n="server-state-changed.label.if_state_option.less_than_or_equal_to"></option><option value="gt" data-i18n="server-state-changed.label.if_state_option.greater_than"></option><option value="gte" data-i18n="server-state-changed.label.if_state_option.greater_than_or_equal_to"></option><option value="includes" data-i18n="server-state-changed.label.if_state_option.includes"></option><option value="does_not_include" data-i18n="server-state-changed.label.if_state_option.does_not_include"></option><option value="jsonata" data-i18n="server-state-changed.label.if_state_option.jsonata"></option></select> <input type="text" id="node-input-ifState" style="width:50%"> <input type="hidden" id="node-input-ifStateType"></div><div class="form-row"><label for="node-input-for" data-i18n="server-state-changed.label.for"></label> <div class="ha-multi-item-row"><input type="text" id="node-input-for"> <input type="hidden" id="node-input-forType"> <select id="node-input-forUnits"><option value="milliseconds" data-i18n="server-state-changed.label.for_option.milliseconds"></option><option value="seconds" data-i18n="server-state-changed.label.for_option.seconds"></option><option value="minutes" data-i18n="server-state-changed.label.for_option.minutes"></option><option value="hours" data-i18n="server-state-changed.label.for_option.hours"></option><option value="days" data-i18n="server-state-changed.label.for_option.days"></option></select></div></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-outputInitially"> <label for="node-input-outputInitially" data-i18n="server-state-changed.label.output_on_connect"></label></div><div class="form-row"><p data-i18n="server-state-changed.label.ignore_state_change_event_when"></p><ul class="ha-ignore-state"><li><input type="checkbox" id="node-input-ignorePrevStateNull"> <label for="node-input-ignorePrevStateNull" data-i18n="server-state-changed.label.ignore_prev_state_null"></label></li><li><input type="checkbox" id="node-input-ignorePrevStateUnknown"> <label for="node-input-ignorePrevStateUnknown" data-i18n="server-state-changed.label.ignore_prev_state_unknown"></label></li><li><input type="checkbox" id="node-input-ignorePrevStateUnavailable"> <label for="node-input-ignorePrevStateUnavailable" data-i18n="server-state-changed.label.ignore_prev_state_unavailable"></label></li><li><input type="checkbox" id="node-input-ignoreCurrentStateUnknown"> <label for="node-input-ignoreCurrentStateUnknown" data-i18n="server-state-changed.label.ignore_current_state_unknown"></label></li><li><input type="checkbox" id="node-input-ignoreCurrentStateUnavailable"> <label for="node-input-ignoreCurrentStateUnavailable" data-i18n="server-state-changed.label.ignore_current_state_unavailable"></label></li><li><input type="checkbox" id="node-input-outputOnlyOnStateChange"> <label for="node-input-outputOnlyOnStateChange" data-i18n="server-state-changed.label.output_only_on_state_change"></label></li></ul></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-fire-event"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-fire-event.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-fire-event.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-event" data-i18n="ha-fire-event.label.event"></label> <input type="text" id="node-input-event"></div><div class="form-row"><label for="node-input-data" data-i18n="ha-fire-event.label.data"></label> <input type="text" id="node-input-data" style="width:70%"> <input type="hidden" id="node-input-dataType"></div></script>
<script type="text/html" data-template-name="ha-get-entities"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-get-entities.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-get-entities.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><ol id="conditions-list"></ol></div><div class="form-row"><label for="node-input-outputType" data-i18n="ha-get-entities.label.output_type"></label> <select id="node-input-outputType" style="width:70%"><option value="array" data-i18n="ha-get-entities.label.output_type_option.array"></option><option value="count" data-i18n="ha-get-entities.label.output_type_option.count"></option><option value="random" data-i18n="ha-get-entities.label.output_type_option.random"></option><option value="split" data-i18n="ha-get-entities.label.output_type_option.split"></option></select></div><div class="form-row checkbox-option output-option" id="output_empty_results"><input type="checkbox" id="node-input-outputEmptyResults"> <label for="node-input-outputEmptyResults" data-i18n="ha-get-entities.label.send_empty_results"></label></div><div class="form-row output-option" id="output_results_count"><label for="node-input-outputResultsCount" style="width:160px" data-i18n="ha-get-entities.label.max_results"></label> <input type="text" id="node-input-outputResultsCount" style="width:150px"></div><div class="form-row output-option" id="output_location"><label for="node-input-outputLocation" data-i18n="ha-get-entities.label.output_location"></label> <input type="hidden" id="node-input-outputLocationType"> <input type="text" id="node-input-outputLocation" style="width:70%"></div></script>
<script type="text/html" data-template-name="api-get-history"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="api-get-history.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="api-get-history.label.server"></label> <input type="text" id="node-input-server"></div><!-- Comparator Selection --><div class="form-row"><label for="node-input-entityId" data-i18n="api-get-history.label.entity_id"></label> <select type="text" id="node-input-entityIdType" style="width:18%"><option value="equals" data-i18n="api-get-history.label.entity_id_option.equal"></option><option value="regex" data-i18n="api-get-history.label.entity_id_option.regex"></option></select> <input type="text" id="node-input-entityId" style="width:52%"></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-useRelativeTime"> <label for="node-input-useRelativeTime" data-i18n="api-get-history.label.use_relative_time"></label></div><div class="form-row relative_row"><label for="node-input-relativeTime" data-i18n="api-get-history.label.in_the_last"></label> <input type="text" id="node-input-relativeTime" data-i18n="[placeholder]api-get-history.placeholder.relative_time" .></div><div class="form-row date_row"><label for="node-input-startDate" data-i18n="api-get-history.label.start_date"></label> <input type="datetime-local" id="node-input-startDate"></div><div class="form-row date_row"><label for="node-input-endDate" data-i18n="api-get-history.label.end_date"></label> <input type="datetime-local" id="node-input-endDate"></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-flatten"> <label for="node-input-flatten" data-i18n="api-get-history.label.flatten_results"></label></div><div class="form-row"><label for="node-input-outputType" data-i18n="api-get-history.label.output_type"></label> <select id="node-input-outputType" style="width:70%"><option value="array" data-i18n="api-get-history.label.output_type_option.array"></option><option value="split" data-i18n="api-get-history.label.output_type_option.split"></option></select></div><div class="form-row output-option" id="output_location"><label for="node-input-outputLocation" data-i18n="api-get-history.label.output_location"></label> <input type="hidden" id="node-input-outputLocationType"> <input type="text" id="node-input-outputLocation" style="width:70%"></div></script>
<script type="text/html" data-template-name="ha-number"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-inputs"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-number.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-number.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><label for="node-input-mode"><span data-i18n="ha-number.label.mode"></span></label> <select id="node-input-mode"><option value="listen" data-i18n="ha-text.label.mode_option.listen"></option><option value="get" data-i18n="ha-text.label.mode_option.get"></option><option value="set" data-i18n="ha-text.label.mode_option.set"></option></select></div><div class="form-row"><label for="node-input-value"><span data-i18n="ha-number.label.value"></span></label> <input type="text" id="node-input-value" style="width:70%"> <input type="hidden" id="node-input-valueType"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="poll-state"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-outputs"><div class="form-row"><label for="node-input-name" data-i18n="poll-state.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="poll-state.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-entityId" data-i18n="poll-state.label.entity_id"></label> <input type="text" id="node-input-entityId"></div><div class="form-row"><label for="node-input-updateinterval" data-i18n="poll-state.label.update_interval"></label> <input type="text" id="node-input-updateInterval" style="width:43%"> <input type="hidden" id="node-input-updateIntervalType"> <select id="node-input-updateIntervalUnits" style="width:27%"><option value="seconds" data-i18n="poll-state.label.update_interval_option.seconds"></option><option value="minutes" data-i18n="poll-state.label.update_interval_option.minutes"></option><option value="hours" data-i18n="poll-state.label.update_interval_option.hours"></option></select></div><div class="form-row"><label for="node-input-ifStateOperator" data-i18n="poll-state.label.if_state"></label> <select type="text" id="node-input-ifStateOperator" style="width:20%"><option value="is" data-i18n="poll-state.label.if_state_option.is"></option><option value="is_not" data-i18n="poll-state.label.if_state_option.is_not"></option><option value="lt" data-i18n="poll-state.label.if_state_option.less_than"></option><option value="lte" data-i18n="poll-state.label.if_state_option.less_than_or_equal_to"></option><option value="gt" data-i18n="poll-state.label.if_state_option.greater_than"></option><option value="gte" data-i18n="poll-state.label.if_state_option.greater_than_or_equal_to"></option><option value="includes" data-i18n="poll-state.label.if_state_option.includes"></option><option value="does_not_include" data-i18n="poll-state.label.if_state_option.does_not_include"></option><option value="jsonata" data-i18n="poll-state.label.if_state_option.jsonata"></option></select> <input type="text" id="node-input-ifState" style="width:50%"> <input type="hidden" id="node-input-ifStateType"></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-outputOnChanged"> <label for="node-input-outputOnChanged" data-i18n="poll-state.label.output_on_change"></label></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-outputInitially"> <label for="node-input-outputInitially" data-i18n="poll-state.label.output_on_connect"></label></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="api-render-template"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="api-render-template.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="api-render-template.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row" style="position:relative;margin-bottom:0"><label for="node-input-template" data-i18n="api-render-template.label.template"></label> <input type="hidden" id="node-input-template" autofocus="autofocus"></div><div class="form-row node-text-editor-row"><div style="height:250px;min-height:150px" class="node-text-editor" id="node-input-template-editor"></div></div><div class="form-row"><label for="node-input-templateLocation" data-i18n="api-render-template.label.template"></label> <input type="text" id="node-input-templateLocation" style="width:70%"> <input type="hidden" id="node-input-templateLocationType"></div><div class="form-row"><label for="node-input-resultsLocation" data-i18n="api-render-template.label.results"></label> <input type="text" id="node-input-resultsLocation" style="width:70%"> <input type="hidden" id="node-input-resultsLocationType"></div></script>
<script type="text/html" data-template-name="ha-select"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-inputs"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-select.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-select.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><label for="node-input-mode"><span data-i18n="ha-select.label.mode"></span></label> <select id="node-input-mode"><option value="listen" data-i18n="ha-text.label.mode_option.listen"></option><option value="get" data-i18n="ha-text.label.mode_option.get"></option><option value="set" data-i18n="ha-text.label.mode_option.set"></option></select></div><div class="form-row"><label for="node-input-value"><span data-i18n="ha-select.label.value"></span></label> <input type="text" id="node-input-value" style="width:70%"> <input type="hidden" id="node-input-valueType"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-sensor"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-sensor.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-sensor.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><label for="node-input-state"><span data-i18n="ha-sensor.label.state"></span></label> <input type="text" id="node-input-state" style="width:70%"> <input type="hidden" id="node-input-stateType"></div><div class="form-row"><ol id="attributes"></ol></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row"><label for="node-input-inputOverride"><span data-i18n="ha-sensor.label.input_override"></span></label> <select id="node-input-inputOverride" style="width:68%"><option value="allow" data-i18n="ha-sensor.label.input_override_option.allow"></option><option value="merge" data-i18n="ha-sensor.label.input_override_option.merge"></option><option value="block" data-i18n="ha-sensor.label.input_override_option.block"></option></select></div></script>
<script type="text/html" data-template-name="ha-sentence"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-inputs"><div class="form-row"><label for="node-input-name" data-i18n="ha-sentence.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-sentence.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-mode"><span data-i18n="ha-select.label.mode"></span></label> <select id="node-input-mode"><option value="trigger" data-i18n="ha-sentence.label.mode_option.trigger"></option><option value="response" data-i18n="ha-sentence.label.mode_option.response"></option></select></div><div class="form-row sentence-trigger"><ol id="node-input-sentences-container"></ol></div><div class="form-row sentence-trigger"><label for="node-input-triggerResponseType"><span data-i18n="ha-sentence.label.response_type"></span></label> <select id="node-input-triggerResponseType"><option value="fixed" data-i18n="ha-sentence.label.response_type_option.fixed"></option><option value="dynamic" data-i18n="ha-sentence.label.response_type_option.dynamic"></option></select></div><div class="form-row sentence-response"><label for="node-input-response" data-i18n="ha-sentence.label.response"></label> <input type="text" id="node-input-response" style="width:70%"> <input type="hidden" id="node-input-responseType"></div><div class="form-row sentence-trigger"><label for="node-input-triggerResponse" data-i18n="ha-sentence.label.response"></label> <input type="text" id="node-input-triggerResponse" placeholder="Done"></div><div class="form-row sentence-trigger"><label for="node-input-responseTimeout" data-i18n="ha-sentence.label.timeout"></label> <input type="text" id="node-input-responseTimeout" value="1000"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row sentence-trigger" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-switch"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-inputs"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-switch.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-switch.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-enableInput"> <label for="node-input-enableInput"><span data-i18n="ha-switch.label.enable_input"></span></label></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-outputOnStateChange"> <label for="node-input-outputOnStateChange"><span data-i18n="ha-switch.label.output_on_state_change"></span></label></div><div id="ha-custom-ouputs" class="form-row"><ol id="custom-outputs"></ol></div></script>
<script type="text/html" data-template-name="ha-tag"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-tag.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-tag.label.server"></label> <input type="text" id="node-input-server"></div><div id="no-tags-found" class="ui-state-error ha-alert-box" data-i18n="ha-tag.errors.no_tags_found"></div><div class="form-row"><ol id="tags"></ol></div><div class="form-row"><ol id="devices"></ol></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-text"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-inputs"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-text.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-text.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><label for="node-input-mode"><span data-i18n="ha-text.label.mode"></span></label> <select id="node-input-mode"><option value="listen" data-i18n="ha-text.label.mode_option.listen"></option><option value="get" data-i18n="ha-text.label.mode_option.get"></option><option value="set" data-i18n="ha-text.label.mode_option.set"></option></select></div><div class="form-row"><label for="node-input-text"><span data-i18n="ha-text.label.text"></span></label> <input type="text" id="node-input-value" style="width:70%"> <input type="hidden" id="node-input-valueType"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-time"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-time.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-time.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-entityId" data-i18n="ha-time.label.entity_id"></label> <input type="text" id="node-input-entityId"></div><div class="form-row"><label for="node-input-property" data-i18n="ha-time.label.property"></label> <input type="text" id="node-input-property" placeholder="state"></div><div class="form-row"><label for="node-input-offset" data-i18n="ha-time.label.offset"></label> <input type="text" id="node-input-offset" style="width:43%"> <input type="hidden" id="node-input-offsetType"> <select id="node-input-offsetUnits" style="width:27%"><option value="seconds" data-i18n="ha-time.label.offset_unit_option.seconds"></option><option value="minutes" data-i18n="ha-time.label.offset_unit_option.minutes"></option><option value="hours" data-i18n="ha-time.label.offset_unit_option.hours"></option></select></div><div class="form-row checkbox-option"><label><input type="checkbox" id="node-input-randomOffset"> <span data-i18n="ha-time.label.randomize_offset"></span></label></div><div class="form-row" id="entitiesFound"></div><div class="form-row checkbox-option"><label><input type="checkbox" id="node-input-repeatDaily"> <span data-i18n="ha-time.label.repeat_daily"></span></label><div id="days-of-the-week"><div><input type="checkbox" checked="checked" id="node-input-sunday"> <label for="node-input-sunday" data-i18n="ha-time.label.sunday"></label></div><div><input type="checkbox" checked="checked" id="node-input-monday"> <label for="node-input-monday" data-i18n="ha-time.label.monday"></label></div><div><input type="checkbox" checked="checked" id="node-input-tuesday"> <label for="node-input-tuesday" data-i18n="ha-time.label.tuesday"></label></div><div><input type="checkbox" checked="checked" id="node-input-wednesday"> <label for="node-input-wednesday" data-i18n="ha-time.label.wednesday"></label></div><div><input type="checkbox" checked="checked" id="node-input-thursday"> <label for="node-input-thursday" data-i18n="ha-time.label.thursday"></label></div><div><input type="checkbox" checked="checked" id="node-input-friday"> <label for="node-input-friday" data-i18n="ha-time.label.friday"></label></div><div><input type="checkbox" checked="checked" id="node-input-saturday"> <label for="node-input-saturday" data-i18n="ha-time.label.saturday"></label></div></div></div><div class="form-row checkbox-option"><label><input type="checkbox" id="node-input-ignorePastDate"> <span data-i18n="ha-time.label.ignore_past_date"></span></label></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-time-entity"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-inputs"><div class="form-row"><label for="node-input-name"><span data-i18n="ha-time-entity.label.name"></span></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-entityConfig"><span data-i18n="ha-time-entity.label.entity_config"></span></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><label for="node-input-mode"><span data-i18n="ha-time-entity.label.mode"></span></label> <select id="node-input-mode"><option value="listen" data-i18n="ha-time-entity.label.mode_option.listen"></option><option value="get" data-i18n="ha-time-entity.label.mode_option.get"></option><option value="set" data-i18n="ha-time-entity.label.mode_option.set"></option></select></div><div class="form-row"><label for="node-input-value"><span data-i18n="ha-time-entity.label.value"></span></label> <input type="text" id="node-input-value" style="width:70%"> <input type="hidden" id="node-input-valueType"></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="trigger-state"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-inputs"> <input type="hidden" id="node-input-outputs"><!-- Name --><div class="form-row"><label for="node-input-name" data-i18n="trigger-state.label.name"></label> <input type="text" id="node-input-name"></div><!-- Server --><div class="form-row"><label for="node-input-server" data-i18n="trigger-state.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><div id="entity-list"></div></div><!-- Constraints List --><div class="form-row"><ol id="constraint-list"></ol></div><!-- Output List --><div class="form-row"><ol id="output-list"></ol></div><div class="form-row checkbox-option-left"><input type="checkbox" id="node-input-outputInitially"> <label for="node-input-outputInitially" data-i18n="trigger-state.label.output_on_connect"></label></div><div class="form-row checkbox-option-left"><input type="checkbox" id="node-input-enableInput"> <label for="node-input-enableInput" data-i18n="trigger-state.label.enable_input"></label></div><div class="form-row checkbox-option-left"><input type="checkbox" id="node-input-debugEnabled"> <label for="node-input-debugEnabled" data-i18n="trigger-state.label.show_debug"></label></div><div id="constraint-template" style="display:none"><!-- Target Selection --><div class="editable-list-row"><!-- Type --> <select type="text" class="target-type" style="width:140px"><option value="this_entity" data-i18n="trigger-state.label.target_value_option.this_entity"></option><option value="entity_id" data-i18n="trigger-state.label.target_value_option.entity_id"></option></select><!-- Value --> <input type="text" class="target-value" disabled="disabled"></div><!-- Property Selection --><div class="editable-list-row"><!-- Type --> <select type="text" class="property-type" style="width:140px"><option value="current_state" data-i18n="trigger-state.label.target_type_option.current_state"></option><option value="previous_state" data-i18n="trigger-state.label.target_type_option.previous_state"></option><option value="property" data-i18n="trigger-state.label.target_type_option.property"></option></select><!-- Value --> <input type="text" class="property-value" disabled="disabled"></div><!-- Comparator Selection --><div class="editable-list-row"><!-- Type --> <select type="text" class="comparator-type" style="width:140px"><option value="is" data-i18n="trigger-state.label.comparator_option.is"></option><option value="is_not" data-i18n="trigger-state.label.comparator_option.is_not"></option><option value=">" data-i18n="trigger-state.label.comparator_option.greater_than"></option><option value=">=" data-i18n="trigger-state.label.comparator_option.greater_than_or_equal_to"></option><option value="<" data-i18n="trigger-state.label.comparator_option.less_than"></option><option value="<=" data-i18n="trigger-state.label.comparator_option.less_than_or_equal_to"></option><option value="includes" data-i18n="trigger-state.label.comparator_option.includes"></option><option value="does_not_include" data-i18n="trigger-state.label.comparator_option.does_not_include"></option></select><!-- Value --> <input type="text" class="comparator-value" style="width:65%"></div></div><div id="output-template" style="display:none"><div class="editable-list-row"><!-- Type --> <select type="text" class="message-type" style="width:140px"><option value="default" data-i18n="trigger-state.label.message_value_option.default"></option><option value="custom" data-i18n="trigger-state.label.message_value_option.custom"></option><option value="payload" data-i18n="trigger-state.label.message_value_option.custom_payload"></option></select> <input type="text" class="message-value" style="width:62%"></div><!-- Output Comparator Selection --><div class="editable-list-row"><select type="text" class="comparator-property-type" style="width:140px"><option value="always" data-i18n="trigger-state.label.comparator_property_value_option.always"></option><option value="current_state" data-i18n="trigger-state.label.comparator_property_value_option.if_state"></option><option value="previous_state" data-i18n="trigger-state.label.comparator_property_value_option.if_prev_state"></option><option value="property" data-i18n="trigger-state.label.comparator_property_value_option.if_property"></option></select> <input type="text" class="comparator-property-value" disabled="disabled"></div><div class="editable-list-row"><!-- Type --> <select type="text" class="comparator-type" style="width:140px" disabled="disabled"><option value="is" data-i18n="trigger-state.label.comparator_option.is"></option><option value="is_not" data-i18n="trigger-state.label.comparator_option.is_not"></option><option value=">" data-i18n="trigger-state.label.comparator_option.greater_than"></option><option value=">=" data-i18n="trigger-state.label.comparator_option.greater_than_or_equal_to"></option><option value="<" data-i18n="trigger-state.label.comparator_option.less_than"></option><option value="<=" data-i18n="trigger-state.label.comparator_option.less_than_or_equal_to"></option><option value="includes" data-i18n="trigger-state.label.comparator_option.includes"></option><option value="does_not_include" data-i18n="trigger-state.label.comparator_option.does_not_include"></option></select> <input type="text" class="comparator-value" style="width:62%"></div></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-update-config"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-update-config.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-update-config.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-entityConfig" data-i18n="ha-update-config.label.entity_config"></label> <input type="text" id="node-input-entityConfig"></div><div class="form-row"><ol id="custom-outputs"></ol></div></script>
<script type="text/html" data-template-name="ha-wait-until"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-wait-until.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-wait-until.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><div id="entity-list"></div></div><div class="form-row"><label for="node-input-property" data-i18n="ha-wait-until.label.wait_until"></label> <input type="text" id="node-input-property" data-i18n="[placeholder]ha-wait-until.placeholder.property"></div><div class="form-row"><label></label> <div class="ha-multi-item-row"><select id="node-input-comparator"><option value="is" data-i18n="ha-wait-until.label.comparator_option.is"></option><option value="is_not" data-i18n="ha-wait-until.label.comparator_option.is_not"></option><option value="lt" data-i18n="ha-wait-until.label.comparator_option.less_than"></option><option value="lte" data-i18n="ha-wait-until.label.comparator_option.less_than_or_equal_to"></option><option value="gt" data-i18n="ha-wait-until.label.comparator_option.greater_than"></option><option value="gte" data-i18n="ha-wait-until.label.comparator_option.greater_than_or_equal_to"></option><option value="includes" data-i18n="ha-wait-until.label.comparator_option.includes"></option><option value="does_not_include" data-i18n="ha-wait-until.label.comparator_option.does_not_include"></option><option value="jsonata" data-i18n="ha-wait-until.label.comparator_option.jsonata"></option></select> <input id="node-input-valueType" type="hidden"> <input id="node-input-value" type="text" data-i18n="[placeholder]ha-wait-until.placeholder.value"></div></div><div class="form-row"><label for="node-input-timeout" data-i18n="ha-wait-until.label.timeout"></label> <div class="ha-multi-item-row"><input type="text" id="node-input-timeout"> <input type="hidden" id="node-input-timeoutType"> <select id="node-input-timeoutUnits"><option value="milliseconds" data-i18n="ha-wait-until.label.timeout_units_option.milliseconds"></option><option value="seconds" data-i18n="ha-wait-until.label.timeout_units_option.seconds"></option><option value="minutes" data-i18n="ha-wait-until.label.timeout_units_option.minutes"></option><option value="hours" data-i18n="ha-wait-until.label.timeout_units_option.hours"></option><option value="days" data-i18n="ha-wait-until.label.timeout_units_option.days"></option></select></div></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row exact-only checkbox-option"><input type="checkbox" id="node-input-checkCurrentState" checked="checked"> <label for="node-input-checkCurrentState" data-i18n="ha-wait-until.label.check_current_state"></label></div><div class="form-row checkbox-option"><input type="checkbox" id="node-input-blockInputOverrides"> <label for="node-input-blockInputOverrides" data-i18n="ha-wait-until.label.block_input_overrides"></label></div></script>
<script type="text/html" data-template-name="ha-webhook"><input type="hidden" id="node-input-version"> <input type="hidden" id="node-input-outputs"><div class="form-row"><label for="node-input-name" data-i18n="ha-webhook.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-webhook.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><label for="node-input-webhookId" data-i18n="ha-webhook.label.id"></label> <div style="display:inline-flex;width:70%"><input type="text" id="node-input-webhookId" style="flex-grow:1"> <a id="copyId" class="editor-button" style="margin-left:10px"><i class="fa fa-copy"></i> </a><a id="refresh" class="editor-button" style="margin-left:10px"><i class="fa fa-refresh"></i></a></div></div><div class="form-row"><p data-i18n="ha-webhook.label.allowed_methods"></p><ul class="ha-ignore-state"><li><input type="checkbox" id="node-input-method_post"> <label for="node-input-method_post" data-i18n="ha-webhook.label.post"></label></li><li><input type="checkbox" id="node-input-method_put"> <label for="node-input-method_put" data-i18n="ha-webhook.label.put"></label></li><li><input type="checkbox" id="node-input-method_get"> <label for="node-input-method_get" data-i18n="ha-webhook.label.get"></label></li><li><input type="checkbox" id="node-input-method_head"> <label for="node-input-method_head" data-i18n="ha-webhook.label.head"></label></li></ul></div><div class="form-row"><ol id="custom-outputs"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-template-name="ha-zone"><input type="hidden" id="node-input-version"><div class="form-row"><label for="node-input-name" data-i18n="ha-zone.label.name"></label> <input type="text" id="node-input-name"></div><div class="form-row"><label for="node-input-server" data-i18n="ha-zone.label.server"></label> <input type="text" id="node-input-server"></div><div class="form-row"><ol id="entities"></ol></div><div class="form-row"><label for="node-input-event" data-i18n="ha-zone.label.event"></label> <select id="node-input-event"><option value="enter" data-i18n="ha-zone.label.option.enter"></option><option value="leave" data-i18n="ha-zone.label.option.leave"></option><option value="enter_leave" data-i18n="ha-zone.label.option.enter_or_leave"></option></select></div><div class="form-row"><ol id="zones"></ol></div><div class="form-row" id="exposed-as-row"><label for="node-input-exposeAsEntityConfig" data-i18n="ha-tag.label.expose_as"></label> <input type="text" id="node-input-exposeAsEntityConfig"></div></script>
<script type="text/html" data-help-name="ha-api"><p>The API node provides access to all points of the Home Assistant WebSocket and HTTP API. This enables you to interact programmatically with Home Assistant, sending and receiving data through these protocols. It’s a powerful tool for integrating third-party systems, custom automations, or advanced control within Node-RED, offering full access to Home Assistant's core functionalities.</p><h3>Config</h3><dl class="message-properties"><dt>Protocol <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><ul><li>Values: <code>websocket|http</code></li><li>Default: <code>websocket</code></li></ul><dd>Protocol to use to access Home Assistant API.</dd><dt>Method<span class="property-type">string</span></dt><ul><li>Values: <code>get|post</code></li></ul><dd>Type of method to use to access the HTTP endpoint.</dd><dt>Path<span class="property-type">string</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a></li></ul><dd>URL of the API endpoint.</dd><dt>Params<span class="property-type">Object</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a></li></ul><dd>A JSON object with key/value pairs that will be converted into URL parameters.</dd><dt>Data<span class="property-type">Object</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> when the data type is JSON</li></ul><dd>JSON Object to send for WebSocket requests and HTTP posts.</dd><dt>Results<span class="property-type">string</span></dt></dl><h3>Input</h3><dl class="message-properties"><dd>All properties need to be under <code>msg.payload</code>.</dd><dt>protocol<span class="property-type">string</span></dt><ul><li>Values: <code>websocket|http</code></li></ul><dd>Overrides or sets the protocol property of the config.</dd><dt>method<span class="property-type">string</span></dt><ul><li>Values: <code>get|post</code></li></ul><dd>Overrides or sets the method property of the config.</dd><dt>path<span class="property-type">string</span></dt><dd>Overrides or sets the path property of the config.</dd><dt>data<span class="property-type">Object|string</span></dt><dd>Overrides or sets the data/params property of the config.</dd><dt>location<span class="property-type">string</span></dt><dd>Overrides or sets the results property of the config.</dd><dt>locationType<span class="property-type">string</span></dt><ul><li>Values: <code>msg|flow|global</code></li></ul><dd>Overrides or sets the results type property of the config.</dd></dl><h3>Output</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>results</code>: results of the API request</li><li><code>config</code>: config properties of the node</li></ul></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://developers.home-assistant.io/docs/api/rest">http api</a></li><li><a href="https://developers.home-assistant.io/docs/api/websocket">websocket api</a></li></ul></dl></script>
<script type="text/html" data-help-name="api-call-service"><p>This node allows you to send a request to Home Assistant to perform specific actions. These actions could include tasks such as turning on a light (<code>light.turn_on</code>), selecting an option from a dropdown menu (<code>input_select.select_option</code>), or any other service call supported by Home Assistant. It serves as a bridge between Node-RED and Home Assistant, enabling automation flows to directly control devices or entities in your smart home setup.</p><div class="home-assistant-custom-block tip"><p class="custom-block-title">Helpful Examples</p><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/action.html" rel="noopener noreferrer">Action Tips and Tricks</a></p></div><h3>Configuration</h3><dl class="message-properties"><dt>Action <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a></li></ul><dd>Action to perform</dd><dt>Floor<span class="property-type">an array of floor ids</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> for ids</li></ul><dd>A list of floor ids that will be used as targets for the action</dd><dt>Area<span class="property-type">an array of area ids</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> for ids</li></ul><dd>A list of area ids that will be used as targets for the action</dd><dd>Custom ids can be inserted into the list by adding a <code>#</code> at the end of the id</dd><dt>Device<span class="property-type">an array of device ids</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> for ids</li></ul><dd>A list of device ids that will be used as targets for the action</dd><dd>Custom ids can be inserted into the list by adding a <code>#</code> at the end of the id</dd><dt>Entity<span class="property-type">an array of entity ids</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> for ids</li></ul><dd>A list of entity ids that will be used as targets for the action</dd><dt>Label<span class="property-type">an array of label ids</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> for ids</li></ul><dd>A list of label ids that will be used as targets for the action</dd><dt>Data<span class="property-type">JSONata | JSON</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> when data type is JSON</li></ul><dd>JSON object to pass along.</dd><dt>Merge Context<span class="property-type">string</span></dt><dd>If defined will attempt to merge the global and flow context variable into the config</dd><dt>Alternative Template Tags<span class="property-type">boolean</span></dt><dd>Will change the tags used for the mustache template to <code><%</code> and <code>%></code></dd><dt>Queue<span class="property-type">none | first | all | last</span></dt><dd>Will store the first, last, or all messages received while disconnected from Home Assistant and send them once connected again</dd><dt>Block Input Overrides<span class="property-type">boolean</span></dt><ul><li>Default: <code>true</code></li></ul><dd>Stop <code>msg.payload</code> values from overriding local config</dd></dl><h3>Input</h3><dl class="message-properties"><dd>All properties need to be under <code>msg.payload</code>.</dd><dd>Sample input</dd><pre><code class="language-JSON">{
"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
}
}
</code></pre><h5>Merging</h5><dd>If the incoming message has a <code>payload</code> property with <code>action</code> set it will override any config values if set.</dd><dd>If the incoming message has a <code>payload.data</code> that is an object these properties will be <strong>merged</strong> with any config values set.</dd><dd>If the node has a property value in its config for <code>Merge Context</code> then the <code>flow</code> and <code>global</code> contexts will be checked for this property which should be an object that will also be merged into the data payload.</dd><h5>Merge Resolution</h5><dd>As seen above the <code>data</code> 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</dd><dd>Config Data, Global Data, Flow Data, Payload Data ( payload data property always wins if provided )</dd><dt>action<span class="property-type">string</span></dt><dd>Action to call</dd><dt>data<span class="property-type">JSON Object</span></dt><dd>Data to send with the action</dd><dt>target<span class="property-type">JSON Object with floor_id, area_id, device_id, entity_id, and label_id as array properties</span></dt><dd>Targets of the action</dd></dl><h3>Output</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>config</code>: config properties of the node</li><li><code>results</code>: response from Home Assistant</li><li><code>sent data</code>: data sent to Home Assistant</li></ul></dl><h3>References</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/action.html" rel="noopener noreferrer">External Docs</a></p></div></dl></script>
<script type="text/html" data-help-name="ha-binary-sensor"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>This node allows you to create a binary sensor entity within Home Assistant that can be controlled directly from Node-RED. A binary sensor is a type of entity that has only two possible states: typically "on" or "off". It can represent various real-world conditions, such as whether a door is open or closed, or if motion is detected.</p><h3>Configuration</h3><dl class="message-properties"><dt>State <span text="required" class="home-assistant-badge">required</span><span class="property-type">boolean</span></dt><dd>The state of the entity should be updated to</dd><dd>To set the Home Assistant state to <code>Unknown</code>, send a state with a js expression <code>null</code>.</dd><dt>Attributes<span class="property-type">Object</span></dt><dd>Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]</dd><dt>Input Override<span class="property-type">string</span></dt><ul><li>Values: <code>accept | merge | block</code></li></ul><dd>Determine how input values will be handled. When merge is selected the message object values will override the configuration values.</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>properties of <code>msg.payload</code></dd><dt>state<span class="property-type">string | number | boolean</span></dt><dd>The value of the entity state will be updated.</dd><dt>attributes<span class="property-type">Object</span></dt><dd>Key/Value pair of attributes to update. The key should be a string and the value can be a <code>[string | number | boolean | object]</code></dd></dl></script>
<script type="text/html" data-help-name="ha-button"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>The Button node creates a button entity within Home Assistant that, when pressed, triggers a flow in Node-RED. This is useful for manual triggers within automations, allowing users to start an automation sequence directly from the Home Assistant interface with a simple click.</p><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>entity</code>: complete entity object</li><li><code>entity id</code>: entity id of the pressed button</li><li><code>entity state</code>: entity state of the pressed button</li><li><code>config</code>: config properties of the node</li></ul></dl></script>
<script type="text/html" data-help-name="server"><p>The <strong>Server Config</strong> node defines how Node-RED connects to your Home Assistant instance. It manages connection details, authentication, and various integration settings to ensure a stable connection between Node-RED and Home Assistant.</p><hr><h3>Connection Settings</h3><dl class="message-properties"><dt>Name<span class="property-type">string</span></dt><dd>A user-defined label for this configuration. This name is also used as the <strong>namespace</strong> for related global context data (see Context).</dd><hr><dt>Using the Home Assistant Add-on<span class="property-type">boolean</span></dt><dd>If you’re running Node-RED as a <strong>Home Assistant Add-on (Hass.io)</strong>, enable this option. No additional configuration (such as URL or access token) is required.</dd><hr><dt>Base URL<span class="property-type">string</span></dt><dd>The base URL and port of your Home Assistant instance.</dd><dd><strong>Examples:</strong></dd><ul><li><code>http://192.168.0.100:8123</code></li><li><code>https://homeassistant.mysite.com</code></li></ul><hr><dt>Access Token<span class="property-type">string</span></dt><dd>A <strong>Long-Lived Access Token</strong> used to authenticate with Home Assistant’s API.</dd><hr><dt>Allow Unauthorized SSL Certificates<span class="property-type">boolean</span></dt><dd>Allows Node-RED to accept <strong>self-signed certificates</strong> when connecting to Home Assistant.</dd><hr><dt>Enable Heartbeat<span class="property-type">boolean</span></dt><dd>Enables periodic <strong>ping</strong> messages sent through the WebSocket connection. If no <strong>pong</strong> response is received within 5 seconds, Node-RED automatically attempts to reconnect.</dd><hr><dt>Heartbeat Interval<span class="property-type">number</span></dt><dd>Specifies how often (in seconds) the heartbeat ping is sent. The <strong>minimum value</strong> is <strong>10 seconds</strong>.</dd><hr></dl><h3>Config Settings</h3><dl class="message-properties"><dt>State Boolean<span class="property-type">array of strings</span></dt><dd>Defines which strings should be interpreted as boolean <code>true</code> when comparing state values. Comparisons are <strong>case-insensitive</strong> and ignore surrounding whitespace.</dd><dd><strong>Default values:</strong></dd><pre><code>["y", "yes", "on", "true", "home", "open"]
</code></pre><dd>See <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket../node/conditions.html#home-assistant-boolean" rel="noopener noreferrer">Home Assistant Boolean</a> for more details.</dd><hr><dt>Enable Global Context Store<span class="property-type">boolean</span></dt><dd>When enabled, Home Assistant connection data, states, and services are stored in the Node-RED <strong>global context</strong>. This allows other nodes or function nodes to access Home Assistant data directly.</dd><dd><strong>Example:</strong></dd><pre><code class="language-js">const haCtx = global.get("homeassistant");
const configCtx = haCtx.homeAssistant;
const entityState = configCtx.states["switch.my_switch"];
return entityState.state === "on";
</code></pre><hr></dl><h3>UI Settings</h3><dl class="message-properties"><dt>Cache Autocomplete Results<span class="property-type">boolean</span></dt><dd>Caches JSON autocomplete results for faster UI performance.</dd><hr><dt>ID Selector Display<span class="property-type"></span></dt><dd>Determines which text is shown in selectors after an entity ID has been chosen (for example, name, ID, or friendly name).</dd><hr><dt>Status Date Format<span class="property-type"></span></dt><h5>Separator</h5><dd>A string displayed between the <strong>state</strong> and <strong>date</strong> in an event node’s status text.</dd><h5>Additional Options</h5><dd>Supports all standard <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options">DateTimeFormat Options</a>.</dd><hr></dl><h3>Details</h3><dl class="message-properties"><dd>Every Home Assistant node in Node-RED must reference a <strong>Server Config</strong> node. This configuration defines how Node-RED connects to and communicates with your Home Assistant instance.</dd><hr><dt>Context<span class="property-type"></span></dt><dd>Each Server Config node also exposes data in the <strong>global context</strong>, using the configuration’s <strong>Name</strong> (converted to camelCase) as the namespace.</dd><dd>The following context values are available:</dd><table><thead><tr><th>Key</th><th>Description</th><th>Update Behavior</th></tr></thead><tbody><tr><td><code>states</code></td><td>All entity states</td><td>Always kept up to date as state changes occur</td></tr><tr><td><code>services</code></td><td>Available Home Assistant services</td><td>Loaded on initial deploy</td></tr><tr><td><code>events</code></td><td>Available Home Assistant events</td><td>Loaded on initial deploy</td></tr></tbody></table><hr><dt>Context Example<span class="property-type"></span></dt><dd>If your Server Config node is named <strong>Home Assistant</strong> and you have an entity <code>switch.my_switch</code>, you can access its state with:</dd><pre><code class="language-js">const haCtx = global.get("homeassistant");
const configCtx = haCtx.homeAssistant;
const entityState = configCtx.states["switch.my_switch"];
return entityState.state === "on";
</code></pre><hr></dl><h3>Connection Issues</h3><dl class="message-properties"><dd>Node-RED communicates with Home Assistant using both the <strong>WebSocket</strong> and <strong>REST API</strong>.</dd><dd>If you encounter connection issues:</dd><ol><li><p>Verify that the Home Assistant API is accessible <strong>from the same host</strong> running Node-RED.</p></li><li><p>Test the connection using a REST client or command line:</p><pre><code class="language-bash">curl -H "Authorization: Bearer <YOUR_LONG_LIVED_ACCESS_TOKEN>" \
http://<home_assistant_host>:8123/api/
</code></pre></li><li><p>Confirm that your <strong>Base URL</strong> and <strong>Access Token</strong> are correct.</p></li><li><p>Review the Node-RED logs for any connection or authentication errors.</p></li></ol><hr></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://home-assistant.io/developers/rest_api">Home Assistant REST API</a></li><li><a href="https://developers.home-assistant.io/docs/auth_api/#long-lived-access-token">Home Assistant Long-Lived Access Tokens</a></li><li><a href="https://nodered.org/docs/user-guide/context">Node-RED Context Documentation</a></li></ul></dl></script>
<script type="text/html" data-help-name="api-current-state"><p>This node is used to fetch the last known state of any entity within Home Assistant when it receives an input. It’s useful for making decisions based on the current status of entities, such as checking if a light is already on before turning it off, or determining the temperature reading before adjusting the thermostat.</p><h3>Configuration</h3><dl class="message-properties"><dt>Entity ID <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a></li></ul><dd>The id of the entity to return.</dd><dt>If State<span class="property-type">string</span></dt><dd>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.</dd><dd><strong>Also see:</strong></dd><ul><li><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/conditionals.html" rel="noopener noreferrer">Conditionals</a></li></ul><dt>For<span class="property-type">number</span></dt><dd>The amount of time the entity state needs to have been constant for the "If state" to be <code>true</code></dd><dt>State Type<span class="property-type"></span></dt><div class="home-assistant-custom-block warning"><p class="custom-block-title">DEPRECATED</p><p>This feature is being phased out and will be removed in version <strong>1.0.0</strong>.<br>Use the <strong>output properties</strong> for state conversion moving forward.</p></div><ul><li>Type: <code>string</code></li><li>Values: <code>string|number|boolean</code></li><li>Default: <code>string</code></li></ul><dd>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 (<code>y|yes|true|on|home|open</code>). Original value stored in <code>msg.data.original_state</code></dd><dt>Block Input Overrides<span class="property-type">boolean</span></dt><ul><li>Default: <code>false</code></li></ul><dd>Stop <code>msg.payload</code> values from overriding local config</dd></dl><h3>Inputs</h3><dl class="message-properties"><dt>payload.entityId<span class="property-type">string</span></dt></dl><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>entity</code>: full entity object</li><li><code>entity id</code>: entity id of the triggered entity</li><li><code>entity state</code>: entity state of the triggered entity</li><li><code>config</code>: config properties of the node</li></ul></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://home-assistant.io/docs/configuration/state_object/">Home Assistant State Objects</a></li></ul></dl></script>
<script type="text/html" data-help-name="ha-device-config"><p>The Device Config node is used for configuring devices that have been added to Home Assistant. It allows you to set up and manage device-specific settings and options within Node-RED, ensuring that your automations can correctly interact with your devices.</p><h3>Configuration</h3><dl class="message-properties"><dt>Name<span class="property-type">string</span></dt><dd>The name of the device that will show in Home Assistant</dd><dt>Manufacturer<span class="property-type">string</span></dt><dd>The manufacturer of the device</dd><dt>Model<span class="property-type">string</span></dt><dd>The model of the device</dd><dt>Software Version<span class="property-type">string</span></dt><dd>The software version of the device</dd><dt>Hardware Version<span class="property-type">string</span></dt><dd>The hardware version of the device</dd></dl></script>
<script type="text/html" data-help-name="ha-device"><p>The Device node enables you to create device automations and call device actions within Home Assistant. This node interacts with devices connected to your Home Assistant instance, allowing you to perform tasks such as turning devices on or off, changing settings, or triggering specific device-related actions.</p><h3>Configuration</h3><dl class="message-properties"><dt>Type<span class="property-type">string</span></dt><ul><li>Values: <code>trigger | action</code></li></ul><dt>Device<span class="property-type">string</span></dt><dd>Id of the device</dd><dt>Trigger<span class="property-type">object</span></dt><dd>Home Assistant object of the trigger</dd><dt>Action<span class="property-type">object</span></dt><dd>Home Assistant object of the action</dd><dt>Capabilities<span class="property-type">object</span></dt></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>config</code>: config properties of the node</li><li><code>device id</code>: device id that triggered the node</li><li><code>event data</code>: event data received from Home Assistant</li><li><code>sent data</code>: data sent to Home Assistant</li></ul></dl></script>
<script type="text/html" data-help-name="ha-entity-config"><p>The Entity Config node provides configuration options for the different entity type nodes within Node-RED. It’s used to set up and manage the properties and settings for entities, ensuring they behave as expected within your automations and Home Assistant environment.</p><h3>Configuration</h3><dl class="message-properties"><dt>Name<span class="property-type">string</span></dt><dd>The name of the entity that will show in Node-RED</dd><dt>Device<span class="property-type">string</span></dt><ul><li><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/device-config.html" rel="noopener noreferrer">device config documentation</a></li></ul><dd>A list of devices the entity can be associated with. This is used to group entities together in the UI.</dd><div class="home-assistant-custom-block warning"><p class="custom-block-title">Caveat</p><p>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.</p></div><dt>Type <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><ul><li>Values: <code>binary_sensor|button|sensor|switch</code></li></ul><dt>Resend state and attributes<span class="property-type">boolean</span></dt><dd>When the entity in Home Assistant is created the state and attributes will also be set. This is only applicable with certain entities nodes.</dd><dt>Other Properties<span class="property-type"></span></dt><dd>Configuration options are available for the selected entities</dd><dd><a href="https://developers.home-assistant.io/docs/core/entity">https://developers.home-assistant.io/docs/core/entity</a></dd></dl></script>
<script type="text/html" data-help-name="ha-entity"><div class="home-assistant-custom-block danger"><p class="custom-block-title">DEPRECATED</p><p>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.</p></div><p>Creates an entity in Home Assistant which can be manipulated from this node.</p><p><code>binary sensor</code>, <code>sensor</code>, and <code>switch</code></p><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><h3>Configuration</h3><dl class="message-properties"><dt>Type <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><ul><li>Values <code>binary_sensor|sensor|switch</code></li><li>Default: <code>sensor</code></li></ul><dd>The state the entity should be updated to</dd><dt>Home Assistant Config<span class="property-type">Object</span></dt><dd>Configuration options available for the selected entity</dd><div class="home-assistant-custom-block danger"><p class="custom-block-title">WARNING</p><p>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.</p></div></dl><h3>Sensor Configuration</h3><dl class="message-properties"><dt>State <span text="required" class="home-assistant-badge">required</span><span class="property-type">string | number | boolean</span></dt><dd>The state the entity should be updated to</dd><dt>Attributes<span class="property-type">Object</span></dt><dd>Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]</dd><dt>Input Override<span class="property-type">string</span></dt><ul><li>Values: <code>accept | merge | block</code></li></ul><dd>Determine how input values will be handled. When merge is selected the message object values will override the configuration values.</dd><dt>Resend state and attributes<span class="property-type">boolean</span></dt><dd>When creating the entity in Home Assistant this will also send the last updated state and attributes then node sent to Home Assistant</dd></dl><h3>Switch Configuration</h3><dl class="message-properties"><dt>Output on state change<span class="property-type">boolean</span></dt><dd>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.</dd><dt>Payload<span class="property-type">str | num | bool | JSONata | timestamp</span></dt><dd>Customizable output set to <code>msg.payload</code> if <code>Output on state change</code> is enabled.</dd></dl><h3>Sensors Inputs</h3><dl class="message-properties"><dd>properties of <code>msg.payload</code></dd><dt>state<span class="property-type">string | number | boolean</span></dt><dd>The state the entity should be updated to</dd><dt>attributes<span class="property-type">Object</span></dt><dd>Key/Value pair of attributes to update. The key should be a string and the value can be a <code>[string | number | boolean | object]</code></dd></dl><h3>Switch Inputs</h3><dl class="message-properties"><dt>msg.enable<span class="property-type">boolean</span></dt><dd>Set to <code>true</code> to turn on the switch and <code>false</code> to turn off. If the message has a property <code>enable</code> set to the type <code>boolean</code> the node will not have any output.</dd></dl><h3>Outputs</h3><dl class="message-properties"><dd><strong>Status Color</strong></dd><ul><li>Green/Red: output from the node was due to input to the node</li><li>Blue: output from the node was due to the state of the node changing</li><li>Yellow: state of node changed but no output</li></ul></dl></script>
<script type="text/html" data-help-name="server-events"><p>This node listens for all types of events from Home Assistant, with the ability to filter by event type. It’s a powerful tool for triggering automations based on specific events occurring within Home Assistant, such as state changes, sensor readings, or user interactions.</p><h3>Configuration</h3><dl class="message-properties"><dt>Name<span class="property-type">string</span></dt><dd>the name of the node</dd><dt>Event Type<span class="property-type">string</span></dt><dd>filter by event type or leave blank for all events</dd><div class="home-assistant-custom-block danger"><p class="custom-block-title">WARNING</p><p>Leaving this empty will listen for all events from Home Assistant which may overload the WebSocket message queue.</p><p><a href="https://github.com/zachowj/node-red-contrib-home-assistant-websocket/issues/153#issuecomment-539290950">GitHub Issue #153</a></p></div><dt>Event data<span class="property-type">json</span></dt><dd>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.</dd><dt>Output only after Home Assistant is running<span class="property-type">boolean</span></dt><dd>What until Home Assistant has reported its state as <code>running</code> before outputting events. Client events will always output.</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>event data</code>: event received from Home Assistant</li><li><code>config</code>: config properties of the node</li></ul></dl><h3>Client Events</h3><dl class="message-properties"><dd>Use <code>home_assistant_client</code> as the event type to receive events from the Websocket client.</dd><dd>Events sent from the client:</dd><ul><li><strong>connecting</strong> - when trying to connect to HA</li><li><strong>connected</strong> - after the authorization has been accepted</li><li><strong>disconnected</strong> - when the socket stops attempting to connect or disconnected after having been connected</li><li><strong>error</strong> - when a disconnect happens of the WebSocket with an error</li><li><strong>states_loaded</strong> - the first time all states are loaded from HA</li><li><strong>services_loaded</strong> - the first time all services are loaded from HA</li><li><strong>running</strong> - when HA is in a running state and states have been loaded</li></ul></dl></script>
<script type="text/html" data-help-name="ha-events-calendar"><p>The Calendar node listens for events from Home Assistant's calendar integration. It triggers a flow in Node-RED when a calendar event starts or ends, allowing you to automate actions based on your calendar schedule. This node polls the configured calendar at roughly 15‑minute intervals to discover upcoming items. When a calendar item matches the configured filter it is queued and the node schedules the flow to fire at the selected moment (start or end) adjusted by the configured Offset. Behavior notes:</p><p>The node polls calendars roughly every 15 minutes to discover events, then schedules an exact trigger at the event start or end adjusted by the configured offset. Events are tracked by unique ID to prevent duplicates, recurring and overlapping occurrences are handled independently, and a Node‑RED restart rescans and recovers pending occurrences — but very last‑minute changes between polls may be missed.</p><h3>Configuration:</h3><dl class="message-properties"><dt>Entity ID <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>The entity_id for the calendar that contains triggerable calendar items.</dd><dt>Relative To <span text="required" class="home-assistant-badge">required</span><span class="property-type">start | end</span></dt><ul><li>Default: <code>start</code></li></ul><dd>Whether to trigger an event at the start or end of each matching calendar item.</dd><dt>Offset <span text="required" class="home-assistant-badge">required</span><span class="property-type">number</span></dt><ul><li>Default: 0 seconds</li></ul><dd>A negative or positive amount of time to allow the event to be triggered before or after the calendar item's start/end time.</dd><dt>Filter<span class="property-type">string</span></dt><dd>A string to filter calendar items. If set, only calendar items whose summary contains this string will trigger events.</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>calendar item</code>: the calendar item object as provided by the Home Assistant API</li></ul><pre><code class="language-json">{
"start": "2023-10-01T09:00:00-07:00", // ISO 8601 format with timezone offset
"end": "2023-10-01T10:00:00-07:00", // ISO 8601 format with timezone offset
"summary": "Team Meeting", // Event summary
"description": "Weekly sync with the team", // Event description
"location": "Conference Room A", // Event location
"uid": "12345-abcde-67890-fghij", // Unique identifier for the event
"recurrence_id": null, // Recurrence ID if applicable
"rrule": null, // Recurrence rule if applicable
"all_day": false // Boolean indicating if it's an all-day event
}
</code></pre></dl></script>
<script type="text/html" data-help-name="server-state-changed"><p>The Events: State node listens for state changes of entities within Home Assistant. It triggers a flow in Node-RED whenever an entity's state changes, allowing you to automate responses to various conditions, like turning on lights when motion is detected or sending a notification when a door is opened.</p><h3>Configuration:</h3><dl class="message-properties"><dt>Entity <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>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.</dd><dd>Example:</dd><ul><li><code>light.kitchen</code> (entity) listens for state changes of the <code>light.kitchen</code> entity</li><li><code>^light.*</code> (regex) listens for state changes of all entities that start with <code>light.</code></li><li><code>light</code> (substring) listens for state changes of all entities that contain <code>light</code> in the entity ID</li></ul><dt>If State<span class="property-type">string</span></dt><dd>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.</dd><dd><strong>Also see:</strong></dd><ul><li><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/conditionals.html" rel="noopener noreferrer">Conditionals</a></li></ul><dt>For<span class="property-type">number</span></dt><dd>An amount of time an entity's state needs to be in that state before triggering.</dd><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p>Output on Connect state changes will not start a timer.</p></div><dt>State Type<span class="property-type"></span></dt><div class="home-assistant-custom-block warning"><p class="custom-block-title">DEPRECATED</p><p>This feature is being phased out and will be removed in version <strong>1.0.0</strong>.<br>Use the <strong>output properties</strong> for state conversion moving forward.</p></div><ul><li>Type: <code>string</code></li><li>Values: <code>string|number|boolean</code></li><li>Default: <code>string</code></li></ul><dd>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 (<code>y|yes|true|on|home|open</code>). Original value stored in msg.data.original_state</dd><dt>Ignore state change event<span class="property-type">boolean</span></dt><dd>A list of possible states that will be ignored.</dd><dt>Output on Connect<span class="property-type">boolean</span></dt><dd>Output once on startup/deploy</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>event data</code>: full event object</li><li><code>entity id</code>: entity id of the triggered entity</li><li><code>entity state</code>: entity state of the triggered entity</li><li><code>config</code>: config properties of the node</li></ul></dl></script>
<script type="text/html" data-help-name="ha-fire-event"><p>The Fire Event node allows you to fire an event on the Home Assistant event bus. This can be used to trigger automations or notify other parts of the system about specific occurrences. It’s a way to programmatically generate events that other nodes or systems can listen to and react upon.</p><h3>Configuration</h3><dl class="message-properties"><dt>Event <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>Event name to fire</dd><dt>data<span class="property-type">Object</span></dt><dd>JSON object to pass along</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>If the incoming message has a <code>payload</code> property with <code>event</code> set it will override any config values if set. If the incoming message has a <code>payload.data</code> that is an object or parsable into an object these properties will be <strong>merged</strong> with any config values set. If the node has a property value in its config for <code>Merge Context</code> then the <code>flow</code> and <code>global</code> contexts will be checked for this property which should be an object that will also be merged into the data payload.</dd><dt>payload.event<span class="property-type">string</span></dt><dd>Event to fire</dd><dt>payload.data<span class="property-type">Object</span></dt><dd>Event data to send</dd></dl><h3>Outputs</h3><dl class="message-properties"><dt>payload.event_type<span class="property-type">string</span></dt><dd>Event Type that was fired</dd><dt>payload.data<span class="property-type">Object</span></dt><dd>The event <code>data</code> sent if one was used</dd></dl><h3>References</h3><dl class="message-properties"><dd><a href="https://developers.home-assistant.io/docs/en/dev_101_events.html#firing-events">Home Assistant Events</a></dd></dl></script>
<script type="text/html" data-help-name="ha-get-entities"><p>The Get Entities node retrieves entities based on specific search criteria, with three different output options. This node is useful for filtering and finding entities that match certain conditions, such as all lights that are currently on, or sensors reporting a specific range of values.</p><h3>Configuration</h3><dl class="message-properties"><dt>Search Criteria<span class="property-type"></span></dt><dd>All specified criteria must be met for an entity to be considered valid.</dd><dt>Property<span class="property-type"></span></dt><dd>Autocomplete is available for all properties currently set on loaded entities.</dd></dl><h3>Inputs</h3><dl class="message-properties"><dt>Payload<span class="property-type">Object</span></dt><dd>Override the configuration values by passing in a property with a valid value.</dd><ul><li><code>rules</code> (array)<ul><li><code>condition</code>: string (e.g., <code>state_object</code>, <code>label_registry</code>, <code>area_registry</code>, <code>device_registry</code>, <code>floor_registry</code>)</li><li><code>property</code>: string</li><li><code>logic</code>: string</li><li><code>value</code>: string</li><li><code>valueType</code>: string</li></ul></li><li><code>outputType</code>: string</li><li><code>outputEmptyResults</code>: boolean</li><li><code>outputLocationType</code>: string</li><li><code>outputLocation</code>: string</li><li><code>outputResultsCount</code>: number</li></ul><h5>Example</h5><dd>To retrieve all entities with the device class <code>battery</code> on the <code>First floor</code> that are not labeled <code>not replaceable</code>, include the following in the <code>payload</code> property of the message:</dd><pre><code class="language-json">{
"rules": [
{
"condition": "state_object",
"property": "attributes.device_class",
"logic": "is",
"value": "battery",
"valueType": "str"
},
{
"condition": "floor_registry",
"property": "name",
"logic": "is",
"value": "First floor",
"valueType": "str"
},
{
"condition": "label_registry",
"property": "name",
"logic": "is_not",
"value": "not replaceable",
"valueType": "str"
}
]
}
</code></pre></dl><h3>Outputs</h3><dl class="message-properties"><dt>Array<span class="property-type">Array</span></dt><dd>Returns an array of state objects based on the search criteria and sends them to the specified output location.</dd><dt>Count<span class="property-type">number</span></dt><dd>Returns the total count of valid entities.</dd><dt>Random<span class="property-type">Object | Array</span></dt><dd>Returns a random object or array from the available state objects. If <code>One Max Results</code> is selected, it will return a single object; otherwise, it will return an array of state objects.</dd><dt>Split<span class="property-type">msg.part</span></dt><dd>Sends a separate message for each state object, similar to the output of a split node.</dd></dl><h3>State Object Format</h3><dl class="message-properties"><dd>Sample output when the output type is an array:</dd><pre><code class="language-json">[
{
"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
}
]
</code></pre><dt>entity_id<span class="property-type">string</span></dt><dd>The entity to which this state belongs.</dd><dt>state<span class="property-type">string</span></dt><dd>The main attribute state value, such as 'on', 'off', 'home', 'open', 'closed', etc.</dd><dt>attributes<span class="property-type">Object</span></dt><dd>Supported attributes of the state as set by Home Assistant.</dd><dt>last_changed<span class="property-type">string</span></dt><dd>ISO Date string representing the last time the entity state changed.</dd><dt>timeSinceChangedMs<span class="property-type">number</span></dt><dd>Milliseconds since the last state change of the entity.</dd><dt>last_updated<span class="property-type">string</span></dt><dd>ISO Date string representing the last time the entity state was updated.</dd><dt>context<span class="property-type">Object</span></dt><dd>Information about who or what last changed the state of this entity.</dd></dl><h3>Examples</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/get-entities.html#examples">link</a></p></div></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://home-assistant.io/docs/configuration/state_object/">Home Assistant State Objects</a></li></ul></dl></script>
<script type="text/html" data-help-name="api-get-history"><p>The Get History node fetches the history of Home Assistant entities based on input criteria. This can be used to analyze past states or events, such as tracking temperature changes over time or reviewing when a door was last opened. It’s useful for creating more complex automations based on historical data.</p><h3>Configuration</h3><dl class="message-properties"><dt>Entity ID<span class="property-type">string</span></dt><dd>The entity id to fetch history for. Can be a single entity id or a comma separated list of entity ids.</dd><dt>Entity ID Type<span class="property-type">string</span></dt><ul><li>Values: <code>==</code> | <code>regex</code></li></ul><dd>The type of entity id matching to use. <code>==</code> will do an exact match, <code>regex</code> will use a regular expression to match the entity ids.</dd><dt>Start Date<span class="property-type">string</span></dt><ul><li>Values: ISO Formattted Date</li><li>Default: 24 hours prior</li></ul><dd>Date to start fetching history from. Will override the configuration if passed in. If <code>relativetime</code> is used this will be ignored.</dd><dd><strong>Also See:</strong></dd><ul><li><a href="https://en.wikipedia.org/wiki/ISO_8601">https://en.wikipedia.org/wiki/ISO_8601</a></li></ul><dt>End Date<span class="property-type">string</span></dt><ul><li>Values: ISO Formattted Date</li><li>Default: 24 hours from start date</li></ul><dd>The end date to fetch history too. Will override the configuration if passed in. If <code>relativetime</code> is used this will be ignored.</dd><dd><strong>Also See:</strong></dd><ul><li><a href="https://en.wikipedia.org/wiki/ISO_8601">https://en.wikipedia.org/wiki/ISO_8601</a></li></ul><dt>Use Relative Time<span class="property-type">boolean</span></dt><dd>A checkbox to use relative time or not. If checked the <code>startdate</code> and <code>enddate</code> will be ignored and the <code>relativetime</code> will be used instead.</dd><dt>In the Last<span class="property-type">string</span></dt><dd>A time string that will be parsed the following keywords into time values.</dd><dd>Example: <code>4h 30m</code> = The last 4 hours and 30 minutes</dd><pre><code>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
</code></pre><dt>Flatten Results<span class="property-type"></span></dt><dd>Instead of returning the data from home assistant ( array for each entity_id ) return one flattened array of one item per history entry</dd><dt>Output Types<span class="property-type">string</span></dt><ul><li>Values: <code>array</code> | <code>split</code></li><li>Default: <code>array</code></li></ul><dd>The type of output to return. <code>array</code> will return an array of history objects. <code>split</code> will return an array of history objects for each entity id.</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>All properties of <code>msg.payload</code></dd><dt>entityId<span class="property-type">string</span></dt><dt>entityIdType<span class="property-type">equalregex</span></dt><dt>startDate<span class="property-type">string</span></dt><ul><li>Values: ISO Formattted Date</li></ul><dt>endDate<span class="property-type">string</span></dt><ul><li>Values: ISO Formattted Date</li></ul><dt>relativeTime<span class="property-type">string</span></dt><dt>flatten<span class="property-type">boolean</span></dt></dl><h3>Outputs</h3><dl class="message-properties"><dt>payload<span class="property-type">array</span></dt><dd>The history returned by home-assistant, which is an array of arrays where each array entry contains history objects for one particular entity</dd><dd>Example output of <code>msg</code>:</dd><pre><code class="language-json">{
"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"
},
...
]
}
</code></pre></dl><h3>Examples</h3><dl class="message-properties"><dd><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket../cookbook/check-if-an-entity-was-turned-on-in-the-last-24-hours.html" rel="noopener noreferrer">Check if an entity was a certain state in the last 24 hours</a></dd></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://www.home-assistant.io/integrations/history">Home Assistant History Component</a></li><li><a href="https://developers.home-assistant.io/docs/en/external_api_rest.html#get-apihistoryperiodlttimestamp">Home Assistant API: /api/history/period</a></li></ul></dl></script>
<script type="text/html" data-help-name="ha-number"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>The Number node creates a number entity in Home Assistant that can be manipulated from within Node-RED. This entity type is typically used to represent numeric values that can be adjusted, such as a thermostat setting or a brightness level for lights.</p><h3>Configuration</h3><dl class="message-properties"><dt>Mode <span text="required" class="home-assistant-badge">required</span><span class="property-type"></span></dt><dd>The mode of the node</dd><dt>Value <span text="required" class="home-assistant-badge">required</span><span class="property-type">number</span></dt><dd>The value of the entity should be updated to</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>properties of <code>msg.payload</code></dd><dt>value<span class="property-type">number</span></dt><dd>The value of the entity should be updated to</dd></dl><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>value</code>: The value of the entity</li><li><code>previous value</code>: The previous value of the entity</li><li><code>config</code>: The config properties of the node</li></ul></dl><h3>Examples</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/number.html#examples">link</a></p></div></dl></script>
<script type="text/html" data-help-name="poll-state"><p>The Poll State node outputs the state of an entity at regular intervals. It can also be configured to trigger at startup and whenever the entity changes state, if desired. This node is useful for regularly checking the status of an entity, ensuring your automations stay up to date with the latest information.</p><h3>Configuration</h3><dl class="message-properties"><dt>Entity ID <span text="required" class="home-assistant-badge">required</span><span class="property-type"></span></dt><dd>The entity id of the entity to poll for.</dd><dt>Update Interval<span class="property-type">number</span></dt><dd>The amount of time between checking/sending updates.</dd><dt>If State<span class="property-type">string</span></dt><dd>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.</dd><dd><strong>Also see:</strong></dd><ul><li><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/conditionals.html" rel="noopener noreferrer">Conditionals</a></li></ul><dt>State Type<span class="property-type"></span></dt><div class="home-assistant-custom-block warning"><p class="custom-block-title">DEPRECATED</p><p>This feature is being phased out and will be removed in version <strong>1.0.0</strong>.<br>Use the <strong>output properties</strong> for state conversion moving forward.</p></div><ul><li>Type: <code>string</code></li></ul><dd>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</dd><dt>Output Initially<span class="property-type">boolean</span></dt><dd>Output once on startup/deploy then on each interval</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dt>topic<span class="property-type">string</span></dt><dd>entity_id of changed entity</dd><dt>payload<span class="property-type">object</span></dt><dd>The last known state of the entity</dd><dt>data.timeSinceChanged<span class="property-type">string</span></dt><dd>Human readable format string of time since last updated, example "1 hour ago"</dd><dt>data.timeSinceChangedMs<span class="property-type">number</span></dt><dd>Number of milliseconds since last changed</dd></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://home-assistant.io/docs/configuration/state_object/">Home Assistant State Objects</a></li></ul></dl></script>
<script type="text/html" data-help-name="api-render-template"><p>The Render Template node allows you to render templates based on input data. Templates in Home Assistant are powerful tools for dynamically generating text or values based on the state of entities or other variables. This node sends the template to Home Assistant for rendering and outputs the result.</p><div class="home-assistant-custom-block tip"><p class="custom-block-title">NOTE:</p><p>The node will output any Home Assistant API errors for catching with the 'catch-all' node</p></div><h3>Configuration</h3><dl class="message-properties"><dt>template<span class="property-type">string</span></dt><dd>Jinja template to be rendered, discarded if <code>msg.template</code> is provided via input msg</dd><dt>Template Location<span class="property-type"></span></dt><dd>Customizable location to output original template</dd><dt>Results<span class="property-type"></span></dt><dd>Customizable location to output rendered template</dd></dl><h3>Inputs</h3><dl class="message-properties"><dt>template<span class="property-type">string</span></dt><dd>Jinja template to be rendered</dd></dl><h3>Outputs</h3><dl class="message-properties"><dt>template<span class="property-type">string</span></dt><dd>The original template sent to Home Assistant for rendering</dd><dt>payload<span class="property-type">string</span></dt><dd>The rendered template</dd></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://home-assistant.io/docs/configuration/templating/">Home Assistant Template Docs</a></li><li><a href="http://jinja.pocoo.org/docs/dev/templates/">Jinja Docs</a></li></ul></dl></script>
<script type="text/html" data-help-name="ha-select"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>The Select node creates a select entity in Home Assistant that can be manipulated from Node-RED. This type of entity typically represents a dropdown menu or a list of options from which the user can choose, and it can be used to control or adjust settings within your automations.</p><h3>Configuration</h3><dl class="message-properties"><dt>Mode <span text="required" class="home-assistant-badge">required</span><span class="property-type"></span></dt><dd>The mode of the node</dd><dt>value <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>A string to the set current value of the select entity</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>properties of <code>msg.payload</code></dd><dt>Value<span class="property-type">string</span></dt><dd>The string of the text entity should be updated to</dd></dl><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>value</code>: The text string of the entity</li><li><code>previous value</code>: The previous text string of the entity</li><li><code>config</code>: The config properties of the node</li></ul></dl><h3>Examples</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/select.html#examples">link</a></p></div></dl></script>
<script type="text/html" data-help-name="ha-sensor"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>The Sensor node creates a sensor entity within Home Assistant that is controlled from Node-RED. Sensors are entities that report data from various sources, such as temperature, humidity, or motion detection. This node allows you to create and manage such sensors directly from your Node-RED flows.</p><h3>Configuration</h3><dl class="message-properties"><dt>State <span text="required" class="home-assistant-badge">required</span><span class="property-type">string | number | boolean</span></dt><dd>The state the entity should be updated to</dd><dd>To set the Home Assistant state to <code>Unknown</code>, send a state with a js expression <code>null</code>.</dd><dt>Attributes<span class="property-type">Object</span></dt><dd>Key/Value pair of attributes to update. The key should be a string and the value can be a [string | number | boolean | object]</dd><dt>Input Override<span class="property-type">string</span></dt><ul><li>Values: <code>accept | merge | block</code></li></ul><dd>Determine how input values will be handled. When merge is selected the message object values will override the configuration values.</dd><dt>Resend state and attributes<span class="property-type">boolean</span></dt><dd>When creating the entity in Home Assistant this will also send the last updated state and attributes then node sent to Home Assistant</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>properties of <code>msg.payload</code></dd><dt>state<span class="property-type">string | number | boolean</span></dt><dd>The state the entity should be updated to</dd><dt>attributes<span class="property-type">Object</span></dt><dd>Key/Value pair of attributes to update. The key should be a string and the value can be a <code>[string | number | boolean | object]</code></dd></dl></script>
<script type="text/html" data-help-name="ha-sentence"><p>The <strong>Sentence</strong> node is triggered when the Home Assistant <a href="https://www.home-assistant.io/voice_control/">Assist</a> feature matches a sentence from a voice assistant using the default <a href="https://www.home-assistant.io/integrations/conversation/">conversation agent</a>. This node enables voice control integrations, allowing specific voice commands to trigger automations within Node-RED.</p><p>Sentences support basic template syntax. Refer to the Home Assistant <a href="https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger">documentation</a> for more details.</p><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p>This node requires the <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> to be installed in Home Assistant.</p></div><h3>Configuration Options</h3><dl class="message-properties"><dt>Mode<span class="property-type">string</span></dt><ul><li><strong>Options</strong>:<ul><li><code>trigger</code></li><li><code>response</code></li></ul></li></ul><dd>Defines the node’s function.<br>If set to <strong>trigger</strong>, the node activates when a sentence is matched.<br>If set to <strong>response</strong>, the node sends a dynamic response back to Home Assistant.</dd><dt>Sentences<span class="property-type">string</span></dt><dd>A list of sentences to match. Supports basic template syntax. For more details, see the Home Assistant <a href="https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger">documentation</a>.</dd><dt>Response Type<span class="property-type">string</span></dt><ul><li><strong>Options</strong>:<ul><li><code>dynamic</code></li><li><code>fixed</code></li></ul></li></ul><dd>Specifies the type of response sent to Home Assistant:</dd><ul><li><strong>Fixed</strong>: The same response is sent for all matched sentences.</li><li><strong>Dynamic</strong>: The response is determined by the node set to response mode.</li></ul><dt>Response<span class="property-type">string</span></dt><dd>The message sent to Home Assistant when a sentence is matched. This option is used only if the <strong>Response Type</strong> is set to <code>fixed</code>.</dd><dt>Fallback Response<span class="property-type">string</span></dt><dd>The message sent to Home Assistant when a timeout occurs. This is used when the <strong>Response Type</strong> is set to <code>dynamic</code>.</dd><dt>Response Timeout<span class="property-type">number</span></dt><dd>Specifies the time in milliseconds to wait for a response before sending the <strong>Fallback Response</strong>. This option is used only when the <strong>Response Type</strong> is set to <code>dynamic</code>.</dd><dt>Expose As<span class="property-type">string</span></dt><dd>Select an entity to create a switch in Home Assistant. Turning the switch on or off will enable or disable this node in Node-RED.</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>All properties must be provided in <code>msg.payload</code>.</dd><dd>Example input:</dd><pre><code class="language-json">{
"response": "The light is now on"
}
</code></pre><dt>Response<span class="property-type">string</span></dt><dd>The response sent to Home Assistant when a sentence is matched. This is used only when the <strong>Response Type</strong> is set to <code>dynamic</code>.</dd></dl><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>trigger id</code>: The sentence that triggered the flow.</li><li><code>config</code>: The node's configuration properties.</li></ul></dl><h3>Examples</h3><dl class="message-properties"><div><p>For detailed usage examples, see the <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/sentence.html#examples">Examples</a> section.</p></div></dl></script>
<script type="text/html" data-help-name="ha-switch"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>The Switch node creates a switch entity within Home Assistant that can be controlled from Node-RED. This node also allows a flow to be started from a service call, making it a versatile tool for both controlling devices and triggering automations.</p><h3>Configuration</h3><dl class="message-properties"><dt>Enable input<span class="property-type"></span></dt><dd>Input is disabled by default. It can be enabled by checking this option.</dd><dt>Output on state change<span class="property-type">boolean</span></dt><dd>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.</dd></dl><h3>Inputs</h3><dl class="message-properties"><dt>msg.enable<span class="property-type">boolean</span></dt><dd>Set to <code>true</code> to turn on the switch and <code>false</code> to turn it off. If the message has a property <code>enable</code> defined and set to a <code>boolean</code> the node will not have any output.</dd></dl><h3>Outputs</h3><dl class="message-properties"><dd><strong>Status Color</strong></dd><ul><li>Green/Red: output from the node was due to input to the node</li><li>Blue: output from the node was due to the state of the node changing</li><li>Yellow: state of node changed but no output</li></ul></dl><h3>Examples</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/switch.html#examples">link</a></p></div></dl></script>
<script type="text/html" data-help-name="ha-tag"><p>The Tag node outputs data when Home Assistant receives a tag scanned event for a configured tag ID. This node is useful for creating automations based on NFC tags or other scannable identifiers, allowing specific actions to be triggered when a tag is scanned.</p><h3>Configuration</h3><dl class="message-properties"><dt>Tags<span class="property-type">array</span></dt><dd>An array of tag ids to monitor for tag scanned events.</dd><dt>Devices<span class="property-type">array</span></dt><dd>An array of device ids to check when a configured tag is scanned.</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>event data</code>: full event object</li><li><code>tag id</code>: tag id of the tag that was scanned.</li><li><code>config</code>: config properties of the node</li></ul><dt>event object<span class="property-type">object</span></dt><table><thead><tr><th>Field</th><th>Description</th></tr></thead><tbody><tr><td>device_id</td><td>ID of the device that scanned the tag</td></tr><tr><td>tag_id</td><td>ID of the tag that was scanned</td></tr><tr><td>tag_name</td><td>Home Assistant name of the tag that was scanned</td></tr><tr><td>user_id</td><td>Home Assistant user ID on device that scanned the tag</td></tr></tbody></table></dl></script>
<script type="text/html" data-help-name="ha-text"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>The Text node creates a text entity within Home Assistant that can be manipulated from Node-RED. Text entities are used to store and display text values, and this node allows you to dynamically update and control these values within your automations.</p><h3>Configuration</h3><dl class="message-properties"><dt>Mode <span text="required" class="home-assistant-badge">required</span><span class="property-type"></span></dt><dd>The mode of the node</dd><dt>Text <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>The string of the entity should be updated to</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>properties of <code>msg.payload</code></dd><dt>Text<span class="property-type">string</span></dt><dd>The string of the text entity should be updated to</dd></dl><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>value</code>: The text string of the entity</li><li><code>previous value</code>: The previous text string of the entity</li><li><code>config</code>: The config properties of the node</li></ul></dl><h3>Examples</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/text.html#examples">link</a></p></div></dl></script>
<script type="text/html" data-help-name="ha-time-entity"><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><p>The Time Entity node creates a time entity within Home Assistant that can be controlled from Node-RED. This entity type is used to represent time values, such as a specific time of day or a duration, and can be used to trigger automations based on time-related conditions.</p><h3>Configuration</h3><dl class="message-properties"><dt>Mode <span text="required" class="home-assistant-badge">required</span><span class="property-type"></span></dt><dd>The mode of the node</dd><dt>Value <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><ul><li>Format: <code>HH:mm:ss</code> | <code>HH:mm</code></li></ul><dd>The value of the entity should be updated to</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>properties of <code>msg.payload</code></dd><dt>value<span class="property-type">string</span></dt><ul><li>Format: <code>HH:mm:ss</code> | <code>HH:mm</code></li></ul><dd>The value of the entity should be updated to</dd></dl><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>value</code>: The value of the entity</li><li><code>previous value</code>: The previous value of the entity</li><li><code>config</code>: The config properties of the node</li></ul></dl><h3>Examples</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/time-entity.html#examples">link</a></p></div></dl></script>
<script type="text/html" data-help-name="ha-time"><p>The Time node can be scheduled to trigger at a specific future date and time, based on a Home Assistant entity. This node is useful for creating time-based automations, such as triggering a notification or alarm at a specific hour.</p><h3>Configuration</h3><dl class="message-properties"><dt>Entity Id<span class="property-type">string</span></dt><dd>A Home Assistant entity to be used when scheduling the node.</dd><dt>Property<span class="property-type">string</span></dt><dd>Which property of the entity object to use to schedule the node.</dd><dd>example properties:</dd><ul><li><code>entity_id</code></li><li><code>state</code></li><li><code>attributes.date</code></li><li><code>last_updated</code></li></ul><dd>example values for the property:</dd><ul><li><code>2020-12-31T02:47:54.837Z</code></li><li><code>1609382842709</code></li><li><code>13:40</code></li><li><code>23:59:02</code></li></ul><dt>Offset<span class="property-type">number</span></dt><dd>A negative or positive number that will be added to the scheduled time.</dd><dt>Randomize time within the offset<span class="property-type">boolean</span></dt><dd>When selected the time to trigger will be random selected from the scheduled time to the +/- offset.</dd><dt>Payload<span class="property-type">string | number | boolean | object</span></dt><dd>The payload is fully customizable. The default will be a JSONata expression that outputs the entity state.</dd><dt>Repeat Daily<span class="property-type">boolean</span></dt><dd>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.</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dt>topic<span class="property-type">string</span></dt><dd>The entity id in the configuration.</dd><dt>payload<span class="property-type">string | number | boolean | object</span></dt><dt>data<span class="property-type">object</span></dt><dd>The entity object of the entity in the configuration.</dd></dl></script>
<script type="text/html" data-help-name="trigger-state"><p>The Trigger: State node functions similarly to the State Changed Node but provides advanced functionality for common automation use cases. This node allows for more complex conditions and actions based on entity state changes, making it a powerful tool for creating detailed and nuanced automations.</p><h3>Configuration</h3><dl class="message-properties"><dt>Entity <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>Example:</dd><ul><li><code>light.kitchen</code> (entity) listens for state changes of the <code>light.kitchen</code> entity</li><li><code>^light.*</code> (regex) listens for state changes of all entities that start with <code>light.</code></li><li><code>light</code> (substring) listens for state changes of all entities that contain <code>light</code> in the entity ID</li></ul><dt>State Type<span class="property-type"></span></dt><div class="home-assistant-custom-block warning"><p class="custom-block-title">DEPRECATED</p><p>This feature is being phased out and will be removed in version <strong>1.0.0</strong>.<br>Use the <strong>output properties</strong> for state conversion moving forward.</p></div><ul><li>Type: <code>string</code></li><li>Values: <code>string|number|boolean</code></li><li>Default: <code>string</code></li></ul><dd>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 (<code>y|yes|true|on|home|open</code>). Original value stored in msg.data.original_state</dd><dt>Conditions<span class="property-type"></span></dt><dd>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.</dd><dd><strong>See Also:</strong></dd><ul><li><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/conditionals.html" rel="noopener noreferrer">Conditionals</a></li></ul><dt>Custom Outputs<span class="property-type"></span></dt><dd>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.</dd><dt>Output on connect<span class="property-type">boolean</span></dt><dd>Output once on startup/deployment.</dd><dt>Enable input<span class="property-type">boolean</span></dt><dd>Enable the input to be used to send a message to the node.</dd><dt>Output debug information<span class="property-type">boolean</span></dt><dd>Output debug information to the debug tab.</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Input</h3><dl class="message-properties"><dd>Input is disabled by default. It can be enabled using the <code>Enable Input</code> option. Input can be used to enable/disable the node or for testing.</dd><dt>Enable / Disable<span class="property-type">string</span></dt><dd>If the incoming payload or message is a string and equal to <code>enable</code> or <code>disable</code> then set the node accordingly. Saves over restarts.</dd></dl><h3>Output</h3><dl class="message-properties"><dt>topic<span class="property-type">string</span></dt><dd>The entity_id that triggered the node</dd><dt>payload<span class="property-type">string</span></dt><dd>The state as sent by home assistant</dd><dt>data<span class="property-type">object</span></dt><dd>The original home assistant event containing <code>entity_id</code> <code>new_state</code> and <code>old_state</code> properties</dd></dl><h3>Testing</h3><dl class="message-properties"><dd>To test automation without having to manually change the state in home assistant send an input <code>payload</code> as an object which contains <code>entity_id</code>, <code>new_state</code>, and <code>old_state</code> properties. This will trigger the node as if the event came from Home Assistant.</dd><pre><code class="language-json">{
"entity_id": "test_entity",
"old_state": {
"state": "on"
},
"new_state": {
"state": "off"
}
}
</code></pre></dl><h3>References</h3><dl class="message-properties"><ul><li><a href="https://home-assistant.io/docs/configuration/state_object">HA State Object</a></li></ul></dl></script>
<script type="text/html" data-help-name="ha-update-config"><p>The Update Config node allows you to update the configuration of entities within Home Assistant. This node is used for dynamically adjusting the settings of entities, ensuring they stay in sync with your automation requirements.</p><h3>Configuration</h3><dl class="message-properties"><dt>Name<span class="property-type">string</span></dt><dd>A name for the node.</dd><dt>Server<span class="property-type">string</span></dt><dd>The node id of a <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/config-server.html" rel="noopener noreferrer">Server Config</a> node.</dd><dt>Entity Config<span class="property-type">string</span></dt><dd>The node id of an <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/entity-config.html" rel="noopener noreferrer">entity config</a>. This can be overridden by the <code>payload.id</code> property on the msg object.</dd></dl><h3>Inputs</h3><dl class="message-properties"><dd>All properties must be under <code>msg.payload</code> and will be ignored if not.</dd><dt>Example input<span class="property-type"></span></dt><dd>Example of the <code>msg.payload</code> object.</dd><pre><code class="language-json">{
"id": "d9d27ac6b4ebf78f",
"icon": "mdi:lightbulb",
"name": "My Light",
"entityPicture": "/local/images/my_light.png"
}
</code></pre><dt>id<span class="property-type">string</span></dt><dd>The node id of an entity config.</dd><dt>icon<span class="property-type">string</span></dt><dd>The icon to use for the entity.</dd><dt>name<span class="property-type">string</span></dt><dd>The friendly name to use for the entity.</dd><dt>entityPicture<span class="property-type">string</span></dt><dd>The entity picture to use for the entity.</dd></dl><h3>Examples</h3><dl class="message-properties"><div><p><a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/update-config.html#examples">link</a></p></div></dl>```</script>
<script type="text/html" data-help-name="ha-wait-until"><p>The Wait Until node waits for a specific condition to be met or for a timeout to occur before passing on the last received message. This node is useful for pausing the flow of automation until certain criteria are met, such as waiting for a door to close before turning off the lights.</p><h3>Configuration</h3><dl class="message-properties"><dt>Entities <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><ul><li>Accepts <a href="https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/mustache-templates.html" rel="noopener noreferrer">Mustache Templates</a> only for entity type</li></ul><dd>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.</dd><dd>The types that can be used are: entity id, substring, and regex.</dd><h5>Examples</h5><ul><li><code>light.living_room</code> - Will wait for the entity with the id <code>light.living_room</code></li><li><code>motion</code> - Will wait for any entity that has <code>motion</code> in the entity id</li><li><code>^light\..*</code> - Will wait for any entity that starts with <code>light.</code></li></ul><dt>Wait Until <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>The <code>property</code> field will be checked against the <code>value</code> field using the comparator.</dd><dt>Timeout<span class="property-type">number</span></dt><dd>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.</dd><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p>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.</p></div><dt>Check against the current state<span class="property-type">boolean</span></dt><dd>When an input is received it will check the comparator against the current state instead of waiting for a state change.</dd><div class="home-assistant-custom-block tip"><p class="custom-block-title">INFO</p><p>This is only available when there is only one entity selected</p></div></dl><h3>Input</h3><dl class="message-properties"><dt>reset<span class="property-type"></span></dt><dd>If the received message has this property set to any value the node will be set to inactive and the timeout cleared.</dd><dt>payload<span class="property-type">object</span></dt><dt>Example<span class="property-type"></span></dt><dt>Full Payload<span class="property-type"></span></dt><pre><code class="language-json">{
"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
}
</code></pre><h5>Override with a Single Entity</h5><pre><code class="language-json">{
"entities": "light.living_room"
}
</code></pre><h5>Override with a Several Entities</h5><pre><code class="language-json">{
"entities": ["light.living_room", "light.bedroom"]
}
</code></pre></dl><h3>Output</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>entity</code>: entity data of the triggered entity. Will be <code>undefined</code> if multiple entities are selected and the timeout occurs.</li><li><code>config</code>: config properties of the node</li></ul></dl></script>
<script type="text/html" data-help-name="ha-webhook"><p>The Webhook node outputs data received from a created webhook in Home Assistant. Webhooks are a way to receive data or trigger automations from external sources, and this node allows you to integrate those triggers into your Node-RED flows.</p><div class="home-assistant-custom-block warning"><p class="custom-block-title">WARNING</p><p><em>Needs <a href="https://github.com/zachowj/hass-node-red">Custom Integration</a> installed in Home Assistant for this node to function</em></p></div><h3>Configuration</h3><dl class="message-properties"><dt>ID <span text="required" class="home-assistant-badge">required</span><span class="property-type">string</span></dt><dd>A string to be used for the webhook URL in Home Assistant.</dd><dt>Allowed Methods <span text="required" class="home-assistant-badge">required</span><span class="property-type">list</span></dt><dd>A list of allowed methods that Home Assistant will accept for the webhook. At least one method must be selected.</dd></dl><!-- @include: @snippets/node/expose-as.md --><h3>Outputs</h3><dl class="message-properties"><dd>Value types:</dd><ul><li><code>received data</code>: The parsed body from the webhook request</li><li><code>trigger id</code>: webhook id</li><li><code>headers</code>: entity state of the triggered entity</li><li><code>params</code>: Query string parameters</li><li><code>config</code>: config properties of the node</li></ul></dl></script>
<script type="text/html" data-help-name="ha-zone"><p>The Zone node outputs data when a configured entity enters or leaves one of the defined zones in Home Assistant. Zones are geographical areas you define in Home Assistant, and this node can trigger automations based on whether entities (like phones or trackers) enter or exit these zones.</p><h3>Configuration</h3><dl class="message-properties"><dt>Entities<span class="property-type">array</span></dt><dd>An array of entity ids to monitor for zone changes.</dd><dt>Event<span class="property-type">string</span></dt><dd>Set when to check an entity. Either entering or leaving a zone.</dd><dt>Zones<span class="property-type">array</span></dt><dd>An array of zone ids to check when a configured entity updates.</dd></dl><h3>Outputs</h3><dl class="message-properties"><dt>topic<span class="property-type">string</span></dt><dd>The entity id of the device/person that triggered the update.</dd><dt>payload<span class="property-type">string</span></dt><dd>The state of the device/person entity that triggered the update.</dd><dt>data<span class="property-type">object</span></dt><dd>The entity object of the device/person that triggered the update.</dd><dt>zones<span class="property-type">array</span></dt><dd>An array of zone entities where the device/person entity entered/left after an update of location.</dd></dl><!-- @include: @snippets/node/expose-as.md --></script>
<script type="text/html" data-template-name="ha_entity_filter"><div class="form-row ha-entity-search-row"><label data-i18n="home-assistant.label.filter_results_label"></label> <input type="text"></div><div class="form-row ha-entity-search-row"><ul></ul></div></script>
<script type="text/html" data-template-name="ha_sidebar"><div class="home-assistant-sidebar-container"></div></script>
<script type="text/html" data-template-name="ha_sidebar_toolbar"><div><a class="red-ui-footer-button" id="home-assistant-diagnostics-button" href="#"><i class="fa fa-cogs"></i></a></div></script>
<script type="text/html" id="handlebars-notification-bar" data-template-name="x-tmpl-handlebars"><li class="ha-notification"><svg width="24" height="24" viewBox="0 0 240 240" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M240 224.762C240 233.012 233.25 239.762 225 239.762H15C6.75 239.762 0 233.012 0 224.762V134.762C0 126.512 4.77 114.993 10.61 109.153L109.39 10.3725C115.22 4.5425 124.77 4.5425 130.6 10.3725L229.39 109.162C235.22 114.992 240 126.522 240 134.772V224.772V224.762Z" fill="#F2F4F9"></path><path d="M229.39 109.153L130.61 10.3725C124.78 4.5425 115.23 4.5425 109.4 10.3725L10.61 109.153C4.78 114.983 0 126.512 0 134.762V224.762C0 233.012 6.75 239.762 15 239.762H107.27L66.64 199.132C64.55 199.852 62.32 200.262 60 200.262C48.7 200.262 39.5 191.062 39.5 179.762C39.5 168.462 48.7 159.262 60 159.262C71.3 159.262 80.5 168.462 80.5 179.762C80.5 182.092 80.09 184.322 79.37 186.412L111 218.042V102.162C104.2 98.8225 99.5 91.8425 99.5 83.7725C99.5 72.4725 108.7 63.2725 120 63.2725C131.3 63.2725 140.5 72.4725 140.5 83.7725C140.5 91.8425 135.8 98.8225 129 102.162V183.432L160.46 151.972C159.84 150.012 159.5 147.932 159.5 145.772C159.5 134.472 168.7 125.272 180 125.272C191.3 125.272 200.5 134.472 200.5 145.772C200.5 157.072 191.3 166.272 180 166.272C177.5 166.272 175.12 165.802 172.91 164.982L129 208.892V239.772H225C233.25 239.772 240 233.022 240 224.772V134.772C240 126.522 235.23 115.002 229.39 109.162V109.153Z" fill="#18BCF2"></path></svg><div id="notification-issues"><span class="ha-issue-count">{{issuesCount}}</span> <i class="fa fa-exclamation-triangle"></i></div></li></script>
<script type="text/html" id="handlebars-sidebar-filter" data-template-name="x-tmpl-handlebars"><div class="ha-list-filter"><select><option value="__all__"></option>{{#each types}}<option value="{{this}}">{{this}}</option>{{/each}}</select></div></script>
<script type="text/html" id="handlebars-sidebar-issues-list" data-template-name="x-tmpl-handlebars">{{#each issues}}<li data-id="{{this.id}}" {{{ishidden this.hide}}}><div class="ha-issues-list-row" {{{backgroundcolor this.color}}}>{{#if this.isFontAwesomeIcon}} <i class="ha-icon fa fa-fw {{this.icon}}"></i> {{else}}<div class="ha-icon" style="background-image:url(icons/node-red-contrib-home-assistant-websocket/{{this.icon}})"></div>{{/if}} <span>{{this.name}}</span> <button type="button" class="red-ui-button red-ui-button-small ha-edit-node"><i class="fa fa-pencil"></i></button> <button type="button" class="red-ui-button red-ui-button-small ha-find-node"><i class="fa fa-search"></i></button> <button type="button" class="red-ui-button red-ui-button-small ha-hidden-issue"><i class="fa fa-eye"></i> <i class="fa fa-eye-slash"></i></button></div><ul>{{#each this.issues}}<li>{{this}}</li>{{/each}}</ul></li>{{else}}<li>{{i18n "home-assistant.sidebar.stacks.no_issues"}}</li>{{/each}}</script>
<script type="text/html" id="handlebars-sidebar-issues" data-template-name="x-tmpl-handlebars"><div id="ha-issue-header"><input type="checkbox" id="ha-issues-toggle-hidden" checked="checked"> <label for="ha-issues-toggle-hidden">{{i18n 'home-assistant.sidebar.issues.show_hidden'}}</label></div><ul class="ha-issues-list ha-show-hidden"></ul></script>
<script type="text/html" id="handlebars-sidebar-list" data-template-name="x-tmpl-handlebars"><ul class="ha-list">{{#each list}}<li class="ha-list-row" data-id="{{this.id}}" data-type="{{this.type}}"><div class="ha-list-row-name">{{this.name}}</div><div class="ha-list-row-count">{{this.count}}</div></li>{{/each}}</ul></script>
<script type="text/javascript">(()=>{var Ei=Object.defineProperty;var gt=(e,t)=>{for(var n in t)Ei(e,n,{get:t[n],enumerable:!0})};var Be="0.0.0";var vt="home-assistant-print-to-debug",$e="__ALL_TAGS__";var me=(i=>(i.String="string",i.Number="number",i.Boolean="boolean",i.HA_Boolean="ha_boolean",i))(me||{});var u=(e,t)=>{let o=RED._(`node-red-contrib-home-assistant-websocket/all:${e}`,t);return o.indexOf(`
`)!==-1&&(o=o.split(`
`).map(i=>`<p>${i}</p>`).join("")),o};function Me(e,t){if(e===t)return!0;if(typeof e!="object"||typeof t!="object"||e==null||t==null)return!1;let n=Object.keys(e),o=Object.keys(t);if(n.length<o.length)return!1;for(let i of o)if(!n.includes(i)||!Me(e[i],t[i]))return!1;return!0}function ht(e,t){return e=e.split(".").map(n=>n.padStart(5)).join("."),t=t.split(".").map(n=>n.padStart(5)).join("."),e<=t}function fe(e,t){return e.split(".").reduce((n,o)=>n[o],t)}function bt(e){return e&&(e instanceof jQuery||e.constructor.prototype.jquery)}var Tt={},St={},M={},xt={},$t={},_t={},Fe={};function Dt(e,t){let n=Y(e);Tt[n]=t}function Nt(e,t){let n=Y(e);St[n]=t}function wt(e,t){let n=Y(e);M[n]||(M[n]={}),t.forEach(o=>{M[n][o.entity_id]=o})}function It(e,t){let n=Y(e);Fe[n]=t}function Pt(e,t){let n=Y(e);M[n]=t}function Ot(e,t){let n=Y(e);xt[n]=t}function Rt(e,t){let n=Y(e);$t[n]=t}function Ct(e,t){let n=Y(e);_t[n]=t}function Y(e){return e.split("/")[2]}function At(e,t){let n=[];switch(t){case"entities":{if(!(e in M))return[];let o="attributes.friendly_name";n=Object.values(M[e]).map(i=>({value:i.entity_id,label:fe(o,i)||i.entity_id})).sort(ge);break}case"properties":{if(!(e in M))return[];n=Object.values(M[e]).map(o=>({value:o.entity_id,label:o.state})).sort(ge);break}case"trackers":{if(!(e in M))return[];let o="attributes.friendly_name";n=Object.values(M[e]).filter(i=>i.entity_id.startsWith("person.")||i.entity_id.startsWith("device_tracker.")).map(i=>({value:i.entity_id,label:fe(o,i)||i.entity_id})).sort(ge);break}case"zones":{if(!(e in M))return[];let o="attributes.friendly_name";n=Object.values(M[e]).filter(i=>i.entity_id.startsWith("zone.")).map(i=>({value:i.entity_id,label:fe(o,i)||i.entity_id})).sort(ge);break}case"calendars":{if(!(e in M))return[];let o="attributes.friendly_name";n=Object.values(M[e]).filter(i=>i.entity_id.startsWith("calendar.")).map(i=>({value:i.entity_id,label:fe(o,i)||i.entity_id})).sort(ge);break}}return n}function ge(e,t){let n=e.label,o=t.label;return n===o?0:n.localeCompare(o)}function _e(e,t){let n=Je(e);if(t&&n?.length){let o=n.find(i=>i.area_id===t);if(o)return o.name}return u("ha-device.ui.no_area")}function Je(e){return Tt[e]??[]}function De(e){return St[e]??[]}function Ge(e,t){return M[e][t]}function Ht(e,t){return Fe[e].find(n=>n.id===t)}function Lt(e){return Fe[e]??[]}function kt(e){return M[e]??{}}function Bt(e){return xt[e]??[]}function Mt(e){return $t[e]??[]}function Vt(e,t){if(!(e in M))return[];let n=t in M[e]?Object.keys(Ve(M[e][t])):Object.values(M[e]).map(r=>Object.keys(Ve(r)));return[...new Set([].concat(...n))].sort((r,a)=>!r.includes(".")&&a.includes(".")?-1:r.includes(".")&&!a.includes(".")?1:r<a?-1:r>a?1:0)}function Ft(e){return _t[e]??{}}function Ve(e,t,n="."){return Object.keys(e).reduce((o,i)=>{let r=e[i],a=[t,i].filter(Boolean).join(n);return[typeof r=="object",r!==null,!(r instanceof Date),!(r instanceof RegExp),!(Array.isArray(r)&&r.length===0)].every(Boolean)?{...o,...Ve(r,a,n)}:{...o,[a]:r}},{})}function Jt(e){function t(n){let o,i=1;return typeof n=="string"&&n.startsWith("-")?(i=-1,o=n.substring(1)):o=n,function(r,a){let s=r[o],d=a[o];return(typeof s=="string"&&typeof d=="string"?s.localeCompare(d):s<d?-1:s>d?1:0)*i}}return function(n,o){let i=0,r=0,a=e?.length;for(;r===0&&i<a;)r=t(e[i])(n,o),i++;return r}}var Ti=(e,t,n)=>{let o=[];if(n==="regex")try{let i=new RegExp(t);o=e.filter(r=>i.test(r.entity_id))}catch{o=[]}else n==="substring"&&(o=e.filter(i=>i.entity_id.includes(t)));return o.sort(Jt(["entity_id"]))},Si=e=>e.length?e.map(t=>`<li>${t.entity_id}</li>`).join(""):`<li>${u("home-assistant.label.no_matches_found")}</li>`,Gt,Wt={show:e=>{RED.view.state(RED.state.EDITING);let t={title:u("home-assistant.label.filter_results_title"),width:"inherit",buttons:[{id:"node-dialog-cancel",text:u("home-assistant.label.cancel"),click:()=>{RED.tray.close()}},{id:"node-dialog-ok",text:u("home-assistant.label.done"),class:"primary",click:()=>{e.complete(Gt),RED.tray.close()}}],open:n=>{let o=n.find(".red-ui-tray-body");RED.editor.buildEditForm(o,"dialog-form","ha_entity_filter","node-red-contrib-home-assistant-websocket/all"),n.i18n(),$("#dialog-form").addClass("home-assistant"),o.find("select").val(e.filterType),o.find("input").val(e.filter).on("input",i=>{let r=Ti(e.entities,i.target.value,e.filterType);Gt=i.target.value,o.find("ul").html(Si(r))}).trigger("input")}};RED.tray.show(t)}},Ut=({filter:e,filterType:t,entities:n,complete:o})=>{RED.editor.showTypeEditor("ha_entity_filter",{filter:e,filterType:t,entities:n,complete:o})};var jt=()=>{RED.editor.registerTypeEditor("ha_entity_filter",Wt)};var j,We={};function qt(e,t){let o=e.split("/")[2];We[o]=t.version}function zt(){let e=["ha-binary-sensor","ha-button","ha-number","ha-select","ha-sensor","ha-switch","ha-text","ha-time-entity"];return"type"in j&&j?.type&&e.includes(j.type)}function $i(){let e=$("#node-input-server").val();if(zt()&&(e=RED.nodes.node($("#node-input-entityConfig").val())?.server),!(!e||e==="_ADD_"))return e}function Qt(){let e=$i();return e&&We[e]?We[e]:Be}function we(){return Qt()!==Be}function ve(e){return $(`#node-input-${e}`).val()==="_ADD_"}function _(e){j=e;let t="type"in j&&j.type;_i(),$("#node-input-server, #node-input-entityConfig").on("change",()=>{switch(t){case"ha-binary-sensor":case"ha-button":case"ha-number":case"ha-select":case"ha-sensor":case"ha-switch":case"ha-text":case"ha-time-entity":ve("entityConfig")||se(t);break;case"ha-device":se(t);break;case"ha-sentence":{let n=$("#node-input-mode").val();$("#exposed-as-row").toggle(n==="trigger"),ve("server")||se(t)}break;case"ha-webhook":ve("server")||se(t);break;case"server-events":case"ha-events-calendar":case"server-state-changed":case"poll-state":case"ha-tag":case"trigger-state":case"ha-zone":case"ha-time":default:Ii();break}}),zt()&&$("#node-input-mode").on("change",wi)}function _i(){let e="type"in j&&j.type;switch(e){case"ha-binary-sensor":case"ha-button":case"ha-number":case"ha-select":case"ha-sensor":case"ha-switch":case"ha-text":case"ha-time-entity":ve("entityConfig")||se(e);break;case"ha-device":case"ha-sentence":case"ha-webhook":ve("server")||se(e);break;case"server-events":case"ha-events-calendar":case"server-state-changed":case"poll-state":case"ha-tag":case"ha-time":case"trigger-state":case"ha-zone":break;default:Di()}}function Di(){let e=$("<div />",{id:"exposeToHa",class:`form-row checkbox-option${"type"in j&&j.type==="trigger-state"?"-left":""}`});$("<input />",{type:"checkbox",id:"node-input-exposeToHomeAssistant",checked:j.exposeToHomeAssistant}).on("change",function(){$("#haConfigRow").toggle($("#node-input-exposeToHomeAssistant").is(":checked")===!0)}).appendTo(e),$("<label />",{for:"node-input-exposeToHomeAssistant",text:"Expose to Home Assistant"}).appendTo(e);let t=$("<div />",{class:"form-row",id:"haConfigRow"}),n=$("<ol />",{id:"haConfig"}).appendTo(t),o=j.haConfig||[{property:"name",value:""},{property:"icon",value:""}];n.editableList({addButton:!1,header:$("<div>Home Assistant Config (optional)</div>"),addItem:function(i,r,a){let s=$("<div />").appendTo(i),d=$("<label>").appendTo(s);$("<span>").text(a.property.replace(/_/g," ")).appendTo(d),$("<input />",{type:"hidden",name:"property",value:a.property}).appendTo(d),$("<input />",{type:"text",name:"value",value:a.value}).attr("autocomplete","disable").appendTo(d)}}).editableList("addItems",o),$("#dialog-form").append(e).append(t),$("#node-input-exposeToHomeAssistant").trigger("change")}var Ni={"ha-binary-sensor":"1.1.0","ha-button":"1.0.4","ha-device":"4.0.2","ha-number":"1.3.0","ha-select":"1.4.0","ha-sentence":"4.1.0","ha-sensor":"1.1.0","ha-switch":"1.1.0","ha-tag":"0.5.0","ha-text":"1.3.0","ha-time-entity":"2.1.0","ha-webhook":"1.6.0"};function se(e){let t=Ni[e],n=Qt(),o=!t||ht(t,n),i=we()&&o;if(!$("#integrationAlert").length){let r=`
<div id="integrationAlert" class="ui-state-error ha-alert-box">
This node requires the <a href="https://github.com/zachowj/hass-node-red" target="_blank">
Node-RED custom integration${o?"":` version ${t}+`}
<i class="fa fa-external-link external-link"></i></a> to be installed in Home Assistant for it to function.
</div>`;$("#dialog-form").prepend(r)}$("#integrationAlert").toggle(!i)}function wi(){let e=$("#node-input-mode").val();$("#exposed-as-row").toggle(e==="listen")}function Ii(){$("#node-input-exposeAsEntityConfig").closest("div.form-row").toggle(we()),we()||$("#node-input-exposeToHomeAssistant").prop("checked",!1).trigger("change"),$("#exposeToHa").toggle(we())}var Oi=Handlebars.compile($("#handlebars-notification-bar").html()),Pe=[],Kt=!1;function Ue(){return Pe}var he;function Ri(){he=$(Oi({issuesCount:Pe.length}));let e=he.find("#notification-issues").on("click",()=>{RED.events.emit("home-assistant:open-issues")});RED.popover.tooltip(e,u("home-assistant.service.issue.tooltip_description")),he.prependTo(".red-ui-header-toolbar")}function Zt(e,t){Pe=t,RED.events.emit("home-assistant:issues-updated"),Kt||(Kt=!0,Ri());let n=Pe.filter(o=>!o.hide).length;he.toggle(n>0),he.find(".ha-issue-count").text(n)}function Yt(e,t){RED.debug.handleDebugMessage(t)}var Xt=e=>{try{navigator?.clipboard?.writeText(e)}catch{let n=document.createElement("textarea");n.textContent=e;let o=document.getElementsByTagName("body")[0];o.appendChild(n),n.select(),document.execCommand("copy"),o.removeChild(n)}};function en(){$("#home-assistant-diagnostics-button").on("click",function(e){e.preventDefault();let t=u("home-assistant.sidebar.diagnostics.fetching_data"),n=$(`
<div id="home-assistant-diagnostics-dialog">
<textarea id="home-assistant-diagnostics-textarea" style="width: 100%;resize: none;" rows="12" >${t}</textarea>
</div>
`);RED.keyboard.disable(),n.dialog({classes:{"ui-dialog":"red-ui-editor-dialog","ui-dialog-titlebar-close":"hide","ui-widget-overlay":"red-ui-editor-dialog"},modal:!0,closeOnEscape:!0,width:450,resizable:!1,draggable:!1,title:u("home-assistant.sidebar.diagnostics.environment_data"),close:function(){$("#home-assistant-diagnostics-dialog").dialog("destroy").remove(),RED.keyboard.enable()},buttons:[{text:u("home-assistant.sidebar.diagnostics.copy"),click:function(){let o=document.getElementById("home-assistant-diagnostics-textarea");Xt(o.value),RED.notify(u("home-assistant.sidebar.diagnostics.copied")),$(this).dialog("close")}},{text:u("home-assistant.sidebar.diagnostics.close"),click:function(){$(this).dialog("close")}}]}),$.get("homeassistant/diagnostics",function(o){$("#home-assistant-diagnostics-textarea").val(o)}).fail(function(){$("#home-assistant-diagnostics-textarea").val(u("home-assistant.sidebar.diagnostics.failed_fetch"))})})}Handlebars.registerHelper("backgroundcolor",function(e){return`style="background-color: ${e};"`});Handlebars.registerHelper("ishidden",function(e){return e?'class="ha-hidden"':""});Handlebars.registerHelper("i18n",function(e){return u(e)});var Ci=Handlebars.compile($("#handlebars-sidebar-list").html()),Ai=Handlebars.compile($("#handlebars-sidebar-filter").html()),Hi=Handlebars.compile($("#handlebars-sidebar-issues").html()),Li=Handlebars.compile($("#handlebars-sidebar-issues-list").html());function ki(e){let t=[],n=new Set;return RED.nodes.eachConfig(function(o){return o.type===e&&(o.entityType&&n.add(o.entityType),t.push({name:o.name||o.id,id:o.id,count:o.users.length,type:o.entityType})),!0}),{list:t.sort((o,i)=>o.name.localeCompare(i.name)),types:[...n].sort()}}var tn,nn,on,te;function je(){[{type:"server",section:tn},{type:"ha-entity-config",section:nn},{type:"ha-device-config",section:on}].forEach(({type:e,section:t})=>{t.content.empty();let n=ki(e);n.types.length>1&&$(Ai(n)).on("change","select",function(){let o=$(this).val();t.content.find(".ha-list-row").each(function(){let i=$(this);o==="__all__"||i.data("type")===o?i.show():i.hide()})}).appendTo(t.content),$(Ci(n)).on("click",".ha-list-row-name",function(o){o.stopPropagation(),RED.editor.editConfig("",e,$(this).parent().data("id"),"")}).on("click",".ha-list-row-count",function(o){o.stopPropagation(),RED.search.show($(this).parent().data("id"))}).appendTo(t.content)})}function Bi(e){return e.map(t=>{let n=RED.nodes.node(t.nodeId),o=n?._def.icon,i=!!o?.startsWith("font-awesome/"),r=i?o.slice(13):o;return{color:n._def.color,icon:r,isFontAwesomeIcon:i,name:n?n._def.label.call(n):t.nodeId,id:t.nodeId,issues:t.messages,hide:t.hide}})}function Mi(e){te&&($(Hi({issues:e})).on("click","#ha-issues-toggle-hidden",function(){this.checked?$(".ha-issues-list").addClass("ha-show-hidden"):$(".ha-issues-list").removeClass("ha-show-hidden")}).appendTo(te.content),Vi(te.content.find(".ha-issues-list").append(rn(e))))}function Vi(e){e.on("click",".ha-find-node",function(t){t.stopPropagation(),RED.view.reveal($(this).parents("li").data("id"))}).on("click",".ha-edit-node",function(t){t.stopPropagation();let n=$(this).parents("li").data("id"),o=RED.nodes.node(n);o&&RED.editor.edit(o)}).on("click",".ha-hidden-issue",function(t){t.stopPropagation();let n=$(this).parents("li[data-id]"),o=n.data("id"),i=$(this).data("popover");i&&(i.close(),i.setContent(n.hasClass("ha-hidden")?u("home-assistant.sidebar.issues.show_issue"):u("home-assistant.sidebar.issues.hide_issue"))),$.ajax({url:"homeassistant/issues/hidden",type:"POST",data:JSON.stringify({issue:o}),contentType:"application/json",success:()=>{RED.notify(u("home-assistant.service.issue.issue_hidden",{issue_id:o}),{type:"success",id:`issue${o}`,timeout:2e3}),n.addClass("ha-hidden")},error:function(r,a){let s="";r.status===500?s=u("home-assistant.service.issue.failed_to_hide",{issue_id:o}):r.status===0?s=u("home-assistant.service.issue.no-response"):s=u("home-assistant.service.issue.unexpected",{status:r.status,message:a}),RED.notify(s,"error")}})})}function rn(e){let t=$(Li({issues:Bi(e)}));return $(".ha-edit-node",t).each(function(){RED.popover.tooltip($(this),u("home-assistant.sidebar.issues.open_editor"))}),$(".ha-find-node",t).each(function(){RED.popover.tooltip($(this),u("home-assistant.sidebar.issues.find_node"))}),$(".ha-hidden-issue",t).each(function(){let n=$(this),o=n.parents("li").hasClass("ha-hidden"),i=RED.popover.tooltip(n,u(o?"home-assistant.sidebar.issues.show_issue":"home-assistant.sidebar.issues.hide_issue"));$(this).data("popover",i)}),t}function an(e){let t=$("<div>",{id:"home-assistant-stack",class:"home-assistant-sidebar-stack"}).appendTo(e),n=RED.stack.create({container:t});tn=n.add({title:u("home-assistant.sidebar.stacks.server"),collapsible:!0}),nn=n.add({title:u("home-assistant.sidebar.stacks.entity"),collapsible:!0}),on=n.add({title:u("home-assistant.sidebar.stacks.device"),collapsible:!0}),te=n.add({title:u("home-assistant.sidebar.stacks.issues"),collapsible:!0}),je(),Mi(Ue()),RED.events.on("home-assistant:open-issues",()=>{RED.sidebar.show("ha_sidebar"),te.isExpanded()||te.expand()}),RED.events.on("home-assistant:issues-updated",()=>{te.content.find(".ha-issues-list").empty().append(rn(Ue()))})}function qe(){RED.events.off("runtime-state",qe);let e=$($('script[data-template-name="ha_sidebar"]').i18n().html()),t=$($('script[data-template-name="ha_sidebar_toolbar"]').i18n().html());an(e),RED.sidebar.addTab({id:"ha_sidebar",label:"Home Assistant",name:"Home Assistant",content:e.get(0),closeable:!0,disableOnEdit:!0,iconClass:"fa fa-home",toolbar:t,onchange:()=>je()}),en()}var sn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>{let t={...e,version:1};try{let n=JSON.parse(e.data);n.entity_id?(t.entityId=n.entity_id,delete n.entity_id,t.data=Object.keys(n).length?JSON.stringify(n):""):t.entityId=""}catch{}return t}},{version:2,up:e=>{let t={...e,version:2,outputProperties:[]};return e.output_location_type!=="none"&&(t.outputProperties=[{property:e.output_location,propertyType:e.output_location_type,value:"",valueType:"data"}]),t}},{version:3,up:e=>({...e,version:3,queue:"none"})},{version:4,up:e=>({...e,version:4,target:{entityId:e?.entityId?e.entityId.split(",").map(n=>n.trim()):[],areaId:[],deviceId:[]},domain:e.service_domain,mergeContext:e.mergecontext,entityId:void 0,service_domain:void 0,mergecontext:void 0})},{version:5,up:e=>({...e,version:5,areaId:e.target?.areaId,deviceId:e.target?.deviceId,entityId:e.target?.entityId,target:void 0})},{version:6,up:e=>{let t={...e,version:6,floorId:[],labelId:[]};return(e.domain||e.service)&&(t.action=`${e.domain}.${e.service}`),t}},{version:7,up:e=>({...e,version:7,blockInputOverrides:!1})}];var pn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>{let t={...e,version:1,outputProperties:[],location:void 0,locationType:void 0};return e.locationType!=="none"&&(t.outputProperties=[{property:e.location,propertyType:e.locationType,value:"",valueType:"results"}]),t}}];var un=[{version:0,up:e=>({...e,version:0})}];var ln=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,ha_boolean:e.ha_boolean||"y|yes|true|on|home|open",rejectUnauthorizedCerts:e.rejectUnauthorizedCerts!==void 0?e.rejectUnauthorizedCerts:!0,connectionDelay:e.connectionDelay!==void 0?e.connectionDelay:!0,cacheJson:e.cacheJson!==void 0?e.cacheJson:!0})},{version:2,up:e=>({...e,version:2,heartbeat:!1,heartbeatInterval:30})},{version:3,up:e=>({...e,version:3,areaSelector:"friendlyName",deviceSelector:"friendlyName",entitySelector:"friendlyName"})},{version:4,up:e=>({...e,version:4,statusSeparator:"at: ",statusYear:"hidden",statusMonth:"short",statusDay:"numeric",statusHourCycle:"h23",statusTimeFormat:"h:m"})},{version:5,up:e=>({...e,version:5,enableGlobalContextStore:!0})},{version:6,up:e=>{let t={...e,version:6},n=[];typeof e.ha_boolean=="string"&&(n=e.ha_boolean.split("|"));let o=new Set(n.map(i=>i.toLowerCase().trim()));return t.ha_boolean=Array.from(o),t}}];var dn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,blockInputOverrides:!1,entity_location:"data",halt_if_compare:"is",override_payload:e.override_payload===!1?"none":"msg",override_data:e.override_data===!1?"none":"msg",state_location:"payload",state_type:"str"})},{version:2,up:e=>{let t={...e,version:2,outputProperties:[],state_location:void 0,override_payload:void 0,entity_location:void 0,override_data:void 0,override_topic:void 0};return e.override_payload!=="none"&&t.outputProperties.push({property:e.state_location,propertyType:e.override_payload,value:"",valueType:"entityState"}),e.override_data!=="none"&&t.outputProperties.push({property:e.entity_location,propertyType:e.override_data,value:"",valueType:"entity"}),e.override_topic===!0&&t.outputProperties.push({property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}),t}},{version:3,up:e=>({...e,version:3,for:0,forType:"num",forUnits:"minutes"})}];var cn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>{let t={...e,version:1,exposeAsEntityConfig:""};return t.exposeToHomeAssistant=void 0,t.haConfig=void 0,t}}];var yn=[{version:0,up:e=>({...e,version:0})}];var mn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,inputOverride:"allow"})},{version:2,up:e=>{let t={...e,version:2};return t.config.push({property:"state_class",value:""}),t.config.push({property:"last_reset",value:""}),t}},{version:3,up:e=>({...e,version:3})}];var fn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1})},{version:2,up:e=>({...e,version:2})},{version:3,up:e=>({...e,version:3})},{version:4,up:e=>({...e,version:4})},{version:5,up:e=>({...e,version:5})},{version:6,up:e=>({...e,version:6})}];var gn=[{version:0,up:e=>({...e,version:0,waitForRunning:e.waitForRunning!==void 0?e.waitForRunning:!0})},{version:1,up:e=>({...e,version:1,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"}]})},{version:2,up:e=>({...e,version:2,eventType:e.event_type,event_type:void 0})},{version:3,up:e=>{let t={...e,version:3,exposeAsEntityConfig:""};return t.exposeToHomeAssistant=void 0,t.haConfig=void 0,t}}];var vn=[{version:0,up:e=>({...e,version:0})}];var q=(s=>(s.Floor="floor",s.Area="area",s.Device="device",s.Entity="entity",s.Label="label",s.Substring="substring",s.Regex="regex",s))(q||{}),be=(r=>(r.Floor="floor_registry",r.Area="area_registry",r.Device="device_registry",r.State="state_object",r.Label="label_registry",r))(be||{});var hn=[{version:0,up:e=>({...e,version:0,state_type:e.state_type!==void 0?e.state_type:"str",halt_if_type:e.halt_if_type!==void 0?e.halt_if_type:"str",halt_if_compare:e.halt_if_compare!==void 0?e.halt_if_compare:"is"})},{version:1,up:e=>({...e,version:1,ignorePrevStateNull:!1,ignorePrevStateUnknown:!1,ignorePrevStateUnavailable:!1,ignoreCurrentStateUnknown:!1,ignoreCurrentStateUnavailable:!1})},{version:2,up:e=>({...e,version:2,for:e.for!==void 0?e.for:"0",forType:e.forType||"num",forUnits:e.forUnits||"minutes"})},{version:3,up:e=>({...e,version:3,outputProperties:[{property:"payload",propertyType:"msg",value:"",valueType:"entityState"},{property:"data",propertyType:"msg",value:"",valueType:"eventData"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}]})},{version:4,up:e=>{let t={...e,version:4};return e.entityidfiltertype==="substring"&&e.entityidfilter?.includes(",")&&(t.entityidfiltertype="list",t.entityidfilter=e.entityidfilter.split(",").map(n=>n.trim()).filter(n=>n.length>0)),t}},{version:5,up:e=>{let t={...e,version:5,entityId:e.entityidfilter,entityIdType:e.entityidfiltertype,ifState:e.haltifstate,ifStateType:e.halt_if_type,ifStateOperator:e.halt_if_compare,outputInitially:e.outputinitially,stateType:e.state_type,outputOnlyOnStateChange:e.output_only_on_state_change,exposeAsEntityConfig:""};return t.entityidfilter=void 0,t.entityidfiltertype=void 0,t.haltifstate=void 0,t.halt_if_type=void 0,t.halt_if_compare=void 0,t.outputinitially=void 0,t.state_type=void 0,t.output_only_on_state_change=void 0,t.exposeToHomeAssistant=void 0,t.haConfig=void 0,t}},{version:6,up:e=>{let t={...e,version:6,entities:[],entityId:void 0,entityIdType:void 0},n={entity:[],substring:[],regex:[]};switch(e.entityIdType){case"list":n.entity=e.entityId;break;case"exact":n.entity=[e.entityId];break;case"substring":n.substring=[e.entityId];break;case"regex":n.regex=[e.entityId];break}return t.entities=n,t}}];var bn=[{version:0,up:e=>({...e,version:0})}];var En=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>{let t={...e,version:1,outputType:e.output_type,outputEmptyResults:e.output_empty_results,outputLocationType:e.output_location_type,outputLocation:e.output_location,outputResultsCount:e.output_results_count};return t.output_type=void 0,t.output_empty_results=void 0,t.output_location_type=void 0,t.output_location=void 0,t.output_results_count=void 0,t}}];var Tn=[{version:0,up:e=>{let t={...e,version:0,output_type:e.output_type===void 0?"array":e.output_type};return t.output_location===void 0&&(t.output_location="payload",t.output_location_type="msg"),t}},{version:1,up:e=>{let t={...e,version:1,startDate:e.startdate,endDate:e.enddate,entityId:e.entityid,outputType:e.output_type,outputLocationType:e.output_location_type,outputLocation:e.output_location,entityIdType:e.entityidtype==="includes"?"regex":"equals"};return t.startdate=void 0,t.enddate=void 0,t.entityid=void 0,t.entityidtype=void 0,t.output_type=void 0,t.output_location_type=void 0,t.output_location=void 0,t}}];var Sn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,mode:e.mode==="out"?"set":"listen"})}];var xn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,state_type:"str",halt_if_type:"str",halt_if_compare:"is",updateIntervalUnits:"seconds"})},{version:2,up:e=>({...e,version:2,updateIntervalType:"num"})},{version:3,up:e=>{let t={...e,version:3,entityId:e.entity_id,exposeAsEntityConfig:"",ifState:e.halt_if,ifStateType:e.halt_if_type,ifStateOperator:e.halt_if_compare,outputInitially:e.outputinitially,outputOnChanged:e.outputonchanged,outputProperties:[{property:"payload",propertyType:"msg",value:"",valueType:"entityState"},{property:"data",propertyType:"msg",value:"",valueType:"entity"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],stateType:e.state_type,updateInterval:e.updateinterval};return t.entity_id=void 0,t.updateinterval=void 0,t.outputinitially=void 0,t.outputonchanged=void 0,t.state_type=void 0,t.halt_if=void 0,t.halt_if_type=void 0,t.halt_if_compare=void 0,t.exposeToHomeAssistant=void 0,t.haConfig=void 0,t}}];var $n=[{version:0,up:e=>{let t={...e,version:0};return t.templateLocationType===void 0&&(t.templateLocation="template",t.templateLocationType="msg"),t.resultsLocationType===void 0&&(t.resultsLocation="payload",t.resultsLocationType="msg"),t}}];var _n=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,mode:e.mode==="out"?"set":"listen"})}];var Dn=[{version:0,up:e=>({...e,version:0})}];var Nn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,exposeAsEntityConfig:"",response:""})},{version:2,up:e=>({...e,version:2,mode:"trigger",triggerResponseType:"fixed",responseType:"jsonata",responseTimeout:1e3})}];var wn=[{version:0,up:e=>({...e,version:0})}];var In=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,outputProperties:[{property:"payload",propertyType:"msg",value:"",valueType:"eventData"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}]})},{version:2,up:e=>{let t={...e,version:2,exposeAsEntityConfig:e.exposeAsEntityConfig??""};return t.exposeToHomeAssistant=void 0,t.haConfig=void 0,t}}];var Pn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,mode:e.mode==="out"?"set":"listen"})}];var On=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,sunday:!0,monday:!0,tuesday:!0,wednesday:!0,thursday:!0,friday:!0,saturday:!0})},{version:2,up:e=>{let t=e.payloadType==="jsonata"&&e.payload==="$entity().state";return{...e,version:2,outputProperties:[{property:"payload",propertyType:"msg",value:t?"":e.payload,valueType:t?"entityState":e.payloadType},{property:"data",propertyType:"msg",value:"",valueType:"entity"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],payload:void 0,payloadType:void 0}}},{version:3,up:e=>{let t={...e,version:3,exposeAsEntityConfig:""};return t.debugenabled=void 0,t.exposeToHomeAssistant=void 0,t.haConfig=void 0,t}},{version:4,up:e=>({...e,version:4,ignorePastDate:!1})}];var Rn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>({...e,version:1,inputs:1,enableInput:!0})},{version:2,up:e=>{let t={...e,version:2};return e.entityidfiltertype==="substring"&&e.entityid?.includes(",")&&(t.entityidfiltertype="list",t.entityid=e.entityid.split(",").map(n=>n.trim()).filter(n=>n.length>0)),t}},{version:3,up:e=>{let t={...e,version:3,entityId:e.entityid,entityIdType:e.entityidfiltertype,debugEnabled:e.debugenabled,customOutputs:e.customoutputs,outputInitially:e.outputinitially,stateType:e.state_type,exposeAsEntityConfig:""};return t.entityid=void 0,t.entityidfiltertype=void 0,t.debugenabled=void 0,t.customoutputs=void 0,t.outputinitially=void 0,t.state_type=void 0,t}},{version:4,up:e=>{let t={...e,version:4};return e.stateType===void 0&&(t.stateType="str"),t}},{version:5,up:e=>{let t={...e,version:5,entities:[],entityId:void 0,entityIdType:void 0},n={entity:[],substring:[],regex:[]};switch(e.entityIdType){case"list":n.entity=e.entityId;break;case"exact":n.entity=[e.entityId];break;case"substring":n.substring=[e.entityId];break;case"regex":n.regex=[e.entityId];break}return t.entities=n,t}}];var Cn=[{version:0,up:e=>{let t={...e,version:0,entityIdFilterType:e.entityIdFilterType||"exact",timeoutType:e.timeoutType||"num"};return t.blockInputOverrides===void 0&&(t.blockInputOverrides=!0),t.checkCurrentState===void 0&&(t.checkCurrentState=!1),t}},{version:1,up:e=>{let t={...e,version:1};return e.entityIdFilterType==="substring"&&e.entityId?.includes(",")&&(t.entityIdFilterType="list",t.entityId=e.entityId.split(",").map(n=>n.trim()).filter(n=>n.length>0)),t}},{version:2,up:e=>{let t={...e,version:2,outputProperties:[],entityLocation:void 0,entityLocationType:void 0};return e.entityLocationType!=="none"&&t.outputProperties.push({property:e.entityLocation,propertyType:e.entityLocationType,value:"",valueType:"entity"}),t}},{version:3,up:e=>{let t={...e,version:3,entities:[],entityId:void 0,entityIdFilterType:void 0},n={entity:[],substring:[],regex:[]};switch(e.entityIdFilterType){case"list":n.entity=e.entityId;break;case"exact":n.entity=[e.entityId];break;case"substring":n.substring=[e.entityId];break;case"regex":n.regex=[e.entityId];break}return t.entities=n,t}}];var An=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>{let t={...e,version:1,outputProperties:[{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],payloadLocation:void 0,payloadLocationType:void 0,headersLocation:void 0,headersLocationType:void 0};return e.payloadLocationType!=="none"&&t.outputProperties.push({property:e.payloadLocation,propertyType:e.payloadLocationType,value:"",valueType:"data"}),e.headersLocationType!=="none"&&t.outputProperties.push({property:e.headersLocation,propertyType:e.headersLocationType,value:"",valueType:"headers"}),t}},{version:2,up:e=>({...e,version:2,method_post:!0,method_put:!0,method_get:!1,method_head:!1})},{version:3,up:e=>({...e,version:3,exposeAsEntityConfig:""})}];var Hn=[{version:0,up:e=>({...e,version:0})},{version:1,up:e=>{let t={...e,version:1,exposeAsEntityConfig:""};return t.exposeToHomeAssistant=void 0,t.haConfig=void 0,t}}];var Fi={"ha-api":pn,"ha-binary-sensor":un,"api-call-service":sn,server:ln,"api-current-state":dn,"ha-device":cn,"ha-device-config":yn,"ha-entity":mn,"ha-entity-config":fn,"server-events":gn,"ha-events-calendar":vn,"server-state-changed":hn,"ha-fire-event":bn,"ha-get-entities":En,"api-get-history":Tn,"ha-number":Sn,"poll-state":xn,"api-render-template":$n,"ha-select":_n,"ha-sensor":Dn,"ha-sentence":Nn,"ha-switch":wn,"trigger-state":Rn,"ha-tag":In,"ha-text":Pn,"ha-time":On,"ha-wait-until":Cn,"ha-webhook":An,"ha-zone":Hn};function ze(e){let t=Gi(e.type);if(e.version!==void 0&&e.version>=t)return e;let n=Ji(e.type,e.version)?.up;if(n){let o=n(e);return ze(o)}return e}function Ji(e,t=-1){return Ln(e)?.find(i=>i.version===Number(t)+1)}function Ln(e){return Fi[e]}function Gi(e){return(Ln(e)??[]).reduce((o,i)=>i.version>o?i.version:o,0)}var Wi=e=>{RED.nodes.import({type:"ha-entity-config",id:e.id,server:e.server,deviceConfig:"",name:`${e.entityType.replace("_"," ")} config for ${e.name||e.id}`,version:RED.settings.get("haEntityConfigVersion",0),entityType:e.entityType,haConfig:e.config??[],resend:e.resend??!1})},Ui=(e,t)=>{let n={id:t,name:e.name,inputs:1,outputs:1,version:0,g:e.g,x:e.x,y:e.y,z:e.z,entityConfig:e.id};switch(e.entityType){case"binary_sensor":case"sensor":n={...n,type:e.entityType==="sensor"?"ha-sensor":"ha-binary-sensor",state:e.state??"payload",stateType:e.stateType??"msg",attributes:e.attributes??[],inputOverride:e.inputOverride??"allow",outputProperties:e.outputLocationType==="none"?[]:[{property:e.outputLocation,propertyType:e.outputLocationType,value:"",valueType:"data"}]};break;case"switch":default:n={...n,type:"ha-switch",outputs:2,outputOnStateChange:e.outputOnStateChange??!1,enableInput:!0,outputProperties:e.outputPayloadType==="none"?[]:[{property:"payload",propertyType:"msg",value:e.outputPayload,valueType:e.outputPayloadType}]};break}RED.nodes.import(n)},kn=(e,t)=>{let n;for(n in t)t[n].forEach(o=>{RED.nodes.addLink({...o,[n]:RED.nodes.node(e)})})},Bn=()=>{let e;do e=RED.nodes.id();while(RED.nodes.node(e));return e},Mn=e=>{let t={source:RED.nodes.getNodeLinks(e.id),target:RED.nodes.getNodeLinks(e.id,1)},n=Bn();if(e.g){let i=RED.nodes.node(e.id);i&&RED.group.removeFromGroup(RED.nodes.group(e.g),i)}RED.nodes.remove(e.id),Wi(e),Ui(e,n),kn(n,t);let o=RED.nodes.node(n);o&&(RED.nodes.moveNodeToTab(o,e.z),e.g&&RED.group.addToGroup(RED.nodes.group(e.g),o),o.changed=!0),RED.view.redraw(!0)},Vn=(e,t)=>{let n={source:RED.nodes.getNodeLinks(e.id),target:RED.nodes.getNodeLinks(e.id,1)};if(e.g){let r=RED.nodes.node(e.id);r&&RED.group.removeFromGroup(RED.nodes.group(e.g),r)}RED.nodes.import([{type:"ha-entity-config",id:e.id,server:e.server,deviceConfig:"",name:`exposed as for ${e.name||e.id}`,version:RED.settings.get("haEntityConfigVersion",0),entityType:"switch",haConfig:t??[],resend:!1}],{importMap:{[e.id]:"replace"}});let o=Bn();RED.nodes.import({...e,id:o,exposeAsEntityConfig:e.id}),kn(o,n);let i=RED.nodes.node(o);i&&(RED.nodes.moveNodeToTab(i,e.z),e.g&&RED.group.addToGroup(RED.nodes.group(e.g),i),i.changed=!0),RED.view.redraw(!0)};var pe;function Fn(){let t=RED.view.selection()?.nodes?.[0];t&&ue(t)&&!ne(t)&&(Qe(t),RED.nodes.dirty(!0),RED.notify(u("home-assistant.ui.migrations.node_schema_updated")))}function Jn(e){!ue(e)||ne(e)||(e=Qe(e),Gn(e)||RED.events.on("editor:close",function t(){RED.events.off("editor:close",t),RED.editor.edit(e)}),RED.nodes.dirty(!0),RED.tray.close(),RED.notify(u("home-assistant.ui.migrations.node_schema_updated")))}var ji=["ha-device","server-events","server-state-changed","poll-state","ha-tag","ha-time","ha-zone"];function Qe(e){let t=RED.nodes.convertNode(e,!1),n=ji.includes(e.type)&&(e.exposeToHomeAssistant===!0||e.type==="ha-device"&&e.version<1)?t.haConfig:void 0,o=ze(t);"type"in o&&o.type==="ha-entity"?Mn(o):n&&Vn(o,n);let i;for(i in o)o[i]===void 0?delete e[i]:e[i]=o[i];e.changed=!0,RED.editor.updateNodeProperties(e);let r=$("#upgrade-ha-node");return r.is(":visible")&&Wn()===0&&r.hide(),e}function qi(){let e=[],t=n=>{ue(n)&&!ne(n)&&e.push(n)};RED.nodes.eachNode(t),RED.nodes.eachConfig(t),e.forEach(n=>Qe(n)),RED.nodes.dirty(!0),RED.notify(u("home-assistant.ui.migrations.all_nodes_updated")),RED.view.redraw()}function zi(){let e="home-assistant.ui.migrations",t=u(`${e}.button_ok`),n=u(`${e}.button_cancel`);$("#ha-dialog-confirm").dialog({resizable:!1,height:"auto",width:400,modal:!0,buttons:{[t]:function(){$(this).dialog("close"),qi()},[n]:function(){$(this).dialog("close")}}})}function Qi(e){return`${e.split("-").reduce((n,o,i)=>n.concat(`${i?o[0].toUpperCase():o[0]}${o.slice(1)}`),[]).join("")}Version`}function ne(e){let t=RED.settings.get(Qi(e.type),-1),n=Gn(e)&&e.version===void 0?e._def.defaults.version.value:e.version;return n!==void 0&&n>=t}function ue(e){return RED.nodes.registry.getNodeSetForType(e.type)?.module==="node-red-contrib-home-assistant-websocket"}function Gn(e){return e?.type&&["server","ha-entity-config","ha-device-config"].includes(e.type)}function Wn(){let e=0,t=n=>{ue(n)&&!ne(n)&&e++};return RED.nodes.eachNode(t),RED.nodes.eachConfig(t),e}function Un(){Ki(),pe=$("#upgrade-ha-node"),pe.hide(),pe.on("click",zi)}function jn(e){ue(e)&&!ne(e)&&pe.show()}function qn(e){pe.is(":visible")&&ue(e)&&Wn()===0&&pe.hide()}function Ki(){let e="home-assistant.ui.migrations",t=u(`${e}.title`),n=u(`${e}.warning`),o=u(`${e}.message`),i=u(`${e}.button_label`),r=u("home-assistant.ui.notifications.attention"),a=$.parseHTML(`<div id="ha-dialog-confirm" title="${t}">
${o}
<div class="ui-state-error ha-alert-box"><strong>${r}:</strong> ${n}</div>
</div>`),s=$.parseHTML(`<li><button id="upgrade-ha-node"><i class="fa fa-refresh"></i> ${i}</button></li>`);$("body").append(a),$("#red-ui-header .red-ui-header-toolbar").prepend(s)}var Q,J,Ee,Ke=!1;function Zi(){let e;RED.nodes.eachConfig(t=>(t.type==="server"&&!e&&(e=t.id),!0)),e&&Q.val(e)}function v(e,t,n){Q=$(t),Ee=e,Ee.server||Zi(),J=Q.val(),setTimeout(()=>{Q.on("change",()=>{J=Q.val(),n?.(J)})},500)}function zn(){return J}function oe(e,t){let n=Q.val();(Ee.server||n&&n!=="_ADD_")&&(J=Ee.server||n,Oe(e,t)),Q.on("change",()=>{J=Q.val(),J!==n&&(n=J,Oe(e,t))})}function Oe(e,t){J!=="_ADD_"&&$.getJSON(`homeassistant/${e}/${J}`).done(n=>{t(n)}).fail(n=>{n.status===503&&Ke===!1&&(Ke=!0,RED.notify(Ee._("config-server.errors.server_deploy")),setTimeout(()=>Ke=!1,2e3))})}function Ze(e,t,{params:n={}}){let o=`homeassistant/${t}/${Q.val()}`;$.isEmptyObject(n)||(o+=`?${$.param(n)}`),$.getJSON(o).done(i=>{e(i)})}function Re(e,t={}){let n=`homeassistant/${e}/${Q.val()}`;return $.isEmptyObject(t)||(n+=`?${$.param(t)}`),new Promise((o,i)=>{$.getJSON(n).done(r=>o(r)).fail(r=>i(r))})}var Qn=e=>_e(J,e),Kn=()=>Je(J),Zn=()=>De(J);var Yn=()=>Lt(J),Ce=()=>Object.values(kt(J)),Xn=()=>Bt(J),eo=()=>Mt(J),K=()=>Ft(J),Ye=()=>{let e=RED.nodes.node(J);return{areaSelector:e?.areaSelector,deviceSelector:e?.deviceSelector,entitySelector:e?.entitySelector,status:{separator:e?.statusSeparator,year:e?.statusYear,month:e?.statusMonth,day:e?.statusDay,hourCycle:e?.statusHourCycle,timeFormat:e?.statusTimeFormat}}};var Yi=e=>{$("#dialog-form, #node-config-dialog-edit-form").addClass("home-assistant"),Jn(e)},Xi=e=>$.parseHTML(`
<div class="ui-state-error ha-alpha-box">
Alpha version: At this point anything could change or not work.
<br />
Found an issue? Post it in
<a
href="https://github.com/zachowj/node-red-contrib-home-assistant-websocket/issues"
target="_blank"
rel="noreferrer"
>
issues
</a>
. Have questions or comments? Post them
<a
href="https://github.com/zachowj/node-red-contrib-home-assistant-websocket/discussions/${e}"
target="_blank"
rel="noreferrer"
>
here
</a>
.
</div>
`),er=e=>$.parseHTML(`
<div class="ui-state-error ha-beta-box">
Beta version: Config should be stable and hopefully not too many bugs.
<br />
Found an issue? Post it in
<a
href="https://github.com/zachowj/node-red-contrib-home-assistant-websocket/issues"
target="_blank"
rel="noreferrer"
>
issues
</a>
. Have questions or comments? Post them
<a
href="https://github.com/zachowj/node-red-contrib-home-assistant-websocket/discussions/${e}"
target="_blank"
rel="noreferrer"
>
here
</a>
.
</div>
`);function tr(){let e=[];return ne(this)||e.push("ha-node-label-legacy"),this.name&&e.push("node_label_italic"),e.join(" ")}var l={alphaWarning:Xi,betaWarning:er,labelStyle:tr,setup:Yi};var nr="en-US",or=Intl?.DateTimeFormat()?.resolvedOptions()?.locale,ir={month:"short",day:"numeric",hour:"numeric",minute:"numeric"};function to({date:e=new Date,locale:t=or??nr,options:n=ir}){return new Intl.DateTimeFormat(t,n).format(e)}function no(e){return/^\$\{[a-zA-Z_][a-zA-Z0-9_]*\}$/.test(e)}function oo(e){return/{{(?:(?!}}).+)}}/g.test(e)}var rr={category:"config",defaults:{name:{value:"Home Assistant",required:!1},version:{value:RED.settings.get("serverVersion",0)},addon:{value:!1},rejectUnauthorizedCerts:{value:!0},ha_boolean:{value:["y","yes","true","on","home","open"]},connectionDelay:{value:!0},cacheJson:{value:!0},heartbeat:{value:!1},heartbeatInterval:{value:30,validate:function(e){return!$("#node-config-input-heartbeat").is(":checked")||RED.validators.number()(e)&&Number(e)>=10}},areaSelector:{value:"friendlyName"},deviceSelector:{value:"friendlyName"},entitySelector:{value:"friendlyName"},statusSeparator:{value:": "},statusYear:{value:"hidden"},statusMonth:{value:"short"},statusDay:{value:"numeric"},statusHourCycle:{value:"default"},statusTimeFormat:{value:"h:m"},enableGlobalContextStore:{value:!1}},credentials:{host:{type:"text"},access_token:{type:"text"}},icon:"font-awesome/fa-home",label:function(){return this.name||"Home Assistant"},oneditprepare:function(){l.setup(this);let e=$("#node-config-input-addon"),t=$("#node-config-input-host");this.rejectUnauthorizedCerts===!1&&$("#accept_unauthorized_certs").prop("checked",!0),["http://hassio/homeassistant","http://supervisor/core"].includes(t.val())&&e.prop("checked",!0);function o(){$("#server-info").toggle(!e.prop("checked")),$(".addon").toggle(e.prop("checked"))}o(),e.on("click",function(){o()});try{t.autocomplete("destroy")}catch{}let i=$("#discoverInstances");i.on("click",function(){if($(this).hasClass("disabled"))return;let r=$("i",this).removeClass("fa-search").addClass("spinner");i.addClass("disabled"),t.autocomplete({source:(a,s)=>{$.ajax({dataType:"json",url:"/homeassistant/discover",cache:!1}).done(d=>{s(d)})},minLength:0,response:()=>{r.addClass("fa-search").removeClass("spinner"),i.removeClass("disabled")},close:()=>t.autocomplete("destroy")}).autocomplete("search","")}),$("#node-config-input-heartbeat").on("change",function(){$("#heartbeatIntervalRow").toggle(this.checked)}),$("#node-config-input-statusHourCycle").on("change",function(){let r={hour:"numeric",minute:"numeric"},a=$(this).val();a&&a!=="default"&&(r.hourCycle=a),$("#node-config-input-statusTimeFormat").children().each(function(){let s=$(this);switch(s.val()){case"h:m:s":r.second="numeric";break;case"h:m:s.ms":r.second="numeric",r.fractionalSecondDigits=3;break;default:break}let d=to({date:new Date(2022,1,1,3,4,5,6),options:r});s.text(d)})}).trigger("change"),$("#ha-boolean-list").editableList({addButton:!0,removable:!0,sortable:!1,height:"auto",header:$("<div>").append(u("config-server.label.state_boolean_list")),addItem:function(r,a,s){let d=$("<div/>").appendTo(r),g=$('<input type="text" style="width: 100%"/>').appendTo(d);typeof s=="string"&&g.val(s)}}),$("#ha-boolean-list").editableList("addItems",this.ha_boolean||[]),$("#ha-server-settings").accordion(),$("#node-config-dialog-edit-form").addClass("ha-config-server-editor")},oneditsave:function(){let e=$("#node-config-input-addon").is(":checked"),n=$("#node-config-input-host").val(),o=new Set;if($("#ha-boolean-list").editableList("items").each(function(){let i=$("input",this).val();i&&o.add(i.toLowerCase().trim())}),this.ha_boolean=Array.from(o),e)this.addon=!0,this.rejectUnauthorizedCerts=!0;else{let i=document.createElement("a");i.href=n,n!==i.origin&&!no(n)&&RED.notify("Invalid format of Base URL: "+n),this.rejectUnauthorizedCerts=!$("#accept_unauthorized_certs").prop("checked"),this.connectionDelay=!1}}},io=rr;function Xe(e,t){let n=[],o=Ye().deviceSelector==="id",i=Ye().entitySelector==="id";switch(t){case"floor":e.floors.forEach(r=>{n.push({label:r.name,value:r.floor_id,alias:[r.floor_id]})});break;case"area":e.areas.forEach(r=>{n.push({label:r.name,value:r.area_id,alias:[r.area_id]})});break;case"device":e.devices.forEach(r=>{let a=o?r.id:r.name_by_user||r.name;n.push({label:a,value:r.id,description:Qn(r.area_id),alias:[r.id]})});break;case"entity":{e.entities.forEach(r=>{let a=i?r.entity_id:r.attributes?.friendly_name||r.entity_id,s=i?r.attributes?.friendly_name:r.entity_id;n.push({label:a,value:r.entity_id,description:s})});break}case"label":e.labels.forEach(r=>{n.push({label:r.name,value:r.label_id,alias:[r.label_id]})});break;default:break}return n.sort((r,a)=>(r.label??r.value).localeCompare(a.label??a.value))}function ar(e){switch(e){case"device":case"entity":return{hasOptionDescription:!0};case"area":case"floor":case"label":default:return{}}}function ro(e,t,n){let o=$("<div>",{class:"virtual-select",style:"flex:1;"});return VirtualSelect.init({ele:o[0],hideClearButton:!0,search:!0,maxWidth:"100%",options:Xe(e,t),placeholder:"",allowNewOption:!0,optionsCount:6,selectedValue:n,...ar(t)}),o}function sr(e){return $("<a>",{href:"#",class:"red-ui-button",style:"margin-left: 10px;",title:u("home-assistant.component.id-selector.label.copy")}).on("click",function(o){o.preventDefault();let i=e.find(".virtual-select");if(i.length===0)return;let r=i[0].value;r&&RED.clipboard.copyText(r)&&RED.notify(u("home-assistant.ui.notifications.clipboard_copy"),{type:"success",timeout:2e3})}).append($("<i>",{class:"fa fa-copy"}))}function pr(e,t){return $("<a>",{href:"#",class:"red-ui-button id-delete-button",style:"margin-left: 10px;",title:u("home-assistant.component.id-selector.label.delete")}).on("click",o=>{o.preventDefault();let i=t.data("data"),r=t.closest("li");r.addClass("red-ui-editableList-item-deleting"),r.fadeOut(200,()=>{e.editableList("removeItem",i)});let a=t.find(".virtual-select");a.length&&a[0].destroy()}).append($("<i>",{class:"fa fa-remove"}))}function ur(e){return $("<input>",{type:"text",class:"id-selector-regex",css:{flex:1},value:e})}function lr(e,t){return $("<a>",{href:"#",class:"red-ui-button",style:"margin-left: 10px;",title:u("home-assistant.component.id-selector.label.preview")}).on("click",function(i){i.preventDefault();let r=e.find("input"),a=r.val();typeof a!="string"||t!=="substring"&&t!=="regex"||Ut({filter:a,filterType:t,entities:Ce(),complete:s=>{r.val(s)}})}).append($("<i>",{class:"fa fa-eye"}))}function ao(e,t,n,o,i){let r=$("<div>",{class:"id-selector-row"}).html(n),a=$("<div>",{class:"id-selector-wrapper"});switch(n){case"floor":case"area":case"device":case"entity":case"label":ro(i,n,o).appendTo(a),sr(t).appendTo(a);break;case"substring":case"regex":ur(o).appendTo(a),lr(t,n).appendTo(a);break;default:}return pr(e,t).appendTo(a),[r,a]}function Te(e,t){e.includes(t)||e.push(t)}function dr(e,t){return t.some(n=>Array.isArray(n)?n.every(o=>(e&o)!==0):(e&n)!==0)}function so(e,t){return t.length===0?!0:dr(e,t)}var z=class{#e;#n;#o;#t;#i;constructor({types:t,element:n,headerText:o,filter:i}){this.#o=t,this.#e=$(n),this.#n=o,this.#t=i??[],this.#i=this.#r(),this.init()}#r(){let t=Yn(),n=Ce(),o=Zn(),i=Kn(),r=Xn(),a=eo();if(this.#t.length===0)return{entities:n,devices:o,areas:i,floors:r,labels:a};let s=[],d=[],g=[],y=[],p=[];for(let m of this.#t){let{integration:f,domain:S,device_class:R,supported_features:x}=m;for(let N of n){let I=t.find(A=>A.entity_id===N.entity_id);if(f&&I?.platform!==f)continue;let C=N.entity_id.split(".")[0];if(S?.length&&!S.includes(C)||R?.length&&N.attributes.device_class!==void 0&&!R.includes(N.attributes.device_class)||x!==void 0&&N.attributes.supported_features!==void 0&&!so(N.attributes.supported_features,x)||(s.push(N),!I))continue;let k=A=>{for(let Z of A){let ft=a.find(bi=>bi.label_id===Z);ft&&Te(p,ft)}};I.labels.length&&k(I.labels);let U;I.device_id&&(U=o.find(A=>A.id===I.device_id),U&&(Te(d,U),k(U.labels)));let B,G=I.area_id??U?.area_id;if(G&&(B=i.find(A=>A.area_id===G),B&&(Te(g,B),k(B.labels))),B?.floor_id){let A=r.find(Z=>Z.floor_id===B?.floor_id);A&&Te(y,A)}}}return{entities:s,devices:d,areas:g,floors:y,labels:p}}#a(t){return{label:u(`home-assistant.component.id-selector.label.add-button.${t}`),icon:"fa fa-plus",class:"red-ui-editableList-add",click:()=>{this.#e.editableList("addItem",{type:t})}}}#s(){return this.#o.map(n=>this.#a(n))}init(){this.#e.addClass("id-selector"),this.#e.editableList({addButton:!1,height:"auto",header:$("<div>").append(this.#n),addItem:(t,n,o)=>{ao(this.#e,t,o.type,o.value,this.#i).forEach(r=>t.append(r))},buttons:this.#s()})}addId(t,n){this.#e.editableList("addItem",{type:t,value:n})}clear(){this.#e.find(".id-delete-button").trigger("click")}refreshOptions(){let t=this;this.#e.editableList("items").each(function(){let n=$(this),{type:o}=n.data("data");if(!po(o))return;let i=n.find(".virtual-select");if(i.length){let r=Xe(t.#i,o);i[0].setOptions(r,!0)}})}updateFilter(t){this.#t=t,this.#i=this.#r(),this.refreshOptions()}};function po(e){return Object.values(q).includes(e)}function X(e){let t=$(e).editableList("items"),n={floor:new Set,area:new Set,device:new Set,entity:new Set,label:new Set,substring:new Set,regex:new Set};return t.each(function(){let{type:o}=$(this).data("data");if(!po(o))return;let i="";switch(o){case"entity":case"device":case"area":case"floor":case"label":{i=$(this).find(".virtual-select")[0].value;break}case"substring":case"regex":{i=$(this).find(".id-selector-regex").val();break}default:break}i.length&&n[o].add(i)}),{floor:Array.from(n.floor),area:Array.from(n.area),device:Array.from(n.device),entity:Array.from(n.entity),label:Array.from(n.label),substring:Array.from(n.substring),regex:Array.from(n.regex)}}var uo="#custom-outputs",Se,Ae=[],cr=Object.values(me).map(e=>({value:e,label:u(`home-assistant.label.entity_state_cast.option.${e.toLowerCase()}`)})),et={config:{value:"config",label:"config.",hasValue:!0},deviceId:{value:"deviceId",label:"device id",hasValue:!1},entity:{value:"entity",label:"entity",hasValue:!1},entityId:{value:"triggerId",label:"entity id",hasValue:!1},entityState:{value:"entityState",label:"entity state",hasValue:!1,options:cr},eventData:{value:"eventData",label:"event data",hasValue:!1},headers:{value:"headers",label:"headers",hasValue:!1},params:{value:"params",label:"params",hasValue:!1},prevEntity:{value:"prevEntity",label:"previous entity",hasValue:!1},previousValue:{value:"previousValue",label:"previous value",hasValue:!1},results:{value:"results",label:"results",hasValue:!1},receivedData:{value:"data",label:"received data",hasValue:!1},sentData:{value:"data",label:"sent data",hasValue:!1},tagId:{value:"triggerId",label:"tag id",hasValue:!1},timeSinceChangedMs:{value:"timeSinceChangedMs",label:"timeSinceChangedMs",hasValue:!1},triggerId:{value:"triggerId",label:"trigger id",hasValue:!1},value:{value:"value",label:"value",hasValue:!1},calendarItem:{value:"calendarItem",label:"calendar item",hasValue:!1}},yr=[et.config,"flow","global","str","num","bool","date","jsonata"];function h(e=[],{element:t=uo,extraTypes:n=[]}={}){Se=$(t),Ae=n,Se.editableList({addButton:!0,removable:!0,sortable:!0,height:"auto",header:$("<div>").append(u("home-assistant.label.output_properties")),addItem:function(o,i,r){o.css({overflow:"hidden",whiteSpace:"nowrap"});let a=$("<div />").appendTo(o),s=$("<input/>",{class:"property-name",type:"text"}).css("width","30%").appendTo(a).typedInput({types:["msg","flow","global"]});$("<div/>",{style:"display:inline-block; padding:0px 6px;"}).text("=").appendTo(a);let d=$("<input/>",{class:"property-value",type:"text"}).css("width","calc(70% - 30px)").appendTo(a).typedInput({default:"str",types:mr()});r.property&&s.typedInput("value",r.property),r.propertyType&&s.typedInput("type",r.propertyType),r.value&&d.typedInput("value",r.value),r.valueType&&d.typedInput("type",r.valueType)}}),Se.editableList("addItems",e)}function mr(){let e=Ae.reduce((t,n)=>n in et?[...t,et[n]]:t,[]);if(e=[...e,...yr],Ae.includes("msg")){let t=e.indexOf("flow");e.splice(t,0,"msg")}return e}function b(){let e=$(uo).editableList("items"),t=[];return e.each(function(){let n=$(this).find(".property-name"),o=$(this).find(".property-value"),i=n.typedInput("value"),r=n.typedInput("type"),a=o.typedInput("value"),s=o.typedInput("type");t.push({property:i,propertyType:r,value:a,valueType:s})}),t}function lo(e){Se.editableList("empty"),Se.editableList("addItems",e)}function co(e){Ae=e}function E(e){return e===void 0||Array.isArray(e)&&!e.some(t=>t.property.length===0)}var tt={target:"_blank",ref:"noopener noreferrer",class:"social-bar-button"},yo=u("home-assistant.ui.text.documentation");function fr(e){return $("<a>",{href:`https://zachowj.github.io/node-red-contrib-home-assistant-websocket/${e?`node/${e}.html`:""}`,title:yo,text:yo,...tt})}var gr=u("home-assistant.ui.text.discord");function vr(){return $("<a>",{href:"https://discord.gg/QNdsZgNBnU",title:"Discord",text:gr,...tt})}var mo=u("home-assistant.ui.text.discussions");function hr(){return $("<a>",{href:"https://github.com/zachowj/node-red-contrib-home-assistant-websocket/discussions",title:mo,text:mo,...tt})}function br(){return $("<span>",{text:u("home-assistant.ui.text.looking_for_help")})}function c(e){let t=$("<div>",{id:"ha-social-bar"});t.append(br()).append(fr(e)).append($("<span>").text(" / ")).append(hr()).append($("<span>").text(" / ")).append(vr()),$("#dialog-form").prepend(t)}function le(){let e=$("#ha-action").val(),[t,n]=e.toLowerCase().split(".");return[t,n]}function nt(e){return Object.keys(e).sort().reduce((o,i)=>(Object.keys(e[i]).sort().forEach(a=>{o.push({value:`${i}.${a}`,label:`${i}.${a}`,description:e[i][a].description})}),o),[])}var ot=()=>{let e=$("#service-data-desc"),t=$(".service-description",e),n=$("tbody",e),o=$(".unknown-service",e),i=$(".known-service",e),r=$("#example-data"),[a,s]=le(),g=K()?.[a]?.[s];if(g){let y=g.description?g.description:"No description provided by home assistant",p=g.fields,m=Object.keys(p).reduce((f,S)=>{let R=p[S];return!R.description&&!R.example||f.push(`<tr><td><code>${S}</code></td><td>${p[S].description??""}</td><td>${p[S].example??""}</td></tr>`),f},[]);t.html(y),$("#service-data-desc .title").html(`${a}.${s}`),m.length?($("#service-data-table").show(),r.show(),n.html(m.length>0?m.join(""):"")):($("#service-data-table").hide(),r.hide(),t.append("<p>No fields documented by Home Assistant<p>")),o.hide(),i.show()}else o.show(),i.hide(),r.hide(),$("#service-data-desc .title").html("")},fo=()=>{let e=$("#node-input-data"),[t,n]=le(),o=$("#node-input-server").val();if(t&&n&&o){let r=K()?.[t]?.[n];if(r){let a=r.fields,s=Object.keys(a).reduce((d,g)=>{let y=a[g].example;if(g==="entity_id")return d[g]=y??"",d;if(y===void 0)return d;if(typeof y=="string")if(y[0]==="["&&y[y.length-1]==="]")try{d[g]=JSON.parse(y)}catch{}else y[0]==='"'&&y[y.length-1]==='"'?d[g]=y.substring(1,y.length-1):d[g]=y;else typeof y=="number"&&!isNaN(y)?d[g]=Number(y):y&&(d[g]=y);return d},{});Object.keys(s).length&&e.typedInput("value",JSON.stringify(s))}}};function go(e){return{integration:e.integration,domain:Array.isArray(e.domain)?e.domain:e.domain?[e.domain]:void 0,device_class:Array.isArray(e.device_class)?e.device_class:e.device_class?[e.device_class]:void 0,supported_features:e.supported_features}}function Er(e){return e.entity?Array.isArray(e.entity)?e.entity.map(go):[go(e.entity)]:[]}function vo(e){if(oo(e))return"all";let t=K(),[n,o]=le();return Object.keys(t).length===0||!t?.[n]?.[o]||t?.[n]?.[o]?.target!==void 0?"all":"none"}function it(){let e=K(),[t,n]=le(),o=e?.[t]?.[n]?.target;return o?Er(o):[]}var Tr={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,icon:"ha-call-service.svg",align:"right",paletteLabel:"action",label:function(){return this.name||this.action||"action"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("apiCallServiceVersion",0)},debugenabled:{value:!1},action:{value:""},floorId:{value:[]},areaId:{value:[]},deviceId:{value:[]},entityId:{value:[]},labelId:{value:[]},data:{value:"",validate:RED.validators.typedInput({type:"dateType",allowBlank:!0})},dataType:{value:"jsonata"},mergeContext:{value:""},mustacheAltTags:{value:!1},outputProperties:{value:[],validate:E},queue:{value:"none"},blockInputOverrides:{value:!0},domain:{value:""},service:{value:""},target:{value:void 0},output_location:{value:void 0},output_location_type:{value:void 0},service_domain:{value:void 0},mergecontext:{value:void 0}},oneditprepare:function(){l.setup(this);let e=$("#ha-action"),t="";v(this,"#node-input-server",function(a){if(a===t)return;t=a,ot(),n.refreshOptions();let s=K();e[0].setOptions(nt(s))}),VirtualSelect.init({ele:"#ha-action",allowNewOption:!0,search:!0,maxWidth:"70%",placeholder:"",selectedValue:this.action,silentInitialValueSet:!0,hasOptionDescription:!0,options:nt(K()),optionsCount:8});let n=new z({element:"#target-list",types:["entity","device","area","floor","label"],headerText:u("ha-action.label.targets"),filter:it()}),o={floor:this.floorId,area:this.areaId,device:this.deviceId,entity:this.entityId,label:this.labelId};Object.entries(o).forEach(([a,s])=>{s?.forEach(d=>{n.addId(a,d)})}),e.on("change",()=>{ot(),n.updateFilter(it());let a=e.val(),s=vo(a)==="all";$("#target-list").parents(".form-row").toggle(s),s||n.clear()}).trigger("change");let i=$("#node-input-data"),r=$("#node-input-dataType");i.typedInput({default:"jsonata",types:["jsonata","json"],typeField:"#node-input-dataType"}),i.on("change",()=>{$("#mustacheAltTags").toggle(r.val()==="json")}),h(this.outputProperties,{extraTypes:["sentData","results","msg"]}),$("#example-data").on("click",fo),c("action")},oneditsave:function(){this.action=$("#ha-action").val(),this.action.indexOf(".")!==-1&&([this.domain,this.service]=this.action.split("."));let e=X("#target-list");this.floorId=e.floor,this.areaId=e.area,this.deviceId=e.device,this.entityId=e.entity,this.labelId=e.label,this.outputProperties=b()}},ho=Tr;var Sr={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,icon:"font-awesome/fa-paper-plane-o",paletteLabel:"API",label:function(){return this.name||"API"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haApiVersion",0)},debugenabled:{value:!1},protocol:{value:"websocket"},method:{value:"get"},path:{value:""},data:{value:"",validate:RED.validators.typedInput({type:"dateType",allowBlank:!0})},dataType:{value:"jsonata"},responseType:{value:"json"},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"results"}],validate:E},location:{value:void 0},locationType:{value:void 0}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),$("#node-input-data").typedInput({types:["jsonata","json"],typeField:"#node-input-dataType"}),$("#node-input-protocol").on("change",function(){let e=$(this).val()==="http";$(".http").toggle(e),$("#node-input-method").trigger("change")}).trigger("change"),$("#node-input-method").on("change",function(){let e=$("#node-input-method").val(),t=$("#node-input-protocol").val()==="http"&&["get","delete"].includes(e)?"parameters":"data";$("#data-label").text(u(`ha-api.label.${t}`))}),$("#node-input-location").typedInput({types:["msg","flow","global",{value:"none",label:"None",hasValue:!1}],typeField:"#node-input-locationType"}),h(this.outputProperties,{extraTypes:["results"]}),c("API")},oneditsave:function(){this.outputProperties=b()}},bo=Sr;var xr="node-red-contrib-home-assistant-websocket/all:",Eo=`${xr}ha-entity-config.data.label`,$r=(e,t,n)=>$("<input />",{type:"date",name:"value",value:t,id:e,"data-property":n.id}),_r=(e,t,n)=>{let o=new Date(t),i=a=>a<10?"0"+a:a,r=t?`${o.getFullYear()}-${i(o.getMonth()+1)}-${i(o.getDate())}T${i(o.getHours())}:${i(o.getMinutes())}`:"";return $("<input />",{type:"datetime-local",name:"value",value:r,id:e,"data-property":n.id})},Dr=(e,t,n)=>{let o=$("<ol />",{id:e}),i=$("<div />",{style:"width: 70%;display: inline-block;"}).append(o);return o.editableList({addButton:!0,removable:!0,sortable:!0,height:"auto",addItem:function(r,a,s){$("<input />",{type:"text",value:typeof s=="string"?s:"",style:"width: 95%"}).appendTo(r)}}),o.editableList("addItems",Array.isArray(t)?t:n),i},To=(e,t,n)=>$("<input />",{type:"text",name:"value",value:t,id:e,"data-property":n.id}).attr("autocomplete","off"),Nr=(e,t,n)=>$("<input />",{type:"number",name:"value",value:t,id:e,"data-property":n.id}).attr("autocomplete","off"),wr=(e,t,n)=>{let o=$("<select />",{name:"value",id:e,style:"width: 70%","data-property":n.id}),i=`${Eo}.${n.id}_options`;return n.values.forEach(r=>{$("<option />",{value:r,text:r?RED._(`${i}.${r}`):"",selected:r===t}).appendTo(o)}),o},Ir=(e,t,n)=>{let o=$("#ha-config-device_class").val(),i=n.values[o];if(o===""||i===null)return To(e,t,n);let r=$("<select />",{name:"value",id:e,style:"width: 70%","data-property":n.id});return i.forEach(a=>{$("<option />",{value:a,text:a,selected:a===t}).appendTo(r)}),r},rt=(e,t)=>{let n=`ha-config-${t.id}`,o=$("<div />",{class:"form-row ha-config-row","data-type":t.type}),i=RED._(`${Eo}.${t.id}`),r=$("<label>",{for:n}).text(i);switch(o.append(r," "),t.type){case"date":o.append($r(n,e,t));break;case"datetime":o.append(_r(n,e,t));break;case"editableList":r.css({verticalAlign:"top"}),o.append(Dr(n,e,t.values));break;case"number":o.append(Nr(n,e,t));break;case"select":o.append(wr(n,e,t));break;case"unit_of_measurement":{o.append(Ir(n,e,t));break}case"string":o.append(To(n,e,t));break}return o},T=(e,t="entityConfig")=>{$(`#node-input-btn-${t}-add`).on("click",function(){$("body").data("haEntityType",e)}),$(`#node-input-lookup-${t}`).on("click",function(){$(`#node-input-${t}`).val()==="_ADD_"&&$("body").data("haEntityType",e)})},So=()=>{let e=$("body").data("haEntityType");e&&($("#node-config-input-entityType").val(e),$("body").data("haEntityType",null))};var Pr=["msg","flow","global","jsonata","str","num","bool"],Or=["str","num","bool","date","jsonata","msg","flow","global"],Rr={category:"home_assistant_entities",color:"#41BDF5",inputs:1,outputs:1,icon:"font-awesome/fa-check-circle-o",align:"right",paletteLabel:"binary sensor",label:function(){return this.name||"binary sensor"},labelStyle:l.labelStyle,defaults:{name:{value:""},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="binary_sensor",required:!0},version:{value:RED.settings.get("haBinarySensorVersion",0)},state:{value:"payload"},stateType:{value:"msg"},attributes:{value:[]},inputOverride:{value:"allow"},outputProperties:{value:[],validate:E}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),_(this),$("#node-input-state").typedInput({types:Pr,typeField:"#node-input-stateType",type:this.stateType}),T("binary_sensor"),$("#attributes").editableList({removable:!0,addButton:"add attribute",header:$("<div>").append($.parseHTML("<div style='width:40%; display: inline-grid'>Attribute Key</div><div style='display: inline-grid'>Value</div>")),addItem:function(t,n,o){let i=$("<div />").appendTo(t);$("<input />",{type:"text",name:"property",style:"width: 40%;margin-right: 5px;"}).attr("autocomplete","disable").appendTo(i).val(o.property);let r=$("<input />",{type:"text",name:"value",style:"width: 55%;"}).appendTo(i).val(o.value);r.typedInput({types:Or}),r.typedInput("type",o.valueType)}}).editableList("addItems",this.attributes),h(this.outputProperties,{extraTypes:["sentData"]}),c("binary-sensor")},oneditsave:function(){this.attributes=[];let e=this;$("#attributes").editableList("items").each(function(){let t=$(this);e.attributes.push({property:t.find("input[name=property]").val(),value:t.find("input[name=value]").typedInput("value"),valueType:t.find("input[name=value]").typedInput("type")})}),this.outputProperties=b()}},xo=Rr;var Cr={category:"home_assistant_entities",color:"#41BDF5",inputs:0,outputs:1,icon:"font-awesome/fa-hand-o-up",align:"left",paletteLabel:"button",label:function(){return this.name||"button"},labelStyle:l.labelStyle,defaults:{name:{value:""},version:{value:RED.settings.get("haButtonVersion",0)},debugenabled:{value:!1},outputs:{value:1},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="button",required:!0},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"entityState"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"},{property:"data",propertyType:"msg",value:"",valueType:"entity"}],validate:E}},oneditprepare:function(){l.setup(this),_(this),T("button"),h(this.outputProperties,{extraTypes:["entity","entityState","entityId"]}),c("button")},oneditsave:function(){this.outputProperties=b()}},$o=Cr;var Ar={serverId:"#node-input-server",type:"entities"};function W({root:e,options:t}){let n=bt(e)?e:$(e),o={...Ar,...t},i=$(o.serverId).val(),r=o.type;n.autocomplete({source:(a,s)=>{let d=a.term.toLowerCase(),g=At(i,r).filter(y=>y.value.toLowerCase().includes(d)||y.label.toLowerCase().includes(d));s(g)},minLength:0}).autocomplete("instance")._renderItem=(a,s)=>$("<li>").append(`<div>${s.label}<p class="sublabel">${s.value}</p></div>`).appendTo(a)}var de=function(e,t,n,o){let i=$(e),r=$(n),a={value:"entity",label:"entity."},s={value:"habool",label:"Home Assistant State Boolean",hasValue:!1},d=["str","num","bool","re","jsonata","msg","flow","global",a];o!=="currentState"&&d.splice(5,1),i.after(' <a id="clearIfState" class="editor-button"><i class="fa fa-remove"></i></a>');let g=$("#clearIfState");function y(p){let m=["flow","global",a],f=d.includes("msg")?["msg",...m]:m;switch(p){case"is":case"is_not":return d;case"lt":case"lte":case"gt":case"gte":return["num","jsonata",...f];case"includes":case"does_not_include":return["str","jsonata",...f,s];case"jsonata":return["jsonata"];default:return d}}i.typedInput({default:"str",types:y(r.val()),typeField:t}),r.on("change",function(){let p=$(this),m=y(p.val());i.typedInput("types",m)}),r.trigger("change"),i.on("change",function(){$(this).val()&&g.show()}),g.on("click",p=>{i.typedInput("type","str"),i.typedInput("value",""),$(p.currentTarget).hide()}),i.val()||g.hide()};function _o(){return $("#dialog-form").find(".form-row.ha-deprecated:visible").not(".ha-deprecated--description").length>0}function ee(e,t){if(!t.length)return;let n=$("<div></div>"),o=$(`
<div class="form-row ui-widget" id="ha-deprecated-settings" style="cursor: pointer; margin-bottom: 1em; font-weight: bold;">
${u("home-assistant.ui.deprecated_settings.title")}
</div>
`).on("click",()=>{let r=_o();$(".form-row.ha-deprecated").toggle(!r)}),i=$(`
<div class="form-row ha-deprecated ha-deprecated--description" style="margin-bottom: 1em; font-style: italic;">
${u("home-assistant.ui.deprecated_settings.description")}
</div>
`);n.append(o,i);for(let r of t)switch(r){case"state_type":n.append(Hr(Lr(e),e));break}$("#dialog-form").append(n.children()),_o()||i.hide()}function Hr(e,t){let n=e.clone();return n.find('[id^="node-input-"]').each(function(){let o=$(this).attr("id")?.replace("node-input-","");if(!o)return;let i=t[o];i!==void 0&&$(this).val(typeof i=="string"||typeof i=="number"?i:String(i))}),n}function Lr(e){let t=e.type==="api-current-state"?"state_type":"stateType",n=`
<div class="form-row ha-deprecated">
<label for="node-input-${t}">${u("api-current-state.label.state_type")}</label>
<select type="text" id="node-input-${t}">
<option value="str">${u("api-current-state.label.state_type_option.string")}</option>
<option value="num">${u("api-current-state.label.state_type_option.number")}</option>
<option value="habool">${u("api-current-state.label.state_type_option.boolean")}</option>
</select>
</div>
<div class="form-row ha-deprecated" style="color: var(--red-ui-text-color-warning);font-weight: bold;">
${u("home-assistant.ui.deprecated_settings.state_type_warning")}
</div>
`,o=$(n);return e[t]==="str"&&o.filter(".form-row.ha-deprecated").hide(),o}var kr={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,outputLabels:function(e){if(this.halt_if){if(e===0)return"'If State' is true";if(e===1)return"'If State' is false"}},icon:"ha-current-state.svg",paletteLabel:"current state",label:function(){return this.name||`current_state: ${this.entity_id}`},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("apiCurrentStateVersion",0)},outputs:{value:1},halt_if:{value:""},halt_if_type:{value:"str"},halt_if_compare:{value:"is"},entity_id:{value:""},state_type:{value:"str"},blockInputOverrides:{value:!0},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"string",valueType:"entityState"},{property:"data",propertyType:"msg",value:"",valueType:"entity"}],validate:E},for:{value:"0"},forType:{value:"num"},forUnits:{value:"minutes"},override_topic:{value:!1},state_location:{value:"payload"},override_payload:{value:"msg"},entity_location:{value:"data"},override_data:{value:"msg"}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),W({root:"#node-input-entity_id"}),de("#node-input-halt_if","#node-input-halt_if_type","#node-input-halt_if_compare","currentState"),$("#node-input-halt_if_compare").on("change",function(){let e=["is","is_not","includes","does_not_include"].includes(this.value);$("#for-row").toggle(e)}),$("#node-input-for").typedInput({default:"num",types:["num","jsonata","msg","flow","global"],typeField:"#node-input-forType"}),h(this.outputProperties,{extraTypes:["entity","entityId","entityState"]}),c("current-state"),ee(this,["state_type"])},oneditsave:function(){let t=$("#node-input-halt_if").val()!==""||$("#node-input-halt_if_type").val()==="habool"?2:1;$("#node-input-outputs").val(t),this.outputProperties=b()}},Do=kr;var lt={};gt(lt,{getCapabilitiesList:()=>Vr,getEventList:()=>Fr,inputCount:()=>Mr,setDefaultOutputs:()=>Jr});function ut(e){let t=De(e),n=[];return t.forEach(o=>{n.push({value:o.id,label:o.name_by_user||o.name,description:_e(e,o.area_id)})}),n.sort((o,i)=>(o.label||o.value).localeCompare(i.label||i.value)),n}async function ce(e,t,n){let o=await Re(e,t).catch(i=>{throw new Error(`${u(n)} ${i.message??""}`)});if(!o.success)throw new Error(`${u(n)} ${o.message}`);return o.data}var Mr=1;async function Vr(e){return ce("deviceActionCapabilities",{event:JSON.stringify(e)},"ha-device.error.failed_to_fetch_capabilities")}async function Fr(e){return ce("deviceActions",{deviceId:e},"ha-device.error.failed_to_fetch_actions")}function Jr(){return[]}var dt={};gt(dt,{getCapabilitiesList:()=>Wr,getEventList:()=>Ur,inputCount:()=>Gr,setDefaultOutputs:()=>jr});var Gr=0;async function Wr(e){return ce("deviceTriggerCapabilities",{event:JSON.stringify(e)},"ha-device.error.failed_to_fetch_capabilities")}async function Ur(e){return ce("deviceTriggers",{deviceId:e},"ha-device.error.failed_to_fetch_actions")}function jr(e){return e}function ye(e,t){return`<label for="${t}">${e.replace(/_/g," ")}</label>`}function No(e=[],t=[]){let n=[];return e.forEach(o=>{let i=t.find(r=>r.name===o.name);switch(o.type){case"boolean":{let r=qr(o,i);n.push($(r));break}case"float":{let r=zr(o,i);n.push($(r));break}case"integer":{let r=Qr(o,i);n.push(r);break}case"positive_time_period_dict":{let r=Kr(o,i);n.push($(r));break}case"select":{let r=Zr(o,i);n.push($(r));break}case"string":{let r=Yr(o,i);n.push($(r));break}default:{let r=u("ha-device.error.unknown_field_type",{type:o.type}),a=Xr(r,{type:o.type});n.push($(a))}}}),n}function qr(e,t){let n=`deviceExtra-${e.name}`,o=t?t.value:"",i=`${ye(e.name,n)}
<input type="checkbox" id="${n}" style="width: auto" value="${o}"/>
`;return re(i)}function zr(e,t){let n=`deviceExtra-${e.name}`,o=t?t.value:"",i=`
${ye(e.name,n)}
<input type="text" id="${n}" style="width: 35%" value="${o}"/>
`;return e.description&&e.description.suffix&&(i+=`<span>${e.description.suffix}</span>`),re(i)}function Qr(e,t){let n=`deviceExtra-${e.name}`,o=t?t.value:"",i=$(`
${ye(e.name,n)}
<div class="range-row">
<input type="checkbox" />
<input type="range" id="${n}" max="${e.valueMax}" min="${e.valueMin??0}" value="${o}" />
<input type="text" value="${o}" />
</div>
`),r=i.find('input[type="checkbox"]'),a=i.find('input[type="range"]'),s=i.find('input[type="text"]');return(e.optional===!1||t?.value!==void 0)&&r.prop("checked",!0),e.optional===!1&&r.hide(),r.on("change",()=>{a.prop("disabled",!r.prop("checked")).trigger("change"),s.prop("disabled",!r.prop("checked"))}).trigger("change"),a.on("change input",()=>{s.val(a.val())}).trigger("change"),s.on("keyup change",()=>{let d=s.val();if(d.length>0){let g=Number(d);g<e.valueMin&&s.val(e.valueMin),g>e.valueMax&&s.val(e.valueMax),a.val(s.val())}}),re(i)}function Kr(e,t){let n=`deviceExtra-${e.name}`,o=t?t.value:"",i=d=>t&&d===t.unit?"selected":"",r="ha-device.label",a={seconds:u(`${r}.seconds`),minutes:u(`${r}.minutes`),hours:u(`${r}.hours`)},s=`
${ye(e.name,n)}
<input type="text" id="${n}" style="width: 35%" value="${o}"/>
<select id="${n}Units" style="width: 35%">
<option value="seconds" ${i("seconds")}>${a.seconds}</option>
<option value="minutes" ${i("minutes")}>${a.minutes}</option>
<option value="hours" ${i("hours")}>${a.hours}</option>
</select>`;return re(s)}function Zr(e,t={}){let n=`deviceExtra-${e.name}`,o=e.options.reduce((r,[a,s])=>{let d=t.value===a?"selected":"";return r.push(`<option value="${a}" ${d}>${s}</option>`),r},[]),i=`
${ye(e.name,n)}
<select id="${n}" style="width: 70%">
${o.join("")}
</select>
`;return re(i)}function Yr(e,t){let n=`deviceExtra-${e.name}`,o=t?t.value:"",i=`
${ye(e.name,n)}
<input type="text" id="${n}" style="width: 70%" value="${o}"/>
`;return re(i)}function Xr(e,t={}){let n=`<label class="error"><i class="fa fa-exclamation-triangle"></i> Error</label>${e} -- <a href="https://github.com/zachowj/node-red-contrib-home-assistant-websocket/issues/new?title=[Device Node] Unknown extra type: ${t.type}" target="_blank"> ${u("ha-device.error.report")}</a>`;return re(n)}function re(e,t=["deviceExtra"]){return e instanceof $?$(`<div class="form-row ${t.join(" ")}"></div>`).append(e):`<div class="form-row ${t.join(" ")}">${e}</div>`}function wo(e=[]){return e.reduce((n,o)=>{let i=`deviceExtra-${o.name}`,r=$(`#${i}`).val();switch(o.type){case"boolean":n.push({name:o.name,type:o.type,value:$(`#${i}`).is(":checked")});break;case"float":case"positive_time_period_dict":if(r?.length&&!isNaN(Number(r))){let a={name:o.name,type:o.type,value:Number(r),unit:o.type==="positive_time_period_dict"?$(`#${i}Units`).val():void 0};n.push(a)}break;case"integer":{if($(`#${i}`).siblings('input[type="checkbox"]').prop("checked")&&r?.length&&!isNaN(Number(r))){let d={name:o.name,type:o.type,value:Number(r)};n.push(d)}break}case"select":r.length&&n.push({name:o.name,type:o.type,value:r});break;case"string":r?.length&&n.push({name:o.name,type:o.type,value:r});break}return n},[])}function ct(e){return e==="action"?lt:dt}function ta(e){if(!Array.isArray(e))return!0;for(let t of e)switch(t.type){case"float":if(!Number.isFinite(Number(t.value)))return!1;break;case"positive_time_period_dict":{if(Math.sign(t.value)===-1)return!1;break}}return!0}var Io=[{property:"payload",propertyType:"msg",value:"",valueType:"eventData"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],na={category:"home_assistant",color:"#77DD77",inputs:0,outputs:1,icon:"font-awesome/fa-cube",paletteLabel:"device",label:function(){return this.name||`device ${this.deviceType}`},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haDeviceVersion",0)},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},inputs:{value:0},deviceType:{value:"trigger"},device:{value:""},event:{value:void 0,validate:e=>e!==void 0},capabilities:{value:[],validate:ta},outputProperties:{value:Io,validate:E},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0}},oneditprepare:async function(){let e="_ADD_",t=$("#node-input-server"),n=$("#node-input-deviceType"),o=$("#ha-device"),i=$("#event");l.setup(this),v(this,"#node-input-server",async x=>{d(),o[0].setOptions(ut(x)),x!==e&&(await s(),await m(o.val()))}),_(this);let r=ct(n.val()),a;T("switch","exposeAsEntityConfig");let s=async()=>{let x=RED.i18n.lang();try{a=await Re("translations",{cat:"device_automation",lang:x})}catch{RED.notify("Error retrieving translations.")}};await s(),VirtualSelect.init({ele:"#ha-device",allowNewOption:!0,search:!0,maxWidth:"70%",placeholder:"",selectedValue:this.device,silentInitialValueSet:!0,hasOptionDescription:!0,options:ut(zn()),optionsCount:8,hideClearButton:!0}),o.on("change",async function(x){await m(x.currentTarget.value)}),i.on("change",async function(x){let N=x.currentTarget.value;if(N==="__NONE__")return;let I=i.data("events");await f(I[N])});let d=()=>{y(),p()},g=async x=>{let N=o.val(),I=x.currentTarget.value;p(),N&&(r=ct(I),await m(N)),co(R(I));let C=I==="trigger"?Io:[],k=r.setDefaultOutputs(C);lo(k),i.prev().text(I),$("#node-input-exposeAsEntityConfig").closest("div.form-row").toggle(I==="trigger")};t.one("change",async()=>{d(),t.val()!==e&&await m(this.device,this.event,this.capabilities),setTimeout(()=>{n.on("change",g)},100)});let y=()=>{i.html(`<option value="__NONE__">No ${n.val()}s</option>`).trigger("change").prop("disabled",!0)},p=()=>{$(".deviceExtra").remove()},m=async(x,N,I)=>{if(!x)return;let C=await r.getEventList(x).catch(U=>(RED.notify(U),[])),k;if(C.length===0)y(),p(),k=0;else{if(C[0].device_id!==o.val())return;let U=n.val();i.data("events",C).empty().prop("disabled",!1);let B=[];for(let G=0;G<C.length;G++){let A=S(U,C[G]);B.push(new Option(A,G.toString()))}i.append(B),k=C.findIndex(G=>Me(N,G)),k=k===-1?0:k,f(C[k],I)}$("option",i).eq(k).prop("selected",!0)},f=async(x,N)=>{p();let I=await r.getCapabilitiesList(x).catch(C=>(RED.notify(C),[]));if(I?.length){i.data("capabilities",I);let C=No(I,N);i.parent().after(C)}},S=(x,N)=>{let I=(B="type")=>`component.${N.domain}.device_automation.${x}_${B}.${N[B]}`,C=a?.[I()]??(N.subtype?`"${N.subtype}" ${N.type}`:N.type),k={entity_name:()=>{let B="<unknown>";if(!N.entity_id)return B;let G=t.val(),A=Ht(G,N.entity_id);if(!A)return B;if(A?.name)return A.name;let Z=Ge(G,A.entity_id);return Z?Z.attributes.friendly_name===void 0?Z.entity_id.replace(/_/g," "):Z.attributes.friendly_name??"":A.original_name||A.entity_id},subtype:()=>a[I("subtype")]||N.subtype},U=Object.keys(k);for(let B of U){let G=`{${B}}`;if(C.indexOf(G)!==-1)try{let A=k[B]();C=C.replace(G,A)}catch(A){RED.notify(`Error fetaching translation device event: ${JSON.stringify(A)}`)}}return C},R=x=>({action:["sentData"],trigger:["eventData","triggerId"]})[x];$("#dialog-form").prepend(l.betaWarning(1467)),h(this.outputProperties,{extraTypes:R(n.val())}),c("device")},oneditsave:function(){let e=ct($("#node-input-deviceType").val());this.inputs=e.inputCount,this.device=$("#ha-device").val();let t=$("#event"),n=t.val();if(n!=="__NONE__"){let o=t.data("events"),i=t.data("capabilities");this.event=o[n],this.capabilities=wo(i)}this.outputProperties=b()}},Po=na;var oa={category:"config",defaults:{version:{value:RED.settings.get("haDeviceConfigVersion",0)},name:{value:"",required:!1},hwVersion:{value:"",required:!1},manufacturer:{value:"Node-RED",required:!1},model:{value:"",required:!1},swVersion:{value:"",required:!1}},icon:"font-awesome/fa-device",label:function(){return this.name||"Device Config"},oneditprepare:function(){l.setup(this)}},Oo=oa;var ia={category:"home_assistant_deprecated",color:"#A6BBCF",inputs:1,outputs:1,icon:function(){return this?.entityType==="switch"?"ha-entity-switch.svg":"font-awesome/fa-genderless"},align:"right",paletteLabel:"entity",label:function(){return this.name||`type: ${this.entityType}`},labelStyle:function(){return this.name?"node_label_italic":""},defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haEntityVersion",0)},debugenabled:{value:!1},outputs:{value:1},entityType:{value:"sensor"},config:{value:[{property:"name",value:""},{property:"device_class",value:""},{property:"icon",value:""},{property:"unit_of_measurement",value:""},{property:"state_class",value:""},{property:"last_reset",value:""}]},state:{value:"payload"},stateType:{value:"msg"},attributes:{value:[]},resend:{value:!0},outputLocation:{value:"payload"},outputLocationType:{value:"none"},inputOverride:{value:"allow"},outputOnStateChange:{value:null},outputPayload:{value:null},outputPayloadType:{value:null}},oneditprepare:function(){l.setup(this),this.server&&RED.tray.close()}},Ro=ia;var ra=["battery","battery_charging","co","cold","connectivity","door","garage_door","gas","heat","light","lock","moisture","motion","moving","occupancy","opening","plug","power","presence","problem","running","safety","smoke","sound","tamper","update","vibration","window"],Co=[{id:"entity_category",type:"select",values:["","config","diagnostic"]},{id:"device_class",type:"select",values:["",...ra]}];var Ao=[{id:"entity_category",type:"select",values:["","config","diagnostic"]},{id:"device_class",type:"select",values:["","restart","update"]}];var He=["AED","AFN","ALL","AMD","ANG","AOA","ARS","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","BMD","BND","BOB","BOV","BRL","BSD","BTN","BWP","BYN","BZD","CAD","CDF","CHE","CHF","CHW","CLF","CLP","COP","COU","CRC","CUC","CUP","CVE","CZK","DJF","DKK","DOP","DZD","EGP","ERN","ETB","EUR","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MAD","MDL","MGA","MKD","MMK","MNT","MOP","MRU","MUR","MVR","MWK","MXN","MXV","MYR","MZN","NAD","NGN","NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","CNY","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLL","SOS","SRD","SSP","STN","SVC","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","USD","USN","UYI","UYU","UYW","UZS","VED","VES","VND","VUV","WST","XAF","XAG","XAU","XBA","XBB","XBC","XBD","XCD","XDR","XOF","XPD","XPF","XPT","XSU","XTS","XUA","XXX","YER","ZAR","ZMW","ZWL"];var sa=["apparent_power","aqi","atmospheric_pressure","battery","carbon_dioxide","carbon_monoxide","current","data_rate","data_size","distance","energy","energy_storage","frequency","gas","humidity","illuminance","irradiance","moisture","monetary","nitrogen_dioxide","nitrogen_monoxide","nitrous_oxide","ozone","pm1","pm10","pm25","power","power_factor","precipitation","precipitation_intensity","pressure","reactive_power","signal_strength","sound_pressure","speed","sulphur_dioxide","temperature","volatile_organic_compounds","voltage","volume","volume_storage","water","weight","wind_speed"],pa={apparent_power:["VA"],aqi:null,atmospheric_pressure:["cbar","bar","hPa","inHg","kPa","mbar","Pa","psi"],battery:["%"],carbon_dioxide:["ppm"],carbon_monoxide:["ppm"],current:["A"],data_rate:["bit/s","kbit/s","Mbit/s","Gbit/s","B/s","kB/s","MB/s","GB/s","KiB/s","MiB/s","GiB/s"],data_size:["bit","kbit","Mbit","Gbit","B","kB","MB","GB","TB","PB","EB","ZB","YB","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],distance:["km","m","cm","mm","mi","yd","in"],energy:["Wh","kWh","MWh","GJ"],energy_storage:["Wh","kWh","MWh","MJ","GJ"],frequency:["Hz","kHz","MHz","GHz"],gas:["m\xB3","ft\xB3"],humidity:["%"],illuminance:["lx","lm"],irradiance:["W/m\xB2","BTU/(h*ft\xB2)"],moisture:["%"],monetary:He,nitrogen_dioxide:["\xB5g/m\xB3"],nitrogen_monoxide:["\xB5g/m\xB3"],nitrous_oxide:["\xB5g/m\xB3"],ozone:["\xB5g/m\xB3"],pm1:["\xB5g/m\xB3"],pm25:["\xB5g/m\xB3"],pm10:["\xB5g/m\xB3"],power:["W","kW"],power_factor:["%"],precipitation:["mm","in","cm"],precipitation_intensity:["mm/h","mm/d","in/h","in/d"],pressure:["cbar","bar","hPa","inHg","kPa","mbar","Pa","psi"],reactive_power:["var"],signal_strength:["dB","dBm"],sound_pressure:["dB","dBA"],speed:["ft/s","in/d","in/h","km/h","kn","m/s","mm/d","mph"],sulphur_dioxide:["\xB5g/m\xB3"],temperature:["\xB0C","\xB0F"],volatile_organic_compounds:["\xB5g/m\xB3"],voltage:["V"],volume:["fl. oz.","ft\xB3","gal","L","mL","m\xB3"],volume_storage:["L","mL","gal","fl. oz.","m\xB3","ft\xB3","CCF"],water:["L","gal","m\xB3","ft\xB3"],weight:["g","kg","lb","mg","oz","\xB5g"],wind_speed:["ft/s","km/h","kn","m/s","mph"]},Ho=[{id:"entity_category",type:"select",values:["","config","diagnostic"]},{id:"device_class",type:"select",values:["",...sa]},{id:"unit_of_measurement",type:"unit_of_measurement",values:pa},{id:"min_value",type:"number"},{id:"max_value",type:"number"},{id:"step_value",type:"number"},{id:"mode",type:"select",values:["auto","box","slider"]}];var Lo=[{id:"entity_category",type:"select",values:["","config","diagnostic"]},{id:"options",type:"editableList",values:["option1"]}];var ua=["apparent_power","aqi","area","atmospheric_pressure","battery","blood_glucose_concentration","carbon_dioxide","carbon_monoxide","conductivity","current","data_rate","data_size","date","distance","duration","energy","energy_storage","enum","frequency","gas","humidity","illuminance","irradiance","moisture","monetary","nitrogen_dioxide","nitrogen_monoxide","nitrous_oxide","ozone","pm1","pm10","pm25","potential_hydrogen","power","power_factor","precipitation","precipitation_intensity","pressure","reactive_power","signal_strength","sound_pressure","speed","sulphur_dioxide","temperature","timestamp","volatile_organic_compounds","volatile_organic_compounds_parts","voltage","volume","volume_flow_rate","volume_storage","water","weight","wind_speed"],la={apparent_power:["VA"],aqi:null,area:["m\xB2","cm\xB2","km\xB2","mm\xB2","in\xB2","ft\xB2","yd\xB2","mi\xB2","ac","ha"],atmospheric_pressure:["cbar","bar","hPa","inHg","kPa","mbar","Pa","psi"],battery:["%"],blood_glucose_concentration:["mg/dL","mmol/L"],carbon_dioxide:["ppm"],carbon_monoxide:["ppm"],conductivity:["S/cm","mS/cm","\xB5S/cm"],current:["A"],data_rate:["bit/s","kbit/s","Mbit/s","Gbit/s","B/s","kB/s","MB/s","GB/s","KiB/s","MiB/s","GiB/s"],data_size:["bit","kbit","Mbit","Gbit","B","kB","MB","GB","TB","PB","EB","ZB","YB","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],date:null,distance:["km","m","cm","mm","mi","yd","in"],duration:["d","h","min","s","ms","\xB5s"],energy:["Wh","kWh","MWh","GJ"],energy_storage:["Wh","kWh","MWh","MJ","GJ"],enum:null,frequency:["Hz","kHz","MHz","GHz"],gas:["m\xB3","ft\xB3"],humidity:["%"],illuminance:["lx","lm"],irradiance:["W/m\xB2","BTU/(h*ft\xB2)"],moisture:["%"],monetary:He,nitrogen_dioxide:["\xB5g/m\xB3"],nitrogen_monoxide:["\xB5g/m\xB3"],nitrous_oxide:["\xB5g/m\xB3"],ozone:["\xB5g/m\xB3"],pm1:["\xB5g/m\xB3"],pm25:["\xB5g/m\xB3"],pm10:["\xB5g/m\xB3"],potential_hydrogen:null,power:["W","kW"],power_factor:["%"],precipitation:["mm","in","cm"],precipitation_intensity:["mm/h","mm/d","in/h","in/d"],pressure:["cbar","bar","hPa","inHg","kPa","mbar","Pa","psi"],reactive_power:["var"],signal_strength:["dB","dBm"],sound_pressure:["dB","dBA"],speed:["ft/s","in/s","in/d","in/h","km/h","kn","m/min","m/s","mm/s","mm/h","mm/d","mph"],sulphur_dioxide:["\xB5g/m\xB3"],temperature:["\xB0C","\xB0F"],timestamp:null,volatile_organic_compounds:["\xB5g/m\xB3"],volatile_organic_compounds_parts:["ppm","ppb"],voltage:["V"],volume:["fl. oz.","ft\xB3","gal","L","mL","m\xB3"],volume_flow_rate:["m\xB3/h","ft\xB3/min","L/min","gal/min","mL/s"],volume_storage:["L","mL","gal","fl. oz.","m\xB3","ft\xB3","CCF"],water:["L","gal","m\xB3","ft\xB3"],weight:["g","kg","lb","mg","oz","\xB5g"],wind_speed:["ft/s","km/h","kn","m/s","mph"]},ko=[{id:"entity_category",type:"select",values:["","diagnostic"]},{id:"device_class",type:"select",values:["",...ua]},{id:"unit_of_measurement",type:"unit_of_measurement",values:la},{id:"state_class",type:"select",values:["","measurement","total","total_increasing"]},{id:"last_reset",type:"datetime"}];var Bo=[{id:"entity_category",type:"select",values:["","config","diagnostic"]},{id:"device_class",type:"select",values:["","outlet","switch"]}];var Mo=[{id:"entity_category",type:"select",values:["","config","diagnostic"]},{id:"mode",type:"select",values:["text","password"]},{id:"min_length",type:"number"},{id:"max_length",type:"number"},{id:"pattern",type:"string"}];var Vo=[{id:"name",type:"string"},{id:"icon",type:"string"},{id:"entity_picture",type:"string"}],Fo={button:Ao,binary_sensor:Co,number:Ho,select:Lo,sensor:ko,switch:Bo,text:Mo};var da={binary_sensor:["resend"],sensor:["resend"]},ca={category:"config",defaults:{server:{value:"",type:"server",required:!0},deviceConfig:{value:"",type:"ha-device-config",required:!1},name:{value:""},version:{value:RED.settings.get("haEntityConfigVersion",0)},entityType:{value:"binary_sensor",required:!0},haConfig:{value:[],validate:function(e){if($("#node-config-input-entityType").val()==="select"){let n=e.find(o=>o.property==="options");if(!n||!Array.isArray(n.value)||!n.value.length)return!1}return!0}},resend:{value:!1},debugEnabled:{value:!1}},label:function(){return this.name||`${this.entityType} ${this.id}`},oneditprepare:function(){l.setup(this),this.deviceConfig||$("#node-config-input-deviceConfig").val("_ADD_"),So();let e=$("#ha-config-rows"),t=this;$("#node-config-input-entityType").on("change",function(){let n=$(this).val();$(".ha-config-row").remove(),$("#node-config-dialog-edit-form .ha-optional-row").each(function(){let i=$(this),r=i.attr("id");r&&i.hasClass("ha-optional-row")&&i.toggle(da[n]?.includes(r.replace(/-row$/,"")))});let o=[...Vo,...Fo[n]??[]];o.forEach(i=>{let r=t.haConfig.find(a=>a.property===i.id)?.value??"";e.append(rt(r,i))}),(n==="number"||n==="sensor")&&$("#ha-config-device_class").on("change",function(){let i=t.haConfig.find(a=>a.property==="unit_of_measurement")?.value??"",r=o.find(a=>a.id==="unit_of_measurement")?.values??[];$("#ha-config-unit_of_measurement").parent().replaceWith(rt(i,{id:"unit_of_measurement",type:"unit_of_measurement",values:r}))})})},oneditsave:function(){let e=[];$(".ha-config-row").each(function(){let t=$(this);switch(t.data("type")){case"datetime":case"date":{let o=t.find("input").data("property"),i=t.find("input").val();if(i==="")return;let r=new Date(i);e.push({property:o,value:r.toISOString()});break}case"editableList":{let i=t.find("ol").editableList("items"),r=[];i.each(function(){let a=$(this).find("input");r.push(a.val())}),e.push({property:"options",value:r});break}case"number":{let o=t.find("input").data("property"),i=t.find("input").val(),r=i.length?Number(i):"";e.push({property:o,value:r});break}case"string":{let o=t.find("input").data("property"),i=t.find("input").val();e.push({property:o,value:i});break}case"select":{let o=t.find("select"),i=o.data("property"),r=o.val();e.push({property:i,value:r});break}case"unit_of_measurement":{let o=t.find("select, input"),i=o.data("property"),r=o.val();e.push({property:i,value:r});break}}}),this.haConfig=e}},Jo=ca;var ya={category:"home_assistant",color:"#41BDF5",defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("serverEventsVersion",0)},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},eventType:{value:"",required:!1},eventData:{value:"",validate:RED.validators.typedInput({allowBlank:!0})},waitForRunning:{value:!0},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"eventData"},{property:"topic",propertyType:"msg",value:'$outputData("eventData").event_type',valueType:"jsonata"}],validate:E},event_type:{value:void 0},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0}},inputs:0,outputs:1,icon:"ha-events-all.svg",paletteLabel:"events: all",label:function(){return this.name||`events: ${this.eventType||"all"}`},labelStyle:l.labelStyle,oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),_(this),T("switch","exposeAsEntityConfig"),$("#node-input-eventData").typedInput({types:["json"]}),$("#node-input-eventType").on("change input",function(){let e=$(this).val().trim();$("#eventAlert").toggle(e.length===0),this.value=e}),h(this.outputProperties,{extraTypes:["eventData"]}),c("events-all")},oneditsave:function(){this.outputProperties=b()}},Go=ya;var fa={category:"home_assistant",color:"#77DD77",inputs:0,outputs:1,outputLabels:["Calendar event triggered"],icon:"ha-events-calendar.svg",paletteLabel:"events: calendar",label:function(){return this.name||"calendar event"},labelStyle:l.labelStyle,defaults:{name:{value:""},version:{value:RED.settings.get("eventsCalendarVersion",0)},server:{value:"",type:"server",required:!0},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},entityId:{value:"",required:!0},filter:{value:""},filterType:{value:"str",required:!0},eventType:{value:"start",required:!0},offset:{value:0,required:!0},offsetType:{value:"num",required:!0},offsetUnits:{value:"minutes",required:!0},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"calendarItem"}],validate:E}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),_(this),T("switch","exposeAsEntityConfig"),$("#dialog-form").prepend(l.betaWarning(1295)),W({root:"#node-input-entityId",options:{type:"calendars"}}),$("#node-input-offset").typedInput({default:"num",types:["num","jsonata"],typeField:"#node-input-offsetType"}),$("#node-input-filter").typedInput({types:["str","jsonata"],typeField:"#node-input-filterType"}),h(this.outputProperties,{extraTypes:["calendarItem"]}),c("events-calendar")},oneditsave:function(){this.outputProperties=b()}},Wo=fa;var ga={category:"home_assistant",color:"#41BDF5",inputs:0,outputs:1,outputLabels:["'If State' is true","'If State' is false"],icon:"ha-events-state-changed.svg",paletteLabel:"events: state",label:function(){let e=[];return this.entities&&Object.entries(this.entities).forEach(([,t])=>{Array.isArray(t)&&t?.length&&(e=[...e,...t])}),this.name||`state_changed: ${e}`},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("serverStateChangedVersion",0)},outputs:{value:1},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},entities:{value:{entity:[""],substring:[],regex:[]}},outputInitially:{value:!1},stateType:{value:"str"},ifState:{value:""},ifStateType:{value:"str"},ifStateOperator:{value:"is"},outputOnlyOnStateChange:{value:!0},for:{value:"0"},forType:{value:"num"},forUnits:{value:"minutes"},ignorePrevStateNull:{value:!1},ignorePrevStateUnknown:{value:!1},ignorePrevStateUnavailable:{value:!1},ignoreCurrentStateUnknown:{value:!1},ignoreCurrentStateUnavailable:{value:!1},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"string",valueType:"entityState"},{property:"data",propertyType:"msg",value:"",valueType:"eventData"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],validate:E},entityId:{value:void 0},entityIdType:{value:void 0},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0},entityidfilter:{value:void 0},entityidfiltertype:{value:void 0},outputinitially:{value:void 0},state_type:{value:void 0},haltifstate:{value:void 0},halt_if_type:{value:void 0},halt_if_compare:{value:void 0},output_only_on_state_change:{value:void 0}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server",()=>{e.refreshOptions()}),_(this),T("switch","exposeAsEntityConfig");let e=new z({element:"#entity-list",types:["entity","substring","regex"],headerText:u("server-state-changed.label.entities")});Object.entries(this.entities).forEach(([t,n])=>{n?.forEach(o=>{e.addId(t,o)})}),de("#node-input-ifState","#node-input-ifStateType","#node-input-ifStateOperator"),$("#node-input-for").typedInput({default:"num",types:["num","jsonata","flow","global"],typeField:"#node-input-forType"}),h(this.outputProperties,{extraTypes:["eventData","entityId","entityState"]}),c("events-state"),ee(this,["state_type"])},oneditsave:function(){let e=$("#node-input-ifState").val()||$("#node-input-ifStateType").val()==="habool"?2:1;$("#node-input-outputs").val(e);let t=X("#entity-list");this.entities={entity:t.entity,substring:t.substring,regex:t.regex},this.outputProperties=b()}},Uo=ga;var va={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,icon:"ha-fire-event.svg",align:"right",paletteLabel:"fire event",label:function(){return this.name||`Event: ${this.event}`},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haFireEventVersion",0)},event:{value:""},data:{value:"",validate:RED.validators.typedInput({type:"dateType",allowBlank:!0})},dataType:{value:"jsonata"}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),$("#node-input-data").typedInput({types:["json","jsonata"],typeField:"#node-input-dataType"}),c("fire-event")}},jo=va;var yt=[{value:"is",text:"=="},{value:"is_not",text:"!="},{value:"lt",text:"<"},{value:"lte",text:"<="},{value:"gt",text:">"},{value:"gte",text:">="},{value:"includes",text:"in"},{value:"does_not_include",text:"not in"},{value:"starts_with",text:"starts with"},{value:"in_group",text:"in group"},{value:"jsonata",text:"JSONata"}],ha=[{value:"is",text:"=="},{value:"is_not",text:"!="},{value:"cont",text:"contains"},{value:"does_not_cont",text:"does not contain"},{value:"includes",text:"in"},{value:"does_not_include",text:"not in"},{value:"starts_with",text:"starts with"},{value:"is_null",text:"is null"},{value:"is_not_null",text:"is not null"}],Le={value:"entity",label:"entity."},qo=["str","num","bool","re","jsonata","msg","flow","global",Le],ba=["str","jsonata","msg","flow","global",Le],Ea={state_object:[],floor_registry:["aliases","floor_id","level","name"],area_registry:["aliases","area_id","name"],device_registry:["hw_version","id","manufacturer","model","model_id","name","name_by_user","serial_number","sw_version"],label_registry:["description","label_id","name"]};function Ta(e){e.condition||(e.condition="state_object");let t=$("<span />",{text:u(`home-assistant.component.property-selector.label.${e.condition}_property`),class:"property-label"}),n=$("<select>",{class:"input-property"});Ea[e.condition].forEach(r=>{n.append($("<option></option>").val(r).text(r))}),n.val(e.property);let o=$("<select>",{class:"input-logic"});ha.forEach(r=>{$("<option>",{value:r.value,text:r.text}).appendTo(o)}),e.logic&&o.val(e.logic);let i=$("<input>",{type:"text",class:"input-value",css:{width:"100%"}}).wrap('<div class="input-value-wrapper"></div>').val(e.value);return i.typedInput({types:ba}),i.typedInput("type",e.valueType),[t,n,o,i.parent()]}function mt(e){Oe("properties",t=>{let n=t.map(o=>({value:o,label:o}));e(n)})}function Sa(e){e.hasOwnProperty("logic")||(e.logic="is");let t=$("<span />",{text:"Entity Property",class:"property-label"}),n=$("<div />",{class:"input-property virtual-select"});VirtualSelect.init({ele:n[0],hideClearButton:!0,search:!0,maxWidth:"100%",placeholder:"",allowNewOption:!0,optionsCount:6,selectedValue:e.property}),mt(r=>{n[0].setOptions(r,!0)});let o=$("<select/>",{class:"input-logic"}).on("change",function(){let a=$(this).val(),s=qo;switch(a==="jsonata"?(n[0].disable(),n[0].reset()):n[0].enable(),a){case"is":case"is_not":break;case"lt":case"lte":case"gt":case"gte":s=["num","jsonata","msg","flow","global",Le];break;case"includes":case"does_not_include":case"starts_with":case"in_group":s=["str","jsonata","msg","flow","global",Le];break;case"jsonata":s=["jsonata"];break}i.typedInput("types",s)});for(let r in yt)o.append($("<option></option>").val(yt[r].value).text(yt[r].text));let i=$("<input />",{class:"input-value",type:"text",css:{width:"100%"}}).wrap('<div class="input-value-wrapper"></div>').val(e.value);return i.typedInput({types:qo}),i.typedInput("type",e.valueType),e.logic&&o.val(e.logic).trigger("change"),[t,n,o,i.parent()]}function zo(e){switch(e.condition){case"area_registry":case"device_registry":case"floor_registry":case"label_registry":return Ta(e);case"state_object":default:return Sa(e)}}var xe=class{#e;#n;constructor({types:t,element:n}){this.#n=t,this.#e=$(n),this.init()}#o(t){return{label:u(`home-assistant.component.property-selector.label.add-button.${t}`),icon:"fa fa-plus",class:"red-ui-editableList-add",click:()=>{this.#e.editableList("addItem",{condition:t})}}}#t(){return this.#n.map(n=>this.#o(n))}init(){this.#e.addClass("property-selector"),this.#e.editableList({addButton:!1,removable:!0,height:"auto",addItem:(t,n,o)=>{zo(o).forEach(r=>t.append(r)),t.addClass("property-selector")},buttons:this.#t()})}addId(t){t.condition||(t.condition="state_object"),this.#e.editableList("addItem",t)}clear(){this.#e.find(".id-delete-button").trigger("click")}refreshOptions(){this.#e.editableList("items").each(function(){let t=$(this),{condition:n}=t.data("data");if(!Qo(n))return;let o=t.find(".virtual-select");o.length&&mt(i=>{o[0].setOptions(i,!0)})})}};function Qo(e){return Object.values(be).includes(e)}function xa(e,t){let n=$(e),o=n.find("select.input-property").val(),i=n.find("select.input-logic").val(),r=n.find("input.input-value"),a=r.typedInput("value"),s=r.typedInput("type");return{condition:t,property:o,logic:i,value:a,valueType:s}}function $a(e){let t=$(e),n=t.find(".input-property")[0].value,o=t.find("select.input-logic").val(),i=t.find(".input-value").typedInput("value"),r=t.find(".input-value").typedInput("type");return{condition:"state_object",property:n,logic:o,value:i,valueType:r}}function _a(e){return Qo(e.condition)&&e.property!==void 0&&e.logic!==void 0&&e.value!==void 0&&e.valueType!==void 0}function Ko(e){let t=$(e).editableList("items"),n=[];return t.each(function(){let{condition:o}=$(this).data("data"),i;switch(o){case"device_registry":case"area_registry":case"floor_registry":case"label_registry":i=xa(this,o);break;case"state_object":default:i=$a(this);break}_a(i)&&n.push(i)}),n}var Da={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,icon:"ha-get-entities.svg",paletteLabel:"get entities",label:function(){return this.name||"get entities"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haGetEntitiesVersion",0)},rules:{value:[{condition:"state_object",property:"",logic:"is",value:"",valueType:"str"}]},outputType:{value:"array"},outputEmptyResults:{value:!1},outputLocationType:{value:"msg"},outputLocation:{value:"payload"},outputResultsCount:{value:1,validate:function(e){return $("#node-input-outputType").val()==="random"?Number.isInteger(Number(e)):!0}},output_type:{value:void 0},output_empty_results:{value:void 0},output_location_type:{value:void 0},output_location:{value:void 0},output_results_count:{value:void 0}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server",()=>{e.refreshOptions()});let e=new xe({element:"#conditions-list",types:["state_object","device_registry","area_registry","floor_registry","label_registry"]});this.rules.forEach(t=>{e.addId(t)}),$("#node-input-outputLocation").typedInput({types:["msg","flow","global"],typeField:"#node-input-outputLocationType"}),$("#node-input-outputResultsCount").spinner({min:1}),$("#node-input-outputType").on("change",function(){switch($(".output-option").hide(),$(this).val()){case"array":$("#output_empty_results").show(),$("#output_location").show();break;case"count":$("#output_location").show();break;case"random":$("#output_results_count").show(),$("#output_location").show();break;case"split":default:break}}).trigger("change"),c("get-entities")},oneditsave:function(){this.rules=Ko("#conditions-list")}},Zo=Da;var Na={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,icon:"ha-get-history.svg",paletteLabel:"get history",label:function(){if(this.name)return this.name;if(this.useRelativeTime&&this.relativeTime)return this.relativeTime;if(this.startDate){let e=new Date(this.startDate);return`${e.toLocaleDateString()} ${e.toLocaleTimeString()}`}return"get history"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("apiGetHistoryVersion",0)},startDate:{value:""},endDate:{value:""},entityId:{value:""},entityIdType:{value:"equals"},useRelativeTime:{value:!0},relativeTime:{value:""},flatten:{value:!0},outputType:{value:"array"},outputLocationType:{value:"msg"},outputLocation:{value:"payload"},startdate:{value:void 0},enddate:{value:void 0},entityid:{value:void 0},entityidtype:{value:void 0},output_type:{value:void 0},output_location_type:{value:void 0},output_location:{value:void 0}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),W({root:"#node-input-entityId"}),$("#node-input-useRelativeTime").on("change",function(){this.checked?($(".relative_row").show(),$(".date_row").hide()):($(".relative_row").hide(),$(".date_row").show())}),$("#node-input-outputLocation").typedInput({types:["msg","flow","global"],typeField:"#node-input-outputLocationType"}),$("#node-input-outputType").on("change",e=>{let t=e.target;$(".output-option").toggle(t.value==="array")}).trigger("change"),c("get-history")}},Yo=Na;var wa={category:"home_assistant_entities",color:"#41BDF5",inputs:0,outputs:1,icon:"font-awesome/fa-hashtag",align:"left",paletteLabel:"number",label:function(){return this.name||"number"},labelStyle:l.labelStyle,defaults:{name:{value:""},version:{value:RED.settings.get("haNumberVersion",0)},debugenabled:{value:!1},inputs:{value:0},outputs:{value:1},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="number",required:!0},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},mode:{value:"listen"},value:{value:"payload"},valueType:{value:"msg"},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"value"},{property:"previousValue",propertyType:"msg",value:"",valueType:"previousValue"}],validate:E}},oneditprepare:function(){l.setup(this),_(this),T("number"),T("switch","exposeAsEntityConfig"),$("#node-input-mode").on("change",function(){$("#node-input-value").parent().toggle(this.value==="set"),$("#node-input-inputs").val(this.value==="listen"?0:1)}),$("#node-input-value").typedInput({types:["msg","flow","global","jsonata","num"],typeField:"#node-input-valueType",type:this.valueType}),h(this.outputProperties,{extraTypes:["value","previousValue"]}),c("number")},oneditsave:function(){this.outputProperties=b()}},Xo=wa;var Ia={category:"home_assistant",color:"#41BDF5",inputs:0,outputs:1,outputLabels:[u("poll-state.output_label.if_state_true"),u("poll-state.output_label.if_state_false")],icon:"ha-poll-state.svg",paletteLabel:"poll state",label:function(){return this.name||`poll state: ${this.entityId}`},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("pollStateVersion",0)},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},updateInterval:{value:"60"},updateIntervalType:{value:"num"},updateIntervalUnits:{value:"seconds"},outputInitially:{value:!1},outputOnChanged:{value:!1},entityId:{value:"",required:!0},stateType:{value:"str"},ifState:{value:""},ifStateType:{value:"str"},ifStateOperator:{value:"is"},outputs:{value:1},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"entityState"},{property:"data",propertyType:"msg",value:"",valueType:"entity"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],validate:E},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0},updateinterval:{value:void 0},outputinitially:{value:void 0},outputonchanged:{value:void 0},entity_id:{value:void 0},state_type:{value:void 0},halt_if:{value:void 0},halt_if_type:{value:void 0},halt_if_compare:{value:void 0}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),_(this),W({root:"#node-input-entityId"}),T("switch","exposeAsEntityConfig"),$("#node-input-updateInterval").typedInput({types:["num","jsonata"],typeField:"#node-input-updateIntervalType"}),de("#node-input-ifState","#node-input-ifStateType","#node-input-ifStateOperator"),h(this.outputProperties,{extraTypes:["entity","entityId","entityState"]}),c("poll-state"),ee(this,["state_type"])},oneditsave:function(){let e=$("#node-input-ifState").val()||$("#node-input-ifStateType").val()==="habool"?2:1;$("#node-input-outputs").val(e),this.outputProperties=b()}},ei=Ia;var ae,Pa={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,icon:"ha-render-template.svg",paletteLabel:"render template",label:function(){return this.name||"template"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("apiRenderTemplateVersion",0)},template:{value:""},resultsLocation:{value:"payload"},resultsLocationType:{value:"msg"},templateLocation:{value:""},templateLocationType:{value:"none"}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server");let e=$("#node-input-template");$("#node-input-templateLocation").typedInput({types:["msg","flow","global",{value:"none",label:"none",hasValue:!1}],typeField:"#node-input-templateLocationType"}),$("#node-input-resultsLocation").typedInput({types:["msg","flow","global"],typeField:"#node-input-resultsLocationType"}),ae=RED.editor.createEditor({id:"node-input-template-editor",mode:"ace/mode/text",value:e.val()}),c("render-template")},oneditresize:function(){let e=$("#dialog-form>div:not(.node-text-editor-row)"),t=$("#dialog-form>div.node-text-editor-row"),n=$(".node-text-editor"),i=$("#dialog-form").height()??0;for(let r=0;r<e.length;r++){let a=$(e[r]).outerHeight(!0);typeof a=="number"&&(i-=a)}i-=parseInt(t.css("marginTop"))+parseInt(t.css("marginBottom")),n.css("height",`${i}px`),ae?.resize()},oneditcancel:function(){ae?.destroy(),ae=void 0},oneditsave:function(){let e=ae?.getValue()??"";$("#node-input-template").val(e),ae?.destroy(),ae=void 0}},ti=Pa;var Oa={category:"home_assistant_entities",color:"#41BDF5",inputs:0,outputs:1,icon:"font-awesome/fa-list",align:"left",paletteLabel:"select",label:function(){return this.name||"select"},labelStyle:l.labelStyle,defaults:{name:{value:""},version:{value:RED.settings.get("haTextVersion",0)},debugenabled:{value:!1},inputs:{value:0},outputs:{value:1},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="select",required:!0},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},mode:{value:"listen"},value:{value:"payload"},valueType:{value:"msg"},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"value"},{property:"previousValue",propertyType:"msg",value:"",valueType:"previousValue"}],validate:E}},oneditprepare:function(){l.setup(this),_(this),T("select"),T("switch","exposeAsEntityConfig");let e=$("#node-input-value").parent();$("#node-input-mode").on("change",function(){e.toggle(this.value==="set"),$("#node-input-inputs").val(this.value==="listen"?0:1)}),$("#node-input-value").typedInput({types:["msg","flow","global","jsonata","str"],typeField:"#node-input-valueType",type:this.valueType}),h(this.outputProperties,{extraTypes:["value","previousValue"]}),c("select")},oneditsave:function(){this.outputProperties=b()}},ni=Oa;var Ra=["msg","flow","global","jsonata","str","num","bool"],Ca=["str","num","bool","date","jsonata","msg","flow","global"],Aa={category:"home_assistant_entities",color:"#41BDF5",inputs:1,outputs:1,icon:"font-awesome/fa-genderless",align:"right",paletteLabel:"sensor",label:function(){return this.name||"sensor"},labelStyle:l.labelStyle,defaults:{name:{value:""},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="sensor",required:!0},version:{value:RED.settings.get("haSensorVersion",0)},state:{value:"payload"},stateType:{value:"msg"},attributes:{value:[]},inputOverride:{value:"allow"},outputProperties:{value:[],validate:E}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),_(this),$("#node-input-state").typedInput({types:Ra,typeField:"#node-input-stateType",type:this.stateType}),T("sensor"),$("#attributes").editableList({removable:!0,addButton:"add attribute",header:$("<div>").append($.parseHTML("<div style='width:40%; display: inline-grid'>Attribute Key</div><div style='display: inline-grid'>Value</div>")),addItem:function(t,n,o){let i=$("<div />").appendTo(t);$("<input />",{type:"text",name:"property",style:"width: 40%;margin-right: 5px;"}).attr("autocomplete","disable").appendTo(i).val(o.property);let r=$("<input />",{type:"text",name:"value",style:"width: 55%;"}).appendTo(i).val(o.value);r.typedInput({types:Ca}),r.typedInput("type",o.valueType)}}).editableList("addItems",this.attributes),h(this.outputProperties,{extraTypes:["sentData"]}),c("sensor")},oneditsave:function(){this.attributes=[];let e=this;$("#attributes").editableList("items").each(function(){let t=$(this);e.attributes.push({property:t.find("input[name=property]").val(),value:t.find("input[name=value]").typedInput("value"),valueType:t.find("input[name=value]").typedInput("type")})}),this.outputProperties=b()}},oi=Aa;var Ha={category:"home_assistant",color:"#77DD77",outputs:1,outputLabels:"",icon:"font-awesome/fa-comment-o",paletteLabel:"sentence",label:function(){return this.name||"sentence"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haSentenceVersion",0)},inputs:{value:0},outputs:{value:1},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},mode:{value:"trigger"},sentences:{value:[],validate:function(e){return e.length>0||this.mode!=="trigger"}},response:{value:""},responseType:{value:"str"},triggerResponse:{value:""},triggerResponseType:{value:"fixed"},responseTimeout:{value:1e3},outputProperties:{value:[{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"},{property:"payload",propertyType:"msg",value:"",valueType:"triggerId"}],validate:E}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),_(this),T("switch","exposeAsEntityConfig"),$("#dialog-form").prepend(l.betaWarning(981));let e=this;$("#node-input-mode").on("change",function(){$("#node-input-inputs").val(this.value==="trigger"?0:1);let t=$("#node-input-mode").val();$(".sentence-trigger").toggle(t==="trigger"),$(".sentence-response").toggle(t==="response"),$("#node-input-response").typedInput({types:["str","jsonata","msg","flow","global"],typeField:"#node-input-responseType",type:e.responseType})}),$("#node-input-triggerResponseType").on("change",function(){let t=this.value;$("#node-input-responseTimeout").parent().toggle(t==="dynamic"),$("#node-input-triggerResponse").siblings("label").text(u(t==="fixed"?"ha-sentence.label.response":"ha-sentence.label.fallback_response"))}).trigger("change"),$("#node-input-sentences-container").editableList({addButton:!0,removable:!0,height:"auto",header:$("<div>").append(this._("ha-sentence.label.sentences")),addItem:function(t,n,o){$("<input />",{type:"text",value:typeof o=="string"?o:"",style:"width: 100%"}).appendTo(t)}}).editableList("addItems",this.sentences.length?this.sentences:[""]),h(this.outputProperties,{extraTypes:["triggerId","results","deviceId"]}),c("sentence")},oneditsave:function(){let e=[];$("#node-input-sentences-container").editableList("items").each(function(){let n=$(this).find("input").val();n&&e.push(n)}),this.sentences=e,this.outputProperties=b()}},ii=Ha;var La={category:"home_assistant_entities",color:"#41BDF5",inputs:0,outputs:1,icon:"font-awesome/fa-toggle-on",align:"left",paletteLabel:"switch",label:function(){return this.name||"switch"},labelStyle:l.labelStyle,defaults:{name:{value:""},version:{value:RED.settings.get("haSwitchVersion",0)},debugenabled:{value:!1},inputs:{value:0},outputs:{value:2},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!0},enableInput:{value:!1},outputOnStateChange:{value:!1},outputProperties:{value:[{property:"outputType",propertyType:"msg",value:"state change",valueType:"str"},{property:"payload",propertyType:"msg",value:"",valueType:"entityState"}],validate:E}},oneditprepare:function(){l.setup(this),_(this),T("switch"),h(this.outputProperties,{extraTypes:["entityState"]}),$("#node-input-outputOnStateChange").on("change",function(){$("#ha-custom-ouputs").toggle($(this).is(":checked"))}),c("switch")},oneditsave:function(){this.outputProperties=b(),$("#node-input-inputs").val($("#node-input-enableInput").is(":checked")?1:0)}},ri=La;var ka={category:"home_assistant",color:"#41BDF5",outputs:1,icon:"font-awesome/fa-tag",paletteLabel:"tag",label:function(){return this.name||"tag"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haTagVersion",0)},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},tags:{value:[""],required:!0,validate:function(e){return!!e.length}},devices:{value:[]},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"eventData"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],validate:E},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0}},oneditprepare:function(){l.setup(this),_(this);let e=$("#tags"),t=$("#devices"),n=[],o=this._;T("switch","exposeAsEntityConfig");let i=(d,g)=>{let y=$("<select>",{width:"70%"}).append($("<option>").attr({value:$e,selected:g===$e}).text(o("ha-tag.label.all_tags"))).appendTo(d);n.forEach(p=>{$("<option>").attr({value:p.id,selected:p.id===g}).text(p.name||p.id).appendTo(y)})};e.editableList({addButton:!0,removable:!0,height:"auto",header:$("<div>").append(o("ha-tag.label.tags")),addItem:function(d,g,y){let p=$("<div />").appendTo(d);$("<span />",{text:o("ha-tag.label.tag"),style:"padding-right: 74px;"}).appendTo(p),i(p,y)},buttons:[{id:"ha-tag-update-tag-list",label:o("ha-tag.label.update_tag_list"),icon:"fa fa-refresh",click:()=>{Ze(s,"tags",{params:{update:!0}})}}]}),$("#ha-tag-update-tag-list").css("float","right").css("margin-right","unset");let r=()=>{$("#no-tags-found").toggle(n.length===0)};function a(d,g){let y=d.name||d.tag_id,p=g.name||g.tag_id;return y===p?0:y.localeCompare(p)}let s=d=>{n=d.sort(a);let g=new Set;e.editableList("items").each(function(){let p=$(this).find("select").val();g.add(p)});let y=Array.from(g).filter(p=>p===$e?!0:n.find(m=>m.id===p));e.editableList("empty"),e.editableList("addItems",y),r()};v(this,"#node-input-server"),oe("tags",d=>{n=d,e.editableList("addItems",this.tags),s(d)}),$("#update-tag-list").on("click",()=>{Ze(s,"tags",{params:{update:!0}})}),t.editableList({addButton:!0,removable:!0,height:"auto",header:$("<div>").append(o("ha-tag.label.devices")),addItem:function(d,g,y){let p=$("<div />").appendTo(d);$("<span />",{text:o("ha-tag.label.device_id"),style:"padding-right: 35px;"}).appendTo(p);let m=$.isEmptyObject(y)?"":y;$("<input />",{type:"text",class:"input-device"}).appendTo(p).val(m)}}),t.editableList("addItems",this.devices),h(this.outputProperties,{extraTypes:["eventData","tagId"]}),c("tag")},oneditsave:function(){let e=$("#tags").editableList("items"),t=$("#devices").editableList("items"),n=new Set,o=new Set;e.each(function(){let i=$(this).find("select").val();n.add(i)}),t.each(function(){let i=$(this).find(".input-device").val();i.trim().replace(/\s/g,"").length&&o.add(i)}),this.tags=Array.from(n),this.devices=Array.from(o),this.outputProperties=b()}},ai=ka;var Ba={category:"home_assistant_entities",color:"#41BDF5",inputs:0,outputs:1,icon:"font-awesome/fa-font",align:"left",paletteLabel:"text",label:function(){return this.name||"text"},labelStyle:l.labelStyle,defaults:{name:{value:""},version:{value:RED.settings.get("haTextVersion",0)},debugenabled:{value:!1},inputs:{value:0},outputs:{value:1},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="text",required:!0},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},mode:{value:"listen"},value:{value:"payload"},valueType:{value:"msg"},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"value"},{property:"previousValue",propertyType:"msg",value:"",valueType:"previousValue"}],validate:E}},oneditprepare:function(){l.setup(this),_(this),T("text"),T("switch","exposeAsEntityConfig");let e=$("#node-input-value").parent();$("#node-input-mode").on("change",function(){e.toggle(this.value==="set"),$("#node-input-inputs").val(this.value==="listen"?0:1)}),$("#node-input-value").typedInput({types:["msg","flow","global","jsonata","str"],typeField:"#node-input-valueType",type:this.valueType}),h(this.outputProperties,{extraTypes:["value","previousValue"]}),c("text")},oneditsave:function(){this.outputProperties=b()}},si=Ba;var Ma={category:"home_assistant",color:"#41BDF5",outputs:1,icon:"font-awesome/fa-clock-o",paletteLabel:"time",label:function(){return this.name||(this.entityId?`${this.entityId}.${this.property||"state"}`:"time")},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haTimeVersion",0)},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},entityId:{value:"",required:!0},property:{value:""},offset:{value:"0"},offsetType:{value:"num"},offsetUnits:{value:"minutes"},randomOffset:{value:!1},repeatDaily:{value:!1},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"entityState"},{property:"data",propertyType:"msg",value:"",valueType:"entity"},{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"}],validate:E},sunday:{value:!0},monday:{value:!0},tuesday:{value:!0},wednesday:{value:!0},thursday:{value:!0},friday:{value:!0},saturday:{value:!0},ignorePastDate:{value:!0},debugenabled:{value:void 0},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0},payload:{value:void 0},payloadType:{value:void 0}},oneditprepare:function(){l.setup(this);let e=$("#node-input-server"),t=$("#node-input-entityId");v(this,"#node-input-server"),_(this),T("switch","exposeAsEntityConfig"),W({root:"#node-input-entityId"}),$("#node-input-property").autocomplete({source:(n,o)=>{let i=Vt(e.val(),t.val());o($.ui.autocomplete.filter(i,n.term))},minLength:0}),$("#node-input-offset").typedInput({types:["num","jsonata"],typeField:"#node-input-offsetType"}),$("#node-input-payload").typedInput({types:["str","num","bool","jsonata","date"],typeField:"#node-input-payloadType"}),$("#node-input-repeatDaily").on("change",function(){$("#days-of-the-week").toggle($(this).is(":checked"))}).trigger("change"),h(this.outputProperties,{extraTypes:["entityState","entityId","entity"]}),c("time")},oneditsave:function(){this.outputProperties=b()}},pi=Ma;var Va={category:"home_assistant_entities",color:"#41BDF5",inputs:0,outputs:1,icon:"font-awesome/fa-clock-o",align:"left",paletteLabel:"time",label:function(){return this.name||"time entity"},labelStyle:l.labelStyle,defaults:{name:{value:""},version:{value:RED.settings.get("haTimeEntityVersion",0)},debugenabled:{value:!1},inputs:{value:0},outputs:{value:1},entityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="time",required:!0},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},mode:{value:"listen"},value:{value:"payload"},valueType:{value:"msg"},outputProperties:{value:[{property:"payload",propertyType:"msg",value:"",valueType:"value"},{property:"previousValue",propertyType:"msg",value:"",valueType:"previousValue"}],validate:E}},oneditprepare:function(){l.setup(this),_(this),T("time"),T("switch","exposeAsEntityConfig");let e=$("#node-input-value").parent();$("#node-input-mode").on("change",function(){e.toggle(this.value==="set"),$("#node-input-inputs").val(this.value==="listen"?0:1)}),$("#node-input-value").typedInput({types:["msg","flow","global","jsonata","str"],typeField:"#node-input-valueType",type:this.valueType}),h(this.outputProperties,{extraTypes:["value","previousValue"]}),c("time-entity")},oneditsave:function(){this.outputProperties=b()}},ui=Va;var li={value:"entity",label:"entity."},di={value:"prevEntity",label:"prev entity."},ci={value:"habool",label:"Home Assistant State Boolean",hasValue:!1},Fa={category:"home_assistant",color:"#41BDF5",inputs:0,outputs:2,outputLabels:function(e){if(e===0)return"allowed";if(e===1)return"blocked";let n=this.customOutputs[e-2],o;return n.comparatorPropertyType==="always"?o="always sent":o=`${n.comparatorPropertyType.replace("_"," ")} ${n.comparatorType.replace("_","")} ${n.comparatorValue}`,o},icon:"font-awesome/fa-map-signs",paletteLabel:"trigger: state",label:function(){let e=[];return this.entities&&Object.entries(this.entities).forEach(([,t])=>{Array.isArray(t)&&t?.length&&(e=[...e,...t])}),this.name||`trigger-state: ${e}`},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("triggerStateVersion",0)},inputs:{value:0},outputs:{value:2},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},entities:{value:{entity:[""],substring:[],regex:[]}},debugEnabled:{value:!1},constraints:{value:[{targetType:"this_entity",targetValue:"",propertyType:"current_state",propertyValue:"new_state.state",comparatorType:"is",comparatorValueDatatype:"str",comparatorValue:""}]},customOutputs:{value:[]},outputInitially:{value:!1},stateType:{value:"str"},enableInput:{value:!1},entityId:{value:void 0},entityIdType:{value:void 0},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0},entityid:{value:void 0},entityidfiltertype:{value:void 0},debugenabled:{value:void 0},customoutputs:{value:void 0},outputinitially:{value:void 0},state_type:{value:void 0}},oneditprepare:function(){l.setup(this);let e=$("#constraint-list"),t=$("#output-list");v(this,"#node-input-server",()=>{n.refreshOptions()}),T("switch","exposeAsEntityConfig");let n=new z({element:"#entity-list",types:["entity","substring","regex"],headerText:u("server-state-changed.label.entities")});Object.entries(this.entities).forEach(([p,m])=>{m?.forEach(f=>{n.addId(p,f)})});let o=[],i=[],r=[];oe("entities",p=>{o=p}),oe("properties",p=>{i=p,r=[...p.map(m=>`new_state.${m}`),...p.map(m=>`old_state.${m}`)].sort()}),_(this);let a=$("#node-input-outputs").val('{"0": 0, "1": 1}'),s=()=>JSON.parse(a.val()),d=p=>{a.val(JSON.stringify(p))},g=p=>{t.editableList("items").each(function(f){let S=$(this).data("data");p[Object.prototype.hasOwnProperty.call(S,"index")?S.index:S._index]=f+2})};e.on("change",".target-type",function(){let p=$(this),m=p.val()==="this_entity",f=p.parent().parent(),S=p.next(),R=f.find(".property-type");m?S.attr("disabled","disabled").val(""):S.removeAttr("disabled"),R.find("option[value=previous_state]").toggle(m),R.val()==="previous_state"&&R.val("current_state").trigger("change")}),e.on("change",".property-type",function(p){let m=p.target.value;["current_state","previous_state"].includes(m)?$(this).next().attr("disabled","disabled").val(""):$(this).next().removeAttr("disabled")}),t.on("change",".comparator-property-type",function(p){let m=p.target.value,f=$(this).parent().parent(),S=f.find(".comparator-type"),R=f.find(".comparator-value"),x=f.find(".comparator-property-value");switch(m){case"always":x.attr("disabled","disabled"),S.attr("disabled","disabled"),R.attr("disabled","disabled"),x.val("");break;case"previous_state":case"current_state":x.attr("disabled","disabled"),S.removeAttr("disabled"),R.removeAttr("disabled"),x.val("");break;case"property":x.removeAttr("disabled"),S.removeAttr("disabled"),R.removeAttr("disabled");break}});let y=(p,m,f)=>{if($("#constraint-template").children().clone().appendTo(p),p.find(".target-value").autocomplete({source:(R,x)=>{let N=R.term.toLowerCase(),I=o.filter(C=>C.includes(N));x(I)},minLength:0}),p.find(".property-value").autocomplete({source:(R,x)=>{let N=R.term.toLowerCase(),C=(p.find(".target-type").val()==="this_entity"?r:i).filter(k=>k.includes(N));x(C)},minLength:0}),p.find(".comparator-value").typedInput({default:"str",types:["str","num","bool","re","jsonata",li,di,ci]}),$.isEmptyObject(f))return;p.find(".target-type").val(f.targetType).trigger("change"),p.find(".target-value").val(f.targetValue),p.find(".property-type").val(f.propertyType).trigger("change"),f.propertyType==="property"&&p.find(".property-value").val(f.propertyValue),p.find(".comparator-type").val(f.comparatorType);let S=p.find(".comparator-value");S.typedInput("type",f.comparatorValueDatatype),S.typedInput("value",f.comparatorValue)};e.editableList({addButton:!0,removable:!0,height:"auto",header:$("<div>").append(u("trigger-state.label.conditions")),addItem:y}),e.editableList("addItems",this.constraints.length?this.constraints:[]),t.on("change",".message-type",function(p){let m=p.target.value;$(this).parent().find(".message-value").typedInput(m==="default"?"hide":"show")}),t.on("change",".comparator-property-type",function(p){let m=p.target.value,f=$(this).parent().parent(),S=f.find(".comparator-property-value"),R=f.find(".comparator-type"),x=f.find(".comparator-value");switch(m){case"always":S.attr("disabled","disabled"),R.attr("disabled","disabled"),x.typedInput("hide"),S.val("");break;case"previous_state":case"current_state":S.attr("disabled","disabled"),R.removeAttr("disabled"),x.typedInput("show"),S.val("");break;case"property":S.removeAttr("disabled"),R.removeAttr("disabled"),x.typedInput("show");break}}),t.editableList({addButton:!0,removable:!0,sortable:!0,height:"auto",header:$("<div>").append("Custom outputs"),addItem:function(p,m,f){f.hasOwnProperty("condition")||(f.condition={});let S=f.condition;f.hasOwnProperty("index")||(f._index=Math.floor(563609*Math.random()).toString()),$("#output-template").children().clone().appendTo(p),p.css({overflow:"hidden",whiteSpace:"nowrap"}),p.find(".message-value").typedInput({default:"json",types:["str","num","bool","json","jsonata"]}),p.find(".comparator-property-value").autocomplete({source:(I,C)=>{let k=I.term.toLowerCase(),B=r.filter(G=>G.includes(k));C(B)},minLength:0}),p.find(".comparator-value").typedInput({default:"str",types:["str","num","bool","re","jsonata",li,di,ci]});let R=s();if(R[f.hasOwnProperty("index")?f.index:f._index]=m+2,d(R),$.isEmptyObject(S)){p.find(".message-type,.comparator-property-type").trigger("change");return}p.find(".message-type").val(S.messageType).trigger("change");let x=p.find(".message-value");x.typedInput("value",S.messageValue),x.typedInput("type",S.messageValueType),p.find(".comparator-property-type").val(S.comparatorPropertyType).trigger("change"),S.comparatorPropertyType==="property"&&p.find(".comparator-property-value").val(S.comparatorPropertyValue),p.find(".comparator-type").val(S.comparatorType);let N=p.find(".comparator-value");N.typedInput("value",S.comparatorValue),N.typedInput("type",S.comparatorValueDataType)},removeItem:function(p){let m=s();Object.prototype.hasOwnProperty.call(p,"index")?m[p.index]=-1:delete m[p._index],g(m),d(m)},sortItems:function(){let p=s();g(p),d(p)}}),this.customOutputs.forEach((p,m)=>t.editableList("addItem",{condition:p,index:m+2})),c("trigger-state"),ee(this,["state_type"])},oneditsave:function(){let e=$("#constraint-list").editableList("items"),t=$("#output-list").editableList("items"),n=[],o=[];e.each(function(){let r=$(this),a=r.find(".comparator-value"),s={targetType:r.find(".target-type").val(),targetValue:r.find(".target-value").val(),propertyType:r.find(".property-type").val(),propertyValue:r.find(".property-value").val(),comparatorType:r.find(".comparator-type").val(),comparatorValueDatatype:a.typedInput("type"),comparatorValue:a.typedInput("value")};s.propertyType==="current_state"?s.propertyValue="new_state.state":s.propertyType==="previous_state"&&(s.propertyValue="old_state.state"),n.push(s)}),t.each(function(){let r=$(this),a=r.find(".message-value"),s=r.find(".comparator-value"),d={messageType:r.find(".message-type").val(),messageValue:a.typedInput("value"),messageValueType:a.typedInput("type"),comparatorPropertyType:r.find(".comparator-property-type").val(),comparatorPropertyValue:r.find(".comparator-property-value").val(),comparatorType:r.find(".comparator-type").val(),comparatorValue:s.typedInput("value"),comparatorValueDataType:s.typedInput("type")};d.comparatorPropertyType==="current_state"?d.comparatorPropertyValue="new_state.state":d.comparatorPropertyType==="previous_state"&&(d.comparatorPropertyValue="old_state.state"),o.push(d)}),$("#node-input-inputs").val($("#node-input-enableInput").is(":checked")?1:0),this.constraints=n,this.customOutputs=o;let i=X("#entity-list");this.entities={entity:i.entity,substring:i.substring,regex:i.regex}}},yi=Fa;var Ja={category:"home_assistant_entities",color:"#41BDF5",inputs:1,outputs:1,icon:"font-awesome/fa-asterisk",align:"right",paletteLabel:"update config",label:function(){return this.name||"update config"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},entityConfig:{value:"",type:"ha-entity-config",required:!1},version:{value:RED.settings.get("haSensorVersion",0)},outputProperties:{value:[],validate:E}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),this.entityConfig==="_ADD_"&&$("#node-input-entityConfig").val("_ADD_"),h(this.outputProperties),c("update-config")},oneditsave:function(){this.outputProperties=b()}},mi=Ja;var Ga={category:"home_assistant",color:"#41BDF5",inputs:1,outputs:1,outputLabels:["","timed out"],icon:"ha-wait-until.svg",paletteLabel:"wait until",label:function(){return this.name||"wait until"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haWaitUntilVersion",0)},outputs:{value:1},entities:{value:{entity:[""],substring:[],regex:[]}},property:{value:""},comparator:{value:"is"},value:{value:""},valueType:{value:"str"},timeout:{value:"0"},timeoutType:{value:"num"},timeoutUnits:{value:"seconds"},checkCurrentState:{value:!0},blockInputOverrides:{value:!0},outputProperties:{value:[]},entityId:{value:void 0},entityIdFilterType:{value:void 0},entityLocation:{value:void 0},entityLocationType:{value:void 0}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server",()=>{e.refreshOptions()});let e=new z({element:"#entity-list",types:["entity","substring","regex"],headerText:u("server-state-changed.label.entities")});Object.entries(this.entities).forEach(([r,a])=>{a?.forEach(s=>{e.addId(r,s)})});let t=[];oe("properties",r=>{t=r,$("#node-input-property").autocomplete({source:t,minLength:0})});let n={value:"entity",label:"entity."},o=["str","num","bool","re","jsonata","msg","flow","global",n];$("#node-input-value").typedInput({default:"str",types:o,typeField:"#node-input-valueType"}),$("#node-input-comparator").on("change",function(){let r=o,a=$(this).val();switch($("#node-input-property").prop("disabled",a==="jsonata"),a){case"is":case"is_not":break;case"lt":case"lte":case"gt":case"gte":r=["num","jsonata","msg","flow","global",n];break;case"includes":case"does_not_include":r=["str","jsonata","msg","flow","global"];break;case"jsonata":r=["jsonata"];break}$("#node-input-value").typedInput("types",r)}),$("#node-input-timeout").typedInput({default:"num",types:["num","jsonata"],typeField:"#node-input-timeoutType"});let i=$("#node-input-entityIdFilterType");i.on("change",function(){$(".exact-only").toggle(i.val()==="exact")}),h(this.outputProperties,{extraTypes:["entity"]}),c("wait-until")},oneditsave:function(){let e=X("#entity-list");this.entities={entity:e.entity,substring:e.substring,regex:e.regex};let t=$("#node-input-timeoutType").val(),n=$("#node-input-timeout").val();this.outputs=t==="jsonata"||t==="num"&&Number(n)>0?2:1,this.outputProperties=b()}},fi=Ga;function gi(e){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";return Array.from({length:e},()=>t[Math.floor(Math.random()*t.length)]).join("")}function ke(){return["method_post","method_get","method_put","method_head"].some(t=>this[t])}var Wa={category:"home_assistant",color:"#41BDF5",outputs:1,outputLabels:"",icon:"ha-webhook.svg",paletteLabel:"webhook",label:function(){return this.name||"webhook"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haWebhookVersion",0)},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},outputs:{value:1},webhookId:{value:gi(32),required:!0},method_get:{value:!1,validate:ke},method_head:{value:!1,validate:ke},method_post:{value:!0,validate:ke},method_put:{value:!0,validate:ke},outputProperties:{value:[{property:"topic",propertyType:"msg",value:"",valueType:"triggerId"},{property:"payload",propertyType:"msg",value:"",valueType:"data"}],validate:E},payloadLocation:{value:!1},payloadLocationType:{value:!1},headersLocation:{value:!1},headersLocationType:{value:!1}},oneditprepare:function(){l.setup(this),v(this,"#node-input-server"),_(this);let e=$("#node-input-webhookId");T("switch","exposeAsEntityConfig"),$("#copyId").on("click",function(){let t=e.get(0),n=t.value;t.value=`https://<ip>:<port>/api/webhook/${n}`,t.select(),t.setSelectionRange(0,99999),document.execCommand("copy"),t.value=n}),$("#refresh").on("click",function(){e.val(gi(32))}),$("[id^=node-input-method_]").on("change",function(){$("[id^=node-input-method_]").is(":checked")?$(this).closest("div").removeClass("input-error"):$(this).closest("div").addClass("input-error")}).trigger("change"),h(this.outputProperties,{extraTypes:["receivedData","headers","params","triggerId"]}),c("webhook")},oneditsave:function(){this.outputProperties=b()}},vi=Wa;var Ua={category:"home_assistant",color:"#41BDF5",outputs:1,icon:"font-awesome/fa-map-marker",paletteLabel:"zone",label:function(){return this.name||"zone"},labelStyle:l.labelStyle,defaults:{name:{value:""},server:{value:"",type:"server",required:!0},version:{value:RED.settings.get("haZoneVersion",0)},exposeAsEntityConfig:{value:"",type:"ha-entity-config",filter:e=>e.entityType==="switch",required:!1},entities:{value:[""],required:!0,validate:e=>!!e.length},event:{value:"enter"},zones:{value:[""],required:!0,validate:e=>!!e.length},exposeToHomeAssistant:{value:void 0},haConfig:{value:void 0}},oneditprepare:function(){l.setup(this);let e=$("#entities"),t=$("#zones");v(this,"#node-input-server"),_(this),T("switch","exposeAsEntityConfig"),e.editableList({addButton:!0,removable:!0,height:"auto",header:$("<div>").append("Entities"),addItem:function(n,o,i){let r=$("<div />").appendTo(n);$("<span />",{text:"Entity",style:"padding-right: 35px;"}).appendTo(r);let a=$.isEmptyObject(i)?"":i,s=$("<input />",{type:"text",class:"input-entity"}).appendTo(r).val(a);W({root:s,options:{type:"trackers"}})}}),e.editableList("addItems",this.entities),t.editableList({addButton:!0,removable:!0,height:"auto",header:$("<div>").append("zones"),addItem:function(n,o,i){let r=$("<div />").appendTo(n);$("<span />",{text:"Zone",style:"padding-right: 35px;"}).appendTo(r);let a=$.isEmptyObject(i)?"":i,s=$("<input />",{type:"text",class:"input-zone"}).appendTo(r).val(a);W({root:s,options:{type:"zones"}})}}),t.editableList("addItems",this.zones),c("zone")},oneditsave:function(){let e=$("#entities").editableList("items"),t=$("#zones").editableList("items"),n=new Set,o=new Set;e.each(function(){let i=$(this).find(".input-entity").val().replace(/\s/g,"");i.length&&n.add(i)}),t.each(function(){let i=$(this).find(".input-zone").val().replace(/\s/g,"");i.length&&o.add(i)}),this.entities=Array.from(n),this.zones=Array.from(o)}},hi=Ua;var ja={"homeassistant/areas/#":Dt,"homeassistant/devices/#":Nt,"homeassistant/entity/#":wt,"homeassistant/entities/#":Pt,"homeassistant/floors/#":Ot,"homeassistant/labels/#":Rt,"homeassistant/integration/#":qt,"homeassistant/services/#":Ct,"homeassistant/entityRegistry/#":It,"homeassistant/issues":Zt,[vt]:Yt};Object.entries(ja).forEach(([e,t],n)=>{setTimeout(()=>{RED.comms.subscribe(e,t)},n*150)});Un();jt();RED.events.on("nodes:add",jn);RED.events.on("nodes:remove",qn);RED.events.on("editor:open",Fn);RED.events.on("runtime-state",qe);RED.nodes.registerType("ha-device-config",Oo);RED.nodes.registerType("ha-entity-config",Jo);RED.nodes.registerType("server",io);RED.nodes.registerType("ha-api",bo);RED.nodes.registerType("api-call-service",ho);RED.nodes.registerType("api-current-state",Do);RED.nodes.registerType("ha-device",Po);RED.nodes.registerType("ha-entity",Ro);RED.nodes.registerType("server-events",Go);RED.nodes.registerType("ha-events-calendar",Wo);RED.nodes.registerType("server-state-changed",Uo);RED.nodes.registerType("ha-fire-event",jo);RED.nodes.registerType("ha-get-entities",Zo);RED.nodes.registerType("api-get-history",Yo);RED.nodes.registerType("poll-state",ei);RED.nodes.registerType("api-render-template",ti);RED.nodes.registerType("ha-sentence",ii);RED.nodes.registerType("ha-tag",ai);RED.nodes.registerType("ha-time",pi);RED.nodes.registerType("trigger-state",yi);RED.nodes.registerType("ha-wait-until",fi);RED.nodes.registerType("ha-webhook",vi);RED.nodes.registerType("ha-zone",hi);RED.nodes.registerType("ha-binary-sensor",xo);RED.nodes.registerType("ha-button",$o);RED.nodes.registerType("ha-number",Xo);RED.nodes.registerType("ha-select",ni);RED.nodes.registerType("ha-sensor",oi);RED.nodes.registerType("ha-switch",ri);RED.nodes.registerType("ha-text",si);RED.nodes.registerType("ha-time-entity",ui);RED.nodes.registerType("ha-update-config",mi);})();
</script>