UNPKG

iobroker.nspanel-lovelace-ui

Version:

NsPanel Lovelace UI is a Firmware for the nextion screen inside of NSPanel in the Design of Lovelace UI Design.

1,413 lines (1,412 loc) 55.9 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var panel_exports = {}; __export(panel_exports, { Panel: () => Panel }); module.exports = __toCommonJS(panel_exports); var import_panel_message = require("./panel-message"); var import_screensaver = require("../pages/screensaver"); var Types = __toESM(require("../types/types")); var pages = __toESM(require("../types/pages")); var import_library = require("../classes/library"); var definition = __toESM(require("../const/definition")); var import_pageMedia = require("../pages/pageMedia"); var import_pageGrid = require("../pages/pageGrid"); var import_navigation = require("../classes/navigation"); var import_pageThermo = require("../pages/pageThermo"); var import_pagePower = require("../pages/pagePower"); var import_pageEntities = require("../pages/pageEntities"); var import_pageNotification = require("../pages/pageNotification"); var import_system_templates = require("../templates/system-templates"); var import_pageAlarm = require("../pages/pageAlarm"); var import_pageChart = require("../pages/pageChart"); var import_pageLChart = require("../pages/pageLChart"); var import_pageQR = require("../pages/pageQR"); var import_data_item = require("../classes/data-item"); var import_Color = require("../const/Color"); var import_pageSchedule = require("../pages/pageSchedule"); var import_card = require("../templates/card"); var import_tools = require("../const/tools"); const DefaultOptions = { format: { weekday: "short", month: "short", year: "numeric", day: "numeric" }, CustomFormat: "", locale: "de-DE", pages: [] }; class Panel extends import_library.BaseClass { loopTimeout; pages = []; _activePage = void 0; data = {}; blockStartup = null; _isOnline = false; options; flashing = false; screenSaver; lastCard = ""; notifyIndex = -1; initDone = false; buttons; navigation; format; controller; topic; reivCallbacks = []; panelSend; statesControler; config; CustomFormat; sendToTasmota = () => { }; timeout; dim = { standby: definition.genericStateObjects.panel.panels.cmd.dim.standby.common.def, active: definition.genericStateObjects.panel.panels.cmd.dim.active.common.def, delay: definition.genericStateObjects.panel.panels.cmd.dim.delay.common.def, dayMode: definition.genericStateObjects.panel.panels.cmd.dim.dayMode.common.def, nightStandby: definition.genericStateObjects.panel.panels.cmd.dim.nightStandby.common.def, nightActive: definition.genericStateObjects.panel.panels.cmd.dim.nightActive.common.def, nightHourStart: definition.genericStateObjects.panel.panels.cmd.dim.nightHourStart.common.def, nightHourEnd: definition.genericStateObjects.panel.panels.cmd.dim.nightHourEnd.common.def, schedule: definition.genericStateObjects.panel.panels.cmd.dim.schedule.common.def }; screenSaverDoubleClick = true; detach = { left: false, right: false }; persistentPageItems = {}; info = { isOnline: false, nspanel: { displayVersion: "", model: "", bigIconLeft: false, bigIconRight: false, onlineVersion: "", firmwareUpdate: 100, currentPage: "" }, tasmota: { firmwareversion: "", onlineVersion: "", safeboot: false, mqttClient: "", net: { Hostname: "", IPAddress: "", Gateway: "", Subnetmask: "", DNSServer1: "", DNSServer2: "", Mac: "", IP6Global: "", IP6Local: "", Ethernet: { Hostname: "", IPAddress: "", Gateway: "", Subnetmask: "", DNSServer1: "", DNSServer2: "", Mac: "", IP6Global: "", IP6Local: "" }, Webserver: 0, HTTP_API: 0, WifiConfig: 0, WifiPower: 0 }, uptime: "", sts: { Time: "", Uptime: "", UptimeSec: 0, Heap: 0, SleepMode: "", Sleep: 0, LoadAvg: 0, MqttCount: 0, Berry: { HeapUsed: 0, Objects: 0 }, POWER1: "", POWER2: "", Wifi: { AP: 0, SSId: "", BSSId: "", Channel: 0, Mode: "", RSSI: 0, Signal: 0, LinkCount: 0, Downtime: "" } } } }; constructor(adapter, options) { var _a, _b; super(adapter, options.name, (_a = options.friendlyName) != null ? _a : options.name); this.panelSend = new import_panel_message.PanelSend(adapter, { name: `${this.friendlyName}-SendClass`, mqttClient: options.controller.mqttClient, topic: options.topic, panel: this }); this.info.tasmota.mqttClient = this.library.cleandp(this.name); this.options = options; this.timeout = options.timeout || 15; this.buttons = options.buttons; this.CustomFormat = (_b = options.CustomFormat) != null ? _b : ""; this.config = options.config; this.format = Object.assign(DefaultOptions.format, options.format); this.controller = options.controller; this.topic = options.topic; if (typeof this.panelSend.addMessage === "function") { this.sendToPanelClass = this.panelSend.addMessage; } if (typeof this.panelSend.addMessageTasmota === "function") { this.sendToTasmota = this.panelSend.addMessageTasmota; } this.statesControler = options.controller.statesControler; options.pages = options.pages.filter((b) => { var _a2, _b2, _c; if (((_a2 = b.config) == null ? void 0 : _a2.card) === "screensaver" || ((_b2 = b.config) == null ? void 0 : _b2.card) === "screensaver2" || ((_c = b.config) == null ? void 0 : _c.card) === "screensaver3") { return true; } if (options.navigation.find((c) => c && c.name === b.uniqueID)) { return true; } return false; }); options.pages = options.pages.concat(import_system_templates.systemPages); options.navigation = (options.navigation || []).concat(import_system_templates.systemNavigation); let scsFound = 0; for (let a = 0; a < options.pages.length; a++) { let pageConfig = options.pages[a] ? Panel.getPage(options.pages[a], this) : options.pages[a]; if (!pageConfig || !pageConfig.config) { continue; } const pmconfig = { card: pageConfig.config.card, panel: this, id: String(a), name: `${pageConfig.uniqueID}`, alwaysOn: pageConfig.alwaysOn, adapter: this.adapter, panelSend: this.panelSend, dpInit: pageConfig.dpInit }; switch (pageConfig.config.card) { case "cardChart": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageChart.PageChart(pmconfig, pageConfig); break; } case "cardLChart": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageLChart.PageLChart(pmconfig, pageConfig); break; } case "cardEntities": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageEntities.PageEntities(pmconfig, pageConfig); break; } case "cardSchedule": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageSchedule.PageSchedule(pmconfig, pageConfig); break; } case "cardGrid3": case "cardGrid2": case "cardGrid": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageGrid.PageGrid(pmconfig, pageConfig); break; } case "cardThermo": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageThermo.PageThermo(pmconfig, pageConfig); break; } case "cardMedia": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageMedia.PageMedia(pmconfig, pageConfig); break; } case "cardQR": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageQR.PageQR(pmconfig, pageConfig); break; } case "cardAlarm": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageAlarm.PageAlarm(pmconfig, pageConfig); break; } case "cardPower": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pagePower.PagePower(pmconfig, pageConfig); break; } case "popupNotify2": case "popupNotify": { pageConfig = Panel.getPage(pageConfig, this); this.pages[a] = new import_pageNotification.PageNotify(pmconfig, pageConfig); break; } case "screensaver": case "screensaver2": case "screensaver3": { scsFound++; const ssconfig = { card: pageConfig.config.card, panel: this, id: String(a), name: `${pageConfig.uniqueID}`, adapter: this.adapter, panelSend: this.panelSend, dpInit: "" }; this.screenSaver = new import_screensaver.Screensaver(ssconfig, pageConfig); this.pages[a] = this.screenSaver; break; } default: { this.log.error(`Page config is missing card property for page ${pageConfig.uniqueID}`); } } } if (scsFound === 0) { this.log.error("no screensaver found! Stop!"); void this.adapter.controller.delete(); throw new Error("no screensaver found! Stop!"); } const navConfig = { adapter: this.adapter, panel: this, navigationConfig: options.navigation }; this.navigation = new import_navigation.Navigation(navConfig); } init = async () => { var _a, _b; await this.controller.mqttClient.subscript(`${this.topic}/tele/#`, this.onMessage); await this.controller.mqttClient.subscript(`${this.topic}/stat/#`, this.onMessage); this.isOnline = false; const channelObj = this.library.cloneObject(definition.genericStateObjects.panel.panels._channel); channelObj.common.name = this.friendlyName; channelObj.native = { topic: this.topic, tasmotaName: this.friendlyName, name: this.name //configName: this.configName, }; await this.library.writedp(`panels.${this.name}`, void 0, channelObj); await this.library.writedp( `panels.${this.name}.cmd`, void 0, definition.genericStateObjects.panel.panels.cmd._channel ); await this.library.writedp( `panels.${this.name}.cmd.dim`, void 0, definition.genericStateObjects.panel.panels.cmd.dim._channel ); await this.library.writedp( `panels.${this.name}.cmd.screenSaver`, void 0, definition.genericStateObjects.panel.panels.cmd.screenSaver._channel ); await this.library.writedp( `panels.${this.name}.alarm`, void 0, definition.genericStateObjects.panel.panels.alarm._channel ); await this.library.writedp( `panels.${this.name}.buttons`, void 0, definition.genericStateObjects.panel.panels.buttons._channel ); await this.library.writedp( `panels.${this.name}.buttons.left`, true, definition.genericStateObjects.panel.panels.buttons.left ); await this.library.writedp( `panels.${this.name}.buttons.right`, true, definition.genericStateObjects.panel.panels.buttons.right ); const keys = Object.keys(this.dim); for (const d of keys) { const key = d; const state2 = this.library.readdb(`panels.${this.name}.cmd.dim.${key}`); if (state2 && state2.val != null && key in this.dim && typeof state2.val === typeof this.dim[key]) { this.dim[key] = state2.val; } await this.library.writedp( `panels.${this.name}.cmd.dim.${key}`, this.dim[key], definition.genericStateObjects.panel.panels.cmd.dim[key] ); } let state = this.library.readdb(`panels.${this.name}.cmd.screenSaver.doubleClick`); if (state && state.val != null) { this.screenSaverDoubleClick = !!state.val; } await this.library.writedp( `panels.${this.name}.cmd.screenSaver.doubleClick`, this.screenSaverDoubleClick, definition.genericStateObjects.panel.panels.cmd.screenSaver.doubleClick ); if (state && !state.val) { await this.library.writedp( `panels.${this.name}.buttons.screensaverGesture`, 0, definition.genericStateObjects.panel.panels.buttons.screensaverGesture ); } else { await this.library.writedp( `panels.${this.name}.buttons.screensaverGesture`, void 0, definition.genericStateObjects.panel.panels.buttons.screensaverGesture ); } state = this.library.readdb(`panels.${this.name}.cmd.detachRight`); if (state && state.val != null) { this.detach.right = !!state.val; } state = this.library.readdb(`panels.${this.name}.cmd.detachLeft`); if (state && state.val != null) { this.detach.left = !!state.val; } await this.library.writedp( `panels.${this.name}.cmd.detachRight`, this.detach.right, definition.genericStateObjects.panel.panels.cmd.detachRight ); await this.library.writedp( `panels.${this.name}.cmd.detachLeft`, this.detach.left, definition.genericStateObjects.panel.panels.cmd.detachLeft ); state = this.library.readdb(`panels.${this.name}.cmd.screenSaver.timeout`); if (state) { this.timeout = parseInt(String(state.val)); } await this.library.writedp( `panels.${this.name}.cmd.screenSaver.timeout`, this.timeout, definition.genericStateObjects.panel.panels.cmd.screenSaver.timeout ); state = this.library.readdb(`panels.${this.name}.info.nspanel.firmwareUpdate`); await this.library.writedp( `panels.${this.name}.info.nspanel.firmwareUpdate`, state && typeof state.val === "number" ? state.val >= 99 ? 100 : state.val : void 0, definition.genericStateObjects.panel.panels.info.nspanel.firmwareUpdate ); for (const id in definition.InternalStates.panel) { const obj = definition.InternalStates.panel[id]; await this.statesControler.setInternalState( `${this.name}/${id}`, obj.val, obj.ack, obj.common, obj.noTrigger ? void 0 : this.onInternalCommand ); } for (const page of this.pages) { if (page && page.name) { this.log.debug( `Initialisation of page ${page.name} - card: ${page.card} - pageItems: ${(page.pageItemConfig || []).length}` ); await page.init(); } else { this.log.error("Page failed or has no name!"); } } this.navigation.init(); this.adapter.subscribeStates(`panels.${this.name}.cmd.*`); this.adapter.subscribeStates(`panels.${this.name}.alarm.*`); this.log.debug(`Panel ${this.name} is initialised!`); { const currentPage = this.library.readdb(`panels.${this.name}.cmd.mainNavigationPoint`); if (currentPage && currentPage.val) { this.navigation.setMainPageByName(String(currentPage.val)); } definition.genericStateObjects.panel.panels.cmd.mainNavigationPoint.common.states = this.navigation.buildCommonStates(); const page = this.navigation.getCurrentMainPoint(); await this.library.writedp( `panels.${this.name}.cmd.mainNavigationPoint`, page, definition.genericStateObjects.panel.panels.cmd.mainNavigationPoint ); } const currentScreensaver = this.library.readdb(`panels.${this.name}.cmd.screenSaver.layout`); const scs = this.pages.filter( (a) => a && (a.card === "screensaver" || a.card === "screensaver2" || a.card === "screensaver3") ); if (currentScreensaver && currentScreensaver.val != null) { if (scs && scs[0]) { this.screenSaver = scs[0]; if (pages.isScreenSaverModeAsNumber(currentScreensaver.val)) { this.screenSaver.overwriteModel(currentScreensaver.val, true); } } } await this.library.writedp( `panels.${this.name}.cmd.screenSaver.layout`, this.screenSaver && this.screenSaver.mode ? import_screensaver.Screensaver.mapModeToNumber(this.screenSaver.mode) : 0, definition.genericStateObjects.panel.panels.cmd.screenSaver.layout ); state = this.library.readdb(`panels.${this.name}.cmd.screenSaver.rotationTime`); let temp = 0; if (state && typeof state.val === "number") { temp = state.val === 0 ? state.val : state.val < 3 ? 3 : state.val > 3600 ? 3600 : state.val; if (this.screenSaver) { this.screenSaver.rotationTime = temp * 1e3; } } await this.library.writedp( `panels.${this.name}.cmd.screenSaver.rotationTime`, temp, definition.genericStateObjects.panel.panels.cmd.screenSaver.rotationTime ); state = this.library.readdb(`panels.${this.name}.cmd.screenSaver.infoIcon`); if (state && typeof state.val === "string" && this.screenSaver) { this.screenSaver.infoIcon = state.val; } await this.library.writedp( `panels.${this.name}.cmd.screenSaver.infoIcon`, (_b = (_a = this.screenSaver) == null ? void 0 : _a.infoIcon) != null ? _b : "", definition.genericStateObjects.panel.panels.cmd.screenSaver.infoIcon ); if (this.buttons) { for (const b in this.buttons) { const k = b; const button = this.buttons[k]; if (button && this.screenSaver) { switch (button.mode) { case "page": { break; } case "switch": case "button": { if (typeof button.state === "string") { button.state = new import_data_item.Dataitem( this.adapter, { type: "state", dp: button.state }, this.screenSaver, this.statesControler ); if (!await button.state.isValidAndInit()) { this.buttons[k] = null; } } break; } } } } } state = this.library.readdb(`panels.${this.name}.info.nspanel.bigIconLeft`); this.info.nspanel.bigIconLeft = state ? !!state.val : false; state = this.library.readdb(`panels.${this.name}.info.nspanel.bigIconRight`); this.info.nspanel.bigIconRight = state ? !!state.val : false; this.initDone = true; this.restartLoops(); }; sendToPanelClass = () => { }; sendToPanel = (payload, ackForType, opt) => { this.sendToPanelClass(payload, ackForType, opt); }; async setActivePage(_page, _notSleep) { var _a, _b, _c; if (_page === void 0) { return; } let page = this._activePage; let sleep = false; if (typeof _page === "boolean") { sleep = !_page; } else { page = _page; sleep = _notSleep != null ? _notSleep : false; } if (!this._activePage) { if (page === void 0) { return; } page.setLastPage((_a = this._activePage) != null ? _a : void 0); await page.setVisibility(true); this._activePage = page; } else if (sleep !== this._activePage.sleep || page !== this._activePage) { if (page != this._activePage) { if (this._activePage) { await this._activePage.setVisibility(false); } if (page) { page.setLastPage((_b = this._activePage) != null ? _b : void 0); if (!sleep) { await page.setVisibility(true); } page.sleep = sleep; this._activePage = page; } } else if (sleep !== this._activePage.sleep) { page.setLastPage((_c = this._activePage) != null ? _c : void 0); if (!sleep) { await this._activePage.setVisibility(true); } this._activePage.sleep = sleep; } } } getActivePage() { if (!this._activePage) { throw new Error(`No active page here, check code!`); } return this._activePage; } get isOnline() { return this._isOnline; } set isOnline(s) { if (this.unload) { return; } this.info.isOnline = s; if (s !== this._isOnline) { void this.library.writedp( `panels.${this.name}.info.isOnline`, s, definition.genericStateObjects.panel.panels.info.isOnline ); if (s) { this.log.info("is online!"); } else { this._activePage = void 0; this.log.warn("is offline!"); } } this._isOnline = s; } async isValid() { return true; } registerOnMessage(fn) { if (this.reivCallbacks.indexOf(fn) === -1) { this.reivCallbacks.push(fn); } } onMessage = async (topic, message) => { for (const fn of this.reivCallbacks) { if (fn) { await fn(topic, message); } } if (topic.endsWith(definition.ReiveTopicAppendix)) { const event = this.convertToEvent(message); if (event) { await this.HandleIncomingMessage(event); } else if (message) { let msg = null; try { msg = JSON.parse(message); } catch { this.log.warn(`Receive a broken msg from mqtt: ${msg}`); } if (!msg) { return; } if ("Flashing" in msg) { this.isOnline = false; this.flashing = msg.Flashing.complete < 99; this.log.info(`Flashing: ${msg.Flashing.complete}%`); await this.library.writedp( `panels.${this.name}.info.nspanel.firmwareUpdate`, msg.Flashing.complete >= 99 ? 100 : msg.Flashing.complete, definition.genericStateObjects.panel.panels.info.nspanel.firmwareUpdate ); return; } } } else if (topic.endsWith("/tele/LWT")) { if (message === "Offline") { this.isOnline = false; } } else if (topic.endsWith("/tele/INFO1")) { this.restartLoops(); } else { const command = (topic.match(/[0-9a-zA-Z]+?\/[0-9a-zA-Z]+$/g) || [])[0]; if (command) { switch (command) { case "stat/POWER2": { await this.library.writedp( `panels.${this.name}.cmd.power2`, message === "ON", definition.genericStateObjects.panel.panels.cmd.power2 ); await this.statesControler.setInternalState(`${this.name}/cmd/power2`, message === "ON", true); break; } case "stat/POWER1": { await this.library.writedp( `panels.${this.name}.cmd.power1`, message === "ON", definition.genericStateObjects.panel.panels.cmd.power1 ); await this.statesControler.setInternalState(`${this.name}/cmd/power1`, message === "ON", true); break; } case "stat/STATUS0": { const data = JSON.parse(message); if (this.name !== this.library.cleandp(data.StatusNET.Mac, false, true)) { this.log.error(`Receive wrong mac address ${data.StatusNET.Mac}! Update ur config!`); } const o = await this.adapter.getForeignObjectAsync(`system.adapter.${this.adapter.namespace}`); if (o && o.native) { if (this.name == this.library.cleandp(data.StatusNET.Mac, false, true)) { const index = o.native.panels.findIndex((a) => a.id === this.name); const ip = data.StatusNET.IPAddress; if (index !== -1 && o.native.panels[index].ip != ip) { o.native.panels[index].ip = ip; await this.adapter.setForeignObjectAsync(o._id, o); } } } await this.library.writedp( `panels.${this.name}.info`, void 0, definition.genericStateObjects.panel.panels.info._channel ); await this.library.writedp( `panels.${this.name}.info.status`, message, definition.genericStateObjects.panel.panels.info.status ); this.info.tasmota.mqttClient = data.StatusMQT.MqttClient; this.info.tasmota.net = data.StatusNET; this.info.tasmota.firmwareversion = data.StatusFWR.Version; this.info.tasmota.safeboot = data.StatusFWR.Version.includes("Safeboot"); this.info.tasmota.uptime = data.StatusSTS.Uptime; this.info.tasmota.sts = data.StatusSTS; await this.writeInfo(); } } } } }; sendRules() { this.sendToTasmota( `${this.topic}/cmnd/Rule3`, `ON CustomSend DO RuleTimer1 120 ENDON ON Rules#Timer=1 DO CustomSend pageType~pageStartup ENDON${this.detach.left ? ` ON Button1#state do Publish ${this.topic}/tele/RESULT {"CustomRecv":"event,button1"} ENDON` : ""}${this.detach.right ? ` ON Button2#state do Publish ${this.topic}/tele/RESULT {"CustomRecv":"event,button2"} ENDON` : ""}` ); this.sendToTasmota(`${this.topic}/cmnd/Rule3`, "1"); } async onStateChange(id, state) { if (state.ack) { return; } if (id.split(".")[1] === this.name) { const cmd = id.replace(`panels.${this.name}.cmd.`, ""); switch (cmd) { case "power1": { this.sendToTasmota(`${this.topic}/cmnd/POWER1`, state.val ? "ON" : "OFF"); break; } case "power2": { this.sendToTasmota(`${this.topic}/cmnd/POWER2`, state.val ? "ON" : "OFF"); break; } case "mainNavigationPoint": { this.navigation.setMainPageByName(state.val ? String(state.val) : "main"); await this.library.writedp( `panels.${this.name}.cmd.mainNavigationPoint`, // eslint-disable-next-line @typescript-eslint/no-base-to-string state.val ? String(state.val) : "main" ); break; } case "goToNavigationPoint": { await this.navigation.setTargetPageByName(state.val ? String(state.val) : "main"); break; } case "screenSaver.timeout": { if (state && state.val != null && typeof state.val === "number") { await this.statesControler.setInternalState( `${this.name}/cmd/screenSaverTimeout`, parseInt(String(state.val)), false ); } break; } case "dim.standby": { if (state && state.val != null && typeof state.val === "number") { await this.statesControler.setInternalState( `${this.name}/cmd/dimStandby`, parseInt(String(state.val)), false ); } break; } case "dim.active": { if (state && state.val != null && typeof state.val === "number") { await this.statesControler.setInternalState( `${this.name}/cmd/dimActive`, parseInt(String(state.val)), false ); } break; } case "dim.dayMode": { if (this.dim.schedule) { this.log.warn("Dim schedule is active - User input ignored!"); } else { this.dim.dayMode = !!state.val; this.sendDimmode(); } await this.library.writedp( `panels.${this.name}.cmd.dim.dayMode`, this.dim.dayMode, definition.genericStateObjects.panel.panels.cmd.dim.dayMode ); break; } case "dim.schedule": { this.dim.schedule = !!state.val; if (this.dim.schedule) { this.sendDimmode(); } await this.library.writedp( `panels.${this.name}.cmd.dim.schedule`, this.dim.schedule, definition.genericStateObjects.panel.panels.cmd.dim.schedule ); break; } case "dim.nightActive": { if (state && state.val != null && typeof state.val === "number") { await this.statesControler.setInternalState( `${this.name}/cmd/dimNightActive`, parseInt(String(state.val)), false ); } break; } case "dim.nightStandby": { if (state && state.val != null && typeof state.val === "number") { await this.statesControler.setInternalState( `${this.name}/cmd/dimNightStandby`, parseInt(String(state.val)), false ); } break; } case "dim.nightHourStart": { if (state && state.val != null && typeof state.val === "number") { if (state.val <= 23 && state.val >= 0 && state.val % 1 === 0) { await this.statesControler.setInternalState( `${this.name}/cmd/dimNightHourStart`, parseInt(String(state.val)), false ); } } break; } case "dim.nightHourEnd": { if (state && state.val != null && typeof state.val === "number") { if (state.val <= 23 && state.val >= 0 && state.val % 1 === 0) { await this.statesControler.setInternalState( `${this.name}/cmd/dimNightHourEnd`, parseInt(String(state.val)), false ); } } break; } case "dim.delay": { if (state && state.val != null && typeof state.val === "number") { this.dim.delay = state.val; this.sendDimmode(); await this.library.writedp( `panels.${this.name}.cmd.dim.delay`, this.dim.delay, definition.genericStateObjects.panel.panels.cmd.dim.delay ); } break; } case "screenSaver.infoIcon": { if (state && state.val != null && typeof state.val === "string") { await this.statesControler.setInternalState( `${this.name}/cmd/screenSaverInfoIcon`, state.val, false ); } break; } case "screenSaver.doubleClick": { if (state && state.val != null) { await this.statesControler.setInternalState( `${this.name}/cmd/screenSaverDoubleClick`, !!state.val, false ); } break; } case "detachLeft": { await this.statesControler.setInternalState(`${this.name}/cmd/detachLeft`, !!state.val, false); break; } case "detachRight": { await this.statesControler.setInternalState(`${this.name}/cmd/detachRight`, !!state.val, false); break; } case "screenSaver.layout": { if (typeof state.val === "number" && pages.isScreenSaverModeAsNumber(state.val)) { await this.statesControler.setInternalState( `${this.name}/cmd/screenSaverLayout`, state.val, false ); } break; } case "screenSaver.rotationTime": { if (state && state.val != null && typeof state.val === "number") { await this.statesControler.setInternalState( `${this.name}/cmd/screenSaverRotationTime`, parseInt(String(state.val)), false ); } break; } } } } /** * timeout screensaver after sec * * @param sec seconds for timeout */ sendScreeensaverTimeout(sec) { this.log.debug(`Set screeensaver timeout to ${sec}s.`); this.sendToPanel(`timeout~${sec}`, false); } sendDimmode() { const hour = (/* @__PURE__ */ new Date()).getHours(); const oldDayMode = this.dim.dayMode; if (this.dim.schedule) { if (this.dim.nightHourStart > this.dim.nightHourEnd) { if (hour >= this.dim.nightHourStart || hour < this.dim.nightHourEnd) { this.dim.dayMode = false; } else { this.dim.dayMode = true; } } else { if (hour >= this.dim.nightHourStart && hour < this.dim.nightHourEnd) { this.dim.dayMode = false; } else { this.dim.dayMode = true; } } } let cmd = `${import_Color.Color.rgb_dec565(import_Color.Color.Black)}~${import_Color.Color.rgb_dec565(import_Color.Color.White)}`; if (this.dim.dayMode) { cmd = `dimmode~${this.dim.standby}~${this.dim.active}~${cmd}`; } else { cmd = `dimmode~${this.dim.nightStandby}~${this.dim.nightActive}~${cmd}`; } if (this.dim.dayMode !== oldDayMode) { void this.library.writedp( `panels.${this.name}.cmd.dim.dayMode`, this.dim.dayMode, definition.genericStateObjects.panel.panels.cmd.dim.dayMode ); } this.sendToPanel(cmd, false); } restartLoops() { if (this.loopTimeout) { this.adapter.clearTimeout(this.loopTimeout); } this.loopTimeout = this.adapter.setTimeout(this.loop, 100); } /** * Do panel work always at full minute * */ loop = () => { this.pages = this.pages.filter((a) => a && !a.unload); let t = Math.random() * 3e4 + 1e4; if (!this.isOnline) { t = 5e3; if (!this.flashing) { this.sendToPanel("pageType~pageStartup", false, { retain: true }); } } if (this.unload) { return; } this.loopTimeout = this.adapter.setTimeout(this.loop, t); }; requestStatusTasmota() { this.sendToTasmota(`${this.topic}/cmnd/STATUS0`, ""); } async delete() { var _a; await super.delete(); if (this.blockStartup) { this.adapter.clearTimeout(this.blockStartup); } this.isOnline = false; if (this.loopTimeout) { this.adapter.clearTimeout(this.loopTimeout); } await this.library.writedp( `panels.${this.name}.info.isOnline`, false, definition.genericStateObjects.panel.panels.info.isOnline ); await this.panelSend.delete(); await this.navigation.delete(); await ((_a = this.screenSaver) == null ? void 0 : _a.delete()); for (const a of this.pages) { if (a) { await a.delete(); } } this.persistentPageItems = {}; this.pages = []; this._activePage = void 0; this.data = {}; this.screenSaver = void 0; } getPagebyUniqueID(uniqueID) { var _a; if (!uniqueID) { return null; } const index = this.pages.findIndex((a) => a && a.name && a.name === uniqueID); return (_a = this.pages[index]) != null ? _a : null; } async writeInfo() { await this.library.writeFromJson( `panels.${this.name}.info`, "panel.panels.info", definition.genericStateObjects, this.info ); } /** * Handle incoming messages from panel * * @param event incoming event.... * @returns void */ async HandleIncomingMessage(event) { if (!event.method) { return; } if (this._activePage && this._activePage.card !== "cardAlarm") { this.log.debug(`Receive message:${JSON.stringify(event)}`); } if (!this.screenSaver) { return; } if (this.isOnline === false && event.method !== "startup") { void this.restartLoops(); return; } switch (event.method) { case "startup": { if (this.blockStartup) { return; } this.blockStartup = this.adapter.setTimeout(() => { this.blockStartup = null; }, 5e3); this.isOnline = true; this.info.nspanel.displayVersion = event.opt; this.info.nspanel.model = event.action; this.requestStatusTasmota(); this.sendToTasmota(`${this.topic}/cmnd/POWER1`, ""); this.sendToTasmota(`${this.topic}/cmnd/POWER2`, ""); this.sendRules(); await this.adapter.delay(200); await this.writeInfo(); this.sendScreeensaverTimeout(this.timeout); this.sendDimmode(); this.navigation.resetPosition(); await this.adapter.delay(100); const i = this.pages.findIndex((a) => a && a.name === "///WelcomePopup"); const popup = i !== -1 ? this.pages[i] : void 0; if (popup) { if (this._activePage === popup) { this._activePage.sendType(true); await this._activePage.update(); } else { await this.setActivePage(popup, false); } } await this.adapter.delay(100); if (this.screenSaver) { await this.screenSaver.createPageItems(); await this.screenSaver.HandleDate(); await this.screenSaver.HandleTime(); } this.log.info("Panel startup finished!"); break; } case "sleepReached": { await this.setActivePage(this.screenSaver); this.navigation.resetPosition(); this.pages.forEach((a) => a && a.reset()); break; } case "pageOpenDetail": { await this.setActivePage(false); await this.getActivePage().onPopupRequest( event.id, event.popup, event.action, event.opt, event ); break; } case "buttonPress2": { if (event.id == "screensaver") { if (this.screenSaverDoubleClick && this.screenSaver.screensaverSwipe) { switch (event.action) { case "bExit": { await this.library.writedp( `panels.${this.name}.buttons.screensaverGesture`, 2, definition.genericStateObjects.panel.panels.buttons.screensaverGesture ); break; } case "swipeUp": { await this.library.writedp( `panels.${this.name}.buttons.screensaverGesture`, 3, definition.genericStateObjects.panel.panels.buttons.screensaverGesture ); break; } case "swipeDown": { await this.library.writedp( `panels.${this.name}.buttons.screensaverGesture`, 4, definition.genericStateObjects.panel.panels.buttons.screensaverGesture ); break; } case "swipeLeft": { await this.library.writedp( `panels.${this.name}.buttons.screensaverGesture`, 5, definition.genericStateObjects.panel.panels.buttons.screensaverGesture ); break; } case "swipeRight": { await this.library.writedp( `panels.${this.name}.buttons.screensaverGesture`, 6, definition.genericStateObjects.panel.panels.buttons.screensaverGesture ); break; } } } if (this.screenSaverDoubleClick && parseInt(event.opt) > 1 || !this.screenSaverDoubleClick) { this.navigation.resetPosition(); await this.navigation.setCurrentPage(); break; } } else if (event.action === "bExit" && event.id !== "popupNotify") { await this.setActivePage(true); } else { if (event.action === "button" && ["bNext", "bPrev", "bUp", "bHome", "bSubNext", "bSubPrev"].indexOf(event.id) != -1) { if (["bPrev", "bUp", "bSubPrev"].indexOf(event.id) != -1) { this.getActivePage().goLeft(); } else if (["bNext", "bHome", "bSubNext"].indexOf(event.id) != -1) { this.getActivePage().goRight(); } break; } await this.getActivePage().onPopupRequest( event.id, event.popup, event.action, event.opt, event ); await this.getActivePage().onButtonEvent(event); } break; } case "renderCurrentPage": { await this.panelSend.onMessage("/stat/RESULT", `{ "CustomSend": "${event.method}" }`); break; } case "button1": { await this.onDetachButtonEvent("left"); break; } case "button2": { await this.onDetachButtonEvent("right"); break; } default: { this.log.warn("Missing method in HandleIncomingMessage()"); } } } onDetachButtonEvent = async (button) => { const action = this.buttons ? button === "left" ? this.buttons.left : this.buttons.right : null; await this.library.writedp(`panels.${this.name}.buttons.${button}`, false, null, true, true); if (action) { switch (action.mode) { case "button": { if (typeof action.state === "string") { this.log.error(`Button ${button} has no state!`); return; } await action.state.setStateTrue(); break; } case "page": { if (typeof action.page === "string") { await this.navigation.setTargetPageByName(action.page); } break; } case "switch": { if (typeof action.state === "string") { this.log.error(`Button ${button} has no state!`); return; } await action.state.setStateFlip(); break; } } } }; onInternalCommand = async (id, state) => { var _a, _b, _c; if (!id.startsWith(this.name)) { return null; } const token = id.replace(`${this.name}/`, ""); if (state && !state.ack && state.val != null) { switch (token) { case "cmd/power1": { this.sendToTasmota(`${this.topic}/cmnd/POWER1`, state.val ? "ON" : "OFF"); break; } case "cmd/power2": { this.sendToTasmota(`${this.topic}/cmnd/POWER2`, state.val ? "ON" : "OFF"); break; } case `cmd/detachRight`: { this.detach.right = !!state.val; await this.library.writedp(`panels.${this.name}.cmd.detachRight`, this.detach.right); this.sendRules(); break; } case "cmd/detachLeft": { this.detach.left = !!state.val; await this.library.writedp(`panels.${this.name}.cmd.detachLeft`, this.detach.left); this.sendRules(); break; } case "cmd/bigIconLeft": { this.info.nspanel.bigIconLeft = !!state.val; this.screenSaver && await this.screenSaver.HandleScreensaverStatusIcons(); await this.library.writeFromJson( `panels.${this.name}.info`, "panel.panels.info", definition.genericStateObjects, this.info ); break; } case "cmd/bigIconRight": { this.info.nspanel.bigIconRight = !!state.val; this.screenSaver && await this.screenSaver.HandleScreensaverStatusIcons(); await this.library.writeFromJson( `panels.${this.name}.info`, "panel.panels.info", definition.genericStateObjects, this.info ); break; } case "cmd/screenSaverTimeout": { if (typeof state.val !== "boolean") { const val = parseInt(String(state.val)); this.timeout = val; this.sendScreeensaverTimeout(this.timeout); await this.statesControler.setInternalState(`${this.name}/cmd/screenSaverTimeout`, val, true); await this.library.writedp(`panels.${this.name}.cmd.screenSaver.timeout`, this.timeout); } break; } case "cmd/dimStandby": { const val = parseInt(String(state.val)); this.dim.standby = val; this.sendDimmode(); await this.library.writedp(`panels.${this.name}.cmd.dim.standby`, this.dim.standby); break; } case "cmd/dimActive": { const val = parseInt(String(state.val)); this.dim.active = val; this.sendDimmode(); await this.library.writedp(`panels.${this.name}.cmd.dim.active`, this.dim.active); break; } case "cmd/dimNightActive": { const val = parseInt(String(state.val)); this.dim.nightActive = val; this.sendDimmode(); await this.library.writedp(`panels.${this.name}.cmd.dim.nightActive`, this.dim.nightActive); break; } case "cmd/dimNightStandby": { const val = parseInt(String(state.val)); this.dim.nightStandby = val; this.sendDimmode(); await this.library.writedp(`panels.${this.name}.cmd.dim.nightStandby`, this.dim.nightStandby); break; } case "cmd/dimNightHourStart": { const val = parseInt(String(state.val)); this.dim.nightHourStart = val; this.sendDimmode(); await this.library.writedp(`panels.${this.name}.cmd.dim.nightHourStart`, this.dim.nightHourStart); break; } case "cmd/dimNightHourEnd": { const val = parseInt(String(state.val)); this.dim.nightHourEnd = val; this.sendDimmode(); await this.library.writedp(`panels.${this.name}.cmd.dim.nightHourEnd`, this.dim.nightHourEnd); break; } case "cmd/NotificationCleared2": case "cmd/NotificationCleared": { await this.controller.systemNotification.clearNotification(this.notifyIndex); } // eslint-disable-next-line no-fallthrough case "cmd/NotificationNext2": case "cmd/NotificationNext": { this.notifyIndex = this.controller.systemNotification.getNotificationIndex(++this.notifyIndex); if (this.notifyIndex !== -1) { const val = this.controller.systemNotification.getNotification(this.notifyIndex); if (val) { await this.statesControler.setInternalState( `${this.name}/cmd/popupNotification${token.endsWith("2") ? "" : "2"}`, JSON.stringify(val), false ); } break; } await this.HandleIncomingMessage({ type: "event", method: "buttonPress2", id: "popupNotify", action: "bExit", opt: "" }); break; } case "cmd/TasmotaRestart": { this.sendToTasmota(`${this.topic}/cmnd/Restart`, "1"); this.log.info("Restart Tasmota!"); this.isOnline = false; break; } case "cmd/screenSaverRotationTime": { if (this.screenSaver && typeof state.val === "number") { const val = state.val === 0 ? state.val : state.val < 3 ? 3 : state.val > 3600 ? 3600 : state.val; if (this.screenSaver.rotationTime !== val * 1e3) { this.screenSaver.rotationTime = val * 1e3; await this.screenSaver.restartRotationLoop(); } await this.library.writedp(`panels.${this.name}.cmd.screenSaver.rotationTime`, val); } break; } case "cmd/screenSaverDoubleClick": { if (this.screenSaver && typeof state.val === "boolean") { this.screenSaverDoubleClick = !!state.val; await this.library.writedp(`panels.${this.name}.cmd.screenSaver.doubleClick`, state.val); } break; } case "cmd/screenSaverInfoIcon": { if (this.screenSaver && typeof state.val === "string") { this.screenSaver.infoIcon = state.val; await this.library.writedp(`panels.${this.name}.cmd.screenSaver.infoIcon`, state.val); } break; } case "cmd/screenSaverLayout": { if (typeof state.val === "number" && pages.isScreenSaverModeAsNumber(state.val)) { if (this.screenSaver) { this.screenSaver.overwriteModel(state.val);