node-red-contrib-deconz
Version:
deCONZ connectivity nodes for node-red
1 lines • 51.5 kB
JavaScript
class DeconzEditor{constructor(e,t={}){this.node=e,this.options=t}get elements(){return{}}get NRCD(){return"node-red-contrib-deconz"}findElements(){this.$elements={},Object.keys(this.elements).forEach(e=>{this.$elements[e]=this.findElement(this.elements[e])})}findElement(e){return"#"!==e.charAt(0)&&"."!==e.charAt(0)&&(e="#"+e),$(e)}async init(){this.findElements()}async connect(){}sendError(e,t=1e4){let i=RED.notify(e,{timeout:t,type:"error",buttons:[{text:"Ok",class:"primary",click:()=>i.close()}]})}getIcon(e,t=!1){return"deconz"===e?"icons/node-red-contrib-deconz/icon-color.png":"homekit"===e?"icons/node-red-contrib-deconz/homekit-logo.png":RED.nodes.fontAwesome.getIconList().includes("fa-"+e)?`${t?"fa ":""}fa-`+e:e}createIconElement(e,t,i=!1){if("fa-"===e.substr(0,3)){if(RED.nodes.fontAwesome.getIconUnicode(e))return void $("<i/>").appendTo(t).addClass("fa "+e+(i?" fa-lg":""));e=RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"}$("<div/>").appendTo(t).css("backgroundImage","url("+e+")")}getI18n(e,t,i={}){let s=e;t&&(s+="."+t),i.defaultValue="_deconz_undefined_";var n=RED._(s,i);if("_deconz_undefined_"!==n)return n}async generateSimpleListField(e,t){var i=$("<select/>",{id:t.id});if(t.choices)for(var[s,n]of t.choices)i.append($("<option/>").attr("value",s).html(RED._(n)));var a=await this.generateInputWithLabel(i,t);return e.append(a),void 0!==t.currentValue&&i.val(t.currentValue),i}async generateTypedInput(e,t){var i=$("<input/>",{id:e,placeholder:RED._(t)}),s=$("<input/>",{id:e+"_type",type:"hidden"});return i.append(s),i}async initTypedInput(e,t){t=$.extend({addDefaultTypes:!0,displayOnlyIcon:!1,value:{},width:"200px"},t);var i=$.extend({types:["msg","flow","global"]},t.typedInput);if(i.typeField=t.typeId,t.addDefaultTypes)for(var s of["msg","flow","global","jsonata"])i.types.includes(s)||i.types.push(s);if(t.displayOnlyIcon){let n=this;var a,o=function(e,t){let i;for(const s of this.typeList)"object"==typeof s&&s.value===this.propertyType&&(i=s);void 0!==i&&void 0!==i.icon&&(this.oldValue=this.input.val(),this.input.val(""),this.valueLabelContainer.hide(),n.createIconElement(i.icon,this.selectLabel),this.selectTrigger.addClass("red-ui-typedInput-full-width"),this.selectLabel.show())};for(a of i.types)"string"!=typeof a&&(a.hasValue=!0,a.valueLabel=o)}e.typedInput(i),void 0!==t.width&&e.typedInput("width",t.width),t.value&&(void 0!==t.value.type&&e.typedInput("type",t.value.type),void 0!==t.value.value)&&e.typedInput("value",t.value.value)}async generateTypedInputField(e,t){var i=await this.generateTypedInput(t.id,this.getI18n(t.i18n,"placeholder")),s=await this.generateInputWithLabel(i,t);return e.append(s),await this.initTypedInput(i,t),i}async generateDoubleTypedInputField(e,t,i){var s=await this.generateTypedInput(t.id,t.placeholder),n=await this.generateInputWithLabel(s,t),a=await this.generateTypedInput(i.id,i.placeholder);n.append(a),e.append(n),t.displayOnlyIcon=!0,t.width="50px",i.width="150px",await this.initTypedInput(s,t),await this.initTypedInput(a,i)}generateTypedInputType(e,t,i={}){if(i.value=t,void 0===i.label&&(i.label=this.getI18n(e,`options.${t}.label`,{})||t),!1!==i.icon&&void 0===i.icon&&(i.icon=this.getIcon(this.getI18n(e,`options.${t}.icon`))),i.icon&&"fa-"===i.icon.substr(0,3)&&(i.icon="fa "+i.icon),Array.isArray(i.subOptions)){Array.isArray(i.options)||(i.options=[]);for(const s of i.subOptions)i.options.push(this.generateTypedInputType(e+".options."+t,"string"==typeof s?s:s.name,{icon:!1}))}return i}async generateCheckboxField(e,t){var i=$("<input/>",{id:t.id,type:"checkbox",style:"display: table-cell; width: 14px;vertical-align: top;margin-right: 5px",checked:t.currentValue}),i=await this.generateInputWithLabel(i,t);i.append($("<span/>").html(RED._(t.descText)).css("display","table-cell")),e.append(i)}async generateInputWithLabel(e,t={}){var i,s=$("<div/>",{class:"form-row",style:"padding:5px;margin:0;display:table;min-width:420px;"}),n=e.attr("id");return n&&((i=$("<label/>")).attr("for",n),i.attr("class","l-width"),i.attr("style","display:table-cell;"),void 0===t.title&&(t.title=this.getI18n(t.i18n,"title")),t.title&&i.attr("title",this.getI18n(t.i18n,"title")),void 0===t.icon&&(t.icon=this.getI18n(t.i18n,"icon")),t.icon&&(this.createIconElement(this.getIcon(t.icon),i),i.append(" ")),void 0===t.label&&(t.label=this.getI18n(t.i18n,"label")),t.label&&i.append(`<span>${t.label}</span>`),s.append(i)),e.css("display","table-cell"),s.append(e),s}async generateHR(e,t="5px",i="50px"){e.append(`<hr style="margin: ${t} ${i};">`)}async generateSeparator(e,t){e.append(`<div class="separator">${RED._(t)}</div>`)}static versionCompare(e,t,i={}){const s=i&&i.lexicographical;var n=i&&i.zeroExtend;let a=e.split("."),o=t.split(".");function r(e){return(s?/^\d+[A-Za-z]*$/:/^\d+$/).test(e)}if(!a.every(r)||!o.every(r))return NaN;if(n){for(;a.length<o.length;)a.push("0");for(;o.length<a.length;)o.push("0")}s||(a=a.map(Number),o=o.map(Number));for(let l=0;l<a.length;++l){if(o.length===l)return 1;if(a[l]!==o[l])return a[l]>o[l]?1:-1}return a.length!==o.length?-1:0}}class DeconzMainEditor extends DeconzEditor{constructor(e,t={}){if(super(e,$.extend(!0,{have:{statustext:!0,query:!0,device:!0,output_rules:!1,commands:!1,specific:!1},device:{batteryFilter:!1},output_rules:{format:{single:!0,array:!1,sum:!1,average:!1,min:!1,max:!1},type:{attribute:!0,state:!0,config:!0,homekit:!1,scene_call:!1}},commands:{type:{deconz_state:!0,homekit:!0,custom:!0,pause:!0}},specific:{api:{},output:{},server:{}}},t)),this.subEditor={},this.initDone=!1,this.options.have.statustext&&(this.subEditor.statustext=new DeconzStatusTextEditor(this.node,this.options.statustext)),this.options.have.device&&(this.subEditor.device=new DeconzDeviceEditor(this.node,this.options.device)),this.options.have.query&&(this.subEditor.query=new DeconzQueryEditor(this.node,this.options.query)),this.options.have.specific)switch(this.node.type){case"deconz-api":this.subEditor.specific=new DeconzSpecificApiEditor(this.node,this.options.specific.api);break;case"deconz-output":this.subEditor.specific=new DeconzSpecificOutputEditor(this.node,this.options.specific.output);break;case"deconz-server":this.subEditor.specific=new DeconzSpecificServerEditor(this.node,this.options.specific.server)}this.options.have.output_rules&&(this.subEditor.output_rules=new DeconzOutputRuleListEditor(this.node,this.options.output_rules)),this.options.have.commands&&(this.subEditor.commands=new DeconzCommandListEditor(this.node,this.options.commands))}get elements(){return{tipBox:"node-input-tip-box",server:"node-input-server"}}async configurationMigration(){if(!((this.node.config_version||0)>=this.node._def.defaults.config_version.value)){var e={};for(const o of Object.keys(this.node._def.defaults))e[o]=this.node[o];var t={id:this.node.id,type:this.node.type,config:JSON.stringify(e)};let i="Error while migrating the configuration of the node from version "+(this.node.config_version||0)+" to version "+this.node._def.defaults.config_version.value+".";t=await $.getJSON(this.NRCD+"/configurationMigration",t).catch((e,t)=>{this.$elements.tipBox.append(`<div class="form-tips form-warning"><p>Migration errors:</p><p>${i}</p></div>`)});if(t&&!t.notNeeded){if(t.new)for(var[s,n]of Object.entries(t.new))this.node[s]=n;if(t.delete&&Array.isArray(t.delete))for(const r of t.delete)delete this.node[r];var a=e=>"node-red-contrib-deconz"===e.substr(0,23)?RED._(e):e;t.errors&&Array.isArray(t.errors)&&0<t.errors.length&&this.$elements.tipBox.append('<div class="form-tips form-warning"><p>Migration errors:</p><ul>'+`<li>${t.errors.map(a).join("</li><li>")}</li>`+"</ul></div>"),t.info&&Array.isArray(t.info)&&0<t.info.length&&this.$elements.tipBox.append('<div class="form-tips"><p>Migration info:</p><ul>'+`<li>${t.info.map(a).join("</li><li>")}</li>`+"</ul></div>")}}}async init(){await new Promise(e=>setTimeout(e,100)),await super.init(),await this.configurationMigration(),this.initPromises=[];for(const t of Object.values(this.subEditor))this.initPromises.push(t.init(this));await Promise.all(this.initPromises),this.initDone=!0,delete this.initPromises;var e=[];for(const i of Object.values(this.subEditor))e.push(i.connect());await Promise.all(e)}get serverNode(){return"deconz-server"===this.node.type?this.node:RED.nodes.node(this.$elements.server.val())}async isInitialized(){this.initDone||await Promise.all(this.initPromises)}async updateQueryDeviceDisplay(e){var t=this.subEditor.query.$elements.select.typedInput("type");switch(t){case"device":await this.subEditor.device.updateList(e);break;case"json":case"jsonata":this.subEditor.query.$elements.select.typedInput("validate")&&await this.subEditor.query.updateList(e)}await this.subEditor.device.display("device"===t),await this.subEditor.query.display("device"!==t)}oneditsave(){var e;this.options.have.output_rules&&(e=this.subEditor.output_rules.value,this.node.outputs=e.length,this.node.output_rules=e),this.options.have.commands&&(this.node.commands=this.subEditor.commands.value),this.options.have.specific&&(this.node.specific=this.subEditor.specific.value)}}class DeconzStatusTextEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({allowedTypes:["msg","jsonata"]},t))}get elements(){return{statustext:"node-input-statustext"}}async init(e){await super.init(),this.mainEditor=e,this.initTypedInput()}initTypedInput(){var e=[];this.mainEditor.options.have.statustext&&e.push({value:"auto",label:RED._(this.NRCD+"/server:editor.inputs.statustext.options.auto"),icon:`icons/${this.NRCD}/icon-color.png`,hasValue:!1}),this.$elements.statustext.typedInput({type:"auto",types:e.concat(this.options.allowedTypes),typeField:`#${this.elements.statustext}_type`})}}class DeconzDeviceListEditor extends DeconzEditor{constructor(e,t={}){super(e,t)}get xhrURL(){return this.NRCD+"/itemlist"}get xhrParams(){return{controllerID:this.mainEditor.serverNode.id,forceRefresh:this.options.refresh}}async display(e=!0){if(this.$elements.showHide)return e?this.$elements.showHide.show():this.$elements.showHide.hide(),this.$elements.showHide.promise()}async getItems(e,t){t.forceRefresh=e.refresh;var i=await $.getJSON(this.xhrURL,t).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});if(!i||!i.error_message)return this.formatItemList(i.items,e.keepOnlyMatched);console.warn(i.error_message),RED.notify("Warning : "+i.error_message,{type:"warning",timeout:1e4})}async updateList(e){var t,i;e=$.extend({refresh:!0},e),this.mainEditor.serverNode&&(t=this.$elements.list,i=this.xhrParams,!0===this.options.batteryFilter&&(e.keepOnlyMatched=!0,i.query=JSON.stringify({type:"match",method:"OR",match:{"config.battery":{type:"complex",operator:"!==",value:void 0},"state.battery":{type:"complex",operator:"!==",value:void 0}}})),i=await this.getItems(e,i),t.children().remove(),i&&this.generateHtmlItemList(i,this.$elements.list),t.multipleSelect("refresh"),i)&&t.multipleSelect("enable")}formatItemList(e,t=!1){let s={};var i=(e,i)=>{e.forEach(e=>{var t=e.type;void 0===s[t]&&(s[t]=[]),e.query_match=i,s[t].push(e)})};return i(e.matched,!0),!1===t&&i(e.rejected,!1),s}generateHtmlItemList(e,t){var i,s,n=this.constructor===DeconzQueryEditor;for([i,s]of Object.entries(e).sort((e,t)=>{var i=e[0].toLowerCase(),s=t[0].toLowerCase();return i<s?-1:s<i?1:0})){var a=$("<optgroup/>").attr("label",i);for(const r of s.sort((e,t)=>{var i=e.name.toLowerCase(),s=t.name.toLowerCase();return i<s?-1:s<i?1:0})){let e=r.name;"groups"===r.device_type&&(e+=" (lights: "+r.lights.length,r.scenes.length&&(e+=", scenes: "+r.scenes.length),e+=")");var o=$("<option>"+e+"</option>").attr("value",r.device_path);n&&r.query_match&&o.attr("selected",""),o.appendTo(a)}a.appendTo(t)}}}class DeconzQueryEditor extends DeconzDeviceListEditor{constructor(e,t={}){super(e,$.extend({allowedTypes:["json","jsonata"]},t))}get elements(){return{select:"node-input-query",list:"node-input-query_result",showHide:".deconz-query-selector",refreshButton:"#force-refresh-query-result"}}get type(){return this.$elements.select.typedInput("type")}set type(e){this.$elements.list.typedInput("type",e)}get value(){return this.$elements.select.typedInput("value")}set value(e){this.$elements.list.typedInput("value",e)}get xhrParams(){var e=super.xhrParams;return e.query=this.value,e.queryType=this.type,e.nodeID=this.node.id,e}async init(e){await super.init(),this.mainEditor=e,this.initTypedInput(),this.$elements.list.multipleSelect({maxHeight:300,dropWidth:320,width:320,single:!1,selectAll:!1,filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),numberDisplayed:1,disableIfEmpty:!0,showClear:!1,hideOptgroupCheckboxes:!0,filterGroup:!0,onClick:e=>{this.$elements.list.multipleSelect(e.selected?"uncheck":"check",e.value)}}),await this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0})}initTypedInput(){var e=[];this.mainEditor.options.have.device&&e.push({value:"device",label:RED._(this.NRCD+"/server:editor.inputs.device.query.options.device"),icon:`icons/${this.NRCD}/icon-color.png`,hasValue:!1}),this.$elements.select.typedInput({type:"text",types:e.concat(this.options.allowedTypes),typeField:"#node-input-search_type"})}async connect(){await super.connect(),this.$elements.select.on("change",()=>{this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0}),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()}),this.$elements.refreshButton.on("click",()=>{this.updateList(),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()})}}class DeconzDeviceEditor extends DeconzDeviceListEditor{constructor(e,t={}){super(e,$.extend({batteryFilter:!1},t))}get elements(){return{list:"node-input-device_list",showHide:".deconz-device-selector",refreshButton:"#force-refresh"}}get value(){return this.$elements.list.multipleSelect("getSelects")}set value(e){this.$elements.list.multipleSelect("setSelects",e)}async init(e){await super.init(),this.mainEditor=e,this.$elements.list.multipleSelect({maxHeight:300,dropWidth:320,width:320,single:"multiple"!==this.$elements.list.attr("multiple"),filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),showClear:!0})}async connect(){await super.connect();var e=()=>{this.updateList($.extend(this.options,{useSelectedData:!0})),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()};this.mainEditor.$elements.server.on("change",e),this.$elements.refreshButton.on("click",e),this.mainEditor.options.have.output_rules&&this.$elements.list.on("change",()=>{this.mainEditor.subEditor.output_rules.refresh()})}async updateList(e){let t;(e=$.extend({useSavedData:!1,useSelectedData:!1},e)).useSelectedData&&(t=this.$elements.list.multipleSelect("getSelects")),await super.updateList(e),e.useSavedData&&Array.isArray(this.node.device_list)?this.$elements.list.multipleSelect("setSelects",this.node.device_list):e.useSelectedData&&Array.isArray(t)&&this.$elements.list.multipleSelect("setSelects",t)}}class DeconzSpecificApiEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{container:"deconz-api-form",name:"node-config-input-name",method:"node-config-input-method",endpoint:"node-config-input-endpoint",payload:"node-config-input-payload"}}get default(){return{name:"",method:{type:"GET"},endpoint:{type:"str",value:"/"},payload:{type:"json",value:"{}"}}}async init(){this.node.specific=$.extend(!0,this.default.specific,this.node.specific);var e=this.findElement(this.elements.container);await this.generateMethodField(e,this.node.specific.method),await this.generateEndpointField(e,this.node.specific.endpoint),await this.generatePayloadField(e,this.node.specific.payload),await super.init()}async connect(){await super.connect()}get value(){return{method:{type:this.$elements.method.typedInput("type"),value:this.$elements.method.typedInput("value")},endpoint:{type:this.$elements.endpoint.typedInput("type"),value:this.$elements.endpoint.typedInput("value")},payload:{type:this.$elements.payload.typedInput("type"),value:this.$elements.payload.typedInput("value")}}}set value(e){this.$elements.name.val(e.name);for(var t of["method","endpoint","payload"])this.$elements[t].typedInput("type",e[t].type),this.$elements[t].typedInput("value",e[t].value);for(const i of Object.values(this.$elements))i.trigger("change")}async generateMethodField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.method";await this.generateTypedInputField(e,{id:this.elements.method,i18n:i,value:t,width:"250px",typedInput:{types:[this.generateTypedInputType(i,"GET",{hasValue:!1}),this.generateTypedInputType(i,"POST",{hasValue:!1}),this.generateTypedInputType(i,"PUT",{hasValue:!1}),this.generateTypedInputType(i,"DELETE",{hasValue:!1})]}})}async generateEndpointField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.endpoint";await this.generateTypedInputField(e,{id:this.elements.endpoint,i18n:i,value:t,width:"250px",typedInput:{types:["str"]}})}async generatePayloadField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.payload";await this.generateTypedInputField(e,{id:this.elements.payload,i18n:i,value:t,width:"250px",typedInput:{types:["json","jsonata"]}})}}class DeconzSpecificOutputEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{container:"specific-container",delay:"node-input-delay",result:"node-input-result"}}get default(){return{delay:{type:"num",value:50},result:{type:"at_end"}}}async init(){this.node.specific=$.extend(!0,this.default,this.node.specific);var e=this.findElement(this.elements.container);await this.generateSeparator(e,this.NRCD+"/server:editor.inputs.separator.specific"),await this.generateDelayField(e,this.node.specific.delay),await this.generateResultField(e,this.node.specific.result),await super.init()}async generateDelayField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.output.delay";await this.generateTypedInputField(e,{id:this.elements.delay,i18n:i,value:t,width:"250px",typedInput:{types:["num"]}})}async generateResultField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.output.result";await this.generateTypedInputField(e,{id:this.elements.result,i18n:i,value:t,width:"250px",typedInput:{types:[this.generateTypedInputType(i,"never",{hasValue:!1}),this.generateTypedInputType(i,"after_command",{hasValue:!1}),this.generateTypedInputType(i,"at_end",{hasValue:!1})]}})}async connect(){await super.connect()}get value(){return{delay:{type:this.$elements.delay.typedInput("type"),value:this.$elements.delay.typedInput("value")},result:{type:this.$elements.result.typedInput("type"),value:this.$elements.result.typedInput("value")}}}}class DeconzSpecificServerEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{name:"node-config-input-name",ip:"node-config-input-ip",port:"node-config-input-port",apikey:"node-config-input-secured_apikey",ws_port:"node-config-input-ws_port",secure:"node-config-input-secure",polling:"node-config-input-polling",getSettingsButton:"node-contrib-deconz-get-settings"}}get default(){return{name:"",ip:"",port:"",apikey:"",ws_port:"",secure:!1,polling:15}}get xhrURL(){return this.NRCD+"/serverAutoconfig"}async init(){this.node.specific=$.extend(!0,this.default,this.node.specific),await super.init(),this.node.migration_secured_apikey&&(this.$elements.apikey.val(this.node.migration_secured_apikey),this.$elements.apikey.trigger("change"))}async connect(){await super.connect(),this.$elements.getSettingsButton.on("click",()=>this.discoverParams())}async discoverParams(e){void 0===e&&(e={});let t,s=!1,n=()=>{t&&"function"==typeof t.close&&t.close(),s=!0};t=RED.notify("<p>Trying to find the server settings, please wait...<br>This can take up to 15 seconds.</p>",{modal:!0,fixed:!0,type:"info",buttons:[{text:"Cancel",class:"primary",click:n}]});try{var a=Object.assign({},this.value,e);void 0===a.discoverParam&&(a.discoverParam={}),a.discoverParam.devicetype="Node-Red Deconz Plugin"+(this.node?" id:"+this.node.id:"");let i=await $.getJSON(this.xhrURL,{config:JSON.stringify(a)}).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});if(!s)if(i.error){let e=`<p>Error ${i.error.code}: ${i.error.description}</p>`;var o=[{text:"Cancel",click:n}];switch(i.error.code){case"GATEWAY_CHOICE":e+="<p>There is multiple Deconz device in you network, please select the one you want to configure.</p>";let t=this;for(const[r,l]of i.error.gateway_list.entries())o.push({text:`#${r+1}: `+l.name,id:"node-red-contrib-deconz-gateway-id-"+r,class:"primary",click:()=>{return e=l.bridge_id,n(),e&&(i.currentSettings.discoverParam.targetGatewayID=e),void t.discoverParams(i.currentSettings);var e}});o.push(o.shift());break;case"DECONZ_ERROR":101===i.error.type&&(o.unshift({text:"I pressed the link button",class:"primary",click:()=>{n(),this.discoverParams(i.currentSettings)}}),e=(e+="<p>The reason why the request failed is that the gateway was not unlocked. This mechanism is needed to prevent anybody from access to the gateway without being permitted to do so.</p><ul><li>In a new browser tab open the <a href='http://phoscon.de/pwa/' target='_blank'>Phoscon App</a></li><li>Click on Menu -> Settings -> Gateway</li><li>Click on \"Advanced\" button</li><li>Click on the \"Authenticate app\" button</li></ul>")+`<p>Within 60 seconds after unlocking the gateway, click on the button "${o[0].text}".</p>`);break;default:o[o.length-1].text="Cancel"}e+=`<p>Logs:</p><pre>${i.log.join("\n")}</pre>`,n(),t=RED.notify(e,{modal:!0,fixed:!0,type:"error",buttons:o})}else i.success?(n(),t=RED.notify("<p>Settings fetched successfully !</p>",{modal:!1,fixed:!1,type:"success"}),this.value=i.currentSettings):(n(),t=RED.notify(`<p>Unknown error : ${JSON.stringify(i)}</p>`,{modal:!0,fixed:!0,type:"error",buttons:[{text:"Ok",class:"primary",click:n}]}))}catch(e){n(),t=RED.notify(`<p>Error while processing request: ${e.toString()}</p>`,{type:"error"})}}get value(){return{name:this.$elements.name.val(),ip:this.$elements.ip.val(),port:this.$elements.port.val(),apikey:this.$elements.apikey.val(),ws_port:this.$elements.ws_port.val(),secure:this.$elements.secure.prop("checked"),polling:this.$elements.polling.val()}}set value(e){this.$elements.name.val(e.name),this.$elements.ip.val(e.ip),this.$elements.port.val(e.port),this.$elements.apikey.val(e.apikey),this.$elements.ws_port.val(e.ws_port),this.$elements.secure.prop("checked",e.secure),this.$elements.polling.val(e.polling);for(const t of Object.values(this.$elements))t.trigger("change")}}class DeconzListItemEditor extends DeconzEditor{constructor(e,t,i,s={}){super(e,s),this.listEditor=t,i.uniqueId(),this.uniqueId=i.attr("id"),this.container=i}set index(e){void 0!==e&&this.$elements&&this.$elements.outputButton&&this.$elements.outputButton.find(".node-input-rule-index").html(e+1),this._index=e}get index(){return this._index}async init(){await this.generateOutputButton(this.container.children().first()),await super.init()}async generateOutputButton(e){$("<a/>",{id:this.elements.outputButton,class:"red-ui-button top-right-badge",title:RED._(this.options.button_title)}).append(` → <span class="node-input-rule-index">${this.index+1}</span> `).appendTo(e)}}class DeconzListItemListEditor extends DeconzEditor{constructor(e,t={}){super(e,t),this.items={}}get listType(){return"item"}get buttons(){return[]}async init(e){await super.init(),this.mainEditor=e}async initList(n,e=[]){var t=this.buttons,i=0===t.length||DeconzEditor.versionCompare(RED.settings.version,"1.3.0")<0;this.$elements.list.editableList({sortable:!0,removable:!0,height:"auto",addButton:i,buttons:t,addItem:(e,t,i)=>{var s=new n(this.node,this,e,this.options);i.uniqueId=s.uniqueId,(this.items[i.uniqueId]=s).init(i,t)},removeItem:e=>{if(!e.uniqueId||!this.items[e.uniqueId])throw new Error(`Error while removing the ${this.listType}, the ${this.listType} ${e.uniqueId} does not exist.`);var t=this.items[e.uniqueId].index;delete this.items[e.uniqueId];for(const e of Object.values(this.items))e.index>t&&e.index--},sortItems:e=>{e.each((e,t)=>{if(!this.items[t.attr("id")])throw new Error(`Error while moving the ${this.listType}, the ${this.listType} ${e+1} does not exist.`);this.items[t.attr("id")].index=e})}}),0<e.length&&this.$elements.list.editableList("addItems",e)}get value(){var e=[];for(const t of Object.values(this.items).sort((e,t)=>e.index-t.index))e.push(t.value);return e}refresh(){}}class DeconzOutputRuleEditor extends DeconzListItemEditor{constructor(e,t,i,s={}){super(e,t,i,s=$.extend({enableEachState:!0},s))}get elements(){var e={};for(const t of["format","type","payload","output","onstart","onerror","outputButton"])e[t]=`node-input-output-rule-${this.uniqueId}-`+t;return e}get value(){var e={};switch(e.type=this.$elements.type.val(),e.format=this.$elements.format.val(),e.type){case"attribute":case"state":case"config":"deconz-input"===this.node.type&&(e.output=this.$elements.output.val()),["deconz-input","deconz-battery"].includes(this.node.type)&&(e.onstart=this.$elements.onstart.is(":checked")),["deconz-input","deconz-get"].includes(this.node.type)&&(e.payload=this.$elements.payload.multipleSelect("getSelects"));break;case"homekit":["deconz-input","deconz-battery"].includes(this.node.type)&&(e.onstart=this.$elements.onstart.is(":checked")),"deconz-input"===this.node.type&&(e.onerror=this.$elements.onerror.is(":checked")),["deconz-input","deconz-get"].includes(this.node.type)&&(e.payload=this.$elements.payload.multipleSelect("getSelects"))}return e}get defaultRule(){var e={type:"state",payload:["__complete__"],format:"single"};return"deconz-input"===this.node.type&&(e.output="always",e.onstart=!0,e.onerror=!0),"deconz-battery"===this.node.type&&(e.onstart=!0),e}async init(e,t){this._index=t,e=$.extend(!0,this.defaultRule,e),await this.generatePayloadTypeField(this.container,e.type),["deconz-input","deconz-get"].includes(this.node.type)&&await this.generatePayloadField(this.container),await this.generatePayloadFormatField(this.container,e.format),"deconz-input"===this.node.type&&await this.generateOutputField(this.container,(void 0!==e.output?e:this.defaultRule).output),["deconz-input","deconz-battery"].includes(this.node.type)&&await this.generateOnStartField(this.container,(void 0!==e.onstart?e:this.defaultRule).onstart),"deconz-input"===this.node.type&&await this.generateOnErrorField(this.container,(void 0!==e.onerror?e:this.defaultRule).onerror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.initPayloadList(e.payload),await this.updateShowHide(e.type),await this.connect()}async connect(){await super.connect(),this.$elements.type.on("change",()=>{var e=this.$elements.type.val();["attribute","state","config","homekit"].includes(e)&&this.updatePayloadList(),this.updateShowHide(e)}),this.$elements.outputButton.on("click",()=>{try{var t=RED.nodes.filterLinks({source:this.node,sourcePort:this.index}).map(e=>{var t=e.target.type;return""!==e.target.name?t+":"+e.target.name:void 0!==e.target._def.label?t+":"+e.target._def.label():t});let e=RED.notify(`The output ${this.index+1} is sending message to ${t.length} nodes :<br>`+t.join("<br>"),{modal:!0,timeout:5e3,buttons:[{text:"okay",class:"primary",click:()=>e.close()}]})}catch(e){this.sendError("This is using not documented API so can be broken at anytime.<br>Error while getting connected nodes: "+e.toString())}})}async updateShowHide(e){switch(e){case"attribute":case"state":case"config":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").show(),this.$elements.onstart.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").hide();break;case"homekit":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").hide(),this.$elements.onstart.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").show();break;case"scene_call":this.$elements.payload.closest(".form-row").hide(),this.$elements.output.closest(".form-row").hide(),this.$elements.onstart.closest(".form-row").hide(),this.$elements.onerror.closest(".form-row").hide()}}async updatePayloadList(){if(this.listEditor.mainEditor.serverNode){this.$elements.payload.multipleSelect("disable"),this.$elements.payload.children().remove();var t=this.listEditor.mainEditor.subEditor.query.type,i=this.listEditor.mainEditor.subEditor.device.value,s=this.$elements.type.val();if(["attribute","state","config","homekit"].includes(s)){var n=this.NRCD+"/server:editor.inputs.outputs.payload";let e="";if("homekit"===s?e+='<option value="__auto__">'+RED._(n+".options.auto")+"</option>":(e+='<option value="__complete__">'+RED._(n+".options.complete")+"</option>",!0===this.options.enableEachState&&(e+='<option value="__each__">'+RED._(n+".options.each")+"</option>")),this.$elements.payload.html(e),"device"===t){var a=await $.getJSON(this.NRCD+`/${s}list`,{controllerID:this.listEditor.mainEditor.serverNode.id,devices:JSON.stringify(this.listEditor.mainEditor.subEditor.device.value)});for(const l of"attribute"===s?["attribute","state","config"]:[s]){let e=this.getI18n(n+".group_label."+l);void 0===e&&(e=l);var o=$("<optgroup/>",{label:e});for(const p of Object.keys(a.count[l]).sort()){let e=a.sample[l][p];e="string"==typeof e?`"${e}"`:Array.isArray(e)?`[${e.toString()}]`:null===e||void 0===e?"NULL":e.toString();let t;var r=a.count[l][p];t=r===i.length?RED._(n+".item_list",{name:p,sample:e}):RED._(n+".item_list_mix",{name:p,sample:e,item_count:r,device_count:i.length}),$("<option>"+t+"</option>").attr("value","attribute"===s&&"attribute"!==l?l+"."+p:p).appendTo(o)}$.isEmptyObject(a.count[l])||o.appendTo(this.$elements.payload)}}this.$elements.payload.multipleSelect("refresh").multipleSelect("enable")}}}async initPayloadList(e){let t=this.$elements.payload;t.addClass("multiple-select"),t.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!1,selectAll:!1,container:".node-input-output-container-row",filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),onClick:e=>{if(e.selected)switch(e.value){case"__complete__":case"__each__":case"__auto__":t.multipleSelect("setSelects",[e.value]);break;default:t.multipleSelect("uncheck","__complete__"),t.multipleSelect("uncheck","__each__"),t.multipleSelect("uncheck","__auto__")}},onUncheckAll:()=>{t.multipleSelect("setSelects",["__complete__","__auto__"])},onOptgroupClick:e=>{e.selected&&(t.multipleSelect("uncheck","__complete__"),t.multipleSelect("uncheck","__each__"),t.multipleSelect("uncheck","__auto__"))}}),await this.updatePayloadList(),e&&t.multipleSelect("setSelects",e)}async generatePayloadTypeField(e,t){var i,s,n=this.NRCD+"/server:editor.inputs.outputs.type",a=[];for([i,s]of Object.entries(this.listEditor.options.type))s&&a.push([i,n+".options."+i]);await this.generateSimpleListField(e,{id:this.elements.type,i18n:n,choices:a,currentValue:t})}async generatePayloadField(e){var t=this.NRCD+"/server:editor.inputs.outputs.payload";await this.generateSimpleListField(e,{id:this.elements.payload,i18n:t})}async generatePayloadFormatField(e,t){var i,s,n=this.NRCD+"/server:editor.inputs.outputs.format",a=[];for([i,s]of Object.entries(this.listEditor.options.format))s&&a.push([i,n+".options."+i]);await this.generateSimpleListField(e,{id:this.elements.format,i18n:n,choices:a,currentValue:t})}async generateOutputField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.output";await this.generateSimpleListField(e,{id:this.elements.output,i18n:i,choices:[["always",i+".options.always"],["onchange",i+".options.onchange"],["onupdate",i+".options.onupdate"]],currentValue:t})}async generateOnStartField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.on_start";await this.generateCheckboxField(e,{id:this.elements.onstart,i18n:i,currentValue:t})}async generateOnErrorField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.on_error";await this.generateCheckboxField(e,{id:this.elements.onerror,i18n:i,currentValue:t})}}class DeconzOutputRuleListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"rule"}get buttons(){var e,t=[],i=this.NRCD+"/server:editor.inputs.outputs.type";for(const[s,n]of Object.entries(this.options.type))n&&(e=this.getI18n(i+".options."+s),t.push({label:this.getI18n(i+".add_button","label",{type:e}),icon:this.getIcon(this.getI18n(i+".add_button","icon"),!0),title:this.getI18n(i+".add_button","title",{type:e}),click:()=>this.$elements.list.editableList("addItem",{type:s})}));return t}async init(e){await super.init(e),await this.initList(DeconzOutputRuleEditor,this.node.output_rules)}refresh(){for(const e of Object.values(this.items))e.updatePayloadList()}}class DeconzCommandEditor extends DeconzListItemEditor{constructor(e,t,i,s={}){super(e,t,i,s=$.extend({},s)),this.containers={}}get lightKeys(){return["bri","sat","hue","ct","xy"]}get argKeys(){return["on","alert","effect","colorloopspeed","open","stop","lift","tilt","scene_mode","group","scene","scene_name","target","command","payload","delay","transitiontime","retryonerror","aftererror"]}get elements(){var e=this.argKeys;e.push("typedomain"),e.push("outputButton"),e.push("scene_picker"),e.push("scene_picker_refresh");for(const i of this.lightKeys)e.push(i),e.push(i+"_direction");var t={};for(const s of e)t[s]=`node-input-output-rule-${this.uniqueId}-`+s;return t}set value(e){}get value(){var e={arg:{}};e.type=this.$elements.typedomain.typedInput("type"),e.domain=this.$elements.typedomain.typedInput("value");for(const t of this.argKeys)this.$elements[t].parent(".form-row").is(":visible")&&(e.arg[t]={type:this.$elements[t].typedInput("type"),value:this.$elements[t].typedInput("value")});for(const i of this.lightKeys)this.$elements[i].parent(".form-row").is(":visible")&&(e.arg[i]={direction:this.$elements[i+"_direction"].typedInput("type"),type:this.$elements[i].typedInput("type"),value:this.$elements[i].typedInput("value")});return e}get defaultCommand(){return{type:"deconz_state",domain:"lights",target:"state",arg:{on:{type:"keep"},bri:{direction:"set",type:"num"},sat:{direction:"set",type:"num"},hue:{direction:"set",type:"num"},ct:{direction:"set",type:"num"},xy:{direction:"set",type:"num"},alert:{type:"str"},effect:{type:"str"},colorloopspeed:{type:"num"},transitiontime:{type:"num"},command:{type:"str",value:"on"},payload:{type:"msg",value:"payload"},delay:{type:"num",value:2e3},target:{type:"state"},group:{type:"num"},scene_mode:{type:"single"},scene_call:{type:"num"},scene_name:{type:"str"},retryonerror:{type:"num",value:0},aftererror:{type:"continue"}}}}async init(e,t){this._index=t,e=$.extend(!0,this.defaultCommand,e),await this.generateTypeDomainField(this.container,{type:e.type,value:e.domain}),this.containers.light=$("<div>").appendTo(this.container),await this.generateLightOnField(this.containers.light,e.arg.on);for(const i of["bri","sat","hue","ct","xy"])await this.generateLightColorField(this.containers.light,i,e.arg[i]),"bri"===i&&await this.generateHR(this.containers.light);await this.generateHR(this.containers.light),await this.generateLightAlertField(this.containers.light,e.arg.alert),await this.generateLightEffectField(this.containers.light,e.arg.effect),await this.generateLightColorLoopSpeedField(this.containers.light,e.arg.colorloopspeed),this.containers.windows_cover=$("<div>").appendTo(this.container),await this.generateCoverOpenField(this.containers.windows_cover,e.arg.open),await this.generateCoverStopField(this.containers.windows_cover,e.arg.stop),await this.generateCoverLiftField(this.containers.windows_cover,e.arg.lift),await this.generateCoverTiltField(this.containers.windows_cover,e.arg.tilt),this.containers.scene_call=$("<div>").appendTo(this.container),await this.generateSceneModeField(this.containers.scene_call,e.arg.scene_mode),this.containers.scene_call_single=$("<div>").appendTo(this.containers.scene_call),await this.generateScenePickerField(this.containers.scene_call_single,e.arg.group+"."+e.arg.scene),await this.generateSceneGroupField(this.containers.scene_call_single,e.arg.group),await this.generateSceneSceneField(this.containers.scene_call_single,e.arg.scene),this.containers.scene_call_dynamic=$("<div>").appendTo(this.containers.scene_call),await this.generateSceneNameField(this.containers.scene_call_dynamic,e.arg.scene_name),this.containers.target=$("<div>").appendTo(this.container),await this.generateTargetField(this.containers.target,e.arg.target),this.containers.command=$("<div>").appendTo(this.container),await this.generateCommandField(this.containers.command,e.arg.command),this.containers.payload=$("<div>").appendTo(this.container),await this.generatePayloadField(this.containers.payload,e.arg.payload),this.containers.pause=$("<div>").appendTo(this.container),await this.generatePauseDelayField(this.containers.pause,e.arg.delay),this.containers.transition=$("<div>").appendTo(this.container),await this.generateHR(this.containers.transition),await this.generateCommonTransitionTimeField(this.containers.transition,e.arg.transitiontime),this.containers.common=$("<div>").appendTo(this.container),await this.generateHR(this.containers.common),await this.generateCommonOnErrorRetryField(this.containers.common,e.arg.retryonerror),await this.generateCommonOnErrorAfterField(this.containers.common,e.arg.aftererror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.updateShowHide(e.type,e.domain),await this.connect()}async connect(){await super.connect(),this.$elements.typedomain.on("change",(e,t,i)=>{this.updateShowHide(t,i)}),this.$elements.outputButton.on("click",async()=>{try{if("device"!==this.listEditor.mainEditor.subEditor.query.type)this.sendError("Error : The run command can only work with device list.",5e3);else{var t=this.value,i=this.listEditor.mainEditor.subEditor.device.value;if(0!==i.length||("deconz_state"===t.type&&"scene_call"===t.domain||"custom"===t.type&&"scene_call"===t.arg.target.type))if("pause"===t.type)this.sendError("Error : Can't test pause command.",5e3);else{for(var[s,n]of Object.entries(t.arg))if(["msg","flow","global","jsonata"].includes(n.type))return void this.sendError(`Error : Cant run this command because the value "${s}" is type "${n.type}".`,5e3);let e=RED.notify("Sending request...",{type:"info"});await $.post(this.NRCD+"/testCommand",{controllerID:this.listEditor.mainEditor.serverNode.id,device_list:i,command:t,delay:this.listEditor.mainEditor.subEditor.specific.value.delay}).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});e.close(),e=RED.notify("Ok",{timeout:1e3,type:"success"})}else this.sendError("Error : No device selected.",5e3)}}catch(e){let t=RED.notify(e.toString(),{type:"error",buttons:[{class:"error",click:()=>t.close()}]})}});const e=()=>{var e=this.$elements.scene_picker.multipleSelect("getSelects");1===e.length&&(this.$elements.group.off("change",t),this.$elements.scene.off("change",t),e=e[0].split("."),this.$elements.group.typedInput("type","num"),this.$elements.group.typedInput("value",e[0]),this.$elements.scene.typedInput("type","num"),this.$elements.scene.typedInput("value",e[1]),this.$elements.group.on("change",t),this.$elements.scene.on("change",t))},t=()=>{this.$elements.scene_picker.off("change",e),this.$elements.scene_picker.multipleSelect("setSelects","num"!==this.$elements.group.typedInput("type")||"num"!==this.$elements.group.typedInput("type")?[]:[this.$elements.group.typedInput("value")+"."+this.$elements.scene.typedInput("value")]),this.$elements.scene_picker.on("change",e)};this.$elements.scene_mode.on("change",()=>{var e="single"===this.$elements.scene_mode.typedInput("type");this.containers.scene_call_single.toggle(e),this.containers.scene_call_dynamic.toggle(!e)}),this.$elements.scene_picker.on("change",e),this.$elements.group.on("change",t),this.$elements.scene.on("change",t),this.$elements.scene_picker_refresh.on("click",()=>this.updateSceneList()),this.$elements.target.on("change",(e,t,i)=>{this.containers.command.toggle("scene_call"!==t)})}async updateShowHide(e,t){var i,s,n=[];switch(e){case"deconz_state":switch(t){case"lights":case"groups":n.push("light"),n.push("transition");break;case"covers":n.push("windows_cover");break;case"scene_call":n.push("scene_call"),await this.updateSceneList(),n.push("scene_call_"+("single"===this.$elements.scene_mode.typedInput("type")?"single":"dynamic"))}n.push("common");break;case"homekit":this.$elements.payload.typedInput("types",["msg","flow","global","json","jsonata"]),n.push("payload"),n.push("transition"),n.push("common");break;case"custom":n.push("target"),"scene_call"!==this.$elements.target.typedInput("type")&&n.push("command"),this.$elements.payload.typedInput("types",["msg","flow","global","str","num","bool","json","jsonata","date"]),n.push("payload"),n.push("transition"),n.push("common");break;case"pause":n.push("pause")}for([i,s]of Object.entries(this.containers))s.toggle(n.includes(i))}async updateSceneList(){this.$elements.scene_picker.multipleSelect("disable"),this.$elements.scene_picker.children().remove();var e=this.listEditor.mainEditor.subEditor.query;if(void 0!==e){var t=e.xhrParams,e=(t.queryType="json",t.query=JSON.stringify({match:{device_type:"groups"}}),await e.getItems({refresh:!0,keepOnlyMatched:!0},t));if(void 0!==e&&void 0!==e.LightGroup){for(const s of e.LightGroup){var i=$("<optgroup/>",{label:s.id+" - "+s.name});if(s.scenes&&0<s.scenes.length){for(const n of s.scenes)$(`<option>${n.id} - ${n.name}</option>`).attr("value",s.id+"."+n.id).appendTo(i);i.appendTo(this.$elements.scene_picker)}}this.$elements.scene_picker.multipleSelect("refresh").multipleSelect("enable"),this.$elements.scene_picker.multipleSelect("setSelects","num"!==this.$elements.group.typedInput("type")||"num"!==this.$elements.group.typedInput("type")?[]:[this.$elements.group.typedInput("value")+"."+this.$elements.scene.typedInput("value")])}}}async generateTypeDomainField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type";await this.generateTypedInputField(e,{id:this.elements.typedomain,i18n:i,value:t,addDefaultTypes:!1,typedInput:{default:"deconz_state",types:[this.generateTypedInputType(i,"deconz_state",{subOptions:["lights","covers","groups","scene_call"]}),this.generateTypedInputType(i,"homekit",{hasValue:!1}),this.generateTypedInputType(i,"custom",{hasValue:!1}),this.generateTypedInputType(i,"pause",{hasValue:!1})]}})}async generateLightOnField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.on";await this.generateTypedInputField(e,{id:this.elements.on,i18n:i,value:t,typedInput:{default:"keep",types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i,"toggle",{hasValue:!1})]}})}async generateLightColorField(e,t,i={}){var s=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields";let n=["num"];var a=[this.generateTypedInputType(s+".lightFields","set",{hasValue:!1})];switch(t){case"bri":n.push("str"),a.push(this.generateTypedInputType(s+".lightFields","inc",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","dec",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","detect_from_value",{hasValue:!1}));break;case"ct":n.push("str"),n.push(this.generateTypedInputType(s+".ct","deconz",{subOptions:["cold","white","warm"]})),a.push(this.generateTypedInputType(s+".lightFields","inc",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","dec",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","detect_from_value",{hasValue:!1}));break;case"xy":n=["json"]}await this.generateDoubleTypedInputField(e,{id:this.elements[t+"_direction"],i18n:s+"."+t,addDefaultTypes:!1,value:{type:i.direction},typedInput:{types:a}},{id:this.elements[t],value:{type:i.type,value:["xy"===t&&void 0===i.value?"[]":i.value]},typedInput:{types:n}})}async generateLightAlertField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.alert";await this.generateTypedInputField(e,{id:this.elements.alert,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"deconz",{subOptions:["none","select","lselect"]})]}})}async generateLightEffectField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.effect";await this.generateTypedInputField(e,{id:this.elements.effect,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"deconz",{subOptions:["none","colorloop"]})]}})}async generateLightColorLoopSpeedField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.colorloopspeed";await this.generateTypedInputField(e,{id:this.elements.colorloopspeed,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCoverOpenField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.open";await this.generateTypedInputField(e,{id:this.elements.open,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i,"toggle",{hasValue:!1})]}})}async generateCoverStopField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.stop";await this.generateTypedInputField(e,{id:this.elements.stop,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]})]}})}async generateCoverLiftField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.lift";await this.generateTypedInputField(e,{id:this.elements.lift,i18n:i,value:t,typedInput:{types:["num","str",this.generateTypedInputType(i,"stop",{hasValue:!1})]}})}async generateCoverTiltField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.tilt";await this.generateTypedInputField(e,{id:this.elements.tilt,i18n:i,value:t,typedInput:{types:["num"]}})}async generateSceneModeField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.mode";await this.generateTypedInputField(e,{id:this.elements.scene_mode,i18n:i,value:t,addDefaultTypes:!1,typedInput:{types:[this.generateTypedInputType(i,"single",{hasValue:!1}),this.generateTypedInputType(i,"dynamic",{hasValue:!1})]}})}async generateScenePickerField(e,t=0){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.picker",s=await this.generateSimpleListField(e,{id:this.elements.scene_picker,i18n:i}),i=(s.addClass("multiple-select"),s.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!0,singleRadio:!0,hideOptgroupCheckboxes:!0,showClear:!0,selectAll:!1,filter:!0,filterPlaceholder:this.getI18n(i,"filter_place_holder"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),container:".node-input-output-container-row"}),$("<a/>",{id:this.elements.scene_picker_refresh,class:"red-ui-button",style:"margin-left:10px;"}));this.createIconElement(this.getIcon("refresh"),i),s.closest(".form-row").append(i)}async generateSceneGroupField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.group";await this.generateTypedInputField(e,{id:this.elements.group,i18n:i,value:t,typedInput:{types:["num"]}})}async generateSceneSceneField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene";await this.generateTypedInputField(e,{id:this.elements.scene,i18n:i,value:t,typedInput:{types:["num","str",this.generateTypedInputType(i,"deconz",{subOptions:["next","prev"]})]}})}async generateSceneNameField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene_name";await this.generateTypedInputField(e,{id:this.elements.scene_name,i18n:i,value:t,typedInput:{types:["str","re"]}})}async generateTargetField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.target";await this.generateTypedInputField(e,{id:this.elements.target,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"attribute",{hasValue:!1}),this.generateTypedInputType(i,"state",{hasValue:!1}),this.generateTypedInputType(i,"config",{hasValue:!1}),this.generateTypedInputType(i,"scene_call",{hasValue:!1})]}})}async generateCommandField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.command";await this.generateTypedInputField(e,{id:this.elements.command,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"object",{hasValue:!1})]}})}async generatePayloadField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.payload";await this.generateTypedInputField(e,{id:this.elements.payload,i18n:i,value:t,addDefaultTypes:!1,typedInput:{types:["msg","flow","global","str","num","bool","json","jsonata","date"]}})}async generatePauseDelayField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.pause.fields.delay";await this.generateTypedInputField(e,{id:this.elements.delay,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCommonTransitionTimeField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_s