node-red-contrib-deconz
Advanced tools
Comparing version 2.0.0-beta.10 to 2.0.0-beta.11
@@ -51,3 +51,3 @@ { | ||
}, | ||
"version": "2.0.0-beta.10", | ||
"version": "2.0.0-beta.11", | ||
"devDependencies": { | ||
@@ -54,0 +54,0 @@ "grunt": "^1.3.0", |
@@ -1,2 +0,2 @@ | ||
class DeconzEditor{constructor(node,options={}){this.node=node,this.options=options}get elements(){return{}}get NRCD(){return"node-red-contrib-deconz"}findElements(){this.$elements={},Object.keys(this.elements).forEach(k=>{this.$elements[k]=this.findElement(this.elements[k])})}findElement(identifier){return"#"!==identifier.charAt(0)&&"."!==identifier.charAt(0)&&(identifier="#"+identifier),$(identifier)}async init(){this.findElements()}async connect(){}sendError(msg,timeout=1e4){let myNotification=RED.notify(msg,{timeout:timeout,type:"error",buttons:[{text:"okay",class:"primary",click:()=>myNotification.close()}]})}getIcon(icon,includeClass=!1){return"deconz"===icon?"icons/node-red-contrib-deconz/icon-color.png":"homekit"===icon?"icons/node-red-contrib-deconz/homekit-logo.png":RED.nodes.fontAwesome.getIconList().includes(`fa-${icon}`)?`${includeClass?"fa ":""}fa-${icon}`:icon}createIconElement(icon,container,isLarge=!1){if("fa-"===icon.substr(0,3)){if(RED.nodes.fontAwesome.getIconUnicode(icon)){let faIconElement=$("<i/>").appendTo(container);return void faIconElement.addClass("fa "+icon+(isLarge?" fa-lg":""))}icon=RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"}let imageIconElement=$("<div/>").appendTo(container);imageIconElement.css("backgroundImage","url("+icon+")")}getI18n(prefix,suffix,value={}){let _path=prefix;suffix&&(_path+=`.${suffix}`),value.defaultValue="__undefined__";value=RED._(_path,value);if("__undefined__"!==value)return value}async generateSimpleListField(container,options){let input=$("<select/>",{id:options.id});if(options.choices)for(var[key,value]of options.choices)input.append($("<option/>").attr("value",key).html(RED._(value)));var row=await this.generateInputWithLabel(input,options);return container.append(row),void 0!==options.currentValue&&input.val(options.currentValue),input}async generateTypedInput(container,inputType){let input=$("<input/>",{id:inputType.id,placeholder:RED._(inputType.placeholder)});inputType=$("<input/>",{id:`${inputType.id}_type`,type:"hidden"});return input.append(inputType),input}async initTypedInput(input,options){options=$.extend({addDefaultTypes:!0,displayOnlyIcon:!1,value:{},width:"200px"},options);let typedInputOptions=$.extend({types:["msg","flow","global"]},options.typedInput);if(typedInputOptions.typeField=options.typeId,options.addDefaultTypes&&(typedInputOptions.types.push("msg"),typedInputOptions.types.push("flow"),typedInputOptions.types.push("global"),typedInputOptions.types.push("jsonata")),options.displayOnlyIcon){let that=this;function valueLabel(a,b){let typeDefinition;for(const type of this.typeList)"object"==typeof type&&type.value===this.propertyType&&(typeDefinition=type);void 0!==typeDefinition&&void 0!==typeDefinition.icon&&(this.oldValue=this.input.val(),this.input.val(""),this.valueLabelContainer.hide(),that.createIconElement(typeDefinition.icon,this.selectLabel),this.selectTrigger.addClass("red-ui-typedInput-full-width"),this.selectLabel.show())}var type;for(type of typedInputOptions.types)"string"!=typeof type&&(type.hasValue=!0,type.valueLabel=valueLabel)}input.typedInput(typedInputOptions),void 0!==options.width&&input.typedInput("width",options.width),options.value&&(void 0!==options.value.type&&input.typedInput("type",options.value.type),void 0!==options.value.value&&input.typedInput("value",options.value.value))}async generateTypedInputField(container,options){var input=await this.generateTypedInput(container,{id:options.id,placeholder:this.getI18n(options.i18n,"placeholder")}),row=await this.generateInputWithLabel(input,options);return container.append(row),await this.initTypedInput(input,options),input}async generateDoubleTypedInputField(container,optionsFirst,optionsSecond){var inputFirst=await this.generateTypedInput(container,optionsFirst);let row=await this.generateInputWithLabel(inputFirst,optionsFirst);var inputSecond=await this.generateTypedInput(container,optionsSecond);row.append(inputSecond),container.append(row),optionsFirst.displayOnlyIcon=!0,optionsFirst.width="50px",optionsSecond.width="150px",await this.initTypedInput(inputFirst,optionsFirst),await this.initTypedInput(inputSecond,optionsSecond)}generateTypedInputType(i18n,name,data={}){if(data.value=name,void 0===data.label&&(data.label=this.getI18n(i18n,`options.${name}.label`,{})||name),!1!==data.icon&&void 0===data.icon&&(data.icon=this.getIcon(this.getI18n(i18n,`options.${name}.icon`))),data.icon&&"fa-"===data.icon.substr(0,3)&&(data.icon="fa "+data.icon),Array.isArray(data.subOptions)){Array.isArray(data.options)||(data.options=[]);for(const opt of data.subOptions)data.options.push(this.generateTypedInputType(`${i18n}.options.${name}`,"string"==typeof opt?opt:opt.name,{icon:!1}))}return data}async generateCheckboxField(container,options){var input=$("<input/>",{id:options.id,type:"checkbox",style:"display: table-cell; width: 14px;vertical-align: top;margin-right: 5px",checked:options.currentValue});let row=await this.generateInputWithLabel(input,options);row.append($("<span/>").html(RED._(options.descText)).css("display","table-cell")),container.append(row)}async generateInputWithLabel(input,options={}){let row=$("<div/>",{class:"form-row",style:"padding:5px;margin:0;display:table;min-width:420px;"});var inputID=input.attr("id");if(inputID){let labelElement=$("<label/>");labelElement.attr("for",inputID),labelElement.attr("class","l-width"),labelElement.attr("style","display:table-cell;"),void 0===options.title&&(options.title=this.getI18n(options.i18n,"title")),options.title&&labelElement.attr("title",this.getI18n(options.i18n,"title")),void 0===options.icon&&(options.icon=this.getI18n(options.i18n,"icon")),options.icon&&(this.createIconElement(this.getIcon(options.icon),labelElement),labelElement.append(" ")),void 0===options.label&&(options.label=this.getI18n(options.i18n,"label")),options.label&&labelElement.append(`<span>${options.label}</span>`),row.append(labelElement)}return input.css("display","table-cell"),row.append(input),row}async generateHR(container,topBottom="5px",leftRight="50px"){container.append(`<hr style="margin: ${topBottom} ${leftRight};">`)}async generateSeparator(container,label){container.append(`<div class="separator">${RED._(label)}</div>`)}}class DeconzMainEditor extends DeconzEditor{constructor(node,options={}){super(node,$.extend(!0,{have:{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}},commands:{type:{deconz_state:!0,homekit:!0,custom:!0,pause:!0}},specific:{output:{}}},options)),this.subEditor={},this.initDone=!1,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&&"deconz-output"===this.node.type&&(this.subEditor.specific=new DeconzSpecificOutputEditor(this.node,this.options.specific.output)),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{server:"node-input-server"}}async configurationMigration(){if(!((this.node.config_version||0)>=this.node._def.defaults.config_version.value)){let config={};for(const key of Object.keys(this.node._def.defaults))config[key]=this.node[key];var data={type:this.node.type,config:JSON.stringify(config)};let errorMsg="Error while migrating the configuration of the node from version "+(this.node.config_version||0)+" to version "+this.node._def.defaults.config_version.value+".",result=await $.getJSON(`${this.NRCD}/configurationMigration`,data).catch((t,u)=>{this.sendError(errorMsg)});if(result&&!result.notNeeded){if(result.new)for(var[key,value]of Object.entries(result.new))this.node[key]=value;if(result.delete&&Array.isArray(result.delete))for(const key of result.delete)delete this.node[key];result.errors&&Array.isArray(result.errors)&&0<result.errors.length&&this.sendError(errorMsg+"<br><li>"+result.errors.join("</li><li>")+"</li>")}}}async init(){await new Promise(resolve=>setTimeout(resolve,100)),await this.configurationMigration(),await super.init(),this.serverNode=RED.nodes.node(this.$elements.server.val()),this.initPromises=[];for(const editor of Object.values(this.subEditor))this.initPromises.push(editor.init(this));await Promise.all(this.initPromises),this.initDone=!0,delete this.initPromises;let connectPromises=[];for(const editor of Object.values(this.subEditor))connectPromises.push(editor.connect());await Promise.all(connectPromises)}async isInitialized(){this.initDone||await Promise.all(this.initPromises)}async updateQueryDeviceDisplay(options){var type=this.subEditor.query.$elements.select.typedInput("type");switch(type){case"device":await this.subEditor.device.updateList(options);break;case"json":case"jsonata":console.log("update ?"),this.subEditor.query.$elements.select.typedInput("validate")&&(console.log("yes!"),await this.subEditor.query.updateList(options))}await this.subEditor.device.display("device"===type),await this.subEditor.query.display("device"!==type)}oneditsave(){var newRules;this.options.have.output_rules&&(newRules=this.subEditor.output_rules.value,this.node.outputs=newRules.length,this.node.output_rules=newRules),this.options.have.commands&&(this.node.commands=this.subEditor.commands.value),this.options.have.specific&&(this.node.specific=this.subEditor.specific.value)}}class DeconzDeviceListEditor extends DeconzEditor{constructor(node,options={}){super(node,options)}get xhrURL(){return`${this.NRCD}/itemlist`}get xhrParams(){return{controllerID:this.mainEditor.serverNode.id,forceRefresh:this.options.refresh}}async display(display=!0){if(this.$elements.showHide)return display?this.$elements.showHide.show():this.$elements.showHide.hide(),this.$elements.showHide.promise()}async getItems(options,result){result.forceRefresh=options.refresh;result=await $.getJSON(this.xhrURL,result).catch((t,u)=>{this.sendError(400===t.status&&t.responseText?t.responseText:u.toString())});if(!result||!result.error_message)return this.formatItemList(result.items,options.keepOnlyMatched);console.warn(result.error_message)}async updateList(devices){devices=$.extend({refresh:!0},devices);let list=this.$elements.list,params=this.xhrParams;!0===this.options.batteryFilter&&(devices.keepOnlyMatched=!0,params.query=JSON.stringify({type:"match",match:{"config.battery":{type:"complex",operator:"!==",value:void 0}}}));devices=await this.getItems(devices,params);list.children().remove(),devices&&this.generateHtmlItemList(devices,this.$elements.list),list.multipleSelect("refresh"),devices&&list.multipleSelect("enable")}formatItemList(items,keepOnlyMatched=!1){let itemList={};var injectItems=(part,matched)=>{part.forEach(item=>{var device_type=item.type;void 0===itemList[device_type]&&(itemList[device_type]=[]),item.query_match=matched,itemList[device_type].push(item)})};return injectItems(items.matched,!0),!1===keepOnlyMatched&&injectItems(items.rejected,!1),itemList}generateHtmlItemList(items,htmlContainer){var group_key,item_list,queryMode=this.constructor===DeconzQueryEditor;for([group_key,item_list]of Object.entries(items).sort((x,y)=>{x=x[0].toLowerCase(),y=y[0].toLowerCase();return x<y?-1:y<x?1:0})){let groupHtml=$("<optgroup/>").attr("label",group_key);for(const item of item_list.sort((x,y)=>{x=x.name.toLowerCase(),y=y.name.toLowerCase();return x<y?-1:y<x?1:0})){let label=item.name;"groups"===item.device_type&&(label+=" (lights: "+item.lights.length,item.scenes.length&&(label+=", scenes: "+item.scenes.length),label+=")");let opt=$("<option>"+label+"</option>").attr("value",item.device_path);queryMode&&item.query_match&&opt.attr("selected",""),opt.appendTo(groupHtml)}groupHtml.appendTo(htmlContainer)}}}class DeconzQueryEditor extends DeconzDeviceListEditor{constructor(node,options={}){super(node,$.extend({allowedTypes:["json","jsonata"]},options))}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(val){this.$elements.list.typedInput("type",val)}get value(){return this.$elements.select.typedInput("value")}set value(val){this.$elements.list.typedInput("value",val)}get xhrParams(){let params=super.xhrParams;return params.query=this.value,params.queryType=this.type,params.nodeID=this.node.id,params}async init(mainEditor){await super.init(),this.mainEditor=mainEditor,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:view=>{this.$elements.list.multipleSelect(view.selected?"uncheck":"check",view.value)}}),await this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0})}initTypedInput(){let options=[];this.mainEditor.options.have.device&&options.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:options.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.subEditor.output_rules.refresh()}),this.$elements.refreshButton.on("click",()=>{this.updateList(),this.mainEditor.subEditor.output_rules.refresh()})}}class DeconzDeviceEditor extends DeconzDeviceListEditor{constructor(node,options={}){super(node,$.extend({batteryFilter:!1},options))}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(val){this.$elements.list.multipleSelect("setSelects",val)}async init(mainEditor){await super.init(),this.mainEditor=mainEditor,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(),this.$elements.refreshButton.on("click",()=>{this.updateList($.extend(this.options,{useSelectedData:!0})),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()}),this.mainEditor.options.have.output_rules&&this.$elements.list.on("change",()=>{this.mainEditor.subEditor.output_rules.refresh()})}async updateList(options){let itemsSelected;(options=$.extend({useSavedData:!1,useSelectedData:!1},options)).useSelectedData&&(itemsSelected=this.$elements.list.multipleSelect("getSelects")),await super.updateList(options),options.useSavedData&&Array.isArray(this.node.device_list)?this.$elements.list.multipleSelect("setSelects",this.node.device_list):options.useSelectedData&&Array.isArray(itemsSelected)&&this.$elements.list.multipleSelect("setSelects",itemsSelected)}}class DeconzSpecificOutputEditor extends DeconzEditor{constructor(node,options={}){super(node,$.extend({},options))}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 container=this.findElement(this.elements.container);await this.generateSeparator(container,`${this.NRCD}/server:editor.inputs.separator.specific`),await this.generateDelayField(container,this.node.specific.delay),await this.generateResultField(container,this.node.specific.result),await super.init()}async generateDelayField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.specific.output.delay`;await this.generateTypedInputField(container,{id:this.elements.delay,i18n:i18n,value:value,width:"250px",typedInput:{types:["num"]}})}async generateResultField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.specific.output.result`;await this.generateTypedInputField(container,{id:this.elements.result,i18n:i18n,value:value,width:"250px",typedInput:{types:[this.generateTypedInputType(i18n,"never",{hasValue:!1}),this.generateTypedInputType(i18n,"after_command",{hasValue:!1}),this.generateTypedInputType(i18n,"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 DeconzListItemEditor extends DeconzEditor{constructor(node,listEditor,container,options={}){super(node,options),this.listEditor=listEditor,container.uniqueId(),this.uniqueId=container.attr("id"),this.container=container}set index(value){void 0!==value&&this.$elements&&this.$elements.outputButton&&this.$elements.outputButton.find(".node-input-rule-index").html(value+1),this._index=value}get index(){return this._index}async init(){await this.generateOutputButton(this.container.children().first()),await super.init()}async generateOutputButton(container){$("<a/>",{id:this.elements.outputButton,class:"red-ui-button top-right-badge"}).append(` → <span class="node-input-rule-index">${this.index+1}</span> `).appendTo(container)}}class DeconzListItemListEditor extends DeconzEditor{constructor(node,options={}){super(node,options),this.items={}}get listType(){return"item"}get buttons(){return[]}async init(mainEditor){await super.init(),this.mainEditor=mainEditor}async initList(itemEditorClass,items=[]){var buttons=this.buttons;this.$elements.list.editableList({sortable:!0,removable:!0,height:"auto",addButton:0===buttons.length,buttons:buttons,addItem:(row,index,item)=>{let itemEditor=new itemEditorClass(this.node,this,row,this.options);item.uniqueId=itemEditor.uniqueId,this.items[item.uniqueId]=itemEditor,itemEditor.init(item,index)},removeItem:item=>{if(!item.uniqueId||!this.items[item.uniqueId])throw new Error(`Error while removing the ${this.listType}, the ${this.listType} ${item.uniqueId} does not exist.`);var deletedIndex=this.items[item.uniqueId].index;delete this.items[item.uniqueId];for(const item of Object.values(this.items))item.index>deletedIndex&&item.index--},sortItems:items=>{items.each((index,item)=>{if(!this.items[item.attr("id")])throw new Error(`Error while moving the ${this.listType}, the ${this.listType} ${index+1} does not exist.`);this.items[item.attr("id")].index=index})}}),0<items.length&&this.$elements.list.editableList("addItems",items)}get value(){let result=[];for(const rule of Object.values(this.items).sort((a,b)=>a.index-b.index))result.push(rule.value);return result}refresh(){}}class DeconzOutputRuleEditor extends DeconzListItemEditor{constructor(node,listEditor,container,options={}){super(node,listEditor,container,options=$.extend({enableEachState:!0},options))}get elements(){let elements={};for(const key of["format","type","payload","output","onstart","onerror","outputButton"])elements[key]=`node-input-output-rule-${this.uniqueId}-${key}`;return elements}get value(){let value={};switch(value.type=this.$elements.type.val(),value.format=this.$elements.format.val(),value.type){case"attribute":case"state":case"config":"deconz-input"===this.node.type&&(value.output=this.$elements.output.val()),["deconz-input","deconz-battery"].includes(this.node.type)&&(value.onstart=this.$elements.onstart.is(":checked")),"deconz-input"===this.node.type&&(value.payload=this.$elements.payload.multipleSelect("getSelects"));break;case"homekit":["deconz-input","deconz-battery"].includes(this.node.type)&&(value.onstart=this.$elements.onstart.is(":checked")),"deconz-input"===this.node.type&&(value.onerror=this.$elements.onerror.is(":checked"))}return value}get defaultRule(){let rule={type:"state",payload:["__complete__"],format:"single"};return"deconz-input"===this.node.type&&(rule.output="always",rule.onstart=!0,rule.onerror=!0),"deconz-battery"===this.node.type&&(rule.onstart=!0),rule}async init(rule,index){this._index=index,rule=$.extend(!0,this.defaultRule,rule),await this.generatePayloadTypeField(this.container,rule.type),["deconz-input","deconz-get"].includes(this.node.type)&&await this.generatePayloadField(this.container),await this.generatePayloadFormatField(this.container,rule.format),"deconz-input"===this.node.type&&await this.generateOutputField(this.container,(void 0!==rule.output?rule:this.defaultRule).output),["deconz-input","deconz-battery"].includes(this.node.type)&&await this.generateOnStartField(this.container,(void 0!==rule.onstart?rule:this.defaultRule).onstart),"deconz-input"===this.node.type&&await this.generateOnErrorField(this.container,(void 0!==rule.onerror?rule:this.defaultRule).onerror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.initPayloadList(rule.payload),await this.updateShowHide(rule.type),await this.connect()}async connect(){await super.connect(),this.$elements.type.on("change",()=>{var type=this.$elements.type.val();["attribute","state","config"].includes(type)&&this.updatePayloadList(),this.updateShowHide(type)}),this.$elements.outputButton.on("click",()=>{try{let nodes=RED.nodes.filterLinks({source:this.node,sourcePort:this.index}).map(l=>{var result=l.target.type;return""!==l.target.name?result+":"+l.target.name:void 0!==l.target._def.label?result+":"+l.target._def.label():result}),myNotification=RED.notify(`The output ${this.index+1} is sending message to ${nodes.length} nodes :<br>${nodes.join("<br>")}`,{modal:!0,timeout:5e3,buttons:[{text:"okay",class:"primary",click:()=>myNotification.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(type){switch(type){case"attribute":case"state":case"config":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").hide();break;case"homekit":this.$elements.payload.closest(".form-row").hide(),this.$elements.output.closest(".form-row").hide(),this.$elements.onerror.closest(".form-row").show()}}async updatePayloadList(){this.$elements.payload.multipleSelect("disable"),this.$elements.payload.children().remove();var queryType=this.listEditor.mainEditor.subEditor.query.type,devices=this.listEditor.mainEditor.subEditor.device.value,type=this.$elements.type.val();if("homekit"!==type){var i18n=`${this.NRCD}/server:editor.inputs.outputs.payload`;let html='<option value="__complete__">'+RED._(`${i18n}.options.complete`)+"</option>";if(!0===this.options.enableEachState&&(html+='<option value="__each__">'+RED._(`${i18n}.options.each`)+"</option>"),this.$elements.payload.html(html),"device"===queryType){var data=await $.getJSON(`${this.NRCD}/${type}list`,{controllerID:this.listEditor.mainEditor.serverNode.id,devices:JSON.stringify(this.listEditor.mainEditor.subEditor.device.value)});for(const _type of"attribute"===type?["attribute","state","config"]:[type]){let groupHtml=$("<optgroup/>",{label:RED._(`${i18n}.group_label.${_type}`)});for(const item of Object.keys(data.count[_type]).sort()){let sample=data.sample[_type][item];sample="string"==typeof sample?`"${sample}"`:Array.isArray(sample)?`[${sample.toString()}]`:null===sample||void 0===sample?"NULL":sample.toString();let label;var count=data.count[_type][item];label=count===devices.length?RED._(`${i18n}.item_list`,{name:item,sample:sample}):RED._(`${i18n}.item_list_mix`,{name:item,sample:sample,item_count:count,device_count:devices.length}),$("<option>"+label+"</option>").attr("value","attribute"===type&&"attribute"!==_type?`${_type}.${item}`:item).appendTo(groupHtml)}$.isEmptyObject(data.count[_type])||groupHtml.appendTo(this.$elements.payload)}}this.$elements.payload.multipleSelect("refresh").multipleSelect("enable")}}async initPayloadList(value){let list=this.$elements.payload;list.addClass("multiple-select"),list.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:view=>{if(view.selected)switch(view.value){case"__complete__":case"__each__":list.multipleSelect("setSelects",[view.value]);break;default:list.multipleSelect("uncheck","__complete__"),list.multipleSelect("uncheck","__each__")}},onUncheckAll:()=>{list.multipleSelect("setSelects","__complete__")},onOptgroupClick:view=>{view.selected&&(list.multipleSelect("uncheck","__complete__"),list.multipleSelect("uncheck","__each__"))}}),await this.updatePayloadList(),value&&list.multipleSelect("setSelects",value)}async generatePayloadTypeField(container,value){var type,enabled,i18n=`${this.NRCD}/server:editor.inputs.outputs.type`;let choices=[];for([type,enabled]of Object.entries(this.listEditor.options.type))enabled&&choices.push([type,`${i18n}.options.${type}`]);await this.generateSimpleListField(container,{id:this.elements.type,i18n:i18n,choices:choices,currentValue:value})}async generatePayloadField(container){var i18n=`${this.NRCD}/server:editor.inputs.outputs.payload`;await this.generateSimpleListField(container,{id:this.elements.payload,i18n:i18n})}async generatePayloadFormatField(container,value){var format,enabled,i18n=`${this.NRCD}/server:editor.inputs.outputs.format`;let choices=[];for([format,enabled]of Object.entries(this.listEditor.options.format))enabled&&choices.push([format,`${i18n}.options.${format}`]);await this.generateSimpleListField(container,{id:this.elements.format,i18n:i18n,choices:choices,currentValue:value})}async generateOutputField(container,value){var i18n=`${this.NRCD}/server:editor.inputs.outputs.output`;await this.generateSimpleListField(container,{id:this.elements.output,i18n:i18n,choices:[["always",`${i18n}.options.always`],["onchange",`${i18n}.options.onchange`],["onupdate",`${i18n}.options.onupdate`]],currentValue:value})}async generateOnStartField(container,value){var i18n=`${this.NRCD}/server:editor.inputs.outputs.on_start`;await this.generateCheckboxField(container,{id:this.elements.onstart,i18n:i18n,currentValue:value})}async generateOnErrorField(container,value){var i18n=`${this.NRCD}/server:editor.inputs.outputs.on_error`;await this.generateCheckboxField(container,{id:this.elements.onerror,i18n:i18n,currentValue:value})}}class DeconzOutputRuleListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"rule"}get buttons(){let buttons=[];var type_name,i18n=`${this.NRCD}/server:editor.inputs.outputs.type`;for(const[type,enabled]of Object.entries(this.options.type))enabled&&(type_name=this.getI18n(`${i18n}.options.${type}`),buttons.push({label:this.getI18n(`${i18n}.add_button`,"label",{type:type_name}),icon:this.getIcon(this.getI18n(`${i18n}.add_button`,"icon"),!0),title:this.getI18n(`${i18n}.add_button`,"title",{type:type_name}),click:()=>this.$elements.list.editableList("addItem",{type:type})}));return buttons}async init(mainEditor){await super.init(mainEditor),await this.initList(DeconzOutputRuleEditor,this.node.output_rules)}refresh(){for(const rule of Object.values(this.items))rule.updatePayloadList()}}class DeconzCommandEditor extends DeconzListItemEditor{constructor(node,listEditor,container,options={}){super(node,listEditor,container,options=$.extend({},options)),this.containers={}}get lightKeys(){return["bri","sat","hue","ct","xy"]}get argKeys(){return["on","alert","effect","colorloopspeed","open","stop","lift","tilt","group","scene","target","command","payload","delay","transitiontime","retryonerror","aftererror"]}get elements(){let keys=this.argKeys;keys.push("typedomain"),keys.push("outputButton"),keys.push("scene_picker"),keys.push("scene_picker_refresh");for(const lightKey of this.lightKeys)keys.push(lightKey),keys.push(lightKey+"_direction");let elements={};for(const key of keys)elements[key]=`node-input-output-rule-${this.uniqueId}-${key}`;return elements}set value(command){}get value(){let value={arg:{}};value.type=this.$elements.typedomain.typedInput("type"),value.domain=this.$elements.typedomain.typedInput("value");for(const key of this.argKeys)value.arg[key]={type:this.$elements[key].typedInput("type"),value:this.$elements[key].typedInput("value")};for(const key of this.lightKeys)value.arg[key]={direction:this.$elements[key+"_direction"].typedInput("type"),type:this.$elements[key].typedInput("type"),value:this.$elements[key].typedInput("value")};return value}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_call:{type:"num"},retryonerror:{type:"num",value:0},aftererror:{type:"continue"}}}}async init(command,index){this._index=index,command=$.extend(!0,this.defaultCommand,command),await this.generateTypeDomainField(this.container,{type:command.type,value:command.domain}),this.containers.light=$("<div>").appendTo(this.container),await this.generateLightOnField(this.containers.light,command.arg.on);for(const lightType of["bri","sat","hue","ct","xy"])await this.generateLightColorField(this.containers.light,lightType,command.arg[lightType]),"bri"===lightType&&await this.generateHR(this.containers.light);await this.generateHR(this.containers.light),await this.generateLightAlertField(this.containers.light,command.arg.alert),await this.generateLightEffectField(this.containers.light,command.arg.effect),await this.generateLightColorLoopSpeedField(this.containers.light,command.arg.colorloopspeed),this.containers.windows_cover=$("<div>").appendTo(this.container),await this.generateCoverOpenField(this.containers.windows_cover,command.arg.open),await this.generateCoverStopField(this.containers.windows_cover,command.arg.stop),await this.generateCoverLiftField(this.containers.windows_cover,command.arg.lift),await this.generateCoverTiltField(this.containers.windows_cover,command.arg.tilt),this.containers.scene_call=$("<div>").appendTo(this.container),await this.generateScenePickerField(this.containers.scene_call,`${command.arg.group}.${command.arg.scene}`),await this.generateSceneGroupField(this.containers.scene_call,command.arg.group),await this.generateSceneSceneField(this.containers.scene_call,command.arg.scene),this.containers.command=$("<div>").appendTo(this.container),await this.generateTargetField(this.containers.command,command.arg.target),await this.generateCommandField(this.containers.command,command.arg.command),this.containers.payload=$("<div>").appendTo(this.container),await this.generatePayloadField(this.containers.payload,command.arg.payload),this.containers.pause=$("<div>").appendTo(this.container),await this.generatePauseDelayField(this.containers.pause,command.arg.delay),this.containers.transition=$("<div>").appendTo(this.container),await this.generateHR(this.containers.transition),await this.generateCommonTransitionTimeField(this.containers.transition,command.arg.transitiontime),this.containers.common=$("<div>").appendTo(this.container),await this.generateHR(this.containers.common),await this.generateCommonOnErrorRetryField(this.containers.common,command.arg.retryonerror),await this.generateCommonOnErrorAfterField(this.containers.common,command.arg.aftererror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.updateShowHide(command.type,command.domain),await this.connect()}async connect(){await super.connect(),this.$elements.typedomain.on("change",(event,type,value)=>{this.updateShowHide(type,value)});const updateSceneGroupSelection=()=>{let value=this.$elements.scene_picker.multipleSelect("getSelects");var parts;1===value.length&&(this.$elements.group.off("change",updateScenePickerSelection),this.$elements.scene.off("change",updateScenePickerSelection),parts=value[0].split("."),this.$elements.group.typedInput("type","num"),this.$elements.group.typedInput("value",parts[0]),this.$elements.scene.typedInput("type","num"),this.$elements.scene.typedInput("value",parts[1]),this.$elements.group.on("change",updateScenePickerSelection),this.$elements.scene.on("change",updateScenePickerSelection))},updateScenePickerSelection=()=>{this.$elements.scene_picker.off("change",updateSceneGroupSelection),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",updateSceneGroupSelection)};this.$elements.scene_picker.on("change",updateSceneGroupSelection),this.$elements.group.on("change",updateScenePickerSelection),this.$elements.scene.on("change",updateScenePickerSelection),this.$elements.scene_picker_refresh.on("click",()=>this.updateSceneList())}async updateShowHide(type,domain){let containers=[];switch(type){case"deconz_state":switch(domain){case"lights":case"groups":containers.push("light"),containers.push("transition");break;case"covers":containers.push("windows_cover");break;case"scene_call":containers.push("scene_call"),await this.updateSceneList()}containers.push("common");break;case"homekit":containers.push("payload"),containers.push("transition"),containers.push("common");break;case"custom":containers.push("command"),containers.push("payload"),containers.push("transition"),containers.push("common");break;case"pause":containers.push("pause")}for(var[key,value]of Object.entries(this.containers))value.toggle(containers.includes(key))}async updateSceneList(){this.$elements.scene_picker.multipleSelect("disable"),this.$elements.scene_picker.children().remove();let queryEditor=this.listEditor.mainEditor.subEditor.query;if(void 0!==queryEditor){let params=queryEditor.xhrParams;params.queryType="json",params.query=JSON.stringify({match:{device_type:"groups"}});var groups=await queryEditor.getItems({refresh:!0,keepOnlyMatched:!0},params);if(void 0!==groups.LightGroup){for(const group of groups.LightGroup){let groupHtml=$("<optgroup/>",{label:`${group.id} - ${group.name}`});if(group.scenes&&0<group.scenes.length){for(const scene of group.scenes)$(`<option>${scene.id} - ${scene.name}</option>`).attr("value",`${group.id}.${scene.id}`).appendTo(groupHtml);groupHtml.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(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type`;await this.generateTypedInputField(container,{id:this.elements.typedomain,i18n:i18n,value:value,addDefaultTypes:!1,typedInput:{default:"deconz_state",types:[this.generateTypedInputType(i18n,"deconz_state",{subOptions:["lights","covers","groups","scene_call"]}),this.generateTypedInputType(i18n,"homekit",{hasValue:!1}),this.generateTypedInputType(i18n,"custom",{hasValue:!1}),this.generateTypedInputType(i18n,"pause",{hasValue:!1})]}})}async generateLightOnField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.on`;await this.generateTypedInputField(container,{id:this.elements.on,i18n:i18n,value:value,typedInput:{default:"keep",types:[this.generateTypedInputType(i18n,"keep",{hasValue:!1}),this.generateTypedInputType(i18n,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i18n,"toggle",{hasValue:!1})]}})}async generateLightColorField(container,fieldName,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields`;let fieldFormat=["num"],directionsFormat=[this.generateTypedInputType(`${i18n}.lightFields`,"set",{hasValue:!1})];switch(fieldName){case"bri":fieldFormat.push("str"),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"inc",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"dec",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"detect_from_value",{hasValue:!1}));break;case"ct":fieldFormat.push("str"),fieldFormat.push(this.generateTypedInputType(`${i18n}.ct`,"deconz",{subOptions:["cold","white","warm"]})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"inc",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"dec",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"detect_from_value",{hasValue:!1}));break;case"xy":fieldFormat=["json"]}await this.generateDoubleTypedInputField(container,{id:this.elements[`${fieldName}_direction`],i18n:`${i18n}.${fieldName}`,addDefaultTypes:!1,value:{type:value.direction},typedInput:{types:directionsFormat}},{id:this.elements[fieldName],value:{type:value.type,value:["xy"===fieldName&&void 0===value.value?"[]":value.value]},typedInput:{types:fieldFormat}})}async generateLightAlertField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.alert`;await this.generateTypedInputField(container,{id:this.elements.alert,i18n:i18n,value:value,typedInput:{types:["str",this.generateTypedInputType(i18n,"deconz",{subOptions:["none","select","lselect"]})]}})}async generateLightEffectField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.effect`;await this.generateTypedInputField(container,{id:this.elements.effect,i18n:i18n,value:value,typedInput:{types:["str",this.generateTypedInputType(i18n,"deconz",{subOptions:["none","colorloop"]})]}})}async generateLightColorLoopSpeedField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.colorloopspeed`;await this.generateTypedInputField(container,{id:this.elements.colorloopspeed,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCoverOpenField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.open`;await this.generateTypedInputField(container,{id:this.elements.open,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"keep",{hasValue:!1}),this.generateTypedInputType(i18n,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i18n,"toggle",{hasValue:!1})]}})}async generateCoverStopField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.stop`;await this.generateTypedInputField(container,{id:this.elements.stop,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"keep",{hasValue:!1}),this.generateTypedInputType(i18n,"set",{subOptions:["true","false"]})]}})}async generateCoverLiftField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.lift`;await this.generateTypedInputField(container,{id:this.elements.lift,i18n:i18n,value:value,typedInput:{types:["num","str",this.generateTypedInputType(i18n,"stop",{hasValue:!1})]}})}async generateCoverTiltField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.tilt`;await this.generateTypedInputField(container,{id:this.elements.tilt,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateScenePickerField(container,value=0){var buttonElement=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.picker`;let list=await this.generateSimpleListField(container,{id:this.elements.scene_picker,i18n:buttonElement});list.addClass("multiple-select"),list.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!0,singleRadio:!0,hideOptgroupCheckboxes:!0,showClear:!0,selectAll:!1,filter:!0,filterPlaceholder:this.getI18n(buttonElement,"filter_place_holder"),placeholder:RED._(`${this.NRCD}/server:editor.multiselect.none_selected`),container:".node-input-output-container-row"});buttonElement=$("<a/>",{id:this.elements.scene_picker_refresh,class:"red-ui-button",style:"margin-left:10px;"});this.createIconElement(this.getIcon("refresh"),buttonElement),list.closest(".form-row").append(buttonElement)}async generateSceneGroupField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.group`;await this.generateTypedInputField(container,{id:this.elements.group,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateSceneSceneField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene`;await this.generateTypedInputField(container,{id:this.elements.scene,i18n:i18n,value:value,typedInput:{types:["num","str",this.generateTypedInputType(i18n,"deconz",{subOptions:["next","prev"]})]}})}async generateTargetField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.common.fields.target`;await this.generateTypedInputField(container,{id:this.elements.target,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"attribute",{hasValue:!1}),this.generateTypedInputType(i18n,"state",{hasValue:!1}),this.generateTypedInputType(i18n,"config",{hasValue:!1})]}})}async generateCommandField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.common.fields.command`;await this.generateTypedInputField(container,{id:this.elements.command,i18n:i18n,value:value,typedInput:{types:["str",this.generateTypedInputType(i18n,"object",{hasValue:!1})]}})}async generatePayloadField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.common.fields.payload`;await this.generateTypedInputField(container,{id:this.elements.payload,i18n:i18n,value:value,addDefaultTypes:!1,typedInput:{types:["msg","flow","global","str","num","bool","json","jsonata","date"]}})}async generatePauseDelayField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.pause.fields.delay`;await this.generateTypedInputField(container,{id:this.elements.delay,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCommonTransitionTimeField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.transitiontime`;await this.generateTypedInputField(container,{id:this.elements.transitiontime,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCommonOnErrorRetryField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.retryonerror`;await this.generateTypedInputField(container,{id:this.elements.retryonerror,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCommonOnErrorAfterField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.aftererror`;await this.generateTypedInputField(container,{id:this.elements.aftererror,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"continue",{hasValue:!1}),this.generateTypedInputType(i18n,"stop",{hasValue:!1})]}})}}class DeconzCommandListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"command"}get buttons(){let buttons=[];var type_name,i18n=`${this.NRCD}/server:editor.inputs.commands.type`;for(const[type,enabled]of Object.entries(this.options.type))enabled&&(type_name=this.getI18n(`${i18n}.options.${type}`,"label"),buttons.push({label:this.getI18n(`${i18n}.add_button`,"label",{type:type_name}),icon:this.getIcon(this.getI18n(`${i18n}.add_button`,"icon"),!0),title:this.getI18n(`${i18n}.add_button`,"title",{type:type_name}),click:()=>this.$elements.list.editableList("addItem",{type:type})}));return buttons}async init(mainEditor){await super.init(mainEditor),await this.initList(DeconzCommandEditor,this.node.commands)}} | ||
class DeconzEditor{constructor(node,options={}){this.node=node,this.options=options}get elements(){return{}}get NRCD(){return"node-red-contrib-deconz"}findElements(){this.$elements={},Object.keys(this.elements).forEach(k=>{this.$elements[k]=this.findElement(this.elements[k])})}findElement(identifier){return"#"!==identifier.charAt(0)&&"."!==identifier.charAt(0)&&(identifier="#"+identifier),$(identifier)}async init(){this.findElements()}async connect(){}sendError(msg,timeout=1e4){let myNotification=RED.notify(msg,{timeout:timeout,type:"error",buttons:[{text:"okay",class:"primary",click:()=>myNotification.close()}]})}getIcon(icon,includeClass=!1){return"deconz"===icon?"icons/node-red-contrib-deconz/icon-color.png":"homekit"===icon?"icons/node-red-contrib-deconz/homekit-logo.png":RED.nodes.fontAwesome.getIconList().includes(`fa-${icon}`)?`${includeClass?"fa ":""}fa-${icon}`:icon}createIconElement(icon,container,isLarge=!1){if("fa-"===icon.substr(0,3)){if(RED.nodes.fontAwesome.getIconUnicode(icon)){let faIconElement=$("<i/>").appendTo(container);return void faIconElement.addClass("fa "+icon+(isLarge?" fa-lg":""))}icon=RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"}let imageIconElement=$("<div/>").appendTo(container);imageIconElement.css("backgroundImage","url("+icon+")")}getI18n(prefix,suffix,value={}){let _path=prefix;suffix&&(_path+=`.${suffix}`),value.defaultValue="__undefined__";value=RED._(_path,value);if("__undefined__"!==value)return value}async generateSimpleListField(container,options){let input=$("<select/>",{id:options.id});if(options.choices)for(var[key,value]of options.choices)input.append($("<option/>").attr("value",key).html(RED._(value)));var row=await this.generateInputWithLabel(input,options);return container.append(row),void 0!==options.currentValue&&input.val(options.currentValue),input}async generateTypedInput(container,inputType){let input=$("<input/>",{id:inputType.id,placeholder:RED._(inputType.placeholder)});inputType=$("<input/>",{id:`${inputType.id}_type`,type:"hidden"});return input.append(inputType),input}async initTypedInput(input,options){options=$.extend({addDefaultTypes:!0,displayOnlyIcon:!1,value:{},width:"200px"},options);let typedInputOptions=$.extend({types:["msg","flow","global"]},options.typedInput);if(typedInputOptions.typeField=options.typeId,options.addDefaultTypes&&(typedInputOptions.types.push("msg"),typedInputOptions.types.push("flow"),typedInputOptions.types.push("global"),typedInputOptions.types.push("jsonata")),options.displayOnlyIcon){let that=this;function valueLabel(a,b){let typeDefinition;for(const type of this.typeList)"object"==typeof type&&type.value===this.propertyType&&(typeDefinition=type);void 0!==typeDefinition&&void 0!==typeDefinition.icon&&(this.oldValue=this.input.val(),this.input.val(""),this.valueLabelContainer.hide(),that.createIconElement(typeDefinition.icon,this.selectLabel),this.selectTrigger.addClass("red-ui-typedInput-full-width"),this.selectLabel.show())}var type;for(type of typedInputOptions.types)"string"!=typeof type&&(type.hasValue=!0,type.valueLabel=valueLabel)}input.typedInput(typedInputOptions),void 0!==options.width&&input.typedInput("width",options.width),options.value&&(void 0!==options.value.type&&input.typedInput("type",options.value.type),void 0!==options.value.value&&input.typedInput("value",options.value.value))}async generateTypedInputField(container,options){var input=await this.generateTypedInput(container,{id:options.id,placeholder:this.getI18n(options.i18n,"placeholder")}),row=await this.generateInputWithLabel(input,options);return container.append(row),await this.initTypedInput(input,options),input}async generateDoubleTypedInputField(container,optionsFirst,optionsSecond){var inputFirst=await this.generateTypedInput(container,optionsFirst);let row=await this.generateInputWithLabel(inputFirst,optionsFirst);var inputSecond=await this.generateTypedInput(container,optionsSecond);row.append(inputSecond),container.append(row),optionsFirst.displayOnlyIcon=!0,optionsFirst.width="50px",optionsSecond.width="150px",await this.initTypedInput(inputFirst,optionsFirst),await this.initTypedInput(inputSecond,optionsSecond)}generateTypedInputType(i18n,name,data={}){if(data.value=name,void 0===data.label&&(data.label=this.getI18n(i18n,`options.${name}.label`,{})||name),!1!==data.icon&&void 0===data.icon&&(data.icon=this.getIcon(this.getI18n(i18n,`options.${name}.icon`))),data.icon&&"fa-"===data.icon.substr(0,3)&&(data.icon="fa "+data.icon),Array.isArray(data.subOptions)){Array.isArray(data.options)||(data.options=[]);for(const opt of data.subOptions)data.options.push(this.generateTypedInputType(`${i18n}.options.${name}`,"string"==typeof opt?opt:opt.name,{icon:!1}))}return data}async generateCheckboxField(container,options){var input=$("<input/>",{id:options.id,type:"checkbox",style:"display: table-cell; width: 14px;vertical-align: top;margin-right: 5px",checked:options.currentValue});let row=await this.generateInputWithLabel(input,options);row.append($("<span/>").html(RED._(options.descText)).css("display","table-cell")),container.append(row)}async generateInputWithLabel(input,options={}){let row=$("<div/>",{class:"form-row",style:"padding:5px;margin:0;display:table;min-width:420px;"});var inputID=input.attr("id");if(inputID){let labelElement=$("<label/>");labelElement.attr("for",inputID),labelElement.attr("class","l-width"),labelElement.attr("style","display:table-cell;"),void 0===options.title&&(options.title=this.getI18n(options.i18n,"title")),options.title&&labelElement.attr("title",this.getI18n(options.i18n,"title")),void 0===options.icon&&(options.icon=this.getI18n(options.i18n,"icon")),options.icon&&(this.createIconElement(this.getIcon(options.icon),labelElement),labelElement.append(" ")),void 0===options.label&&(options.label=this.getI18n(options.i18n,"label")),options.label&&labelElement.append(`<span>${options.label}</span>`),row.append(labelElement)}return input.css("display","table-cell"),row.append(input),row}async generateHR(container,topBottom="5px",leftRight="50px"){container.append(`<hr style="margin: ${topBottom} ${leftRight};">`)}async generateSeparator(container,label){container.append(`<div class="separator">${RED._(label)}</div>`)}}class DeconzMainEditor extends DeconzEditor{constructor(node,options={}){super(node,$.extend(!0,{have:{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}},commands:{type:{deconz_state:!0,homekit:!0,custom:!0,pause:!0}},specific:{output:{}}},options)),this.subEditor={},this.initDone=!1,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&&"deconz-output"===this.node.type&&(this.subEditor.specific=new DeconzSpecificOutputEditor(this.node,this.options.specific.output)),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{server:"node-input-server"}}async configurationMigration(){if(!((this.node.config_version||0)>=this.node._def.defaults.config_version.value)){let config={};for(const key of Object.keys(this.node._def.defaults))config[key]=this.node[key];var data={type:this.node.type,config:JSON.stringify(config)};let errorMsg="Error while migrating the configuration of the node from version "+(this.node.config_version||0)+" to version "+this.node._def.defaults.config_version.value+".",result=await $.getJSON(`${this.NRCD}/configurationMigration`,data).catch((t,u)=>{this.sendError(errorMsg)});if(result&&!result.notNeeded){if(result.new)for(var[key,value]of Object.entries(result.new))this.node[key]=value;if(result.delete&&Array.isArray(result.delete))for(const key of result.delete)delete this.node[key];result.errors&&Array.isArray(result.errors)&&0<result.errors.length&&this.sendError(errorMsg+"<br><li>"+result.errors.join("</li><li>")+"</li>")}}}async init(){await new Promise(resolve=>setTimeout(resolve,100)),await this.configurationMigration(),await super.init(),this.serverNode=RED.nodes.node(this.$elements.server.val()),this.initPromises=[];for(const editor of Object.values(this.subEditor))this.initPromises.push(editor.init(this));await Promise.all(this.initPromises),this.initDone=!0,delete this.initPromises;let connectPromises=[];for(const editor of Object.values(this.subEditor))connectPromises.push(editor.connect());await Promise.all(connectPromises)}async isInitialized(){this.initDone||await Promise.all(this.initPromises)}async updateQueryDeviceDisplay(options){var type=this.subEditor.query.$elements.select.typedInput("type");switch(type){case"device":await this.subEditor.device.updateList(options);break;case"json":case"jsonata":this.subEditor.query.$elements.select.typedInput("validate")&&await this.subEditor.query.updateList(options)}await this.subEditor.device.display("device"===type),await this.subEditor.query.display("device"!==type)}oneditsave(){var newRules;this.options.have.output_rules&&(newRules=this.subEditor.output_rules.value,this.node.outputs=newRules.length,this.node.output_rules=newRules),this.options.have.commands&&(this.node.commands=this.subEditor.commands.value),this.options.have.specific&&(this.node.specific=this.subEditor.specific.value)}}class DeconzDeviceListEditor extends DeconzEditor{constructor(node,options={}){super(node,options)}get xhrURL(){return`${this.NRCD}/itemlist`}get xhrParams(){return{controllerID:this.mainEditor.serverNode.id,forceRefresh:this.options.refresh}}async display(display=!0){if(this.$elements.showHide)return display?this.$elements.showHide.show():this.$elements.showHide.hide(),this.$elements.showHide.promise()}async getItems(options,result){result.forceRefresh=options.refresh;result=await $.getJSON(this.xhrURL,result).catch((t,u)=>{this.sendError(400===t.status&&t.responseText?t.responseText:u.toString())});if(!result||!result.error_message)return this.formatItemList(result.items,options.keepOnlyMatched);console.warn(result.error_message)}async updateList(devices){devices=$.extend({refresh:!0},devices);let list=this.$elements.list,params=this.xhrParams;!0===this.options.batteryFilter&&(devices.keepOnlyMatched=!0,params.query=JSON.stringify({type:"match",match:{"config.battery":{type:"complex",operator:"!==",value:void 0}}}));devices=await this.getItems(devices,params);list.children().remove(),devices&&this.generateHtmlItemList(devices,this.$elements.list),list.multipleSelect("refresh"),devices&&list.multipleSelect("enable")}formatItemList(items,keepOnlyMatched=!1){let itemList={};var injectItems=(part,matched)=>{part.forEach(item=>{var device_type=item.type;void 0===itemList[device_type]&&(itemList[device_type]=[]),item.query_match=matched,itemList[device_type].push(item)})};return injectItems(items.matched,!0),!1===keepOnlyMatched&&injectItems(items.rejected,!1),itemList}generateHtmlItemList(items,htmlContainer){var group_key,item_list,queryMode=this.constructor===DeconzQueryEditor;for([group_key,item_list]of Object.entries(items).sort((x,y)=>{x=x[0].toLowerCase(),y=y[0].toLowerCase();return x<y?-1:y<x?1:0})){let groupHtml=$("<optgroup/>").attr("label",group_key);for(const item of item_list.sort((x,y)=>{x=x.name.toLowerCase(),y=y.name.toLowerCase();return x<y?-1:y<x?1:0})){let label=item.name;"groups"===item.device_type&&(label+=" (lights: "+item.lights.length,item.scenes.length&&(label+=", scenes: "+item.scenes.length),label+=")");let opt=$("<option>"+label+"</option>").attr("value",item.device_path);queryMode&&item.query_match&&opt.attr("selected",""),opt.appendTo(groupHtml)}groupHtml.appendTo(htmlContainer)}}}class DeconzQueryEditor extends DeconzDeviceListEditor{constructor(node,options={}){super(node,$.extend({allowedTypes:["json","jsonata"]},options))}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(val){this.$elements.list.typedInput("type",val)}get value(){return this.$elements.select.typedInput("value")}set value(val){this.$elements.list.typedInput("value",val)}get xhrParams(){let params=super.xhrParams;return params.query=this.value,params.queryType=this.type,params.nodeID=this.node.id,params}async init(mainEditor){await super.init(),this.mainEditor=mainEditor,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:view=>{this.$elements.list.multipleSelect(view.selected?"uncheck":"check",view.value)}}),await this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0})}initTypedInput(){let options=[];this.mainEditor.options.have.device&&options.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:options.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.subEditor.output_rules.refresh()}),this.$elements.refreshButton.on("click",()=>{this.updateList(),this.mainEditor.subEditor.output_rules.refresh()})}}class DeconzDeviceEditor extends DeconzDeviceListEditor{constructor(node,options={}){super(node,$.extend({batteryFilter:!1},options))}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(val){this.$elements.list.multipleSelect("setSelects",val)}async init(mainEditor){await super.init(),this.mainEditor=mainEditor,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(),this.$elements.refreshButton.on("click",()=>{this.updateList($.extend(this.options,{useSelectedData:!0})),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()}),this.mainEditor.options.have.output_rules&&this.$elements.list.on("change",()=>{this.mainEditor.subEditor.output_rules.refresh()})}async updateList(options){let itemsSelected;(options=$.extend({useSavedData:!1,useSelectedData:!1},options)).useSelectedData&&(itemsSelected=this.$elements.list.multipleSelect("getSelects")),await super.updateList(options),options.useSavedData&&Array.isArray(this.node.device_list)?this.$elements.list.multipleSelect("setSelects",this.node.device_list):options.useSelectedData&&Array.isArray(itemsSelected)&&this.$elements.list.multipleSelect("setSelects",itemsSelected)}}class DeconzSpecificOutputEditor extends DeconzEditor{constructor(node,options={}){super(node,$.extend({},options))}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 container=this.findElement(this.elements.container);await this.generateSeparator(container,`${this.NRCD}/server:editor.inputs.separator.specific`),await this.generateDelayField(container,this.node.specific.delay),await this.generateResultField(container,this.node.specific.result),await super.init()}async generateDelayField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.specific.output.delay`;await this.generateTypedInputField(container,{id:this.elements.delay,i18n:i18n,value:value,width:"250px",typedInput:{types:["num"]}})}async generateResultField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.specific.output.result`;await this.generateTypedInputField(container,{id:this.elements.result,i18n:i18n,value:value,width:"250px",typedInput:{types:[this.generateTypedInputType(i18n,"never",{hasValue:!1}),this.generateTypedInputType(i18n,"after_command",{hasValue:!1}),this.generateTypedInputType(i18n,"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 DeconzListItemEditor extends DeconzEditor{constructor(node,listEditor,container,options={}){super(node,options),this.listEditor=listEditor,container.uniqueId(),this.uniqueId=container.attr("id"),this.container=container}set index(value){void 0!==value&&this.$elements&&this.$elements.outputButton&&this.$elements.outputButton.find(".node-input-rule-index").html(value+1),this._index=value}get index(){return this._index}async init(){await this.generateOutputButton(this.container.children().first()),await super.init()}async generateOutputButton(container){$("<a/>",{id:this.elements.outputButton,class:"red-ui-button top-right-badge"}).append(` → <span class="node-input-rule-index">${this.index+1}</span> `).appendTo(container)}}class DeconzListItemListEditor extends DeconzEditor{constructor(node,options={}){super(node,options),this.items={}}get listType(){return"item"}get buttons(){return[]}async init(mainEditor){await super.init(),this.mainEditor=mainEditor}async initList(itemEditorClass,items=[]){var buttons=this.buttons;this.$elements.list.editableList({sortable:!0,removable:!0,height:"auto",addButton:0===buttons.length,buttons:buttons,addItem:(row,index,item)=>{let itemEditor=new itemEditorClass(this.node,this,row,this.options);item.uniqueId=itemEditor.uniqueId,this.items[item.uniqueId]=itemEditor,itemEditor.init(item,index)},removeItem:item=>{if(!item.uniqueId||!this.items[item.uniqueId])throw new Error(`Error while removing the ${this.listType}, the ${this.listType} ${item.uniqueId} does not exist.`);var deletedIndex=this.items[item.uniqueId].index;delete this.items[item.uniqueId];for(const item of Object.values(this.items))item.index>deletedIndex&&item.index--},sortItems:items=>{items.each((index,item)=>{if(!this.items[item.attr("id")])throw new Error(`Error while moving the ${this.listType}, the ${this.listType} ${index+1} does not exist.`);this.items[item.attr("id")].index=index})}}),0<items.length&&this.$elements.list.editableList("addItems",items)}get value(){let result=[];for(const rule of Object.values(this.items).sort((a,b)=>a.index-b.index))result.push(rule.value);return result}refresh(){}}class DeconzOutputRuleEditor extends DeconzListItemEditor{constructor(node,listEditor,container,options={}){super(node,listEditor,container,options=$.extend({enableEachState:!0},options))}get elements(){let elements={};for(const key of["format","type","payload","output","onstart","onerror","outputButton"])elements[key]=`node-input-output-rule-${this.uniqueId}-${key}`;return elements}get value(){let value={};switch(value.type=this.$elements.type.val(),value.format=this.$elements.format.val(),value.type){case"attribute":case"state":case"config":"deconz-input"===this.node.type&&(value.output=this.$elements.output.val()),["deconz-input","deconz-battery"].includes(this.node.type)&&(value.onstart=this.$elements.onstart.is(":checked")),["deconz-input","deconz-get"].includes(this.node.type)&&(value.payload=this.$elements.payload.multipleSelect("getSelects"));break;case"homekit":["deconz-input","deconz-battery"].includes(this.node.type)&&(value.onstart=this.$elements.onstart.is(":checked")),"deconz-input"===this.node.type&&(value.onerror=this.$elements.onerror.is(":checked"))}return value}get defaultRule(){let rule={type:"state",payload:["__complete__"],format:"single"};return"deconz-input"===this.node.type&&(rule.output="always",rule.onstart=!0,rule.onerror=!0),"deconz-battery"===this.node.type&&(rule.onstart=!0),rule}async init(rule,index){this._index=index,rule=$.extend(!0,this.defaultRule,rule),await this.generatePayloadTypeField(this.container,rule.type),["deconz-input","deconz-get"].includes(this.node.type)&&await this.generatePayloadField(this.container),await this.generatePayloadFormatField(this.container,rule.format),"deconz-input"===this.node.type&&await this.generateOutputField(this.container,(void 0!==rule.output?rule:this.defaultRule).output),["deconz-input","deconz-battery"].includes(this.node.type)&&await this.generateOnStartField(this.container,(void 0!==rule.onstart?rule:this.defaultRule).onstart),"deconz-input"===this.node.type&&await this.generateOnErrorField(this.container,(void 0!==rule.onerror?rule:this.defaultRule).onerror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.initPayloadList(rule.payload),await this.updateShowHide(rule.type),await this.connect()}async connect(){await super.connect(),this.$elements.type.on("change",()=>{var type=this.$elements.type.val();["attribute","state","config"].includes(type)&&this.updatePayloadList(),this.updateShowHide(type)}),this.$elements.outputButton.on("click",()=>{try{let nodes=RED.nodes.filterLinks({source:this.node,sourcePort:this.index}).map(l=>{var result=l.target.type;return""!==l.target.name?result+":"+l.target.name:void 0!==l.target._def.label?result+":"+l.target._def.label():result}),myNotification=RED.notify(`The output ${this.index+1} is sending message to ${nodes.length} nodes :<br>${nodes.join("<br>")}`,{modal:!0,timeout:5e3,buttons:[{text:"okay",class:"primary",click:()=>myNotification.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(type){switch(type){case"attribute":case"state":case"config":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").hide();break;case"homekit":this.$elements.payload.closest(".form-row").hide(),this.$elements.output.closest(".form-row").hide(),this.$elements.onerror.closest(".form-row").show()}}async updatePayloadList(){this.$elements.payload.multipleSelect("disable"),this.$elements.payload.children().remove();var queryType=this.listEditor.mainEditor.subEditor.query.type,devices=this.listEditor.mainEditor.subEditor.device.value,type=this.$elements.type.val();if("homekit"!==type){var i18n=`${this.NRCD}/server:editor.inputs.outputs.payload`;let html='<option value="__complete__">'+RED._(`${i18n}.options.complete`)+"</option>";if(!0===this.options.enableEachState&&(html+='<option value="__each__">'+RED._(`${i18n}.options.each`)+"</option>"),this.$elements.payload.html(html),"device"===queryType){var data=await $.getJSON(`${this.NRCD}/${type}list`,{controllerID:this.listEditor.mainEditor.serverNode.id,devices:JSON.stringify(this.listEditor.mainEditor.subEditor.device.value)});for(const _type of"attribute"===type?["attribute","state","config"]:[type]){let groupHtml=$("<optgroup/>",{label:RED._(`${i18n}.group_label.${_type}`)});for(const item of Object.keys(data.count[_type]).sort()){let sample=data.sample[_type][item];sample="string"==typeof sample?`"${sample}"`:Array.isArray(sample)?`[${sample.toString()}]`:null===sample||void 0===sample?"NULL":sample.toString();let label;var count=data.count[_type][item];label=count===devices.length?RED._(`${i18n}.item_list`,{name:item,sample:sample}):RED._(`${i18n}.item_list_mix`,{name:item,sample:sample,item_count:count,device_count:devices.length}),$("<option>"+label+"</option>").attr("value","attribute"===type&&"attribute"!==_type?`${_type}.${item}`:item).appendTo(groupHtml)}$.isEmptyObject(data.count[_type])||groupHtml.appendTo(this.$elements.payload)}}this.$elements.payload.multipleSelect("refresh").multipleSelect("enable")}}async initPayloadList(value){let list=this.$elements.payload;list.addClass("multiple-select"),list.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:view=>{if(view.selected)switch(view.value){case"__complete__":case"__each__":list.multipleSelect("setSelects",[view.value]);break;default:list.multipleSelect("uncheck","__complete__"),list.multipleSelect("uncheck","__each__")}},onUncheckAll:()=>{list.multipleSelect("setSelects","__complete__")},onOptgroupClick:view=>{view.selected&&(list.multipleSelect("uncheck","__complete__"),list.multipleSelect("uncheck","__each__"))}}),await this.updatePayloadList(),value&&list.multipleSelect("setSelects",value)}async generatePayloadTypeField(container,value){var type,enabled,i18n=`${this.NRCD}/server:editor.inputs.outputs.type`;let choices=[];for([type,enabled]of Object.entries(this.listEditor.options.type))enabled&&choices.push([type,`${i18n}.options.${type}`]);await this.generateSimpleListField(container,{id:this.elements.type,i18n:i18n,choices:choices,currentValue:value})}async generatePayloadField(container){var i18n=`${this.NRCD}/server:editor.inputs.outputs.payload`;await this.generateSimpleListField(container,{id:this.elements.payload,i18n:i18n})}async generatePayloadFormatField(container,value){var format,enabled,i18n=`${this.NRCD}/server:editor.inputs.outputs.format`;let choices=[];for([format,enabled]of Object.entries(this.listEditor.options.format))enabled&&choices.push([format,`${i18n}.options.${format}`]);await this.generateSimpleListField(container,{id:this.elements.format,i18n:i18n,choices:choices,currentValue:value})}async generateOutputField(container,value){var i18n=`${this.NRCD}/server:editor.inputs.outputs.output`;await this.generateSimpleListField(container,{id:this.elements.output,i18n:i18n,choices:[["always",`${i18n}.options.always`],["onchange",`${i18n}.options.onchange`],["onupdate",`${i18n}.options.onupdate`]],currentValue:value})}async generateOnStartField(container,value){var i18n=`${this.NRCD}/server:editor.inputs.outputs.on_start`;await this.generateCheckboxField(container,{id:this.elements.onstart,i18n:i18n,currentValue:value})}async generateOnErrorField(container,value){var i18n=`${this.NRCD}/server:editor.inputs.outputs.on_error`;await this.generateCheckboxField(container,{id:this.elements.onerror,i18n:i18n,currentValue:value})}}class DeconzOutputRuleListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"rule"}get buttons(){let buttons=[];var type_name,i18n=`${this.NRCD}/server:editor.inputs.outputs.type`;for(const[type,enabled]of Object.entries(this.options.type))enabled&&(type_name=this.getI18n(`${i18n}.options.${type}`),buttons.push({label:this.getI18n(`${i18n}.add_button`,"label",{type:type_name}),icon:this.getIcon(this.getI18n(`${i18n}.add_button`,"icon"),!0),title:this.getI18n(`${i18n}.add_button`,"title",{type:type_name}),click:()=>this.$elements.list.editableList("addItem",{type:type})}));return buttons}async init(mainEditor){await super.init(mainEditor),await this.initList(DeconzOutputRuleEditor,this.node.output_rules)}refresh(){for(const rule of Object.values(this.items))rule.updatePayloadList()}}class DeconzCommandEditor extends DeconzListItemEditor{constructor(node,listEditor,container,options={}){super(node,listEditor,container,options=$.extend({},options)),this.containers={}}get lightKeys(){return["bri","sat","hue","ct","xy"]}get argKeys(){return["on","alert","effect","colorloopspeed","open","stop","lift","tilt","group","scene","target","command","payload","delay","transitiontime","retryonerror","aftererror"]}get elements(){let keys=this.argKeys;keys.push("typedomain"),keys.push("outputButton"),keys.push("scene_picker"),keys.push("scene_picker_refresh");for(const lightKey of this.lightKeys)keys.push(lightKey),keys.push(lightKey+"_direction");let elements={};for(const key of keys)elements[key]=`node-input-output-rule-${this.uniqueId}-${key}`;return elements}set value(command){}get value(){let value={arg:{}};value.type=this.$elements.typedomain.typedInput("type"),value.domain=this.$elements.typedomain.typedInput("value");for(const key of this.argKeys)value.arg[key]={type:this.$elements[key].typedInput("type"),value:this.$elements[key].typedInput("value")};for(const key of this.lightKeys)value.arg[key]={direction:this.$elements[key+"_direction"].typedInput("type"),type:this.$elements[key].typedInput("type"),value:this.$elements[key].typedInput("value")};return value}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_call:{type:"num"},retryonerror:{type:"num",value:0},aftererror:{type:"continue"}}}}async init(command,index){this._index=index,command=$.extend(!0,this.defaultCommand,command),await this.generateTypeDomainField(this.container,{type:command.type,value:command.domain}),this.containers.light=$("<div>").appendTo(this.container),await this.generateLightOnField(this.containers.light,command.arg.on);for(const lightType of["bri","sat","hue","ct","xy"])await this.generateLightColorField(this.containers.light,lightType,command.arg[lightType]),"bri"===lightType&&await this.generateHR(this.containers.light);await this.generateHR(this.containers.light),await this.generateLightAlertField(this.containers.light,command.arg.alert),await this.generateLightEffectField(this.containers.light,command.arg.effect),await this.generateLightColorLoopSpeedField(this.containers.light,command.arg.colorloopspeed),this.containers.windows_cover=$("<div>").appendTo(this.container),await this.generateCoverOpenField(this.containers.windows_cover,command.arg.open),await this.generateCoverStopField(this.containers.windows_cover,command.arg.stop),await this.generateCoverLiftField(this.containers.windows_cover,command.arg.lift),await this.generateCoverTiltField(this.containers.windows_cover,command.arg.tilt),this.containers.scene_call=$("<div>").appendTo(this.container),await this.generateScenePickerField(this.containers.scene_call,`${command.arg.group}.${command.arg.scene}`),await this.generateSceneGroupField(this.containers.scene_call,command.arg.group),await this.generateSceneSceneField(this.containers.scene_call,command.arg.scene),this.containers.command=$("<div>").appendTo(this.container),await this.generateTargetField(this.containers.command,command.arg.target),await this.generateCommandField(this.containers.command,command.arg.command),this.containers.payload=$("<div>").appendTo(this.container),await this.generatePayloadField(this.containers.payload,command.arg.payload),this.containers.pause=$("<div>").appendTo(this.container),await this.generatePauseDelayField(this.containers.pause,command.arg.delay),this.containers.transition=$("<div>").appendTo(this.container),await this.generateHR(this.containers.transition),await this.generateCommonTransitionTimeField(this.containers.transition,command.arg.transitiontime),this.containers.common=$("<div>").appendTo(this.container),await this.generateHR(this.containers.common),await this.generateCommonOnErrorRetryField(this.containers.common,command.arg.retryonerror),await this.generateCommonOnErrorAfterField(this.containers.common,command.arg.aftererror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.updateShowHide(command.type,command.domain),await this.connect()}async connect(){await super.connect(),this.$elements.typedomain.on("change",(event,type,value)=>{this.updateShowHide(type,value)});const updateSceneGroupSelection=()=>{let value=this.$elements.scene_picker.multipleSelect("getSelects");var parts;1===value.length&&(this.$elements.group.off("change",updateScenePickerSelection),this.$elements.scene.off("change",updateScenePickerSelection),parts=value[0].split("."),this.$elements.group.typedInput("type","num"),this.$elements.group.typedInput("value",parts[0]),this.$elements.scene.typedInput("type","num"),this.$elements.scene.typedInput("value",parts[1]),this.$elements.group.on("change",updateScenePickerSelection),this.$elements.scene.on("change",updateScenePickerSelection))},updateScenePickerSelection=()=>{this.$elements.scene_picker.off("change",updateSceneGroupSelection),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",updateSceneGroupSelection)};this.$elements.scene_picker.on("change",updateSceneGroupSelection),this.$elements.group.on("change",updateScenePickerSelection),this.$elements.scene.on("change",updateScenePickerSelection),this.$elements.scene_picker_refresh.on("click",()=>this.updateSceneList())}async updateShowHide(type,domain){let containers=[];switch(type){case"deconz_state":switch(domain){case"lights":case"groups":containers.push("light"),containers.push("transition");break;case"covers":containers.push("windows_cover");break;case"scene_call":containers.push("scene_call"),await this.updateSceneList()}containers.push("common");break;case"homekit":containers.push("payload"),containers.push("transition"),containers.push("common");break;case"custom":containers.push("command"),containers.push("payload"),containers.push("transition"),containers.push("common");break;case"pause":containers.push("pause")}for(var[key,value]of Object.entries(this.containers))value.toggle(containers.includes(key))}async updateSceneList(){this.$elements.scene_picker.multipleSelect("disable"),this.$elements.scene_picker.children().remove();let queryEditor=this.listEditor.mainEditor.subEditor.query;if(void 0!==queryEditor){let params=queryEditor.xhrParams;params.queryType="json",params.query=JSON.stringify({match:{device_type:"groups"}});var groups=await queryEditor.getItems({refresh:!0,keepOnlyMatched:!0},params);if(void 0!==groups.LightGroup){for(const group of groups.LightGroup){let groupHtml=$("<optgroup/>",{label:`${group.id} - ${group.name}`});if(group.scenes&&0<group.scenes.length){for(const scene of group.scenes)$(`<option>${scene.id} - ${scene.name}</option>`).attr("value",`${group.id}.${scene.id}`).appendTo(groupHtml);groupHtml.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(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type`;await this.generateTypedInputField(container,{id:this.elements.typedomain,i18n:i18n,value:value,addDefaultTypes:!1,typedInput:{default:"deconz_state",types:[this.generateTypedInputType(i18n,"deconz_state",{subOptions:["lights","covers","groups","scene_call"]}),this.generateTypedInputType(i18n,"homekit",{hasValue:!1}),this.generateTypedInputType(i18n,"custom",{hasValue:!1}),this.generateTypedInputType(i18n,"pause",{hasValue:!1})]}})}async generateLightOnField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.on`;await this.generateTypedInputField(container,{id:this.elements.on,i18n:i18n,value:value,typedInput:{default:"keep",types:[this.generateTypedInputType(i18n,"keep",{hasValue:!1}),this.generateTypedInputType(i18n,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i18n,"toggle",{hasValue:!1})]}})}async generateLightColorField(container,fieldName,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields`;let fieldFormat=["num"],directionsFormat=[this.generateTypedInputType(`${i18n}.lightFields`,"set",{hasValue:!1})];switch(fieldName){case"bri":fieldFormat.push("str"),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"inc",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"dec",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"detect_from_value",{hasValue:!1}));break;case"ct":fieldFormat.push("str"),fieldFormat.push(this.generateTypedInputType(`${i18n}.ct`,"deconz",{subOptions:["cold","white","warm"]})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"inc",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"dec",{hasValue:!1})),directionsFormat.push(this.generateTypedInputType(`${i18n}.lightFields`,"detect_from_value",{hasValue:!1}));break;case"xy":fieldFormat=["json"]}await this.generateDoubleTypedInputField(container,{id:this.elements[`${fieldName}_direction`],i18n:`${i18n}.${fieldName}`,addDefaultTypes:!1,value:{type:value.direction},typedInput:{types:directionsFormat}},{id:this.elements[fieldName],value:{type:value.type,value:["xy"===fieldName&&void 0===value.value?"[]":value.value]},typedInput:{types:fieldFormat}})}async generateLightAlertField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.alert`;await this.generateTypedInputField(container,{id:this.elements.alert,i18n:i18n,value:value,typedInput:{types:["str",this.generateTypedInputType(i18n,"deconz",{subOptions:["none","select","lselect"]})]}})}async generateLightEffectField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.effect`;await this.generateTypedInputField(container,{id:this.elements.effect,i18n:i18n,value:value,typedInput:{types:["str",this.generateTypedInputType(i18n,"deconz",{subOptions:["none","colorloop"]})]}})}async generateLightColorLoopSpeedField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.colorloopspeed`;await this.generateTypedInputField(container,{id:this.elements.colorloopspeed,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCoverOpenField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.open`;await this.generateTypedInputField(container,{id:this.elements.open,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"keep",{hasValue:!1}),this.generateTypedInputType(i18n,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i18n,"toggle",{hasValue:!1})]}})}async generateCoverStopField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.stop`;await this.generateTypedInputField(container,{id:this.elements.stop,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"keep",{hasValue:!1}),this.generateTypedInputType(i18n,"set",{subOptions:["true","false"]})]}})}async generateCoverLiftField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.lift`;await this.generateTypedInputField(container,{id:this.elements.lift,i18n:i18n,value:value,typedInput:{types:["num","str",this.generateTypedInputType(i18n,"stop",{hasValue:!1})]}})}async generateCoverTiltField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.tilt`;await this.generateTypedInputField(container,{id:this.elements.tilt,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateScenePickerField(container,value=0){var buttonElement=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.picker`;let list=await this.generateSimpleListField(container,{id:this.elements.scene_picker,i18n:buttonElement});list.addClass("multiple-select"),list.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!0,singleRadio:!0,hideOptgroupCheckboxes:!0,showClear:!0,selectAll:!1,filter:!0,filterPlaceholder:this.getI18n(buttonElement,"filter_place_holder"),placeholder:RED._(`${this.NRCD}/server:editor.multiselect.none_selected`),container:".node-input-output-container-row"});buttonElement=$("<a/>",{id:this.elements.scene_picker_refresh,class:"red-ui-button",style:"margin-left:10px;"});this.createIconElement(this.getIcon("refresh"),buttonElement),list.closest(".form-row").append(buttonElement)}async generateSceneGroupField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.group`;await this.generateTypedInputField(container,{id:this.elements.group,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateSceneSceneField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene`;await this.generateTypedInputField(container,{id:this.elements.scene,i18n:i18n,value:value,typedInput:{types:["num","str",this.generateTypedInputType(i18n,"deconz",{subOptions:["next","prev"]})]}})}async generateTargetField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.common.fields.target`;await this.generateTypedInputField(container,{id:this.elements.target,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"attribute",{hasValue:!1}),this.generateTypedInputType(i18n,"state",{hasValue:!1}),this.generateTypedInputType(i18n,"config",{hasValue:!1})]}})}async generateCommandField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.common.fields.command`;await this.generateTypedInputField(container,{id:this.elements.command,i18n:i18n,value:value,typedInput:{types:["str",this.generateTypedInputType(i18n,"object",{hasValue:!1})]}})}async generatePayloadField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.common.fields.payload`;await this.generateTypedInputField(container,{id:this.elements.payload,i18n:i18n,value:value,addDefaultTypes:!1,typedInput:{types:["msg","flow","global","str","num","bool","json","jsonata","date"]}})}async generatePauseDelayField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.pause.fields.delay`;await this.generateTypedInputField(container,{id:this.elements.delay,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCommonTransitionTimeField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.transitiontime`;await this.generateTypedInputField(container,{id:this.elements.transitiontime,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCommonOnErrorRetryField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.retryonerror`;await this.generateTypedInputField(container,{id:this.elements.retryonerror,i18n:i18n,value:value,typedInput:{types:["num"]}})}async generateCommonOnErrorAfterField(container,value={}){var i18n=`${this.NRCD}/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.aftererror`;await this.generateTypedInputField(container,{id:this.elements.aftererror,i18n:i18n,value:value,typedInput:{types:[this.generateTypedInputType(i18n,"continue",{hasValue:!1}),this.generateTypedInputType(i18n,"stop",{hasValue:!1})]}})}}class DeconzCommandListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"command"}get buttons(){let buttons=[];var type_name,i18n=`${this.NRCD}/server:editor.inputs.commands.type`;for(const[type,enabled]of Object.entries(this.options.type))enabled&&(type_name=this.getI18n(`${i18n}.options.${type}`,"label"),buttons.push({label:this.getI18n(`${i18n}.add_button`,"label",{type:type_name}),icon:this.getIcon(this.getI18n(`${i18n}.add_button`,"icon"),!0),title:this.getI18n(`${i18n}.add_button`,"title",{type:type_name}),click:()=>this.$elements.list.editableList("addItem",{type:type})}));return buttons}async init(mainEditor){await super.init(mainEditor),await this.initList(DeconzCommandEditor,this.node.commands)}} | ||
//# sourceMappingURL=deconz-editor.js.map |
@@ -32,4 +32,4 @@ const dotProp = require('dot-prop'); | ||
migrate(config) { | ||
if (!this.handler || !this.handler.migrate) { | ||
return {error: 'Configuration migration handler not found.'}; | ||
if (this.handler === undefined || !this.handler.migrate) { | ||
return {errors: [`Configuration migration handler not found for node type '${this.type}'.`]}; | ||
} | ||
@@ -47,3 +47,3 @@ | ||
let result = this.migrate(config); | ||
if (result.notNeeded === true) return result; | ||
if (result.errors !== undefined || result.notNeeded === true) return result; | ||
@@ -50,0 +50,0 @@ // Apply new configuration |
@@ -23,2 +23,23 @@ const ConfigMigrationHandler = require('./ConfigMigrationHandler'); | ||
// Change custom string command that have valid deconz_cmd | ||
if (this.config.commandType === 'str' && [ | ||
'on', | ||
'toggle', | ||
'bri', 'hue', 'sat', | ||
'ct', 'xy', | ||
'scene', 'alert', 'effect', | ||
'colorloopspeed' | ||
].includes(this.config.command)) { | ||
this.config.commandType = 'deconz_cmd'; | ||
} | ||
if (Utils.isDeviceCover(device) && this.config.commandType === 'str' && [ | ||
'open', | ||
'stop', | ||
'lift', | ||
'tilt' | ||
].includes(this.config.command)) { | ||
this.config.commandType = 'deconz_cmd'; | ||
} | ||
// TODO Migrate commands | ||
@@ -56,9 +77,9 @@ switch (this.config.commandType) { | ||
command.arg.on = { | ||
type: 'turn', | ||
value: true | ||
type: 'set', | ||
value: 'true' | ||
}; | ||
} else if (this.config.payload === 'false') { | ||
command.arg.on = { | ||
type: 'turn', | ||
value: false | ||
type: 'set', | ||
value: 'false' | ||
}; | ||
@@ -72,9 +93,9 @@ } else { | ||
command.arg.on = { | ||
type: 'turn', | ||
value: true | ||
type: 'set', | ||
value: 'true' | ||
}; | ||
} else if (this.config.payload === '0') { | ||
command.arg.on = { | ||
type: 'turn', | ||
value: false | ||
type: 'set', | ||
value: 'false' | ||
}; | ||
@@ -93,3 +114,4 @@ } else { | ||
command.arg.on = { | ||
type: 'toggle' | ||
type: 'toggle', | ||
value: '' | ||
}; | ||
@@ -114,6 +136,6 @@ break; | ||
command.arg[this.config.command].type = 'num'; | ||
if (isNaN(this.config.payload)) { | ||
if (isNaN(parseInt(this.config.payload))) { | ||
this.result.errors.push(`Invalid value '${this.config.payload}' for option '${this.config.command}'`); | ||
} else { | ||
command.arg[this.config.command].value = parseInt(this.config.payload); | ||
command.arg[this.config.command].value = this.config.payload; | ||
} | ||
@@ -144,7 +166,7 @@ break; | ||
default: | ||
if (isNaN(this.config.payload)) { | ||
if (isNaN(parseInt(this.config.payload))) { | ||
this.result.errors.push(`Invalid value '${this.config.payload}' for option 'ct'`); | ||
} else { | ||
command.arg.ct.type = 'num'; | ||
command.arg.ct.value = parseInt(this.config.payload); | ||
command.arg.ct.value = this.config.payload; | ||
} | ||
@@ -163,6 +185,6 @@ break; | ||
command.arg.ct.type = 'num'; | ||
if (isNaN(this.config.payload)) { | ||
if (isNaN(parseInt(this.config.payload))) { | ||
this.result.errors.push(`Invalid value '${this.config.payload}' for option 'ct'`); | ||
} else { | ||
command.arg.ct.value = parseInt(this.config.payload); | ||
command.arg.ct.value = this.config.payload; | ||
} | ||
@@ -176,2 +198,5 @@ break; | ||
case 'xy': | ||
command.arg.xy = { | ||
direction: 'set' | ||
}; | ||
switch (this.config.payloadType) { | ||
@@ -195,3 +220,3 @@ case 'msg': | ||
let part = this.config.device.substring(6); | ||
if (part.length === 0 || isNaN(part)) { | ||
if (part.length === 0 || isNaN(parseInt(part))) { | ||
this.result.errors.push(`Invalid group ID '${this.config.device}' for calling scene`); | ||
@@ -201,3 +226,3 @@ } else { | ||
type: 'num', | ||
value: parseInt(part) | ||
value: String(part) | ||
}; | ||
@@ -210,3 +235,3 @@ } | ||
case 'num': | ||
if (isNaN(this.config.payload)) { | ||
if (isNaN(parseInt(this.config.payload))) { | ||
this.result.errors.push(`Invalid scene ID '${this.config.payload}' for calling scene`); | ||
@@ -216,3 +241,3 @@ } else { | ||
type: 'num', | ||
value: parseInt(this.config.payload) | ||
value: this.config.payload | ||
}; | ||
@@ -236,3 +261,2 @@ } | ||
case 'alert': | ||
command.arg.alert = {}; | ||
switch (this.config.payloadType) { | ||
@@ -244,3 +268,6 @@ case 'deconz_payload': | ||
case 'lselect': | ||
command.arg.alert.type = this.config.payload; | ||
command.arg.alert = { | ||
type: 'deconz', | ||
value: this.config.payload | ||
}; | ||
break; | ||
@@ -255,9 +282,15 @@ default: | ||
case 'global': | ||
command.arg.alert.type = this.config.payloadType; | ||
command.arg.alert.value = this.config.payload; | ||
command.arg.alert = { | ||
type: this.config.payloadType, | ||
value: this.config.payload | ||
}; | ||
break; | ||
case 'str': | ||
case 'num': | ||
command.arg.alert.type = 'str'; | ||
command.arg.alert.value = this.config.payload.toString(); | ||
command.arg.alert = { | ||
type: 'str', | ||
value: this.config.payload | ||
}; | ||
if (['none', 'select', 'lselect'].includes(command.arg.alert.value)) | ||
command.arg.alert.type = 'deconz'; | ||
break; | ||
@@ -276,3 +309,6 @@ default: | ||
case 'colorloop': | ||
command.arg.effect.type = this.config.payload; | ||
command.arg.effect = { | ||
type: 'deconz', | ||
value: this.config.payload | ||
}; | ||
break; | ||
@@ -287,9 +323,15 @@ default: | ||
case 'global': | ||
command.arg.effect.type = this.config.payloadType; | ||
command.arg.effect.value = this.config.payload; | ||
command.arg.effect = { | ||
type: this.config.payloadType, | ||
value: this.config.payload | ||
}; | ||
break; | ||
case 'str': | ||
case 'num': | ||
command.arg.effect.type = 'str'; | ||
command.arg.effect.value = this.config.payload.toString(); | ||
command.arg.effect = { | ||
type: 'str', | ||
value: this.config.payload | ||
}; | ||
if (['none', 'colorloop'].includes(command.arg.effect.value)) | ||
command.arg.effect.type = 'deconz'; | ||
break; | ||
@@ -307,22 +349,96 @@ default: | ||
case 'global': | ||
command.arg.ct.type = this.config.payloadType; | ||
command.arg.ct.value = this.config.payload; | ||
command.arg.colorloopspeed = { | ||
type: this.config.payloadType, | ||
value: this.config.payload | ||
}; | ||
break; | ||
case 'str': | ||
case 'num': | ||
command.arg.ct.type = 'num'; | ||
if (isNaN(this.config.payload)) { | ||
this.result.errors.push(`Invalid value '${this.config.payload}' for option 'ct'`); | ||
command.arg.colorloopspeed = {type: 'num'}; | ||
if (isNaN(parseInt(this.config.payload))) { | ||
this.result.errors.push(`Invalid value '${this.config.payload}' for option 'colorloopspeed'`); | ||
} else { | ||
command.arg.ct.value = parseInt(this.config.payload); | ||
command.arg.colorloopspeed.value = this.config.payload; | ||
} | ||
break; | ||
default: | ||
this.result.errors.push(`Invalid value type '${this.config.payloadType}' for option 'ct'`); | ||
this.result.errors.push(`Invalid value type '${this.config.payloadType}' for option 'colorloopspeed'`); | ||
break; | ||
} | ||
break; | ||
case 'open': | ||
case 'stop': | ||
switch (this.config.payloadType) { | ||
case 'msg': | ||
case 'flow': | ||
case 'global': | ||
command.arg[this.config.command] = { | ||
type: this.config.payloadType, | ||
value: this.config.payload | ||
}; | ||
break; | ||
case 'str': | ||
if (['true', 'false'].includes(this.config.payload)) { | ||
command.arg[this.config.command] = { | ||
type: 'set', | ||
value: this.config.payload | ||
}; | ||
} else { | ||
this.result.errors.push(`Invalid value '${this.config.payload}' for option '${this.config.command}'`); | ||
} | ||
break; | ||
default: | ||
this.result.errors.push(`Invalid value type '${this.config.payloadType}' for option '${this.config.command}'`); | ||
break; | ||
} | ||
break; | ||
case 'lift': | ||
switch (this.config.payloadType) { | ||
case 'msg': | ||
case 'flow': | ||
case 'global': | ||
case 'str': | ||
case 'num': | ||
if (this.config.payload === 'stop') { | ||
command.arg.lift = {type: 'stop'}; | ||
} else { | ||
command.arg.lift = { | ||
type: this.config.payloadType, | ||
value: this.config.payload | ||
}; | ||
} | ||
break; | ||
default: | ||
this.result.errors.push(`Invalid value type '${this.config.payloadType}' for option 'lift'`); | ||
break; | ||
} | ||
break; | ||
case 'tilt': | ||
switch (this.config.payloadType) { | ||
case 'msg': | ||
case 'flow': | ||
case 'global': | ||
case 'num': | ||
command.arg.tilt = { | ||
type: this.config.payloadType, | ||
value: this.config.payload | ||
}; | ||
break; | ||
default: | ||
this.result.errors.push(`Invalid value type '${this.config.payloadType}' for option 'tilt'`); | ||
break; | ||
} | ||
break; | ||
} | ||
if (this.config.command !== 'on') | ||
if (this.config.command !== 'on' && | ||
this.config.command !== 'toggle' && | ||
![ | ||
'scene', 'alert', 'effect', 'colorloopspeed', | ||
'open', 'stop', 'lift', 'tilt' | ||
].includes(this.config.command) | ||
) | ||
command.arg.on = {type: 'set', value: 'true'}; | ||
@@ -408,6 +524,8 @@ if (this.config.command === 'bri' && !isNaN(this.config.payload)) | ||
command.arg.transition = {type: 'num'}; | ||
if (isNaN(this.config.transitionTime)) { | ||
if (this.config.transitionTime === '') { | ||
command.arg.transition.value = ''; | ||
} else if (isNaN(parseInt(this.config.transitionTime))) { | ||
this.result.errors.push(`Invalid value '${this.config.transitionTime}' for option 'transition'`); | ||
} else { | ||
command.arg.transition.value = parseInt(this.config.transitionTime); | ||
command.arg.transition.value = this.config.transitionTime; | ||
} | ||
@@ -414,0 +532,0 @@ break; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
450010
6244