diff --git a/ioBroker/DEV/NSPanelTs.ts b/ioBroker/DEV/NSPanelTs.ts index 2e749a6c..b097e961 100644 --- a/ioBroker/DEV/NSPanelTs.ts +++ b/ioBroker/DEV/NSPanelTs.ts @@ -103,9 +103,10 @@ ReleaseNotes: - 16.01.2024 - v4.3.3.38 Optimate: function SendTime() - 17.01.2024 - v4.3.3.38 Add: ScreensaverEntityIconSelect for MRIcons is like common.states for states. - 17.01.2024 - v4.3.3.38 Add: Changing the ScreensaverEntityValue value updates the screensaver. - - 19.01.2024 - v4.3.3.38 Change: yAxisTicks parameter is not required in cardLChart PageItem + - 19.01.2024 - v4.3.3.38 Change: yAxisTicks parameter is not required in cardLChart PageItem - 20.01.2024 - v4.3.3.38 Add: click on indicatorIcon navigate to Page - 23.01.2024 - v4.3.3.39 Add: Optional setOn & setOff for HW button with mode 'set' + - 28.01.2024 - v4.3.3.39 Fix: ack for read-only state Todo: @@ -6321,7 +6322,7 @@ function HandleButtonEvent(words: any): void { alwaysOn = false; SendToPanel({ payload: 'timeout~' + getState(NSPanel_Path + 'Config.Screensaver.timeoutScreensaver').val }); } - + setOrCreate(NSPanel_Path + "Event.Button.Action", buttonAction ?? words[2], false, {name: 'Incoming button acion', type: 'string', role: 'text', write: false, read: true}); setOrCreate(NSPanel_Path + "Event.Button.Value", words[4] != undefined ? words[4] : '', false, {name: 'Incoming button value', type: 'string', role: 'text', write: false, read: true}); setOrCreate(NSPanel_Path + "Event.Button.Id", id, false, {name: 'Incoming button id', type: 'string', role: 'text', write: false, read: true}); diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 819fe057..b097e961 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------- -TypeScript v4.3.3.38 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar / @TT-Tom / @ticaki / @Britzelpuf / @Sternmiere / @ravenS0ne +TypeScript v4.3.3.39 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar / @TT-Tom / @ticaki / @Britzelpuf / @Sternmiere / @ravenS0ne - abgestimmt auf TFT 53 / v4.3.3 / BerryDriver 9 / Tasmota 13.3.0 @joBr99 Projekt: https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker NsPanelTs.ts (dieses TypeScript in ioBroker) Stable: https://github.com/joBr99/nspanel-lovelace-ui/blob/main/ioBroker/NsPanelTs.ts @@ -103,8 +103,11 @@ ReleaseNotes: - 16.01.2024 - v4.3.3.38 Optimate: function SendTime() - 17.01.2024 - v4.3.3.38 Add: ScreensaverEntityIconSelect for MRIcons is like common.states for states. - 17.01.2024 - v4.3.3.38 Add: Changing the ScreensaverEntityValue value updates the screensaver. - - 19.01.2024 - v4.3.3.38 Change: yAxisTicks parameter is not required in cardLChart PageItem + - 19.01.2024 - v4.3.3.38 Change: yAxisTicks parameter is not required in cardLChart PageItem - 20.01.2024 - v4.3.3.38 Add: click on indicatorIcon navigate to Page + - 23.01.2024 - v4.3.3.39 Add: Optional setOn & setOff for HW button with mode 'set' + - 28.01.2024 - v4.3.3.39 Fix: ack for read-only state + Todo: - XX.XX.XXXX - v5.0.0 Change the bottomScreensaverEntity (rolling) if more than 6 entries are defined @@ -971,7 +974,7 @@ export const config: Config = { // _________________________________ DE: Ab hier keine Konfiguration mehr _____________________________________ // _________________________________ EN: No more configuration from here _____________________________________ -const scriptVersion: string = 'v4.3.3.38'; +const scriptVersion: string = 'v4.3.3.39'; const tft_version: string = 'v4.3.3'; const desired_display_firmware_version = 53; const berry_driver_version = 9; @@ -985,6 +988,8 @@ let weatherForecast: boolean; let pageCounter: number = 0; let alwaysOn: boolean = false; +let buttonToggleState: {[key: string]: boolean} = {}; + const axios = require('axios'); const dayjs = require('dayjs'); const moment = require('moment'); @@ -3165,9 +3170,9 @@ function findPageItem(searching: String): PageItem { function GeneratePage(page: PageType): void { try { activePage = page; - setIfExists(NSPanel_Path + 'ActivePage.type', activePage.type); - setIfExists(NSPanel_Path + 'ActivePage.heading', activePage.heading); - setIfExists(NSPanel_Path + 'ActivePage.id0', activePage.items[0] !== undefined ? activePage.items[0].id : ''); + setIfExists(NSPanel_Path + 'ActivePage.type', activePage.type, null, true); + setIfExists(NSPanel_Path + 'ActivePage.heading', activePage.heading, null, true); + setIfExists(NSPanel_Path + 'ActivePage.id0', activePage.items[0] !== undefined ? activePage.items[0].id : '', null, true); switch (page.type) { case 'cardEntities': SendToPanel(GenerateEntitiesPage(page)); @@ -3241,7 +3246,13 @@ function HandleHardwareButton(method: NSPanel.EventMethod): void { break; case 'set': if (Debug) log('HandleHardwareButton -> Mode Set', 'info'); - if (buttonConfig.entity) { + if (buttonConfig.setOn && existsState(buttonConfig.setOn.dp) && !buttonToggleState[method]) { + setState(buttonConfig.setOn.dp, buttonConfig.setOn.val); + buttonToggleState[method] = true; + } else if (buttonConfig.setOff && existsState(buttonConfig.setOff.dp) && buttonToggleState[method]) { + setState(buttonConfig.setOff.dp, buttonConfig.setOff.val); + buttonToggleState[method] = false; + } else if (buttonConfig.entity && existsState(buttonConfig.entity)) { setState(buttonConfig.entity, buttonConfig.setValue); } screensaverEnabled = true; @@ -6178,7 +6189,7 @@ function GenerateChartPage(page: NSPanel.PageChart): NSPanel.Payload[] { let yAxisTicks : number[] = []; if (!page.items[0].yAxisTicks) { - const sorted = [...txt.matchAll(timeValueRegEx)].map(x => Number(x[1])).sort((x, y) => x < y ? -1 : 1); + const sorted = [...String(txt).matchAll(timeValueRegEx)].map(x => Number(x[1])).sort((x, y) => x < y ? -1 : 1); if (sorted.length === 0) { throw new Error (`Page item ${id} yAxisTicks is undefined and unable to be calculated!`) } @@ -6223,17 +6234,17 @@ function GenerateChartPage(page: NSPanel.PageChart): NSPanel.Payload[] { } } -function setIfExists(id: string, value: any, type: string | null = null): boolean { +function setIfExists(id: string, value: any, type: string | null = null, ack: boolean = false): boolean { try { if (type === null) { if (existsState(id)) { - setState(id, value); + setState(id, value, ack); return true; } } else { const obj = getObject(id); if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) { - setState(id, value); + setState(id, value, ack); return true; } } @@ -6312,6 +6323,10 @@ function HandleButtonEvent(words: any): void { SendToPanel({ payload: 'timeout~' + getState(NSPanel_Path + 'Config.Screensaver.timeoutScreensaver').val }); } + setOrCreate(NSPanel_Path + "Event.Button.Action", buttonAction ?? words[2], false, {name: 'Incoming button acion', type: 'string', role: 'text', write: false, read: true}); + setOrCreate(NSPanel_Path + "Event.Button.Value", words[4] != undefined ? words[4] : '', false, {name: 'Incoming button value', type: 'string', role: 'text', write: false, read: true}); + setOrCreate(NSPanel_Path + "Event.Button.Id", id, false, {name: 'Incoming button id', type: 'string', role: 'text', write: false, read: true}); + if (Debug) { log('HandleButtonEvent buttonAction: ' + buttonAction, 'info'); } @@ -7358,6 +7373,16 @@ function HandleButtonEvent(words: any): void { } } +function setOrCreate(id : string, value : any, forceCreation: boolean = true, common: Partial = { }, 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); + } else { + setState(id, value, true); + } +} + //Determination of page navigation (CustomSend-Payload) function GetNavigationString(pageId: number): string { try { @@ -8475,9 +8500,9 @@ function UnsubscribeWatcher(): void { } function HandleScreensaver(): void { - setIfExists(NSPanel_Path + 'ActivePage.type', 'screensaver'); - setIfExists(NSPanel_Path + 'ActivePage.id0', 'screensaver'); - setIfExists(NSPanel_Path + 'ActivePage.heading', 'Screensaver'); + 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 + 'Config.Screensaver.ScreensaverAdvanced')) { if (getState(NSPanel_Path + 'Config.Screensaver.ScreensaverAdvanced').val) { SendToPanel({ payload: 'pageType~screensaver2' }); @@ -9036,7 +9061,7 @@ function HandleScreensaverStatusIcons() : void { } else { payloadString += '~'; } - + // statusUpdate~icon1~icon1Color~icon1font~icon2~icon2color~icon2font~icon2font SendToPanel({ payload: 'statusUpdate~' + payloadString }); } catch (err: any) { @@ -9890,6 +9915,7 @@ namespace NSPanel { export type PageBaseType = { type: PagetypeType, + uniqueName?: string, heading: string, items: PageItem[], useColor: boolean, @@ -10000,6 +10026,8 @@ namespace NSPanel { // mean string start with getState(' and end with ').val type getStateID = string; export type PageBaseItem = { + uniqueName?: string, + role?: string, id?: string | null, icon?: string, icon2?: string, @@ -10057,6 +10085,8 @@ namespace NSPanel { page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PageGrid2 | PagePower | PageChart | PageUnlock | null), entity: string | null, setValue: string | number | boolean | null + setOn?: {dp:string, val:iobJS.StateValue} + setOff?: {dp:string, val:iobJS.StateValue}; } export type Config = {