node-red-contrib-deconz
Advanced tools
Comparing version 2.3.10 to 2.3.11
@@ -10,6 +10,15 @@ # Changelog | ||
## [2.3.11] - 2023-12-27 ![Relative date](https://img.shields.io/date/1703697133?label=) | ||
### Fixed | ||
- Fix more JSONata Expression handling for Node-Red 4.0. @Zehir | ||
- Fix default value for node status of deconz-battery. @Zehir | ||
- Fix deconz-battery node filter not showing devices with `state.battery`. (#228) @Zehir | ||
- Fix HomeKit attribute BatteryLevel and StatusLowBattery for devices with `state.battery`. @Zehir | ||
## [2.3.10] - 2023-12-14 ![Relative date](https://img.shields.io/date/1702556236?label=) | ||
### Fixed | ||
- Fix JSONata Expression handling for Node-Red 4.0. @Zehir | ||
@@ -16,0 +25,0 @@ |
@@ -52,3 +52,3 @@ const NODE_PATH = "/node-red-contrib-deconz/"; | ||
*/ | ||
RED.httpAdmin.get(NODE_PATH + "itemlist", function (req, res) { | ||
RED.httpAdmin.get(NODE_PATH + "itemlist", async function (req, res) { | ||
try { | ||
@@ -68,9 +68,14 @@ let config = req.query; | ||
) { | ||
query = RED.util.evaluateNodeProperty( | ||
req.query.query, | ||
queryType, | ||
RED.nodes.getNode(req.query.nodeID), | ||
{}, | ||
undefined | ||
); | ||
query = await new Promise((resolve, reject) => { | ||
RED.util.evaluateNodeProperty( | ||
req.query.query, | ||
queryType, | ||
RED.nodes.getNode(req.query.nodeID), | ||
{}, | ||
(err, value) => { | ||
if (err) reject(err); | ||
else resolve(value); | ||
} | ||
); | ||
}); | ||
} | ||
@@ -295,2 +300,3 @@ } catch (e) { | ||
let cp = new CommandParser(config.command, {}, fakeNode); | ||
await cp.build(); | ||
let devices = []; | ||
@@ -305,3 +311,3 @@ for (let path of config.device_list) { | ||
} | ||
let requests = cp.getRequests(fakeNode, devices); | ||
let requests = await cp.getRequests(fakeNode, devices); | ||
for (const [request_id, request] of requests.entries()) { | ||
@@ -313,7 +319,7 @@ const response = await got( | ||
retry: | ||
Utils.getNodeProperty( | ||
(await Utils.getNodeProperty( | ||
config.command.arg.retryonerror, | ||
this, | ||
{} | ||
) || 0, | ||
)) || 0, | ||
json: request.params, | ||
@@ -325,3 +331,3 @@ responseType: "json", | ||
await Utils.sleep( | ||
Utils.getNodeProperty(config.delay, this, {}) || 50 | ||
(await Utils.getNodeProperty(config.delay, this, {})) || 50 | ||
); | ||
@@ -328,0 +334,0 @@ } |
@@ -83,3 +83,3 @@ const OutputMsgFormatter = require("../src/runtime/OutputMsgFormatter"); | ||
let methods = ["GET", "POST", "PUT", "DELETE"]; | ||
let method = Utils.getNodeProperty( | ||
let method = await Utils.getNodeProperty( | ||
config.specific.method, | ||
@@ -92,3 +92,3 @@ node, | ||
if (!methods.includes(method)) method = "GET"; | ||
let endpoint = Utils.getNodeProperty( | ||
let endpoint = await Utils.getNodeProperty( | ||
config.specific.endpoint, | ||
@@ -98,3 +98,3 @@ node, | ||
); | ||
let payload = Utils.getNodeProperty( | ||
let payload = await Utils.getNodeProperty( | ||
config.specific.payload, | ||
@@ -101,0 +101,0 @@ node, |
@@ -120,3 +120,3 @@ const CommandParser = require("../src/runtime/CommandParser"); | ||
let delay = Utils.getNodeProperty( | ||
let delay = await Utils.getNodeProperty( | ||
node.config.specific.delay, | ||
@@ -173,3 +173,3 @@ this, | ||
let resultTimings = ["never", "after_command", "at_end"]; | ||
let resultTiming = Utils.getNodeProperty( | ||
let resultTiming = await Utils.getNodeProperty( | ||
node.config.specific.result, | ||
@@ -190,3 +190,3 @@ this, | ||
if (command.type === "pause") { | ||
let sleep_delay = Utils.getNodeProperty( | ||
let sleep_delay = await Utils.getNodeProperty( | ||
command.arg.delay, | ||
@@ -217,3 +217,4 @@ this, | ||
let cp = new CommandParser(command, message_in, node); | ||
let requests = cp.getRequests(node, devices); | ||
await cp.build(); | ||
let requests = await cp.getRequests(node, devices); | ||
let request_count = requests.length; | ||
@@ -245,7 +246,7 @@ for (const [request_id, request] of requests.entries()) { | ||
retry: | ||
Utils.getNodeProperty( | ||
(await Utils.getNodeProperty( | ||
command.arg.retryonerror, | ||
this, | ||
message_in | ||
) || 0, | ||
)) || 0, | ||
json: request.params, | ||
@@ -351,3 +352,3 @@ responseType: "json", | ||
if ( | ||
Utils.getNodeProperty( | ||
(await Utils.getNodeProperty( | ||
command.arg.aftererror, | ||
@@ -357,3 +358,3 @@ this, | ||
["continue", "stop"] | ||
) === "stop" | ||
)) === "stop" | ||
) | ||
@@ -360,0 +361,0 @@ return; |
@@ -826,3 +826,3 @@ const got = require("got"); | ||
updateNodeStatus(node, msgToSend) { | ||
async updateNodeStatus(node, msgToSend) { | ||
if (node.server.ready === false) { | ||
@@ -889,3 +889,3 @@ node.status({ | ||
shape: "dot", | ||
text: Utils.getNodeProperty( | ||
text: await Utils.getNodeProperty( | ||
{ | ||
@@ -929,2 +929,4 @@ type: node.config.statustext_type, | ||
let battery = dotProp.get(firstmsg, "meta.config.battery"); | ||
if (battery === undefined) | ||
battery = dotProp.get(firstmsg, "meta.state.battery"); | ||
if (battery === undefined) return; | ||
@@ -931,0 +933,0 @@ node.status({ |
{ | ||
"name": "node-red-contrib-deconz", | ||
"version": "2.3.10", | ||
"version": "2.3.11", | ||
"description": "deCONZ connectivity nodes for node-red", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -1,2 +0,2 @@ | ||
class DeconzEditor{constructor(e,t={}){this.node=e,this.options=t}get elements(){return{}}get NRCD(){return"node-red-contrib-deconz"}findElements(){this.$elements={},Object.keys(this.elements).forEach(e=>{this.$elements[e]=this.findElement(this.elements[e])})}findElement(e){return"#"!==e.charAt(0)&&"."!==e.charAt(0)&&(e="#"+e),$(e)}async init(){this.findElements()}async connect(){}sendError(e,t=1e4){let i=RED.notify(e,{timeout:t,type:"error",buttons:[{text:"Ok",class:"primary",click:()=>i.close()}]})}getIcon(e,t=!1){return"deconz"===e?"icons/node-red-contrib-deconz/icon-color.png":"homekit"===e?"icons/node-red-contrib-deconz/homekit-logo.png":RED.nodes.fontAwesome.getIconList().includes("fa-"+e)?`${t?"fa ":""}fa-`+e:e}createIconElement(e,t,i=!1){if("fa-"===e.substr(0,3)){if(RED.nodes.fontAwesome.getIconUnicode(e))return void $("<i/>").appendTo(t).addClass("fa "+e+(i?" fa-lg":""));e=RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"}$("<div/>").appendTo(t).css("backgroundImage","url("+e+")")}getI18n(e,t,i={}){let s=e;t&&(s+="."+t),i.defaultValue="_deconz_undefined_";var n=RED._(s,i);if("_deconz_undefined_"!==n)return n}async generateSimpleListField(e,t){var i=$("<select/>",{id:t.id});if(t.choices)for(var[s,n]of t.choices)i.append($("<option/>").attr("value",s).html(RED._(n)));var a=await this.generateInputWithLabel(i,t);return e.append(a),void 0!==t.currentValue&&i.val(t.currentValue),i}async generateTypedInput(e,t){var i=$("<input/>",{id:e,placeholder:RED._(t)}),s=$("<input/>",{id:e+"_type",type:"hidden"});return i.append(s),i}async initTypedInput(e,t){t=$.extend({addDefaultTypes:!0,displayOnlyIcon:!1,value:{},width:"200px"},t);var i=$.extend({types:["msg","flow","global"]},t.typedInput);if(i.typeField=t.typeId,t.addDefaultTypes)for(var s of["msg","flow","global","jsonata"])i.types.includes(s)||i.types.push(s);if(t.displayOnlyIcon){let n=this;var a,o=function(e,t){let i;for(const s of this.typeList)"object"==typeof s&&s.value===this.propertyType&&(i=s);void 0!==i&&void 0!==i.icon&&(this.oldValue=this.input.val(),this.input.val(""),this.valueLabelContainer.hide(),n.createIconElement(i.icon,this.selectLabel),this.selectTrigger.addClass("red-ui-typedInput-full-width"),this.selectLabel.show())};for(a of i.types)"string"!=typeof a&&(a.hasValue=!0,a.valueLabel=o)}e.typedInput(i),void 0!==t.width&&e.typedInput("width",t.width),t.value&&(void 0!==t.value.type&&e.typedInput("type",t.value.type),void 0!==t.value.value)&&e.typedInput("value",t.value.value)}async generateTypedInputField(e,t){var i=await this.generateTypedInput(t.id,this.getI18n(t.i18n,"placeholder")),s=await this.generateInputWithLabel(i,t);return e.append(s),await this.initTypedInput(i,t),i}async generateDoubleTypedInputField(e,t,i){var s=await this.generateTypedInput(t.id,t.placeholder),n=await this.generateInputWithLabel(s,t),a=await this.generateTypedInput(i.id,i.placeholder);n.append(a),e.append(n),t.displayOnlyIcon=!0,t.width="50px",i.width="150px",await this.initTypedInput(s,t),await this.initTypedInput(a,i)}generateTypedInputType(e,t,i={}){if(i.value=t,void 0===i.label&&(i.label=this.getI18n(e,`options.${t}.label`,{})||t),!1!==i.icon&&void 0===i.icon&&(i.icon=this.getIcon(this.getI18n(e,`options.${t}.icon`))),i.icon&&"fa-"===i.icon.substr(0,3)&&(i.icon="fa "+i.icon),Array.isArray(i.subOptions)){Array.isArray(i.options)||(i.options=[]);for(const s of i.subOptions)i.options.push(this.generateTypedInputType(e+".options."+t,"string"==typeof s?s:s.name,{icon:!1}))}return i}async generateCheckboxField(e,t){var i=$("<input/>",{id:t.id,type:"checkbox",style:"display: table-cell; width: 14px;vertical-align: top;margin-right: 5px",checked:t.currentValue}),i=await this.generateInputWithLabel(i,t);i.append($("<span/>").html(RED._(t.descText)).css("display","table-cell")),e.append(i)}async generateInputWithLabel(e,t={}){var i,s=$("<div/>",{class:"form-row",style:"padding:5px;margin:0;display:table;min-width:420px;"}),n=e.attr("id");return n&&((i=$("<label/>")).attr("for",n),i.attr("class","l-width"),i.attr("style","display:table-cell;"),void 0===t.title&&(t.title=this.getI18n(t.i18n,"title")),t.title&&i.attr("title",this.getI18n(t.i18n,"title")),void 0===t.icon&&(t.icon=this.getI18n(t.i18n,"icon")),t.icon&&(this.createIconElement(this.getIcon(t.icon),i),i.append(" ")),void 0===t.label&&(t.label=this.getI18n(t.i18n,"label")),t.label&&i.append(`<span>${t.label}</span>`),s.append(i)),e.css("display","table-cell"),s.append(e),s}async generateHR(e,t="5px",i="50px"){e.append(`<hr style="margin: ${t} ${i};">`)}async generateSeparator(e,t){e.append(`<div class="separator">${RED._(t)}</div>`)}static versionCompare(e,t,i={}){const s=i&&i.lexicographical;var n=i&&i.zeroExtend;let a=e.split("."),o=t.split(".");function r(e){return(s?/^\d+[A-Za-z]*$/:/^\d+$/).test(e)}if(!a.every(r)||!o.every(r))return NaN;if(n){for(;a.length<o.length;)a.push("0");for(;o.length<a.length;)o.push("0")}s||(a=a.map(Number),o=o.map(Number));for(let l=0;l<a.length;++l){if(o.length===l)return 1;if(a[l]!==o[l])return a[l]>o[l]?1:-1}return a.length!==o.length?-1:0}}class DeconzMainEditor extends DeconzEditor{constructor(e,t={}){if(super(e,$.extend(!0,{have:{statustext:!0,query:!0,device:!0,output_rules:!1,commands:!1,specific:!1},device:{batteryFilter:!1},output_rules:{format:{single:!0,array:!1,sum:!1,average:!1,min:!1,max:!1},type:{attribute:!0,state:!0,config:!0,homekit:!1,scene_call:!1}},commands:{type:{deconz_state:!0,homekit:!0,custom:!0,pause:!0}},specific:{api:{},output:{},server:{}}},t)),this.subEditor={},this.initDone=!1,this.options.have.statustext&&(this.subEditor.statustext=new DeconzStatusTextEditor(this.node,this.options.statustext)),this.options.have.device&&(this.subEditor.device=new DeconzDeviceEditor(this.node,this.options.device)),this.options.have.query&&(this.subEditor.query=new DeconzQueryEditor(this.node,this.options.query)),this.options.have.specific)switch(this.node.type){case"deconz-api":this.subEditor.specific=new DeconzSpecificApiEditor(this.node,this.options.specific.api);break;case"deconz-output":this.subEditor.specific=new DeconzSpecificOutputEditor(this.node,this.options.specific.output);break;case"deconz-server":this.subEditor.specific=new DeconzSpecificServerEditor(this.node,this.options.specific.server)}this.options.have.output_rules&&(this.subEditor.output_rules=new DeconzOutputRuleListEditor(this.node,this.options.output_rules)),this.options.have.commands&&(this.subEditor.commands=new DeconzCommandListEditor(this.node,this.options.commands))}get elements(){return{tipBox:"node-input-tip-box",server:"node-input-server"}}async configurationMigration(){if(!((this.node.config_version||0)>=this.node._def.defaults.config_version.value)){var e={};for(const o of Object.keys(this.node._def.defaults))e[o]=this.node[o];var t={id:this.node.id,type:this.node.type,config:JSON.stringify(e)};let i="Error while migrating the configuration of the node from version "+(this.node.config_version||0)+" to version "+this.node._def.defaults.config_version.value+".";t=await $.getJSON(this.NRCD+"/configurationMigration",t).catch((e,t)=>{this.$elements.tipBox.append(`<div class="form-tips form-warning"><p>Migration errors:</p><p>${i}</p></div>`)});if(t&&!t.notNeeded){if(t.new)for(var[s,n]of Object.entries(t.new))this.node[s]=n;if(t.delete&&Array.isArray(t.delete))for(const r of t.delete)delete this.node[r];var a=e=>"node-red-contrib-deconz"===e.substr(0,23)?RED._(e):e;t.errors&&Array.isArray(t.errors)&&0<t.errors.length&&this.$elements.tipBox.append('<div class="form-tips form-warning"><p>Migration errors:</p><ul>'+`<li>${t.errors.map(a).join("</li><li>")}</li>`+"</ul></div>"),t.info&&Array.isArray(t.info)&&0<t.info.length&&this.$elements.tipBox.append('<div class="form-tips"><p>Migration info:</p><ul>'+`<li>${t.info.map(a).join("</li><li>")}</li>`+"</ul></div>")}}}async init(){await new Promise(e=>setTimeout(e,100)),await super.init(),await this.configurationMigration(),this.initPromises=[];for(const t of Object.values(this.subEditor))this.initPromises.push(t.init(this));await Promise.all(this.initPromises),this.initDone=!0,delete this.initPromises;var e=[];for(const i of Object.values(this.subEditor))e.push(i.connect());await Promise.all(e)}get serverNode(){return"deconz-server"===this.node.type?this.node:RED.nodes.node(this.$elements.server.val())}async isInitialized(){this.initDone||await Promise.all(this.initPromises)}async updateQueryDeviceDisplay(e){var t=this.subEditor.query.$elements.select.typedInput("type");switch(t){case"device":await this.subEditor.device.updateList(e);break;case"json":case"jsonata":this.subEditor.query.$elements.select.typedInput("validate")&&await this.subEditor.query.updateList(e)}await this.subEditor.device.display("device"===t),await this.subEditor.query.display("device"!==t)}oneditsave(){var e;this.options.have.output_rules&&(e=this.subEditor.output_rules.value,this.node.outputs=e.length,this.node.output_rules=e),this.options.have.commands&&(this.node.commands=this.subEditor.commands.value),this.options.have.specific&&(this.node.specific=this.subEditor.specific.value)}}class DeconzStatusTextEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({allowedTypes:["msg","jsonata"]},t))}get elements(){return{statustext:"node-input-statustext"}}async init(e){await super.init(),this.mainEditor=e,this.initTypedInput()}initTypedInput(){var e=[];this.mainEditor.options.have.statustext&&e.push({value:"auto",label:RED._(this.NRCD+"/server:editor.inputs.statustext.options.auto"),icon:`icons/${this.NRCD}/icon-color.png`,hasValue:!1}),this.$elements.statustext.typedInput({type:"auto",types:e.concat(this.options.allowedTypes),typeField:`#${this.elements.statustext}_type`})}}class DeconzDeviceListEditor extends DeconzEditor{constructor(e,t={}){super(e,t)}get xhrURL(){return this.NRCD+"/itemlist"}get xhrParams(){return{controllerID:this.mainEditor.serverNode.id,forceRefresh:this.options.refresh}}async display(e=!0){if(this.$elements.showHide)return e?this.$elements.showHide.show():this.$elements.showHide.hide(),this.$elements.showHide.promise()}async getItems(e,t){t.forceRefresh=e.refresh;var i=await $.getJSON(this.xhrURL,t).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});if(!i||!i.error_message)return this.formatItemList(i.items,e.keepOnlyMatched);console.warn(i.error_message),RED.notify("Warning : "+i.error_message,{type:"warning",timeout:1e4})}async updateList(e){var t,i;e=$.extend({refresh:!0},e),this.mainEditor.serverNode&&(t=this.$elements.list,i=this.xhrParams,!0===this.options.batteryFilter&&(e.keepOnlyMatched=!0,i.query=JSON.stringify({type:"match",match:{"config.battery":{type:"complex",operator:"!==",value:void 0}}})),i=await this.getItems(e,i),t.children().remove(),i&&this.generateHtmlItemList(i,this.$elements.list),t.multipleSelect("refresh"),i)&&t.multipleSelect("enable")}formatItemList(e,t=!1){let s={};var i=(e,i)=>{e.forEach(e=>{var t=e.type;void 0===s[t]&&(s[t]=[]),e.query_match=i,s[t].push(e)})};return i(e.matched,!0),!1===t&&i(e.rejected,!1),s}generateHtmlItemList(e,t){var i,s,n=this.constructor===DeconzQueryEditor;for([i,s]of Object.entries(e).sort((e,t)=>{var i=e[0].toLowerCase(),s=t[0].toLowerCase();return i<s?-1:s<i?1:0})){var a=$("<optgroup/>").attr("label",i);for(const r of s.sort((e,t)=>{var i=e.name.toLowerCase(),s=t.name.toLowerCase();return i<s?-1:s<i?1:0})){let e=r.name;"groups"===r.device_type&&(e+=" (lights: "+r.lights.length,r.scenes.length&&(e+=", scenes: "+r.scenes.length),e+=")");var o=$("<option>"+e+"</option>").attr("value",r.device_path);n&&r.query_match&&o.attr("selected",""),o.appendTo(a)}a.appendTo(t)}}}class DeconzQueryEditor extends DeconzDeviceListEditor{constructor(e,t={}){super(e,$.extend({allowedTypes:["json","jsonata"]},t))}get elements(){return{select:"node-input-query",list:"node-input-query_result",showHide:".deconz-query-selector",refreshButton:"#force-refresh-query-result"}}get type(){return this.$elements.select.typedInput("type")}set type(e){this.$elements.list.typedInput("type",e)}get value(){return this.$elements.select.typedInput("value")}set value(e){this.$elements.list.typedInput("value",e)}get xhrParams(){var e=super.xhrParams;return e.query=this.value,e.queryType=this.type,e.nodeID=this.node.id,e}async init(e){await super.init(),this.mainEditor=e,this.initTypedInput(),this.$elements.list.multipleSelect({maxHeight:300,dropWidth:320,width:320,single:!1,selectAll:!1,filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),numberDisplayed:1,disableIfEmpty:!0,showClear:!1,hideOptgroupCheckboxes:!0,filterGroup:!0,onClick:e=>{this.$elements.list.multipleSelect(e.selected?"uncheck":"check",e.value)}}),await this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0})}initTypedInput(){var e=[];this.mainEditor.options.have.device&&e.push({value:"device",label:RED._(this.NRCD+"/server:editor.inputs.device.query.options.device"),icon:`icons/${this.NRCD}/icon-color.png`,hasValue:!1}),this.$elements.select.typedInput({type:"text",types:e.concat(this.options.allowedTypes),typeField:"#node-input-search_type"})}async connect(){await super.connect(),this.$elements.select.on("change",()=>{this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0}),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()}),this.$elements.refreshButton.on("click",()=>{this.updateList(),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()})}}class DeconzDeviceEditor extends DeconzDeviceListEditor{constructor(e,t={}){super(e,$.extend({batteryFilter:!1},t))}get elements(){return{list:"node-input-device_list",showHide:".deconz-device-selector",refreshButton:"#force-refresh"}}get value(){return this.$elements.list.multipleSelect("getSelects")}set value(e){this.$elements.list.multipleSelect("setSelects",e)}async init(e){await super.init(),this.mainEditor=e,this.$elements.list.multipleSelect({maxHeight:300,dropWidth:320,width:320,single:"multiple"!==this.$elements.list.attr("multiple"),filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),showClear:!0})}async connect(){await super.connect();var e=()=>{this.updateList($.extend(this.options,{useSelectedData:!0})),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()};this.mainEditor.$elements.server.on("change",e),this.$elements.refreshButton.on("click",e),this.mainEditor.options.have.output_rules&&this.$elements.list.on("change",()=>{this.mainEditor.subEditor.output_rules.refresh()})}async updateList(e){let t;(e=$.extend({useSavedData:!1,useSelectedData:!1},e)).useSelectedData&&(t=this.$elements.list.multipleSelect("getSelects")),await super.updateList(e),e.useSavedData&&Array.isArray(this.node.device_list)?this.$elements.list.multipleSelect("setSelects",this.node.device_list):e.useSelectedData&&Array.isArray(t)&&this.$elements.list.multipleSelect("setSelects",t)}}class DeconzSpecificApiEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{container:"deconz-api-form",name:"node-config-input-name",method:"node-config-input-method",endpoint:"node-config-input-endpoint",payload:"node-config-input-payload"}}get default(){return{name:"",method:{type:"GET"},endpoint:{type:"str",value:"/"},payload:{type:"json",value:"{}"}}}async init(){this.node.specific=$.extend(!0,this.default.specific,this.node.specific);var e=this.findElement(this.elements.container);await this.generateMethodField(e,this.node.specific.method),await this.generateEndpointField(e,this.node.specific.endpoint),await this.generatePayloadField(e,this.node.specific.payload),await super.init()}async connect(){await super.connect()}get value(){return{method:{type:this.$elements.method.typedInput("type"),value:this.$elements.method.typedInput("value")},endpoint:{type:this.$elements.endpoint.typedInput("type"),value:this.$elements.endpoint.typedInput("value")},payload:{type:this.$elements.payload.typedInput("type"),value:this.$elements.payload.typedInput("value")}}}set value(e){this.$elements.name.val(e.name);for(var t of["method","endpoint","payload"])this.$elements[t].typedInput("type",e[t].type),this.$elements[t].typedInput("value",e[t].value);for(const i of Object.values(this.$elements))i.trigger("change")}async generateMethodField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.method";await this.generateTypedInputField(e,{id:this.elements.method,i18n:i,value:t,width:"250px",typedInput:{types:[this.generateTypedInputType(i,"GET",{hasValue:!1}),this.generateTypedInputType(i,"POST",{hasValue:!1}),this.generateTypedInputType(i,"PUT",{hasValue:!1}),this.generateTypedInputType(i,"DELETE",{hasValue:!1})]}})}async generateEndpointField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.endpoint";await this.generateTypedInputField(e,{id:this.elements.endpoint,i18n:i,value:t,width:"250px",typedInput:{types:["str"]}})}async generatePayloadField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.payload";await this.generateTypedInputField(e,{id:this.elements.payload,i18n:i,value:t,width:"250px",typedInput:{types:["json","jsonata"]}})}}class DeconzSpecificOutputEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{container:"specific-container",delay:"node-input-delay",result:"node-input-result"}}get default(){return{delay:{type:"num",value:50},result:{type:"at_end"}}}async init(){this.node.specific=$.extend(!0,this.default,this.node.specific);var e=this.findElement(this.elements.container);await this.generateSeparator(e,this.NRCD+"/server:editor.inputs.separator.specific"),await this.generateDelayField(e,this.node.specific.delay),await this.generateResultField(e,this.node.specific.result),await super.init()}async generateDelayField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.output.delay";await this.generateTypedInputField(e,{id:this.elements.delay,i18n:i,value:t,width:"250px",typedInput:{types:["num"]}})}async generateResultField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.output.result";await this.generateTypedInputField(e,{id:this.elements.result,i18n:i,value:t,width:"250px",typedInput:{types:[this.generateTypedInputType(i,"never",{hasValue:!1}),this.generateTypedInputType(i,"after_command",{hasValue:!1}),this.generateTypedInputType(i,"at_end",{hasValue:!1})]}})}async connect(){await super.connect()}get value(){return{delay:{type:this.$elements.delay.typedInput("type"),value:this.$elements.delay.typedInput("value")},result:{type:this.$elements.result.typedInput("type"),value:this.$elements.result.typedInput("value")}}}}class DeconzSpecificServerEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{name:"node-config-input-name",ip:"node-config-input-ip",port:"node-config-input-port",apikey:"node-config-input-secured_apikey",ws_port:"node-config-input-ws_port",secure:"node-config-input-secure",polling:"node-config-input-polling",getSettingsButton:"node-contrib-deconz-get-settings"}}get default(){return{name:"",ip:"",port:"",apikey:"",ws_port:"",secure:!1,polling:15}}get xhrURL(){return this.NRCD+"/serverAutoconfig"}async init(){this.node.specific=$.extend(!0,this.default,this.node.specific),await super.init(),this.node.migration_secured_apikey&&(this.$elements.apikey.val(this.node.migration_secured_apikey),this.$elements.apikey.trigger("change"))}async connect(){await super.connect(),this.$elements.getSettingsButton.on("click",()=>this.discoverParams())}async discoverParams(e){void 0===e&&(e={});let t,s=!1,n=()=>{t&&"function"==typeof t.close&&t.close(),s=!0};t=RED.notify("<p>Trying to find the server settings, please wait...<br>This can take up to 15 seconds.</p>",{modal:!0,fixed:!0,type:"info",buttons:[{text:"Cancel",class:"primary",click:n}]});try{var a=Object.assign({},this.value,e);void 0===a.discoverParam&&(a.discoverParam={}),a.discoverParam.devicetype="Node-Red Deconz Plugin"+(this.node?" id:"+this.node.id:"");let i=await $.getJSON(this.xhrURL,{config:JSON.stringify(a)}).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});if(!s)if(i.error){let e=`<p>Error ${i.error.code}: ${i.error.description}</p>`;var o=[{text:"Cancel",click:n}];switch(i.error.code){case"GATEWAY_CHOICE":e+="<p>There is multiple Deconz device in you network, please select the one you want to configure.</p>";let t=this;for(const[r,l]of i.error.gateway_list.entries())o.push({text:`#${r+1}: `+l.name,id:"node-red-contrib-deconz-gateway-id-"+r,class:"primary",click:()=>{return e=l.bridge_id,n(),e&&(i.currentSettings.discoverParam.targetGatewayID=e),void t.discoverParams(i.currentSettings);var e}});o.push(o.shift());break;case"DECONZ_ERROR":101===i.error.type&&(o.unshift({text:"I pressed the link button",class:"primary",click:()=>{n(),this.discoverParams(i.currentSettings)}}),e=(e+="<p>The reason why the request failed is that the gateway was not unlocked. This mechanism is needed to prevent anybody from access to the gateway without being permitted to do so.</p><ul><li>In a new browser tab open the <a href='http://phoscon.de/pwa/' target='_blank'>Phoscon App</a></li><li>Click on Menu -> Settings -> Gateway</li><li>Click on \"Advanced\" button</li><li>Click on the \"Authenticate app\" button</li></ul>")+`<p>Within 60 seconds after unlocking the gateway, click on the button "${o[0].text}".</p>`);break;default:o[o.length-1].text="Cancel"}e+=`<p>Logs:</p><pre>${i.log.join("\n")}</pre>`,n(),t=RED.notify(e,{modal:!0,fixed:!0,type:"error",buttons:o})}else i.success?(n(),t=RED.notify("<p>Settings fetched successfully !</p>",{modal:!1,fixed:!1,type:"success"}),this.value=i.currentSettings):(n(),t=RED.notify(`<p>Unknown error : ${JSON.stringify(i)}</p>`,{modal:!0,fixed:!0,type:"error",buttons:[{text:"Ok",class:"primary",click:n}]}))}catch(e){n(),t=RED.notify(`<p>Error while processing request: ${e.toString()}</p>`,{type:"error"})}}get value(){return{name:this.$elements.name.val(),ip:this.$elements.ip.val(),port:this.$elements.port.val(),apikey:this.$elements.apikey.val(),ws_port:this.$elements.ws_port.val(),secure:this.$elements.secure.prop("checked"),polling:this.$elements.polling.val()}}set value(e){this.$elements.name.val(e.name),this.$elements.ip.val(e.ip),this.$elements.port.val(e.port),this.$elements.apikey.val(e.apikey),this.$elements.ws_port.val(e.ws_port),this.$elements.secure.prop("checked",e.secure),this.$elements.polling.val(e.polling);for(const t of Object.values(this.$elements))t.trigger("change")}}class DeconzListItemEditor extends DeconzEditor{constructor(e,t,i,s={}){super(e,s),this.listEditor=t,i.uniqueId(),this.uniqueId=i.attr("id"),this.container=i}set index(e){void 0!==e&&this.$elements&&this.$elements.outputButton&&this.$elements.outputButton.find(".node-input-rule-index").html(e+1),this._index=e}get index(){return this._index}async init(){await this.generateOutputButton(this.container.children().first()),await super.init()}async generateOutputButton(e){$("<a/>",{id:this.elements.outputButton,class:"red-ui-button top-right-badge",title:RED._(this.options.button_title)}).append(` → <span class="node-input-rule-index">${this.index+1}</span> `).appendTo(e)}}class DeconzListItemListEditor extends DeconzEditor{constructor(e,t={}){super(e,t),this.items={}}get listType(){return"item"}get buttons(){return[]}async init(e){await super.init(),this.mainEditor=e}async initList(n,e=[]){var t=this.buttons,i=0===t.length||DeconzEditor.versionCompare(RED.settings.version,"1.3.0")<0;this.$elements.list.editableList({sortable:!0,removable:!0,height:"auto",addButton:i,buttons:t,addItem:(e,t,i)=>{var s=new n(this.node,this,e,this.options);i.uniqueId=s.uniqueId,(this.items[i.uniqueId]=s).init(i,t)},removeItem:e=>{if(!e.uniqueId||!this.items[e.uniqueId])throw new Error(`Error while removing the ${this.listType}, the ${this.listType} ${e.uniqueId} does not exist.`);var t=this.items[e.uniqueId].index;delete this.items[e.uniqueId];for(const e of Object.values(this.items))e.index>t&&e.index--},sortItems:e=>{e.each((e,t)=>{if(!this.items[t.attr("id")])throw new Error(`Error while moving the ${this.listType}, the ${this.listType} ${e+1} does not exist.`);this.items[t.attr("id")].index=e})}}),0<e.length&&this.$elements.list.editableList("addItems",e)}get value(){var e=[];for(const t of Object.values(this.items).sort((e,t)=>e.index-t.index))e.push(t.value);return e}refresh(){}}class DeconzOutputRuleEditor extends DeconzListItemEditor{constructor(e,t,i,s={}){super(e,t,i,s=$.extend({enableEachState:!0},s))}get elements(){var e={};for(const t of["format","type","payload","output","onstart","onerror","outputButton"])e[t]=`node-input-output-rule-${this.uniqueId}-`+t;return e}get value(){var e={};switch(e.type=this.$elements.type.val(),e.format=this.$elements.format.val(),e.type){case"attribute":case"state":case"config":"deconz-input"===this.node.type&&(e.output=this.$elements.output.val()),["deconz-input","deconz-battery"].includes(this.node.type)&&(e.onstart=this.$elements.onstart.is(":checked")),["deconz-input","deconz-get"].includes(this.node.type)&&(e.payload=this.$elements.payload.multipleSelect("getSelects"));break;case"homekit":["deconz-input","deconz-battery"].includes(this.node.type)&&(e.onstart=this.$elements.onstart.is(":checked")),"deconz-input"===this.node.type&&(e.onerror=this.$elements.onerror.is(":checked")),["deconz-input","deconz-get"].includes(this.node.type)&&(e.payload=this.$elements.payload.multipleSelect("getSelects"))}return e}get defaultRule(){var e={type:"state",payload:["__complete__"],format:"single"};return"deconz-input"===this.node.type&&(e.output="always",e.onstart=!0,e.onerror=!0),"deconz-battery"===this.node.type&&(e.onstart=!0),e}async init(e,t){this._index=t,e=$.extend(!0,this.defaultRule,e),await this.generatePayloadTypeField(this.container,e.type),["deconz-input","deconz-get"].includes(this.node.type)&&await this.generatePayloadField(this.container),await this.generatePayloadFormatField(this.container,e.format),"deconz-input"===this.node.type&&await this.generateOutputField(this.container,(void 0!==e.output?e:this.defaultRule).output),["deconz-input","deconz-battery"].includes(this.node.type)&&await this.generateOnStartField(this.container,(void 0!==e.onstart?e:this.defaultRule).onstart),"deconz-input"===this.node.type&&await this.generateOnErrorField(this.container,(void 0!==e.onerror?e:this.defaultRule).onerror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.initPayloadList(e.payload),await this.updateShowHide(e.type),await this.connect()}async connect(){await super.connect(),this.$elements.type.on("change",()=>{var e=this.$elements.type.val();["attribute","state","config","homekit"].includes(e)&&this.updatePayloadList(),this.updateShowHide(e)}),this.$elements.outputButton.on("click",()=>{try{var t=RED.nodes.filterLinks({source:this.node,sourcePort:this.index}).map(e=>{var t=e.target.type;return""!==e.target.name?t+":"+e.target.name:void 0!==e.target._def.label?t+":"+e.target._def.label():t});let e=RED.notify(`The output ${this.index+1} is sending message to ${t.length} nodes :<br>`+t.join("<br>"),{modal:!0,timeout:5e3,buttons:[{text:"okay",class:"primary",click:()=>e.close()}]})}catch(e){this.sendError("This is using not documented API so can be broken at anytime.<br>Error while getting connected nodes: "+e.toString())}})}async updateShowHide(e){switch(e){case"attribute":case"state":case"config":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").show(),this.$elements.onstart.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").hide();break;case"homekit":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").hide(),this.$elements.onstart.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").show();break;case"scene_call":this.$elements.payload.closest(".form-row").hide(),this.$elements.output.closest(".form-row").hide(),this.$elements.onstart.closest(".form-row").hide(),this.$elements.onerror.closest(".form-row").hide()}}async updatePayloadList(){if(this.listEditor.mainEditor.serverNode){this.$elements.payload.multipleSelect("disable"),this.$elements.payload.children().remove();var t=this.listEditor.mainEditor.subEditor.query.type,i=this.listEditor.mainEditor.subEditor.device.value,s=this.$elements.type.val();if(["attribute","state","config","homekit"].includes(s)){var n=this.NRCD+"/server:editor.inputs.outputs.payload";let e="";if("homekit"===s?e+='<option value="__auto__">'+RED._(n+".options.auto")+"</option>":(e+='<option value="__complete__">'+RED._(n+".options.complete")+"</option>",!0===this.options.enableEachState&&(e+='<option value="__each__">'+RED._(n+".options.each")+"</option>")),this.$elements.payload.html(e),"device"===t){var a=await $.getJSON(this.NRCD+`/${s}list`,{controllerID:this.listEditor.mainEditor.serverNode.id,devices:JSON.stringify(this.listEditor.mainEditor.subEditor.device.value)});for(const l of"attribute"===s?["attribute","state","config"]:[s]){let e=this.getI18n(n+".group_label."+l);void 0===e&&(e=l);var o=$("<optgroup/>",{label:e});for(const p of Object.keys(a.count[l]).sort()){let e=a.sample[l][p];e="string"==typeof e?`"${e}"`:Array.isArray(e)?`[${e.toString()}]`:null===e||void 0===e?"NULL":e.toString();let t;var r=a.count[l][p];t=r===i.length?RED._(n+".item_list",{name:p,sample:e}):RED._(n+".item_list_mix",{name:p,sample:e,item_count:r,device_count:i.length}),$("<option>"+t+"</option>").attr("value","attribute"===s&&"attribute"!==l?l+"."+p:p).appendTo(o)}$.isEmptyObject(a.count[l])||o.appendTo(this.$elements.payload)}}this.$elements.payload.multipleSelect("refresh").multipleSelect("enable")}}}async initPayloadList(e){let t=this.$elements.payload;t.addClass("multiple-select"),t.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!1,selectAll:!1,container:".node-input-output-container-row",filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),onClick:e=>{if(e.selected)switch(e.value){case"__complete__":case"__each__":case"__auto__":t.multipleSelect("setSelects",[e.value]);break;default:t.multipleSelect("uncheck","__complete__"),t.multipleSelect("uncheck","__each__"),t.multipleSelect("uncheck","__auto__")}},onUncheckAll:()=>{t.multipleSelect("setSelects",["__complete__","__auto__"])},onOptgroupClick:e=>{e.selected&&(t.multipleSelect("uncheck","__complete__"),t.multipleSelect("uncheck","__each__"),t.multipleSelect("uncheck","__auto__"))}}),await this.updatePayloadList(),e&&t.multipleSelect("setSelects",e)}async generatePayloadTypeField(e,t){var i,s,n=this.NRCD+"/server:editor.inputs.outputs.type",a=[];for([i,s]of Object.entries(this.listEditor.options.type))s&&a.push([i,n+".options."+i]);await this.generateSimpleListField(e,{id:this.elements.type,i18n:n,choices:a,currentValue:t})}async generatePayloadField(e){var t=this.NRCD+"/server:editor.inputs.outputs.payload";await this.generateSimpleListField(e,{id:this.elements.payload,i18n:t})}async generatePayloadFormatField(e,t){var i,s,n=this.NRCD+"/server:editor.inputs.outputs.format",a=[];for([i,s]of Object.entries(this.listEditor.options.format))s&&a.push([i,n+".options."+i]);await this.generateSimpleListField(e,{id:this.elements.format,i18n:n,choices:a,currentValue:t})}async generateOutputField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.output";await this.generateSimpleListField(e,{id:this.elements.output,i18n:i,choices:[["always",i+".options.always"],["onchange",i+".options.onchange"],["onupdate",i+".options.onupdate"]],currentValue:t})}async generateOnStartField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.on_start";await this.generateCheckboxField(e,{id:this.elements.onstart,i18n:i,currentValue:t})}async generateOnErrorField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.on_error";await this.generateCheckboxField(e,{id:this.elements.onerror,i18n:i,currentValue:t})}}class DeconzOutputRuleListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"rule"}get buttons(){var e,t=[],i=this.NRCD+"/server:editor.inputs.outputs.type";for(const[s,n]of Object.entries(this.options.type))n&&(e=this.getI18n(i+".options."+s),t.push({label:this.getI18n(i+".add_button","label",{type:e}),icon:this.getIcon(this.getI18n(i+".add_button","icon"),!0),title:this.getI18n(i+".add_button","title",{type:e}),click:()=>this.$elements.list.editableList("addItem",{type:s})}));return t}async init(e){await super.init(e),await this.initList(DeconzOutputRuleEditor,this.node.output_rules)}refresh(){for(const e of Object.values(this.items))e.updatePayloadList()}}class DeconzCommandEditor extends DeconzListItemEditor{constructor(e,t,i,s={}){super(e,t,i,s=$.extend({},s)),this.containers={}}get lightKeys(){return["bri","sat","hue","ct","xy"]}get argKeys(){return["on","alert","effect","colorloopspeed","open","stop","lift","tilt","scene_mode","group","scene","scene_name","target","command","payload","delay","transitiontime","retryonerror","aftererror"]}get elements(){var e=this.argKeys;e.push("typedomain"),e.push("outputButton"),e.push("scene_picker"),e.push("scene_picker_refresh");for(const i of this.lightKeys)e.push(i),e.push(i+"_direction");var t={};for(const s of e)t[s]=`node-input-output-rule-${this.uniqueId}-`+s;return t}set value(e){}get value(){var e={arg:{}};e.type=this.$elements.typedomain.typedInput("type"),e.domain=this.$elements.typedomain.typedInput("value");for(const t of this.argKeys)this.$elements[t].parent(".form-row").is(":visible")&&(e.arg[t]={type:this.$elements[t].typedInput("type"),value:this.$elements[t].typedInput("value")});for(const i of this.lightKeys)this.$elements[i].parent(".form-row").is(":visible")&&(e.arg[i]={direction:this.$elements[i+"_direction"].typedInput("type"),type:this.$elements[i].typedInput("type"),value:this.$elements[i].typedInput("value")});return e}get defaultCommand(){return{type:"deconz_state",domain:"lights",target:"state",arg:{on:{type:"keep"},bri:{direction:"set",type:"num"},sat:{direction:"set",type:"num"},hue:{direction:"set",type:"num"},ct:{direction:"set",type:"num"},xy:{direction:"set",type:"num"},alert:{type:"str"},effect:{type:"str"},colorloopspeed:{type:"num"},transitiontime:{type:"num"},command:{type:"str",value:"on"},payload:{type:"msg",value:"payload"},delay:{type:"num",value:2e3},target:{type:"state"},group:{type:"num"},scene_mode:{type:"single"},scene_call:{type:"num"},scene_name:{type:"str"},retryonerror:{type:"num",value:0},aftererror:{type:"continue"}}}}async init(e,t){this._index=t,e=$.extend(!0,this.defaultCommand,e),await this.generateTypeDomainField(this.container,{type:e.type,value:e.domain}),this.containers.light=$("<div>").appendTo(this.container),await this.generateLightOnField(this.containers.light,e.arg.on);for(const i of["bri","sat","hue","ct","xy"])await this.generateLightColorField(this.containers.light,i,e.arg[i]),"bri"===i&&await this.generateHR(this.containers.light);await this.generateHR(this.containers.light),await this.generateLightAlertField(this.containers.light,e.arg.alert),await this.generateLightEffectField(this.containers.light,e.arg.effect),await this.generateLightColorLoopSpeedField(this.containers.light,e.arg.colorloopspeed),this.containers.windows_cover=$("<div>").appendTo(this.container),await this.generateCoverOpenField(this.containers.windows_cover,e.arg.open),await this.generateCoverStopField(this.containers.windows_cover,e.arg.stop),await this.generateCoverLiftField(this.containers.windows_cover,e.arg.lift),await this.generateCoverTiltField(this.containers.windows_cover,e.arg.tilt),this.containers.scene_call=$("<div>").appendTo(this.container),await this.generateSceneModeField(this.containers.scene_call,e.arg.scene_mode),this.containers.scene_call_single=$("<div>").appendTo(this.containers.scene_call),await this.generateScenePickerField(this.containers.scene_call_single,e.arg.group+"."+e.arg.scene),await this.generateSceneGroupField(this.containers.scene_call_single,e.arg.group),await this.generateSceneSceneField(this.containers.scene_call_single,e.arg.scene),this.containers.scene_call_dynamic=$("<div>").appendTo(this.containers.scene_call),await this.generateSceneNameField(this.containers.scene_call_dynamic,e.arg.scene_name),this.containers.target=$("<div>").appendTo(this.container),await this.generateTargetField(this.containers.target,e.arg.target),this.containers.command=$("<div>").appendTo(this.container),await this.generateCommandField(this.containers.command,e.arg.command),this.containers.payload=$("<div>").appendTo(this.container),await this.generatePayloadField(this.containers.payload,e.arg.payload),this.containers.pause=$("<div>").appendTo(this.container),await this.generatePauseDelayField(this.containers.pause,e.arg.delay),this.containers.transition=$("<div>").appendTo(this.container),await this.generateHR(this.containers.transition),await this.generateCommonTransitionTimeField(this.containers.transition,e.arg.transitiontime),this.containers.common=$("<div>").appendTo(this.container),await this.generateHR(this.containers.common),await this.generateCommonOnErrorRetryField(this.containers.common,e.arg.retryonerror),await this.generateCommonOnErrorAfterField(this.containers.common,e.arg.aftererror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.updateShowHide(e.type,e.domain),await this.connect()}async connect(){await super.connect(),this.$elements.typedomain.on("change",(e,t,i)=>{this.updateShowHide(t,i)}),this.$elements.outputButton.on("click",async()=>{try{if("device"!==this.listEditor.mainEditor.subEditor.query.type)this.sendError("Error : The run command can only work with device list.",5e3);else{var t=this.value,i=this.listEditor.mainEditor.subEditor.device.value;if(0!==i.length||("deconz_state"===t.type&&"scene_call"===t.domain||"custom"===t.type&&"scene_call"===t.arg.target.type))if("pause"===t.type)this.sendError("Error : Can't test pause command.",5e3);else{for(var[s,n]of Object.entries(t.arg))if(["msg","flow","global","jsonata"].includes(n.type))return void this.sendError(`Error : Cant run this command because the value "${s}" is type "${n.type}".`,5e3);let e=RED.notify("Sending request...",{type:"info"});await $.post(this.NRCD+"/testCommand",{controllerID:this.listEditor.mainEditor.serverNode.id,device_list:i,command:t,delay:this.listEditor.mainEditor.subEditor.specific.value.delay}).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});e.close(),e=RED.notify("Ok",{timeout:1e3,type:"success"})}else this.sendError("Error : No device selected.",5e3)}}catch(e){let t=RED.notify(e.toString(),{type:"error",buttons:[{class:"error",click:()=>t.close()}]})}});const e=()=>{var e=this.$elements.scene_picker.multipleSelect("getSelects");1===e.length&&(this.$elements.group.off("change",t),this.$elements.scene.off("change",t),e=e[0].split("."),this.$elements.group.typedInput("type","num"),this.$elements.group.typedInput("value",e[0]),this.$elements.scene.typedInput("type","num"),this.$elements.scene.typedInput("value",e[1]),this.$elements.group.on("change",t),this.$elements.scene.on("change",t))},t=()=>{this.$elements.scene_picker.off("change",e),this.$elements.scene_picker.multipleSelect("setSelects","num"!==this.$elements.group.typedInput("type")||"num"!==this.$elements.group.typedInput("type")?[]:[this.$elements.group.typedInput("value")+"."+this.$elements.scene.typedInput("value")]),this.$elements.scene_picker.on("change",e)};this.$elements.scene_mode.on("change",()=>{var e="single"===this.$elements.scene_mode.typedInput("type");this.containers.scene_call_single.toggle(e),this.containers.scene_call_dynamic.toggle(!e)}),this.$elements.scene_picker.on("change",e),this.$elements.group.on("change",t),this.$elements.scene.on("change",t),this.$elements.scene_picker_refresh.on("click",()=>this.updateSceneList()),this.$elements.target.on("change",(e,t,i)=>{this.containers.command.toggle("scene_call"!==t)})}async updateShowHide(e,t){var i,s,n=[];switch(e){case"deconz_state":switch(t){case"lights":case"groups":n.push("light"),n.push("transition");break;case"covers":n.push("windows_cover");break;case"scene_call":n.push("scene_call"),await this.updateSceneList(),n.push("scene_call_"+("single"===this.$elements.scene_mode.typedInput("type")?"single":"dynamic"))}n.push("common");break;case"homekit":this.$elements.payload.typedInput("types",["msg","flow","global","json","jsonata"]),n.push("payload"),n.push("transition"),n.push("common");break;case"custom":n.push("target"),"scene_call"!==this.$elements.target.typedInput("type")&&n.push("command"),this.$elements.payload.typedInput("types",["msg","flow","global","str","num","bool","json","jsonata","date"]),n.push("payload"),n.push("transition"),n.push("common");break;case"pause":n.push("pause")}for([i,s]of Object.entries(this.containers))s.toggle(n.includes(i))}async updateSceneList(){this.$elements.scene_picker.multipleSelect("disable"),this.$elements.scene_picker.children().remove();var e=this.listEditor.mainEditor.subEditor.query;if(void 0!==e){var t=e.xhrParams,e=(t.queryType="json",t.query=JSON.stringify({match:{device_type:"groups"}}),await e.getItems({refresh:!0,keepOnlyMatched:!0},t));if(void 0!==e&&void 0!==e.LightGroup){for(const s of e.LightGroup){var i=$("<optgroup/>",{label:s.id+" - "+s.name});if(s.scenes&&0<s.scenes.length){for(const n of s.scenes)$(`<option>${n.id} - ${n.name}</option>`).attr("value",s.id+"."+n.id).appendTo(i);i.appendTo(this.$elements.scene_picker)}}this.$elements.scene_picker.multipleSelect("refresh").multipleSelect("enable"),this.$elements.scene_picker.multipleSelect("setSelects","num"!==this.$elements.group.typedInput("type")||"num"!==this.$elements.group.typedInput("type")?[]:[this.$elements.group.typedInput("value")+"."+this.$elements.scene.typedInput("value")])}}}async generateTypeDomainField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type";await this.generateTypedInputField(e,{id:this.elements.typedomain,i18n:i,value:t,addDefaultTypes:!1,typedInput:{default:"deconz_state",types:[this.generateTypedInputType(i,"deconz_state",{subOptions:["lights","covers","groups","scene_call"]}),this.generateTypedInputType(i,"homekit",{hasValue:!1}),this.generateTypedInputType(i,"custom",{hasValue:!1}),this.generateTypedInputType(i,"pause",{hasValue:!1})]}})}async generateLightOnField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.on";await this.generateTypedInputField(e,{id:this.elements.on,i18n:i,value:t,typedInput:{default:"keep",types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i,"toggle",{hasValue:!1})]}})}async generateLightColorField(e,t,i={}){var s=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields";let n=["num"];var a=[this.generateTypedInputType(s+".lightFields","set",{hasValue:!1})];switch(t){case"bri":n.push("str"),a.push(this.generateTypedInputType(s+".lightFields","inc",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","dec",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","detect_from_value",{hasValue:!1}));break;case"ct":n.push("str"),n.push(this.generateTypedInputType(s+".ct","deconz",{subOptions:["cold","white","warm"]})),a.push(this.generateTypedInputType(s+".lightFields","inc",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","dec",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","detect_from_value",{hasValue:!1}));break;case"xy":n=["json"]}await this.generateDoubleTypedInputField(e,{id:this.elements[t+"_direction"],i18n:s+"."+t,addDefaultTypes:!1,value:{type:i.direction},typedInput:{types:a}},{id:this.elements[t],value:{type:i.type,value:["xy"===t&&void 0===i.value?"[]":i.value]},typedInput:{types:n}})}async generateLightAlertField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.alert";await this.generateTypedInputField(e,{id:this.elements.alert,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"deconz",{subOptions:["none","select","lselect"]})]}})}async generateLightEffectField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.effect";await this.generateTypedInputField(e,{id:this.elements.effect,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"deconz",{subOptions:["none","colorloop"]})]}})}async generateLightColorLoopSpeedField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.colorloopspeed";await this.generateTypedInputField(e,{id:this.elements.colorloopspeed,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCoverOpenField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.open";await this.generateTypedInputField(e,{id:this.elements.open,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i,"toggle",{hasValue:!1})]}})}async generateCoverStopField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.stop";await this.generateTypedInputField(e,{id:this.elements.stop,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]})]}})}async generateCoverLiftField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.lift";await this.generateTypedInputField(e,{id:this.elements.lift,i18n:i,value:t,typedInput:{types:["num","str",this.generateTypedInputType(i,"stop",{hasValue:!1})]}})}async generateCoverTiltField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.tilt";await this.generateTypedInputField(e,{id:this.elements.tilt,i18n:i,value:t,typedInput:{types:["num"]}})}async generateSceneModeField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.mode";await this.generateTypedInputField(e,{id:this.elements.scene_mode,i18n:i,value:t,addDefaultTypes:!1,typedInput:{types:[this.generateTypedInputType(i,"single",{hasValue:!1}),this.generateTypedInputType(i,"dynamic",{hasValue:!1})]}})}async generateScenePickerField(e,t=0){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.picker",s=await this.generateSimpleListField(e,{id:this.elements.scene_picker,i18n:i}),i=(s.addClass("multiple-select"),s.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!0,singleRadio:!0,hideOptgroupCheckboxes:!0,showClear:!0,selectAll:!1,filter:!0,filterPlaceholder:this.getI18n(i,"filter_place_holder"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),container:".node-input-output-container-row"}),$("<a/>",{id:this.elements.scene_picker_refresh,class:"red-ui-button",style:"margin-left:10px;"}));this.createIconElement(this.getIcon("refresh"),i),s.closest(".form-row").append(i)}async generateSceneGroupField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.group";await this.generateTypedInputField(e,{id:this.elements.group,i18n:i,value:t,typedInput:{types:["num"]}})}async generateSceneSceneField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene";await this.generateTypedInputField(e,{id:this.elements.scene,i18n:i,value:t,typedInput:{types:["num","str",this.generateTypedInputType(i,"deconz",{subOptions:["next","prev"]})]}})}async generateSceneNameField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene_name";await this.generateTypedInputField(e,{id:this.elements.scene_name,i18n:i,value:t,typedInput:{types:["str","re"]}})}async generateTargetField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.target";await this.generateTypedInputField(e,{id:this.elements.target,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"attribute",{hasValue:!1}),this.generateTypedInputType(i,"state",{hasValue:!1}),this.generateTypedInputType(i,"config",{hasValue:!1}),this.generateTypedInputType(i,"scene_call",{hasValue:!1})]}})}async generateCommandField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.command";await this.generateTypedInputField(e,{id:this.elements.command,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"object",{hasValue:!1})]}})}async generatePayloadField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.payload";await this.generateTypedInputField(e,{id:this.elements.payload,i18n:i,value:t,addDefaultTypes:!1,typedInput:{types:["msg","flow","global","str","num","bool","json","jsonata","date"]}})}async generatePauseDelayField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.pause.fields.delay";await this.generateTypedInputField(e,{id:this.elements.delay,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCommonTransitionTimeField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.transitiontime";await this.generateTypedInputField(e,{id:this.elements.transitiontime,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCommonOnErrorRetryField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.retryonerror";await this.generateTypedInputField(e,{id:this.elements.retryonerror,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCommonOnErrorAfterField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.aftererror";await this.generateTypedInputField(e,{id:this.elements.aftererror,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"continue",{hasValue:!1}),this.generateTypedInputType(i,"stop",{hasValue:!1})]}})}}class DeconzCommandListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"command"}get buttons(){var e,t=[],i=this.NRCD+"/server:editor.inputs.commands.type";for(const[s,n]of Object.entries(this.options.type))n&&(e=this.getI18n(i+".options."+s,"label"),t.push({label:this.getI18n(i+".add_button","label",{type:e}),icon:this.getIcon(this.getI18n(i+".add_button","icon"),!0),title:this.getI18n(i+".add_button","title",{type:e}),click:()=>this.$elements.list.editableList("addItem",{type:s})}));return t}async init(e){await super.init(e),await this.initList(DeconzCommandEditor,this.node.commands)}} | ||
class DeconzEditor{constructor(e,t={}){this.node=e,this.options=t}get elements(){return{}}get NRCD(){return"node-red-contrib-deconz"}findElements(){this.$elements={},Object.keys(this.elements).forEach(e=>{this.$elements[e]=this.findElement(this.elements[e])})}findElement(e){return"#"!==e.charAt(0)&&"."!==e.charAt(0)&&(e="#"+e),$(e)}async init(){this.findElements()}async connect(){}sendError(e,t=1e4){let i=RED.notify(e,{timeout:t,type:"error",buttons:[{text:"Ok",class:"primary",click:()=>i.close()}]})}getIcon(e,t=!1){return"deconz"===e?"icons/node-red-contrib-deconz/icon-color.png":"homekit"===e?"icons/node-red-contrib-deconz/homekit-logo.png":RED.nodes.fontAwesome.getIconList().includes("fa-"+e)?`${t?"fa ":""}fa-`+e:e}createIconElement(e,t,i=!1){if("fa-"===e.substr(0,3)){if(RED.nodes.fontAwesome.getIconUnicode(e))return void $("<i/>").appendTo(t).addClass("fa "+e+(i?" fa-lg":""));e=RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"}$("<div/>").appendTo(t).css("backgroundImage","url("+e+")")}getI18n(e,t,i={}){let s=e;t&&(s+="."+t),i.defaultValue="_deconz_undefined_";var n=RED._(s,i);if("_deconz_undefined_"!==n)return n}async generateSimpleListField(e,t){var i=$("<select/>",{id:t.id});if(t.choices)for(var[s,n]of t.choices)i.append($("<option/>").attr("value",s).html(RED._(n)));var a=await this.generateInputWithLabel(i,t);return e.append(a),void 0!==t.currentValue&&i.val(t.currentValue),i}async generateTypedInput(e,t){var i=$("<input/>",{id:e,placeholder:RED._(t)}),s=$("<input/>",{id:e+"_type",type:"hidden"});return i.append(s),i}async initTypedInput(e,t){t=$.extend({addDefaultTypes:!0,displayOnlyIcon:!1,value:{},width:"200px"},t);var i=$.extend({types:["msg","flow","global"]},t.typedInput);if(i.typeField=t.typeId,t.addDefaultTypes)for(var s of["msg","flow","global","jsonata"])i.types.includes(s)||i.types.push(s);if(t.displayOnlyIcon){let n=this;var a,o=function(e,t){let i;for(const s of this.typeList)"object"==typeof s&&s.value===this.propertyType&&(i=s);void 0!==i&&void 0!==i.icon&&(this.oldValue=this.input.val(),this.input.val(""),this.valueLabelContainer.hide(),n.createIconElement(i.icon,this.selectLabel),this.selectTrigger.addClass("red-ui-typedInput-full-width"),this.selectLabel.show())};for(a of i.types)"string"!=typeof a&&(a.hasValue=!0,a.valueLabel=o)}e.typedInput(i),void 0!==t.width&&e.typedInput("width",t.width),t.value&&(void 0!==t.value.type&&e.typedInput("type",t.value.type),void 0!==t.value.value)&&e.typedInput("value",t.value.value)}async generateTypedInputField(e,t){var i=await this.generateTypedInput(t.id,this.getI18n(t.i18n,"placeholder")),s=await this.generateInputWithLabel(i,t);return e.append(s),await this.initTypedInput(i,t),i}async generateDoubleTypedInputField(e,t,i){var s=await this.generateTypedInput(t.id,t.placeholder),n=await this.generateInputWithLabel(s,t),a=await this.generateTypedInput(i.id,i.placeholder);n.append(a),e.append(n),t.displayOnlyIcon=!0,t.width="50px",i.width="150px",await this.initTypedInput(s,t),await this.initTypedInput(a,i)}generateTypedInputType(e,t,i={}){if(i.value=t,void 0===i.label&&(i.label=this.getI18n(e,`options.${t}.label`,{})||t),!1!==i.icon&&void 0===i.icon&&(i.icon=this.getIcon(this.getI18n(e,`options.${t}.icon`))),i.icon&&"fa-"===i.icon.substr(0,3)&&(i.icon="fa "+i.icon),Array.isArray(i.subOptions)){Array.isArray(i.options)||(i.options=[]);for(const s of i.subOptions)i.options.push(this.generateTypedInputType(e+".options."+t,"string"==typeof s?s:s.name,{icon:!1}))}return i}async generateCheckboxField(e,t){var i=$("<input/>",{id:t.id,type:"checkbox",style:"display: table-cell; width: 14px;vertical-align: top;margin-right: 5px",checked:t.currentValue}),i=await this.generateInputWithLabel(i,t);i.append($("<span/>").html(RED._(t.descText)).css("display","table-cell")),e.append(i)}async generateInputWithLabel(e,t={}){var i,s=$("<div/>",{class:"form-row",style:"padding:5px;margin:0;display:table;min-width:420px;"}),n=e.attr("id");return n&&((i=$("<label/>")).attr("for",n),i.attr("class","l-width"),i.attr("style","display:table-cell;"),void 0===t.title&&(t.title=this.getI18n(t.i18n,"title")),t.title&&i.attr("title",this.getI18n(t.i18n,"title")),void 0===t.icon&&(t.icon=this.getI18n(t.i18n,"icon")),t.icon&&(this.createIconElement(this.getIcon(t.icon),i),i.append(" ")),void 0===t.label&&(t.label=this.getI18n(t.i18n,"label")),t.label&&i.append(`<span>${t.label}</span>`),s.append(i)),e.css("display","table-cell"),s.append(e),s}async generateHR(e,t="5px",i="50px"){e.append(`<hr style="margin: ${t} ${i};">`)}async generateSeparator(e,t){e.append(`<div class="separator">${RED._(t)}</div>`)}static versionCompare(e,t,i={}){const s=i&&i.lexicographical;var n=i&&i.zeroExtend;let a=e.split("."),o=t.split(".");function r(e){return(s?/^\d+[A-Za-z]*$/:/^\d+$/).test(e)}if(!a.every(r)||!o.every(r))return NaN;if(n){for(;a.length<o.length;)a.push("0");for(;o.length<a.length;)o.push("0")}s||(a=a.map(Number),o=o.map(Number));for(let l=0;l<a.length;++l){if(o.length===l)return 1;if(a[l]!==o[l])return a[l]>o[l]?1:-1}return a.length!==o.length?-1:0}}class DeconzMainEditor extends DeconzEditor{constructor(e,t={}){if(super(e,$.extend(!0,{have:{statustext:!0,query:!0,device:!0,output_rules:!1,commands:!1,specific:!1},device:{batteryFilter:!1},output_rules:{format:{single:!0,array:!1,sum:!1,average:!1,min:!1,max:!1},type:{attribute:!0,state:!0,config:!0,homekit:!1,scene_call:!1}},commands:{type:{deconz_state:!0,homekit:!0,custom:!0,pause:!0}},specific:{api:{},output:{},server:{}}},t)),this.subEditor={},this.initDone=!1,this.options.have.statustext&&(this.subEditor.statustext=new DeconzStatusTextEditor(this.node,this.options.statustext)),this.options.have.device&&(this.subEditor.device=new DeconzDeviceEditor(this.node,this.options.device)),this.options.have.query&&(this.subEditor.query=new DeconzQueryEditor(this.node,this.options.query)),this.options.have.specific)switch(this.node.type){case"deconz-api":this.subEditor.specific=new DeconzSpecificApiEditor(this.node,this.options.specific.api);break;case"deconz-output":this.subEditor.specific=new DeconzSpecificOutputEditor(this.node,this.options.specific.output);break;case"deconz-server":this.subEditor.specific=new DeconzSpecificServerEditor(this.node,this.options.specific.server)}this.options.have.output_rules&&(this.subEditor.output_rules=new DeconzOutputRuleListEditor(this.node,this.options.output_rules)),this.options.have.commands&&(this.subEditor.commands=new DeconzCommandListEditor(this.node,this.options.commands))}get elements(){return{tipBox:"node-input-tip-box",server:"node-input-server"}}async configurationMigration(){if(!((this.node.config_version||0)>=this.node._def.defaults.config_version.value)){var e={};for(const o of Object.keys(this.node._def.defaults))e[o]=this.node[o];var t={id:this.node.id,type:this.node.type,config:JSON.stringify(e)};let i="Error while migrating the configuration of the node from version "+(this.node.config_version||0)+" to version "+this.node._def.defaults.config_version.value+".";t=await $.getJSON(this.NRCD+"/configurationMigration",t).catch((e,t)=>{this.$elements.tipBox.append(`<div class="form-tips form-warning"><p>Migration errors:</p><p>${i}</p></div>`)});if(t&&!t.notNeeded){if(t.new)for(var[s,n]of Object.entries(t.new))this.node[s]=n;if(t.delete&&Array.isArray(t.delete))for(const r of t.delete)delete this.node[r];var a=e=>"node-red-contrib-deconz"===e.substr(0,23)?RED._(e):e;t.errors&&Array.isArray(t.errors)&&0<t.errors.length&&this.$elements.tipBox.append('<div class="form-tips form-warning"><p>Migration errors:</p><ul>'+`<li>${t.errors.map(a).join("</li><li>")}</li>`+"</ul></div>"),t.info&&Array.isArray(t.info)&&0<t.info.length&&this.$elements.tipBox.append('<div class="form-tips"><p>Migration info:</p><ul>'+`<li>${t.info.map(a).join("</li><li>")}</li>`+"</ul></div>")}}}async init(){await new Promise(e=>setTimeout(e,100)),await super.init(),await this.configurationMigration(),this.initPromises=[];for(const t of Object.values(this.subEditor))this.initPromises.push(t.init(this));await Promise.all(this.initPromises),this.initDone=!0,delete this.initPromises;var e=[];for(const i of Object.values(this.subEditor))e.push(i.connect());await Promise.all(e)}get serverNode(){return"deconz-server"===this.node.type?this.node:RED.nodes.node(this.$elements.server.val())}async isInitialized(){this.initDone||await Promise.all(this.initPromises)}async updateQueryDeviceDisplay(e){var t=this.subEditor.query.$elements.select.typedInput("type");switch(t){case"device":await this.subEditor.device.updateList(e);break;case"json":case"jsonata":this.subEditor.query.$elements.select.typedInput("validate")&&await this.subEditor.query.updateList(e)}await this.subEditor.device.display("device"===t),await this.subEditor.query.display("device"!==t)}oneditsave(){var e;this.options.have.output_rules&&(e=this.subEditor.output_rules.value,this.node.outputs=e.length,this.node.output_rules=e),this.options.have.commands&&(this.node.commands=this.subEditor.commands.value),this.options.have.specific&&(this.node.specific=this.subEditor.specific.value)}}class DeconzStatusTextEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({allowedTypes:["msg","jsonata"]},t))}get elements(){return{statustext:"node-input-statustext"}}async init(e){await super.init(),this.mainEditor=e,this.initTypedInput()}initTypedInput(){var e=[];this.mainEditor.options.have.statustext&&e.push({value:"auto",label:RED._(this.NRCD+"/server:editor.inputs.statustext.options.auto"),icon:`icons/${this.NRCD}/icon-color.png`,hasValue:!1}),this.$elements.statustext.typedInput({type:"auto",types:e.concat(this.options.allowedTypes),typeField:`#${this.elements.statustext}_type`})}}class DeconzDeviceListEditor extends DeconzEditor{constructor(e,t={}){super(e,t)}get xhrURL(){return this.NRCD+"/itemlist"}get xhrParams(){return{controllerID:this.mainEditor.serverNode.id,forceRefresh:this.options.refresh}}async display(e=!0){if(this.$elements.showHide)return e?this.$elements.showHide.show():this.$elements.showHide.hide(),this.$elements.showHide.promise()}async getItems(e,t){t.forceRefresh=e.refresh;var i=await $.getJSON(this.xhrURL,t).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});if(!i||!i.error_message)return this.formatItemList(i.items,e.keepOnlyMatched);console.warn(i.error_message),RED.notify("Warning : "+i.error_message,{type:"warning",timeout:1e4})}async updateList(e){var t,i;e=$.extend({refresh:!0},e),this.mainEditor.serverNode&&(t=this.$elements.list,i=this.xhrParams,!0===this.options.batteryFilter&&(e.keepOnlyMatched=!0,i.query=JSON.stringify({type:"match",method:"OR",match:{"config.battery":{type:"complex",operator:"!==",value:void 0},"state.battery":{type:"complex",operator:"!==",value:void 0}}})),i=await this.getItems(e,i),t.children().remove(),i&&this.generateHtmlItemList(i,this.$elements.list),t.multipleSelect("refresh"),i)&&t.multipleSelect("enable")}formatItemList(e,t=!1){let s={};var i=(e,i)=>{e.forEach(e=>{var t=e.type;void 0===s[t]&&(s[t]=[]),e.query_match=i,s[t].push(e)})};return i(e.matched,!0),!1===t&&i(e.rejected,!1),s}generateHtmlItemList(e,t){var i,s,n=this.constructor===DeconzQueryEditor;for([i,s]of Object.entries(e).sort((e,t)=>{var i=e[0].toLowerCase(),s=t[0].toLowerCase();return i<s?-1:s<i?1:0})){var a=$("<optgroup/>").attr("label",i);for(const r of s.sort((e,t)=>{var i=e.name.toLowerCase(),s=t.name.toLowerCase();return i<s?-1:s<i?1:0})){let e=r.name;"groups"===r.device_type&&(e+=" (lights: "+r.lights.length,r.scenes.length&&(e+=", scenes: "+r.scenes.length),e+=")");var o=$("<option>"+e+"</option>").attr("value",r.device_path);n&&r.query_match&&o.attr("selected",""),o.appendTo(a)}a.appendTo(t)}}}class DeconzQueryEditor extends DeconzDeviceListEditor{constructor(e,t={}){super(e,$.extend({allowedTypes:["json","jsonata"]},t))}get elements(){return{select:"node-input-query",list:"node-input-query_result",showHide:".deconz-query-selector",refreshButton:"#force-refresh-query-result"}}get type(){return this.$elements.select.typedInput("type")}set type(e){this.$elements.list.typedInput("type",e)}get value(){return this.$elements.select.typedInput("value")}set value(e){this.$elements.list.typedInput("value",e)}get xhrParams(){var e=super.xhrParams;return e.query=this.value,e.queryType=this.type,e.nodeID=this.node.id,e}async init(e){await super.init(),this.mainEditor=e,this.initTypedInput(),this.$elements.list.multipleSelect({maxHeight:300,dropWidth:320,width:320,single:!1,selectAll:!1,filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),numberDisplayed:1,disableIfEmpty:!0,showClear:!1,hideOptgroupCheckboxes:!0,filterGroup:!0,onClick:e=>{this.$elements.list.multipleSelect(e.selected?"uncheck":"check",e.value)}}),await this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0})}initTypedInput(){var e=[];this.mainEditor.options.have.device&&e.push({value:"device",label:RED._(this.NRCD+"/server:editor.inputs.device.query.options.device"),icon:`icons/${this.NRCD}/icon-color.png`,hasValue:!1}),this.$elements.select.typedInput({type:"text",types:e.concat(this.options.allowedTypes),typeField:"#node-input-search_type"})}async connect(){await super.connect(),this.$elements.select.on("change",()=>{this.mainEditor.updateQueryDeviceDisplay({useSavedData:!0}),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()}),this.$elements.refreshButton.on("click",()=>{this.updateList(),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()})}}class DeconzDeviceEditor extends DeconzDeviceListEditor{constructor(e,t={}){super(e,$.extend({batteryFilter:!1},t))}get elements(){return{list:"node-input-device_list",showHide:".deconz-device-selector",refreshButton:"#force-refresh"}}get value(){return this.$elements.list.multipleSelect("getSelects")}set value(e){this.$elements.list.multipleSelect("setSelects",e)}async init(e){await super.init(),this.mainEditor=e,this.$elements.list.multipleSelect({maxHeight:300,dropWidth:320,width:320,single:"multiple"!==this.$elements.list.attr("multiple"),filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),showClear:!0})}async connect(){await super.connect();var e=()=>{this.updateList($.extend(this.options,{useSelectedData:!0})),this.mainEditor.options.have.output_rules&&this.mainEditor.subEditor.output_rules.refresh()};this.mainEditor.$elements.server.on("change",e),this.$elements.refreshButton.on("click",e),this.mainEditor.options.have.output_rules&&this.$elements.list.on("change",()=>{this.mainEditor.subEditor.output_rules.refresh()})}async updateList(e){let t;(e=$.extend({useSavedData:!1,useSelectedData:!1},e)).useSelectedData&&(t=this.$elements.list.multipleSelect("getSelects")),await super.updateList(e),e.useSavedData&&Array.isArray(this.node.device_list)?this.$elements.list.multipleSelect("setSelects",this.node.device_list):e.useSelectedData&&Array.isArray(t)&&this.$elements.list.multipleSelect("setSelects",t)}}class DeconzSpecificApiEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{container:"deconz-api-form",name:"node-config-input-name",method:"node-config-input-method",endpoint:"node-config-input-endpoint",payload:"node-config-input-payload"}}get default(){return{name:"",method:{type:"GET"},endpoint:{type:"str",value:"/"},payload:{type:"json",value:"{}"}}}async init(){this.node.specific=$.extend(!0,this.default.specific,this.node.specific);var e=this.findElement(this.elements.container);await this.generateMethodField(e,this.node.specific.method),await this.generateEndpointField(e,this.node.specific.endpoint),await this.generatePayloadField(e,this.node.specific.payload),await super.init()}async connect(){await super.connect()}get value(){return{method:{type:this.$elements.method.typedInput("type"),value:this.$elements.method.typedInput("value")},endpoint:{type:this.$elements.endpoint.typedInput("type"),value:this.$elements.endpoint.typedInput("value")},payload:{type:this.$elements.payload.typedInput("type"),value:this.$elements.payload.typedInput("value")}}}set value(e){this.$elements.name.val(e.name);for(var t of["method","endpoint","payload"])this.$elements[t].typedInput("type",e[t].type),this.$elements[t].typedInput("value",e[t].value);for(const i of Object.values(this.$elements))i.trigger("change")}async generateMethodField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.method";await this.generateTypedInputField(e,{id:this.elements.method,i18n:i,value:t,width:"250px",typedInput:{types:[this.generateTypedInputType(i,"GET",{hasValue:!1}),this.generateTypedInputType(i,"POST",{hasValue:!1}),this.generateTypedInputType(i,"PUT",{hasValue:!1}),this.generateTypedInputType(i,"DELETE",{hasValue:!1})]}})}async generateEndpointField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.endpoint";await this.generateTypedInputField(e,{id:this.elements.endpoint,i18n:i,value:t,width:"250px",typedInput:{types:["str"]}})}async generatePayloadField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.api.payload";await this.generateTypedInputField(e,{id:this.elements.payload,i18n:i,value:t,width:"250px",typedInput:{types:["json","jsonata"]}})}}class DeconzSpecificOutputEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{container:"specific-container",delay:"node-input-delay",result:"node-input-result"}}get default(){return{delay:{type:"num",value:50},result:{type:"at_end"}}}async init(){this.node.specific=$.extend(!0,this.default,this.node.specific);var e=this.findElement(this.elements.container);await this.generateSeparator(e,this.NRCD+"/server:editor.inputs.separator.specific"),await this.generateDelayField(e,this.node.specific.delay),await this.generateResultField(e,this.node.specific.result),await super.init()}async generateDelayField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.output.delay";await this.generateTypedInputField(e,{id:this.elements.delay,i18n:i,value:t,width:"250px",typedInput:{types:["num"]}})}async generateResultField(e,t={}){var i=this.NRCD+"/server:editor.inputs.specific.output.result";await this.generateTypedInputField(e,{id:this.elements.result,i18n:i,value:t,width:"250px",typedInput:{types:[this.generateTypedInputType(i,"never",{hasValue:!1}),this.generateTypedInputType(i,"after_command",{hasValue:!1}),this.generateTypedInputType(i,"at_end",{hasValue:!1})]}})}async connect(){await super.connect()}get value(){return{delay:{type:this.$elements.delay.typedInput("type"),value:this.$elements.delay.typedInput("value")},result:{type:this.$elements.result.typedInput("type"),value:this.$elements.result.typedInput("value")}}}}class DeconzSpecificServerEditor extends DeconzEditor{constructor(e,t={}){super(e,$.extend({},t))}get elements(){return{name:"node-config-input-name",ip:"node-config-input-ip",port:"node-config-input-port",apikey:"node-config-input-secured_apikey",ws_port:"node-config-input-ws_port",secure:"node-config-input-secure",polling:"node-config-input-polling",getSettingsButton:"node-contrib-deconz-get-settings"}}get default(){return{name:"",ip:"",port:"",apikey:"",ws_port:"",secure:!1,polling:15}}get xhrURL(){return this.NRCD+"/serverAutoconfig"}async init(){this.node.specific=$.extend(!0,this.default,this.node.specific),await super.init(),this.node.migration_secured_apikey&&(this.$elements.apikey.val(this.node.migration_secured_apikey),this.$elements.apikey.trigger("change"))}async connect(){await super.connect(),this.$elements.getSettingsButton.on("click",()=>this.discoverParams())}async discoverParams(e){void 0===e&&(e={});let t,s=!1,n=()=>{t&&"function"==typeof t.close&&t.close(),s=!0};t=RED.notify("<p>Trying to find the server settings, please wait...<br>This can take up to 15 seconds.</p>",{modal:!0,fixed:!0,type:"info",buttons:[{text:"Cancel",class:"primary",click:n}]});try{var a=Object.assign({},this.value,e);void 0===a.discoverParam&&(a.discoverParam={}),a.discoverParam.devicetype="Node-Red Deconz Plugin"+(this.node?" id:"+this.node.id:"");let i=await $.getJSON(this.xhrURL,{config:JSON.stringify(a)}).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});if(!s)if(i.error){let e=`<p>Error ${i.error.code}: ${i.error.description}</p>`;var o=[{text:"Cancel",click:n}];switch(i.error.code){case"GATEWAY_CHOICE":e+="<p>There is multiple Deconz device in you network, please select the one you want to configure.</p>";let t=this;for(const[r,l]of i.error.gateway_list.entries())o.push({text:`#${r+1}: `+l.name,id:"node-red-contrib-deconz-gateway-id-"+r,class:"primary",click:()=>{return e=l.bridge_id,n(),e&&(i.currentSettings.discoverParam.targetGatewayID=e),void t.discoverParams(i.currentSettings);var e}});o.push(o.shift());break;case"DECONZ_ERROR":101===i.error.type&&(o.unshift({text:"I pressed the link button",class:"primary",click:()=>{n(),this.discoverParams(i.currentSettings)}}),e=(e+="<p>The reason why the request failed is that the gateway was not unlocked. This mechanism is needed to prevent anybody from access to the gateway without being permitted to do so.</p><ul><li>In a new browser tab open the <a href='http://phoscon.de/pwa/' target='_blank'>Phoscon App</a></li><li>Click on Menu -> Settings -> Gateway</li><li>Click on \"Advanced\" button</li><li>Click on the \"Authenticate app\" button</li></ul>")+`<p>Within 60 seconds after unlocking the gateway, click on the button "${o[0].text}".</p>`);break;default:o[o.length-1].text="Cancel"}e+=`<p>Logs:</p><pre>${i.log.join("\n")}</pre>`,n(),t=RED.notify(e,{modal:!0,fixed:!0,type:"error",buttons:o})}else i.success?(n(),t=RED.notify("<p>Settings fetched successfully !</p>",{modal:!1,fixed:!1,type:"success"}),this.value=i.currentSettings):(n(),t=RED.notify(`<p>Unknown error : ${JSON.stringify(i)}</p>`,{modal:!0,fixed:!0,type:"error",buttons:[{text:"Ok",class:"primary",click:n}]}))}catch(e){n(),t=RED.notify(`<p>Error while processing request: ${e.toString()}</p>`,{type:"error"})}}get value(){return{name:this.$elements.name.val(),ip:this.$elements.ip.val(),port:this.$elements.port.val(),apikey:this.$elements.apikey.val(),ws_port:this.$elements.ws_port.val(),secure:this.$elements.secure.prop("checked"),polling:this.$elements.polling.val()}}set value(e){this.$elements.name.val(e.name),this.$elements.ip.val(e.ip),this.$elements.port.val(e.port),this.$elements.apikey.val(e.apikey),this.$elements.ws_port.val(e.ws_port),this.$elements.secure.prop("checked",e.secure),this.$elements.polling.val(e.polling);for(const t of Object.values(this.$elements))t.trigger("change")}}class DeconzListItemEditor extends DeconzEditor{constructor(e,t,i,s={}){super(e,s),this.listEditor=t,i.uniqueId(),this.uniqueId=i.attr("id"),this.container=i}set index(e){void 0!==e&&this.$elements&&this.$elements.outputButton&&this.$elements.outputButton.find(".node-input-rule-index").html(e+1),this._index=e}get index(){return this._index}async init(){await this.generateOutputButton(this.container.children().first()),await super.init()}async generateOutputButton(e){$("<a/>",{id:this.elements.outputButton,class:"red-ui-button top-right-badge",title:RED._(this.options.button_title)}).append(` → <span class="node-input-rule-index">${this.index+1}</span> `).appendTo(e)}}class DeconzListItemListEditor extends DeconzEditor{constructor(e,t={}){super(e,t),this.items={}}get listType(){return"item"}get buttons(){return[]}async init(e){await super.init(),this.mainEditor=e}async initList(n,e=[]){var t=this.buttons,i=0===t.length||DeconzEditor.versionCompare(RED.settings.version,"1.3.0")<0;this.$elements.list.editableList({sortable:!0,removable:!0,height:"auto",addButton:i,buttons:t,addItem:(e,t,i)=>{var s=new n(this.node,this,e,this.options);i.uniqueId=s.uniqueId,(this.items[i.uniqueId]=s).init(i,t)},removeItem:e=>{if(!e.uniqueId||!this.items[e.uniqueId])throw new Error(`Error while removing the ${this.listType}, the ${this.listType} ${e.uniqueId} does not exist.`);var t=this.items[e.uniqueId].index;delete this.items[e.uniqueId];for(const e of Object.values(this.items))e.index>t&&e.index--},sortItems:e=>{e.each((e,t)=>{if(!this.items[t.attr("id")])throw new Error(`Error while moving the ${this.listType}, the ${this.listType} ${e+1} does not exist.`);this.items[t.attr("id")].index=e})}}),0<e.length&&this.$elements.list.editableList("addItems",e)}get value(){var e=[];for(const t of Object.values(this.items).sort((e,t)=>e.index-t.index))e.push(t.value);return e}refresh(){}}class DeconzOutputRuleEditor extends DeconzListItemEditor{constructor(e,t,i,s={}){super(e,t,i,s=$.extend({enableEachState:!0},s))}get elements(){var e={};for(const t of["format","type","payload","output","onstart","onerror","outputButton"])e[t]=`node-input-output-rule-${this.uniqueId}-`+t;return e}get value(){var e={};switch(e.type=this.$elements.type.val(),e.format=this.$elements.format.val(),e.type){case"attribute":case"state":case"config":"deconz-input"===this.node.type&&(e.output=this.$elements.output.val()),["deconz-input","deconz-battery"].includes(this.node.type)&&(e.onstart=this.$elements.onstart.is(":checked")),["deconz-input","deconz-get"].includes(this.node.type)&&(e.payload=this.$elements.payload.multipleSelect("getSelects"));break;case"homekit":["deconz-input","deconz-battery"].includes(this.node.type)&&(e.onstart=this.$elements.onstart.is(":checked")),"deconz-input"===this.node.type&&(e.onerror=this.$elements.onerror.is(":checked")),["deconz-input","deconz-get"].includes(this.node.type)&&(e.payload=this.$elements.payload.multipleSelect("getSelects"))}return e}get defaultRule(){var e={type:"state",payload:["__complete__"],format:"single"};return"deconz-input"===this.node.type&&(e.output="always",e.onstart=!0,e.onerror=!0),"deconz-battery"===this.node.type&&(e.onstart=!0),e}async init(e,t){this._index=t,e=$.extend(!0,this.defaultRule,e),await this.generatePayloadTypeField(this.container,e.type),["deconz-input","deconz-get"].includes(this.node.type)&&await this.generatePayloadField(this.container),await this.generatePayloadFormatField(this.container,e.format),"deconz-input"===this.node.type&&await this.generateOutputField(this.container,(void 0!==e.output?e:this.defaultRule).output),["deconz-input","deconz-battery"].includes(this.node.type)&&await this.generateOnStartField(this.container,(void 0!==e.onstart?e:this.defaultRule).onstart),"deconz-input"===this.node.type&&await this.generateOnErrorField(this.container,(void 0!==e.onerror?e:this.defaultRule).onerror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.initPayloadList(e.payload),await this.updateShowHide(e.type),await this.connect()}async connect(){await super.connect(),this.$elements.type.on("change",()=>{var e=this.$elements.type.val();["attribute","state","config","homekit"].includes(e)&&this.updatePayloadList(),this.updateShowHide(e)}),this.$elements.outputButton.on("click",()=>{try{var t=RED.nodes.filterLinks({source:this.node,sourcePort:this.index}).map(e=>{var t=e.target.type;return""!==e.target.name?t+":"+e.target.name:void 0!==e.target._def.label?t+":"+e.target._def.label():t});let e=RED.notify(`The output ${this.index+1} is sending message to ${t.length} nodes :<br>`+t.join("<br>"),{modal:!0,timeout:5e3,buttons:[{text:"okay",class:"primary",click:()=>e.close()}]})}catch(e){this.sendError("This is using not documented API so can be broken at anytime.<br>Error while getting connected nodes: "+e.toString())}})}async updateShowHide(e){switch(e){case"attribute":case"state":case"config":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").show(),this.$elements.onstart.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").hide();break;case"homekit":this.$elements.payload.closest(".form-row").show(),this.$elements.output.closest(".form-row").hide(),this.$elements.onstart.closest(".form-row").show(),this.$elements.onerror.closest(".form-row").show();break;case"scene_call":this.$elements.payload.closest(".form-row").hide(),this.$elements.output.closest(".form-row").hide(),this.$elements.onstart.closest(".form-row").hide(),this.$elements.onerror.closest(".form-row").hide()}}async updatePayloadList(){if(this.listEditor.mainEditor.serverNode){this.$elements.payload.multipleSelect("disable"),this.$elements.payload.children().remove();var t=this.listEditor.mainEditor.subEditor.query.type,i=this.listEditor.mainEditor.subEditor.device.value,s=this.$elements.type.val();if(["attribute","state","config","homekit"].includes(s)){var n=this.NRCD+"/server:editor.inputs.outputs.payload";let e="";if("homekit"===s?e+='<option value="__auto__">'+RED._(n+".options.auto")+"</option>":(e+='<option value="__complete__">'+RED._(n+".options.complete")+"</option>",!0===this.options.enableEachState&&(e+='<option value="__each__">'+RED._(n+".options.each")+"</option>")),this.$elements.payload.html(e),"device"===t){var a=await $.getJSON(this.NRCD+`/${s}list`,{controllerID:this.listEditor.mainEditor.serverNode.id,devices:JSON.stringify(this.listEditor.mainEditor.subEditor.device.value)});for(const l of"attribute"===s?["attribute","state","config"]:[s]){let e=this.getI18n(n+".group_label."+l);void 0===e&&(e=l);var o=$("<optgroup/>",{label:e});for(const p of Object.keys(a.count[l]).sort()){let e=a.sample[l][p];e="string"==typeof e?`"${e}"`:Array.isArray(e)?`[${e.toString()}]`:null===e||void 0===e?"NULL":e.toString();let t;var r=a.count[l][p];t=r===i.length?RED._(n+".item_list",{name:p,sample:e}):RED._(n+".item_list_mix",{name:p,sample:e,item_count:r,device_count:i.length}),$("<option>"+t+"</option>").attr("value","attribute"===s&&"attribute"!==l?l+"."+p:p).appendTo(o)}$.isEmptyObject(a.count[l])||o.appendTo(this.$elements.payload)}}this.$elements.payload.multipleSelect("refresh").multipleSelect("enable")}}}async initPayloadList(e){let t=this.$elements.payload;t.addClass("multiple-select"),t.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!1,selectAll:!1,container:".node-input-output-container-row",filter:!0,filterPlaceholder:RED._(this.NRCD+"/server:editor.inputs.device.device.filter"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),onClick:e=>{if(e.selected)switch(e.value){case"__complete__":case"__each__":case"__auto__":t.multipleSelect("setSelects",[e.value]);break;default:t.multipleSelect("uncheck","__complete__"),t.multipleSelect("uncheck","__each__"),t.multipleSelect("uncheck","__auto__")}},onUncheckAll:()=>{t.multipleSelect("setSelects",["__complete__","__auto__"])},onOptgroupClick:e=>{e.selected&&(t.multipleSelect("uncheck","__complete__"),t.multipleSelect("uncheck","__each__"),t.multipleSelect("uncheck","__auto__"))}}),await this.updatePayloadList(),e&&t.multipleSelect("setSelects",e)}async generatePayloadTypeField(e,t){var i,s,n=this.NRCD+"/server:editor.inputs.outputs.type",a=[];for([i,s]of Object.entries(this.listEditor.options.type))s&&a.push([i,n+".options."+i]);await this.generateSimpleListField(e,{id:this.elements.type,i18n:n,choices:a,currentValue:t})}async generatePayloadField(e){var t=this.NRCD+"/server:editor.inputs.outputs.payload";await this.generateSimpleListField(e,{id:this.elements.payload,i18n:t})}async generatePayloadFormatField(e,t){var i,s,n=this.NRCD+"/server:editor.inputs.outputs.format",a=[];for([i,s]of Object.entries(this.listEditor.options.format))s&&a.push([i,n+".options."+i]);await this.generateSimpleListField(e,{id:this.elements.format,i18n:n,choices:a,currentValue:t})}async generateOutputField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.output";await this.generateSimpleListField(e,{id:this.elements.output,i18n:i,choices:[["always",i+".options.always"],["onchange",i+".options.onchange"],["onupdate",i+".options.onupdate"]],currentValue:t})}async generateOnStartField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.on_start";await this.generateCheckboxField(e,{id:this.elements.onstart,i18n:i,currentValue:t})}async generateOnErrorField(e,t){var i=this.NRCD+"/server:editor.inputs.outputs.on_error";await this.generateCheckboxField(e,{id:this.elements.onerror,i18n:i,currentValue:t})}}class DeconzOutputRuleListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"rule"}get buttons(){var e,t=[],i=this.NRCD+"/server:editor.inputs.outputs.type";for(const[s,n]of Object.entries(this.options.type))n&&(e=this.getI18n(i+".options."+s),t.push({label:this.getI18n(i+".add_button","label",{type:e}),icon:this.getIcon(this.getI18n(i+".add_button","icon"),!0),title:this.getI18n(i+".add_button","title",{type:e}),click:()=>this.$elements.list.editableList("addItem",{type:s})}));return t}async init(e){await super.init(e),await this.initList(DeconzOutputRuleEditor,this.node.output_rules)}refresh(){for(const e of Object.values(this.items))e.updatePayloadList()}}class DeconzCommandEditor extends DeconzListItemEditor{constructor(e,t,i,s={}){super(e,t,i,s=$.extend({},s)),this.containers={}}get lightKeys(){return["bri","sat","hue","ct","xy"]}get argKeys(){return["on","alert","effect","colorloopspeed","open","stop","lift","tilt","scene_mode","group","scene","scene_name","target","command","payload","delay","transitiontime","retryonerror","aftererror"]}get elements(){var e=this.argKeys;e.push("typedomain"),e.push("outputButton"),e.push("scene_picker"),e.push("scene_picker_refresh");for(const i of this.lightKeys)e.push(i),e.push(i+"_direction");var t={};for(const s of e)t[s]=`node-input-output-rule-${this.uniqueId}-`+s;return t}set value(e){}get value(){var e={arg:{}};e.type=this.$elements.typedomain.typedInput("type"),e.domain=this.$elements.typedomain.typedInput("value");for(const t of this.argKeys)this.$elements[t].parent(".form-row").is(":visible")&&(e.arg[t]={type:this.$elements[t].typedInput("type"),value:this.$elements[t].typedInput("value")});for(const i of this.lightKeys)this.$elements[i].parent(".form-row").is(":visible")&&(e.arg[i]={direction:this.$elements[i+"_direction"].typedInput("type"),type:this.$elements[i].typedInput("type"),value:this.$elements[i].typedInput("value")});return e}get defaultCommand(){return{type:"deconz_state",domain:"lights",target:"state",arg:{on:{type:"keep"},bri:{direction:"set",type:"num"},sat:{direction:"set",type:"num"},hue:{direction:"set",type:"num"},ct:{direction:"set",type:"num"},xy:{direction:"set",type:"num"},alert:{type:"str"},effect:{type:"str"},colorloopspeed:{type:"num"},transitiontime:{type:"num"},command:{type:"str",value:"on"},payload:{type:"msg",value:"payload"},delay:{type:"num",value:2e3},target:{type:"state"},group:{type:"num"},scene_mode:{type:"single"},scene_call:{type:"num"},scene_name:{type:"str"},retryonerror:{type:"num",value:0},aftererror:{type:"continue"}}}}async init(e,t){this._index=t,e=$.extend(!0,this.defaultCommand,e),await this.generateTypeDomainField(this.container,{type:e.type,value:e.domain}),this.containers.light=$("<div>").appendTo(this.container),await this.generateLightOnField(this.containers.light,e.arg.on);for(const i of["bri","sat","hue","ct","xy"])await this.generateLightColorField(this.containers.light,i,e.arg[i]),"bri"===i&&await this.generateHR(this.containers.light);await this.generateHR(this.containers.light),await this.generateLightAlertField(this.containers.light,e.arg.alert),await this.generateLightEffectField(this.containers.light,e.arg.effect),await this.generateLightColorLoopSpeedField(this.containers.light,e.arg.colorloopspeed),this.containers.windows_cover=$("<div>").appendTo(this.container),await this.generateCoverOpenField(this.containers.windows_cover,e.arg.open),await this.generateCoverStopField(this.containers.windows_cover,e.arg.stop),await this.generateCoverLiftField(this.containers.windows_cover,e.arg.lift),await this.generateCoverTiltField(this.containers.windows_cover,e.arg.tilt),this.containers.scene_call=$("<div>").appendTo(this.container),await this.generateSceneModeField(this.containers.scene_call,e.arg.scene_mode),this.containers.scene_call_single=$("<div>").appendTo(this.containers.scene_call),await this.generateScenePickerField(this.containers.scene_call_single,e.arg.group+"."+e.arg.scene),await this.generateSceneGroupField(this.containers.scene_call_single,e.arg.group),await this.generateSceneSceneField(this.containers.scene_call_single,e.arg.scene),this.containers.scene_call_dynamic=$("<div>").appendTo(this.containers.scene_call),await this.generateSceneNameField(this.containers.scene_call_dynamic,e.arg.scene_name),this.containers.target=$("<div>").appendTo(this.container),await this.generateTargetField(this.containers.target,e.arg.target),this.containers.command=$("<div>").appendTo(this.container),await this.generateCommandField(this.containers.command,e.arg.command),this.containers.payload=$("<div>").appendTo(this.container),await this.generatePayloadField(this.containers.payload,e.arg.payload),this.containers.pause=$("<div>").appendTo(this.container),await this.generatePauseDelayField(this.containers.pause,e.arg.delay),this.containers.transition=$("<div>").appendTo(this.container),await this.generateHR(this.containers.transition),await this.generateCommonTransitionTimeField(this.containers.transition,e.arg.transitiontime),this.containers.common=$("<div>").appendTo(this.container),await this.generateHR(this.containers.common),await this.generateCommonOnErrorRetryField(this.containers.common,e.arg.retryonerror),await this.generateCommonOnErrorAfterField(this.containers.common,e.arg.aftererror),await super.init(),await this.listEditor.mainEditor.isInitialized(),await this.updateShowHide(e.type,e.domain),await this.connect()}async connect(){await super.connect(),this.$elements.typedomain.on("change",(e,t,i)=>{this.updateShowHide(t,i)}),this.$elements.outputButton.on("click",async()=>{try{if("device"!==this.listEditor.mainEditor.subEditor.query.type)this.sendError("Error : The run command can only work with device list.",5e3);else{var t=this.value,i=this.listEditor.mainEditor.subEditor.device.value;if(0!==i.length||("deconz_state"===t.type&&"scene_call"===t.domain||"custom"===t.type&&"scene_call"===t.arg.target.type))if("pause"===t.type)this.sendError("Error : Can't test pause command.",5e3);else{for(var[s,n]of Object.entries(t.arg))if(["msg","flow","global","jsonata"].includes(n.type))return void this.sendError(`Error : Cant run this command because the value "${s}" is type "${n.type}".`,5e3);let e=RED.notify("Sending request...",{type:"info"});await $.post(this.NRCD+"/testCommand",{controllerID:this.listEditor.mainEditor.serverNode.id,device_list:i,command:t,delay:this.listEditor.mainEditor.subEditor.specific.value.delay}).catch((e,t)=>{this.sendError(400===e.status&&e.responseText?e.responseText:t.toString())});e.close(),e=RED.notify("Ok",{timeout:1e3,type:"success"})}else this.sendError("Error : No device selected.",5e3)}}catch(e){let t=RED.notify(e.toString(),{type:"error",buttons:[{class:"error",click:()=>t.close()}]})}});const e=()=>{var e=this.$elements.scene_picker.multipleSelect("getSelects");1===e.length&&(this.$elements.group.off("change",t),this.$elements.scene.off("change",t),e=e[0].split("."),this.$elements.group.typedInput("type","num"),this.$elements.group.typedInput("value",e[0]),this.$elements.scene.typedInput("type","num"),this.$elements.scene.typedInput("value",e[1]),this.$elements.group.on("change",t),this.$elements.scene.on("change",t))},t=()=>{this.$elements.scene_picker.off("change",e),this.$elements.scene_picker.multipleSelect("setSelects","num"!==this.$elements.group.typedInput("type")||"num"!==this.$elements.group.typedInput("type")?[]:[this.$elements.group.typedInput("value")+"."+this.$elements.scene.typedInput("value")]),this.$elements.scene_picker.on("change",e)};this.$elements.scene_mode.on("change",()=>{var e="single"===this.$elements.scene_mode.typedInput("type");this.containers.scene_call_single.toggle(e),this.containers.scene_call_dynamic.toggle(!e)}),this.$elements.scene_picker.on("change",e),this.$elements.group.on("change",t),this.$elements.scene.on("change",t),this.$elements.scene_picker_refresh.on("click",()=>this.updateSceneList()),this.$elements.target.on("change",(e,t,i)=>{this.containers.command.toggle("scene_call"!==t)})}async updateShowHide(e,t){var i,s,n=[];switch(e){case"deconz_state":switch(t){case"lights":case"groups":n.push("light"),n.push("transition");break;case"covers":n.push("windows_cover");break;case"scene_call":n.push("scene_call"),await this.updateSceneList(),n.push("scene_call_"+("single"===this.$elements.scene_mode.typedInput("type")?"single":"dynamic"))}n.push("common");break;case"homekit":this.$elements.payload.typedInput("types",["msg","flow","global","json","jsonata"]),n.push("payload"),n.push("transition"),n.push("common");break;case"custom":n.push("target"),"scene_call"!==this.$elements.target.typedInput("type")&&n.push("command"),this.$elements.payload.typedInput("types",["msg","flow","global","str","num","bool","json","jsonata","date"]),n.push("payload"),n.push("transition"),n.push("common");break;case"pause":n.push("pause")}for([i,s]of Object.entries(this.containers))s.toggle(n.includes(i))}async updateSceneList(){this.$elements.scene_picker.multipleSelect("disable"),this.$elements.scene_picker.children().remove();var e=this.listEditor.mainEditor.subEditor.query;if(void 0!==e){var t=e.xhrParams,e=(t.queryType="json",t.query=JSON.stringify({match:{device_type:"groups"}}),await e.getItems({refresh:!0,keepOnlyMatched:!0},t));if(void 0!==e&&void 0!==e.LightGroup){for(const s of e.LightGroup){var i=$("<optgroup/>",{label:s.id+" - "+s.name});if(s.scenes&&0<s.scenes.length){for(const n of s.scenes)$(`<option>${n.id} - ${n.name}</option>`).attr("value",s.id+"."+n.id).appendTo(i);i.appendTo(this.$elements.scene_picker)}}this.$elements.scene_picker.multipleSelect("refresh").multipleSelect("enable"),this.$elements.scene_picker.multipleSelect("setSelects","num"!==this.$elements.group.typedInput("type")||"num"!==this.$elements.group.typedInput("type")?[]:[this.$elements.group.typedInput("value")+"."+this.$elements.scene.typedInput("value")])}}}async generateTypeDomainField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type";await this.generateTypedInputField(e,{id:this.elements.typedomain,i18n:i,value:t,addDefaultTypes:!1,typedInput:{default:"deconz_state",types:[this.generateTypedInputType(i,"deconz_state",{subOptions:["lights","covers","groups","scene_call"]}),this.generateTypedInputType(i,"homekit",{hasValue:!1}),this.generateTypedInputType(i,"custom",{hasValue:!1}),this.generateTypedInputType(i,"pause",{hasValue:!1})]}})}async generateLightOnField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.on";await this.generateTypedInputField(e,{id:this.elements.on,i18n:i,value:t,typedInput:{default:"keep",types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i,"toggle",{hasValue:!1})]}})}async generateLightColorField(e,t,i={}){var s=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields";let n=["num"];var a=[this.generateTypedInputType(s+".lightFields","set",{hasValue:!1})];switch(t){case"bri":n.push("str"),a.push(this.generateTypedInputType(s+".lightFields","inc",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","dec",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","detect_from_value",{hasValue:!1}));break;case"ct":n.push("str"),n.push(this.generateTypedInputType(s+".ct","deconz",{subOptions:["cold","white","warm"]})),a.push(this.generateTypedInputType(s+".lightFields","inc",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","dec",{hasValue:!1})),a.push(this.generateTypedInputType(s+".lightFields","detect_from_value",{hasValue:!1}));break;case"xy":n=["json"]}await this.generateDoubleTypedInputField(e,{id:this.elements[t+"_direction"],i18n:s+"."+t,addDefaultTypes:!1,value:{type:i.direction},typedInput:{types:a}},{id:this.elements[t],value:{type:i.type,value:["xy"===t&&void 0===i.value?"[]":i.value]},typedInput:{types:n}})}async generateLightAlertField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.alert";await this.generateTypedInputField(e,{id:this.elements.alert,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"deconz",{subOptions:["none","select","lselect"]})]}})}async generateLightEffectField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.effect";await this.generateTypedInputField(e,{id:this.elements.effect,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"deconz",{subOptions:["none","colorloop"]})]}})}async generateLightColorLoopSpeedField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.lights.fields.colorloopspeed";await this.generateTypedInputField(e,{id:this.elements.colorloopspeed,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCoverOpenField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.open";await this.generateTypedInputField(e,{id:this.elements.open,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]}),this.generateTypedInputType(i,"toggle",{hasValue:!1})]}})}async generateCoverStopField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.stop";await this.generateTypedInputField(e,{id:this.elements.stop,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"keep",{hasValue:!1}),this.generateTypedInputType(i,"set",{subOptions:["true","false"]})]}})}async generateCoverLiftField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.lift";await this.generateTypedInputField(e,{id:this.elements.lift,i18n:i,value:t,typedInput:{types:["num","str",this.generateTypedInputType(i,"stop",{hasValue:!1})]}})}async generateCoverTiltField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.covers.fields.tilt";await this.generateTypedInputField(e,{id:this.elements.tilt,i18n:i,value:t,typedInput:{types:["num"]}})}async generateSceneModeField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.mode";await this.generateTypedInputField(e,{id:this.elements.scene_mode,i18n:i,value:t,addDefaultTypes:!1,typedInput:{types:[this.generateTypedInputType(i,"single",{hasValue:!1}),this.generateTypedInputType(i,"dynamic",{hasValue:!1})]}})}async generateScenePickerField(e,t=0){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.picker",s=await this.generateSimpleListField(e,{id:this.elements.scene_picker,i18n:i}),i=(s.addClass("multiple-select"),s.multipleSelect({maxHeight:300,dropWidth:300,width:200,numberDisplayed:1,single:!0,singleRadio:!0,hideOptgroupCheckboxes:!0,showClear:!0,selectAll:!1,filter:!0,filterPlaceholder:this.getI18n(i,"filter_place_holder"),placeholder:RED._(this.NRCD+"/server:editor.multiselect.none_selected"),container:".node-input-output-container-row"}),$("<a/>",{id:this.elements.scene_picker_refresh,class:"red-ui-button",style:"margin-left:10px;"}));this.createIconElement(this.getIcon("refresh"),i),s.closest(".form-row").append(i)}async generateSceneGroupField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.group";await this.generateTypedInputField(e,{id:this.elements.group,i18n:i,value:t,typedInput:{types:["num"]}})}async generateSceneSceneField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene";await this.generateTypedInputField(e,{id:this.elements.scene,i18n:i,value:t,typedInput:{types:["num","str",this.generateTypedInputType(i,"deconz",{subOptions:["next","prev"]})]}})}async generateSceneNameField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.scene_call.fields.scene_name";await this.generateTypedInputField(e,{id:this.elements.scene_name,i18n:i,value:t,typedInput:{types:["str","re"]}})}async generateTargetField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.target";await this.generateTypedInputField(e,{id:this.elements.target,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"attribute",{hasValue:!1}),this.generateTypedInputType(i,"state",{hasValue:!1}),this.generateTypedInputType(i,"config",{hasValue:!1}),this.generateTypedInputType(i,"scene_call",{hasValue:!1})]}})}async generateCommandField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.command";await this.generateTypedInputField(e,{id:this.elements.command,i18n:i,value:t,typedInput:{types:["str",this.generateTypedInputType(i,"object",{hasValue:!1})]}})}async generatePayloadField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.common.fields.payload";await this.generateTypedInputField(e,{id:this.elements.payload,i18n:i,value:t,addDefaultTypes:!1,typedInput:{types:["msg","flow","global","str","num","bool","json","jsonata","date"]}})}async generatePauseDelayField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.pause.fields.delay";await this.generateTypedInputField(e,{id:this.elements.delay,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCommonTransitionTimeField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.transitiontime";await this.generateTypedInputField(e,{id:this.elements.transitiontime,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCommonOnErrorRetryField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.retryonerror";await this.generateTypedInputField(e,{id:this.elements.retryonerror,i18n:i,value:t,typedInput:{types:["num"]}})}async generateCommonOnErrorAfterField(e,t={}){var i=this.NRCD+"/server:editor.inputs.commands.type.options.deconz_state.options.common.fields.aftererror";await this.generateTypedInputField(e,{id:this.elements.aftererror,i18n:i,value:t,typedInput:{types:[this.generateTypedInputType(i,"continue",{hasValue:!1}),this.generateTypedInputType(i,"stop",{hasValue:!1})]}})}}class DeconzCommandListEditor extends DeconzListItemListEditor{get elements(){return{list:"node-input-output-container"}}get listType(){return"command"}get buttons(){var e,t=[],i=this.NRCD+"/server:editor.inputs.commands.type";for(const[s,n]of Object.entries(this.options.type))n&&(e=this.getI18n(i+".options."+s,"label"),t.push({label:this.getI18n(i+".add_button","label",{type:e}),icon:this.getIcon(this.getI18n(i+".add_button","icon"),!0),title:this.getI18n(i+".add_button","title",{type:e}),click:()=>this.$elements.list.editableList("addItem",{type:s})}));return t}async init(e){await super.init(e),await this.initList(DeconzCommandEditor,this.node.commands)}} | ||
//# sourceMappingURL=deconz-editor.js.map |
@@ -17,3 +17,5 @@ const Utils = require("./Utils"); | ||
}; | ||
} | ||
async build() { | ||
switch (this.type) { | ||
@@ -24,14 +26,14 @@ case "deconz_state": | ||
this.valid_domain.push("lights"); | ||
this.parseDeconzStateLightArgs(); | ||
await this.parseDeconzStateLightArgs(); | ||
break; | ||
case "covers": | ||
this.valid_domain.push("covers"); | ||
this.parseDeconzStateCoverArgs(); | ||
await this.parseDeconzStateCoverArgs(); | ||
break; | ||
case "groups": | ||
this.valid_domain.push("groups"); | ||
this.parseDeconzStateLightArgs(); | ||
await this.parseDeconzStateLightArgs(); | ||
break; | ||
case "scene_call": | ||
this.parseDeconzStateSceneCallArgs(); | ||
await this.parseDeconzStateSceneCallArgs(); | ||
break; | ||
@@ -57,3 +59,3 @@ } | ||
this.valid_domain.push("any"); | ||
this.parseCustomArgs(); | ||
await this.parseCustomArgs(); | ||
break; | ||
@@ -63,5 +65,5 @@ } | ||
parseDeconzStateLightArgs() { | ||
async parseDeconzStateLightArgs() { | ||
// On command | ||
this.result.state.on = this.getNodeProperty( | ||
this.result.state.on = await this.getNodeProperty( | ||
this.arg.on, | ||
@@ -91,3 +93,3 @@ ["toggle"], | ||
if (k === "xy") { | ||
let xy = this.getNodeProperty(this.arg.xy); | ||
let xy = await this.getNodeProperty(this.arg.xy); | ||
if (Array.isArray(xy) && xy.length === 2) { | ||
@@ -97,3 +99,5 @@ this.result.state[k] = xy.map(Number); | ||
} else { | ||
this.result.state[k] = Number(this.getNodeProperty(this.arg[k])); | ||
this.result.state[k] = Number( | ||
await this.getNodeProperty(this.arg[k]) | ||
); | ||
} | ||
@@ -103,3 +107,3 @@ break; | ||
this.result.state[`${k}_inc`] = Number( | ||
this.getNodeProperty(this.arg[k]) | ||
await this.getNodeProperty(this.arg[k]) | ||
); | ||
@@ -109,7 +113,7 @@ break; | ||
this.result.state[`${k}_inc`] = -Number( | ||
this.getNodeProperty(this.arg[k]) | ||
await this.getNodeProperty(this.arg[k]) | ||
); | ||
break; | ||
case "detect_from_value": | ||
let value = this.getNodeProperty(this.arg[k]); | ||
let value = await this.getNodeProperty(this.arg[k]); | ||
switch (typeof value) { | ||
@@ -141,8 +145,8 @@ case "string": | ||
if (this.arg[k].value.length > 0) | ||
this.result.state[k] = this.getNodeProperty(this.arg[k]); | ||
this.result.state[k] = await this.getNodeProperty(this.arg[k]); | ||
} | ||
} | ||
parseDeconzStateCoverArgs() { | ||
this.result.state.open = this.getNodeProperty( | ||
async parseDeconzStateCoverArgs() { | ||
this.result.state.open = await this.getNodeProperty( | ||
this.arg.open, | ||
@@ -157,3 +161,3 @@ ["toggle"], | ||
this.result.state.stop = this.getNodeProperty( | ||
this.result.state.stop = await this.getNodeProperty( | ||
this.arg.stop, | ||
@@ -168,8 +172,12 @@ [], | ||
this.result.state.lift = this.getNodeProperty(this.arg.lift, ["stop"]); | ||
this.result.state.tilt = this.getNodeProperty(this.arg.tilt); | ||
this.result.state.lift = await this.getNodeProperty(this.arg.lift, [ | ||
"stop", | ||
]); | ||
this.result.state.tilt = await this.getNodeProperty(this.arg.tilt); | ||
} | ||
parseDeconzStateSceneCallArgs() { | ||
switch (this.getNodeProperty(this.arg.scene_mode, ["single", "dynamic"])) { | ||
async parseDeconzStateSceneCallArgs() { | ||
switch ( | ||
await this.getNodeProperty(this.arg.scene_mode, ["single", "dynamic"]) | ||
) { | ||
case "single": | ||
@@ -179,4 +187,4 @@ case undefined: | ||
mode: "single", | ||
groupId: this.getNodeProperty(this.arg.group), | ||
sceneId: this.getNodeProperty(this.arg.scene), | ||
groupId: await this.getNodeProperty(this.arg.group), | ||
sceneId: await this.getNodeProperty(this.arg.scene), | ||
}; | ||
@@ -187,3 +195,3 @@ break; | ||
mode: "dynamic", | ||
sceneName: this.getNodeProperty(this.arg.scene_name), | ||
sceneName: await this.getNodeProperty(this.arg.scene_name), | ||
}; | ||
@@ -194,4 +202,4 @@ break; | ||
parseHomekitArgs(deviceMeta) { | ||
let values = this.getNodeProperty(this.arg.payload); | ||
async parseHomekitArgs(deviceMeta) { | ||
let values = await this.getNodeProperty(this.arg.payload); | ||
let allValues = values; | ||
@@ -233,8 +241,8 @@ if (dotProp.has(this.message_in, "hap.allChars")) { | ||
"state.transitiontime", | ||
this.getNodeProperty(this.arg.transitiontime) | ||
await this.getNodeProperty(this.arg.transitiontime) | ||
); | ||
} | ||
parseCustomArgs() { | ||
let target = this.getNodeProperty(this.arg.target, [ | ||
async parseCustomArgs() { | ||
let target = await this.getNodeProperty(this.arg.target, [ | ||
"attribute", | ||
@@ -245,4 +253,4 @@ "state", | ||
]); | ||
let command = this.getNodeProperty(this.arg.command, ["object"]); | ||
let value = this.getNodeProperty(this.arg.payload); | ||
let command = await this.getNodeProperty(this.arg.command, ["object"]); | ||
let value = await this.getNodeProperty(this.arg.payload); | ||
switch (target) { | ||
@@ -298,3 +306,3 @@ case "attribute": | ||
*/ | ||
getRequests(node, devices) { | ||
async getRequests(node, devices) { | ||
let deconzApi = node.server.api; | ||
@@ -379,3 +387,3 @@ let requests = []; | ||
}; | ||
this.parseHomekitArgs(device.data); | ||
await this.parseHomekitArgs(device.data); | ||
} | ||
@@ -467,3 +475,3 @@ | ||
getNodeProperty(property, noValueTypes, valueMaps) { | ||
async getNodeProperty(property, noValueTypes, valueMaps) { | ||
if (typeof property === "undefined") return undefined; | ||
@@ -479,3 +487,3 @@ if (Array.isArray(valueMaps)) | ||
return map[1]; | ||
return Utils.getNodeProperty( | ||
return await Utils.getNodeProperty( | ||
property, | ||
@@ -482,0 +490,0 @@ this.node, |
@@ -497,11 +497,27 @@ const dotProp = require("dot-prop"); | ||
//#region Battery | ||
HKF.BatteryLevel = directMap(["to"], "config.battery") | ||
HKF.BatteryLevel = new Attribute() | ||
.services("Battery") | ||
.to((rawEvent, deviceMeta) => { | ||
let battery = dotProp.get(rawEvent, "config.battery"); | ||
if (battery === undefined) { | ||
battery = dotProp.get(rawEvent, "state.battery"); | ||
} | ||
return battery; | ||
}) | ||
.limit(0, 100); | ||
HKF.StatusLowBattery = new Attribute() | ||
.services("Battery") | ||
.needEventMeta("config.battery") | ||
.to((rawEvent, deviceMeta) => | ||
dotProp.get(rawEvent, "config.battery") <= 15 ? 1 : 0 | ||
); | ||
.needEventMeta( | ||
(rawEvent, deviceMeta) => | ||
dotProp.has(rawEvent, "config.battery") || | ||
dotProp.has(rawEvent, "state.battery") | ||
) | ||
.to((rawEvent, deviceMeta) => { | ||
let battery = dotProp.get(rawEvent, "config.battery"); | ||
if (battery === undefined) { | ||
battery = dotProp.get(rawEvent, "state.battery"); | ||
} | ||
return battery <= 15 ? 1 : 0; | ||
}); | ||
//#endregion | ||
@@ -508,0 +524,0 @@ //#region Lock Mechanism |
@@ -24,14 +24,20 @@ const REDUtil = require("@node-red/util/lib/util"); | ||
static getNodeProperty(property, node, message_in, noValueTypes) { | ||
static async getNodeProperty(property, node, message_in, noValueTypes) { | ||
if (typeof property !== "object") return; | ||
if (property.type === "num" && property.value === "") return; | ||
return Array.isArray(noValueTypes) && noValueTypes.includes(property.type) | ||
? property.type | ||
: REDUtil.evaluateNodeProperty( | ||
property.value, | ||
property.type, | ||
node, | ||
message_in, | ||
undefined | ||
); | ||
: await new Promise((resolve, reject) => { | ||
RED.util.evaluateNodeProperty( | ||
property.value, | ||
property.type, | ||
node, | ||
message_in, | ||
(err, value) => { | ||
if (err) reject(err); | ||
else resolve(value); | ||
} | ||
); | ||
}); | ||
} | ||
@@ -38,0 +44,0 @@ |
Sorry, the diff of this file is not supported yet
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
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
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
523382
8804
1