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.
455 lines (454 loc) • 16.1 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __typeError = (msg) => {
throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var data_item_exports = {};
__export(data_item_exports, {
Dataitem: () => Dataitem,
isDataItem: () => isDataItem
});
module.exports = __toCommonJS(data_item_exports);
var import_Color = require("../const/Color");
var import_library = require("./library");
var import_function_and_const = require("../types/function-and-const");
var _compiledReadFn, _compiledWriteFn;
class Dataitem extends import_library.BaseClass {
/**
* Call isValidAndInit() after constructor and check return value - if false, this object is not configured correctly.
*
* @param adapter this of adapter
* @param options {NSPanel.DataItemsOptions}
* @param parent {BaseTriggeredPage}
* @param db {StatesControler}
*/
constructor(adapter, options, parent, db) {
super(adapter, options.name || "");
__privateAdd(this, _compiledReadFn);
__privateAdd(this, _compiledWriteFn);
__publicField(this, "options");
//private obj: ioBroker.Object | null | undefined;
__publicField(this, "stateDB");
__publicField(this, "type");
__publicField(this, "parent");
__publicField(this, "common", {});
__publicField(this, "_writeable", false);
this.options = options;
this.stateDB = db;
this.parent = parent;
switch (this.options.type) {
case "const": {
if (this.options.constVal === "///timeString") {
this.options = {
type: "internal",
dp: "///timeString"
};
}
break;
}
}
switch (this.options.type) {
case "const":
this.options.constVal = import_Color.Color.getColorFromDefaultOrReturn(this.options.constVal);
this.setTypeFromValue(this.options.constVal);
break;
case "state":
case "triggered":
this.type = this.options.forceType ? this.options.forceType : void 0;
break;
case "internalState":
case "internal": {
if (!this.options.dp.startsWith("///")) {
this.options.dp = `${this.parent.basePanel.name}/${this.options.dp}`;
}
this.type = void 0;
}
}
}
get writeable() {
return this._writeable;
}
set writeable(b) {
this._writeable = b;
}
/**
* Init and check dp is valid
*
* @returns if false value is not valid
*/
async isValidAndInit() {
switch (this.options.type) {
case "const":
return !(this.options.constVal === void 0 || this.options.constVal === null);
case "state":
case "internal":
case "internalState":
case "triggered": {
if (!this.options.dp) {
return false;
}
this.options.dp = this.options.dp.replace(
"${this.namespace}",
`${this.adapter.namespace}.panels.${this.parent.basePanel.name}`
);
const obj = await this.stateDB.getObjectAsync(this.options.dp);
if (!obj || obj.type != "state" || !obj.common) {
this.log.warn(`801: ${this.options.dp} has a invalid state object!`);
return false;
}
this.type = this.type || obj.common.type;
this.options.role = obj.common.role;
this._writeable = !!obj.common.write;
this.common = obj.common;
if (this.options.type == "triggered") {
await this.stateDB.setTrigger(this.options.dp, this.parent, false, void 0, this.options.change);
} else if (this.options.type == "internal") {
await this.stateDB.setTrigger(this.options.dp, this.parent, true, void 0, this.options.change);
} else if (this.options.type == "internalState") {
await this.stateDB.setTrigger(this.options.dp, this.parent, true, false);
}
try {
await this.stateDB.getState(this.options.dp);
return true;
} catch (e) {
this.log.error(`Error 1001: ${typeof e === "string" ? e.replaceAll("Error: ", "") : e}`);
return false;
}
}
}
return false;
}
async getRawState() {
try {
switch (this.options.type) {
case "const":
return { val: this.options.constVal, ack: true, ts: Date.now(), lc: Date.now(), from: "" };
case "state":
case "triggered":
if (!this.options.dp) {
throw new Error(`Error 1002 type is ${this.options.type} but dp is undefined`);
}
return await this.stateDB.getState(this.options.dp);
case "internalState":
case "internal": {
return await this.stateDB.getState(this.options.dp);
}
}
} catch (e) {
this.log.error(`Error 1003: ${e.replaceAll("Error: ", "")}`);
}
return null;
}
trueType() {
var _a;
return "dp" in this.options ? (_a = this.stateDB.getType(this.options.dp)) != null ? _a : this.type : this.type;
}
async getCommonStates(force = false) {
return "dp" in this.options ? this.stateDB.getCommonStates(this.options.dp, force) : null;
}
async getState() {
let state = await this.getRawState();
if (state) {
state = structuredClone(state);
if (this.options.type !== "const" && this.options.read) {
try {
if (typeof this.options.read === "string") {
if (!__privateGet(this, _compiledReadFn)) {
__privateSet(this, _compiledReadFn, new Function(
"val",
"Color",
"language",
"lc",
"options",
this.options.read
));
}
state.val = __privateGet(this, _compiledReadFn).call(this, state.val, import_Color.Color, this.adapter.language ? this.adapter.language : "en", state.lc, this.options.constants);
} else {
state.val = this.options.read(state.val);
}
} catch (e) {
this.log.error(
`Read for dp: ${this.options.dp} is invalid! read: ${String(this.options.read)} Error: ${String(e)}`
);
}
}
}
return state;
}
async getObject() {
const state = await this.getState();
if ((state == null ? void 0 : state.val) != null) {
if (typeof state.val === "string") {
try {
const value = JSON.parse(state.val);
return value;
} catch {
let value = state.val;
if (typeof value === "string") {
value = value.trim();
if (value.startsWith("#")) {
const v = import_Color.Color.ConvertWithColordtoRgb(value);
if (import_Color.Color.isRGB(v)) {
return v;
}
} else if (this.options.role === "level.color.name" || this.options.role === "level.color.rgb") {
return import_Color.Color.ConvertWithColordtoRgb(value);
}
}
}
} else if (typeof state.val === "object") {
return state.val;
} else if (typeof state.val === "number") {
return import_Color.Color.decToRgb(state.val);
}
}
return null;
}
async getRGBDec() {
const value = await this.getRGBValue();
if (value) {
return String(import_Color.Color.rgb_dec565(value));
}
return null;
}
async getRGBValue() {
const value = await this.getObject();
if (value) {
if (import_Color.Color.isRGB(value)) {
return value;
}
if (typeof value == "object" && "red" in value && "blue" in value && "green" in value) {
return { r: Number(value.red), g: Number(value.green), b: Number(value.blue) };
}
}
return null;
}
async getIconScale() {
const value = await this.getObject();
if (value) {
if ((0, import_function_and_const.isIconColorScaleElement)(value)) {
return value;
}
}
return null;
}
async getTranslatedString() {
const val = await this.getString();
if (val !== null) {
return this.library.getTranslation(val);
}
return null;
}
/**
* Returns the state's value as a string, or `null` if no meaningful value exists.
*
* Null semantics:
* - Returns `null` when the underlying state is missing, or `state.val === null`.
* - For `state` / `triggered` with `substring` set, returns `null` if `state` is missing
* or `state.val === null`. (No slicing is attempted in that case.)
*
* Notes:
* - Any non-null value is coerced with `String(...)`.
* - This method does NOT distinguish "state exists but empty string" — an empty string
* is a valid (non-null) return value.
*/
async getString() {
const state = await this.getState();
try {
switch (this.options.type) {
case "const":
return state && state.val !== null ? typeof state.val === "object" ? JSON.stringify(state.val) : String(state.val) : null;
case "state":
case "triggered":
if (this.options.substring) {
const args = this.options.substring;
return state && state.val !== null ? typeof state.val === "object" ? JSON.stringify(state.val) : String(state.val).substring(args[0], args[1]) : null;
}
return state && state.val !== null ? typeof state.val === "object" ? JSON.stringify(state.val) : String(state.val) : null;
case "internalState":
case "internal":
return state && state.val !== null ? String(state.val) : null;
}
} catch {
this.log.error(`Error in getString for ${this.options.dp}`);
}
return null;
}
/**
* Returns the state's value as a number (scaled when configured), or `null` if not numeric.
*
* Null semantics:
* - Returns `null` when the state is missing, or when `state.val` cannot be interpreted
* as a finite number (e.g., undefined, '', non-numeric text).
*
* Notes:
* - Accepts numeric strings ("42", "3.14") and numbers.
* - When `options.scale` is present, maps the raw value to 0..100 via Color.scale and truncates.
* - Returns 0 as a valid number when the parsed value is zero; only non-parsable values yield `null`.
*/
async getNumber() {
const result = await this.getState();
if (result && (typeof result.val === "number" || typeof result.val === "string" && result.val && !isNaN(Number(result.val)))) {
let val = parseFloat(String(result.val));
if (this.options.scale !== void 0) {
val = Math.trunc(import_Color.Color.scale(val, this.options.scale.min, this.options.scale.max, 0, 100));
}
return val;
}
return null;
}
/**
* Returns the state's value as a boolean, or `null` if the datapoint does not exist.
*
* Boolean mapping:
* - String values "ok", "on", "yes", "true", "online" (case-insensitive) => true
* - Any other present value uses JS truthiness via `!!state.val`
*
* Null vs false semantics:
* - If `getState()` returns an object, a boolean is always produced (true/false).
* - If `getState()` returns null:
* - If the referenced object exists and is of type "state" (via getObjectAsync), returns **false**
* (i.e., "state exists but currently has no value" -> treat as off/false).
* - If the object does not exist or is not a "state", returns **null**
* (i.e., "no such datapoint" -> unknown / not applicable).
*
* Use cases:
* - `false` means the datapoint exists and evaluates to a falsy state.
* - `null` means "cannot decide": the datapoint is missing or not a state.
*/
async getBoolean() {
const result = await this.getState();
if (result) {
if (typeof result.val === "string") {
switch (result.val.toLowerCase()) {
case "ok":
case "on":
case "yes":
case "true":
case "online":
return true;
}
}
return !!result.val;
}
const o = this.options.dp && await this.parent.basePanel.statesControler.getObjectAsync(this.options.dp);
if (o && o.type === "state") {
return false;
}
return null;
}
setTypeFromValue(val) {
switch (typeof val) {
case "string":
this.type = "string";
break;
case "number":
case "bigint":
this.type = "number";
break;
case "boolean":
this.type = "boolean";
break;
case "undefined":
this.type = void 0;
break;
case "symbol":
case "object":
case "function":
this.type = "object";
}
}
async setStateTrue() {
await this.setState(true);
}
async setStateFalse() {
await this.setState(false);
}
/**
* Flip this 'ON'/'OFF', 0/1 or true/false. Depend on this.type
*/
async setStateFlip() {
const value = await this.getBoolean();
this.log.debug(String(value));
switch (this.type) {
case "boolean":
await this.setState(!value);
break;
case "number":
await this.setState(value ? 0 : 1);
break;
case "string":
await this.setState(value ? "OFF" : "ON");
break;
}
}
/**
* Set a internal, const or external State
*
* @param val number | boolean | string | null
* @returns void
*/
async setState(val) {
if (val === void 0) {
return;
}
if (this.options.type === "const") {
this.options.constVal = val;
} else {
try {
if (this.options.write) {
if (typeof this.options.write === "string") {
if (!__privateGet(this, _compiledWriteFn)) {
__privateSet(this, _compiledWriteFn, new Function("val", "Color", this.options.write));
}
val = __privateGet(this, _compiledWriteFn).call(this, val, import_Color.Color);
} else {
val = this.options.write(val);
}
}
} catch (e) {
this.log.error(
`Write for dp: ${this.options.dp} is invalid! write: ${String(this.options.write)} Error: ${String(e)}`
);
}
await this.stateDB.setState(this, val, this._writeable);
}
}
}
_compiledReadFn = new WeakMap();
_compiledWriteFn = new WeakMap();
function isDataItem(F) {
if (F instanceof Dataitem) {
return true;
}
return false;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Dataitem,
isDataItem
});
//# sourceMappingURL=data-item.js.map