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,334 lines • 81.7 kB
JavaScript
"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 globals = __toESM(require("../types/function-and-const"));
var import_library = require("./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_pagePopup = require("../pages/pagePopup");
var import_system_templates = require("../templates/system-templates");
var import_pageAlarm = require("../pages/pageAlarm");
var import_pageQR = require("../pages/pageQR");
var import_data_item = require("./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");
var import_pageChartBar = require("../pages/pageChartBar");
var import_pageChartLine = require("../pages/pageChartLine");
var import_pageThermo2 = require("../pages/pageThermo2");
var import_admin = require("../configuration/admin");
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;
blockTouchEventsForMs = 200;
// ms
lastSendTypeDate = 0;
isBuzzerAllowed = true;
options;
flashing = false;
screenSaver;
lastCard = "";
notifyIndex = -1;
initDone = false;
lightPopupV2 = true;
// Enable Light Popup v2, created in 2025.
overrideLightPopup = true;
// Override light popup config type.
hideCards = false;
buttons;
navigation;
format;
controller;
topic;
reivCallbacks = [];
panelSend;
statesControler;
CustomFormat;
sendToTasmota = () => {
};
timeout;
dim = {
standby: definition.genericStateObjects.panel.panels.cmd.dim.standby.common.def,
active: definition.genericStateObjects.panel.panels.cmd.dim.active.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 = {
nspanel: {
displayVersion: "",
model: "",
bigIconLeft: false,
bigIconRight: false,
onlineVersion: "",
firmwareUpdate: 100,
berryDriverVersion: 0,
berryDriverVersionOnline: 0,
currentPage: "",
scriptVersion: "unknown"
},
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: ""
}
}
}
};
meetsVersion(version) {
var _a, _b;
if ((_b = (_a = this.info) == null ? void 0 : _a.nspanel) == null ? void 0 : _b.displayVersion) {
return (0, import_tools.isVersionGreaterOrEqual)(this.info.nspanel.displayVersion, version);
}
return false;
}
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.format = { ...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.info.nspanel.scriptVersion = options.scriptVersion || "unknown";
this.info.tasmota.onlineVersion = this.controller.globalPanelInfo.availableTasmotaFirmwareVersion;
this.info.nspanel.onlineVersion = this.controller.globalPanelInfo.availableTftFirmwareVersion;
this.statesControler = options.controller.statesControler;
const admin = new import_admin.AdminConfiguration(this.adapter);
admin.processentrys(options);
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++) {
const 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,
hidden: pageConfig.hidden || false,
dpInit: pageConfig.dpInit
};
const Page = this.newPage(pmconfig, pageConfig);
if (Page) {
this.pages[a] = Page;
if (Page instanceof import_screensaver.Screensaver) {
this.screenSaver = Page;
scsFound += 1;
}
}
}
if (scsFound === 0) {
throw new Error("no screensaver found! Stop!");
}
const navConfig = {
adapter: this.adapter,
panel: this,
navigationConfig: options.navigation
};
this.navigation = new import_navigation.Navigation(navConfig);
}
newPage(pmconfig, pageConfig) {
var _a, _b, _c;
switch ((_a = pageConfig.config) == null ? void 0 : _a.card) {
case "cardChart": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageChartBar.PageChartBar(pmconfig, pageConfig);
}
case "cardLChart": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageChartLine.PageChartLine(pmconfig, pageConfig);
}
case "cardEntities": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageEntities.PageEntities(pmconfig, pageConfig);
}
case "cardSchedule": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageSchedule.PageSchedule(pmconfig, pageConfig);
}
case "cardGrid3":
case "cardGrid2":
case "cardGrid": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageGrid.PageGrid(pmconfig, pageConfig);
}
case "cardThermo": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageThermo.PageThermo(pmconfig, pageConfig);
}
case "cardThermo2": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageThermo2.PageThermo2(pmconfig, pageConfig);
}
case "cardMedia": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageMedia.PageMedia(pmconfig, pageConfig);
}
case "cardQR": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageQR.PageQR(pmconfig, pageConfig);
}
case "cardAlarm": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pageAlarm.PageAlarm(pmconfig, pageConfig);
}
case "cardPower": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pagePower.PagePower(pmconfig, pageConfig);
}
case "popupNotify": {
pageConfig = Panel.getPage(pageConfig, this);
return new import_pagePopup.PagePopup(pmconfig, pageConfig);
}
case "screensaver":
case "screensaver2":
case "screensaver3": {
const ssconfig = {
card: pageConfig.config.card,
panel: this,
id: pmconfig.id,
name: `${pageConfig.uniqueID}`,
adapter: this.adapter,
dpInit: ""
};
if (!pageConfig.config) {
throw new Error(`Page config is missing for page ${pageConfig.uniqueID}`);
}
pageConfig.config.model = ((_c = (_b = this.adapter.config.panels) == null ? void 0 : _b.find((p) => p.topic === this.topic)) == null ? void 0 : _c.model) || "eu";
return new import_screensaver.Screensaver(ssconfig, pageConfig);
}
default: {
throw new Error(`Page config is missing card property for page ${pageConfig.uniqueID}`);
}
}
}
init = async () => {
var _a, _b, _c, _d;
if (this.unload || this.adapter.unload) {
return;
}
this.log.debug(`Panel ${this.name} is initialised!`);
await this.controller.mqttClient.subscribe(`${this.topic}/tele/#`, this.onMessage);
await this.controller.mqttClient.subscribe(`${this.topic}/stat/#`, this.onMessage);
this.log.info(`Setting panel to offline until first message!`);
this.isOnline = false;
const channelObj = structuredClone(definition.genericStateObjects.panel.panels._channel);
channelObj.common.name = this.friendlyName;
channelObj.native = {
topic: this.topic,
tasmotaName: this.friendlyName,
name: this.name
};
if (await this.adapter.getStateAsync(`panels.${this.name}.cmd.dim.delay`)) {
await this.adapter.delObjectAsync(`panels.${this.name}.cmd.dim.delay`);
}
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}.pagePopup`,
void 0,
definition.genericStateObjects.panel.panels.pagePopup._channel
);
await this.library.writedp(
`panels.${this.name}.cmd.pagePopup`,
void 0,
definition.genericStateObjects.panel.panels.cmd.pagePopup._channel
);
for (const key of Object.keys(definition.genericStateObjects.panel.panels.pagePopup)) {
if (key !== "_channel") {
await this.library.writedp(
`panels.${this.name}.pagePopup.${key}`,
void 0,
definition.genericStateObjects.panel.panels.pagePopup[key]
);
}
}
for (const key of Object.keys(definition.genericStateObjects.panel.panels.cmd.pagePopup)) {
if (key !== "_channel") {
await this.library.writedp(
`panels.${this.name}.cmd.pagePopup.${key}`,
void 0,
definition.genericStateObjects.panel.panels.cmd.pagePopup[key]
);
}
}
await this.library.writedp(
`panels.${this.name}.cmd.isBuzzerAllowed`,
void 0,
definition.genericStateObjects.panel.panels.cmd.isBuzzerAllowed
);
this.isBuzzerAllowed = !!((_b = (_a = this.library.readdb(`panels.${this.name}.cmd.isBuzzerAllowed`)) == null ? void 0 : _a.val) != null ? _b : true);
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}.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 key of keys) {
if (!definition.isDimConfigKey(key)) {
continue;
}
const state2 = this.library.readdb(`panels.${this.name}.cmd.dim.${key}`);
if (state2 && state2.val != null && definition.isDimValueForKey(key, state2.val)) {
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.hideCards`);
if (state && state.val != null) {
this.hideCards = !!state.val;
}
await this.library.writedp(
`panels.${this.name}.cmd.hideCards`,
this.hideCards,
definition.genericStateObjects.panel.panels.cmd.hideCards
);
await this.library.writedp(
`panels.${this.name}.cmd.buzzer`,
"",
definition.genericStateObjects.panel.panels.cmd.buzzer
);
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
);
let val = void 0;
state = this.library.readdb(`panels.${this.name}.cmd.screenSaver.headingNotification`);
if (state && typeof state.val === "string" && this.screenSaver) {
this.screenSaver.headingNotification = state.val;
val = state.val;
}
await this.library.writedp(
`panels.${this.name}.cmd.screenSaver.headingNotification`,
val,
definition.genericStateObjects.panel.panels.cmd.screenSaver.headingNotification
);
val = void 0;
state = this.library.readdb(`panels.${this.name}.cmd.screenSaver.textNotification`);
if (state && typeof state.val === "string" && this.screenSaver) {
this.screenSaver.textNotification = state.val;
val = state.val;
}
await this.library.writedp(
`panels.${this.name}.cmd.screenSaver.textNotification`,
val,
definition.genericStateObjects.panel.panels.cmd.screenSaver.textNotification
);
val = void 0;
state = this.library.readdb(`panels.${this.name}.cmd.screenSaver.activateNotification`);
if (state && state.val != null && this.screenSaver) {
this.screenSaver.customNotification = !!state.val;
val = !!state.val;
}
await this.library.writedp(
`panels.${this.name}.cmd.screenSaver.activateNotification`,
!!val,
definition.genericStateObjects.panel.panels.cmd.screenSaver.activateNotification
);
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) {
if (this.adapter.config.debugLogPages) {
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();
if (this.adapter.config.debugLogPages) {
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
);
}
await this.adapter.delay(100);
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 (globals.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`,
(_d = (_c = this.screenSaver) == null ? void 0 : _c.infoIcon) != null ? _d : "",
definition.genericStateObjects.panel.panels.cmd.screenSaver.infoIcon
);
if (this.buttons && this.screenSaver) {
const entries = Object.entries(this.buttons);
const inits = [];
for (const [key, button] of entries) {
if (!button) {
continue;
}
switch (button.mode) {
case "page":
break;
case "switch":
case "button": {
if (typeof button.state === "string") {
const di = new import_data_item.Dataitem(
this.adapter,
{ type: "state", dp: button.state },
this.screenSaver,
this.statesControler
);
button.state = di;
inits.push(
di.isValidAndInit().then((ok) => {
if (!ok) {
if (this.buttons) {
this.buttons[key] = null;
}
}
})
);
}
break;
}
}
}
await Promise.all(inits);
}
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.restartLoops();
};
sendToPanelClass = () => {
};
sendToPanel = (payload, ackForType, force, opt) => {
this.sendToPanelClass(payload, ackForType, force, opt);
};
/**
* Activate a page or toggle sleep on the current page.
*
* Behavior:
* - If `_page` is a boolean: `true` wakes the current page, `false` puts it to sleep.
* - If `_page` is a Page: activates that page; `_notSleep === true` keeps it awake, otherwise it starts asleep.
*
* @param _page Target page or boolean toggle for current page
* @param _notSleep When `_page` is a Page, `true` means not sleeping (visible), `false` means sleeping
* @returns Promise<void>
*/
async setActivePage(_page, _notSleep) {
if (_page === void 0) {
return;
}
let targetPage = this._activePage;
let targetSleep = false;
if (typeof _page === "boolean") {
if (!this._activePage) {
return;
}
targetSleep = !_page;
} else {
targetPage = _page;
targetSleep = _notSleep != null ? _notSleep : false;
}
if (!this._activePage) {
if (!targetPage) {
return;
}
targetPage.setLastPage(void 0);
if (!targetSleep) {
await targetPage.setVisibility(true);
}
targetPage.sleep = targetSleep;
this._activePage = targetPage;
return;
}
if (targetPage && targetPage !== this._activePage) {
await this._activePage.setVisibility(false);
targetPage.setLastPage(this._activePage);
if (!targetSleep) {
await targetPage.setVisibility(true);
}
targetPage.sleep = targetSleep;
this._activePage = targetPage;
return;
}
if (targetSleep !== this._activePage.sleep) {
this._activePage.sleep = targetSleep;
if (!targetSleep) {
this._activePage.sendType(true);
await this._activePage.setVisibility(true);
}
return;
}
if (!targetSleep) {
this.log.warn(
`setActivePage called but nothing changed! Resending active page to panel. Page: ${this._activePage.name} - Sleep: ${this._activePage.sleep}`
);
this._activePage.sendType(true);
await this._activePage.update();
}
}
getActivePage() {
if (!this._activePage) {
throw new Error(`No active page here panel ${this.friendlyName}, check code!`);
}
return this._activePage;
}
get isOnline() {
return this._isOnline;
}
set isOnline(s) {
if (this.unload && s) {
return;
}
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 this._activePage.setVisibility(false);
this.restartLoops();
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.log.info(`Going offline for flashing!`);
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 ("nlui_driver_version" in msg) {
this.info.nspanel.berryDriverVersion = parseInt(msg.nlui_driver_version);
await this.library.writedp(
`panels.${this.name}.info.nspanel.berryDriverVersion`,
this.info.nspanel.berryDriverVersion,
definition.genericStateObjects.panel.panels.info.nspanel.berryDriverVersion
);
if (this.unload || this.adapter.unload) {
return;
}
this.adapter.setTimeout(async () => {
let result = void 0;
try {
result = await this.adapter.fetch(
"https://raw.githubusercontent.com/ticaki/ioBroker.nspanel-lovelace-ui/main/json/version.json"
);
if (!result) {
return;
}
const version = this.adapter.config.useBetaTFT ? result[`berry-beta`].split("_")[0] : result.berry.split("_")[0];
if (parseInt(version) != this.info.nspanel.berryDriverVersion && this.info.nspanel.berryDriverVersion != -1) {
const url = `http://${this.info.tasmota.net.IPAddress}/cm?${this.adapter.config.useTasmotaAdmin ? `user=admin&password=${this.adapter.config.tasmotaAdminPassword}` : ``}&cmnd=Backlog UrlFetch https://raw.githubusercontent.com/ticaki/ioBroker.nspanel-lovelace-ui/main/tasmota/berry/${version}/autoexec.be; Restart 1`;
this.log.info(
`Automatic update of the berry driver version from ${this.info.nspanel.berryDriverVersion} to ${version} on tasmota with IP ${this.info.tasmota.net.IPAddress} and ${this.info.tasmota.net.Hostname}.`
);
await this.adapter.fetch(url);
}
} catch {
}
}, 1);
return;
}
}
} else if (topic.endsWith("/tele/LWT")) {
if (message === "Offline") {
}
} 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();
break;
}
default: {
if (this.adapter.config.debugLogMqtt) {
this.log.debug(`Receive other message ${topic} with ${message}`);
}
}
}
}
}
};
sendRules() {
this.sendToTasmota(
`${this.topic}/cmnd/Rule3`,
`ON CustomSend DO RuleTimer3 120 ENDON ON Rules#Timer=3 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) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
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": {
const v = state.val;
if (typeof v === "string") {
this.navigation.setMainPageByName(v ? v : "main");
await this.library.writedp(`panels.${this.name}.cmd.mainNavigationPoint`, v ? v : "main");
}
break;
}
case "goToNavigationPoint": {
if (typeof state.val === "string") {
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 "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" && globals.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;
}
case "screenSaver.activateNotification": {
if (state && state.val != null) {
await this.statesControler.setInternalState(
`${this.name}/cmd/screensaverActivateNotification`,
!!state.val,
false
);
}
break;
}
case "screenSaver.headingNotification": {
if (state && state.val != null && typeof state.val === "string") {
await this.statesControler.setInternalState(
`${this.name}/cmd/screensaverHeadingNotification`,
String(state.val),
false
);
}
break;
}
case "screenSaver.textNotification": {
if (state && state.val != null && typeof state.val === "string") {
await this.statesControler.setInternalState(
`${this.name}/cmd/screensaverTextNotification`,
String(state.val),
false
);
}
break;
}
/* case 'hideCards': {
if (state && state.val != null) {
this.hideCards = !!state.val;
await this.library.writedp(
`panels.${this.name}.cmd.hideCards`,
this.hideCards,
definition.genericStateObjects.panel.panels.cmd.hideCards,
);
}
break;
} */
case "hideCards": {
if (state && state.val != null) {
await this.statesControler.setInternalState(`${this.name}/cmd/hideCards`, !!state.val, false);
}
break;
}
case "buzzer": {
if (state && state.val != null && typeof state.val === "string" && state.val.trim()) {
this.sendToTasmota(`${this.topic}/cmnd/Buzzer`, state.val.trim());
await this.statesControler.setInternalState(`${this.name}/cmd/buzzer`, "", true);
}
break;
}
case "pagePopup.activate": {
const global = (_a = this.library.readdb(`panels.${this.name}.cmd.pagePopup.global`)) == null ? void 0 : _a.val;
const details = {
id: ((_b = this.library.readdb(`panels.${this.name}.cmd.pagePopup.id`)) == null ? void 0 : _b.val) || "",
priority: (_c = this.library.readdb(`panels.${this.name}.cmd.pagePopup.priority`)) == null ? void 0 : _c.val,
global: !!global,
type: ((_d = this.library.readdb(`panels.${this.name}.cmd.pagePopup.type`)) == null ? void 0 : _d.val) || "information",
headline: ((_e = this.library.readdb(`panels.${this.name}.cmd.pagePopup.headline`)) == null ? void 0 : _e.val) || "",
text: ((_f = this.library.readdb(`panels.${this.name}.cmd.pagePopup.text`)) == null ? void 0 : _f.val) || "",
buttonLeft: ((_g = this.library.readdb(`panels.${this.name}.cmd.pagePopup.buttonLeft`)) == null ? void 0 : _g.val) || "",
buttonMid: ((_h = this.library.readdb(`panels.${this.name}.cmd.pagePopup.buttonMid`)) == null ? void 0 : _h.val) || "",
buttonRight: ((_i = this.library.readdb(`panels.${this.name}.cmd.pagePopup.buttonRight`)) == null ? void 0 : _i.val) || "",
colorHeadline: (0, import_tools.getRGBFromValue)(
((_j = this.library.readdb(`panels.${this.name}.cmd.pagePopup.colorHeadline`)) == null ? void 0 : _j.val) || "#FFFFFF"
),
colorText: (0, import_tools.getRGBFromValue)(
((_k = this.library.readdb(`panels.${this.name}.cmd.pagePopup.colorText`)) == null ? void 0 : _k.val) || "#FFFFFF"
),
colorButtonLeft: (0, import_tools.getRGBFromValue)(
((_l = this.library.readdb(`panels.${this.name}.cmd.pagePopup.colorButtonLeft`)) == null ? void 0 : _l.val) || "#FFFFFF"
),
colorButtonMid: (0, import_tools.getRGBFromValue)(
((_m = this.library.readdb(`panels.${this.name}.cmd.pagePopup.colorButtonMid`)) == null ? void 0 : _m.val) || "#FFFFFF"
),
colorButtonRight: (0, import_tools.getRGBFromValue)(
((_n = this.library.readdb(`panels.${this.name}.cmd.pagePopup.colorButtonRight`)) == null ? void 0 : _n.val) || "#FFFFFF"
),
icon: ((_o = this.library.readdb(`panels.${this.name}.cmd.pagePopup.icon`)) == null ? void 0 : _o.val) || void 0,
textSize: String((_p = this.library.readdb(`panels.${this.name}.cmd.pagePopup.textSize`)) == null ? void 0 : _p.val) || "3",
iconColor: (0, import_tools.getRGBFromValue)(
((_q = this.library.readdb(`panels.${this.name}.cmd.pagePopup.iconColor`)) == null ? void 0 : _q.val) || "#FFFFFF"
),
alwaysOn: !!((_s = (_r = this.library.readdb(`panels.${this.name}.cmd.pagePopup.alwaysOn`)) == null ? void 0 : _r.val) != null ? _s : true),
buzzer: !!((_u = (_t = this.library.readdb(`panels.${this.name}.cmd.pagePopup.buzzer`)) == null ? void 0 : _t.val) != null ? _u : false)
};
let panels = [this];
if (global) {
panels = this.controller.panels;
}
for (const panel of panels) {
await this.statesControler.setInternalState(
`${panel.name}/cmd/popupNotificationCustom`,
JSON.stringify(details),
false
);
}
break;
}
case "isBuzzerAllowed": {
if (state && state.val != null) {
await this.statesControler.setInternalState(
`${this.name}/cmd/isBuzzerAllowed`,
!!state.val,
false
);
}
break;
}
}
}
}
/**
* timeout screensaver after sec
*
* @param sec seconds for timeout
*/
sendScreensaverTimeout(sec) {
if (this.unload) {
return;
}
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.foreground)}`;
this.log.debug(
`set color to RGB ${JSON.stringify(import_Color.Color.foreground)} -> ${import_Color.Color.rgb_dec565(import_Color.Color.foreground)}`
);
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
);
}
if (this.unload) {
return;
}
this.sendToPanel(cmd, false);
}
restartLoops() {
if (this.loopTimeout) {
this.adapter.clearTimeout(this.loopTimeout);
}
if (this.unload || this.adapter.unload) {
return;
}
this.loopTimeout = this.adapter.setTimeout(() => {
this.loop();
}, 200);
}
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.panelSend.resetMessageDB();
this.sendToPanel("pageType~pageStartup", false, true, { retain: true });
}
}
if (this.unload || this.adapter.unload) {
return;
}
this.loopTimeout = this.adapter.setTimeout(() => this.loop, t);
};
requestStatusTasmota() {
this.sendToTasmota(`${this.topic}/cmnd/STATUS0`, "");
}
async delete() {
var _a;
this.unload = true;
this.sendToPanel("pageType~pageStartup", false, true, { retain: true });
if (this.blockStartup) {
this.adapter.clearTimeout(this.blockStartup);
}
this.log.info("Goint offline because delete panel!");
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.navigation.delete();
await ((_a = this.screenSaver) == null ? void 0 : _a.delete());
this.screenSaver = void 0;
for (const a of this.pages) {
if (a) {
await a.delete();
}
}
await this.panelSend.delete();
this.controller.mqttClient.removeByFunction(this.onMessage);
await this.statesControler.deletePageLoop(this.onInternalCommand);
this.persistentPageItems = {};
this.pages = [];
this._activePage = void 0;
this.data = {};
await super.delete();
}
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;
}
getPageIndexbyUnique