Add icon 3

This commit is contained in:
ticaki
2025-01-23 17:01:57 +01:00
parent a3df442a6a
commit deb7f6788e

View File

@@ -452,9 +452,11 @@ let Unlock_Service: PageType =
'type': 'cardUnlock',
'heading': findLocaleServMenu('service_pages'),
'useColor': true,
'items': [/*PageItem*/{ id: 'alias.0.NSPanel.Unlock',
'items': [/*PageItem*/{
id: 'alias.0.NSPanel.Unlock',
targetPage: 'NSPanel_Service_SubPage',
autoCreateALias: true }
autoCreateALias: true
}
]
};
@@ -598,12 +600,16 @@ let NSPanel_Service_SubPage: PageType =
'items': [
/*PageItem*/{navigate: true, id: 'NSPanel_Screensaver', icon: 'monitor-dashboard', offColor: Menu, onColor: Menu, name: findLocaleServMenu('screensaver'), buttonText: findLocaleServMenu('more')},
/*PageItem*/{navigate: true, id: 'NSPanel_Relays', icon: 'electric-switch', offColor: Menu, onColor: Menu, name: findLocaleServMenu('relays'), buttonText: findLocaleServMenu('more')},
/*PageItem*/{ id:AliasPath + 'Config.temperatureUnitNumber', icon: 'gesture-double-tap', name: findLocaleServMenu('temp_unit'), offColor: Menu, onColor: Menu,
modeList: ['°C', '°F', 'K']},
/*PageItem*/{ id: AliasPath + 'Config.localeNumber', icon: 'select-place', name: findLocaleServMenu('language'), offColor: Menu, onColor: Menu,
/*PageItem*/{
id: AliasPath + 'Config.temperatureUnitNumber', icon: 'gesture-double-tap', name: findLocaleServMenu('temp_unit'), offColor: Menu, onColor: Menu,
modeList: ['°C', '°F', 'K']
},
/*PageItem*/{
id: AliasPath + 'Config.localeNumber', icon: 'select-place', name: findLocaleServMenu('language'), offColor: Menu, onColor: Menu,
modeList: ['en-US', 'de-DE', 'nl-NL', 'da-DK', 'es-ES', 'fr-FR', 'it-IT', 'ru-RU', 'nb-NO', 'nn-NO', 'pl-PL', 'pt-PT', 'af-ZA', 'ar-SY',
'bg-BG', 'ca-ES', 'cs-CZ', 'el-GR', 'et-EE', 'fa-IR', 'fi-FI', 'he-IL', 'hr-xx', 'hu-HU', 'hy-AM', 'id-ID', 'is-IS', 'lb-xx',
'lt-LT', 'ro-RO', 'sk-SK', 'sl-SI', 'sv-SE', 'th-TH', 'tr-TR', 'uk-UA', 'vi-VN', 'zh-CN', 'zh-TW']},
'lt-LT', 'ro-RO', 'sk-SK', 'sl-SI', 'sv-SE', 'th-TH', 'tr-TR', 'uk-UA', 'vi-VN', 'zh-CN', 'zh-TW']
},
/*PageItem*/{navigate: true, id: 'NSPanel_Script', icon: 'code-json', offColor: Menu, onColor: Menu, name: findLocaleServMenu('script'), buttonText: findLocaleServMenu('more')},
]
};
@@ -3720,7 +3726,8 @@ async function check_updates() {
* @param {Object} obj - The object containing the state change information.
* @throws {Error} If an error occurs during the state change handling.
*/
on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async function (obj) { try {
on({id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any'}, async function (obj) {
try {
const val = obj.state ? obj.state.val : false;
if (!val) {
if (Debug) {
@@ -3756,7 +3763,8 @@ on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async
* @returns {Promise<void>} A promise that resolves when the update data has been retrieved.
* @throws {Error} If an error occurs during the data retrieval.
*/
async function get_panel_update_data() { try {
async function get_panel_update_data () {
try {
if (isSetOptionActive) {
await createStateAsync(NSPanel_Path + 'Config.Update.UpdateMessage', true, <iobJS.StateCommon> {read: true, write: true, name: 'Update-Message', type: 'boolean', def: true});
if (autoCreateAlias) {
@@ -3803,7 +3811,8 @@ async function get_panel_update_data() { try {
* @function get_current_tasmota_ip_address
* @returns {string} The IP address of the Tasmota device.
*/
function get_current_tasmota_ip_address() { try {
function get_current_tasmota_ip_address () {
try {
const infoObjId = config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESULT'.length) + 'INFO2';
const infoObj = JSON.parse(getState(infoObjId).val);
@@ -4433,7 +4442,8 @@ function update_tasmota_firmware() {
* @param {Object} obj - The object containing the state change information.
* @throws {Error} If an error occurs during the state change handling.
*/
on({ id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESULT'.length) + 'INFO1', change: 'ne' }, async (obj) => { try {
on({id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESULT'.length) + 'INFO1', change: 'ne'}, async (obj) => {
try {
if (getState(NSPanel_Path + 'Config.Update.activ').val == 0) {
let Tasmota_JSON: any = JSON.parse(obj.state.val);
if (Tasmota_JSON.Info1.Version.indexOf('safeboot') != -1) {
@@ -4487,7 +4497,8 @@ async function SendToPanel(val: NSPanel.Payload | NSPanel.Payload[]) {
* @param {Object} obj - The object containing the state change information.
* @throws {Error} If an error occurs during the state change handling.
*/
on({ id: NSPanel_Alarm_Path + 'Alarm.AlarmState', change: 'ne' }, async (obj) => { try {
on({id: NSPanel_Alarm_Path + 'Alarm.AlarmState', change: 'ne'}, async (obj) => {
try {
if ((obj.state ? obj.state.val : '') == 'armed' || (obj.state ? obj.state.val : '') == 'disarmed' || (obj.state ? obj.state.val : '') == 'triggered') {
if (Debug) {
log('Trigger AlarmState aktivePage: ' + activePage, 'info');
@@ -4512,7 +4523,8 @@ on({ id: NSPanel_Alarm_Path + 'Alarm.AlarmState', change: 'ne' }, async (obj) =>
* @param {number | undefined} page - The page number associated with the event, if applicable.
* @param {string[] | undefined} words - Additional words or parameters associated with the event, if applicable.
*/
function HandleMessage(typ: string, method: NSPanel.EventMethod, page: number | undefined, words: string[] | undefined): void { try {
function HandleMessage (typ: string, method: NSPanel.EventMethod, page: number | undefined, words: string[] | undefined): void {
try {
if (typ == 'event') {
switch (method as NSPanel.EventMethod) {
case 'startup':
@@ -4688,7 +4700,8 @@ function GeneratePage(page: PageType): void {
* @function HandleHardwareButton
* @param {NSPanel.EventMethod} method - The method associated with the hardware button event.
*/
function HandleHardwareButton(method: NSPanel.EventMethod): void { try {
function HandleHardwareButton (method: NSPanel.EventMethod): void {
try {
let buttonConfig: NSPanel.ConfigButtonFunction = config[method];
if (buttonConfig.mode === null) {
return;
@@ -4739,7 +4752,8 @@ function HandleHardwareButton(method: NSPanel.EventMethod): void { try {
*
* @function HandleStartupProcess
*/
function HandleStartupProcess(): void { let timeout:number = 10;
function HandleStartupProcess (): void {
let timeout: number = 10;
SendDate();
SendTime();
if (existsState(NSPanel_Path + 'Config.Screensaver.timeoutScreensaver')) {
@@ -4755,7 +4769,8 @@ function HandleStartupProcess(): void { let timeout:number = 10;
*
* @function SendDate
*/
function SendDate(): void { try {
function SendDate (): void {
try {
if (existsObject(NSPanel_Path + 'Config.locale')) {
let dpWeekday = existsObject(NSPanel_Path + 'Config.Dateformat.weekday') ? getState(NSPanel_Path + 'Config.Dateformat.weekday').val : 'short';
let dpMonth = existsObject(NSPanel_Path + 'Config.Dateformat.month') ? getState(NSPanel_Path + 'Config.Dateformat.month').val : 'short';
@@ -4783,7 +4798,8 @@ function SendDate(): void { try {
*
* @function SendTime
*/
function SendTime(): void { try {
function SendTime (): void {
try {
/*const d = new Date();
const hr = (d.getHours() < 10 ? '0' : '') + d.getHours();
const min = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
@@ -4804,7 +4820,8 @@ function SendTime(): void { try {
* @param {NSPanel.PageEntities} page - The entities page configuration.
* @returns {NSPanel.Payload[]} The payload array for the entities page.
*/
function GenerateEntitiesPage(page: NSPanel.PageEntities): NSPanel.Payload[] { try {
function GenerateEntitiesPage (page: NSPanel.PageEntities): NSPanel.Payload[] {
try {
let out_msgs: NSPanel.Payload[];
out_msgs = [{payload: 'pageType~cardEntities'}];
out_msgs.push({payload: GeneratePageElements(page)});
@@ -4824,7 +4841,8 @@ function GenerateEntitiesPage(page: NSPanel.PageEntities): NSPanel.Payload[] {
* @param {NSPanel.PageGrid} page - The grid page configuration.
* @returns {NSPanel.Payload[]} The payload array for the grid page.
*/
function GenerateGridPage(page: NSPanel.PageGrid): NSPanel.Payload[] { try {
function GenerateGridPage (page: NSPanel.PageGrid): NSPanel.Payload[] {
try {
let out_msgs: NSPanel.Payload[] = [{payload: 'pageType~cardGrid'}];
out_msgs.push({payload: GeneratePageElements(page)});
return out_msgs;
@@ -4843,7 +4861,8 @@ function GenerateGridPage(page: NSPanel.PageGrid): NSPanel.Payload[] { try {
* @param {NSPanel.PageGrid2} page - The secondary grid page configuration.
* @returns {NSPanel.Payload[]} The payload array for the secondary grid page.
*/
function GenerateGridPage2(page: NSPanel.PageGrid2): NSPanel.Payload[] { try {
function GenerateGridPage2 (page: NSPanel.PageGrid2): NSPanel.Payload[] {
try {
let out_msgs: NSPanel.Payload[] = [{payload: 'pageType~cardGrid2'}];
out_msgs.push({payload: GeneratePageElements(page)});
return out_msgs;
@@ -4862,7 +4881,8 @@ function GenerateGridPage2(page: NSPanel.PageGrid2): NSPanel.Payload[] { try
* @param {NSPanel.PageGrid3} page - The secondary grid page configuration.
* @returns {NSPanel.Payload[]} The payload array for the secondary grid page.
*/
function GenerateGridPage3(page: NSPanel.PageGrid3): NSPanel.Payload[] { try {
function GenerateGridPage3 (page: NSPanel.PageGrid3): NSPanel.Payload[] {
try {
let out_msgs: NSPanel.Payload[] = [{payload: 'pageType~cardGrid3'}];
out_msgs.push({payload: GeneratePageElements(page)});
return out_msgs;
@@ -4881,7 +4901,8 @@ function GenerateGridPage3(page: NSPanel.PageGrid3): NSPanel.Payload[] { try
* @param {PageType} page - The page type configuration.
* @returns {string} The string representation of the page elements.
*/
function GeneratePageElements(page: PageType): string { try {
function GeneratePageElements (page: PageType): string {
try {
activePage = page;
let maxItems = 0;
switch (page.type) {
@@ -5070,17 +5091,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
* The same extension can be found below in blind. vval=0 means closed / val=100 means open. If val is in between, icon3 is used.
* Icons in this part can be states and strings. The specifications are based on German shutters.
*/
if (pageItem.icon3 && typeof pageItem.icon3 === 'string'){
let max = pageItem.maxValueLevel ?? 100
let min = pageItem.minValueLevel ?? 0
if (min > max && val >= min || min <= max && val <= min) {
iconId = pageItem.icon && existsState(pageItem.icon) && Icons.GetIcon(getState(pageItem.icon).val) || Icons.GetIcon(pageItem.icon) || Icons.GetIcon('window-shutter')
} else if (min > max && val <= max || min <= max && val >= max) {
iconId = pageItem.icon2 && existsState(pageItem.icon2) && Icons.GetIcon(getState(pageItem.icon2).val) || Icons.GetIcon(pageItem.icon2) || Icons.GetIcon('window-shutter-open')
} else {
iconId = existsState(pageItem.icon3) && Icons.GetIcon(getState(pageItem.icon3).val) || Icons.GetIcon(pageItem.icon3) || Icons.GetIcon('window-shutter-alert')
}
}
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['window-shutter', 'window-shutter-open', 'window-shutter-alert']);
iconColor = existsState(pageItem.id + '.COLORDEC')
? getState(pageItem.id + '.COLORDEC').val
: GetIconColor(pageItem, existsState(pageItem.id + '.ACTUAL') ? getState(pageItem.id + '.ACTUAL').val : true, useColors);
@@ -5184,6 +5195,8 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + '.ACTUAL');
}
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
if (pageItem.colorScale != undefined) {
@@ -5416,17 +5429,8 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('window-open');
iconColor = GetIconColor(pageItem, existsState(pageItem.id + '.ACTUAL') ? getState(pageItem.id + '.ACTUAL').val : true, useColors);
// only if icon3 is set go into 3 icons
if (pageItem.icon3 && typeof pageItem.icon3 === 'string'){
let max = pageItem.maxValueLevel ?? 100
let min = pageItem.minValueLevel ?? 0
if (min > max && val >= min || min <= max && val <= min) {
iconId = pageItem.icon && existsState(pageItem.icon) && Icons.GetIcon(getState(pageItem.icon).val) || Icons.GetIcon(pageItem.icon) || Icons.GetIcon('window-shutter')
} else if (min > max && val <= max || min <= max && val >= max) {
iconId = pageItem.icon2 && existsState(pageItem.icon2) && Icons.GetIcon(getState(pageItem.icon2).val) || Icons.GetIcon(pageItem.icon2) || Icons.GetIcon('window-shutter-open')
} else {
iconId = existsState(pageItem.icon3) && Icons.GetIcon(getState(pageItem.icon3).val) || Icons.GetIcon(pageItem.icon3) || Icons.GetIcon('window-shutter-alert')
}
}
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['window-shutter', 'window-shutter-open', 'window-shutter-alert']);
let min_Level: number = 0;
let max_Level: number = 100;
if (pageItem.minValueLevel !== undefined && pageItem.maxValueLevel !== undefined) {
@@ -5554,6 +5558,10 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + '.ACTUAL');
}
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
}
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
if (pageItem.colorScale != undefined) {
@@ -5813,7 +5821,8 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
* @param {string} controlsState - The controls state identifier.
* @returns {string} The locale string for the specified controls object and state.
*/
function findLocale(controlsObject: string, controlsState: string): string { if ( ! existsState(NSPanel_Path + 'Config.locale')) {
function findLocale (controlsObject: string, controlsState: string): string {
if (!existsState(NSPanel_Path + 'Config.locale')) {
if (Debug) {
log('findLocaleServMenu missing object: ' + NSPanel_Path + 'Config.locale' + ' -> ' + controlsState, 'warn');
}
@@ -5863,7 +5872,8 @@ function findLocale(controlsObject: string, controlsState: string): string {
* @param {string} controlsState - The service menu controls state identifier.
* @returns {string} The locale string for the specified service menu controls state.
*/
function findLocaleServMenu(controlsState: string): string { if ( ! existsState(NSPanel_Path + 'Config.locale')) {
function findLocaleServMenu (controlsState: string): string {
if (!existsState(NSPanel_Path + 'Config.locale')) {
if (Debug) {
log('findLocaleServMenu missing object: ' + NSPanel_Path + 'Config.locale' + ' -> ' + controlsState, 'warn');
}
@@ -5922,7 +5932,8 @@ function findLocaleServMenu(controlsState: string): string { if ( ! existsSta
* @param {boolean} useColors - A flag indicating whether colors should be used.
* @returns {number} The color code for the icon.
*/
function GetIconColor(pageItem: PageItem, value: boolean | number, useColors: boolean): number { try {
function GetIconColor (pageItem: PageItem, value: boolean | number, useColors: boolean): number {
try {
// dimmer
if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof value === 'number') {
let maxValue = pageItem.maxValueBrightness !== undefined ? pageItem.maxValueBrightness : 100;
@@ -5963,7 +5974,8 @@ function GetIconColor(pageItem: PageItem, value: boolean | number, useColors: bo
* @function RegisterEntityWatcher
* @param {string} id - The ID of the entity to watch.
*/
function RegisterEntityWatcher(id: string): void { try {
function RegisterEntityWatcher (id: string): void {
try {
if (subscriptions.hasOwnProperty(id)) {
return;
}
@@ -5996,7 +6008,8 @@ function RegisterEntityWatcher(id: string): void { try {
* @param {NSPanel.PopupType} type - The type of popup to display.
* @param {number | undefined} placeId - The place ID associated with the entity, if applicable.
*/
function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: NSPanel.PopupType, placeId: number | undefined): void { try {
function RegisterDetailEntityWatcher (id: string, pageItem: PageItem, type: NSPanel.PopupType, placeId: number | undefined): void {
try {
if (subscriptions.hasOwnProperty(id)) {
return;
}
@@ -6020,7 +6033,8 @@ function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: NSPan
* @param {string} id - The ID of the entity.
* @returns {string} The unit of measurement for the entity.
*/
function GetUnitOfMeasurement(id: string): string { try {
function GetUnitOfMeasurement (id: string): string {
try {
if (!existsObject(id)) return '';
let obj = getObject(id);
@@ -6047,7 +6061,8 @@ function GetUnitOfMeasurement(id: string): string { try {
* @param {NSPanel.PageThermo} page - The thermostat page configuration.
* @returns {NSPanel.Payload[]} The payload array for the thermostat page.
*/
function GenerateThermoPage(page: NSPanel.PageThermo): NSPanel.Payload[] { try {
function GenerateThermoPage (page: NSPanel.PageThermo): NSPanel.Payload[] {
try {
UnsubscribeWatcher();
let id = page.items[0].id;
let out_msgs: NSPanel.Payload[] = [];
@@ -6518,7 +6533,8 @@ function GenerateThermoPage(page: NSPanel.PageThermo): NSPanel.Payload[] { tr
*
* @function unsubscribeMediaSubscriptions
*/
function unsubscribeMediaSubscriptions(): void { for (let i = 0; i < config.pages.length; i++) {
function unsubscribeMediaSubscriptions (): void {
for (let i = 0; i < config.pages.length; i++) {
const page: NSPanel.PageType = config.pages[i];
if (isPageMedia(page)) {
let mediaID = page.items[0].id;
@@ -6561,7 +6577,8 @@ function unsubscribeMediaSubscriptions(): void { for (let i = 0; i < config.p
* @function subscribeMediaSubscriptions
* @param {string} id - The ID of the media entity to subscribe to.
*/
function subscribeMediaSubscriptions(id: string): void { on(
function subscribeMediaSubscriptions (id: string): void {
on(
{id: [id + '.STATE', id + '.ARTIST', id + '.TITLE', id + '.ALBUM', id + '.VOLUME', id + '.REPEAT', id + '.SHUFFLE', id + '.DURATION', id + '.ELAPSED'], change: 'any', ack: true},
async function () {
if (useMediaEvents && pageCounter == 1) {
@@ -6579,7 +6596,8 @@ function subscribeMediaSubscriptions(id: string): void { on(
* @function subscribeMediaSubscriptionsSonosAdd
* @param {string} id - The ID of the Sonos media entity to subscribe to.
*/
function subscribeMediaSubscriptionsSonosAdd(id: string): void { on({ id: [id + '.QUEUE'], change: 'any', ack: true }, async function () {
function subscribeMediaSubscriptionsSonosAdd (id: string): void {
on({id: [id + '.QUEUE'], change: 'any', ack: true}, async function () {
if (useMediaEvents && pageCounter == 1) {
GeneratePage(activePage!);
}
@@ -6893,7 +6911,8 @@ async function createAutoMediaAlias(id: string, mediaDevice: string, adapterPlay
* @param {NSPanel.PageMedia} page - The media page configuration.
* @returns {NSPanel.Payload[]} The payload array for the media page.
*/
function GenerateMediaPage(page: NSPanel.PageMedia): NSPanel.Payload[] { try {
function GenerateMediaPage (page: NSPanel.PageMedia): NSPanel.Payload[] {
try {
unsubscribeMediaSubscriptions();
if (!page.items[0].id) throw new Error('Missing page id for cardMedia!');
@@ -7535,7 +7554,8 @@ function GenerateMediaPage(page: NSPanel.PageMedia): NSPanel.Payload[] { try
* @returns {Promise<void>} A promise that resolves when the alias has been created.
* @throws {Error} If an error occurs during the alias creation.
*/
async function createAutoAlarmAlias(id: string, nsPath: string) { try {
async function createAutoAlarmAlias (id: string, nsPath: string) {
try {
if (Debug) {
log('Alarm Alias Path: ' + id, 'info');
log('Alarm 0_userdata Path: ' + nsPath, 'info');
@@ -7577,7 +7597,8 @@ async function createAutoAlarmAlias(id: string, nsPath: string) { try {
* @param {NSPanel.PageAlarm} page - The alarm page configuration.
* @returns {NSPanel.Payload[]} The payload array for the alarm page.
*/
function GenerateAlarmPage(page: NSPanel.PageAlarm): NSPanel.Payload[] { try {
function GenerateAlarmPage (page: NSPanel.PageAlarm): NSPanel.Payload[] {
try {
activePage = page;
let id = page.items[0].id;
@@ -7742,7 +7763,8 @@ function GenerateAlarmPage(page: NSPanel.PageAlarm): NSPanel.Payload[] { try
* @returns {Promise<void>} A promise that resolves when the alias has been created.
* @throws {Error} If an error occurs during the alias creation.
*/
async function createAutoUnlockAlias(id: string, dpPath: string) { try {
async function createAutoUnlockAlias (id: string, dpPath: string) {
try {
if (Debug) {
log('Unlock Alias Path: ' + id, 'info');
log('Unlock 0_userdata Path: ' + dpPath, 'info');
@@ -7772,7 +7794,8 @@ async function createAutoUnlockAlias(id: string, dpPath: string) { try {
* @param {NSPanel.PageUnlock} page - The unlock page configuration.
* @returns {NSPanel.Payload[]} The payload array for the unlock page.
*/
function GenerateUnlockPage(page: NSPanel.PageUnlock): NSPanel.Payload[] { try {
function GenerateUnlockPage (page: NSPanel.PageUnlock): NSPanel.Payload[] {
try {
activePage = page;
let id = page.items[0].id;
let name = page.heading;
@@ -7850,7 +7873,8 @@ function GenerateUnlockPage(page: NSPanel.PageUnlock): NSPanel.Payload[] { tr
* @returns {Promise<void>} A promise that resolves when the alias has been created.
* @throws {Error} If an error occurs during the alias creation.
*/
async function createAutoQRAlias(id: string, dpPath: string) { try {
async function createAutoQRAlias (id: string, dpPath: string) {
try {
if (Debug) {
log('QRPage Alias Path: ' + id, 'info');
log('QRPage 0_userdata Path: ' + dpPath, 'info');
@@ -7881,7 +7905,8 @@ async function createAutoQRAlias(id: string, dpPath: string) { try {
* @param {NSPanel.PageQR} page - The QR page configuration.
* @returns {NSPanel.Payload[]} The payload array for the QR page.
*/
function GenerateQRPage(page: NSPanel.PageQR): NSPanel.Payload[] { try {
function GenerateQRPage (page: NSPanel.PageQR): NSPanel.Payload[] {
try {
activePage = page;
if (!page.items[0].id) throw new Error('Missing pageItem.id for cardQRPage!');
let id = page.items[0].id;
@@ -7997,7 +8022,8 @@ function GenerateQRPage(page: NSPanel.PageQR): NSPanel.Payload[] { try {
*
* @function unsubscribePowerSubscriptions
*/
function unsubscribePowerSubscriptions(): void { for (let i = 0; i < config.pages.length; i++) {
function unsubscribePowerSubscriptions (): void {
for (let i = 0; i < config.pages.length; i++) {
const page: NSPanel.PageType = config.pages[i];
if (isPagePower(page)) {
let powerID = page.items[0].id;
@@ -8276,7 +8302,8 @@ function GenerateChartPage(page: NSPanel.PageChart): NSPanel.Payload[] {
* @param {boolean} [ack=false] - The acknowledgment flag (optional).
* @returns {boolean} True if the state exists and the value was set, false otherwise.
*/
function setIfExists(id: string, value: any, type: string | null = null, ack: boolean = false): boolean { try {
function setIfExists (id: string, value: any, type: string | null = null, ack: boolean = false): boolean {
try {
if (type === null) {
if (existsState(id)) {
setState(id, value, ack);
@@ -8304,7 +8331,8 @@ function setIfExists(id: string, value: any, type: string | null = null, ack: bo
* @param {string} id - The ID of the entity to toggle.
* @returns {boolean} True if the state was successfully toggled, false otherwise.
*/
function toggleState(id: string): boolean { try {
function toggleState (id: string): boolean {
try {
const obj = getObject(id);
if (existsState(id) && obj.common.type !== undefined && obj.common.type === 'boolean') {
setIfExists(id, !getState(id).val);
@@ -8326,7 +8354,8 @@ function toggleState(id: string): boolean { try {
* @param {string} id - The ID of the entity to trigger.
* @returns {boolean} True if the button action was successfully triggered, false otherwise.
*/
function triggerButton(id: string): boolean { try {
function triggerButton (id: string): boolean {
try {
let obj = getObject(id);
if (existsState(id) && obj.common.type !== undefined && obj.common.type === 'boolean') {
setState(id, true);
@@ -8350,7 +8379,8 @@ function triggerButton(id: string): boolean { try {
* @function HandleButtonEvent
* @param {any} words - The words or parameters associated with the button event.
*/
function HandleButtonEvent(words: any): void { try {
function HandleButtonEvent (words: any): void {
try {
// Turn off the display if the alwaysOnDisplay parameter was specified
if (alwaysOn == true) {
unsubscribePowerSubscriptions();
@@ -9537,7 +9567,8 @@ function HandleButtonEvent(words: any): void { try {
* @param {Partial<iobJS.StateCommon>} [common={}] - The common properties for the state (optional).
* @param {iobJS.SetStateCallback} [callback] - The callback function to execute after setting or creating the state (optional).
*/
function setOrCreate(id: string, value: any, forceCreation: boolean = true, common: Partial<iobJS.StateCommon> = {}, callback?: iobJS.SetStateCallback) { if (!existsState(id)) {
function setOrCreate (id: string, value: any, forceCreation: boolean = true, common: Partial<iobJS.StateCommon> = {}, callback?: iobJS.SetStateCallback) {
if (!existsState(id)) {
extendObject(id.split('.').slice(0, -2).join('.'), {type: 'channel', common: {name: 'channel'}, native: {}});
extendObject(id.split('.').slice(0, -1).join('.'), {type: 'channel', common: {name: 'channel'}, native: {}});
createState(id, value, forceCreation, common, callback);
@@ -9653,7 +9684,8 @@ function getNavigationString(pageId: number): string {
* @param {number | undefined} placeId - The place ID associated with the detail page, if applicable.
* @returns {NSPanel.Payload[]} The payload array for the detail page.
*/
function GenerateDetailPage(type: NSPanel.PopupType, optional: NSPanel.mediaOptional | undefined, pageItem: PageItem, placeId: number | undefined): NSPanel.Payload[] { if (Debug) log('GenerateDetailPage Übergabe Type: ' + type + ' - optional: ' + optional + ' - pageItem.id: ' + pageItem.id, 'info');
function GenerateDetailPage (type: NSPanel.PopupType, optional: NSPanel.mediaOptional | undefined, pageItem: PageItem, placeId: number | undefined): NSPanel.Payload[] {
if (Debug) log('GenerateDetailPage Übergabe Type: ' + type + ' - optional: ' + optional + ' - pageItem.id: ' + pageItem.id, 'info');
try {
let out_msgs: NSPanel.Payload[] = [];
let id = pageItem.id;
@@ -10814,7 +10846,8 @@ function GenerateDetailPage(type: NSPanel.PopupType, optional: NSPanel.mediaOpti
* @param {number} outMax - The maximum value of the output range.
* @returns {number} The scaled number.
*/
function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number { try {
function scale (number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
try {
return outMax + outMin - (((number - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin);
} catch (err: any) {
log('error at function scale: ' + err.message, 'warn');
@@ -10829,7 +10862,8 @@ function scale(number: number, inMin: number, inMax: number, outMin: number, out
*
* @function UnsubscribeWatcher
*/
function UnsubscribeWatcher(): void { try {
function UnsubscribeWatcher (): void {
try {
for (const [key, value] of Object.entries(subscriptions)) {
unsubscribe(value);
delete subscriptions[key];
@@ -10846,7 +10880,8 @@ function UnsubscribeWatcher(): void { try {
*
* @function HandleScreensaver
*/
function HandleScreensaver(): void { setIfExists(NSPanel_Path + 'ActivePage.type', 'screensaver', null, true);
function HandleScreensaver (): void {
setIfExists(NSPanel_Path + 'ActivePage.type', 'screensaver', null, true);
setIfExists(NSPanel_Path + 'ActivePage.id0', 'screensaver', null, true);
setIfExists(NSPanel_Path + 'ActivePage.heading', 'Screensaver', null, true);
if (existsObject(`${NSPanel_Path}${ScreensaverAdvancedEndPath}`) && getState(`${NSPanel_Path}${ScreensaverAdvancedEndPath}`).val) {
@@ -11140,8 +11175,9 @@ function HandleScreensaverUpdate(): void {
}
if (typeof val == 'number') {
val =
(val * (config.bottomScreensaverEntity[i].ScreensaverEntityFactor ? config.bottomScreensaverEntity[i].ScreensaverEntityFactor! : 0)).toFixed(
val = val * (config.bottomScreensaverEntity[i].ScreensaverEntityFactor ? config.bottomScreensaverEntity[i].ScreensaverEntityFactor! : 0)
icon = determineScreensaverStatusIcon(config.bottomScreensaverEntity[i],val,icon)
val = val.toFixed(
config.bottomScreensaverEntity[i].ScreensaverEntityDecimalPlaces
) + config.bottomScreensaverEntity[i].ScreensaverEntityUnitText;
iconColor = GetScreenSaverEntityColor(config.bottomScreensaverEntity[i]);
@@ -11249,7 +11285,8 @@ function HandleScreensaverUpdate(): void {
* @function RegisterScreensaverEntityWatcher
* @param {string} id - The ID of the screensaver entity to watch.
*/
function RegisterScreensaverEntityWatcher(id: string): void { try {
function RegisterScreensaverEntityWatcher (id: string): void {
try {
if (subscriptions.hasOwnProperty(id)) {
return;
}
@@ -11269,7 +11306,8 @@ function RegisterScreensaverEntityWatcher(id: string): void { try {
*
* @function HandleScreensaverStatusIcons
*/
function HandleScreensaverStatusIcons(): void { try {
function HandleScreensaverStatusIcons (): void {
try {
let payloadString = '';
const iconData: Record<'mrIcon1' | 'mrIcon2', NSPanel.ScreenSaverMRDataElement> = {
mrIcon1: {
@@ -11420,7 +11458,8 @@ function HandleScreensaverStatusIcons(): void { try {
* @param {string} valueScaletemp - The temperature value to convert.
* @returns {number} The corresponding color scale value.
*/
function HandleColorScale(valueScaletemp: string): number { switch (valueScaletemp) {
function HandleColorScale (valueScaletemp: string): number {
switch (valueScaletemp) {
case '0':
return rgb_dec565(colorScale0);
case '1':
@@ -11455,7 +11494,8 @@ function HandleColorScale(valueScaletemp: string): number { switch (valueScal
*
* @function HandleScreensaverColors
*/
function HandleScreensaverColors(): void { try {
function HandleScreensaverColors (): void {
try {
let vwIcon: number[] = [];
if (getState(NSPanel_Path + 'Config.Screensaver.autoWeatherColorScreensaverLayout').val) {
vwIcon[0] = vwIconColor[0];
@@ -11530,7 +11570,8 @@ function HandleScreensaverColors(): void { try {
* @param {NSPanel.ScreenSaverElement | null} configElement - The configuration element for the screensaver entity.
* @returns {number} The color code for the screensaver entity.
*/
function GetScreenSaverEntityColor(configElement: NSPanel.ScreenSaverElement | null): number { try {
function GetScreenSaverEntityColor (configElement: NSPanel.ScreenSaverElement | null): number {
try {
let colorReturn: number;
if (configElement && configElement.ScreensaverEntityIconColor != undefined) {
const ScreensaverEntityIconColor = configElement.ScreensaverEntityIconColor as NSPanel.IconScaleElement;
@@ -11606,7 +11647,8 @@ function GetScreenSaverEntityColor(configElement: NSPanel.ScreenSaverElement | n
* @param {number} icon - The AccuWeather icon number.
* @returns {string} The corresponding icon string.
*/
function GetAccuWeatherIcon(icon: number): string { try {
function GetAccuWeatherIcon (icon: number): string {
try {
switch (icon) {
case 30: // Hot
return 'weather-sunny-alert'; // exceptional
@@ -11696,7 +11738,8 @@ function GetAccuWeatherIcon(icon: number): string { try {
* @param {number} icon - The AccuWeather icon number.
* @returns {number} The corresponding color code.
*/
function GetAccuWeatherIconColor(icon: number): number { try {
function GetAccuWeatherIconColor (icon: number): number {
try {
switch (icon) {
case 24: // Ice
case 30: // Hot
@@ -11784,7 +11827,8 @@ function GetAccuWeatherIconColor(icon: number): number { try {
* @param {number} icon - The DasWetter icon number.
* @returns {string} The corresponding icon string.
*/
function GetDasWetterIcon(icon: number): string { try {
function GetDasWetterIcon (icon: number): string {
try {
switch (icon) {
case 1: // Sonnig
return 'weather-sunny'; // sunny
@@ -11852,7 +11896,8 @@ function GetDasWetterIcon(icon: number): string { try {
* @param {number} icon - The DasWetter icon number.
* @returns {number} The corresponding color code.
*/
function GetDasWetterIconColor(icon: number): number { try {
function GetDasWetterIconColor (icon: number): number {
try {
switch (icon) {
case 1: // Sonnig
return rgb_dec565(swSunny);
@@ -11923,7 +11968,8 @@ function GetDasWetterIconColor(icon: number): number { try {
* @param {Object} obj - The object containing the state change information.
* @throws {Error} If an error occurs during the state change handling.
*/
on({ id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESULT'.length) + 'SENSOR' }, async (obj) => { try {
on({id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESULT'.length) + 'SENSOR'}, async (obj) => {
try {
const Tasmota_Sensor = JSON.parse(obj.state.val);
await createStateAsync(NSPanel_Path + 'Sensor.Time', <iobJS.StateCommon> {type: 'string', write: false});
@@ -11967,7 +12013,8 @@ on({ id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESU
* @param {string} Text - The input text to format.
* @returns {string} The formatted text.
*/
function formatInSelText(Text: string): string { let splitText = Text.split(' ');
function formatInSelText (Text: string): string {
let splitText = Text.split(' ');
let lengthLineOne = 0;
let arrayLineOne: string[] = [];
for (let i = 0; i < splitText.length; i++) {
@@ -12003,7 +12050,8 @@ function formatInSelText(Text: string): string { let splitText = Text.split('
* @param {number} percentage - The percentage to determine the blended color.
* @returns {RGB} The blended color as an RGB object.
*/
function GetBlendedColor(percentage: number): RGB { if (percentage < 50) {
function GetBlendedColor (percentage: number): RGB {
if (percentage < 50) {
return Interpolate(config.defaultOffColor, config.defaultOnColor, percentage / 50.0);
}
@@ -12021,7 +12069,8 @@ function GetBlendedColor(percentage: number): RGB { if (percentage < 50) {
* @param {number} fraction - The fraction to determine the interpolation (0.0 to 1.0).
* @returns {RGB} The interpolated RGB color.
*/
function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { let r: number = InterpolateNum(color1.red, color2.red, fraction);
function Interpolate (color1: RGB, color2: RGB, fraction: number): RGB {
let r: number = InterpolateNum(color1.red, color2.red, fraction);
let g: number = InterpolateNum(color1.green, color2.green, fraction);
let b: number = InterpolateNum(color1.blue, color2.blue, fraction);
return {red: Math.round(r), green: Math.round(g), blue: Math.round(b)};
@@ -12038,7 +12087,8 @@ function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { let r
* @param {number} fraction - The fraction to determine the interpolation (0.0 to 1.0).
* @returns {number} The interpolated value.
*/
function InterpolateNum(d1: number, d2: number, fraction: number): number { return d1 + (d2 - d1) * fraction;
function InterpolateNum (d1: number, d2: number, fraction: number): number {
return d1 + (d2 - d1) * fraction;
}
/**
@@ -12072,7 +12122,8 @@ function rad2deg(rad): number {
* @param {number} color - The color value to convert.
* @returns {string} The hexadecimal string representation of the color.
*/
function ColorToHex(color): string { let hexadecimal: string = color.toString(16);
function ColorToHex (color): string {
let hexadecimal: string = color.toString(16);
return hexadecimal.length == 1 ? '0' + hexadecimal : hexadecimal;
}
@@ -12087,7 +12138,8 @@ function ColorToHex(color): string { let hexadecimal: string = color.toString
* @param {number} blue - The blue color value.
* @returns {string} The hexadecimal string representation of the RGB color.
*/
function ConvertRGBtoHex(red: number, green: number, blue: number): string { return '#' + ColorToHex(red) + ColorToHex(green) + ColorToHex(blue);
function ConvertRGBtoHex (red: number, green: number, blue: number): string {
return '#' + ColorToHex(red) + ColorToHex(green) + ColorToHex(blue);
}
/**
@@ -12117,7 +12169,8 @@ function hsv2rgb(hue: number, saturation: number, value: number): [number, numbe
* @param {number} blue - The blue color value.
* @returns {number} The hue value.
*/
function getHue(red: number, green: number, blue: number): number { let min = Math.min(Math.min(red, green), blue);
function getHue (red: number, green: number, blue: number): number {
let min = Math.min(Math.min(red, green), blue);
let max = Math.max(Math.max(red, green), blue);
if (min == max) {
@@ -12200,6 +12253,102 @@ function rgb_to_cie(red: number, green: number, blue: number): string {
return cie;
}
/**
* Determines the icon ID for a given page item based on the provided value thresholds.
* If the icon3 property is missing or invalid, it immediately returns the fallback icon ID.
* Otherwise, it delegates to determineStatusIcon, passing the relevant parameters.
*
* @param {PageItem} pageItem - Contains icon references (icon, icon2, icon3) and threshold values.
* @param {number} val - The current value used to evaluate thresholds.
* @param {string} iconId - The fallback icon ID if no matching icon is found.
* @param {[string, string, string]} [def] - Optional array of default icons corresponding to threshold levels.
* @returns {string} The icon ID determined by value, thresholds, and defaults.
*/
function determinePageItemStatusIcon (pageItem: PageItem, val: number, iconId: string, def?: [string, string, string]): string {
if (!pageItem.icon3 || typeof pageItem.icon3 !== 'string') {
return iconId;
}
const max = pageItem.maxValueLevel ?? pageItem.maxValue ?? 100;
const min = pageItem.minValueLevel ?? pageItem.minValue ?? 0;
return determineStatusIcon(pageItem.icon, pageItem.icon2, pageItem.icon3, val, min, max, iconId, def);
}
/**
* Determines an icon for the screensaver based on the provided value and icon configuration.
*
* @param {NSPanel.ScreenSaverElement} ss - Object containing the ScreensaverEntityIconSelect array.
* @param {number} val - The current value used to determine which icon to select.
* @param {string} iconId - A fallback icon ID if no suitable icon can be retrieved.
* @returns {string} The icon ID that matches the value thresholds, or the fallback icon ID.
*/
function determineScreensaverStatusIcon(ss: NSPanel.ScreenSaverElement, val: number, iconId: string): string {
if (!ss) {
return iconId;
}
if (!ss.ScreensaverEntityIconSelect || !Array.isArray(ss.ScreensaverEntityIconSelect)) {
return iconId;
}
ss.ScreensaverEntityIconSelect = ss.ScreensaverEntityIconSelect.filter((item) => item);
ss.ScreensaverEntityIconSelect = ss.ScreensaverEntityIconSelect.sort((a, b) => a.value - b.value);
for (const item of ss.ScreensaverEntityIconSelect) {
if (val <= item.value) {
return Icons.GetIcon(item.icon) || iconId;
}
}
return Icons.GetIcon(ss.ScreensaverEntityIconSelect[ss.ScreensaverEntityIconSelect.length - 1].icon) || iconId;
}
/**
* Determines which icon to use based on the given value range (min and max) and available icon references.
*
* @param {string | undefined} icon1 - The icon reference for the lower threshold condition.
* @param {string | undefined} icon2 - The icon reference for the higher threshold condition.
* @param {string | undefined} icon3 - The icon reference for the midrange condition.
* @param {number} val - The current value to evaluate.
* @param {number | undefined} min - The minimum threshold.
* @param {number | undefined} max - The maximum threshold.
* @param {string} iconId - The fallback icon identifier.
* @param {[string, string, string]} [def] - Optional array of default icons for each threshold level.
*
* @returns {string} The icon identifier determined by the value, thresholds, and defaults.
*/
function determineStatusIcon (
icon1: string|undefined,
icon2: string|undefined,
icon3: string|undefined,
val: number,
min: number|undefined,
max: number|undefined,
iconId: string,
def?: [string, string, string]
): string {
if (!icon3 && typeof icon3 !== 'string') {
return iconId;
}
if (min === undefined || max === undefined) {
return iconId;
}
function pickIcon(iconKey?: string, defIndex?: number): string {
return (
(iconKey && existsState(iconKey) && Icons.GetIcon(getState(iconKey).val)) ||
Icons.GetIcon(iconKey) ||
(def && defIndex !== undefined ? Icons.GetIcon(def[defIndex]) : undefined) ||
iconId
);
}
if ((min > max && val >= min) || (min <= max && val <= min)) {
iconId = pickIcon(icon1, 0);
} else if ((min > max && val <= max) || (min <= max && val >= max)) {
iconId = pickIcon(icon2, 1);
} else {
// The original code used the entire def array for icon3; here we assume the third index
iconId = pickIcon(icon3, 2);
}
return iconId;
}
/**
* Retrieves the Spotify device ID for a given device name.
@@ -12796,6 +12945,23 @@ namespace NSPanel {
ScreensaverEntityOnText?: string | null;
ScreensaverEntityOffText?: string | null;
ScreensaverEntityNaviToPage?: PageType;
/**
* To show different icons for different values in the screensaver
*
* Value is the threshold for the icon. Lower values are first.
* Example:
* [
{icon: 'sun-thermometer', value:40},
{icon: 'sun-thermometer-outline', value: 35},
{icon: 'thermometer-high', value: 30},
{icon: 'thermometer', value: 25},
{icon: 'thermometer-low', value: 15},
{icon: 'thermometer-minus', value: 3},
{icon: 'snowflake-thermometer', value: -3},
{icon: 'snowflake', value: 10},
]
*/
ScreensaverEntityIconSelect?: {icon:string, value: number}[] | null;
};
export type ScreenSaverMRElement = {