From d029ec2158bd854f8cd4ec478807a92d3182a5aa Mon Sep 17 00:00:00 2001 From: Armilar <102996011+Armilar@users.noreply.github.com> Date: Tue, 25 Oct 2022 21:39:48 +0200 Subject: [PATCH 01/15] v3.5.0 - Upgrade - Add Backgroundcolor to Pages - Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - Add PageNavigation via Datapoint - Add New Parameters to popUpNotify / Layout 2 --- ioBroker/NsPanelTs.ts | 603 +++++++++++++++++++++++++++++------------- 1 file changed, 414 insertions(+), 189 deletions(-) diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 9b81d5d6..085dd438 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -1,6 +1,6 @@ /*----------------------------------------------------------------------- -TypeScript v3.4.0.6 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf -- abgestimmt auf TFT 42 / v3.4.0 / BerryDriver 4 / Tasmota 12.1.1 +TypeScript v3.5.0 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf +- abgestimmt auf TFT 43 / v3.5.0 / BerryDriver 4 / Tasmota 12.2.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 @@ -10,6 +10,11 @@ ioBroker-Unterstützung: https://forum.iobroker.net/topic/50888/sonoff-nspanel WIKI zu diesem Projekt unter: https://github.com/joBr99/nspanel-lovelace-ui/wiki (siehe Sidebar) Icons unter: https://htmlpreview.github.io/?https://github.com/jobr99/Generate-HASP-Fonts/blob/master/cheatsheet.html +******************************************************************************* +Achtung Änderung des Sonoff ESP-Temperatursensors +!!! Bitte "SetOption146 1" in der Tasmota-Console ausführen !!! +******************************************************************************* + ReleaseNotes: Bugfixes und Erweiterungen: - cardQR (für Gäste WLAN) @@ -51,6 +56,10 @@ ReleaseNotes: - 03.10.2022 - v3.4.0.6 Add cardPower (experimental) - 05.10.2022 - v3.4.0.6 Add sueezeboxrpc to cardMedia - 07.10.2022 - v3.4.0.6 Time-configurable change for screensaver icons + - 07.10.2022 - v3.5.0 Add Backgroundcolor to Pages + - 08.10.2022 - v3.5.0 Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp + - 12.10.2022 - v3.5.0 Add PageNavigation via Datapoint + - 25.10.2022 - v3.5.0 Add New Parameters to popUpNotify / Layout 2 Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Releais) genutzt werden Tasmota Konsole: @@ -66,6 +75,7 @@ Mögliche Seiten-Ansichten: cardThermo Page - Thermostat mit Solltemperatur, Isttemperatur, Mode - Weitere Eigenschaften können im Alias definiert werden cardMedia Page - Mediaplayer - Ausnahme: Alias sollte mit Alias-Manager automatisch über Alexa-Verzeichnes Player angelegt werden cardAlarm Page - Alarmseite mit Zustand und Tastenfeld + cardPower Page - Energiefluss Popup-Pages: popupLight Page - in Abhängigkeit zum gewählten Alias werden "Helligkeit", "Farb-Temperatur" und "Farbauswahl" bereitgestellt @@ -99,13 +109,15 @@ Mögliche Aliase: (Vorzugsweise mit ioBroker-Adapter "Geräte verwalten" konfigu Wettervorhersage - Aktuelle Außen-Temperatur (Temp) und aktuelles Accu-Wheather-Icon (Icon) für Screensaver Interne Sonoff-Sensoren (über Tasmota): - ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden + ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden --> SetOption146 1 Temperatur - Raumtemperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden (!!! Achtung: der interne Sonoff-Sensor liefert keine exakten Daten, da das NSPanel-Board und der ESP selbst Hitze produzieren !!! ggf. Offset einplanen oder besser einen externen Sensor über Zigbee etc. verwenden) Timestamp - wird in 0_userdata.0. Zeitpunkt der letzten Sensorübertragung + Tasmota-Status0 - (zyklische Ausführung) liefert relevanten Tasmota-Informationen und kann bei Bedarf in "function get_tasmota_status0()" erweitert werden. Daten werden in 0_userdata.0. abgelegt + Erforderliche Adapter: Accu-Wheater: - Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia @@ -113,9 +125,10 @@ Erforderliche Adapter: Alias-Manager - !!! ausschießlich für MEDIA-Alias MQTT-Adapter - Für Kommunikation zwischen Skript und Tasmota JavaScript-Adapter + Upgrades in Konsole: Tasmota BerryDriver : Backlog UpdateDriverVersion https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; Restart 1 - TFT EU STABLE Version : FlashNextion http://nspanel.pky.eu/lovelace-ui/github/nspanel-v3.4.0.tft + TFT EU STABLE Version : FlashNextion http://nspanel.pky.eu/lovelace-ui/github/nspanel-v3.5.0.tft --------------------------------------------------------------------------------------- */ var Icons = new IconsSelector(); @@ -129,9 +142,10 @@ const Debug = false; // Variablen zur Steuerung der Wettericons auf dem Screensaver (Steuerung in 0_userdata.0.XPANELX.ScreensaverInfo) // Wenn weatherForecastTimer auf true, dann Wechsel zwischen Datenpunkten und Wettervorhersage (30 Sekunden nach Minute (Zeit)) // Wenn weatherForecastTimer auf false, dann Möglichkeit über weatherForecast, ob Datenpunkte oder Wettervorhersage (true = WeatherForecast/false = Datenpunkte) -var weatherForecast: boolean; //Änderung zum Video --> Einstellung siehe Wiki +var weatherForecast: boolean; //= getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val -const HMIOff: RGB = { red: 68, green: 115, blue: 158 }; // Blau-Off - Original +const HMIOff: RGB = { red: 68, green: 115, blue: 158 }; // Blau-Off - Original Entity Off +const HMIDark: RGB = { red: 29, green: 29, blue: 29 }; // Original Background Color const Off: RGB = { red: 253, green: 128, blue: 0 }; // Orange-Off - schönere Farbübergänge const On: RGB = { red: 253, green: 216, blue: 53 }; const MSRed: RGB = { red: 251, green: 105, blue: 98 }; @@ -207,34 +221,46 @@ const swWindy: RGB = { red: 150, green: 150, blue: 150}; var vwIconColor = []; //-- Anfang der Beispiele für Seitengestaltung -- Aliase erforderlich ---------------- -var Power: PagePower = -{ - "type": "cardPower", - "heading": "Power", - "useColor": true, - "subPage": false, - "parent": undefined, - "items": [ - { id: "alias.0.NSPanel_1.TestRGBLichteinzeln", name: "RGB-Licht Hex-Color", interpolateColor: true} - ] -}; -var Test_Licht: PageEntities = +var Test_Licht1: PageEntities = { "type": "cardEntities", - "heading": "Color Aliase", + "heading": "Color Aliase 1", "useColor": true, "subPage": false, "parent": undefined, "items": [ { id: "alias.0.NSPanel_1.TestRGBLichteinzeln", name: "RGB-Licht Hex-Color", interpolateColor: true}, - { id: "alias.0.NSPanel_1.TestFarbtemperatur", name: "Farbtemperatur", interpolateColor: true}, - //{ id: "alias.0.NSPanel_1.TestRGBLicht", name: "RGB-Licht", minValueBrightness: 0, maxValueBrightness: 100, interpolateColor: true}, + { id: "alias.0.NSPanel_1.TestRGBLicht", name: "RGB-Licht", minValueBrightness: 0, maxValueBrightness: 100, interpolateColor: true}, + { id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Licht-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true}, + { id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Licht-Color", minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true} + ] +}; + +var CardPowerExample: PagePower = +{ + "type": "cardPower", + "heading": "cardPower Emulator", + "useColor": true, + "subPage": false, + "parent": undefined, + "items": [ + { id: "alias.0.NSPanel_1.Power.PowerCard" }, + ] +}; + +var Test_Licht2: PageEntities = +{ + "type": "cardEntities", + "heading": "Color Aliase 2", + "useColor": true, + "subPage": false, + "parent": undefined, + "items": [ //Beispiel für RGB Light mit neuem PageItem-Parameter colormode: "xy" alternativ colormode: "rgb" oder weglassen //Steuert im z.B. DeConz Adapter unter Lampen die Farben per CIE (XY) - { id: "alias.0.NSPanel_2.WZ_E14_Fenster_rechts", name: "Fensterbank rechts", minValueBrightness: 0, maxValueBrightness: 100, minValueColorTemp: 500, maxValueColorTemp: 150, interpolateColor: false, colormode: "xy"}, - //{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Licht-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true}, - { id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Licht-Color", minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true} + { id: "alias.0.NSPanel_2.WZ_E14_Fenster_rechts", name: "Fensterbank rechts", minValueBrightness: 0, maxValueBrightness: 100, minValueColorTemp: 500, maxValueColorTemp: 150, interpolateColor: true, colormode: "xy"}, + { id: "alias.0.NSPanel_1.TestFarbtemperatur", name: "Farbtemperatur", interpolateColor: true}, ] }; @@ -264,8 +290,7 @@ var Buero_Seite_1: PageEntities = { id: "alias.0.NSPanel_1.Schreibtischlampe", interpolateColor: true}, { id: "alias.0.NSPanel_1.Deckenbeleuchtung", interpolateColor: true}, { id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true}, - { id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", icon2: "",offColor: MSRed, onColor: MSGreen} - //{ id: "alias.0.NSPanel_1.TestVentil1", icon: "valve-open", icon2: "valve-closed",offColor: MSRed, onColor: MSGreen, name: "Test-Ventil 1"} + { id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", icon2: "power",offColor: MSRed, onColor: MSGreen} ] }; @@ -279,11 +304,11 @@ var Fenster_1: PageEntities = "items": [ { id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"}, { id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"}, - { id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}, + { id: "alias.0.NSPanel_1.TestBlind", icon: "blinds-horizontal", offColor: White, onColor: Yellow, name: "Büro", secondRow: "Hier Text für 2. Zeile"}, { id: "alias.0.NSPanel_1.TestDoorlock", offColor: MSRed, onColor: MSGreen, name: "Türschloss"}, ] }; - +//{ id: "alias.0.NS-Panel.Buero.Rollade", icon: "blinds-horizontal", offColor: White, onColor: Yellow, name: "Büro", secondRow: "Hier Text für 2. Zeile"}, var Button_1: PageEntities = { "type": "cardEntities", @@ -294,6 +319,8 @@ var Button_1: PageEntities = "items": [ { id: "alias.0.NSPanel_1.TestTastensensor", name: "Tastensensor (FFN)"}, { id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "Taste (NDR2)", onColor: colorRadio}, + { id: "alias.0.NSPanel_1.TestVentil1", icon: "valve-open", icon2: "valve-closed",offColor: MSRed, onColor: MSGreen, name: "Test-Ventil 1"}, + { id: "alias.0.NSPanel_1.Radio.NDR2", icon: 'alarm-light', name: "Alert mit Zielseite", offColor: MSGreen, onColor: MSRed, targetPage: 'Abfall', buttonText: 'Popup'}, ] }; @@ -310,21 +337,32 @@ var Subpages_1: PageEntities = ] }; -//Subpage 1 von Subpages_1 -var Abfall: PageEntities = -{ - "type": "cardEntities", - "heading": "Abfallkalender", - "useColor": true, - "subPage": true, - "parent": Subpages_1, - "items": [ - { id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"}, - { id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"}, - { id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"}, - { id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"} - ] -}; + //Subpage 1 von Subpages_1 + var Abfall: PageEntities = + { + "type": "cardEntities", + "heading": "Abfallkalender", + "useColor": true, + "subPage": true, + "parent": Subpages_1, + "items": [ + { id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"}, + { id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"}, + { id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"}, + { id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"} + ] + }; + + //Subpage 2 von Subpages_1 + var WLAN: PageQR = + { + "type": "cardQR", + "heading": "Gäste WLAN", + "useColor": true, + "subPage": true, + "parent": Subpages_1, + "items": [{ id: "alias.0.NSPanel_1.Guest_Wifi", hidePassword: true }] + }; var Buero_Seite_2: PageGrid = { @@ -338,7 +376,7 @@ var Buero_Seite_2: PageGrid = { id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"}, { id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"}, { id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}, - { id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"}, + { id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer", secondRow: "auch Text"}, { id: "alias.0.NSPanel_1.Radio.Bob", icon: "play", onColor: White, name: "TuneIn"} ] }; @@ -396,7 +434,21 @@ var SpotifyPremium: PageMedia = "items": [{ id: "alias.0.NSPanel_1.Media.PlayerSpotifyPremium", adapterPlayerInstance: "spotify-premium.0.", - speakerList: ['LENOVO-W11-X','Terrasse','Überall','Gartenhaus','Esszimmer','Heimkino','Echo Dot Küche','Echo Spot Buero'] + speakerList: ['LENOVO-W11-01','Terrasse','Überall','Gartenhaus','Esszimmer','Heimkino','Echo Dot Küche','Echo Spot Buero'] + }] +}; + +var SqueezeboxRPC: PageMedia = +{ + "type": "cardMedia", + "heading": "SqueezeboxRPC", + "useColor": true, + "subPage": false, + "parent": undefined, + "items": [{ + id: "alias.0.Media.LMS.SqueezePlay", + adapterPlayerInstance: "squeezeboxrpc.0.Players.SqueezePlay.", + speakerList: ['SqueezePlay'] }] }; @@ -407,7 +459,7 @@ var Buero_Themostat: PageThermo = "useColor": true, "subPage": false, "parent": undefined, - "items": [{ id: "alias.0.NSPanel_1.Thermostat_Büro", minValue: 50, maxValue: 300 }] + "items": [{ id: "alias.0.NSPanel_1.Thermostat_Buero", minValue: 50, maxValue: 300 }] }; var Buero_Klimaanlage: PageThermo = @@ -417,18 +469,7 @@ var Buero_Klimaanlage: PageThermo = "useColor": true, "subPage": false, "parent": undefined, - "items": [{ id: "alias.0.NSPanel_1.TestKlimaanlage", minValue: 170, maxValue: 250}] -}; - -//Subpage 2 von Subpages_1 -var WLAN: PageQR = -{ - "type": "cardQR", - "heading": "Gäste WLAN", - "useColor": true, - "subPage": true, - "parent": Subpages_1, - "items": [{ id: "alias.0.NSPanel_1.Guest_Wifi" }] + "items": [{ id: "alias.0.NSPanel_1.TestKlimaanlage", minValue: 50, maxValue: 250}] }; var Buero_Alarm: PageAlarm = @@ -441,6 +482,83 @@ var Buero_Alarm: PageAlarm = "items": [{ id: "alias.0.Alarm" }] }; +//Subpages 2 (+ Info) +var Service: PageEntities = +{ + "type": "cardEntities", + "heading": "NSPanel Service", + "useColor": true, + "subPage": false, + "parent": undefined, + "items": [ + { id: "alias.0.NSPanel_1.NSPanel_AutoUpdate", name: "Auto-Updates" ,icon: "update", offColor: MSRed, onColor: MSGreen}, + { navigate: true, id: "NSPanel_Infos", icon: "information-outline", onColor: White, name: "NSPanel Infos"}, + { navigate: true, id: "NSPanel_Firmware_Updates", icon: "update", onColor: White, name: "Manuelle-Updates"}, + { navigate: true, id: "NSPanel_Einstellungen", icon: "wrench-outline", onColor: White, name: "Einstellungen"} + ] +}; + + //Subpage 1 von Subpages_2 + var NSPanel_Infos: PageEntities = + { + "type": "cardEntities", + "heading": "NSPanel Infos", + "useColor": true, + "subPage": true, + "parent": Service, + "items": [ + { id: "alias.0.NSPanel_1.NSPanel_Hardware", name: "Hardware", icon: "memory", offColor: MSYellow, onColor: MSYellow, useColor: true}, + { id: "alias.0.NSPanel_1.NSPanel_ESP_Temp", name: "ESP Temperatur", icon: "thermometer", unit: "°C", offColor: MSYellow, onColor: MSYellow, useColor: true}, + { id: "alias.0.NSPanel_1.NSPanel_UpTime", name: "Uptime", icon: "timeline-clock-outline", offColor: MSYellow, onColor: MSYellow, useColor: true}, + { id: "alias.0.NSPanel_1.NSPanel_RSSI", name: "Wifi-Signal", icon: "signal-distance-variant", unit: "dBm", offColor: MSYellow, onColor: MSYellow, useColor: true} + ] + }; + + //Subpage 2 von Subpages_2 + var NSPanel_Einstellungen: PageEntities = + { + "type": "cardEntities", + "heading": "Screensaver", + "useColor": true, + "subPage": true, + "parent": Service, + "items": [ + { id: "alias.0.NSPanel_1.Dimmode_BrightnessDay", name: "Brightness Tag", icon: "brightness-5", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 5, maxValue: 10}, + { id: "alias.0.NSPanel_1.Dimmode_BrightnessNight", name: "Brightness Nacht", icon: "brightness-4", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 0, maxValue: 4}, + { id: "alias.0.NSPanel_1.Dimmode_HourDay", name: "Stunde Tag", icon: "sun-clock", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 0, maxValue: 23}, + { id: "alias.0.NSPanel_1.Dimmode_HourNight", name: "Stunde Nacht", icon: "sun-clock-outline", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 0, maxValue: 23} + ] + }; + + //Subpage 3 von Subpages_2 + var NSPanel_Firmware_Updates: PageEntities = + { + "type": "cardEntities", + "heading": "Firmware-Updates", + "useColor": true, + "subPage": true, + "parent": Service, + "items": [ + { id: "alias.0.NSPanel_1.Tasmota_Version", name: "Tasmota Firmware", useColor: true}, + { id: "alias.0.NSPanel_1.TFT_Firmware", name: "TFT-Firmware", useColor: true}, + { navigate: true, id: "Subpage_Level2", icon: "wrench-outline", onColor: White, name: "Subpage Level 2"} + ] + }; + + //Subpage1 von Subpage3 von Subpages_2 + var Subpage2_Level_2: PageEntities = + { + "type": "cardEntities", + "heading": "Firmware-Updates", + "useColor": true, + "subPage": true, + "parent": NSPanel_Firmware_Updates, + "items": [ + { id: "alias.0.NSPanel_1.Tasmota_Version", name: "Tasmota Firmware", useColor: true}, + { id: "alias.0.NSPanel_1.TFT_Firmware", name: "TFT-Firmware", useColor: true}, + ] + }; + var button1Page: PageGrid = { "type": "cardGrid", @@ -471,103 +589,46 @@ var button2Page: PageEntities = ] }; -//Subpages 2 (+ Info) -var Service: PageEntities = -{ - "type": "cardEntities", - "heading": "NSPanel Service", - "useColor": true, - "subPage": false, - "parent": undefined, - "items": [ - { id: "alias.0.NSPanel_1.NSPanel_AutoUpdate", name: "Auto-Updates" ,icon: "update", offColor: MSRed, onColor: MSGreen}, - { navigate: true, id: "NSPanel_Infos", icon: "information-outline", onColor: White, name: "NSPanel Infos"}, - { navigate: true, id: "NSPanel_Firmware_Updates", icon: "update", onColor: White, name: "Manuelle-Updates"}, - { navigate: true, id: "NSPanel_Einstellungen", icon: "wrench-outline", onColor: White, name: "Einstellungen"} - ] -}; - -//Subpage 1 von Subpages_2 -var NSPanel_Infos: PageEntities = -{ - "type": "cardEntities", - "heading": "NSPanel Infos", - "useColor": true, - "subPage": true, - "parent": Service, - "items": [ - { id: "alias.0.NSPanel_1.NSPanel_Hardware", name: "Hardware", icon: "memory", offColor: MSYellow, onColor: MSYellow, useColor: true}, - { id: "alias.0.NSPanel_1.NSPanel_ESP_Temp", name: "ESP Temperatur", icon: "thermometer", unit: "°C", offColor: MSYellow, onColor: MSYellow, useColor: true}, - { id: "alias.0.NSPanel_1.NSPanel_UpTime", name: "Uptime", icon: "timeline-clock-outline", offColor: MSYellow, onColor: MSYellow, useColor: true}, - { id: "alias.0.NSPanel_1.NSPanel_RSSI", name: "Wifi-Signal", icon: "signal-distance-variant", unit: "dBm", offColor: MSYellow, onColor: MSYellow, useColor: true} - ] -}; - -//Subpage 2 von Subpages_2 -var NSPanel_Einstellungen: PageEntities = -{ - "type": "cardEntities", - "heading": "Screensaver", - "useColor": true, - "subPage": true, - "parent": Service, - "items": [ - { id: "alias.0.NSPanel_1.Dimmode_BrightnessDay", name: "Brightness Tag", icon: "brightness-5", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 5, maxValue: 10}, - { id: "alias.0.NSPanel_1.Dimmode_BrightnessNight", name: "Brightness Nacht", icon: "brightness-4", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 0, maxValue: 4}, - { id: "alias.0.NSPanel_1.Dimmode_HourDay", name: "Stunde Tag", icon: "sun-clock", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 0, maxValue: 23}, - { id: "alias.0.NSPanel_1.Dimmode_HourNight", name: "Stunde Nacht", icon: "sun-clock-outline", offColor: MSYellow, onColor: MSYellow, useColor: true, minValue: 0, maxValue: 23} - ] -}; - -//Subpage 3 von Subpages_2 -var NSPanel_Firmware_Updates: PageEntities = -{ - "type": "cardEntities", - "heading": "Firmware-Updates", - "useColor": true, - "subPage": true, - "parent": Service, - "items": [ - { id: "alias.0.NSPanel_1.Tasmota_Version", name: "Tasmota Firmware", useColor: true}, - { id: "alias.0.NSPanel_1.TFT_Firmware", name: "TFT-Firmware", useColor: true}, - ] -}; - //-- ENDE der Beispiele für Seitengestaltung -- Aliase erforderlich ------------------ export const config: Config = { panelRecvTopic: 'mqtt.0.SmartHome.NSPanel_1.tele.RESULT', // anpassen panelSendTopic: 'mqtt.0.SmartHome.NSPanel_1.cmnd.CustomSend', // anpassen - firstScreensaverEntity: { ScreensaverEntity: "accuweather.0.Daily.Day1.Day.PrecipitationProbability", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%", ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100} }, - secondScreensaverEntity: { ScreensaverEntity: "accuweather.0.Current.WindSpeed", ScreensaverEntityIcon: "weather-windy", ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: "km/h", ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 180} }, - thirdScreensaverEntity: { ScreensaverEntity: "accuweather.0.Current.UVIndex", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "UV", ScreensaverEntityUnitText: "", ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 9} }, - fourthScreensaverEntity: { ScreensaverEntity: "accuweather.0.Current.RelativeHumidity", ScreensaverEntityIcon: "water-percent", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "%", ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100, 'val_best': 65} }, + firstScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Hourly.h0.PrecipitationProbability', ScreensaverEntityIcon: 'weather-pouring', ScreensaverEntityText: 'Regen', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100} }, + //firstScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Hourly.h0.PrecipitationProbability', ScreensaverEntityIcon: 'weather-pouring', ScreensaverEntityText: 'Regen', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: Red }, + secondScreensaverEntity: { ScreensaverEntity: '0_userdata.0.Wetter.Windstaerke_homaticIP', ScreensaverEntityIcon: 'weather-windy', ScreensaverEntityText: 'Wind', ScreensaverEntityUnitText: 'bft', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 12} }, + //secondScreensaverEntity: { ScreensaverEntity: 'deconz.0.Sensors.5.open', ScreensaverEntityIcon: 'window-closed-variant', ScreensaverEntityText: 'Fenster', ScreensaverEntityUnitText: '', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 12} }, + //secondScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.WindSpeed', ScreensaverEntityIcon: 'weather-windy', ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: 'km/h', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 120} }, + thirdScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.UVIndex', ScreensaverEntityIcon: 'solar-power', ScreensaverEntityText: 'UV', ScreensaverEntityUnitText: '', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 9} }, + fourthScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.RelativeHumidity', ScreensaverEntityIcon: 'water-percent', ScreensaverEntityText: 'Luft', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100, 'val_best': 65} }, alternativeScreensaverLayout: false, autoWeatherColorScreensaverLayout: true, mrIcon1ScreensaverEntity: { ScreensaverEntity: 'mqtt.0.SmartHome.NSPanel_1.stat.POWER1', ScreensaverEntityIcon: 'light-switch', ScreensaverEntityOnColor: On, ScreensaverEntityOffColor: Off }, mrIcon2ScreensaverEntity: { ScreensaverEntity: 'mqtt.0.SmartHome.NSPanel_1.stat.POWER2', ScreensaverEntityIcon: 'lightbulb', ScreensaverEntityOnColor: On, ScreensaverEntityOffColor: Off }, - timeoutScreensaver: 15, + timeoutScreensaver: 20, dimmode: 20, active: 100, //Standard-Brightness TFT - screenSaverDoubleClick: false, + screenSaverDoubleClick: true, locale: 'de-DE', // en-US, de-DE, nl-NL, da-DK, es-ES, fr-FR, it-IT, ru-RU, etc. timeFormat: '%H:%M', // currently not used dateFormat: '%A, %d. %B %Y', // currently not used - weatherEntity: 'alias.0.Wetter', + weatherEntity: 'alias.0.Wetter', // Dieser Alias muss erstellt werden, damit die 4 kleineren Icons (Wetter oder DP) angezeigt werden können defaultOffColor: Off, defaultOnColor: On, defaultColor: Off, + defaultBackgroundColor: Black, //New Parameter temperatureUnit: '°C', pages: [ - //Power, - Sonos, //Beispiel-Seite + SqueezeboxRPC, //Beispiel-Seite + Buero_Seite_1, //Beispiel-Seite + CardPowerExample, //Beispiel-Seite SpotifyPremium, //Beispiel-Seite Alexa, //Beispiel-Seite Buero_Seite_2, //Beispiel-Seite - Buero_Seite_1, //Beispiel-Seite Buero_Klimaanlage, //Beispiel-Seite Button_1, //Beispiel-Seite - Test_Licht, //Beispiel-Seite + Test_Licht1, //Beispiel-Seite + Test_Licht2, //Beispiel-Seite Test_Funktionen, //Beispiel-Seite Fenster_1, //Beispiel-Seite Subpages_1, //Beispiel-Seite @@ -580,7 +641,8 @@ export const config: Config = { WLAN, //Beispiel-Unterseite NSPanel_Infos, //Beispiel-Unterseite NSPanel_Einstellungen, //Beispiel-Unterseite - NSPanel_Firmware_Updates //Beispiel-Unterseite + NSPanel_Firmware_Updates, //Beispiel-Unterseite + Subpage2_Level_2 ], button1Page: button1Page, //Beispiel-Seite auf Button 1, wenn Rule2 definiert - Wenn nicht definiert --> button1Page: null, button2Page: button2Page //Beispiel-Seite auf Button 2, wenn Rule2 definiert - Wenn nicht definiert --> button1Page: null, @@ -590,21 +652,47 @@ export const config: Config = { const request = require('request'); +//---------------------Begin PageNavi +async function InitPageNavi() { + try { + if (!existsState(NSPanel_Path + 'PageNavi')) { + await createStateAsync(NSPanel_Path + 'PageNavi', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'PageNavi', { val: {"pagetype": "page","pageId": 0}, ack: true }); + } + } catch (err) { + console.log('function InitPageNavi: ' + err.message); + } +} +InitPageNavi(); + +//PageNavi +on({id: [].concat([NSPanel_Path + 'PageNavi']), change: "any"}, async function (obj) { + if (existsState(NSPanel_Path + 'PageNavi')) { + let vObj = JSON.parse(obj.state.val); + if (vObj.pagetype == 'page') { + GeneratePage(config.pages[vObj.pageId]); + } else if (vObj.pagetype == 'subpage') { + GeneratePage(config.subPages[vObj.pageId]); + } + } +}); + //----------------------Begin Dimmode function ScreensaverDimmode(timeDimMode: DimMode) { try { + if (Debug) console.log(rgb_dec565(HMIDark)) if (Debug) console.log('Dimmode='+ timeDimMode.dimmodeOn) if (timeDimMode.dimmodeOn != undefined ? timeDimMode.dimmodeOn : false) { if (compareTime(timeDimMode.timeNight != undefined ? timeDimMode.timeNight : '22:00', timeDimMode.timeDay != undefined ? timeDimMode.timeDay : '07:00', 'not between', undefined)) { - SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active }); + SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); if (Debug) console.log('Day Payload: ' + 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active ) } else { - SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active }); + SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); if (Debug) console.log('Night Payload: ' + 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active ) } } else { - SendToPanel({ payload: 'dimmode~' + config.dimmode + '~' + config.active }); + SendToPanel({ payload: 'dimmode~' + config.dimmode + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); } } catch (err) { console.warn('function ScreensaverDimmode: ' + err.message); @@ -688,12 +776,20 @@ const screensaverNotifyText = NSPanel_Path + 'ScreensaverInfo.popupNotifyText'; // Datenpunkte für Nachricht popupNotify Page const popupNotifyHeading = NSPanel_Path + 'popupNotify.popupNotifyHeading'; +const popupNotifyHeadingColor = NSPanel_Path + 'popupNotify.popupNotifyHeadingColor'; const popupNotifyText = NSPanel_Path + 'popupNotify.popupNotifyText'; +const popupNotifyTextColor = NSPanel_Path + 'popupNotify.popupNotifyTextColor'; const popupNotifyInternalName = NSPanel_Path + 'popupNotify.popupNotifyInternalName'; // Wird mit Button-Action zurückgeschrieben +const popupNotifyButton1TextColor = NSPanel_Path + 'popupNotify.popupNotifyButton1TextColor'; const popupNotifyButton1Text = NSPanel_Path + 'popupNotify.popupNotifyButton1Text'; +const popupNotifyButton2TextColor = NSPanel_Path + 'popupNotify.popupNotifyButton2TextColor'; const popupNotifyButton2Text = NSPanel_Path + 'popupNotify.popupNotifyButton2Text'; const popupNotifySleepTimeout = NSPanel_Path + 'popupNotify.popupNotifySleepTimeout'; // in sek. / wenn 0, dann bleibt die Nachricht stehen const popupNotifyAction = NSPanel_Path + 'popupNotify.popupNotifyAction'; // Antwort aus dem Panel true/false +const popupNotifyLayout = NSPanel_Path + 'popupNotify.popupNotifyLayout'; +const popupNotifyFontIdText = NSPanel_Path + 'popupNotify.popupNotifyFontIdText'; 1 - 5 +const popupNotifyIcon = NSPanel_Path + 'popupNotify.popupNotifyIcon'; 1 - 5 +const popupNotifyIconColor = NSPanel_Path + 'popupNotify.popupNotifyIconColor'; 1 - 5 async function InitPopupNotify() { try { @@ -708,12 +804,20 @@ async function InitPopupNotify() { } await createStateAsync(popupNotifyHeading, { type: 'string' }); + await createStateAsync(popupNotifyHeadingColor, { type: 'string' }); await createStateAsync(popupNotifyText, { type: 'string' }); + await createStateAsync(popupNotifyTextColor, { type: 'string' }); await createStateAsync(popupNotifyInternalName, { type: 'string' }); await createStateAsync(popupNotifyButton1Text, { type: 'string' }); + await createStateAsync(popupNotifyButton1TextColor, { type: 'string' }); await createStateAsync(popupNotifyButton2Text, { type: 'string' }); + await createStateAsync(popupNotifyButton2TextColor, { type: 'string' }); await createStateAsync(popupNotifySleepTimeout, { type: 'number' }); await createStateAsync(popupNotifyAction, { type: 'boolean' }); + await createStateAsync(popupNotifyLayout, { type: 'number' }); + await createStateAsync(popupNotifyFontIdText, { type: 'number' }); + await createStateAsync(popupNotifyIcon, { type: 'string' }); + await createStateAsync(popupNotifyIconColor, { type: 'string' }); // Notification to screensaver on({ id: [screensaverNotifyHeading, screensaverNotifyText], change: 'ne', ack: false }, async (obj) => { @@ -729,20 +833,39 @@ async function InitPopupNotify() { // popupNotify - Notification an separate Seite on({ id: [popupNotifyInternalName], change: 'ne' }, async (obj) => { - var notification = 'entityUpdateDetail' + '~' + + var notification : string = '' + + let v_popupNotifyHeadingColor = (getState(popupNotifyHeadingColor).val != null) ? getState(popupNotifyHeadingColor).val : '65504'// Farbe Headline - gelb 65504 + let v_popupNotifyButton1TextColor = (getState(popupNotifyButton1TextColor).val != null) ? getState(popupNotifyButton1TextColor).val : '63488'// Farbe Headline - gelb 65504 + let v_popupNotifyButton2TextColor = (getState(popupNotifyButton2TextColor).val != null) ? getState(popupNotifyButton2TextColor).val : '2016'// Farbe Headline - gelb 65504 + let v_popupNotifyTextColor = (getState(popupNotifyTextColor).val != null) ? getState(popupNotifyTextColor).val : '65535'// Farbe Headline - gelb 65504 + let v_popupNotifyIconColor = (getState(popupNotifyIconColor).val != null) ? getState(popupNotifyIconColor).val : '65535'// Farbe Headline - gelb 65504 + let v_popupNotifyFontIdText = (getState(popupNotifyFontIdText).val != null) ? getState(popupNotifyFontIdText).val : '1' + let v_popupNotifyIcon = (getState(popupNotifyIcon).val != null) ? getState(popupNotifyIcon).val : 'alert' + + notification = 'entityUpdateDetail' + '~' + getState(popupNotifyInternalName).val + '~' + getState(popupNotifyHeading).val + '~' - + '65504' + '~' // Farbe Headline - gelb + + v_popupNotifyHeadingColor + '~' + getState(popupNotifyButton1Text).val + '~' - + '63488' + '~' // Farbe Button1 - rot + + v_popupNotifyButton1TextColor + '~' + getState(popupNotifyButton2Text).val + '~' - + '2016' + '~' // Farbe Button2 - grün + + v_popupNotifyButton2TextColor + '~' + getState(popupNotifyText).val + '~' - + '65535' + '~' // Farbe Text - weiß + + v_popupNotifyTextColor + '~' + getState(popupNotifySleepTimeout).val; + if (getState(popupNotifyLayout).val == 2) { + notification = notification + '~' + + v_popupNotifyFontIdText + '~' + + Icons.GetIcon(v_popupNotifyIcon) + '~' + + v_popupNotifyIconColor; + } + setIfExists(config.panelSendTopic, 'pageType~popupNotify'); setIfExists(config.panelSendTopic, notification); + }); } catch (err) { console.warn('function InitPopupNotify: ' + err.message); @@ -863,7 +986,7 @@ function get_locales() { async function check_updates() { try { - const desired_display_firmware_version = 42; + const desired_display_firmware_version = 43; const berry_driver_version = 4; if (Debug) console.log('Check-Updates'); @@ -1234,7 +1357,7 @@ function update_berry_driver_version() { } function update_tft_firmware() { - const tft_version: string = 'v3.4.0'; + const tft_version: string = 'v3.5.0'; const desired_display_firmware_url = `http://nspanel.pky.eu/lovelace-ui/github/nspanel-${tft_version}.tft`; try { request({ @@ -1885,6 +2008,8 @@ function findLocale(controlsObject: string, controlsState: string): string { const locale = config.locale; const strJson = getState(NSPanel_Path + 'NSPanel_locales_json').val; + if (Debug) console.log(controlsObject + ' - ' + controlsState); + try { const obj = JSON.parse(strJson); const strLocale = obj[controlsObject][controlsState][locale]; @@ -1896,7 +2021,11 @@ function findLocale(controlsObject: string, controlsState: string): string { } } catch (err) { - console.warn('function findLocale: ' + err.message); + if (err.message.substring(0, 35) == 'Cannot read properties of undefined') { + if (Debug) console.log('function findLocale: missing translation: ' + controlsObject + ' - ' + controlsState); + } else { + console.warn('function findLocale: ' + err.message); + } return controlsState; } } @@ -2520,6 +2649,10 @@ function GenerateQRPage(page: PageQR): Payload[] { var heading = page.heading !== undefined ? page.heading : o.common.name.de var textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;' + var hiddenPWD = false; + if (page.items[0].hidePassword !== undefined && page.items[0].hidePassword == true) { + hiddenPWD = true + } const tempstr = textQR.split(';'); for (let w = 0; w < tempstr.length - 1; w++) { @@ -2540,6 +2673,12 @@ function GenerateQRPage(page: PageQR): Payload[] { var iconId2 = Icons.GetIcon('key'); var displayName2 = 'Passwort'; + if (hiddenPWD) { + var type2 = 'disable'; + var iconId2 = ''; + var displayName2 = ''; + } + out_msgs.push({ payload: 'entityUpd~' + //entityUpd heading + '~' + //heading @@ -2594,7 +2733,7 @@ function GeneratePowerPage(page: PagePower): Payload[] { out_msgs.push({ payload: 'pageType~cardPower' }); //Demo Data if no pageItem present - let array_icon_color = [HMIOff, MSGreen, MSYellow, MSGreen, MSYellow, MSGreen, MSRed]; + let array_icon_color = [White, MSGreen, MSYellow, MSGreen, MSYellow, MSGreen, MSRed]; let array_icon = ['home', 'battery-charging-60', 'solar-power-variant', 'wind-turbine', 'shape', 'transmission-tower', 'car']; let array_powerspeed = ['', '-1', '2', '4', '1', '1', '5']; let array_powerstate = ['', '0,5 kW', '0,9 kW', '2,8 kW', '0,2 kW', '0,1 kW', '4,6 kW']; @@ -2632,6 +2771,7 @@ function GeneratePowerPage(page: PagePower): Payload[] { }); return out_msgs + } catch (err) { console.warn('function GeneratePowerPage: ' + err.message); } @@ -2771,15 +2911,6 @@ function HandleButtonEvent(words): void { } } break; - case 'up': - setIfExists(id + '.OPEN', true); - break; - case 'stop': - setIfExists(id + '.STOP', true); - break; - case 'down': - setIfExists(id + '.CLOSE', true); - break; case 'button': if (existsObject(id)) { var action = false @@ -2811,12 +2942,36 @@ function HandleButtonEvent(words): void { } } break; + case 'up': + setIfExists(id + '.OPEN', true); + break; + case 'stop': + setIfExists(id + '.STOP', true); + break; + case 'down': + setIfExists(id + '.CLOSE', true); + break; case 'positionSlider': (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); timeoutSlider = setTimeout(async function () { setIfExists(id + '.SET', parseInt(words[4])) ? true : setIfExists(id + '.ACTUAL', parseInt(words[4])); }, 250); break; + case 'tiltOpen': + setIfExists(id + '.TILT_OPEN', true); + break; + case 'tiltStop': + setIfExists(id + '.TILT_STOP', true); + break; + case 'tiltClose': + setIfExists(id + '.TILT_CLOSE', true); + break; + case 'tiltSlider': + (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); + timeoutSlider = setTimeout(async function () { + setIfExists(id + '.TILT_SET', parseInt(words[4])) ? true : setIfExists(id + '.TILT_ACTUAL', parseInt(words[4])); + }, 250); + break; case 'brightnessSlider': (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); timeoutSlider = setTimeout(async function () { @@ -3488,16 +3643,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } out_msgs.push({ - payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' - + icon + '~' //iconId - + iconColor + '~' //iconColor - + switchVal + '~' //buttonState - + brightness + '~' //sliderBrightnessPos - + colorTemp + '~' //sliderColorTempPos - + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) - + 'Color' + '~' //Color-Bezeichnung - + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + payload: 'entityUpdateDetail' + '~' //entityUpdateDetail + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + findLocale('lights', 'Brightness') }); //Brightness-Bezeichnung } @@ -3512,14 +3667,69 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { val = getState(id + '.SET').val; RegisterDetailEntityWatcher(id + '.SET', pageItem, type); } + var tilt_position: any = 'disabled' + if (existsState(id + '.TILT_ACTUAL')) { + tilt_position = getState(id + '.TILT_ACTUAL').val; + RegisterDetailEntityWatcher(id + '.TILT_ACTUAL', pageItem, type); + } else if (existsState(id + '.TILT_SET')) { + tilt_position = getState(id + '.TILT_SET').val; + RegisterDetailEntityWatcher(id + '.TILT_SET', pageItem, type); + } + + let textSecondRow = ''; + let icon_id = icon; + let icon_up = Icons.GetIcon('arrow-up'); + let icon_stop = Icons.GetIcon('stop'); + let icon_down = Icons.GetIcon('arrow-down'); + let icon_up_status = getState(id + '.ACTUAL').val != 100 ? 'enable' : 'disable'; + let icon_stop_status = 'enable'; + let icon_down_status = getState(id + '.ACTUAL').val != 0 ? 'enable' : 'disable'; + let textTilt = ''; + let iconTiltLeft = ''; + let iconTiltStop = ''; + let iconTiltRight = ''; + let iconTiltLeftStatus = 'disable'; + let iconTiltStopStatus = 'disable'; + let iconTiltRightStatus = 'disable'; + let tilt_pos = 'disable'; + + if (existsState(id + '.TILT_SET')) { + textTilt = findLocale('blinds', 'Tilt'); + iconTiltLeft = Icons.GetIcon('arrow-top-right'); + iconTiltStop = Icons.GetIcon('stop'); + iconTiltRight = Icons.GetIcon('arrow-bottom-left'); + iconTiltLeftStatus = getState(id + '.TILT_ACTUAL').val != 100 ? 'enable' : 'disable'; + iconTiltStopStatus = 'enable'; + iconTiltRightStatus = getState(id + '.TILT_ACTUAL').val != 0 ? 'enable' : 'disable'; + tilt_pos = tilt_position; + } + + if (pageItem.secondRow != undefined) { + textSecondRow = pageItem.secondRow; + } out_msgs.push({ payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' - + val + '~' //Shutterposition - + '' + '~' - + findLocale('blinds', 'Position') - }); //Position-Bezeichnung + + id + '~' //entity_id + + val + '~' //Shutterposition + + textSecondRow + '~' //pos_status 2.line + + findLocale('blinds', 'Position') + '~' //pos_translation + + icon_id + '~' //{icon_id}~ + + icon_up + '~' //{icon_up}~ + + icon_stop + '~' //{icon_stop}~ + + icon_down + '~' //{icon_down}~ + + icon_up_status + '~' //{icon_up_status}~ + + icon_stop_status + '~' //{icon_stop_status}~ + + icon_down_status + '~' //{icon_down_status}~ + + textTilt + '~' //{textTilt}~ + + iconTiltLeft + '~' //{iconTiltLeft}~ + + iconTiltStop + '~' //{iconTiltStop}~ + + iconTiltRight + '~' //{iconTiltRight}~ + + iconTiltLeftStatus + '~' //{iconTiltLeftStatus}~ + + iconTiltStopStatus + '~' //{iconTiltStopStatus}~ + + iconTiltRightStatus + '~' //{iconTiltRightStatus}~ + + tilt_pos //{tilt_pos}") + }); } } @@ -3608,7 +3818,6 @@ function HandleScreensaverUpdate(): void { if (typeof getState(config.firstScreensaverEntity.ScreensaverEntity).val == 'boolean') { vwIconColor[1] = (getState(config.firstScreensaverEntity.ScreensaverEntity).val == true) ? rgb_dec565(colorScale10) : rgb_dec565(colorScale0); } else if (typeof config.firstScreensaverEntity.ScreensaverEntityIconColor == 'object') { - let iconvalmin = (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_min != undefined) ? config.firstScreensaverEntity.ScreensaverEntityIconColor.val_min : 0 ; let iconvalmax = (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_max != undefined) ? config.firstScreensaverEntity.ScreensaverEntityIconColor.val_max : 100 ; let iconvalbest = (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_best != undefined) ? config.firstScreensaverEntity.ScreensaverEntityIconColor.val_best : iconvalmin ; @@ -3666,8 +3875,11 @@ function HandleScreensaverUpdate(): void { break; } } + if (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[1] = rgb_dec565(config.firstScreensaverEntity.ScreensaverEntityIconColor); + } } else { - vwIconColor[1] = rgb_dec565(sctF1Icon); + vwIconColor[1] = rgb_dec565(sctF1Icon); } } else { vwIconColor[1] = rgb_dec565(sctF1Icon); @@ -3735,6 +3947,9 @@ function HandleScreensaverUpdate(): void { break; } } + if (config.secondScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[2] = rgb_dec565(config.secondScreensaverEntity.ScreensaverEntityIconColor); + } } else { vwIconColor[2] = rgb_dec565(sctF2Icon); } @@ -3804,6 +4019,9 @@ function HandleScreensaverUpdate(): void { break; } } + if (config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[3] = rgb_dec565(config.thirdScreensaverEntity.ScreensaverEntityIconColor); + } } else { vwIconColor[3] = rgb_dec565(sctF2Icon); } @@ -3873,6 +4091,9 @@ function HandleScreensaverUpdate(): void { break; } } + if (config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[4] = rgb_dec565(config.fourthScreensaverEntity.ScreensaverEntityIconColor); + } } else { vwIconColor[4] = rgb_dec565(sctF2Icon); } @@ -4207,7 +4428,8 @@ function InterpolateNum(d1: number, d2: number, fraction: number): number { } function rgb_dec565(rgb: RGB): number { - return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31))); + //return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31))); + return ((rgb.red >> 3) << 11) | ((rgb.green >> 2)) << 5 | ((rgb.blue) >> 3) } /* Convert radians to degrees @@ -4294,22 +4516,22 @@ function pos_to_color(x: number, y: number): RGB { function rgb_to_cie(red, green, blue) { - //Apply a gamma correction to the RGB values, which makes the color more vivid and more the like the color displayed on the screen of your device - var vred = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); - var vgreen = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); - var vblue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); - - //RGB values to XYZ using the Wide RGB D65 conversion formula - var X = vred * 0.664511 + vgreen * 0.154324 + vblue * 0.162028; - var Y = vred * 0.283881 + vgreen * 0.668433 + vblue * 0.047685; - var Z = vred * 0.000088 + vgreen * 0.072310 + vblue * 0.986039; - - //Calculate the xy values from the XYZ values - var ciex = (X / (X + Y + Z)).toFixed(4); - var ciey = (Y / (X + Y + Z)).toFixed(4); - var cie = "[" + ciex + "," + ciey + "]" - - return cie; + //Apply a gamma correction to the RGB values, which makes the color more vivid and more the like the color displayed on the screen of your device + let vred = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); + let vgreen = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); + let vblue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); + + //RGB values to XYZ using the Wide RGB D65 conversion formula + let X = vred * 0.664511 + vgreen * 0.154324 + vblue * 0.162028; + let Y = vred * 0.283881 + vgreen * 0.668433 + vblue * 0.047685; + let Z = vred * 0.000088 + vgreen * 0.072310 + vblue * 0.986039; + + //Calculate the xy values from the XYZ values + let ciex = (X / (X + Y + Z)).toFixed(4); + let ciey = (Y / (X + Y + Z)).toFixed(4); + let cie = "[" + ciex + "," + ciey + "]" + + return cie; } function spotifyGetDeviceID(vDeviceString) { @@ -4391,14 +4613,16 @@ type PageItem = { minValue: (number | undefined), maxValue: (number | undefined), name: (string | undefined), + secondRow: (string | undefined), buttonText: (string | undefined), unit: (string | undefined), navigate: (boolean | undefined), colormode: (string | undefined), adapterPlayerInstance: (string | undefined), mediaDevice: (string | undefined), - targetPage: (string | undefined) - speakerList: (string[] | undefined) + targetPage: (string | undefined), + speakerList: (string[] | undefined), + hidePassword: (boolean | undefined) } type DimMode = { @@ -4432,6 +4656,7 @@ type Config = { defaultColor: RGB, defaultOnColor: RGB, defaultOffColor: RGB, + defaultBackgroundColor: RGB, pages: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower)[], subPages: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower)[], button1Page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower | null), From 0732ee69b6999335407226d5db208069b6044c87 Mon Sep 17 00:00:00 2001 From: Armilar <102996011+Armilar@users.noreply.github.com> Date: Tue, 25 Oct 2022 21:56:13 +0200 Subject: [PATCH 02/15] v3.5.0 - Upgrade - Add Backgroundcolor to Pages - Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - Add PageNavigation via Datapoint - Add New Parameters to popUpNotify / Layout 2 --- ioBroker/NsPanelTs.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 085dd438..07e4226e 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -142,7 +142,7 @@ const Debug = false; // Variablen zur Steuerung der Wettericons auf dem Screensaver (Steuerung in 0_userdata.0.XPANELX.ScreensaverInfo) // Wenn weatherForecastTimer auf true, dann Wechsel zwischen Datenpunkten und Wettervorhersage (30 Sekunden nach Minute (Zeit)) // Wenn weatherForecastTimer auf false, dann Möglichkeit über weatherForecast, ob Datenpunkte oder Wettervorhersage (true = WeatherForecast/false = Datenpunkte) -var weatherForecast: boolean; //= getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val +var weatherForecast: boolean; //Änderung zum Video --> Einstellung siehe Wiki const HMIOff: RGB = { red: 68, green: 115, blue: 158 }; // Blau-Off - Original Entity Off const HMIDark: RGB = { red: 29, green: 29, blue: 29 }; // Original Background Color @@ -2674,9 +2674,9 @@ function GenerateQRPage(page: PageQR): Payload[] { var displayName2 = 'Passwort'; if (hiddenPWD) { - var type2 = 'disable'; - var iconId2 = ''; - var displayName2 = ''; + type2 = 'disable'; + iconId2 = ''; + displayName2 = ''; } out_msgs.push({ From 4e849ae0a1dccf3d715607f3dc60c86754b6efa0 Mon Sep 17 00:00:00 2001 From: Armilar <102996011+Armilar@users.noreply.github.com> Date: Tue, 25 Oct 2022 22:03:25 +0200 Subject: [PATCH 03/15] v3.5.0 - Upgrade - Add Backgroundcolor to Pages - Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - Add PageNavigation via Datapoint - Add New Parameters to popUpNotify / Layout 2 --- ioBroker/NsPanelTs_without_Examples.ts | 4292 ++++++++++++++++++++++++ 1 file changed, 4292 insertions(+) create mode 100644 ioBroker/NsPanelTs_without_Examples.ts diff --git a/ioBroker/NsPanelTs_without_Examples.ts b/ioBroker/NsPanelTs_without_Examples.ts new file mode 100644 index 00000000..ae164f1b --- /dev/null +++ b/ioBroker/NsPanelTs_without_Examples.ts @@ -0,0 +1,4292 @@ +/*----------------------------------------------------------------------- +TypeScript v3.5.0 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf +- abgestimmt auf TFT 43 / v3.5.0 / BerryDriver 4 / Tasmota 12.2.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 +icon_mapping.ts: https://github.com/joBr99/nspanel-lovelace-ui/blob/main/ioBroker/icon_mapping.ts (TypeScript muss in global liegen) + +ioBroker-Unterstützung: https://forum.iobroker.net/topic/50888/sonoff-nspanel +WIKI zu diesem Projekt unter: https://github.com/joBr99/nspanel-lovelace-ui/wiki (siehe Sidebar) +Icons unter: https://htmlpreview.github.io/?https://github.com/jobr99/Generate-HASP-Fonts/blob/master/cheatsheet.html + +******************************************************************************* +Achtung Änderung des Sonoff ESP-Temperatursensors +!!! Bitte "SetOption146 1" in der Tasmota-Console ausführen !!! +******************************************************************************* + +ReleaseNotes: + Bugfixes und Erweiterungen: + - cardQR (für Gäste WLAN) + - cardThermo (Neues Design für Alias Thermostat und zusätzlich für Alias Klimaanlage) + - 08.05.2022 - v2.9.0 - Menüpfeile bei HardwareButtons (button1Page; button2Page) mit Navigation auf Page 0 + - 08.05.2022 - v2.9.0 - Standard-Brightness über neuen Parameter active einstellbar (Test mit 2.9.3) + - 08.05.2022 - v2.9.0 - Schalter (Licht, Dimmer, Hue, etc) in cardGrid lassen sich wieder schalten + - 14.06.2022 - v2.9.0 - Aktion auf Submenüs schaltet unmittelbar auf vorheriges Mainmenu (Many thanks to Grrzzz) + - 14.06.2022 - v2.9.0 - Menü-Pfeile in Subpages (z.B. card QR, cardMedia, etc) (Many thanks to Grrzzz) + - 15.06.2022 - v3.0.0 - Date/Time im Screensaver auf Basis localString (de-DE/en-EN/nl-NL/etc.) + - 16.06.2022 - v3.0.0 - Multilingual - config.locale (en-EN, de-DE, nl-NL, da-DK, es-ES, fr-FR, it-IT, ru-RU, etc.) + - 16.06.2022 - v3.0.0 - Bugfix by Grrzzz - Subpages + - 18.06.2022 - v3.1.0 - Längere Textfelder in cardEntities + - 18.06.2022 - V3.1.0 - Detail-Page Lights/Shutter hat neuen Parameter "id" + - 19.06.2022 - v3.1.0 - Bugfix toLocalTimeString in en-EN/en-US + - 19.06.2022 - v3.1.0 - Fehler in findLocale abgefangen + - 19.06.2022 - v3.1.0 - Umstellung auf "Home Assistant" Sprachfile + - 19.06.2022 - v3.1.0 - Alias "light" und "socket" haben optionalen Parameter icon2 für negative Zustände + - 29.06.2022 - v3.1.1 - Bugfix Github #286 (Active Page) + Bugfix pageThermo, pageMedia, pageAlarm as first Page + - 25.08.2022 - v3.1.0 - Code-Verbesserungen (klein0r) + - 26.08.2022 - v3.2.0 - pageItem mit CIE (XY) Parameter für ColorWheel (Steuerung für z.B Deconz-Farben bei denen Hue nicht greift) + - 28.08.2022 - v3.2.0 - Wechsel zwischen Weather-Forecast und eigenen Datenpunkten im Screensaver (minütlich) + - 28.08.2022 - v3.2.0 - Bugfix für 3.2.0 in GenerateDetailPage: Color-Language nicht über findLocales, da nicht in Sprachfile enthalten + - 29.08.2022 - v3.3.0 - Upgrade TFT 40 + - 29.08.2022 - v3.3.1 - Upgrade TFT 41 + - 04.09.2022 - v3.3.1 - Überarbeitung und BugFix für cardAlarm + - 13.09.2022 - v3.3.1.3 BugFix Screensaver Toggle + - 13.09.2022 - v3.3.1.3 Überarbeitung und BugFix und Refresh Features für cardMedia (Breaking Changes) + - 13.09.2022 - v3.3.1.3 Hinzufügen von SpotifyPremium, Sonos und Chromecast (Google home) zur cardMedia-Logik + - 15.09.2022 - V3.4.0 - BugFix Dimmode + - 15.09.2022 - V3.4.0 - Colormode für Screensaver + AutoColor WeatherForecast + - 16.09.2022 - v3.4.0.1 Visualisierung der Relay Zustände (MRIcons) im Screensaver + Bugfix Screensaver MRIcon2 + - 17.09.2022 - v3.4.0.2 Bugfix for screensaver icons with scaled colors + - 17.09.2022 - v3.4.0.3 Bugfix bNext / bPrev by joBr99 + - 18.09.2022 - v3.4.0.4 Add On/Off Colors in config.mrIcon1ScreensaverEntity and config.mrIcon2ScreensaverEntity + - 19.09.2022 - v3.4.0.5 Add Mode to cardThermo (Alias Thermostat) + - 03.10.2022 - v3.4.0.6 Add 5 Entities in US Panel Version to cardEntities + - 03.10.2022 - v3.4.0.6 Fix screenSaverDoubleClick + - 03.10.2022 - v3.4.0.6 Add cardPower (experimental) + - 05.10.2022 - v3.4.0.6 Add sueezeboxrpc to cardMedia + - 07.10.2022 - v3.4.0.6 Time-configurable change for screensaver icons + - 07.10.2022 - v3.5.0 Add Backgroundcolor to Pages + - 08.10.2022 - v3.5.0 Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp + - 12.10.2022 - v3.5.0 Add PageNavigation via Datapoint + - 25.10.2022 - v3.5.0 Add New Parameters to popUpNotify / Layout 2 + +Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Releais) genutzt werden +Tasmota Konsole: + Rule2 on Button1#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button2"} endon + Rule2 1 (Rule aktivieren) + Rule2 0 (Rule deaktivieren) + +Mögliche Seiten-Ansichten: + screensaver Page - wird nach definiertem Zeitraum (config) mit Dimm-Modus aktiv (Uhrzeit, Datum, Aktuelle Temperatur mit Symbol) + (die 4 kleineren Icons können als Wetter-Vorschau + 4Tage (Symbol + Höschsttemperatur) oder zur Anzeige definierter Infos konfiguriert werden) + cardEntities Page - 4 vertikale angeordnete Steuerelemente - auch als Subpage + cardGrid Page - 6 horizontal angeordnete Steuerelemente in 2 Reihen a 3 Steuerelemente - auch als Subpage + cardThermo Page - Thermostat mit Solltemperatur, Isttemperatur, Mode - Weitere Eigenschaften können im Alias definiert werden + cardMedia Page - Mediaplayer - Ausnahme: Alias sollte mit Alias-Manager automatisch über Alexa-Verzeichnes Player angelegt werden + cardAlarm Page - Alarmseite mit Zustand und Tastenfeld + cardPower Page - Energiefluss + +Popup-Pages: + popupLight Page - in Abhängigkeit zum gewählten Alias werden "Helligkeit", "Farb-Temperatur" und "Farbauswahl" bereitgestellt + popupShutter Page - die Shutter-Potition (Rollo, Jalousie, Markise, Leinwand, etc.) kann über einen Slider verändert werden. + popupNotify Page - Info - Seite mit Headline Text und Buttons - Intern für manuelle Updates / Extern zur Befüllung von Datenpunkten unter 0_userdata + screensaver Notify - Über zwei externe Datenpunkte in 0_userdata können "Headline" und "Text" an den Screensaver zur Info gesendet werden + +Mögliche Aliase: (Vorzugsweise mit ioBroker-Adapter "Geräte verwalten" konfigurieren, da SET, GET, ACTUAL, etc. verwendet werden) + Info - Werte aus Datenpunkt + Schieberegler - Slider numerische Werte (SET/ACTUAL) + Lautstärke - Volume (SET/ACTUAL) und MUTE + Lautstärke-Gruppe - analog Lautstärke + Licht - An/Aus (Schalter) + Steckdose - An/Aus (Schalter) + Dimmer - An/Aus, Brightness + Farbtemperatur - An/Aus, Farbtemperatur und Brightness + HUE-Licht - Zum Schalten von Color-Leuchtmitteln über HUE-Wert, Brightness, Farbtemperatur, An/Aus (HUE kann auch fehlen) + RGB-Licht - RGB-Leuchtmitteln/Stripes welche Rot/Grün/ und Blau separat benötigen (Tasmota, WifiLight, etc.) + Brightness, Farbtemperatur + RGB-Licht-einzeln - RGB-Leuchtmitteln/Stripes welche HEX-Farbwerte benötigen (Tasmota, WifiLight, etc.) + Brightness, Farbtemperatur + Jalousien - Up, Stop, Down, Position + Fenster - Sensor open + Tür - Sensor open + Verschluss - Türschloss SET/ACTUAL/OPEN + Taste - Für Szenen oder Radiosender, etc. --> Nur Funktionsaufruf - Kein Taster wie MonoButton - True/False + Tastensensor - analog Taste + Thermostat - Aktuelle Raumtemperatur, Setpoint, etc. + Klimaanlage - Buttons zur Steuerung der Klimaanlage im unteren Bereich + Temperatur - Anzeige von Temperture - Datenpunkten, ananlog Info + Feuchtigkeit - Anzeige von Humidity - Datenpunkten, ananlog Info + Medien - Steuerung von Alexa - Über Alias-Manager im Verzeichnis Player automatisch anlegen (Geräte-Manager funktioniert nicht) + Wettervorhersage - Aktuelle Außen-Temperatur (Temp) und aktuelles Accu-Wheather-Icon (Icon) für Screensaver + +Interne Sonoff-Sensoren (über Tasmota): + ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden --> SetOption146 1 + Temperatur - Raumtemperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden + (!!! Achtung: der interne Sonoff-Sensor liefert keine exakten Daten, da das NSPanel-Board und der ESP selbst Hitze produzieren !!! + ggf. Offset einplanen oder besser einen externen Sensor über Zigbee etc. verwenden) + Timestamp - wird in 0_userdata.0. Zeitpunkt der letzten Sensorübertragung + +Tasmota-Status0 - (zyklische Ausführung) + liefert relevanten Tasmota-Informationen und kann bei Bedarf in "function get_tasmota_status0()" erweitert werden. Daten werden in 0_userdata.0. abgelegt + +Erforderliche Adapter: + Accu-Wheater: - Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver + Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia + Geräte verwalten - Für Erstellung der Aliase + Alias-Manager - !!! ausschießlich für MEDIA-Alias + MQTT-Adapter - Für Kommunikation zwischen Skript und Tasmota + JavaScript-Adapter + +Upgrades in Konsole: + Tasmota BerryDriver : Backlog UpdateDriverVersion https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; Restart 1 + TFT EU STABLE Version : FlashNextion http://nspanel.pky.eu/lovelace-ui/github/nspanel-v3.5.0.tft +--------------------------------------------------------------------------------------- +*/ +var Icons = new IconsSelector(); +var timeoutSlider: any; +var manually_Update = false; + +const NSPanel_Path = '0_userdata.0.NSPanel.1.'; +const NSPanel_Alarm_Path = '0_userdata.0.NSPanel.'; //Neuer Pfad für gemeinsame Nutzung durch mehrere Panels (bei Nutzung der cardAlarm) +const Debug = false; + +// Variablen zur Steuerung der Wettericons auf dem Screensaver (Steuerung in 0_userdata.0.XPANELX.ScreensaverInfo) +// Wenn weatherForecastTimer auf true, dann Wechsel zwischen Datenpunkten und Wettervorhersage (30 Sekunden nach Minute (Zeit)) +// Wenn weatherForecastTimer auf false, dann Möglichkeit über weatherForecast, ob Datenpunkte oder Wettervorhersage (true = WeatherForecast/false = Datenpunkte) +var weatherForecast: boolean; //Änderung zum Video --> Einstellung siehe Wiki + +const HMIOff: RGB = { red: 68, green: 115, blue: 158 }; // Blau-Off - Original Entity Off +const HMIDark: RGB = { red: 29, green: 29, blue: 29 }; // Original Background Color +const Off: RGB = { red: 253, green: 128, blue: 0 }; // Orange-Off - schönere Farbübergänge +const On: RGB = { red: 253, green: 216, blue: 53 }; +const MSRed: RGB = { red: 251, green: 105, blue: 98 }; +const MSYellow: RGB = { red: 255, green: 235, blue: 156 }; +const MSGreen: RGB = { red: 121, green: 222, blue: 121 }; +const Red: RGB = { red: 255, green: 0, blue: 0 }; +const White: RGB = { red: 255, green: 255, blue: 255 }; +const Yellow: RGB = { red: 255, green: 255, blue: 0 }; +const Green: RGB = { red: 0, green: 255, blue: 0 }; +const Blue: RGB = { red: 0, green: 0, blue: 255 }; +const DarkBlue: RGB = { red: 0, green: 0, blue: 136 }; +const Gray: RGB = { red: 136, green: 136, blue: 136 }; +const Black: RGB = { red: 0, green: 0, blue: 0 }; +const colorSpotify: RGB = { red: 30, green: 215, blue: 96 }; +const colorAlexa: RGB = { red: 49, green: 196, blue: 243 }; +const colorRadio: RGB = { red: 255, green: 127, blue: 0 }; +const BatteryFull: RGB = { red: 96, green: 176, blue: 62 }; +const BatteryEmpty: RGB = { red: 179, green: 45, blue: 25 }; + +//Dynamische Indikatoren +const colorScale0: RGB = { red: 99, green: 190, blue: 123 }; +const colorScale1: RGB = { red: 129, green: 199, blue: 126 }; +const colorScale2: RGB = { red: 161, green: 208, blue: 127 }; +const colorScale3: RGB = { red: 129, green: 217, blue: 126 }; +const colorScale4: RGB = { red: 222, green: 226, blue: 131 }; +const colorScale5: RGB = { red: 254, green: 235, blue: 132 }; +const colorScale6: RGB = { red: 255, green: 210, blue: 129 }; +const colorScale7: RGB = { red: 251, green: 185, blue: 124 }; +const colorScale8: RGB = { red: 251, green: 158, blue: 117 }; +const colorScale9: RGB = { red: 248, green: 131, blue: 111 }; +const colorScale10: RGB = { red: 248, green: 105, blue: 107 }; + +//Screensaver Default Theme Colors +const scbackground: RGB = { red: 0, green: 0, blue: 0}; +const sctime: RGB = { red: 255, green: 255, blue: 255}; +const sctimeAMPM: RGB = { red: 255, green: 255, blue: 255}; +const scdate: RGB = { red: 255, green: 255, blue: 255}; +const sctMainIcon: RGB = { red: 255, green: 255, blue: 255}; +const sctMainText: RGB = { red: 255, green: 255, blue: 255}; +const sctForecast1: RGB = { red: 255, green: 255, blue: 255}; +const sctForecast2: RGB = { red: 255, green: 255, blue: 255}; +const sctForecast3: RGB = { red: 255, green: 255, blue: 255}; +const sctForecast4: RGB = { red: 255, green: 255, blue: 255}; +const sctF1Icon: RGB = { red: 255, green: 235, blue: 156}; +const sctF2Icon: RGB = { red: 255, green: 235, blue: 156}; +const sctF3Icon: RGB = { red: 255, green: 235, blue: 156}; +const sctF4Icon: RGB = { red: 255, green: 235, blue: 156}; +const sctForecast1Val: RGB = { red: 255, green: 255, blue: 255}; +const sctForecast2Val: RGB = { red: 255, green: 255, blue: 255}; +const sctForecast3Val: RGB = { red: 255, green: 255, blue: 255}; +const sctForecast4Val: RGB = { red: 255, green: 255, blue: 255}; +const scbar: RGB = { red: 255, green: 255, blue: 255}; +const sctMainIconAlt: RGB = { red: 255, green: 255, blue: 255}; +const sctMainTextAlt: RGB = { red: 255, green: 255, blue: 255}; +const sctTimeAdd: RGB = { red: 255, green: 255, blue: 255}; + +//Auto-Weather-Colors +const swClearNight: RGB = { red: 150, green: 150, blue: 100}; +const swCloudy: RGB = { red: 75, green: 75, blue: 75}; +const swExceptional: RGB = { red: 255, green: 50, blue: 50}; +const swFog: RGB = { red: 150, green: 150, blue: 150}; +const swHail: RGB = { red: 200, green: 200, blue: 200}; +const swLightning: RGB = { red: 200, green: 200, blue: 0}; +const swLightningRainy: RGB = { red: 200, green: 200, blue: 150}; +const swPartlycloudy: RGB = { red: 150, green: 150, blue: 150}; +const swPouring: RGB = { red: 50, green: 50, blue: 255}; +const swRainy: RGB = { red: 100, green: 100, blue: 255}; +const swSnowy: RGB = { red: 150, green: 150, blue: 150}; +const swSnowyRainy: RGB = { red: 150, green: 150, blue: 255}; +const swSunny: RGB = { red: 255, green: 255, blue: 0}; +const swWindy: RGB = { red: 150, green: 150, blue: 150}; + +var vwIconColor = []; + +//-- Anfang der Variablen für Seitengestaltung -- Aliase erforderlich ---------------- + + + +//-- ENDE der Variablen für Seitengestaltung -- Aliase erforderlich ------------------ + +export const config: Config = { + panelRecvTopic: 'mqtt.0.SmartHome.NSPanel_1.tele.RESULT', // anpassen + panelSendTopic: 'mqtt.0.SmartHome.NSPanel_1.cmnd.CustomSend', // anpassen + firstScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Hourly.h0.PrecipitationProbability', ScreensaverEntityIcon: 'weather-pouring', ScreensaverEntityText: 'Regen', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100} }, + secondScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.WindSpeed', ScreensaverEntityIcon: 'weather-windy', ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: 'km/h', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 120} }, + thirdScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.UVIndex', ScreensaverEntityIcon: 'solar-power', ScreensaverEntityText: 'UV', ScreensaverEntityUnitText: '', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 9} }, + fourthScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.RelativeHumidity', ScreensaverEntityIcon: 'water-percent', ScreensaverEntityText: 'Luft', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100, 'val_best': 65} }, + alternativeScreensaverLayout: false, + autoWeatherColorScreensaverLayout: true, + //!!!! Achtung anpassen !!!! + mrIcon1ScreensaverEntity: { ScreensaverEntity: 'mqtt.0.SmartHome.NSPanel_1.stat.POWER1', ScreensaverEntityIcon: 'light-switch', ScreensaverEntityOnColor: On, ScreensaverEntityOffColor: Off }, + mrIcon2ScreensaverEntity: { ScreensaverEntity: 'mqtt.0.SmartHome.NSPanel_1.stat.POWER2', ScreensaverEntityIcon: 'lightbulb', ScreensaverEntityOnColor: On, ScreensaverEntityOffColor: Off }, + timeoutScreensaver: 20, + dimmode: 20, + active: 100, //Standard-Brightness TFT + screenSaverDoubleClick: true, + locale: 'de-DE', // en-US, de-DE, nl-NL, da-DK, es-ES, fr-FR, it-IT, ru-RU, etc. + timeFormat: '%H:%M', // currently not used + dateFormat: '%A, %d. %B %Y', // currently not used + weatherEntity: 'alias.0.Wetter', // Dieser Alias muss erstellt werden, damit die 4 kleineren Icons (Wetter oder DP) angezeigt werden können + defaultOffColor: Off, + defaultOnColor: On, + defaultColor: Off, + defaultBackgroundColor: Black, //New Parameter + temperatureUnit: '°C', + pages: [ + + ], + subPages: [ + + ], + button1Page: null, //Beispiel-Seite auf Button 1, wenn Rule2 definiert - Wenn nicht definiert --> button1Page: null, + button2Page: null //Beispiel-Seite auf Button 2, wenn Rule2 definiert - Wenn nicht definiert --> button1Page: null, +}; + +// _________________________________ Ab hier keine Konfiguration mehr _____________________________________ + +const request = require('request'); + +//---------------------Begin PageNavi +async function InitPageNavi() { + try { + if (!existsState(NSPanel_Path + 'PageNavi')) { + await createStateAsync(NSPanel_Path + 'PageNavi', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'PageNavi', { val: {"pagetype": "page","pageId": 0}, ack: true }); + } + } catch (err) { + console.log('function InitPageNavi: ' + err.message); + } +} +InitPageNavi(); + +//PageNavi +on({id: [].concat([NSPanel_Path + 'PageNavi']), change: "any"}, async function (obj) { + if (existsState(NSPanel_Path + 'PageNavi')) { + let vObj = JSON.parse(obj.state.val); + if (vObj.pagetype == 'page') { + GeneratePage(config.pages[vObj.pageId]); + } else if (vObj.pagetype == 'subpage') { + GeneratePage(config.subPages[vObj.pageId]); + } + } +}); + +//----------------------Begin Dimmode + +function ScreensaverDimmode(timeDimMode: DimMode) { + try { + if (Debug) console.log(rgb_dec565(HMIDark)) + if (Debug) console.log('Dimmode='+ timeDimMode.dimmodeOn) + if (timeDimMode.dimmodeOn != undefined ? timeDimMode.dimmodeOn : false) { + if (compareTime(timeDimMode.timeNight != undefined ? timeDimMode.timeNight : '22:00', timeDimMode.timeDay != undefined ? timeDimMode.timeDay : '07:00', 'not between', undefined)) { + SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); + if (Debug) console.log('Day Payload: ' + 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active ) + } else { + SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); + if (Debug) console.log('Night Payload: ' + 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active ) + } + } else { + SendToPanel({ payload: 'dimmode~' + config.dimmode + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); + } + } catch (err) { + console.warn('function ScreensaverDimmode: ' + err.message); + } +} + +async function InitWeatherForecast() { + try { + //----Möglichkeit, im Screensaver zwischen Accu-Weather Forecast oder selbstdefinierten Werten zu wählen--------------------------------- + if (existsState(NSPanel_Path + "ScreensaverInfo.weatherForecast") == false || + existsState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer") == false || + existsState(NSPanel_Path + "ScreensaverInfo.entityChangeTime") == false) { + await createStateAsync(NSPanel_Path + "ScreensaverInfo.weatherForecast", true, { type: 'boolean' }); + await createStateAsync(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer", true, { type: 'boolean' }); + await createStateAsync(NSPanel_Path + "ScreensaverInfo.entityChangeTime", 60, { type: 'number' }); + }; + } catch (err) { + console.warn('function InitWeatherForecast: ' + err.message); + } +} + +InitWeatherForecast(); + +async function InitDimmode() { + try { + // Screensaver nachts auf dunkel ("brightnessNight: z.B. 2") oder aus ("brightnessNight:0") + if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay')) { + await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay', { type: 'number' }); + await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay', { val: 8, ack: true }); + } + + if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_hourDay')) { + await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourDay', { type: 'number' }); + await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourDay', { val: 7, ack: true }); + } + + if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight')) { + await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight', { type: 'number' }); + await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight', { val: 1, ack: true }); + } + + if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_hourNight')) { + await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourNight', { type: 'number' }); + await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourNight', { val: 22, ack: true }); + } + + const vTimeDay = getState(NSPanel_Path + 'NSPanel_Dimmode_hourDay').val; + const vTimeNight = getState(NSPanel_Path + 'NSPanel_Dimmode_hourNight').val; + + const timeDimMode = { + dimmodeOn: true, + brightnessDay: getState(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay').val, + brightnessNight: getState(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight').val, + timeDay: (vTimeDay < 10) ? `0${vTimeDay}:00` : `${vTimeDay}:00`, + timeNight: (vTimeNight < 10) ? `0${vTimeNight}:00` : `${vTimeNight}:00` + }; + + // timeDimMode Day + schedule({ hour: getState(NSPanel_Path + 'NSPanel_Dimmode_hourDay').val, minute: 0 }, () => { + ScreensaverDimmode(timeDimMode); + }); + + // timeDimMode Night + schedule({ hour: getState(NSPanel_Path + 'NSPanel_Dimmode_hourNight').val, minute: 0 }, () => { + ScreensaverDimmode(timeDimMode); + }); + + ScreensaverDimmode(timeDimMode); + } catch (err) { + console.warn('function InitDimmode: ' + err.message); + } +} + +InitDimmode(); + +//--------------------End Dimmode + +// Datenpunkte für Nachricht an Screensaver +const screensaverNotifyHeading = NSPanel_Path + 'ScreensaverInfo.popupNotifyHeading'; +const screensaverNotifyText = NSPanel_Path + 'ScreensaverInfo.popupNotifyText'; + +// Datenpunkte für Nachricht popupNotify Page +const popupNotifyHeading = NSPanel_Path + 'popupNotify.popupNotifyHeading'; +const popupNotifyHeadingColor = NSPanel_Path + 'popupNotify.popupNotifyHeadingColor'; +const popupNotifyText = NSPanel_Path + 'popupNotify.popupNotifyText'; +const popupNotifyTextColor = NSPanel_Path + 'popupNotify.popupNotifyTextColor'; +const popupNotifyInternalName = NSPanel_Path + 'popupNotify.popupNotifyInternalName'; // Wird mit Button-Action zurückgeschrieben +const popupNotifyButton1TextColor = NSPanel_Path + 'popupNotify.popupNotifyButton1TextColor'; +const popupNotifyButton1Text = NSPanel_Path + 'popupNotify.popupNotifyButton1Text'; +const popupNotifyButton2TextColor = NSPanel_Path + 'popupNotify.popupNotifyButton2TextColor'; +const popupNotifyButton2Text = NSPanel_Path + 'popupNotify.popupNotifyButton2Text'; +const popupNotifySleepTimeout = NSPanel_Path + 'popupNotify.popupNotifySleepTimeout'; // in sek. / wenn 0, dann bleibt die Nachricht stehen +const popupNotifyAction = NSPanel_Path + 'popupNotify.popupNotifyAction'; // Antwort aus dem Panel true/false +const popupNotifyLayout = NSPanel_Path + 'popupNotify.popupNotifyLayout'; +const popupNotifyFontIdText = NSPanel_Path + 'popupNotify.popupNotifyFontIdText'; 1 - 5 +const popupNotifyIcon = NSPanel_Path + 'popupNotify.popupNotifyIcon'; 1 - 5 +const popupNotifyIconColor = NSPanel_Path + 'popupNotify.popupNotifyIconColor'; 1 - 5 + +async function InitPopupNotify() { + try { + if (!existsState(screensaverNotifyHeading)) { + await createStateAsync(screensaverNotifyHeading, { type: 'string' }); + await setStateAsync(screensaverNotifyHeading, { val: '', ack: true }); + } + + if (!existsState(screensaverNotifyText)) { + await createStateAsync(screensaverNotifyText, { type: 'string' }); + await setStateAsync(screensaverNotifyText, { val: '', ack: true }); + } + + await createStateAsync(popupNotifyHeading, { type: 'string' }); + await createStateAsync(popupNotifyHeadingColor, { type: 'string' }); + await createStateAsync(popupNotifyText, { type: 'string' }); + await createStateAsync(popupNotifyTextColor, { type: 'string' }); + await createStateAsync(popupNotifyInternalName, { type: 'string' }); + await createStateAsync(popupNotifyButton1Text, { type: 'string' }); + await createStateAsync(popupNotifyButton1TextColor, { type: 'string' }); + await createStateAsync(popupNotifyButton2Text, { type: 'string' }); + await createStateAsync(popupNotifyButton2TextColor, { type: 'string' }); + await createStateAsync(popupNotifySleepTimeout, { type: 'number' }); + await createStateAsync(popupNotifyAction, { type: 'boolean' }); + await createStateAsync(popupNotifyLayout, { type: 'number' }); + await createStateAsync(popupNotifyFontIdText, { type: 'number' }); + await createStateAsync(popupNotifyIcon, { type: 'string' }); + await createStateAsync(popupNotifyIconColor, { type: 'string' }); + + // Notification to screensaver + on({ id: [screensaverNotifyHeading, screensaverNotifyText], change: 'ne', ack: false }, async (obj) => { + const heading = getState(screensaverNotifyHeading).val; + const text = getState(screensaverNotifyText).val; + + setIfExists(config.panelSendTopic, `notify~${heading}~${text}`); + + if (obj.id) { + await setStateAsync(obj.id, { val: obj.state.val, ack: true }); // ack new value + } + }); + + // popupNotify - Notification an separate Seite + on({ id: [popupNotifyInternalName], change: 'ne' }, async (obj) => { + + var notification : string = '' + + let v_popupNotifyHeadingColor = (getState(popupNotifyHeadingColor).val != null) ? getState(popupNotifyHeadingColor).val : '65504'// Farbe Headline - gelb 65504 + let v_popupNotifyButton1TextColor = (getState(popupNotifyButton1TextColor).val != null) ? getState(popupNotifyButton1TextColor).val : '63488'// Farbe Headline - gelb 65504 + let v_popupNotifyButton2TextColor = (getState(popupNotifyButton2TextColor).val != null) ? getState(popupNotifyButton2TextColor).val : '2016'// Farbe Headline - gelb 65504 + let v_popupNotifyTextColor = (getState(popupNotifyTextColor).val != null) ? getState(popupNotifyTextColor).val : '65535'// Farbe Headline - gelb 65504 + let v_popupNotifyIconColor = (getState(popupNotifyIconColor).val != null) ? getState(popupNotifyIconColor).val : '65535'// Farbe Headline - gelb 65504 + let v_popupNotifyFontIdText = (getState(popupNotifyFontIdText).val != null) ? getState(popupNotifyFontIdText).val : '1' + let v_popupNotifyIcon = (getState(popupNotifyIcon).val != null) ? getState(popupNotifyIcon).val : 'alert' + + notification = 'entityUpdateDetail' + '~' + + getState(popupNotifyInternalName).val + '~' + + getState(popupNotifyHeading).val + '~' + + v_popupNotifyHeadingColor + '~' + + getState(popupNotifyButton1Text).val + '~' + + v_popupNotifyButton1TextColor + '~' + + getState(popupNotifyButton2Text).val + '~' + + v_popupNotifyButton2TextColor + '~' + + getState(popupNotifyText).val + '~' + + v_popupNotifyTextColor + '~' + + getState(popupNotifySleepTimeout).val; + + if (getState(popupNotifyLayout).val == 2) { + notification = notification + '~' + + v_popupNotifyFontIdText + '~' + + Icons.GetIcon(v_popupNotifyIcon) + '~' + + v_popupNotifyIconColor; + } + + setIfExists(config.panelSendTopic, 'pageType~popupNotify'); + setIfExists(config.panelSendTopic, notification); + + }); + } catch (err) { + console.warn('function InitPopupNotify: ' + err.message); + } +} + +InitPopupNotify(); + +let subscriptions: any = {}; +let screensaverEnabled: boolean = false; +let pageId = 0; + +// Neu für Subpages +let activePage = undefined; + +//Uhrzeit an NSPanel senden +schedule('* * * * *', () => { + try { + SendTime(); + } catch (err) { + console.warn('schedule: ' + err.message); + } +}); + +//Wechsel zwischen Screensaver Enities und WeatherForecast +schedule('*/' + getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val + ' * * * * *', () => { + try { + //WeatherForcast true/false Umschaltung verzögert + if (getState(NSPanel_Path + "ScreensaverInfo.popupNotifyHeading").val == '' && getState(NSPanel_Path + "ScreensaverInfo.popupNotifyText").val == '' && getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val == true && getState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer").val == true) { + setStateDelayed(NSPanel_Path + "ScreensaverInfo.weatherForecast", false, (getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val / 2 * 1000), false); + } else if (getState(NSPanel_Path + "ScreensaverInfo.popupNotifyHeading").val == '' && getState(NSPanel_Path + "ScreensaverInfo.popupNotifyText").val == '' && getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val == false && getState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer").val == true) { + setStateDelayed(NSPanel_Path + "ScreensaverInfo.weatherForecast", true, (getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val / 2 * 1000), false); + } + } catch (err) { + console.warn('schedule: ' + err.message); + } +}); + +function InitHWButton1Color() { + try { + if (config.mrIcon1ScreensaverEntity.ScreensaverEntity != null || config.mrIcon1ScreensaverEntity.ScreensaverEntity != undefined) { + on({id: config.mrIcon1ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) { + HandleScreensaverUpdate(); + }); + } + } catch (err) { + console.warn('function InitHWButton1Color: ' + err.message); + } +} +InitHWButton1Color(); + +function InitHWButton2Color() { + try { + if (config.mrIcon2ScreensaverEntity.ScreensaverEntity != null || config.mrIcon2ScreensaverEntity.ScreensaverEntity != undefined) { + on({id: config.mrIcon2ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) { + HandleScreensaverUpdate(); + }); + } + } catch (err) { + console.warn('function InitHWButton2Color: ' + err.message); + } +} +InitHWButton2Color(); + +//Wechsel zwischen Datenpunkten und Weather-Forecast im Screensaver +on({id: [].concat([NSPanel_Path + "ScreensaverInfo.weatherForecast"]), change: "ne"}, async function (obj) { + weatherForecast = obj.state.val; + HandleScreensaverUpdate(); +}); + +schedule('0 * * * *', () => { + SendDate(); +}); + +// 3:30 Uhr Startup durchführen und aktuelle TFT-Version empfangen +schedule({ hour: 3, minute: 30 }, async () => { + await setStateAsync(config.panelSendTopic, 'pageType~pageStartup'); +}); + +// Updates vergleichen aktuell alle 12 Stunden +schedule('{"time":{"start":"00:00","end":"23:59","mode":"hours","interval":12},"period":{"days":1}}', () => { + get_tasmota_status0(); + get_panel_update_data(); + check_updates(); +}); + +// Mit Start auf Updates checken +get_locales(); +setState(config.panelSendTopic, 'pageType~pageStartup'); +get_tasmota_status0(); +get_panel_update_data(); +check_updates(); + +//------------------Begin Update Functions + +function get_locales() { + try { + if (Debug) console.log('Requesting locales'); + request({ + url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/ioBroker/ioBroker_NSPanel_locales.json', + headers: { + 'User-Agent': 'ioBroker' + } + }, async (error, response, result) => { + try { + if (result) { + await createStateAsync(NSPanel_Path + 'NSPanel_locales_json', { type: 'string', role: 'json' }); + await setStateAsync(NSPanel_Path + 'NSPanel_locales_json', { val: result, ack: true }); + } + } catch (err) { + console.log('get_locales: ' + err.message); + } + }); + } catch (err) { + console.error('error requesting locales in function get_locales: ' + err.message); + } +} + +async function check_updates() { + try { + const desired_display_firmware_version = 43; + const berry_driver_version = 4; + + if (Debug) console.log('Check-Updates'); + // Tasmota-Firmware-Vergleich + if (existsObject(NSPanel_Path + 'Tasmota_Firmware.currentVersion') && existsObject(NSPanel_Path + 'Tasmota_Firmware.onlineVersion')) { + if (getState(NSPanel_Path + 'Tasmota_Firmware.currentVersion').val !== getState(NSPanel_Path + 'Tasmota_Firmware.onlineVersion').val) { + if (existsState(NSPanel_Path + 'NSPanel_autoUpdate')) { + if (getState(NSPanel_Path + 'NSPanel_autoUpdate').val) { + if (Debug) console.log('Auto-Updates eingeschaltet - Update wird durchgeführt'); + // Tasmota Upgrade durchführen + update_tasmota_firmware(); + // Aktuelle Tasmota Version = Online Tasmota Version + + await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.currentVersion', { val: getState(NSPanel_Path + 'Tasmota_Firmware.onlineVersion').val, ack: true }); + } else { + // Auf Tasmota-Updates hinweisen + if (Debug) console.log('Automatische Updates aus'); + + const InternalName = 'TasmotaFirmwareUpdate'; + const Headline = 'Tasmota-Firmware Update'; + const Text = ['Es ist eine neue Version der Tasmota-Firmware', '\r\n', 'verfügbar', '\r\n', '\r\n', 'Installierte Version: ' + String(getState((String(NSPanel_Path) + 'Tasmota_Firmware.currentVersion')).val), '\r\n', 'Verfügbare Version: ' + String(getState((String(NSPanel_Path) + 'Tasmota_Firmware.onlineVersion')).val), '\r\n', '\r\n', 'Upgrade durchführen?'].join(''); + const Button1 = 'Nein'; + const Button2 = 'Ja'; + const Timeout = 0; + + await setStateAsync(popupNotifyHeading, { val: Headline, ack: false }); + await setStateAsync(popupNotifyText, { val: [formatDate(getDateObject((new Date().getTime())), 'TT.MM.JJJJ SS:mm:ss'), '\r\n', '\r\n', Text].join(''), ack: false }); + await setStateAsync(popupNotifyButton1Text, { val: Button1, ack: false }); + await setStateAsync(popupNotifyButton2Text, { val: Button2, ack: false }); + await setStateAsync(popupNotifySleepTimeout, { val: Timeout, ack: false }); + await setStateAsync(popupNotifyInternalName, { val: InternalName, ack: false }); + } + } + } else { + if (Debug) console.log('Tasmota-Version auf NSPanel aktuell'); + } + } + + // Tasmota-Berry-Driver-Vergleich + if (existsObject(NSPanel_Path + 'Berry_Driver.currentVersion')) { + if (getState(NSPanel_Path + 'Berry_Driver.currentVersion').val < berry_driver_version) { + if (existsState(NSPanel_Path + 'NSPanel_autoUpdate')) { + if (getState(NSPanel_Path + 'NSPanel_autoUpdate').val) { + // Tasmota Berry-Driver Update durchführen + update_berry_driver_version(); + // Aktuelle Berry-Driver Version = Online Berry-Driver Version + await setStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', { val: getState(NSPanel_Path + 'Berry_Driver.onlineVersion').val, ack: true }); + + if (Debug) console.log('Berry-Driver automatisch aktualisiert'); + } else { + //Auf BerryDriver-Update hinweisen + if (Debug) console.log('Automatische Updates aus'); + + const InternalName = 'BerryDriverUpdate'; + const Headline = 'Berry-Driver Update'; + const Text = ['Es ist eine neue Version des Berry-Drivers', '\r\n', '(Tasmota) verfügbar', '\r\n', '\r\n', 'Installierte Version: ' + String(getState((String(NSPanel_Path) + 'Berry_Driver.currentVersion')).val), '\r\n', 'Verfügbare Version: ' + String(berry_driver_version), '\r\n', '\r\n', 'Upgrade durchführen?'].join(''); + const Button1 = 'Nein'; + const Button2 = 'Ja'; + const Timeout = 0; + + await setStateAsync(popupNotifyHeading, { val: Headline, ack: false }); + await setStateAsync(popupNotifyText, { val: [formatDate(getDateObject((new Date().getTime())), 'TT.MM.JJJJ SS:mm:ss'), '\r\n', '\r\n', Text].join(''), ack: false }); + await setStateAsync(popupNotifyButton1Text, { val: Button1, ack: false }); + await setStateAsync(popupNotifyButton2Text, { val: Button2, ack: false }); + await setStateAsync(popupNotifySleepTimeout, { val: Timeout, ack: false }); + await setStateAsync(popupNotifyInternalName, { val: InternalName, ack: false }); + } + } + } else { + if (Debug) console.log('Berry-Driver auf NSPanel aktuell'); + } + } + + // TFT-Firmware-Vergleich + if (existsObject(NSPanel_Path + 'Display_Firmware.currentVersion')) { + if (parseInt(getState(NSPanel_Path + 'Display_Firmware.currentVersion').val) < desired_display_firmware_version) { + if (existsState(NSPanel_Path + 'NSPanel_autoUpdate')) { + if (getState(NSPanel_Path + 'NSPanel_autoUpdate').val) { + // TFT-Firmware Update durchführen + update_tft_firmware(); + // Aktuelle TFT-Firmware Version = Online TFT-Firmware Version + await setStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { val: getState(NSPanel_Path + 'Display_Firmware.onlineVersion').val, ack: true }); + + if (Debug) console.log('Display_Firmware automatisch aktualisiert'); + } else { + // Auf TFT-Firmware hinweisen + if (Debug) console.log('Automatische Updates aus'); + + const InternalName = 'TFTFirmwareUpdate'; + const Headline = 'TFT-Firmware Update'; + const Text = ['Es ist eine neue Version der TFT-Firmware', '\r\n', 'verfügbar', '\r\n', '\r\n', 'Installierte Version: ' + String(getState((String(NSPanel_Path) + 'Display_Firmware.currentVersion')).val), '\r\n', 'Verfügbare Version: ' + String(desired_display_firmware_version), '\r\n', '\r\n', 'Upgrade durchführen?'].join(''); + const Button1 = 'Nein'; + const Button2 = 'Ja'; + const Timeout = 0; + + await setStateAsync(popupNotifyHeading, { val: Headline, ack: false }); + await setStateAsync(popupNotifyText, { val: [formatDate(getDateObject((new Date().getTime())), 'TT.MM.JJJJ SS:mm:ss'), '\r\n', '\r\n', Text].join(''), ack: false }); + await setStateAsync(popupNotifyButton1Text, { val: Button1, ack: false }); + await setStateAsync(popupNotifyButton2Text, { val: Button2, ack: false }); + await setStateAsync(popupNotifySleepTimeout, { val: Timeout, ack: false }); + await setStateAsync(popupNotifyInternalName, { val: InternalName, ack: false }); + } + } + } else { + if (Debug) console.log('Display_Firmware auf NSPanel aktuell'); + } + } + } catch (err) { + console.warn('function check_updates: ' + err.message); + } +} + +on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async function (obj) { + try { + const val = obj.state ? obj.state.val : false; + + if (!val) { + manually_Update = false; + if (Debug) console.log('Es wurde Button1 gedrückt'); + } else if (val) { + if (manually_Update) { + const internalName = getState(NSPanel_Path + 'popupNotify.popupNotifyInternalName').val; + + if (internalName == 'TasmotaFirmwareUpdate') { + update_tasmota_firmware(); + } else if (internalName == 'BerryDriverUpdate') { + update_berry_driver_version(); + } else if (internalName == 'TFTFirmwareUpdate') { + update_tft_firmware(); + } + } + + if (Debug) console.log('Es wurde Button2 gedrückt'); + } + } catch (err) { + console.warn('Trigger popupNotifyAction: ' + err.message); + } +}); + +async function get_panel_update_data() { + try { + await createStateAsync(NSPanel_Path + 'NSPanel_autoUpdate', false, { read: true, write: true, name: 'Auto-Update', type: 'boolean', def: false }); + + await createStateAsync(NSPanel_Path + 'NSPanel_ipAddress', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'NSPanel_ipAddress', { val: get_current_tasmota_ip_address(), ack: true }); + + get_online_tasmota_firmware_version(); + get_current_berry_driver_version(); + get_online_berry_driver_version(); + check_version_tft_firmware(); + check_online_display_firmware(); + } catch (err) { + console.warn('function get_panel_update_data: ' + err.message); + } +} + +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); + + if (Debug) console.log(`get_current_tasmota_ip_address: ${infoObj.Info2.IPAddress}`); + + return infoObj.Info2.IPAddress; + } catch (err) { + console.warn('function get_current_tasmota_ip_address: ' + err.message); + } +} + +function get_online_tasmota_firmware_version() { + try { + if (Debug) console.log('Requesting tasmota firmware version'); + request({ + url: 'https://api.github.com/repositories/80286288/releases/latest', + headers: { + 'User-Agent': 'ioBroker' + } + }, async (error, response, result) => { + try { + const Tasmota_JSON = JSON.parse(result); // JSON Resultat in Variable Schreiben + const TasmotaTagName = Tasmota_JSON.tag_name; // JSON nach "tag_name" filtern und in Variable schreiben + const TasmotaVersionOnline = TasmotaTagName.replace(/v/i, ''); // Aus Variable überflüssiges "v" filtern und in Release-Variable schreiben + + await createStateAsync(NSPanel_Path + 'Tasmota_Firmware.onlineVersion', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.onlineVersion', { val: TasmotaVersionOnline, ack: true }); + } catch (err) { + console.log('get_online_tasmota_firmware_version: ' + err.message); + } + }); + } catch (err) { + console.warn('error requesting firmware in function get_online_tasmota_firmware_version: ' + err.message); + } +} + +function get_current_berry_driver_version() { + try { + if (Debug) console.log('Requesting current berry driver version'); + request({ + url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=GetDriverVersion`, + headers: { + 'User-Agent': 'ioBroker' + } + }, async (error, response, result) => { + try { + await createStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', { type: 'number' }); + await setStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', { val: JSON.parse(result).nlui_driver_version, ack: true }); + } catch (err) { + console.warn('get_current_berry_driver_version: ' + err.message); + } + }); + } catch (err) { + console.warn('error requesting firmware in function get_current_berry_driver_version: ' + err.message); + } +} + +function get_tasmota_status0() { + try { + if (Debug) console.log('Requesting tasmota status0'); + request({ + url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=Status0`, + headers: { + 'User-Agent': 'ioBroker' + } + }, async (error, response, result) => { + await createStateAsync(NSPanel_Path + 'Tasmota_Firmware.currentVersion', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Uptime', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Version', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Hardware', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Wifi.AP', { type: 'number' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Wifi.SSId', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Wifi.BSSId', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Wifi.Channel', { type: 'number' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Wifi.Mode', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Wifi.RSSI', { type: 'number' }); + await createStateAsync(NSPanel_Path + 'Tasmota.Wifi.Signal', { type: 'number' }); + + try { + const Tasmota_JSON = JSON.parse(result); + const tasmoVersion = Tasmota_JSON.StatusFWR.Version.indexOf('(') > -1 ? Tasmota_JSON.StatusFWR.Version.split('(')[0] : Tasmota_JSON.StatusFWR.Version; + + await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.currentVersion', { val: tasmoVersion, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Uptime', { val: Tasmota_JSON.StatusPRM.Uptime, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Version', { val: Tasmota_JSON.StatusFWR.Version, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Hardware', { val: Tasmota_JSON.StatusFWR.Hardware, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.AP', { val: Tasmota_JSON.StatusSTS.Wifi.AP, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.SSId', { val: Tasmota_JSON.StatusSTS.Wifi.SSId, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.BSSId', { val: Tasmota_JSON.StatusSTS.Wifi.BSSId, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.Channel', { val: Tasmota_JSON.StatusSTS.Wifi.Channel, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.Mode', { val: Tasmota_JSON.StatusSTS.Wifi.Mode, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.RSSI', { val: Tasmota_JSON.StatusSTS.Wifi.RSSI, ack: true }); + await setStateAsync(NSPanel_Path + 'Tasmota.Wifi.Signal', { val: Tasmota_JSON.StatusSTS.Wifi.Signal, ack: true }); + } catch (err) { + console.warn('get_tasmota_status0' + err.message); + } + }); + } catch (err) { + console.warn('error requesting firmware in function get_tasmota_status0: ' + err.message); + } +} + +function get_online_berry_driver_version() { + try { + if (Debug) console.log('Requesting online berry driver version'); + request({ + url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be', + headers: { + 'User-Agent': 'ioBroker' + } + }, async (error, response, result) => { + if (result) { + try { + const BerryDriverVersionOnline = result.substring((result.indexOf('version_of_this_script = ') + 24), result.indexOf('version_of_this_script = ') + 27).replace(/\s+/g, ''); + await createStateAsync(NSPanel_Path + 'Berry_Driver.onlineVersion', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'Berry_Driver.onlineVersion', { val: BerryDriverVersionOnline, ack: true }); + } catch (err) { + console.log('get_online_berry_driver_version' + err.message); + } + } + }); + } catch (err) { + console.warn('error requesting firmware in function get_online_berry_driver_version: ' + err.message); + } +} + +function check_version_tft_firmware() { + try { + if (Debug) console.log('Requesting online TFT version'); + request({ + url: 'https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/latest', + headers: { + 'User-Agent': 'ioBroker' + } + }, async (error, response, result) => { + if (result) { + try { + var NSPanel_JSON = JSON.parse(result); // JSON Resultat in Variable Schreiben + var NSPanelTagName = NSPanel_JSON.tag_name; // created_at; published_at; name ; draft ; prerelease + var NSPanelVersion = NSPanelTagName.replace(/v/i, ''); // Aus Variable überflüssiges "v" filtern und in Release-Variable schreiben + + await createStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { val: NSPanelVersion, ack: true }); + } catch (err) { + console.log('check_version_tft_firmware: ' + err.message); + } + } + }); + } catch (err) { + console.warn('error requesting firmware in function check_version_tft_firmware: ' + err.message); + } +} + +function check_online_display_firmware() { + try { + if (Debug) console.log('Requesting online firmware version'); + request({ + url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py', + headers: { + 'User-Agent': 'ioBroker' + } + }, async (error, response, result) => { + if (result) { + try { + let desired_display_firmware_version = result.substring((result.indexOf('desired_display_firmware_version =') + 34), result.indexOf('desired_display_firmware_version =') + 38).replace(/\s+/g, ''); + + await createStateAsync(NSPanel_Path + 'Display_Firmware.onlineVersion', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'Display_Firmware.onlineVersion', { val: desired_display_firmware_version, ack: true }); + } catch (err) { + console.warn('check_online_display_firmware' + err.message); + } + } + }); + } catch (err) { + console.warn('error requesting firmware in function check_online_display_firmware: ' + err.message); + } +} + +on({ id: config.panelRecvTopic }, async (obj) => { + if (obj.state.val.startsWith('\{"CustomRecv":')) { + try { + var json = JSON.parse(obj.state.val); + var split = json.CustomRecv.split(','); + if (split[0] == 'event' && split[1] == 'startup') { + await createStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'NSPanel_Version', { type: 'string' }); + + await setStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { val: split[2], ack: true }); + await setStateAsync(NSPanel_Path + 'NSPanel_Version', { val: split[3], ack: true }); + } + } catch (err) { + console.warn('error rceiving CustomRecv: ' + err.message); + } + } +}); + +function update_berry_driver_version() { + try { + request({ + url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=Backlog UpdateDriverVersion https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; Restart 1`, + headers: { + 'User-Agent': 'ioBroker' + } + }, async function (error, response, result) { + + }); + } catch (err) { + console.warn('error at function update_berry_driver_version: ' + err.message); + } +} + +function update_tft_firmware() { + const tft_version: string = 'v3.5.0'; + const desired_display_firmware_url = `http://nspanel.pky.eu/lovelace-ui/github/nspanel-${tft_version}.tft`; + try { + request({ + url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=FlashNextion ${desired_display_firmware_url}`, + headers: { + 'User-Agent': 'ioBroker' + } + }, async function (error, response, result) { + await createStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { type: 'string' }); + await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { val: tft_version, ack: true }); + }); + } catch (err) { + console.warn('error at function update_tft_firmware: ' + err.message); + } +} + +function update_tasmota_firmware() { + try { + request({ + url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=Upgrade 1`, + headers: { + 'User-Agent': 'ioBroker' + } + }, async function (error, response, result) { + }); + } catch (err) { + console.warn('error at function update_tasmota_firmware: ' + err.message); + } +} +//------------------End Update Functions + +// Only monitor the extra nodes if present +var updateArray: string[] = []; + +if (config.firstScreensaverEntity !== null && config.firstScreensaverEntity.ScreensaverEntity != null && existsState(config.firstScreensaverEntity.ScreensaverEntity)) { + updateArray.push(config.firstScreensaverEntity.ScreensaverEntity) +} +if (config.secondScreensaverEntity !== null && config.secondScreensaverEntity.ScreensaverEntity != null && existsState(config.secondScreensaverEntity.ScreensaverEntity)) { + updateArray.push(config.secondScreensaverEntity.ScreensaverEntity) +} +if (config.thirdScreensaverEntity !== null && config.thirdScreensaverEntity.ScreensaverEntity != null && existsState(config.thirdScreensaverEntity.ScreensaverEntity)) { + updateArray.push(config.thirdScreensaverEntity.ScreensaverEntity) +} +if (config.fourthScreensaverEntity !== null && config.fourthScreensaverEntity.ScreensaverEntity != null && existsState(config.fourthScreensaverEntity.ScreensaverEntity)) { + updateArray.push(config.fourthScreensaverEntity.ScreensaverEntity) +} +if (updateArray.length > 0) { + on(updateArray, () => { + HandleScreensaverUpdate(); + }); +} + +on({ id: config.panelRecvTopic }, function (obj) { + try { + if (obj.state.val.startsWith('\{"CustomRecv":')) { + try { + var json = JSON.parse(obj.state.val); + + var split = json.CustomRecv.split(','); + HandleMessage(split[0], split[1], parseInt(split[2]), split); + } catch (err) { + console.warn(err.message); + } + } + } catch (err) { + console.warn('Trigger panelRecTopic: ' + err.message); + } +}); + +function SendToPanel(val: Payload | Payload[]): void { + try { + if (Array.isArray(val)) { + val.forEach(function (id, i) { + setState(config.panelSendTopic, id.payload); + if (Debug) console.log(id.payload); + }); + } else { + setState(config.panelSendTopic, val.payload); + } + } catch (err) { + console.warn('function SendToPanel: ' + err.message); + } +} + +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) console.log(activePage); + if (NSPanel_Path == getState(NSPanel_Alarm_Path + 'Alarm.PANEL').val) { + GeneratePage(activePage); + } + } + } catch (err) { + console.warn('Trigger AlarmState: ' + err.message); + } +}); + +function HandleMessage(typ: string, method: string, page: number, words: Array): void { + try { + if (typ == 'event') { + switch (method) { + case 'startup': + screensaverEnabled = false; + UnsubscribeWatcher(); + HandleStartupProcess(); + pageId = 0; + GeneratePage(config.pages[0]); + break; + case 'sleepReached': + screensaverEnabled = true; + if (pageId < 0) + pageId = 0; + HandleScreensaver(); + break; + case 'pageOpenDetail': + screensaverEnabled = false; + UnsubscribeWatcher(); + let pageItem = findPageItem(words[3]); + if (pageItem !== undefined) + SendToPanel(GenerateDetailPage(words[2], pageItem)); + case 'buttonPress2': + screensaverEnabled = false; + HandleButtonEvent(words); + if (Debug) console.log(words[0] + ' - ' + words[1] + ' - ' + words[2] + ' - ' + words[3] + ' - ' + words[4]); + break; + case 'button1': + case 'button2': + screensaverEnabled = false; + HandleHardwareButton(method); + default: + break; + } + } + } catch (err) { + console.warn('function HandleMessage: ' + err.message); + } +} + +function findPageItem(searching: String): PageItem { + try { + + let pageItem = activePage.items.find(e => e.id === searching); + + if (pageItem !== undefined) { + return pageItem; + } + + config.subPages.every(sp => { + pageItem = sp.items.find(e => e.id === searching); + if (pageItem !== undefined) { + return false; + } + return true; + }); + + return pageItem; + } catch (err) { + console.warn('function findPageItem: ' + err.message); + } +} + +function GeneratePage(page: Page): void { + try { + activePage = page; + switch (page.type) { + case 'cardEntities': + SendToPanel(GenerateEntitiesPage(page)); + break; + case 'cardThermo': + SendToPanel(GenerateThermoPage(page)); + break; + case 'cardGrid': + SendToPanel(GenerateGridPage(page)); + break; + case 'cardMedia': + SendToPanel(GenerateMediaPage(page)); + break; + case 'cardAlarm': + SendToPanel(GenerateAlarmPage(page)); + break; + case 'cardQR': + SendToPanel(GenerateQRPage(page)); + break; + case 'cardPower': + SendToPanel(GeneratePowerPage(page)); + break; + } + } catch (err) { + console.warn('function GeneratePage: ' + err.message); + } +} + +function HandleHardwareButton(method: string): void { + try { + let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | PageQR | PagePower); + if (config.button1Page !== null && method == 'button1') { + page = config.button1Page; + pageId = -1; + } else if (config.button2Page !== null && method == 'button2') { + page = config.button2Page; + pageId = -2; + } else { + return; + } + + GeneratePage(page); + } catch (err) { + console.warn('function HandleHardwareButton: ' + err.message); + } +} + +function HandleStartupProcess(): void { + SendDate(); + SendTime(); + SendToPanel({ payload: 'timeout~' + config.timeoutScreensaver }); +} + +function SendDate(): void { + try { + const date = new Date(); + const options: any = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; + const _SendDate = date.toLocaleDateString(config.locale, options); + + SendToPanel({ payload: 'date~' + _SendDate }); + } catch (err) { + console.warn('function SendDate: ' + err.message); + } +} + +function SendTime(): void { + try { + const d = new Date(); + const hr = (d.getHours() < 10 ? '0' : '') + d.getHours(); + const min = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes(); + + SendToPanel({ payload: 'time~' + hr + ':' + min }); + } catch (err) { + console.warn('function SendTime: ' + err.message); + } +} + +function GenerateEntitiesPage(page: PageEntities): Payload[] { + try { + var out_msgs: Array = []; + out_msgs = [{ payload: 'pageType~cardEntities' }] + out_msgs.push({ payload: GeneratePageElements(page) }); + return out_msgs + } catch (err) { + console.warn('function GenerateEntitiesPage: ' + err.message); + } +} + +function GenerateGridPage(page: PageGrid): Payload[] { + try { + var out_msgs: Array = []; + out_msgs = [{ payload: 'pageType~cardGrid' }] + out_msgs.push({ payload: GeneratePageElements(page) }); + return out_msgs + } catch (err) { + console.warn('function GenerateGridPage: ' + err.message); + } +} + +function GeneratePageElements(page: Page): string { + try { + activePage = page; + let maxItems = 0; + switch (page.type) { + case 'cardThermo': + maxItems = 1; + break; + case 'cardAlarm': + maxItems = 1; + break; + case 'cardMedia': + maxItems = 1; + break; + case 'cardQR': + maxItems = 1; + break; + case 'cardEntities': + if (getState(NSPanel_Path + 'NSPanel_Version').val == 'eu') { + maxItems = 4; + } else { + maxItems = 5; + } + break; + case 'cardGrid': + maxItems = 6; + break; + } + + let pageData = 'entityUpd~' + page.heading + '~' + GetNavigationString(pageId); + + for (let index = 0; index < maxItems; index++) { + if (page.items[index] !== undefined) { + pageData += CreateEntity(page.items[index], index + 1, page.useColor); + } + } + return pageData; + } catch (err) { + console.warn('function GeneratePageElements: ' + err.message); + } +} + +function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string { + try { + var iconId = '0'; + if (pageItem.id == 'delete') { + return '~delete~~~~~'; + } + + var name: string; + var type: string; + + // ioBroker + if (existsObject(pageItem.id) || pageItem.navigate === true) { + var iconColor = rgb_dec565(config.defaultColor); + + if (pageItem.navigate) { + type = 'button'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('gesture-tap-button'); + iconColor = GetIconColor(pageItem, true, useColors); + let buttonText = pageItem.buttonText !== undefined ? pageItem.buttonText : 'PRESS'; + return '~' + type + '~' + 'navigate.' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + pageItem.name + '~' + buttonText; + } + + let o = getObject(pageItem.id) + var val = null; + + if (existsState(pageItem.id + '.GET')) { + val = getState(pageItem.id + '.GET').val; + RegisterEntityWatcher(pageItem.id + '.GET'); + } else if (existsState(pageItem.id + '.SET')) { + val = getState(pageItem.id + '.SET').val; + RegisterEntityWatcher(pageItem.id + '.SET'); + } + + // Fallback if no name is given + name = pageItem.name !== undefined ? pageItem.name : o.common.name.de; + + switch (o.common.role) { + case 'socket': + case 'light': + type = 'light'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); + var iconId2 = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); + var optVal = '0'; + + if (val === true || val === 'true') { + optVal = '1'; + iconColor = GetIconColor(pageItem, true, useColors); + } else { + iconColor = GetIconColor(pageItem, false, useColors); + if (pageItem.icon !== undefined) { + if (pageItem.icon2 !== undefined) { + iconId = iconId2; + } + } + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + optVal; + + case 'hue': + type = 'light'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); + var optVal = '0'; + + if (existsState(pageItem.id + '.ON_ACTUAL')) { + val = getState(pageItem.id + '.ON_ACTUAL').val; + RegisterEntityWatcher(pageItem.id + '.ON_ACTUAL'); + } + + if (val === true || val === 'true') { + optVal = '1'; + iconColor = GetIconColor(pageItem, existsState(pageItem.id + '.DIMMER') ? 100 - getState(pageItem.id + '.DIMMER').val : true, useColors); + } + + if (pageItem.interpolateColor != undefined && pageItem.interpolateColor == true) { + if (existsState(pageItem.id + '.HUE')) { + if (getState(pageItem.id + '.HUE').val != null) { + let huecolor = hsv2rgb(getState(pageItem.id + '.HUE').val, 1, 1); + let rgb = { red: Math.round(huecolor[0]), green: Math.round(huecolor[1]), blue: Math.round(huecolor[2]) }; + iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); + // RegisterDetailEntityWatcher(id + '.HUE'); + } + } + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + optVal; + + case 'ct': + type = 'light'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); + var optVal = '0'; + + if (existsState(pageItem.id + '.ON')) { + val = getState(pageItem.id + '.ON').val; + RegisterEntityWatcher(pageItem.id + '.ON'); + } + + if (val === true || val === 'true') { + optVal = '1'; + iconColor = GetIconColor(pageItem, existsState(pageItem.id + '.DIMMER') ? 100 - getState(pageItem.id + '.DIMMER').val : true, useColors); + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + optVal; + + case 'rgb': + type = 'light'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); + var optVal = '0'; + + if (existsState(pageItem.id + '.ON_ACTUAL')) { + val = getState(pageItem.id + '.ON_ACTUAL').val; + RegisterEntityWatcher(pageItem.id + '.ON_ACTUAL'); + } + + if (val === true || val === 'true') { + optVal = '1'; + iconColor = GetIconColor(pageItem, existsState(pageItem.id + '.DIMMER') ? 100 - getState(pageItem.id + '.DIMMER').val : true, useColors); + } + + if (existsState(pageItem.id + '.RED') && existsState(pageItem.id + '.GREEN') && existsState(pageItem.id + '.BLUE')) { + if (getState(pageItem.id + '.RED').val != null && getState(pageItem.id + '.GREEN').val != null && getState(pageItem.id + '.BLUE').val != null) { + let rgbRed = getState(pageItem.id + '.RED').val; + let rgbGreen = getState(pageItem.id + '.GREEN').val; + let rgbBlue = getState(pageItem.id + '.BLUE').val; + let rgb = { red: Math.round(rgbRed), green: Math.round(rgbGreen), blue: Math.round(rgbBlue) }; + iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); + } + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + optVal; + + case 'rgbSingle': + type = 'light'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); + var optVal = '0'; + + if (existsState(pageItem.id + '.ON_ACTUAL')) { + val = getState(pageItem.id + '.ON_ACTUAL').val; + RegisterEntityWatcher(pageItem.id + '.ON_ACTUAL'); + } + + if (val === true || val === 'true') { + optVal = '1' + iconColor = GetIconColor(pageItem, existsState(pageItem.id + '.DIMMER') ? 100 - getState(pageItem.id + '.DIMMER').val : true, useColors); + } + + if (existsState(pageItem.id + '.RGB')) { + if (getState(pageItem.id + '.RGB').val != null) { + var hex = getState(pageItem.id + '.RGB').val; + var hexRed = parseInt(hex[1] + hex[2], 16); + var hexGreen = parseInt(hex[3] + hex[4], 16); + var hexBlue = parseInt(hex[5] + hex[6], 16); + let rgb = { red: Math.round(hexRed), green: Math.round(hexGreen), blue: Math.round(hexBlue) }; + iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); + } + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + optVal; + + case 'dimmer': + type = 'light'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); + var optVal = '0'; + + if (existsState(pageItem.id + '.ON_ACTUAL')) { + val = getState(pageItem.id + '.ON_ACTUAL').val; + RegisterEntityWatcher(pageItem.id + '.ON_ACTUAL'); + } else if (existsState(pageItem.id + '.ON_SET')) { + val = getState(pageItem.id + '.ON_SET').val; + RegisterEntityWatcher(pageItem.id + '.ON_SET'); + } + + if (val === true || val === 'true') { + optVal = '1'; + iconColor = GetIconColor(pageItem, existsState(pageItem.id + '.ACTUAL') ? 100 - getState(pageItem.id + '.ACTUAL').val : true, useColors); + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + optVal; + + case 'blind': + type = 'shutter'; + 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); + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~'; + + case 'door': + case 'window': + type = 'text'; + + if (existsState(pageItem.id + '.ACTUAL')) { + if (getState(pageItem.id + '.ACTUAL').val) { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'door' ? Icons.GetIcon('door-open') : Icons.GetIcon('window-open-variant'); + iconColor = GetIconColor(pageItem, false, useColors); + var windowState = findLocale('window', 'opened'); + } else { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'door' ? Icons.GetIcon('door-closed') : Icons.GetIcon('window-closed-variant'); + //iconId = Icons.GetIcon('window-closed-variant'); + iconColor = GetIconColor(pageItem, true, useColors); + var windowState = findLocale('window', 'closed'); + } + + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + windowState; + + case 'info': + + case 'humidity': + + case 'temperature': + + case 'value.temperature': + + case 'value.humidity': + + case 'sensor.door': + + case 'sensor.window': + + case 'thermostat': + type = 'text'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'value.temperature' || o.common.role == 'thermostat' ? Icons.GetIcon('thermometer') : Icons.GetIcon('information-outline'); + let unit = ''; + var optVal = '0'; + + if (existsState(pageItem.id + '.ON_ACTUAL')) { + optVal = getState(pageItem.id + '.ON_ACTUAL').val; + unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + '.ON_ACTUAL'); + RegisterEntityWatcher(pageItem.id + '.ON_ACTUAL'); + } else if (existsState(pageItem.id + '.ACTUAL')) { + optVal = getState(pageItem.id + '.ACTUAL').val; + unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + '.ACTUAL'); + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); + } + + if (o.common.role == 'value.temperature') { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('thermometer'); + } + + iconColor = GetIconColor(pageItem, parseInt(optVal), useColors); + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + optVal + ' ' + unit; + + case 'buttonSensor': + case 'button': + type = 'button'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('gesture-tap-button'); + iconColor = GetIconColor(pageItem, true, useColors); + let buttonText = pageItem.buttonText !== undefined ? pageItem.buttonText : 'PRESS'; + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + buttonText; + + case 'lock': + type = 'button'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock'); + iconColor = GetIconColor(pageItem, true, useColors); + + if (existsState(pageItem.id + '.ACTUAL')) { + if (getState(pageItem.id + '.ACTUAL').val) { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock'); + iconColor = GetIconColor(pageItem, true, useColors); + var lockState = findLocale('lock', 'UNLOCK'); + } else { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock-open-variant'); + iconColor = GetIconColor(pageItem, false, useColors); + var lockState = findLocale('lock', 'LOCK'); + } + lockState = pageItem.buttonText !== undefined ? pageItem.buttonText : lockState; + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + lockState; + + case 'slider': + type = 'number'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('plus-minus-variant'); + + if (existsState(pageItem.id + '.SET')) { + val = getState(pageItem.id + '.SET').val; + RegisterEntityWatcher(pageItem.id + '.SET'); + } + + if (existsState(pageItem.id + '.ACTUAL')) { + val = getState(pageItem.id + '.ACTUAL').val; + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); + } + + iconColor = GetIconColor(pageItem, false, useColors) + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + val + '|' + pageItem.minValue + '|' + pageItem.maxValue; + + case 'volumeGroup': + case 'volume': + type = 'number'; + if (existsState(pageItem.id + '.SET')) { + val = getState(pageItem.id + '.SET').val; + RegisterEntityWatcher(pageItem.id + '.SET'); + } + if (existsState(pageItem.id + '.ACTUAL')) { + val = getState(pageItem.id + '.ACTUAL').val; + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); + } + + iconColor = GetIconColor(pageItem, false, useColors) + if (existsState(pageItem.id + '.MUTE')) { + getState(pageItem.id + '.MUTE').val ? iconColor = GetIconColor(pageItem, false, useColors) : iconColor = GetIconColor(pageItem, true, useColors); + RegisterEntityWatcher(pageItem.id + '.MUTE'); + } + + if (val > 0 && val <= 33 && !getState(pageItem.id + '.MUTE').val) { + iconId = Icons.GetIcon('volume-low'); + } else if (val > 33 && val <= 66 && !getState(pageItem.id + '.MUTE').val) { + iconId = Icons.GetIcon('volume-medium'); + } else if (val > 66 && val <= 100 && !getState(pageItem.id + '.MUTE').val) { + iconId = Icons.GetIcon('volume-high'); + } else { + iconId = Icons.GetIcon('volume-mute'); + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + val + '|' + pageItem.minValue + '|' + pageItem.maxValue; + + case 'warning': + type = 'text'; + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('alert-outline'); + iconColor = getState(([pageItem.id, '.LEVEL'].join(''))).val; + let itemName = getState(([pageItem.id, '.TITLE'].join(''))).val; + let itemInfo = getState(([pageItem.id, '.INFO'].join(''))).val; + + return '~' + type + '~' + itemName + '~' + iconId + '~' + iconColor + '~' + itemName + '~' + itemInfo; + + default: + return '~delete~~~~~'; + } + } + return '~delete~~~~~'; + } catch (err) { + console.warn('function CreateEntity: ' + err.message); + } +} + +function findLocale(controlsObject: string, controlsState: string): string { + const locale = config.locale; + const strJson = getState(NSPanel_Path + 'NSPanel_locales_json').val; + + if (Debug) console.log(controlsObject + ' - ' + controlsState); + + try { + const obj = JSON.parse(strJson); + const strLocale = obj[controlsObject][controlsState][locale]; + + if (strLocale != undefined) { + return strLocale; + } else { + return controlsState; + } + + } catch (err) { + if (err.message.substring(0, 35) == 'Cannot read properties of undefined') { + if (Debug) console.log('function findLocale: missing translation: ' + controlsObject + ' - ' + controlsState); + } else { + console.warn('function findLocale: ' + err.message); + } + return controlsState; + } +} + +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; + let minValue = pageItem.minValueBrightness !== undefined ? pageItem.minValueBrightness : 0; + if (pageItem.maxValue !== undefined) maxValue = pageItem.maxValue; + if (pageItem.minValue !== undefined) minValue = pageItem.minValue; + value = value > maxValue ? maxValue : value; + value = value < minValue ? minValue : value; + + return rgb_dec565( + Interpolate( + pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor, + pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor, + scale(value, minValue, maxValue, 0, 1) + ) + ); + } + + if ((pageItem.useColor || useColors) && ((typeof (value) === 'boolean' && value) || value > (pageItem.minValueBrightness !== undefined ? pageItem.minValueBrightness : 0))) { + return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor) + } + + return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor); + } catch (err) { + console.warn('function GetIconColor: ' + err.message); + } +} + +function RegisterEntityWatcher(id: string): void { + try { + if (subscriptions.hasOwnProperty(id)) { + return; + } + + subscriptions[id] = (on({ id: id, change: 'any' }, (data) => { + if (pageId == -1 && config.button1Page != undefined) { + SendToPanel({ payload: GeneratePageElements(config.button1Page) }); + } + if (pageId == -2 && config.button2Page != undefined) { + SendToPanel({ payload: GeneratePageElements(config.button2Page) }); + } + if (activePage !== undefined) { + SendToPanel({ payload: GeneratePageElements(activePage) }); + } + })); + } catch (err) { + console.warn('function RegisterEntityWatcher: ' + err.message); + } +} + +function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void { + try { + if (subscriptions.hasOwnProperty(id)) { + return; + } + + subscriptions[id] = (on({ id: id, change: 'any' }, () => { + SendToPanel(GenerateDetailPage(type, pageItem)); + })) + } catch (err) { + console.warn('function RegisterDetailEntityWatcher: ' + err.message); + } +} + +function GetUnitOfMeasurement(id: string): string { + try { + if (!existsObject(id)) + return ''; + + let obj = getObject(id); + if (typeof obj.common.unit !== 'undefined') { + return obj.common.unit + } + + if (typeof obj.common.alias !== 'undefined' && typeof obj.common.alias.id !== 'undefined') { + return GetUnitOfMeasurement(obj.common.alias.id); + } + + return ''; + } catch (err) { + console.warn('function GetUnitOfMeasurement: ' + err.message); + } +} + +function GenerateThermoPage(page: PageThermo): Payload[] { + try { + var id = page.items[0].id + var out_msgs: Array = []; + out_msgs.push({ payload: 'pageType~cardThermo' }); + + // ioBroker + if (existsObject(id)) { + let o = getObject(id); + let name = page.heading !== undefined ? page.heading : o.common.name.de; + let currentTemp = 0; + if (existsState(id + '.ACTUAL')) + currentTemp = (Math.round(parseFloat(getState(id + '.ACTUAL').val) * 10) / 10); + + let destTemp = 0; + if (existsState(id + '.SET')) { + destTemp = getState(id + '.SET').val.toFixed(2) * 10; + } + let statusStr: String = 'MANU'; + let status = ''; + if (existsState(id + '.MODE')) + status = getState(id + '.MODE').val; + + let minTemp = page.items[0].minValue !== undefined ? page.items[0].minValue : 50; //Min Temp 5°C + let maxTemp = page.items[0].maxValue !== undefined ? page.items[0].maxValue : 300; //Max Temp 30°C + let stepTemp = 5 // 0,5° Schritte + + //Attribute hinzufügen, wenn im Alias definiert + let i_list = Array.prototype.slice.apply($('[state.id="' + id + '.*"]')); + if ((i_list.length - 3) != 0) { + + var i = 0; + var bt = ['~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~']; + + if (o.common.role == 'thermostat') { + + if (existsState(id + '.AUTOMATIC') && getState(id + '.AUTOMATIC').val != null) { + if (getState(id + '.AUTOMATIC').val) { + bt[i++] = Icons.GetIcon('alpha-a-circle') + '~' + rgb_dec565(On) + '~1~' + 'AUTT' + '~'; + statusStr = 'AUTO'; + } else { + bt[i++] = Icons.GetIcon('alpha-a-circle') + '~33840~1~' + 'AUTT' + '~'; + } + } + if (existsState(id + '.MANUAL') && getState(id + '.MANUAL').val != null) { + if (getState(id + '.MANUAL').val) { + bt[i++] = Icons.GetIcon('alpha-m-circle') + '~' + rgb_dec565(On) + '~1~' + 'MANT' + '~'; + statusStr = 'MANU'; + } else { + bt[i++] = Icons.GetIcon('alpha-m-circle') + '~33840~1~' + 'MANT' + '~'; + } + } + if (existsState(id + '.PARTY') && getState(id + '.PARTY').val != null) { + if (getState(id + '.PARTY').val) { + bt[i++] = Icons.GetIcon('party-popper') + '~' + rgb_dec565(On) + '~1~' + 'PART' + '~'; + statusStr = 'PARTY'; + } else { + bt[i++] = Icons.GetIcon('party-popper') + '~33840~1~' + 'PART' + '~'; + } + } + if (existsState(id + '.VACATION') && getState(id + '.VACATION').val != null) { + if (getState(id + '.VACATION').val) { + bt[i++] = Icons.GetIcon('palm-tree') + '~' + rgb_dec565(On) + '~1~' + 'VACT' + '~'; + statusStr = 'VAC'; + } else { + bt[i++] = Icons.GetIcon('palm-tree') + '~33840~1~' + 'VACT' + '~'; + } + } + if (existsState(id + '.BOOST') && getState(id + '.BOOST').val != null) { + if (getState(id + '.BOOST').val) { + bt[i++] = Icons.GetIcon('fast-forward-60') + '~' + rgb_dec565(On) + '~1~' + 'BOOT' + '~'; + statusStr = 'BOOST'; + } else { + bt[i++] = Icons.GetIcon('fast-forward-60') + '~33840~1~' + 'BOOT' + '~'; + } + } + + for (let i_index in i_list) { + let thermostatState = i_list[i_index].split('.'); + if ( + thermostatState[thermostatState.length - 1] != 'SET' && + thermostatState[thermostatState.length - 1] != 'ACTUAL' && + thermostatState[thermostatState.length - 1] != 'MODE' + ) { + i++; + + switch (thermostatState[thermostatState.length - 1]) { + case 'HUMIDITY': + if (existsState(id + '.HUMIDITY') && getState(id + '.HUMIDITY').val != null) { + if (parseInt(getState(id + '.HUMIDITY').val) < 40) { + bt[i - 1] = Icons.GetIcon('water-percent') + '~65504~1~' + 'HUM' + '~'; + } else if (parseInt(getState(id + '.HUMIDITY').val) < 30) { + bt[i - 1] = Icons.GetIcon('water-percent') + '~63488~1~' + 'HUM' + '~'; + } else if (parseInt(getState(id + '.HUMIDITY').val) >= 40) { + bt[i - 1] = Icons.GetIcon('water-percent') + '~2016~1~' + 'HUM' + '~'; + } else if (parseInt(getState(id + '.HUMIDITY').val) > 65) { + bt[i - 1] = Icons.GetIcon('water-percent') + '~65504~1~' + 'HUM' + '~'; + } else if (parseInt(getState(id + '.HUMIDITY').val) > 75) { + bt[i - 1] = Icons.GetIcon('water-percent') + '~63488~1~' + 'HUM' + '~'; + } + } else i--; + break; + case 'LOWBAT': + if (existsState(id + '.LOWBAT') && getState(id + '.LOWBAT').val != null) { + if (getState(id + '.LOWBAT').val) { + bt[i - 1] = Icons.GetIcon('battery-low') + '~63488~1~' + 'LBAT' + '~'; + } else { + bt[i - 1] = Icons.GetIcon('battery-high') + '~2016~1~' + 'LBAT' + '~'; + } + } else i--; + break; + case 'MAINTAIN': + if (existsState(id + '.MAINTAIN') && getState(id + '.MAINTAIN').val != null) { + if (getState(id + '.MAINTAIN').val >> .1) { + bt[i - 1] = Icons.GetIcon('account-wrench') + '~60897~1~' + 'MAIN' + '~'; + } else { + bt[i - 1] = Icons.GetIcon('account-wrench') + '~33840~1~' + 'MAIN' + '~'; + } + } else i--; + break; + case 'UNREACH': + if (existsState(id + '.UNREACH') && getState(id + '.UNREACH').val != null) { + if (getState(id + '.UNREACH').val) { + bt[i - 1] = Icons.GetIcon('wifi-off') + '~63488~1~' + 'WLAN' + '~'; + } else { + bt[i - 1] = Icons.GetIcon('wifi') + '~2016~1~' + 'WLAN' + '~'; + } + } else i--; + break; + case 'POWER': + if (existsState(id + '.POWER') && getState(id + '.POWER').val != null) { + if (getState(id + '.POWER').val) { + bt[i - 1] = Icons.GetIcon('power-standby') + '~2016~1~' + 'POW' + '~'; + } else { + bt[i - 1] = Icons.GetIcon('power-standby') + '~33840~1~' + 'POW' + '~'; + } + } else i--; + break; + case 'ERROR': + if (existsState(id + '.ERROR') && getState(id + '.ERROR').val != null) { + if (getState(id + '.ERROR').val) { + bt[i - 1] = Icons.GetIcon('alert-circle') + '~63488~1~' + 'ERR' + '~'; + } else { + bt[i - 1] = Icons.GetIcon('alert-circle') + '~33840~1~' + 'ERR' + '~'; + } + } else i--; + break; + case 'WORKING': + if (existsState(id + '.WORKING') && getState(id + '.WORKING').val != null) { + if (getState(id + '.WORKING').val) { + bt[i - 1] = Icons.GetIcon('briefcase-check') + '~2016~1~' + 'WORK' + '~'; + } else { + bt[i - 1] = Icons.GetIcon('briefcase-check') + '~33840~1~' + 'WORK' + '~'; + } + } else i--; + break; + default: + i--; + break; + } + } + } + + for (let j = i; j < 9; j++) { + bt[j] = '~~~~'; + } + } + + if (o.common.role == 'airCondition') { + if (existsState(id + '.MODE') && getState(id + '.MODE').val != null) { + let Mode = getState(id + '.MODE').val + if (existsState(id + '.POWER') && getState(id + '.POWER').val != null) { + if (Mode != 0 || getState(id + '.POWER').val) { //0=ON oder .POWER = true + bt[0] = Icons.GetIcon('power-standby') + '~2016~1~' + 'POWER' + '~'; + statusStr = 'ON'; + } else { + bt[0] = Icons.GetIcon('power-standby') + '~35921~0~' + 'POWER' + '~'; + statusStr = 'OFF'; + } + } + if (Mode == 1) { //1=AUTO + bt[1] = Icons.GetIcon('air-conditioner') + '~1024~1~' + 'AUTO' + '~'; + statusStr = 'AUTO'; + } else { + bt[1] = Icons.GetIcon('air-conditioner') + '~35921~0~' + 'AUTO' + '~'; + } + if (Mode == 2) { //2=COOL + bt[2] = Icons.GetIcon('snowflake') + '~11487~1~' + 'COOL' + '~'; + statusStr = 'COOL'; + } else { + bt[2] = Icons.GetIcon('snowflake') + '~35921~0~' + 'COOL' + '~'; + } + if (Mode == 3) { //3=HEAT + bt[3] = Icons.GetIcon('fire') + '~64512~1~' + 'HEAT' + '~'; + statusStr = 'HEAT'; + } else { + bt[3] = Icons.GetIcon('fire') + '~35921~0~' + 'HEAT' + '~'; + } + if (Mode == 4) { //4=ECO + bt[4] = Icons.GetIcon('alpha-e-circle-outline') + '~2016~1~' + 'ECO' + '~'; + statusStr = 'ECO'; + } else { + bt[4] = Icons.GetIcon('alpha-e-circle-outline') + '~35921~0~' + 'ECO' + '~'; + } + if (Mode == 5) { //5=FANONLY + bt[5] = Icons.GetIcon('fan') + '~11487~1~' + 'FAN' + '~'; + statusStr = 'FAN ONLY'; + } else { + bt[5] = Icons.GetIcon('fan') + '~35921~0~' + 'FAN' + '~'; + } + if (Mode == 6) { //6=DRY + bt[6] = Icons.GetIcon('water-percent') + '~60897~1~' + 'DRY' + '~'; + statusStr = 'DRY'; + } else { + bt[6] = Icons.GetIcon('water-percent') + '~35921~0~' + 'DRY' + '~'; + } + if (existsState(id + '.SWING') && getState(id + '.SWING').val != null) { + if (getState(id + '.POWER').val && getState(id + '.SWING').val == 1) { //0=ON oder .SWING = true + bt[7] = Icons.GetIcon('swap-vertical-bold') + '~2016~1~' + 'SWING' + '~'; + } else { + bt[7] = Icons.GetIcon('swap-vertical-bold') + '~35921~0~' + 'SWING' + '~'; + } + } + } + } + } + + let icon_res = bt[0] + bt[1] + bt[2] + bt[3] + bt[4] + bt[5] + bt[6] + bt[7]; + + out_msgs.push({ + payload: 'entityUpd~' + + name + '~' // Heading + + GetNavigationString(pageId) + '~' // Page Navigation + + id + '~' // internalNameEntiy + + currentTemp + config.temperatureUnit + '~' // Ist-Temperatur (String) + + destTemp + '~' // Soll-Temperatur (numerisch ohne Komma) + + statusStr + '~' // Mode + + minTemp + '~' // Thermostat Min-Temperatur + + maxTemp + '~' // Thermostat Max-Temperatur + + stepTemp + '~' // Schritte für Soll (5°C) + + icon_res // Icons Status + + findLocale('thermostat', 'Currently') + '~' // Bezeicher vor Aktueller Raumtemperatur + + findLocale('thermostat', 'State') + '~' // Bezeicner vor + + '~' // Bezeichner vor HVAC -- Gibt es nicht mehr + + config.temperatureUnit + '~' // Bezeichner hinter Solltemp + + '' + '~' // iconTemperature dstTempTwoTempMode + + '' // dstTempTwoTempMode + }); + + } + + if (Debug) console.log(out_msgs); + return out_msgs + } catch (err) { + console.warn('function GenerateThermoPage: ' + err.message); + } +} + +function GenerateMediaPage(page: PageMedia): Payload[] { + try { + var id = page.items[0].id + + var out_msgs: Array = []; + + out_msgs.push({ payload: 'pageType~cardMedia' }); + if (existsObject(id)) { + let name = getState(id + '.ALBUM').val; + let title = getState(id + '.TITLE').val; + let author = getState(id + '.ARTIST').val; + + let vInstance = page.items[0].adapterPlayerInstance; + let v1Adapter = vInstance.split('.'); + let v2Adapter = v1Adapter[0]; + + //Alexa + neue Adpter/Player + let media_icon = Icons.GetIcon('playlist-music'); + + //Spotify-Premium + if (v2Adapter == 'spotify-premium') { + media_icon = Icons.GetIcon('spotify'); + name = getState(id + '.CONTEXT_DESCRIPTION').val; + let nameLenght = name.length; + if (name.substring(0,9) == 'Playlist:') { + let nameLenght = name.length; + name = name.slice(10, nameLenght); + } else if (name.substring(0,6) == 'Album:') { + let nameLenght = name.length; + name = name.slice(10, nameLenght); + } else if (name.substring(0,6) == 'Track') { + name = 'Spotify-Premium'; + } + if (nameLenght == 0) { + name = 'Spotify-Premium'; + } + author = getState(id + '.ARTIST').val + ' | ' + getState(id + '.ALBUM').val; + if (author.length > 30) { + author = getState(id + '.ARTIST').val; + } + if ((getState(id + '.ARTIST').val).length == 0) { + author = 'no music to control'; + } + } + + //Sonos + if (v2Adapter == 'sonos') { + media_icon = Icons.GetIcon('music'); + name = getState(id + '.CONTEXT_DESCRIPTION').val; + let nameLenght = name.length; + if (nameLenght == 0) { + name = 'Sonos Player'; + } + author = getState(id + '.ARTIST').val + ' | ' + getState(id + '.ALBUM').val; + if ((getState(id + '.ARTIST').val).length == 0) { + author = 'no music to control'; + } + } + + //Logitech Squeezebox RPC + if (v2Adapter == 'squeezeboxrpc') { + media_icon = Icons.GetIcon('dlna'); + let nameLenght = name.length; + if (nameLenght == 0) { + name = 'Squeezebox RPC'; + author = 'no music to control'; + } + } + + //Alexa2 + if (v2Adapter == 'alexa2') { + media_icon = Icons.GetIcon('playlist-music'); + let nameLenght = name.length; + if (nameLenght == 0) { + name = 'Alexa Player'; + author = 'no music to control'; + } + } + + let volume = getState(id + '.VOLUME').val; + var iconplaypause = Icons.GetIcon('pause'); //pause + var onoffbutton = 1374; + + //Für alle Player + if (getState(id + '.STATE').val) { + onoffbutton = 65535; + iconplaypause = Icons.GetIcon('pause'); //pause + } else { + iconplaypause = Icons.GetIcon('play'); //play + } + + //Ausnahme für squeezebox, da State = Power + if (getState(id + '.PAUSE').val === false && v2Adapter == 'squeezeboxrpc') { + onoffbutton = 65535; + iconplaypause = Icons.GetIcon('pause'); //pause + } else { + iconplaypause = Icons.GetIcon('play'); //play + } + + if (Debug) console.log(v2Adapter); + + let currentSpeaker = 'kein Speaker gefunden'; + + if (v2Adapter == 'alexa2') { + currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', page.items[0].mediaDevice, '.Info.name'].join(''))).val; + } else if (v2Adapter == 'spotify-premium') { + currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'player.device.name'].join(''))).val; + } else if (v2Adapter == 'sonos') { + currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'root.', page.items[0].mediaDevice, '.members'].join(''))).val; + } else if (v2Adapter == 'squeezeboxrpc') { + if(existsObject(([page.items[0].adapterPlayerInstance, 'Playername'].join('')))) { + currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'Playername'].join(''))).val; + } + } + //------------------------------------------------------------------------------------------------------------- + // nachfolgend alle Alexa-Devices (ist Online / Player- und Commands-Verzeichnis vorhanden) auflisten und verketten + // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter + let speakerlist = ''; + if (page.items[0].speakerList.length > 0) { + for (let i_index in page.items[0].speakerList) { + speakerlist = speakerlist + page.items[0].speakerList[i_index] + '?'; + } + } else { + let i_list = Array.prototype.slice.apply($('[state.id="' + page.items[0].adapterPlayerInstance + 'Echo-Devices.*.Info.name"]')); + for (let i_index in i_list) { + let i = i_list[i_index]; + let deviceId = i; + deviceId = deviceId.split('.'); + if (getState(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.online'].join(''))).val && + existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Player'].join(''))) && + existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Commands'].join('')))) { + speakerlist = speakerlist + getState(i).val + '?'; + } + } + } + speakerlist = speakerlist.substring(0, speakerlist.length - 1); + //-------------------------------------------------------------------------------------------------------------- + + out_msgs.push({ + payload: 'entityUpd~' + //entityUpd + name + '~' + //heading + GetNavigationString(pageId) + '~' + //navigation + id + '~' + //internalNameEntiy + media_icon + '~' + //icon + title + '~' + //title + author + '~' + //author + volume + '~' + //volume + iconplaypause + '~' + //playpauseicon + currentSpeaker + '~' + //currentSpeaker + speakerlist + '~' + //speakerList-seperated-by-? + onoffbutton + }); //On/Off Button Color + } + if (Debug) console.log(out_msgs); + return out_msgs + } catch (err) { + console.warn('function GenerateMediaPage: ' + err.message); + } +} + +function GenerateAlarmPage(page: PageAlarm): Payload[] { + try { + activePage = page; + var id = page.items[0].id + + var out_msgs: Array = []; + out_msgs.push({ payload: 'pageType~cardAlarm' }); + var nsPath = NSPanel_Alarm_Path + 'Alarm.'; + + if (existsState(nsPath + 'AlarmPin') == false || existsState(nsPath + 'AlarmState') == false || existsState(nsPath + 'AlarmType') == false || existsState(nsPath + 'PIN_Failed') == false || existsState(nsPath + 'PANEL') == false) { + createState(nsPath + 'AlarmPin', '0000', { type: 'string' }, function () { setState(nsPath + 'AlarmPin', '0000') }); + createState(nsPath + 'AlarmState', 'disarmed', { type: 'string' }, function () { setState(nsPath + 'AlarmState', 'disarmed') }); + createState(nsPath + 'AlarmType', 'D1', { type: 'string' }, function () { setState(nsPath + 'AlarmType', 'D1') }); + createState(nsPath + 'PIN_Failed', 0, { type: 'number' }, function () { setState(nsPath + 'PIN_Failed', 0) }); + createState(nsPath + 'PANEL', NSPanel_Path, { type: 'string' }, function () { setState(nsPath + 'PANEL', NSPanel_Path) }); + } + + if (existsState(nsPath + 'AlarmPin') && existsState(nsPath + 'AlarmState') && existsState(nsPath + 'AlarmType')) { + //var entityPin = getState(nsPath + 'AlarmPin').val; + var entityState = getState(nsPath + 'AlarmState').val; + //var entityType = getState(nsPath + 'AlarmType').val; + var arm1: string, arm2: string, arm3: string, arm4: string; + var arm1ActionName: string, arm2ActionName: string, arm3ActionName: string, arm4ActionName: string; + var icon = '0'; + var iconcolor = 63488; + var numpadStatus = 'disable'; + var flashing = 'disable'; + + if (Debug) console.log(id); + + if (entityState == 'armed' || entityState == 'triggered') { + arm1 = 'Deaktivieren'; //arm1*~* + arm1ActionName = 'D1'; //arm1ActionName*~* + arm2 = ''; //arm2*~* + arm2ActionName = ''; //arm2ActionName*~* + arm3 = ''; //arm3*~* + arm3ActionName = ''; //arm3ActionName*~* + arm4 = ''; //arm4*~* + arm4ActionName = ''; //arm4ActionName*~* + } + + if (entityState == 'disarmed' || entityState == 'arming' || entityState == 'pending') { + arm1 = 'Vollschutz'; //arm1*~* + arm1ActionName = 'A1'; //arm1ActionName*~* + arm2 = 'Zuhause'; //arm2*~* + arm2ActionName = 'A2'; //arm2ActionName*~* + arm3 = 'Nacht'; //arm3*~* + arm3ActionName = 'A3'; //arm3ActionName*~* + arm4 = 'Besuch'; //arm4*~* + arm4ActionName = 'A4'; //arm4ActionName*~* + } + + if (entityState == 'armed') { + icon = Icons.GetIcon('shield-home'); //icon*~* + iconcolor = 63488; //iconcolor*~* + numpadStatus = 'enable'; //numpadStatus*~* + flashing = 'disable'; //flashing* + } + if (entityState == 'disarmed') { + icon = Icons.GetIcon('shield-off'); //icon*~* + iconcolor = 2016; //iconcolor*~* + numpadStatus = 'enable'; //numpadStatus*~* + flashing = 'disable'; //flashing* + } + if (entityState == 'arming' || entityState == 'pending') { + icon = Icons.GetIcon('shield'); //icon*~* + iconcolor = rgb_dec565({ red: 243, green: 179, blue: 0 }); //iconcolor*~* + numpadStatus = 'disable'; //numpadStatus*~* + flashing = 'enable' //flashing* + } + if (entityState == 'triggered') { + iconcolor = rgb_dec565({ red: 223, green: 76, blue: 30 }); //icon*~* + icon = Icons.GetIcon('bell-ring'); //iconcolor*~* + numpadStatus = 'enable'; //numpadStatus*~* + flashing = 'enable' //flashing* + } + + out_msgs.push({ + payload: 'entityUpd~' + //entityUpd~* + id + '~' + //internalNameEntity*~* + GetNavigationString(pageId) + '~' + //navigation*~* --> hiddenCards + arm1 + '~' + //arm1*~* + arm1ActionName + '~' + //arm1ActionName*~* + arm2 + '~' + //arm2*~* + arm2ActionName + '~' + //arm2ActionName*~* + arm3 + '~' + //arm3*~* + arm3ActionName + '~' + //arm3ActionName*~* + arm4 + '~' + //arm4*~* + arm4ActionName + '~' + //arm4ActionName*~* + icon + '~' + //icon*~* + iconcolor + '~' + //iconcolor*~* + numpadStatus + '~' + //numpadStatus*~* + flashing + }); //flashing* + + if (Debug) console.log(out_msgs); + return out_msgs + } + } catch (err) { + console.warn('function GenerateAlarmPage: ' + err.message); + } +} + +function GenerateQRPage(page: PageQR): Payload[] { + try { + activePage = page; + + var id = page.items[0].id + var out_msgs: Array = []; + out_msgs.push({ payload: 'pageType~cardQR' }); + + let o = getObject(id) + + var heading = page.heading !== undefined ? page.heading : o.common.name.de + var textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;' + var hiddenPWD = false; + if (page.items[0].hidePassword !== undefined && page.items[0].hidePassword == true) { + hiddenPWD = true + } + + const tempstr = textQR.split(';'); + for (let w = 0; w < tempstr.length - 1; w++) { + if (tempstr[w].substring(0, 1) == 'S') { + var optionalValue1 = tempstr[w].slice(2); + } + if (tempstr[w].substring(0, 1) == 'P') { + var optionalValue2 = tempstr[w].slice(2); + } + } + + var type1 = 'text'; + var internalName1 = 'SSID'; + var iconId1 = Icons.GetIcon('wifi'); + var displayName1 = 'SSID'; + var type2 = 'text'; + var internalName2 = 'Passwort'; + var iconId2 = Icons.GetIcon('key'); + var displayName2 = 'Passwort'; + + if (hiddenPWD) { + type2 = 'disable'; + iconId2 = ''; + displayName2 = ''; + } + + out_msgs.push({ + payload: 'entityUpd~' + //entityUpd + heading + '~' + //heading + GetNavigationString(pageId) + '~' + //navigation + textQR + '~' + //textQR + type1 + '~' + //type + internalName1 + '~' + //internalName + iconId1 + '~' + //iconId + 65535 + '~' + //iconColor + displayName1 + '~' + //displayName + optionalValue1 + '~' + //optionalValue + type2 + '~' + //type + internalName2 + '~' + //internalName + iconId2 + '~' + //iconId + 65535 + '~' + //iconColor + displayName2 + '~' + //displayName + optionalValue2 + }); //optionalValue + + //entityUpd,heading,navigation,textQR[,type,internalName,iconId,displayName,optionalValue]x2 + return out_msgs + + } catch (err) { + console.warn('function GenerateQRPage: ' + err.message); + } +} + +function GeneratePowerPage(page: PagePower): Payload[] { + try { + activePage = page; + + if (Debug) console.log(page.items[0].id); + + var demoMode = false; + + try { + var id = page.items[0].id + } catch (err) { + console.log("Kein PageItem definiert - cardPower Demo-Modus aktiv"); + demoMode = true; + } + + let heading = 'cardPower Example'; + if (demoMode != true) { + let o = getObject(id) + heading = page.heading !== undefined ? page.heading : o.common.name.de + } + + const obj = JSON.parse((getState(page.items[0].id + '.ACTUAL').val)); + + var out_msgs: Array = []; + out_msgs.push({ payload: 'pageType~cardPower' }); + + //Demo Data if no pageItem present + let array_icon_color = [White, MSGreen, MSYellow, MSGreen, MSYellow, MSGreen, MSRed]; + let array_icon = ['home', 'battery-charging-60', 'solar-power-variant', 'wind-turbine', 'shape', 'transmission-tower', 'car']; + let array_powerspeed = ['', '-1', '2', '4', '1', '1', '5']; + let array_powerstate = ['', '0,5 kW', '0,9 kW', '2,8 kW', '0,2 kW', '0,1 kW', '4,6 kW']; + + let arrayColorScale = [colorScale0, colorScale1, colorScale2, colorScale3, colorScale4, colorScale5, colorScale6, colorScale7, colorScale8, colorScale9, colorScale10] + + if (!demoMode) { + for (let obji = 0; obji < 6; obji++) { + array_icon_color[obji + 1] = arrayColorScale[obj[obji].iconColor]; + array_icon[obji + 1] = obj[obji].icon; + array_powerspeed[obji + 1] = obj[obji].speed; + array_powerstate[obji + 1] = obj[obji].value + ' ' + obj[obji].unit ; + } + } + + let power_string : any = ''; + + for (let i = 1; i < 7; i++ ) { + power_string = power_string + rgb_dec565(array_icon_color[i]) + '~'; // icon_color~ + power_string = power_string + Icons.GetIcon(array_icon[i]) + '~'; // icon~ + power_string = power_string + array_powerspeed[i] + '~'; // speed~ + power_string = power_string + array_powerstate[i] + '~'; // entity.state~ + } + + power_string = power_string.substring(0, power_string.length - 1); + + out_msgs.push({ + payload: 'entityUpd~' + //entityUpd~* + heading + '~' + //internalNameEntity*~* + GetNavigationString(pageId) + '~' + //navigation*~* + rgb_dec565(array_icon_color[0]) + '~' + // icon_color~ Mitte + Icons.GetIcon(array_icon[0]) + '~' + // icon~ Mitte + array_powerspeed[0] + '~' + // entity.state~ Mitte + power_string + }); + + return out_msgs + + } catch (err) { + console.warn('function GeneratePowerPage: ' + err.message); + } +} + +function setIfExists(id: string, value: any, type: string | null = null): boolean { + try { + if (type === null) { + if (existsState(id)) { + setState(id, value); + return true; + } + } else { + const obj = getObject(id); + if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) { + setState(id, value); + return true; + } + } + + return false; + } catch (err) { + console.warn('function setIfExists: ' + err.message); + } +} + +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); + return true; + } + return false; + } catch (err) { + console.warn('function toggleState: ' + err.message); + } +} + +function HandleButtonEvent(words): void { + try { + var id = words[2] + var buttonAction = words[3]; + + if (Debug) { + console.log(words[0] + ' - ' + words[1] + ' - ' + words[2] + ' - ' + words[3] + ' - ' + words[4] + ' - PageId: ' + pageId); + } + + if ((words[2]).substring(0, 8) == 'navigate') { + GeneratePage(eval((words[2]).substring(9, (words[2]).length))); + return; + } + + if (Debug) console.log(buttonAction); + + switch (buttonAction) { + case 'bUp': + if (pageId < 0) { // Prüfen, ob button1page oder button2page + pageId = 0; + } else { + pageId = Math.abs(pageNum); + } + UnsubscribeWatcher(); + GeneratePage(config.pages[pageId]); + break; + case 'bNext': + var pageNum = (((pageId + 1) % config.pages.length) + config.pages.length) % config.pages.length; + pageId = pageNum; + UnsubscribeWatcher(); + GeneratePage(config.pages[pageId]); + break; + case 'bPrev': + var pageNum = (((pageId - 1) % config.pages.length) + config.pages.length) % config.pages.length; + pageId = pageNum; + UnsubscribeWatcher(); + if (activePage != undefined && activePage.parent != undefined) { + //update pageID + for (let i = 0; i < config.pages.length; i++) { + if (config.pages[i] == activePage.parent) { + pageId = i; + break; + } + } + GeneratePage(activePage.parent); + } + else { + GeneratePage(config.pages[pageId]); + } + break; + case 'bExit': + if (config.screenSaverDoubleClick && words[2] == 'screensaver') { + if (words[4] == 2) { + setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyHeading', ''); + setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyText', ''); + GeneratePage(config.pages[pageId]); + } + } else { + if (Debug) console.log('bExit: ' + words[4] + ' - ' + pageId); + setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyHeading', ''); + setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyText', ''); + GeneratePage(activePage); + } + break; + case 'notifyAction': + if (words[4] == 'yes') { + setState(popupNotifyInternalName, { val: words[2], ack: true }); + setState(popupNotifyAction, { val: true, ack: true }); + } else if (words[4] == 'no') { + setState(popupNotifyInternalName, { val: words[2], ack: true }); + setState(popupNotifyAction, { val: false, ack: true }); + } + + setIfExists(config.panelSendTopic, 'exitPopup'); + + break; + case 'OnOff': + if (existsObject(id)) { + var action = false + if (words[4] == '1') + action = true; + let o = getObject(id); + switch (o.common.role) { + case 'socket': + case 'light': + setIfExists(id + '.SET', action); + break; + case 'dimmer': + setIfExists(id + '.ON_SET', action) ? true : setIfExists(id + '.ON_ACTUAL', action); + break; + case 'ct': + setIfExists(id + '.ON', action); + break; + case 'rgb': + case 'rgbSingle': + case 'hue': // Armilar + setIfExists(id + '.ON_ACTUAL', action); + } + } + break; + case 'button': + if (existsObject(id)) { + var action = false + if (words[4] == '1') + action = true; + let o = getObject(id); + switch (o.common.role) { + case 'lock': + case 'button': + toggleState(id + '.SET') ? true : toggleState(id + '.ON_SET'); + break; + case 'buttonSensor': + toggleState(id + '.ACTUAL'); + break; + case 'socket': + case 'light': + toggleState(id + '.SET') ? true : toggleState(id + '.ON_SET'); + break; + case 'dimmer': + toggleState(id + '.ON_SET') ? true : toggleState(id + '.ON_ACTUAL'); + break; + case 'ct': + toggleState(id + '.ON'); + break; + case 'rgb': + case 'rgbSingle': + case 'hue': // Armilar + toggleState(id + '.ON_ACTUAL'); + } + } + break; + case 'up': + setIfExists(id + '.OPEN', true); + break; + case 'stop': + setIfExists(id + '.STOP', true); + break; + case 'down': + setIfExists(id + '.CLOSE', true); + break; + case 'positionSlider': + (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); + timeoutSlider = setTimeout(async function () { + setIfExists(id + '.SET', parseInt(words[4])) ? true : setIfExists(id + '.ACTUAL', parseInt(words[4])); + }, 250); + break; + case 'tiltOpen': + setIfExists(id + '.TILT_OPEN', true); + break; + case 'tiltStop': + setIfExists(id + '.TILT_STOP', true); + break; + case 'tiltClose': + setIfExists(id + '.TILT_CLOSE', true); + break; + case 'tiltSlider': + (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); + timeoutSlider = setTimeout(async function () { + setIfExists(id + '.TILT_SET', parseInt(words[4])) ? true : setIfExists(id + '.TILT_ACTUAL', parseInt(words[4])); + }, 250); + break; + case 'brightnessSlider': + (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); + timeoutSlider = setTimeout(async function () { + if (existsObject(id)) { + let o = getObject(id); + let pageItem = findPageItem(id); + + switch (o.common.role) { + case 'dimmer': + if (pageItem.minValueBrightness != undefined && pageItem.maxValueBrightness != undefined) { + let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValueBrightness, pageItem.minValueBrightness)) + setIfExists(id + '.SET', sliderPos) ? true : setIfExists(id + '.ACTUAL', sliderPos); + } else { + setIfExists(id + '.SET', parseInt(words[4])) ? true : setIfExists(id + '.ACTUAL', parseInt(words[4])); + } + break; + case 'rgb': + case 'ct': + case 'rgbSingle': + case 'hue': + if (pageItem.minValueBrightness != undefined && pageItem.maxValueBrightness != undefined) { + let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValueBrightness, pageItem.minValueBrightness)) + setIfExists(id + '.DIMMER', sliderPos); + } else { + setIfExists(id + '.DIMMER', parseInt(words[4])); + } + break; + } + } + }, 250); + break; + case 'colorTempSlider': // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur + (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); + timeoutSlider = setTimeout(async function () { + let pageItem = findPageItem(id); + if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValueColorTemp, pageItem.maxValueColorTemp)); + setIfExists(id + '.TEMPERATURE', (colorTempK)); + } else { + setIfExists(id + '.TEMPERATURE', 100 - words[4]); + } + }, 250); + break; + case 'colorWheel': + let colorCoordinates = words[4].split('|'); + let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]); + if (Debug) console.log(rgb); + if (Debug) console.log(getHue(rgb.red, rgb.green, rgb.blue)); + let o = getObject(id); + switch (o.common.role) { + case 'hue': + setIfExists(id + '.HUE', getHue(rgb.red, rgb.green, rgb.blue)); + break; + case 'rgb': + setIfExists(id + '.RED', rgb.red); + setIfExists(id + '.GREEN', rgb.green); + setIfExists(id + '.BLUE', rgb.blue); + break; + case 'rgbSingle': + let pageItem = findPageItem(id); + if (pageItem.colormode == "xy") { + //Für z.B. Deconz XY + setIfExists(id + ".RGB", rgb_to_cie(rgb.red, rgb.green, rgb.blue)); + if (Debug) console.log(rgb_to_cie(rgb.red, rgb.green, rgb.blue)); + } + else { + //Für RGB + setIfExists(id + ".RGB", ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue)); + } + break; + } + break; + case 'tempUpd': + setIfExists(id + '.SET', parseInt(words[4]) / 10); + break; + case 'media-back': + setIfExists(id + '.PREV', true); + setTimeout(function(){ + GeneratePage(activePage); + },3000) + break; + case 'media-pause': + let pageItemTemp = findPageItem(id); + let adaInstanceSplit = pageItemTemp.adapterPlayerInstance.split('.'); + if (adaInstanceSplit[0] == 'squeezeboxrpc') { + let stateVal = getState(pageItemTemp.adapterPlayerInstance + 'state').val + if (stateVal == 0) { + setState(pageItemTemp.adapterPlayerInstance + 'state', 1) + } else if (stateVal == 1) { + setState(pageItemTemp.adapterPlayerInstance + 'state', 0) + } else if (stateVal == null) { + setState(pageItemTemp.adapterPlayerInstance + 'state', 1) + } + } else { + if (getState(id + '.STATE').val === true) { + setIfExists(id + '.PAUSE', true); + } else { + setIfExists(id + '.PLAY', true); + } + } + setTimeout(function(){ + GeneratePage(activePage); + },3000) + break; + case 'media-next': + setIfExists(id + '.NEXT', true); + setTimeout(function(){ + GeneratePage(activePage); + },3000) + break; + case 'volumeSlider': + setIfExists(id + '.VOLUME', parseInt(words[4])) + break; + case 'speaker-sel': + let pageItem = findPageItem(id); + let adapterInstance = pageItem.adapterPlayerInstance; + let adapter = adapterInstance.split('.') + let deviceAdapter = adapter[0]; + + switch (deviceAdapter) { + case 'spotify-premium': + var strDeviceID = spotifyGetDeviceID(words[4]); + setState(adapterInstance + 'devices.' + strDeviceID + ".useForPlayback", true); + break; + case 'alexa2': + let i_list = Array.prototype.slice.apply($('[state.id="' + adapterInstance + 'Echo-Devices.*.Info.name"]')); + for (let i_index in i_list) { + let i = i_list[i_index]; + if ((getState(i).val) === words[4]) { + let deviceId = i; + deviceId = deviceId.split('.'); + setIfExists(adapterInstance + 'Echo-Devices.' + pageItem.mediaDevice + '.Commands.textCommand', 'Schiebe meine Musik auf ' + words[4]); + pageItem.mediaDevice = deviceId[3]; + } + } + break; + case 'sonos': + break; + case 'chromecast': + break; + } + break; + case 'media-OnOff': + let pageItemTem = findPageItem(id); + let adaInstanceSpli = pageItemTem.adapterPlayerInstance.split('.'); + if (adaInstanceSpli[0] == 'squeezeboxrpc') { + let stateVal = getState(pageItemTem.adapterPlayerInstance + 'Power').val + if (stateVal === 0) { + setState(pageItemTem.adapterPlayerInstance + 'Power', 1) + setIfExists(id + '.STOP', false) + setIfExists(id + '.STATE', 1) + } else { + setState(pageItemTem.adapterPlayerInstance + 'Power', 0) + setIfExists(id + '.STOP', true) + setIfExists(id + '.STATE', 0) + } + } else { + setIfExists(id + '.STOP', true) + } + break; + case 'hvac_action': + if (words[4] == 'BOOT' || words[4] == 'PART' || words[4] == 'AUTT' || words[4] == 'MANT' || words[4] == 'VACT') { + + switch (words[4]) { + case 'BOOT': + setIfExists(words[2] + '.' + 'BOOST', !getState(words[2] + '.' + 'BOOST').val) + break; + case 'PART': + setIfExists(words[2] + '.' + 'PARTY', !getState(words[2] + '.' + 'PARTY').val) + break; + case 'AUTT': + setIfExists(words[2] + '.' + 'AUTOMATIC', !getState(words[2] + '.' + 'AUTOMATIC').val) + break; + case 'MANT': + setIfExists(words[2] + '.' + 'MANUAL', !getState(words[2] + '.' + 'MANUAL').val) + break; + case 'VACT': + setIfExists(words[2] + '.' + 'VACATION', !getState(words[2] + '.' + 'VACATION').val) + break; + } + let modes = ['BOOT', 'PART', 'AUTT', 'MANT', 'VACT'] + let modesDP = ['BOOST', 'PARTY', 'AUTOMATIC', 'MANUAL', 'VACATION'] + for (let mode=0; mode < 5; mode++) { + if (words[4] != modes[mode]) { + setIfExists(words[2] + '.' + modesDP[mode], false) + } + } + GeneratePage(config.pages[pageId]); + } else { + var HVACMode = 0; + switch (words[4]) { + case 'POWER': + HVACMode = 0; + setIfExists(words[2] + '.' + words[4], !getState(words[2] + '.' + words[4]).val) + if (getState(words[2] + '.' + words[4]).val) { + HVACMode = 1; + } + break; + case 'AUTO': + HVACMode = 1; + break; + case 'COOL': + HVACMode = 2; + break; + case 'HEAT': + HVACMode = 3; + break; + case 'ECO': + HVACMode = 4; + break; + case 'FAN': + HVACMode = 5; + break; + case 'DRY': + HVACMode = 6; + break; + case 'SWING': + HVACMode = getState(words[2] + '.MODE').val; + if (getState(words[2] + '.SWING').val == 0) { + setIfExists(words[2] + '.SWING', 1); + } else { + setIfExists(words[2] + '.' + 'SWING', 0); + } + break; + } + setIfExists(words[2] + '.' + 'MODE', HVACMode) + GeneratePage(config.pages[pageId]); + } + + break; + case 'number-set': + setIfExists(id + '.SET', parseInt(words[4])) ? true : setIfExists(id + '.ACTUAL', parseInt(words[4])); + break; + case 'A1': // Alarm-Page Alarm 1 aktivieren + if (words[4] != '') { + setIfExists(id + '.TYPE', 'A1'); + setIfExists(id + '.PIN', words[4]); + setIfExists(id + '.ACTUAL', 'arming'); + setIfExists(id + '.PANEL', NSPanel_Path); + } + setTimeout(function(){ + GeneratePage(activePage); + },250) + break; + case 'A2': // Alarm-Page Alarm 2 aktivieren + if (words[4] != '') { + setIfExists(id + '.TYPE', 'A2'); + setIfExists(id + '.PIN', words[4]); + setIfExists(id + '.ACTUAL', 'arming'); + setIfExists(id + '.PANEL', NSPanel_Path); + } + setTimeout(function(){ + GeneratePage(activePage); + },250) + break; + case 'A3': // Alarm-Page Alarm 3 aktivieren + if (words[4] != '') { + setIfExists(id + '.TYPE', 'A3'); + setIfExists(id + '.PIN', words[4]); + setIfExists(id + '.ACTUAL', 'arming'); + setIfExists(id + '.PANEL', NSPanel_Path); + } + setTimeout(function(){ + GeneratePage(activePage); + },250) + break; + case 'A4': // Alarm-Page Alarm 4 aktivieren + if (words[4] != '') { + setIfExists(id + '.TYPE', 'A4'); + setIfExists(id + '.PIN', words[4]); + setIfExists(id + '.ACTUAL', 'arming'); + setIfExists(id + '.PANEL', NSPanel_Path); + } + setTimeout(function(){ + GeneratePage(activePage); + },250) + break; + case 'D1': // Alarm-Page Alarm Deaktivieren + if (Debug) console.log('D1: ' + getState(id + '.PIN').val); + if (Debug) console.log(words[4]); + if (words[4] != '') { + if (getState(id + '.PIN').val == words[4]) { + setIfExists(id + '.PIN', '0000'); + setIfExists(id + '.TYPE', 'D1'); + setIfExists(id + '.ACTUAL', 'pending'); + setIfExists(id + '.PIN_Failed', 0); + } else { + setIfExists(id + '.PIN_Failed', getState(id + '.PIN_Failed').val + 1); + setIfExists(id + '.ACTUAL', 'triggered'); + } + setIfExists(id + '.PANEL', NSPanel_Path); + setTimeout(function(){ + GeneratePage(activePage); + },500) + } + break; + default: + break; + } + } catch (err) { + console.log('function HandleButtonEvent: ' + err.message); + } +} + +function GetNavigationString(pageId: number): string { + try { + + if (Debug) console.log(pageId); + + if (activePage.subPage) + return '1|0'; + + switch (pageId) { + case 0: + return '0|1'; + case config.pages.length - 1: + return '1|0'; + case -1: + return '2|0'; + case -2: + return '2|0'; + default: + return '1|1'; + } + } catch (err) { + console.log('function GetNavigationString: ' + err.message); + } +} + +function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { + try { + var out_msgs: Array = []; + let id = pageItem.id + + if (existsObject(id)) { + var o = getObject(id) + var val: (boolean | number) = 0; + let icon = Icons.GetIcon('lightbulb'); + var iconColor = rgb_dec565(config.defaultColor); + + if (type == 'popupLight') { + let switchVal = '0'; + let brightness = 0; + if (o.common.role == 'light' || o.common.role == 'socket') { + if (existsState(id + '.GET')) { + val = getState(id + '.GET').val; + RegisterDetailEntityWatcher(id + '.GET', pageItem, type); + } else if (existsState(id + '.SET')) { + val = getState(id + '.SET').val; + RegisterDetailEntityWatcher(id + '.SET', pageItem, type); + } + + icon = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); + + if (val) { + switchVal = '1'; + iconColor = GetIconColor(pageItem, true, true); + } else { + iconColor = GetIconColor(pageItem, false, true); + } + + out_msgs.push({ + payload: 'entityUpdateDetail' + '~' // entityUpdateDetail + + id + '~' + + icon + '~' // iconId + + iconColor + '~' // iconColor + + switchVal + '~' // buttonState + + 'disable' + '~' // sliderBrightnessPos + + 'disable' + '~' // sliderColorTempPos + + 'disable' + '~' // colorMode + + '' + '~' // Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' // Temperature-Bezeichnung + + findLocale('lights', 'Brightness') + }); // Brightness-Bezeichnung + } + + // Dimmer + if (o.common.role == 'dimmer') { + if (existsState(id + '.ON_ACTUAL')) { + val = getState(id + '.ON_ACTUAL').val; + RegisterDetailEntityWatcher(id + '.ON_ACTUAL', pageItem, type); + } else if (existsState(id + '.ON_SET')) { + val = getState(id + '.ON_SET').val; + RegisterDetailEntityWatcher(id + '.ON_SET', pageItem, type); + } + + if (val === true) { + var iconColor = GetIconColor(pageItem, val, false); + switchVal = '1' + } + + if (existsState(id + '.ACTUAL')) { + if (pageItem.minValueBrightness != undefined && pageItem.maxValueBrightness != undefined) { + brightness = Math.trunc(scale(getState(id + '.ACTUAL').val, pageItem.minValueBrightness, pageItem.maxValueBrightness, 100, 0)); + } else { + brightness = getState(id + '.ACTUAL').val; + } + } else { + console.warn('Alisas-Datenpunkt: ' + id + '.ACTUAL could not be read'); + } + + if (val === true) { + iconColor = GetIconColor(pageItem, 100 - brightness, true); + switchVal = '1'; + } else { + iconColor = GetIconColor(pageItem, false, true); + } + + RegisterDetailEntityWatcher(id + '.ACTUAL', pageItem, type); + + out_msgs.push({ + payload: 'entityUpdateDetail' + '~' //entityUpdateDetail + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + 'disable' + '~' //sliderColorTempPos + + 'disable' + '~' //colorMod + + '' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') + }); //Brightness-Bezeichnung + + console.log('light.' + id) + + } + + // HUE-Licht + if (o.common.role == 'hue') { + + if (existsState(id + '.ON_ACTUAL')) { + val = getState(id + '.ON_ACTUAL').val; + RegisterDetailEntityWatcher(id + '.ON_ACTUAL', pageItem, type); + } + + if (existsState(id + '.DIMMER')) { + if (pageItem.minValueBrightness != undefined && pageItem.maxValueBrightness != undefined) { + brightness = Math.trunc(scale(getState(id + '.DIMMER').val, pageItem.minValueBrightness, pageItem.maxValueBrightness, 100, 0)); + } else { + brightness = getState(id + '.DIMMER').val; + } + RegisterDetailEntityWatcher(id + '.DIMMER', pageItem, type); + } else { + console.warn('Alias-Datenpunkt: ' + id + '.DIMMER could not be read'); + } + + if (val === true) { + iconColor = GetIconColor(pageItem, 100 - brightness, true); + switchVal = '1'; + } else { + iconColor = GetIconColor(pageItem, false, true); + } + + var colorMode = 'disable'; + if (existsState(id + '.HUE')) { + if (getState(id + '.HUE').val != null) { + colorMode = 'enable'; + let huecolor = hsv2rgb(getState(id + '.HUE').val, 1, 1); + let rgb = { red: Math.round(huecolor[0]), green: Math.round(huecolor[1]), blue: Math.round(huecolor[2]) } + iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); + //RegisterDetailEntityWatcher(id + '.HUE', pageItem, type); + } + } + + var colorTemp = 0; + if (existsState(id + '.TEMPERATURE')) { + if (getState(id + '.TEMPERATURE').val != null) { + if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); + } else { + colorTemp = 100 - getState(id + '.TEMPERATURE').val; + } + //RegisterDetailEntityWatcher(id + '.TEMPERATURE', pageItem, type); + } + } else { + console.warn('Alias-Datenpunkt: ' + id + '.TEMPERATURE could not be read'); + } + + out_msgs.push({ + payload: 'entityUpdateDetail' + '~' //entityUpdateDetail + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') + }); //Brightness-Bezeichnung + } + + // RGB-Licht + if (o.common.role == 'rgb') { + + if (existsState(id + '.ON_ACTUAL')) { + val = getState(id + '.ON_ACTUAL').val; + RegisterDetailEntityWatcher(id + '.ON_ACTUAL', pageItem, type); + } + + if (existsState(id + '.DIMMER')) { + if (pageItem.minValueBrightness != undefined && pageItem.maxValueBrightness != undefined) { + brightness = Math.trunc(scale(getState(id + '.DIMMER').val, pageItem.minValueBrightness, pageItem.maxValueBrightness, 100, 0)); + } else { + brightness = getState(id + '.DIMMER').val; + } + RegisterDetailEntityWatcher(id + '.DIMMER', pageItem, type); + } else { + console.warn('Alias-Datenpunkt: ' + id + '.DIMMER could not be read'); + } + + if (val === true) { + iconColor = GetIconColor(pageItem, 100 - brightness, true); + switchVal = '1'; + } else { + iconColor = GetIconColor(pageItem, false, true); + } + + var colorMode = 'disable'; + if (existsState(id + '.RED') && existsState(id + '.GREEN') && existsState(id + '.BLUE')) { + if (getState(id + '.RED').val != null && getState(id + '.GREEN').val != null && getState(id + '.BLUE').val != null) { + colorMode = 'enable'; + let rgb = { red: Math.round(getState(id + '.RED').val), green: Math.round(getState(id + '.GREEN').val), blue: Math.round(getState(id + '.BLUE').val) } + iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); + //RegisterDetailEntityWatcher(id + '.HUE', pageItem, type); + } + } + + var colorTemp = 0; + if (existsState(id + '.TEMPERATURE')) { + if (getState(id + '.TEMPERATURE').val != null) { + if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); + } else { + colorTemp = 100 - getState(id + '.TEMPERATURE').val; + } + //RegisterDetailEntityWatcher(id + '.TEMPERATURE', pageItem, type); + } + } else { + console.warn('Alias-Datenpunkt: ' + id + '.TEMPERATURE could not be read'); + } + + out_msgs.push({ + payload: 'entityUpdateDetail' + '~' //entityUpdateDetail + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') + }); //Brightness-Bezeichnung + } + + // RGB-Licht-einzeln (HEX) + if (o.common.role == 'rgbSingle') { + + if (existsState(id + '.ON_ACTUAL')) { + val = getState(id + '.ON_ACTUAL').val; + RegisterDetailEntityWatcher(id + '.ON_ACTUAL', pageItem, type); + } + + if (existsState(id + '.DIMMER')) { + if (pageItem.minValueBrightness != undefined && pageItem.maxValueBrightness != undefined) { + brightness = Math.trunc(scale(getState(id + '.DIMMER').val, pageItem.minValueBrightness, pageItem.maxValueBrightness, 100, 0)); + } else { + brightness = getState(id + '.DIMMER').val; + } + RegisterDetailEntityWatcher(id + '.DIMMER', pageItem, type); + } else { + console.warn('Alias-Datenpunkt: ' + id + '.DIMMER could not be read'); + } + + if (val === true) { + iconColor = GetIconColor(pageItem, 100 - brightness, true); + switchVal = '1'; + } else { + iconColor = GetIconColor(pageItem, false, true); + } + + var colorMode = 'disable'; + if (existsState(id + '.RGB')) { + if (getState(id + '.RGB').val != null) { + colorMode = 'enable'; + var hex = getState(id + '.RGB').val; + var hexRed = parseInt(hex[1] + hex[2], 16); + var hexGreen = parseInt(hex[3] + hex[4], 16); + var hexBlue = parseInt(hex[5] + hex[6], 16); + let rgb = { red: Math.round(hexRed), green: Math.round(hexGreen), blue: Math.round(hexBlue) } + iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); + //RegisterDetailEntityWatcher(id + '.HUE', pageItem, type); + } + } + + var colorTemp = 0; + if (existsState(id + '.TEMPERATURE')) { + if (getState(id + '.TEMPERATURE').val != null) { + if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); + } else { + colorTemp = 100 - getState(id + '.TEMPERATURE').val; + } + //RegisterDetailEntityWatcher(id + '.TEMPERATURE', pageItem, type); + } + } else { + console.warn('Alias-Datenpunkt: ' + id + '.TEMPERATURE could not be read'); + } + + out_msgs.push({ + payload: 'entityUpdateDetail' + '~' //entityUpdateDetail + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') + }); //Brightness-Bezeichnung + } + + // Farbtemperatur + if (o.common.role == 'ct') { + + if (existsState(id + '.ON')) { + val = getState(id + '.ON').val; + RegisterDetailEntityWatcher(id + '.ON', pageItem, type); + } + + if (existsState(id + '.DIMMER')) { + if (pageItem.minValueBrightness != undefined && pageItem.maxValueBrightness != undefined) { + brightness = Math.trunc(scale(getState(id + '.DIMMER').val, pageItem.minValueBrightness, pageItem.maxValueBrightness, 100, 0)); + } else { + brightness = getState(id + '.DIMMER').val; + } + RegisterDetailEntityWatcher(id + '.DIMMER', pageItem, type); + } else { + console.warn('Alias-Datenpunkt: ' + id + '.DIMMER could not be read'); + } + + if (val === true) { + iconColor = GetIconColor(pageItem, 100 - brightness, true); + switchVal = '1'; + } else { + iconColor = GetIconColor(pageItem, false, true); + } + + var colorMode = 'disable'; + + var colorTemp = 0; + if (existsState(id + '.TEMPERATURE')) { + if (getState(id + '.TEMPERATURE').val != null) { + if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); + } else { + colorTemp = 100 - getState(id + '.TEMPERATURE').val; + } + //RegisterDetailEntityWatcher(id + '.TEMPERATURE', pageItem, type); + } + } else { + console.warn('Alias-Datenpunkt: ' + id + '.TEMPERATURE could not be read'); + } + + out_msgs.push({ + payload: 'entityUpdateDetail' + '~' //entityUpdateDetail + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') + }); //Brightness-Bezeichnung + } + } + + if (type == 'popupShutter') { + icon = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('window-open'); + if (existsState(id + '.ACTUAL')) { + val = getState(id + '.ACTUAL').val; + RegisterDetailEntityWatcher(id + '.ACTUAL', pageItem, type); + } else if (existsState(id + '.SET')) { + val = getState(id + '.SET').val; + RegisterDetailEntityWatcher(id + '.SET', pageItem, type); + } + var tilt_position: any = 'disabled' + if (existsState(id + '.TILT_ACTUAL')) { + tilt_position = getState(id + '.TILT_ACTUAL').val; + RegisterDetailEntityWatcher(id + '.TILT_ACTUAL', pageItem, type); + } else if (existsState(id + '.TILT_SET')) { + tilt_position = getState(id + '.TILT_SET').val; + RegisterDetailEntityWatcher(id + '.TILT_SET', pageItem, type); + } + + let textSecondRow = ''; + let icon_id = icon; + let icon_up = Icons.GetIcon('arrow-up'); + let icon_stop = Icons.GetIcon('stop'); + let icon_down = Icons.GetIcon('arrow-down'); + let icon_up_status = getState(id + '.ACTUAL').val != 100 ? 'enable' : 'disable'; + let icon_stop_status = 'enable'; + let icon_down_status = getState(id + '.ACTUAL').val != 0 ? 'enable' : 'disable'; + let textTilt = ''; + let iconTiltLeft = ''; + let iconTiltStop = ''; + let iconTiltRight = ''; + let iconTiltLeftStatus = 'disable'; + let iconTiltStopStatus = 'disable'; + let iconTiltRightStatus = 'disable'; + let tilt_pos = 'disable'; + + if (existsState(id + '.TILT_SET')) { + textTilt = findLocale('blinds', 'Tilt'); + iconTiltLeft = Icons.GetIcon('arrow-top-right'); + iconTiltStop = Icons.GetIcon('stop'); + iconTiltRight = Icons.GetIcon('arrow-bottom-left'); + iconTiltLeftStatus = getState(id + '.TILT_ACTUAL').val != 100 ? 'enable' : 'disable'; + iconTiltStopStatus = 'enable'; + iconTiltRightStatus = getState(id + '.TILT_ACTUAL').val != 0 ? 'enable' : 'disable'; + tilt_pos = tilt_position; + } + + if (pageItem.secondRow != undefined) { + textSecondRow = pageItem.secondRow; + } + + out_msgs.push({ + payload: 'entityUpdateDetail' + '~' //entityUpdateDetail + + id + '~' //entity_id + + val + '~' //Shutterposition + + textSecondRow + '~' //pos_status 2.line + + findLocale('blinds', 'Position') + '~' //pos_translation + + icon_id + '~' //{icon_id}~ + + icon_up + '~' //{icon_up}~ + + icon_stop + '~' //{icon_stop}~ + + icon_down + '~' //{icon_down}~ + + icon_up_status + '~' //{icon_up_status}~ + + icon_stop_status + '~' //{icon_stop_status}~ + + icon_down_status + '~' //{icon_down_status}~ + + textTilt + '~' //{textTilt}~ + + iconTiltLeft + '~' //{iconTiltLeft}~ + + iconTiltStop + '~' //{iconTiltStop}~ + + iconTiltRight + '~' //{iconTiltRight}~ + + iconTiltLeftStatus + '~' //{iconTiltLeftStatus}~ + + iconTiltStopStatus + '~' //{iconTiltStopStatus}~ + + iconTiltRightStatus + '~' //{iconTiltRightStatus}~ + + tilt_pos //{tilt_pos}") + }); + } + } + + return out_msgs; + + } catch (err) { + console.log('function GenerateDetailPage: ' + err.message); + } +} + +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) { + console.log('function scale: ' + err.message); + } +} + +function UnsubscribeWatcher(): void { + try { + for (const [key, value] of Object.entries(subscriptions)) { + unsubscribe(value); + delete subscriptions[key]; + } + } catch (err) { + console.log('function UnsubscribeWatcher: ' + err.message); + } +} + +function HandleScreensaver(): void { + SendToPanel({ payload: 'pageType~screensaver' }); + UnsubscribeWatcher(); + HandleScreensaverUpdate(); + HandleScreensaverColors(); +} + +function HandleScreensaverUpdate(): void { + try { + if (screensaverEnabled && config.weatherEntity != null && existsObject(config.weatherEntity)) { + var icon = getState(config.weatherEntity + '.ICON').val; + + let temperature = + existsState(config.weatherEntity + '.ACTUAL') ? getState(config.weatherEntity + '.ACTUAL').val : + existsState(config.weatherEntity + '.TEMP') ? getState(config.weatherEntity + '.TEMP').val : 'null'; + + if (config.alternativeScreensaverLayout) { + temperature = parseInt(Math.round(temperature).toFixed()); + } + + let payloadString = + 'weatherUpdate~' + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + '~' + + temperature + ' ' + config.temperatureUnit + '~'; + + vwIconColor[0] = GetAccuWeatherIconColor(parseInt(icon)); + if (Debug) console.log(GetAccuWeatherIconColor(parseInt(icon))); + + if (weatherForecast) { + // Accu-Weather Forecast Tag 2 - Tag 5 -- Wenn weatherForecast = true + for (let i = 2; i < 6; i++) { + let TempMax = getState('accuweather.0.Summary.TempMax_d' + i).val; + let DayOfWeek = getState('accuweather.0.Summary.DayOfWeek_d' + i).val; + let WeatherIcon = GetAccuWeatherIcon(getState('accuweather.0.Summary.WeatherIcon_d' + i).val); + vwIconColor[i-1] = GetAccuWeatherIconColor(getState('accuweather.0.Summary.WeatherIcon_d' + i).val); + if (Debug) console.log(vwIconColor[i-1]); + payloadString += DayOfWeek + '~' + Icons.GetIcon(WeatherIcon) + '~' + TempMax + ' ' + config.temperatureUnit + '~'; + } + } else { + payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity); + payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity); + payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity); + payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity); + + const colorScale0: RGB = { red: 99, green: 190, blue: 123 }; + const colorScale1: RGB = { red: 129, green: 199, blue: 126 }; + const colorScale2: RGB = { red: 161, green: 208, blue: 127 }; + const colorScale3: RGB = { red: 129, green: 217, blue: 126 }; + const colorScale4: RGB = { red: 222, green: 226, blue: 131 }; + const colorScale5: RGB = { red: 254, green: 235, blue: 132 }; + const colorScale6: RGB = { red: 255, green: 210, blue: 129 }; + const colorScale7: RGB = { red: 251, green: 185, blue: 124 }; + const colorScale8: RGB = { red: 251, green: 158, blue: 117 }; + const colorScale9: RGB = { red: 248, green: 131, blue: 111 }; + const colorScale10: RGB = { red: 248, green: 105, blue: 107 }; + + if (config.firstScreensaverEntity.ScreensaverEntityIconColor != undefined) { + if (typeof getState(config.firstScreensaverEntity.ScreensaverEntity).val == 'boolean') { + vwIconColor[1] = (getState(config.firstScreensaverEntity.ScreensaverEntity).val == true) ? rgb_dec565(colorScale10) : rgb_dec565(colorScale0); + } else if (typeof config.firstScreensaverEntity.ScreensaverEntityIconColor == 'object') { + let iconvalmin = (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_min != undefined) ? config.firstScreensaverEntity.ScreensaverEntityIconColor.val_min : 0 ; + let iconvalmax = (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_max != undefined) ? config.firstScreensaverEntity.ScreensaverEntityIconColor.val_max : 100 ; + let iconvalbest = (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_best != undefined) ? config.firstScreensaverEntity.ScreensaverEntityIconColor.val_best : iconvalmin ; + let valueScale = getState(config.firstScreensaverEntity.ScreensaverEntity).val; + + if (iconvalmin == 0 && iconvalmax == 1) { + vwIconColor[1] = (getState(config.firstScreensaverEntity.ScreensaverEntity).val == 1) ? rgb_dec565(colorScale0) : rgb_dec565(colorScale10); + } else { + if (iconvalbest == iconvalmin) { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } else { + if (valueScale < iconvalbest) { + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + } else { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } + } + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) console.log(valueScaletemp); + switch (valueScaletemp) { + case '0': + vwIconColor[1] = rgb_dec565(colorScale0); + break; + case '1': + vwIconColor[1] = rgb_dec565(colorScale1); + break; + case '2': + vwIconColor[1] = rgb_dec565(colorScale2); + break; + case '3': + vwIconColor[1] = rgb_dec565(colorScale3); + break; + case '4': + vwIconColor[1] = rgb_dec565(colorScale4); + break; + case '5': + vwIconColor[1] = rgb_dec565(colorScale5); + break; + case '6': + vwIconColor[1] = rgb_dec565(colorScale6); + break; + case '7': + vwIconColor[1] = rgb_dec565(colorScale7); + break; + case '8': + vwIconColor[1] = rgb_dec565(colorScale8); + break; + case '9': + vwIconColor[1] = rgb_dec565(colorScale9); + break; + case '10': + vwIconColor[1] = rgb_dec565(colorScale10); + break; + } + } + if (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[1] = rgb_dec565(config.firstScreensaverEntity.ScreensaverEntityIconColor); + } + } else { + vwIconColor[1] = rgb_dec565(sctF1Icon); + } + } else { + vwIconColor[1] = rgb_dec565(sctF1Icon); + } + + if (config.secondScreensaverEntity.ScreensaverEntityIconColor != undefined) { + if (typeof getState(config.secondScreensaverEntity.ScreensaverEntity).val == 'boolean') { + vwIconColor[2] = (getState(config.secondScreensaverEntity.ScreensaverEntity).val == true) ? rgb_dec565(colorScale10) : rgb_dec565(colorScale0); + } else if (typeof config.secondScreensaverEntity.ScreensaverEntityIconColor == 'object') { + + let iconvalmin = (config.secondScreensaverEntity.ScreensaverEntityIconColor.val_min != undefined) ? config.secondScreensaverEntity.ScreensaverEntityIconColor.val_min : 0 ; + let iconvalmax = (config.secondScreensaverEntity.ScreensaverEntityIconColor.val_max != undefined) ? config.secondScreensaverEntity.ScreensaverEntityIconColor.val_max : 100 ; + let iconvalbest = (config.secondScreensaverEntity.ScreensaverEntityIconColor.val_best != undefined) ? config.secondScreensaverEntity.ScreensaverEntityIconColor.val_best : iconvalmin ; + let valueScale = getState(config.secondScreensaverEntity.ScreensaverEntity).val; + + if (iconvalmin == 0 && iconvalmax == 1) { + vwIconColor[2] = (getState(config.secondScreensaverEntity.ScreensaverEntity).val == 1) ? rgb_dec565(colorScale0) : rgb_dec565(colorScale10); + } else { + if (iconvalbest == iconvalmin) { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } else { + if (valueScale < iconvalbest) { + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + } else { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } + } + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) console.log(valueScaletemp); + switch (valueScaletemp) { + case '0': + vwIconColor[2] = rgb_dec565(colorScale0); + break; + case '1': + vwIconColor[2] = rgb_dec565(colorScale1); + break; + case '2': + vwIconColor[2] = rgb_dec565(colorScale2); + break; + case '3': + vwIconColor[2] = rgb_dec565(colorScale3); + break; + case '4': + vwIconColor[2] = rgb_dec565(colorScale4); + break; + case '5': + vwIconColor[2] = rgb_dec565(colorScale5); + break; + case '6': + vwIconColor[2] = rgb_dec565(colorScale6); + break; + case '7': + vwIconColor[2] = rgb_dec565(colorScale7); + break; + case '8': + vwIconColor[2] = rgb_dec565(colorScale8); + break; + case '9': + vwIconColor[2] = rgb_dec565(colorScale9); + break; + case '10': + vwIconColor[2] = rgb_dec565(colorScale10); + break; + } + } + if (config.secondScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[2] = rgb_dec565(config.secondScreensaverEntity.ScreensaverEntityIconColor); + } + } else { + vwIconColor[2] = rgb_dec565(sctF2Icon); + } + } else { + vwIconColor[2] = rgb_dec565(sctF2Icon); + } + + if (config.thirdScreensaverEntity.ScreensaverEntityIconColor != undefined) { + if (typeof getState(config.thirdScreensaverEntity.ScreensaverEntity).val == 'boolean') { + vwIconColor[3] = (getState(config.thirdScreensaverEntity.ScreensaverEntity).val == true) ? rgb_dec565(colorScale10) : rgb_dec565(colorScale0); + } else if (typeof config.thirdScreensaverEntity.ScreensaverEntityIconColor == 'object') { + + let iconvalmin = (config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_min != undefined) ? config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_min : 0 ; + let iconvalmax = (config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_max != undefined) ? config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_max : 100 ; + let iconvalbest = (config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_best != undefined) ? config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_best : iconvalmin ; + let valueScale = getState(config.thirdScreensaverEntity.ScreensaverEntity).val; + + if (iconvalmin == 0 && iconvalmax == 1) { + vwIconColor[3] = (getState(config.thirdScreensaverEntity.ScreensaverEntity).val == 1) ? rgb_dec565(colorScale0) : rgb_dec565(colorScale10); + } else { + if (iconvalbest == iconvalmin) { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } else { + if (valueScale < iconvalbest) { + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + } else { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } + } + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) console.log(valueScaletemp); + switch (valueScaletemp) { + case '0': + vwIconColor[3] = rgb_dec565(colorScale0); + break; + case '1': + vwIconColor[3] = rgb_dec565(colorScale1); + break; + case '2': + vwIconColor[3] = rgb_dec565(colorScale2); + break; + case '3': + vwIconColor[3] = rgb_dec565(colorScale3); + break; + case '4': + vwIconColor[3] = rgb_dec565(colorScale4); + break; + case '5': + vwIconColor[3] = rgb_dec565(colorScale5); + break; + case '6': + vwIconColor[3] = rgb_dec565(colorScale6); + break; + case '7': + vwIconColor[3] = rgb_dec565(colorScale7); + break; + case '8': + vwIconColor[3] = rgb_dec565(colorScale8); + break; + case '9': + vwIconColor[3] = rgb_dec565(colorScale9); + break; + case '10': + vwIconColor[3] = rgb_dec565(colorScale10); + break; + } + } + if (config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[3] = rgb_dec565(config.thirdScreensaverEntity.ScreensaverEntityIconColor); + } + } else { + vwIconColor[3] = rgb_dec565(sctF2Icon); + } + } else { + vwIconColor[3] = rgb_dec565(sctF2Icon); + } + + if (config.fourthScreensaverEntity.ScreensaverEntityIconColor != undefined) { + if (typeof getState(config.fourthScreensaverEntity.ScreensaverEntity).val == 'boolean') { + vwIconColor[4] = (getState(config.fourthScreensaverEntity.ScreensaverEntity).val == true) ? rgb_dec565(colorScale10) : rgb_dec565(colorScale0); + } else if (typeof config.fourthScreensaverEntity.ScreensaverEntityIconColor == 'object') { + + let iconvalmin = (config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_min != undefined) ? config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_min : 0 ; + let iconvalmax = (config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_max != undefined) ? config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_max : 100 ; + let iconvalbest = (config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_best != undefined) ? config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_best : iconvalmin ; + let valueScale = getState(config.fourthScreensaverEntity.ScreensaverEntity).val; + + if (iconvalmin == 0 && iconvalmax == 1) { + vwIconColor[4] = (getState(config.fourthScreensaverEntity.ScreensaverEntity).val == 1) ? rgb_dec565(colorScale0) : rgb_dec565(colorScale10); + } else { + if (iconvalbest == iconvalmin) { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } else { + if (valueScale < iconvalbest) { + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + } else { + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + } + } + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) console.log(valueScaletemp); + switch (valueScaletemp) { + case '0': + vwIconColor[4] = rgb_dec565(colorScale0); + break; + case '1': + vwIconColor[4] = rgb_dec565(colorScale1); + break; + case '2': + vwIconColor[4] = rgb_dec565(colorScale2); + break; + case '3': + vwIconColor[4] = rgb_dec565(colorScale3); + break; + case '4': + vwIconColor[4] = rgb_dec565(colorScale4); + break; + case '5': + vwIconColor[4] = rgb_dec565(colorScale5); + break; + case '6': + vwIconColor[4] = rgb_dec565(colorScale6); + break; + case '7': + vwIconColor[4] = rgb_dec565(colorScale7); + break; + case '8': + vwIconColor[4] = rgb_dec565(colorScale8); + break; + case '9': + vwIconColor[4] = rgb_dec565(colorScale9); + break; + case '10': + vwIconColor[4] = rgb_dec565(colorScale10); + break; + } + } + if (config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { + vwIconColor[4] = rgb_dec565(config.fourthScreensaverEntity.ScreensaverEntityIconColor); + } + } else { + vwIconColor[4] = rgb_dec565(sctF2Icon); + } + } else { + vwIconColor[4] = rgb_dec565(sctF2Icon); + } + } + + //AltLayout + if (config.alternativeScreensaverLayout) { + payloadString += parseInt(getState(config.fourthScreensaverEntity.ScreensaverEntity).val) + '~'; + payloadString += config.fourthScreensaverEntity.ScreensaverEntityUnitText + '~' + } else { + payloadString += '~~' + } + + let hwBtn1Col: any = config.mrIcon1ScreensaverEntity.ScreensaverEntityOffColor; + if (config.mrIcon1ScreensaverEntity.ScreensaverEntity != null) { + if (typeof (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) == 'string') { + let hwBtn1: string = getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val; + if (hwBtn1 == 'ON') { + hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor; + } + payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn1Col) + '~'; + } else if (typeof (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) == 'boolean') { + let hwBtn1: boolean = getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val; + if (hwBtn1) { + hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor; + } + payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn1Col) + '~'; + } + } else { + hwBtn1Col = Black; + payloadString += '~~'; + } + + let hwBtn2Col: any = config.mrIcon2ScreensaverEntity.ScreensaverEntityOffColor; + if (config.mrIcon2ScreensaverEntity.ScreensaverEntity != null) { + if (typeof (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) == 'string') { + let hwBtn2: string = getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val; + if (hwBtn2 == 'ON') { + hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor; + } + payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn2Col) + '~'; + } else if (typeof (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) == 'boolean') { + let hwBtn2: boolean = getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val; + if (hwBtn2) { + hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor; + } + payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn2Col) + '~'; + } + } else { + hwBtn2Col = Black; + payloadString += '~~'; + } + HandleScreensaverColors(); + + SendToPanel({ payload: payloadString }); + + } + } catch (err) { + console.log('HandleScreensaverUpdate: ' + err.message); + } +} + +function HandleScreensaverColors(): void { + try { + let vwIcon = []; + if (config.autoWeatherColorScreensaverLayout) { + vwIcon[0] = vwIconColor[0]; + vwIcon[1] = vwIconColor[1]; + vwIcon[2] = vwIconColor[2]; + vwIcon[3] = vwIconColor[3]; + vwIcon[4] = vwIconColor[4]; + } else { + if (weatherForecast) { + vwIcon[0] = rgb_dec565(sctMainIcon); + vwIcon[1] = rgb_dec565(sctF1Icon); + vwIcon[2] = rgb_dec565(sctF2Icon); + vwIcon[3] = rgb_dec565(sctF3Icon); + vwIcon[4] = rgb_dec565(sctF4Icon); + } else { + vwIcon[0] = rgb_dec565(sctMainIcon); + vwIcon[1] = vwIconColor[1]; + vwIcon[2] = vwIconColor[2]; + vwIcon[3] = vwIconColor[3]; + vwIcon[4] = vwIconColor[4]; + } + } + + let payloadString = 'color' + '~' + + rgb_dec565(scbackground) + '~' + //background + rgb_dec565(sctime) + '~' + //time + rgb_dec565(sctimeAMPM) + '~' + //timeAMPM~ + rgb_dec565(scdate) + '~' + //date~ + vwIcon[0] + '~' + //tMainIcon~ rgb_dec565(sctMainIcon) + rgb_dec565(sctMainText) + '~' + //tMainText~ + rgb_dec565(sctForecast1) + '~' + //tForecast1~ + rgb_dec565(sctForecast2) + '~' + //tForecast2~ + rgb_dec565(sctForecast3) + '~' + //tForecast3~ + rgb_dec565(sctForecast4) + '~' + //tForecast4~ + vwIcon[1] + '~' + //tF1Icon~ rgb_dec565(sctF1Icon) + vwIcon[2] + '~' + //tF2Icon~ rgb_dec565(sctF2Icon) + vwIcon[3] + '~' + //tF3Icon~ rgb_dec565(sctF3Icon) + vwIcon[4] + '~' + //tF4Icon~ rgb_dec565(sctF4Icon) + rgb_dec565(sctForecast1Val) + '~' + //tForecast1Val~ + rgb_dec565(sctForecast2Val) + '~' + //tForecast2Val~ + rgb_dec565(sctForecast3Val) + '~' + //tForecast3Val~ + rgb_dec565(sctForecast4Val) + '~' + //tForecast4Val~ + rgb_dec565(scbar) + '~' + //bar~ + rgb_dec565(sctMainIconAlt) + '~' + //tMainIconAlt + rgb_dec565(sctMainTextAlt) + '~' + //tMainTextAlt + rgb_dec565(sctTimeAdd); + //true; + + SendToPanel({ payload: payloadString }); + } catch (err) { + console.warn('HandleScreensaverColors: '+ err.message); + } +} + +function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string { + try { + if (configElement != null && configElement.ScreensaverEntity != null && existsState(configElement.ScreensaverEntity)) { + let u1 = getState(configElement.ScreensaverEntity).val; + + return configElement.ScreensaverEntityText + '~' + Icons.GetIcon(configElement.ScreensaverEntityIcon) + '~' + u1 + ' ' + configElement.ScreensaverEntityUnitText + '~'; + } + else { + return '~~~'; + } + } catch (err) { + console.warn('GetScreenSaverEntityString: '+ err.message); + } +} + +function GetAccuWeatherIcon(icon: number): string { + try { + switch (icon) { + case 24: // Ice + case 30: // Hot + case 31: // Cold + return 'window-open'; // exceptional + + case 7: // Cloudy + case 8: // Dreary (Overcast) + case 38: // Mostly Cloudy + return 'weather-cloudy'; // cloudy + + case 11: // fog + return 'weather-fog'; // fog + + case 25: // Sleet + return 'weather-hail'; // Hail + + case 15: // T-Storms + return 'weather-lightning'; // lightning + + case 16: // Mostly Cloudy w/ T-Storms + case 17: // Partly Sunny w/ T-Storms + case 41: // Partly Cloudy w/ T-Storms + case 42: // Mostly Cloudy w/ T-Storms + return 'weather-lightning-rainy'; // lightning-rainy + + case 33: // Clear + case 34: // Mostly Clear + case 37: // Hazy Moonlight + return 'weather-night'; + + case 3: // Partly Sunny + case 4: // Intermittent Clouds + case 6: // Mostly Cloudy + case 35: // Partly Cloudy + case 36: // Intermittent Clouds + return 'weather-partly-cloudy'; // partlycloudy + + case 18: // pouring + return 'weather-pouring'; // pouring + + case 12: // Showers + case 13: // Mostly Cloudy w/ Showers + case 14: // Partly Sunny w/ Showers + case 26: // Freezing Rain + case 39: // Partly Cloudy w/ Showers + case 40: // Mostly Cloudy w/ Showers + return 'weather-rainy'; // rainy + + case 19: // Flurries + case 20: // Mostly Cloudy w/ Flurries + case 21: // Partly Sunny w/ Flurries + case 22: // Snow + case 23: // Mostly Cloudy w/ Snow + case 43: // Mostly Cloudy w/ Flurries + case 44: // Mostly Cloudy w/ Snow + return 'weather-snowy'; // snowy + + case 29: // Rain and Snow + return 'weather-snowy-rainy'; // snowy-rainy + + case 1: // Sunny + case 2: // Mostly Sunny + case 5: // Hazy Sunshine + return 'weather-sunny'; // sunny + + case 32: // windy + return 'weather-windy'; // windy + + default: + return 'alert-circle-outline'; + } + } catch (err) { + console.warn('GetAccuWeatherIcon: '+ err.message); + } +} + +function GetAccuWeatherIconColor(icon: number): number { + try{ + switch (icon) { + case 24: // Ice + case 30: // Hot + case 31: // Cold + return rgb_dec565(swExceptional); // exceptional + + case 7: // Cloudy + case 8: // Dreary (Overcast) + case 38: // Mostly Cloudy + return rgb_dec565(swCloudy); // cloudy + + case 11: // fog + return rgb_dec565(swFog); // fog + + case 25: // Sleet + return rgb_dec565(swHail); // Hail + + case 15: // T-Storms + return rgb_dec565(swLightning); // lightning + + case 16: // Mostly Cloudy w/ T-Storms + case 17: // Partly Sunny w/ T-Storms + case 41: // Partly Cloudy w/ T-Storms + case 42: // Mostly Cloudy w/ T-Storms + return rgb_dec565(swLightningRainy); // lightning-rainy + + case 33: // Clear + case 34: // Mostly Clear + case 37: // Hazy Moonlight + return rgb_dec565(swClearNight); + + case 3: // Partly Sunny + case 4: // Intermittent Clouds + case 6: // Mostly Cloudy + case 35: // Partly Cloudy + case 36: // Intermittent Clouds + return rgb_dec565(swPartlycloudy); // partlycloudy + + case 18: // pouring + return rgb_dec565(swPouring); // pouring + + case 12: // Showers + case 13: // Mostly Cloudy w/ Showers + case 14: // Partly Sunny w/ Showers + case 26: // Freezing Rain + case 39: // Partly Cloudy w/ Showers + case 40: // Mostly Cloudy w/ Showers + return rgb_dec565(swRainy); // rainy + + case 19: // Flurries + case 20: // Mostly Cloudy w/ Flurries + case 21: // Partly Sunny w/ Flurries + case 22: // Snow + case 23: // Mostly Cloudy w/ Snow + case 43: // Mostly Cloudy w/ Flurries + case 44: // Mostly Cloudy w/ Snow + return rgb_dec565(swSnowy); // snowy + + case 29: // Rain and Snow + return rgb_dec565(swSnowyRainy); // snowy-rainy + + case 1: // Sunny + case 2: // Mostly Sunny + case 5: // Hazy Sunshine + return rgb_dec565(swSunny); // sunny + + case 32: // windy + return rgb_dec565(swWindy); // windy + + default: + return rgb_dec565(White); + } + } catch (err) { + console.warn('GetAccuWeatherIconColor: '+ err.message); + } +} + +//------------------Begin Read Internal Sensor Data +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', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Sensor.TempUnit', { type: 'string' }); + await createStateAsync(NSPanel_Path + 'Sensor.ANALOG.Temperature', { type: 'number', 'unit': '°C' }); + await createStateAsync(NSPanel_Path + 'Sensor.ESP32.Temperature', { type: 'number', 'unit': '°C' }); + + await setStateAsync(NSPanel_Path + 'Sensor.Time', { val: Tasmota_Sensor.Time, ack: true }); + await setStateAsync(NSPanel_Path + 'Sensor.TempUnit', { val: '°' + Tasmota_Sensor.TempUnit, ack: true }); + await setStateAsync(NSPanel_Path + 'Sensor.ANALOG.Temperature', { val: parseFloat(Tasmota_Sensor.ANALOG.Temperature1), ack: true }); + await setStateAsync(NSPanel_Path + 'Sensor.ESP32.Temperature', { val: parseFloat(Tasmota_Sensor.ESP32.Temperature), ack: true }); + } catch (err) { + console.warn('error with reading senor-data: '+ err.message); + } +}); +//------------------End Read Internal Sensor Data + +function GetBlendedColor(percentage: number): RGB { + if (percentage < 50) { + return Interpolate(config.defaultOffColor, config.defaultOnColor, percentage / 50.0); + } + + return Interpolate(Red, White, (percentage - 50) / 50.0); +} + +function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { + var r: number = InterpolateNum(color1.red, color2.red, fraction); + var g: number = InterpolateNum(color1.green, color2.green, fraction); + var b: number = InterpolateNum(color1.blue, color2.blue, fraction); + return { red: Math.round(r), green: Math.round(g), blue: Math.round(b) }; +} + +function InterpolateNum(d1: number, d2: number, fraction: number): number { + return d1 + (d2 - d1) * fraction; +} + +function rgb_dec565(rgb: RGB): number { + //return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31))); + return ((rgb.red >> 3) << 11) | ((rgb.green >> 2)) << 5 | ((rgb.blue) >> 3) +} + +/* Convert radians to degrees +rad - radians to convert, expects rad in range +/- PI per Math.atan2 +returns {number} degrees equivalent of rad +*/ +function rad2deg(rad) { + return (360 + 180 * rad / Math.PI) % 360; +} + +function ColorToHex(color) { + var hexadecimal = color.toString(16); + return hexadecimal.length == 1 ? '0' + hexadecimal : hexadecimal; +} + +function ConvertRGBtoHex(red: number, green: number, blue: Number) { + return '#' + ColorToHex(red) + ColorToHex(green) + ColorToHex(blue); +} + +/* Convert h,s,v values to r,g,b +hue - in range [0, 360] +saturation - in range 0 to 1 +value - in range 0 to 1 +returns {Array|number} [r, g,b] in range 0 to 255 + */ +function hsv2rgb(hue: number, saturation: number, value: number) { + hue /= 60; + let chroma = value * saturation; + let x = chroma * (1 - Math.abs((hue % 2) - 1)); + let rgb = hue <= 1 ? [chroma, x, 0] : + hue <= 2 ? [x, chroma, 0] : + hue <= 3 ? [0, chroma, x] : + hue <= 4 ? [0, x, chroma] : + hue <= 5 ? [x, 0, chroma] : + [chroma, 0, x]; + + return rgb.map(v => (v + value - chroma) * 255); +} + +function getHue(red: number, green: number, blue: number) { + + var min = Math.min(Math.min(red, green), blue); + var max = Math.max(Math.max(red, green), blue); + + if (min == max) { + return 0; + } + + var hue = 0; + if (max == red) { + hue = (green - blue) / (max - min); + + } else if (max == green) { + hue = 2 + (blue - red) / (max - min); + + } else { + hue = 4 + (red - green) / (max - min); + } + + hue = hue * 60; + if (hue < 0) hue = hue + 360; + + return Math.round(hue); +} + +function pos_to_color(x: number, y: number): RGB { + var r = 160 / 2; + var x = Math.round((x - r) / r * 100) / 100; + var y = Math.round((r - y) / r * 100) / 100; + + r = Math.sqrt(x * x + y * y); + let sat = 0 + if (r > 1) { + sat = 0; + } else { + sat = r; + } + + var hsv = rad2deg(Math.atan2(y, x)); + var rgb = hsv2rgb(hsv, sat, 1); + + return { red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) }; +} + +function rgb_to_cie(red, green, blue) +{ + //Apply a gamma correction to the RGB values, which makes the color more vivid and more the like the color displayed on the screen of your device + let vred = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); + let vgreen = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); + let vblue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); + + //RGB values to XYZ using the Wide RGB D65 conversion formula + let X = vred * 0.664511 + vgreen * 0.154324 + vblue * 0.162028; + let Y = vred * 0.283881 + vgreen * 0.668433 + vblue * 0.047685; + let Z = vred * 0.000088 + vgreen * 0.072310 + vblue * 0.986039; + + //Calculate the xy values from the XYZ values + let ciex = (X / (X + Y + Z)).toFixed(4); + let ciey = (Y / (X + Y + Z)).toFixed(4); + let cie = "[" + ciex + "," + ciey + "]" + + return cie; +} + +function spotifyGetDeviceID(vDeviceString) { + const availableDeviceIDs = getState("spotify-premium.0.devices.availableDeviceListIds").val; + const availableDeviceNames = getState("spotify-premium.0.devices.availableDeviceListString").val; + var arrayDeviceListIds = availableDeviceIDs.split(";"); + var arrayDeviceListSting = availableDeviceNames.split(";"); + var indexPos = arrayDeviceListSting.indexOf(vDeviceString); + var strDevID = arrayDeviceListIds[indexPos]; + return strDevID; +} + +type RGB = { + red: number, + green: number, + blue: number +}; + +type Payload = { + payload: string; +}; + +type Page = { + type: string, + heading: string, + items: PageItem[], + useColor: boolean, + subPage: boolean, + parent: Page, +}; + +interface PageEntities extends Page { + type: 'cardEntities', + items: PageItem[], +}; + +interface PageGrid extends Page { + type: 'cardGrid', + items: PageItem[], +}; + +interface PageThermo extends Page { + type: 'cardThermo', + items: PageItem[], +}; + +interface PageMedia extends Page { + type: 'cardMedia', + items: PageItem[], +}; + +interface PageAlarm extends Page { + type: 'cardAlarm', + items: PageItem[], +}; + +interface PageQR extends Page { + type: 'cardQR', + items: PageItem[], +}; + +interface PagePower extends Page { + type: 'cardPower', + items: PageItem[], +}; + +type PageItem = { + id: string, + icon: (string | undefined), + icon2: (string | undefined), + onColor: (RGB | undefined), + offColor: (RGB | undefined), + useColor: (boolean | undefined), + interpolateColor: (boolean | undefined), + minValueBrightness: (number | undefined), + maxValueBrightness: (number | undefined), + minValueColorTemp: (number | undefined), + maxValueColorTemp: (number | undefined), + minValue: (number | undefined), + maxValue: (number | undefined), + name: (string | undefined), + secondRow: (string | undefined), + buttonText: (string | undefined), + unit: (string | undefined), + navigate: (boolean | undefined), + colormode: (string | undefined), + adapterPlayerInstance: (string | undefined), + mediaDevice: (string | undefined), + targetPage: (string | undefined), + speakerList: (string[] | undefined), + hidePassword: (boolean | undefined) +} + +type DimMode = { + dimmodeOn: (boolean | undefined), + brightnessDay: (number | undefined), + brightnessNight: (number | undefined), + timeDay: (string | undefined), + timeNight: (string | undefined) +} + +type Config = { + panelRecvTopic: string, + panelSendTopic: string, + timeoutScreensaver: number, + dimmode: number, + active: number, + locale: string, + timeFormat: string, + dateFormat: string, + weatherEntity: string | null, + screenSaverDoubleClick: boolean, + temperatureUnit: string, + firstScreensaverEntity: ScreenSaverElement | null, + secondScreensaverEntity: ScreenSaverElement | null, + thirdScreensaverEntity: ScreenSaverElement | null, + fourthScreensaverEntity: ScreenSaverElement | null, + alternativeScreensaverLayout: boolean, + autoWeatherColorScreensaverLayout: boolean, + mrIcon1ScreensaverEntity: ScreenSaverMRElement | null, + mrIcon2ScreensaverEntity: ScreenSaverMRElement | null, + defaultColor: RGB, + defaultOnColor: RGB, + defaultOffColor: RGB, + defaultBackgroundColor: RGB, + pages: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower)[], + subPages: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower)[], + button1Page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower | null), + button2Page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower| null), +}; + +type ScreenSaverElement = { + ScreensaverEntity: string | null, + ScreensaverEntityIcon: string | null, + ScreensaverEntityText: string | null, + ScreensaverEntityUnitText: string | null, + ScreensaverEntityIconColor: any | null, +} + +type ScreenSaverMRElement = { + ScreensaverEntity: string | null, + ScreensaverEntityIcon: string | null, + ScreensaverEntityOnColor: RGB, + ScreensaverEntityOffColor: RGB, +} From 5ce4fa56a1db0f7c076820af18635a1e12564bd3 Mon Sep 17 00:00:00 2001 From: Armilar <102996011+Armilar@users.noreply.github.com> Date: Tue, 25 Oct 2022 22:04:58 +0200 Subject: [PATCH 04/15] v3.5.0 - Upgrade - Add Backgroundcolor to Pages - Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - Add PageNavigation via Datapoint - Add New Parameters to popUpNotify / Layout 2 --- ioBroker/NsPanelTs.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 07e4226e..934d5da4 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -595,10 +595,7 @@ export const config: Config = { panelRecvTopic: 'mqtt.0.SmartHome.NSPanel_1.tele.RESULT', // anpassen panelSendTopic: 'mqtt.0.SmartHome.NSPanel_1.cmnd.CustomSend', // anpassen firstScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Hourly.h0.PrecipitationProbability', ScreensaverEntityIcon: 'weather-pouring', ScreensaverEntityText: 'Regen', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100} }, - //firstScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Hourly.h0.PrecipitationProbability', ScreensaverEntityIcon: 'weather-pouring', ScreensaverEntityText: 'Regen', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: Red }, - secondScreensaverEntity: { ScreensaverEntity: '0_userdata.0.Wetter.Windstaerke_homaticIP', ScreensaverEntityIcon: 'weather-windy', ScreensaverEntityText: 'Wind', ScreensaverEntityUnitText: 'bft', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 12} }, - //secondScreensaverEntity: { ScreensaverEntity: 'deconz.0.Sensors.5.open', ScreensaverEntityIcon: 'window-closed-variant', ScreensaverEntityText: 'Fenster', ScreensaverEntityUnitText: '', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 12} }, - //secondScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.WindSpeed', ScreensaverEntityIcon: 'weather-windy', ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: 'km/h', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 120} }, + secondScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.WindSpeed', ScreensaverEntityIcon: 'weather-windy', ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: 'km/h', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 120} }, thirdScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.UVIndex', ScreensaverEntityIcon: 'solar-power', ScreensaverEntityText: 'UV', ScreensaverEntityUnitText: '', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 9} }, fourthScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.RelativeHumidity', ScreensaverEntityIcon: 'water-percent', ScreensaverEntityText: 'Luft', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100, 'val_best': 65} }, alternativeScreensaverLayout: false, From b659645b25bea381ab0e4e17e28f79b9e3f15f46 Mon Sep 17 00:00:00 2001 From: joBr99 <29555657+joBr99@users.noreply.github.com> Date: Wed, 26 Oct 2022 20:05:48 +0200 Subject: [PATCH 05/15] add arming and triggered for #5414 --- apps/nspanel-lovelace-ui/luibackend/icons.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/nspanel-lovelace-ui/luibackend/icons.py b/apps/nspanel-lovelace-ui/luibackend/icons.py index b8c4999a..caa24798 100644 --- a/apps/nspanel-lovelace-ui/luibackend/icons.py +++ b/apps/nspanel-lovelace-ui/luibackend/icons.py @@ -187,6 +187,10 @@ def map_to_mdi_name(ha_type, state=None, device_class="_", cardType=None): return "weather-night" if state == "armed_vacation": return "shield-airplane" + if state == "arming": + return "shield" + if state == "triggered": + return "shield-home" elif ha_type == "climate": if state in ["auto", "heat_cool"]: return "calendar-sync" From c5f46d827226fd24201d85c801b4855327852383 Mon Sep 17 00:00:00 2001 From: joBr99 <29555657+joBr99@users.noreply.github.com> Date: Wed, 26 Oct 2022 20:08:35 +0200 Subject: [PATCH 06/15] add icons for #541 --- apps/nspanel-lovelace-ui/luibackend/icons.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/nspanel-lovelace-ui/luibackend/icons.py b/apps/nspanel-lovelace-ui/luibackend/icons.py index caa24798..0958b434 100644 --- a/apps/nspanel-lovelace-ui/luibackend/icons.py +++ b/apps/nspanel-lovelace-ui/luibackend/icons.py @@ -187,10 +187,10 @@ def map_to_mdi_name(ha_type, state=None, device_class="_", cardType=None): return "weather-night" if state == "armed_vacation": return "shield-airplane" - if state == "arming": + if state in ["arming", "pending"]: return "shield" if state == "triggered": - return "shield-home" + return "bell-ring" elif ha_type == "climate": if state in ["auto", "heat_cool"]: return "calendar-sync" From 12250b4e117da7ad7cd562106134cb2cbaaf948b Mon Sep 17 00:00:00 2001 From: joBr99 <29555657+joBr99@users.noreply.github.com> Date: Wed, 26 Oct 2022 20:13:39 +0200 Subject: [PATCH 07/15] Update pages.py --- apps/nspanel-lovelace-ui/luibackend/pages.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/apps/nspanel-lovelace-ui/luibackend/pages.py b/apps/nspanel-lovelace-ui/luibackend/pages.py index 529cda70..4fe2ad8f 100644 --- a/apps/nspanel-lovelace-ui/luibackend/pages.py +++ b/apps/nspanel-lovelace-ui/luibackend/pages.py @@ -41,13 +41,9 @@ class LuiPagesGen(object): if ha_type == "alarm_control_panel": if entity.state == "disarmed": icon_color = rgb_dec565([13,160,53]) - if entity.state == "armed_home": - icon_color = rgb_dec565([223,76,30]) - if entity.state == "armed_away": - icon_color = rgb_dec565([223,76,30]) - if entity.state == "armed_night": - icon_color = rgb_dec565([223,76,30]) - if entity.state == "armed_vacation": + if entity.state == "arming": + icon_color = rgb_dec565([244,180,0]) + if entity.state in ["armed_home", "armed_away", "armed_night", "armed_vacation", "pending"]: icon_color = rgb_dec565([223,76,30]) if ha_type == "climate": From b6ab35a2eda5fe42130c049301205b9ce4f3b7eb Mon Sep 17 00:00:00 2001 From: Jens Hartlep Date: Wed, 26 Oct 2022 20:34:35 +0200 Subject: [PATCH 08/15] added null check for .SET state in GenerateThermoPage. In the tado adapter, the level.temperature DP can be null if AWAY or power is off. In this case, use the configured minValue. --- .gitignore | 3 +++ ioBroker/NsPanelTs.ts | 19 +++++++++++++------ ioBroker/NsPanelTs_without_Examples.ts | 19 +++++++++++++------ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 8e187435..bbcc3968 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ __pycache__/ # don't add nextion2text HMI/Nextion2Text.py + +# don't add Webstorm project stuff +.idea \ No newline at end of file diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 934d5da4..06c9bbec 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -2124,22 +2124,29 @@ function GenerateThermoPage(page: PageThermo): Payload[] { let o = getObject(id); let name = page.heading !== undefined ? page.heading : o.common.name.de; let currentTemp = 0; - if (existsState(id + '.ACTUAL')) + if (existsState(id + '.ACTUAL')) { currentTemp = (Math.round(parseFloat(getState(id + '.ACTUAL').val) * 10) / 10); + } + + let minTemp = page.items[0].minValue !== undefined ? page.items[0].minValue : 50; //Min Temp 5°C + let maxTemp = page.items[0].maxValue !== undefined ? page.items[0].maxValue : 300; //Max Temp 30°C + let stepTemp = 5 // 0,5° Schritte let destTemp = 0; if (existsState(id + '.SET')) { - destTemp = getState(id + '.SET').val.toFixed(2) * 10; + // using minValue, if .SET is null (e.g. for tado AWAY or tado is off) + let setValue = getState(id + '.SET').val; + if (setValue == null) { + setValue = minTemp; + } + + destTemp = setValue.toFixed(2) * 10; } let statusStr: String = 'MANU'; let status = ''; if (existsState(id + '.MODE')) status = getState(id + '.MODE').val; - let minTemp = page.items[0].minValue !== undefined ? page.items[0].minValue : 50; //Min Temp 5°C - let maxTemp = page.items[0].maxValue !== undefined ? page.items[0].maxValue : 300; //Max Temp 30°C - let stepTemp = 5 // 0,5° Schritte - //Attribute hinzufügen, wenn im Alias definiert let i_list = Array.prototype.slice.apply($('[state.id="' + id + '.*"]')); if ((i_list.length - 3) != 0) { diff --git a/ioBroker/NsPanelTs_without_Examples.ts b/ioBroker/NsPanelTs_without_Examples.ts index ae164f1b..c4c6182b 100644 --- a/ioBroker/NsPanelTs_without_Examples.ts +++ b/ioBroker/NsPanelTs_without_Examples.ts @@ -1740,22 +1740,29 @@ function GenerateThermoPage(page: PageThermo): Payload[] { let o = getObject(id); let name = page.heading !== undefined ? page.heading : o.common.name.de; let currentTemp = 0; - if (existsState(id + '.ACTUAL')) + if (existsState(id + '.ACTUAL')) { currentTemp = (Math.round(parseFloat(getState(id + '.ACTUAL').val) * 10) / 10); + } + + let minTemp = page.items[0].minValue !== undefined ? page.items[0].minValue : 50; //Min Temp 5°C + let maxTemp = page.items[0].maxValue !== undefined ? page.items[0].maxValue : 300; //Max Temp 30°C + let stepTemp = 5 // 0,5° Schritte let destTemp = 0; if (existsState(id + '.SET')) { - destTemp = getState(id + '.SET').val.toFixed(2) * 10; + // using minValue, if .SET is null (e.g. for tado AWAY or tado is off) + let setValue = getState(id + '.SET').val; + if (setValue == null) { + setValue = minTemp; + } + + destTemp = setValue.toFixed(2) * 10; } let statusStr: String = 'MANU'; let status = ''; if (existsState(id + '.MODE')) status = getState(id + '.MODE').val; - let minTemp = page.items[0].minValue !== undefined ? page.items[0].minValue : 50; //Min Temp 5°C - let maxTemp = page.items[0].maxValue !== undefined ? page.items[0].maxValue : 300; //Max Temp 30°C - let stepTemp = 5 // 0,5° Schritte - //Attribute hinzufügen, wenn im Alias definiert let i_list = Array.prototype.slice.apply($('[state.id="' + id + '.*"]')); if ((i_list.length - 3) != 0) { From 9f75c883375e4d8e00f0d9f1c72bc6d5d73bc633 Mon Sep 17 00:00:00 2001 From: joBr99 <29555657+joBr99@users.noreply.github.com> Date: Wed, 26 Oct 2022 21:41:15 +0200 Subject: [PATCH 09/15] Update pages.py --- apps/nspanel-lovelace-ui/luibackend/pages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/nspanel-lovelace-ui/luibackend/pages.py b/apps/nspanel-lovelace-ui/luibackend/pages.py index 4fe2ad8f..b694ecd7 100644 --- a/apps/nspanel-lovelace-ui/luibackend/pages.py +++ b/apps/nspanel-lovelace-ui/luibackend/pages.py @@ -43,7 +43,7 @@ class LuiPagesGen(object): icon_color = rgb_dec565([13,160,53]) if entity.state == "arming": icon_color = rgb_dec565([244,180,0]) - if entity.state in ["armed_home", "armed_away", "armed_night", "armed_vacation", "pending"]: + if entity.state in ["armed_home", "armed_away", "armed_night", "armed_vacation", "pending", "triggered"]: icon_color = rgb_dec565([223,76,30]) if ha_type == "climate": From 7b4037f16cd9adfd3b98acf202031bcd14df7fce Mon Sep 17 00:00:00 2001 From: Armilar <102996011+Armilar@users.noreply.github.com> Date: Thu, 27 Oct 2022 11:00:57 +0200 Subject: [PATCH 10/15] v3.5.0.1 - Add VD Gate + Hotfix tado thermosta - Fix Thermostat for tado Support (by Sternmiere) - Add VirtualDevice Gate --- ioBroker/NsPanelTs.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 06c9bbec..662c1b83 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------- -TypeScript v3.5.0 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf +TypeScript v3.5.0.1 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf - abgestimmt auf TFT 43 / v3.5.0 / BerryDriver 4 / Tasmota 12.2.0 @joBr99 Projekt: https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker @@ -60,6 +60,8 @@ ReleaseNotes: - 08.10.2022 - v3.5.0 Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - 12.10.2022 - v3.5.0 Add PageNavigation via Datapoint - 25.10.2022 - v3.5.0 Add New Parameters to popUpNotify / Layout 2 + - 26.10.2022 - v3.5.0.1 Fix Thermostat for tado Support (by Sternmiere) + - 27.10.2022 - v3.5.0.1 Add VirtualDevice Gate Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Releais) genutzt werden Tasmota Konsole: @@ -1845,6 +1847,26 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~'; + case 'gate': + type = 'text'; + if (existsState(pageItem.id + '.ACTUAL')) { + if (getState(pageItem.id + '.ACTUAL').val == 0 || getState(pageItem.id + '.ACTUAL').val === false) { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage'); + iconColor = GetIconColor(pageItem, false, useColors); + var gateState = findLocale('window', 'closed'); + } else { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage-open'); + iconId = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : Icons.GetIcon('garage-open'); + iconColor = GetIconColor(pageItem, true, useColors); + var gateState = findLocale('window', 'opened'); + } + + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); + + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + gateState; + case 'door': case 'window': type = 'text'; From 5e030b4040642bcd20e18779bcf8e1d0f2890a3b Mon Sep 17 00:00:00 2001 From: Armilar <102996011+Armilar@users.noreply.github.com> Date: Thu, 27 Oct 2022 11:05:23 +0200 Subject: [PATCH 11/15] v3.5.0.1 - Add VD Gate + Hotfix tado thermostat - Fix Thermostat for tado Support (by Sternmiere) - Add VirtualDevice Gate --- ioBroker/NsPanelTs_without_Examples.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ioBroker/NsPanelTs_without_Examples.ts b/ioBroker/NsPanelTs_without_Examples.ts index c4c6182b..220938d7 100644 --- a/ioBroker/NsPanelTs_without_Examples.ts +++ b/ioBroker/NsPanelTs_without_Examples.ts @@ -60,6 +60,8 @@ ReleaseNotes: - 08.10.2022 - v3.5.0 Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - 12.10.2022 - v3.5.0 Add PageNavigation via Datapoint - 25.10.2022 - v3.5.0 Add New Parameters to popUpNotify / Layout 2 + - 26.10.2022 - v3.5.0.1 Fix Thermostat for tado Support (by Sternmiere) + - 27.10.2022 - v3.5.0.1 Add VirtualDevice Gate Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Releais) genutzt werden Tasmota Konsole: @@ -1461,6 +1463,26 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~'; + case 'gate': + type = 'text'; + if (existsState(pageItem.id + '.ACTUAL')) { + if (getState(pageItem.id + '.ACTUAL').val == 0 || getState(pageItem.id + '.ACTUAL').val === false) { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage'); + iconColor = GetIconColor(pageItem, false, useColors); + var gateState = findLocale('window', 'closed'); + } else { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage-open'); + iconId = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : Icons.GetIcon('garage-open'); + iconColor = GetIconColor(pageItem, true, useColors); + var gateState = findLocale('window', 'opened'); + } + + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); + + } + + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + gateState; + case 'door': case 'window': type = 'text'; From d049e846b5da7622c6d7c149d56487e76a9a5699 Mon Sep 17 00:00:00 2001 From: Armilar <102996011+Armilar@users.noreply.github.com> Date: Thu, 27 Oct 2022 12:40:42 +0200 Subject: [PATCH 12/15] v3.5.0.1 - Add VD Gate + Hotfix tado thermostat - Fix Thermostat for tado Support (by Sternmiere) - Add VirtualDevice Gate --- ioBroker/NsPanelTs_without_Examples.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ioBroker/NsPanelTs_without_Examples.ts b/ioBroker/NsPanelTs_without_Examples.ts index 220938d7..365896d7 100644 --- a/ioBroker/NsPanelTs_without_Examples.ts +++ b/ioBroker/NsPanelTs_without_Examples.ts @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------- -TypeScript v3.5.0 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf +TypeScript v3.5.0.1 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf - abgestimmt auf TFT 43 / v3.5.0 / BerryDriver 4 / Tasmota 12.2.0 @joBr99 Projekt: https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker From f899cb713f82c60135fa0c44c67ae52ae9b78ca8 Mon Sep 17 00:00:00 2001 From: Jens Hartlep Date: Thu, 27 Oct 2022 21:50:28 +0200 Subject: [PATCH 13/15] boy scout rule: - fixed some typos - replaced var with let - fixed some bugs --- ioBroker/NsPanelTs.ts | 658 ++++++++++++++++++++++++------------------ 1 file changed, 384 insertions(+), 274 deletions(-) diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 662c1b83..389ea749 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -46,7 +46,7 @@ ReleaseNotes: - 13.09.2022 - v3.3.1.3 Hinzufügen von SpotifyPremium, Sonos und Chromecast (Google home) zur cardMedia-Logik - 15.09.2022 - V3.4.0 - BugFix Dimmode - 15.09.2022 - V3.4.0 - Colormode für Screensaver + AutoColor WeatherForecast - - 16.09.2022 - v3.4.0.1 Visualisierung der Relay Zustände (MRIcons) im Screensaver + Bugfix Screensaver MRIcon2 + - 16.09.2022 - v3.4.0.1 Visualisierung der Relay Zustände (MRIcons) im Screensaver + Bugfix Screensaver MRIcon2 - 17.09.2022 - v3.4.0.2 Bugfix for screensaver icons with scaled colors - 17.09.2022 - v3.4.0.3 Bugfix bNext / bPrev by joBr99 - 18.09.2022 - v3.4.0.4 Add On/Off Colors in config.mrIcon1ScreensaverEntity and config.mrIcon2ScreensaverEntity @@ -60,10 +60,10 @@ ReleaseNotes: - 08.10.2022 - v3.5.0 Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - 12.10.2022 - v3.5.0 Add PageNavigation via Datapoint - 25.10.2022 - v3.5.0 Add New Parameters to popUpNotify / Layout 2 - - 26.10.2022 - v3.5.0.1 Fix Thermostat for tado Support (by Sternmiere) - - 27.10.2022 - v3.5.0.1 Add VirtualDevice Gate + - 26.10.2022 - v3.5.0.1 Fix Thermostat for tado Support (by Sternmiere) + - 27.10.2022 - v3.5.0.1 Add VirtualDevice Gate -Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Releais) genutzt werden +Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden Tasmota Konsole: Rule2 on Button1#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button2"} endon Rule2 1 (Rule aktivieren) @@ -71,17 +71,17 @@ Tasmota Konsole: Mögliche Seiten-Ansichten: screensaver Page - wird nach definiertem Zeitraum (config) mit Dimm-Modus aktiv (Uhrzeit, Datum, Aktuelle Temperatur mit Symbol) - (die 4 kleineren Icons können als Wetter-Vorschau + 4Tage (Symbol + Höschsttemperatur) oder zur Anzeige definierter Infos konfiguriert werden) + (die 4 kleineren Icons können als Wetter-Vorschau + 4Tage (Symbol + Höchsttemperatur) oder zur Anzeige definierter Infos konfiguriert werden) cardEntities Page - 4 vertikale angeordnete Steuerelemente - auch als Subpage cardGrid Page - 6 horizontal angeordnete Steuerelemente in 2 Reihen a 3 Steuerelemente - auch als Subpage cardThermo Page - Thermostat mit Solltemperatur, Isttemperatur, Mode - Weitere Eigenschaften können im Alias definiert werden - cardMedia Page - Mediaplayer - Ausnahme: Alias sollte mit Alias-Manager automatisch über Alexa-Verzeichnes Player angelegt werden + cardMedia Page - Mediaplayer - Ausnahme: Alias sollte mit Alias-Manager automatisch über Alexa-Verzeichnis Player angelegt werden cardAlarm Page - Alarmseite mit Zustand und Tastenfeld - cardPower Page - Energiefluss + cardPower Page - Energiefluss Popup-Pages: - popupLight Page - in Abhängigkeit zum gewählten Alias werden "Helligkeit", "Farb-Temperatur" und "Farbauswahl" bereitgestellt - popupShutter Page - die Shutter-Potition (Rollo, Jalousie, Markise, Leinwand, etc.) kann über einen Slider verändert werden. + popupLight Page - in Abhängigkeit zum gewählten Alias werden "Helligkeit", "Farbtemperatur" und "Farbauswahl" bereitgestellt + popupShutter Page - die Shutter-Position (Rollo, Jalousie, Markise, Leinwand, etc.) kann über einen Slider verändert werden. popupNotify Page - Info - Seite mit Headline Text und Buttons - Intern für manuelle Updates / Extern zur Befüllung von Datenpunkten unter 0_userdata screensaver Notify - Über zwei externe Datenpunkte in 0_userdata können "Headline" und "Text" an den Screensaver zur Info gesendet werden @@ -105,14 +105,14 @@ Mögliche Aliase: (Vorzugsweise mit ioBroker-Adapter "Geräte verwalten" konfigu Tastensensor - analog Taste Thermostat - Aktuelle Raumtemperatur, Setpoint, etc. Klimaanlage - Buttons zur Steuerung der Klimaanlage im unteren Bereich - Temperatur - Anzeige von Temperture - Datenpunkten, ananlog Info - Feuchtigkeit - Anzeige von Humidity - Datenpunkten, ananlog Info + Temperatur - Anzeige von Temperatur - Datenpunkten, analog Info + Feuchtigkeit - Anzeige von Humidity - Datenpunkten, analog Info Medien - Steuerung von Alexa - Über Alias-Manager im Verzeichnis Player automatisch anlegen (Geräte-Manager funktioniert nicht) - Wettervorhersage - Aktuelle Außen-Temperatur (Temp) und aktuelles Accu-Wheather-Icon (Icon) für Screensaver + Wettervorhersage - Aktuelle Außen-Temperatur (Temp) und aktuelles AccuWeather-Icon (Icon) für Screensaver Interne Sonoff-Sensoren (über Tasmota): - ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden --> SetOption146 1 - Temperatur - Raumtemperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden + ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importiert werden --> SetOption146 1 + Temperatur - Raumtemperatur - wird in 0_userdata.0. abgelegt, kann als Alias importiert werden (!!! Achtung: der interne Sonoff-Sensor liefert keine exakten Daten, da das NSPanel-Board und der ESP selbst Hitze produzieren !!! ggf. Offset einplanen oder besser einen externen Sensor über Zigbee etc. verwenden) Timestamp - wird in 0_userdata.0. Zeitpunkt der letzten Sensorübertragung @@ -121,10 +121,10 @@ Tasmota-Status0 - (zyklische Ausführung) liefert relevanten Tasmota-Informationen und kann bei Bedarf in "function get_tasmota_status0()" erweitert werden. Daten werden in 0_userdata.0. abgelegt Erforderliche Adapter: - Accu-Wheater: - Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver + AccuWeather: - Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia Geräte verwalten - Für Erstellung der Aliase - Alias-Manager - !!! ausschießlich für MEDIA-Alias + Alias-Manager - !!! ausschließlich für MEDIA-Alias MQTT-Adapter - Für Kommunikation zwischen Skript und Tasmota JavaScript-Adapter @@ -133,9 +133,9 @@ Upgrades in Konsole: TFT EU STABLE Version : FlashNextion http://nspanel.pky.eu/lovelace-ui/github/nspanel-v3.5.0.tft --------------------------------------------------------------------------------------- */ -var Icons = new IconsSelector(); -var timeoutSlider: any; -var manually_Update = false; +let Icons = new IconsSelector(); +let timeoutSlider: any; +let manually_Update = false; const NSPanel_Path = '0_userdata.0.NSPanel.1.'; const NSPanel_Alarm_Path = '0_userdata.0.NSPanel.'; //Neuer Pfad für gemeinsame Nutzung durch mehrere Panels (bei Nutzung der cardAlarm) @@ -144,7 +144,7 @@ const Debug = false; // Variablen zur Steuerung der Wettericons auf dem Screensaver (Steuerung in 0_userdata.0.XPANELX.ScreensaverInfo) // Wenn weatherForecastTimer auf true, dann Wechsel zwischen Datenpunkten und Wettervorhersage (30 Sekunden nach Minute (Zeit)) // Wenn weatherForecastTimer auf false, dann Möglichkeit über weatherForecast, ob Datenpunkte oder Wettervorhersage (true = WeatherForecast/false = Datenpunkte) -var weatherForecast: boolean; //Änderung zum Video --> Einstellung siehe Wiki +let weatherForecast: boolean; // Änderung zum Video --> Einstellung siehe Wiki const HMIOff: RGB = { red: 68, green: 115, blue: 158 }; // Blau-Off - Original Entity Off const HMIDark: RGB = { red: 29, green: 29, blue: 29 }; // Original Background Color @@ -220,11 +220,11 @@ const swSnowyRainy: RGB = { red: 150, green: 150, blue: 255}; const swSunny: RGB = { red: 255, green: 255, blue: 0}; const swWindy: RGB = { red: 150, green: 150, blue: 150}; -var vwIconColor = []; +let vwIconColor = []; //-- Anfang der Beispiele für Seitengestaltung -- Aliase erforderlich ---------------- -var Test_Licht1: PageEntities = +let Test_Licht1: PageEntities = { "type": "cardEntities", "heading": "Color Aliase 1", @@ -239,7 +239,7 @@ var Test_Licht1: PageEntities = ] }; -var CardPowerExample: PagePower = +let CardPowerExample: PagePower = { "type": "cardPower", "heading": "cardPower Emulator", @@ -251,7 +251,7 @@ var CardPowerExample: PagePower = ] }; -var Test_Licht2: PageEntities = +let Test_Licht2: PageEntities = { "type": "cardEntities", "heading": "Color Aliase 2", @@ -266,7 +266,7 @@ var Test_Licht2: PageEntities = ] }; -var Test_Funktionen: PageEntities = +let Test_Funktionen: PageEntities = { "type": "cardEntities", "heading": "Sonstige Aliase", @@ -281,7 +281,7 @@ var Test_Funktionen: PageEntities = ] }; -var Buero_Seite_1: PageEntities = +let Buero_Seite_1: PageEntities = { "type": "cardEntities", "heading": "Büro", @@ -296,7 +296,7 @@ var Buero_Seite_1: PageEntities = ] }; -var Fenster_1: PageEntities = +let Fenster_1: PageEntities = { "type": "cardEntities", "heading": "Fenster und Türen", @@ -311,7 +311,7 @@ var Fenster_1: PageEntities = ] }; //{ id: "alias.0.NS-Panel.Buero.Rollade", icon: "blinds-horizontal", offColor: White, onColor: Yellow, name: "Büro", secondRow: "Hier Text für 2. Zeile"}, -var Button_1: PageEntities = +let Button_1: PageEntities = { "type": "cardEntities", "heading": "Button Aliase", @@ -326,7 +326,7 @@ var Button_1: PageEntities = ] }; -var Subpages_1: PageEntities = +let Subpages_1: PageEntities = { "type": "cardEntities", "heading": "Test Subpages", @@ -340,7 +340,7 @@ var Subpages_1: PageEntities = }; //Subpage 1 von Subpages_1 - var Abfall: PageEntities = + let Abfall: PageEntities = { "type": "cardEntities", "heading": "Abfallkalender", @@ -356,7 +356,7 @@ var Subpages_1: PageEntities = }; //Subpage 2 von Subpages_1 - var WLAN: PageQR = + let WLAN: PageQR = { "type": "cardQR", "heading": "Gäste WLAN", @@ -366,7 +366,7 @@ var Subpages_1: PageEntities = "items": [{ id: "alias.0.NSPanel_1.Guest_Wifi", hidePassword: true }] }; -var Buero_Seite_2: PageGrid = +let Buero_Seite_2: PageGrid = { "type": "cardGrid", "heading": "Büro 2", @@ -383,7 +383,7 @@ var Buero_Seite_2: PageGrid = ] }; -var Radiosender: PageGrid = +let Radiosender: PageGrid = { "type": "cardGrid", "heading": "Büro 2", @@ -396,7 +396,7 @@ var Radiosender: PageGrid = // NEW: Neue Definition von Medien-Aliasen // adapterPlayerInstance = alexa2.0. or spotify-premium.0. or sonos.0. or chromecast.0. // MEDIA ALIASE können auch per JS-Script erstellt werden https://github.com/joBr99/nspanel-lovelace-ui/wiki/ioBroker-ALIAS-Definitionen#medien---cardmedia -var Alexa: PageMedia = +let Alexa: PageMedia = { "type": "cardMedia", "heading": "Alexa", @@ -411,7 +411,7 @@ var Alexa: PageMedia = }] }; -var Sonos: PageMedia = +let Sonos: PageMedia = { "type": "cardMedia", "heading": "Sonos", @@ -426,7 +426,7 @@ var Sonos: PageMedia = }] }; -var SpotifyPremium: PageMedia = +let SpotifyPremium: PageMedia = { "type": "cardMedia", "heading": "Spotify-Premium", @@ -440,7 +440,7 @@ var SpotifyPremium: PageMedia = }] }; -var SqueezeboxRPC: PageMedia = +let SqueezeboxRPC: PageMedia = { "type": "cardMedia", "heading": "SqueezeboxRPC", @@ -454,7 +454,7 @@ var SqueezeboxRPC: PageMedia = }] }; -var Buero_Themostat: PageThermo = +let Buero_Themostat: PageThermo = { "type": "cardThermo", "heading": "Test Thermostat", @@ -464,7 +464,7 @@ var Buero_Themostat: PageThermo = "items": [{ id: "alias.0.NSPanel_1.Thermostat_Buero", minValue: 50, maxValue: 300 }] }; -var Buero_Klimaanlage: PageThermo = +let Buero_Klimaanlage: PageThermo = { "type": "cardThermo", "heading": "Test Klimaanlage", @@ -474,7 +474,7 @@ var Buero_Klimaanlage: PageThermo = "items": [{ id: "alias.0.NSPanel_1.TestKlimaanlage", minValue: 50, maxValue: 250}] }; -var Buero_Alarm: PageAlarm = +let Buero_Alarm: PageAlarm = { "type": "cardAlarm", "heading": "Alarm", @@ -485,7 +485,7 @@ var Buero_Alarm: PageAlarm = }; //Subpages 2 (+ Info) -var Service: PageEntities = +let Service: PageEntities = { "type": "cardEntities", "heading": "NSPanel Service", @@ -501,7 +501,7 @@ var Service: PageEntities = }; //Subpage 1 von Subpages_2 - var NSPanel_Infos: PageEntities = + let NSPanel_Infos: PageEntities = { "type": "cardEntities", "heading": "NSPanel Infos", @@ -517,7 +517,7 @@ var Service: PageEntities = }; //Subpage 2 von Subpages_2 - var NSPanel_Einstellungen: PageEntities = + let NSPanel_Einstellungen: PageEntities = { "type": "cardEntities", "heading": "Screensaver", @@ -533,7 +533,7 @@ var Service: PageEntities = }; //Subpage 3 von Subpages_2 - var NSPanel_Firmware_Updates: PageEntities = + let NSPanel_Firmware_Updates: PageEntities = { "type": "cardEntities", "heading": "Firmware-Updates", @@ -548,7 +548,7 @@ var Service: PageEntities = }; //Subpage1 von Subpage3 von Subpages_2 - var Subpage2_Level_2: PageEntities = + let Subpage2_Level_2: PageEntities = { "type": "cardEntities", "heading": "Firmware-Updates", @@ -561,7 +561,7 @@ var Service: PageEntities = ] }; -var button1Page: PageGrid = +let button1Page: PageGrid = { "type": "cardGrid", "heading": "Radio", @@ -578,7 +578,7 @@ var button1Page: PageGrid = ] }; -var button2Page: PageEntities = +let button2Page: PageEntities = { "type": "cardEntities", "heading": "Büro", @@ -680,15 +680,23 @@ on({id: [].concat([NSPanel_Path + 'PageNavi']), change: "any"}, async function ( function ScreensaverDimmode(timeDimMode: DimMode) { try { - if (Debug) console.log(rgb_dec565(HMIDark)) - if (Debug) console.log('Dimmode='+ timeDimMode.dimmodeOn) + if (Debug) { + console.log(rgb_dec565(HMIDark)) + } + if (Debug) { + console.log('Dimmode=' + timeDimMode.dimmodeOn) + } if (timeDimMode.dimmodeOn != undefined ? timeDimMode.dimmodeOn : false) { if (compareTime(timeDimMode.timeNight != undefined ? timeDimMode.timeNight : '22:00', timeDimMode.timeDay != undefined ? timeDimMode.timeDay : '07:00', 'not between', undefined)) { SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); - if (Debug) console.log('Day Payload: ' + 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active ) + if (Debug) { + console.log('Day Payload: ' + 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active) + } } else { SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); - if (Debug) console.log('Night Payload: ' + 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active ) + if (Debug) { + console.log('Night Payload: ' + 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active) + } } } else { SendToPanel({ payload: 'dimmode~' + config.dimmode + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); @@ -707,7 +715,7 @@ async function InitWeatherForecast() { await createStateAsync(NSPanel_Path + "ScreensaverInfo.weatherForecast", true, { type: 'boolean' }); await createStateAsync(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer", true, { type: 'boolean' }); await createStateAsync(NSPanel_Path + "ScreensaverInfo.entityChangeTime", 60, { type: 'number' }); - }; + } } catch (err) { console.warn('function InitWeatherForecast: ' + err.message); } @@ -786,9 +794,9 @@ const popupNotifyButton2Text = NSPanel_Path + 'popupNotify.popupNotifyButton2Tex const popupNotifySleepTimeout = NSPanel_Path + 'popupNotify.popupNotifySleepTimeout'; // in sek. / wenn 0, dann bleibt die Nachricht stehen const popupNotifyAction = NSPanel_Path + 'popupNotify.popupNotifyAction'; // Antwort aus dem Panel true/false const popupNotifyLayout = NSPanel_Path + 'popupNotify.popupNotifyLayout'; -const popupNotifyFontIdText = NSPanel_Path + 'popupNotify.popupNotifyFontIdText'; 1 - 5 -const popupNotifyIcon = NSPanel_Path + 'popupNotify.popupNotifyIcon'; 1 - 5 -const popupNotifyIconColor = NSPanel_Path + 'popupNotify.popupNotifyIconColor'; 1 - 5 +const popupNotifyFontIdText = NSPanel_Path + 'popupNotify.popupNotifyFontIdText'; // 1 - 5 +const popupNotifyIcon = NSPanel_Path + 'popupNotify.popupNotifyIcon'; // 1 - 5 +const popupNotifyIconColor = NSPanel_Path + 'popupNotify.popupNotifyIconColor'; // 1 - 5 async function InitPopupNotify() { try { @@ -831,10 +839,10 @@ async function InitPopupNotify() { }); // popupNotify - Notification an separate Seite - on({ id: [popupNotifyInternalName], change: 'ne' }, async (obj) => { - - var notification : string = '' - + on({ id: [popupNotifyInternalName], change: 'ne' }, async () => { + + let notification: string; + let v_popupNotifyHeadingColor = (getState(popupNotifyHeadingColor).val != null) ? getState(popupNotifyHeadingColor).val : '65504'// Farbe Headline - gelb 65504 let v_popupNotifyButton1TextColor = (getState(popupNotifyButton1TextColor).val != null) ? getState(popupNotifyButton1TextColor).val : '63488'// Farbe Headline - gelb 65504 let v_popupNotifyButton2TextColor = (getState(popupNotifyButton2TextColor).val != null) ? getState(popupNotifyButton2TextColor).val : '2016'// Farbe Headline - gelb 65504 @@ -889,10 +897,10 @@ schedule('* * * * *', () => { } }); -//Wechsel zwischen Screensaver Enities und WeatherForecast +//Wechsel zwischen Screensaver Entities und WeatherForecast schedule('*/' + getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val + ' * * * * *', () => { try { - //WeatherForcast true/false Umschaltung verzögert + //WeatherForecast true/false Umschaltung verzögert if (getState(NSPanel_Path + "ScreensaverInfo.popupNotifyHeading").val == '' && getState(NSPanel_Path + "ScreensaverInfo.popupNotifyText").val == '' && getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val == true && getState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer").val == true) { setStateDelayed(NSPanel_Path + "ScreensaverInfo.weatherForecast", false, (getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val / 2 * 1000), false); } else if (getState(NSPanel_Path + "ScreensaverInfo.popupNotifyHeading").val == '' && getState(NSPanel_Path + "ScreensaverInfo.popupNotifyText").val == '' && getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val == false && getState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer").val == true) { @@ -906,7 +914,7 @@ schedule('*/' + getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val function InitHWButton1Color() { try { if (config.mrIcon1ScreensaverEntity.ScreensaverEntity != null || config.mrIcon1ScreensaverEntity.ScreensaverEntity != undefined) { - on({id: config.mrIcon1ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) { + on({id: config.mrIcon1ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function () { HandleScreensaverUpdate(); }); } @@ -919,7 +927,7 @@ InitHWButton1Color(); function InitHWButton2Color() { try { if (config.mrIcon2ScreensaverEntity.ScreensaverEntity != null || config.mrIcon2ScreensaverEntity.ScreensaverEntity != undefined) { - on({id: config.mrIcon2ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) { + on({id: config.mrIcon2ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function () { HandleScreensaverUpdate(); }); } @@ -962,7 +970,9 @@ check_updates(); function get_locales() { try { - if (Debug) console.log('Requesting locales'); + if (Debug) { + console.log('Requesting locales'); + } request({ url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/ioBroker/ioBroker_NSPanel_locales.json', headers: { @@ -988,13 +998,17 @@ async function check_updates() { const desired_display_firmware_version = 43; const berry_driver_version = 4; - if (Debug) console.log('Check-Updates'); + if (Debug) { + console.log('Check-Updates'); + } // Tasmota-Firmware-Vergleich if (existsObject(NSPanel_Path + 'Tasmota_Firmware.currentVersion') && existsObject(NSPanel_Path + 'Tasmota_Firmware.onlineVersion')) { if (getState(NSPanel_Path + 'Tasmota_Firmware.currentVersion').val !== getState(NSPanel_Path + 'Tasmota_Firmware.onlineVersion').val) { if (existsState(NSPanel_Path + 'NSPanel_autoUpdate')) { if (getState(NSPanel_Path + 'NSPanel_autoUpdate').val) { - if (Debug) console.log('Auto-Updates eingeschaltet - Update wird durchgeführt'); + if (Debug) { + console.log('Auto-Updates eingeschaltet - Update wird durchgeführt'); + } // Tasmota Upgrade durchführen update_tasmota_firmware(); // Aktuelle Tasmota Version = Online Tasmota Version @@ -1002,7 +1016,9 @@ async function check_updates() { await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.currentVersion', { val: getState(NSPanel_Path + 'Tasmota_Firmware.onlineVersion').val, ack: true }); } else { // Auf Tasmota-Updates hinweisen - if (Debug) console.log('Automatische Updates aus'); + if (Debug) { + console.log('Automatische Updates aus'); + } const InternalName = 'TasmotaFirmwareUpdate'; const Headline = 'Tasmota-Firmware Update'; @@ -1020,7 +1036,9 @@ async function check_updates() { } } } else { - if (Debug) console.log('Tasmota-Version auf NSPanel aktuell'); + if (Debug) { + console.log('Tasmota-Version auf NSPanel aktuell'); + } } } @@ -1034,10 +1052,14 @@ async function check_updates() { // Aktuelle Berry-Driver Version = Online Berry-Driver Version await setStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', { val: getState(NSPanel_Path + 'Berry_Driver.onlineVersion').val, ack: true }); - if (Debug) console.log('Berry-Driver automatisch aktualisiert'); + if (Debug) { + console.log('Berry-Driver automatisch aktualisiert'); + } } else { //Auf BerryDriver-Update hinweisen - if (Debug) console.log('Automatische Updates aus'); + if (Debug) { + console.log('Automatische Updates aus'); + } const InternalName = 'BerryDriverUpdate'; const Headline = 'Berry-Driver Update'; @@ -1055,7 +1077,9 @@ async function check_updates() { } } } else { - if (Debug) console.log('Berry-Driver auf NSPanel aktuell'); + if (Debug) { + console.log('Berry-Driver auf NSPanel aktuell'); + } } } @@ -1069,10 +1093,14 @@ async function check_updates() { // Aktuelle TFT-Firmware Version = Online TFT-Firmware Version await setStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { val: getState(NSPanel_Path + 'Display_Firmware.onlineVersion').val, ack: true }); - if (Debug) console.log('Display_Firmware automatisch aktualisiert'); + if (Debug) { + console.log('Display_Firmware automatisch aktualisiert'); + } } else { // Auf TFT-Firmware hinweisen - if (Debug) console.log('Automatische Updates aus'); + if (Debug) { + console.log('Automatische Updates aus'); + } const InternalName = 'TFTFirmwareUpdate'; const Headline = 'TFT-Firmware Update'; @@ -1090,7 +1118,9 @@ async function check_updates() { } } } else { - if (Debug) console.log('Display_Firmware auf NSPanel aktuell'); + if (Debug) { + console.log('Display_Firmware auf NSPanel aktuell'); + } } } } catch (err) { @@ -1104,7 +1134,9 @@ on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async if (!val) { manually_Update = false; - if (Debug) console.log('Es wurde Button1 gedrückt'); + if (Debug) { + console.log('Es wurde Button1 gedrückt'); + } } else if (val) { if (manually_Update) { const internalName = getState(NSPanel_Path + 'popupNotify.popupNotifyInternalName').val; @@ -1118,7 +1150,9 @@ on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async } } - if (Debug) console.log('Es wurde Button2 gedrückt'); + if (Debug) { + console.log('Es wurde Button2 gedrückt'); + } } } catch (err) { console.warn('Trigger popupNotifyAction: ' + err.message); @@ -1147,7 +1181,9 @@ function get_current_tasmota_ip_address() { const infoObjId = config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESULT'.length) + 'INFO2'; const infoObj = JSON.parse(getState(infoObjId).val); - if (Debug) console.log(`get_current_tasmota_ip_address: ${infoObj.Info2.IPAddress}`); + if (Debug) { + console.log(`get_current_tasmota_ip_address: ${infoObj.Info2.IPAddress}`); + } return infoObj.Info2.IPAddress; } catch (err) { @@ -1157,7 +1193,9 @@ function get_current_tasmota_ip_address() { function get_online_tasmota_firmware_version() { try { - if (Debug) console.log('Requesting tasmota firmware version'); + if (Debug) { + console.log('Requesting tasmota firmware version'); + } request({ url: 'https://api.github.com/repositories/80286288/releases/latest', headers: { @@ -1182,7 +1220,9 @@ function get_online_tasmota_firmware_version() { function get_current_berry_driver_version() { try { - if (Debug) console.log('Requesting current berry driver version'); + if (Debug) { + console.log('Requesting current berry driver version'); + } request({ url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=GetDriverVersion`, headers: { @@ -1203,7 +1243,9 @@ function get_current_berry_driver_version() { function get_tasmota_status0() { try { - if (Debug) console.log('Requesting tasmota status0'); + if (Debug) { + console.log('Requesting tasmota status0'); + } request({ url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=Status0`, headers: { @@ -1248,7 +1290,9 @@ function get_tasmota_status0() { function get_online_berry_driver_version() { try { - if (Debug) console.log('Requesting online berry driver version'); + if (Debug) { + console.log('Requesting online berry driver version'); + } request({ url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be', headers: { @@ -1272,7 +1316,9 @@ function get_online_berry_driver_version() { function check_version_tft_firmware() { try { - if (Debug) console.log('Requesting online TFT version'); + if (Debug) { + console.log('Requesting online TFT version'); + } request({ url: 'https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/latest', headers: { @@ -1281,9 +1327,9 @@ function check_version_tft_firmware() { }, async (error, response, result) => { if (result) { try { - var NSPanel_JSON = JSON.parse(result); // JSON Resultat in Variable Schreiben - var NSPanelTagName = NSPanel_JSON.tag_name; // created_at; published_at; name ; draft ; prerelease - var NSPanelVersion = NSPanelTagName.replace(/v/i, ''); // Aus Variable überflüssiges "v" filtern und in Release-Variable schreiben + let NSPanel_JSON = JSON.parse(result); // JSON Resultat in Variable Schreiben + let NSPanelTagName = NSPanel_JSON.tag_name; // created_at; published_at; name ; draft ; prerelease + let NSPanelVersion = NSPanelTagName.replace(/v/i, ''); // Aus Variable überflüssiges "v" filtern und in Release-Variable schreiben await createStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { type: 'string' }); await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { val: NSPanelVersion, ack: true }); @@ -1299,7 +1345,9 @@ function check_version_tft_firmware() { function check_online_display_firmware() { try { - if (Debug) console.log('Requesting online firmware version'); + if (Debug) { + console.log('Requesting online firmware version'); + } request({ url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py', headers: { @@ -1325,8 +1373,8 @@ function check_online_display_firmware() { on({ id: config.panelRecvTopic }, async (obj) => { if (obj.state.val.startsWith('\{"CustomRecv":')) { try { - var json = JSON.parse(obj.state.val); - var split = json.CustomRecv.split(','); + let json = JSON.parse(obj.state.val); + let split = json.CustomRecv.split(','); if (split[0] == 'event' && split[1] == 'startup') { await createStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { type: 'string' }); await createStateAsync(NSPanel_Path + 'NSPanel_Version', { type: 'string' }); @@ -1347,7 +1395,7 @@ function update_berry_driver_version() { headers: { 'User-Agent': 'ioBroker' } - }, async function (error, response, result) { + }, async function () { }); } catch (err) { @@ -1364,7 +1412,7 @@ function update_tft_firmware() { headers: { 'User-Agent': 'ioBroker' } - }, async function (error, response, result) { + }, async function () { await createStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { type: 'string' }); await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { val: tft_version, ack: true }); }); @@ -1380,7 +1428,7 @@ function update_tasmota_firmware() { headers: { 'User-Agent': 'ioBroker' } - }, async function (error, response, result) { + }, async function () { }); } catch (err) { console.warn('error at function update_tasmota_firmware: ' + err.message); @@ -1389,7 +1437,7 @@ function update_tasmota_firmware() { //------------------End Update Functions // Only monitor the extra nodes if present -var updateArray: string[] = []; +let updateArray: string[] = []; if (config.firstScreensaverEntity !== null && config.firstScreensaverEntity.ScreensaverEntity != null && existsState(config.firstScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.firstScreensaverEntity.ScreensaverEntity) @@ -1413,9 +1461,9 @@ on({ id: config.panelRecvTopic }, function (obj) { try { if (obj.state.val.startsWith('\{"CustomRecv":')) { try { - var json = JSON.parse(obj.state.val); + let json = JSON.parse(obj.state.val); - var split = json.CustomRecv.split(','); + let split = json.CustomRecv.split(','); HandleMessage(split[0], split[1], parseInt(split[2]), split); } catch (err) { console.warn(err.message); @@ -1429,9 +1477,11 @@ on({ id: config.panelRecvTopic }, function (obj) { function SendToPanel(val: Payload | Payload[]): void { try { if (Array.isArray(val)) { - val.forEach(function (id, i) { + val.forEach(function (id) { setState(config.panelSendTopic, id.payload); - if (Debug) console.log(id.payload); + if (Debug) { + console.log(id.payload); + } }); } else { setState(config.panelSendTopic, val.payload); @@ -1444,7 +1494,9 @@ function SendToPanel(val: Payload | Payload[]): void { 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) console.log(activePage); + if (Debug) { + console.log(activePage); + } if (NSPanel_Path == getState(NSPanel_Alarm_Path + 'Alarm.PANEL').val) { GeneratePage(activePage); } @@ -1475,17 +1527,22 @@ function HandleMessage(typ: string, method: string, page: number, words: Array { pageItem = sp.items.find(e => e.id === searching); - if (pageItem !== undefined) { - return false; - } - return true; + + return pageItem === undefined; }); return pageItem; @@ -1600,7 +1655,7 @@ function SendTime(): void { function GenerateEntitiesPage(page: PageEntities): Payload[] { try { - var out_msgs: Array = []; + let out_msgs: Array; out_msgs = [{ payload: 'pageType~cardEntities' }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs @@ -1611,8 +1666,7 @@ function GenerateEntitiesPage(page: PageEntities): Payload[] { function GenerateGridPage(page: PageGrid): Payload[] { try { - var out_msgs: Array = []; - out_msgs = [{ payload: 'pageType~cardGrid' }] + let out_msgs: Array = [{ payload: 'pageType~cardGrid' }]; out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } catch (err) { @@ -1664,17 +1718,17 @@ function GeneratePageElements(page: Page): string { function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string { try { - var iconId = '0'; + let iconId = '0'; if (pageItem.id == 'delete') { return '~delete~~~~~'; } - var name: string; - var type: string; + let name: string; + let type: string; // ioBroker if (existsObject(pageItem.id) || pageItem.navigate === true) { - var iconColor = rgb_dec565(config.defaultColor); + let iconColor = rgb_dec565(config.defaultColor); if (pageItem.navigate) { type = 'button'; @@ -1685,7 +1739,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = } let o = getObject(pageItem.id) - var val = null; + let val = null; if (existsState(pageItem.id + '.GET')) { val = getState(pageItem.id + '.GET').val; @@ -1698,13 +1752,15 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = // Fallback if no name is given name = pageItem.name !== undefined ? pageItem.name : o.common.name.de; + let optVal = '0'; + switch (o.common.role) { case 'socket': case 'light': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); - var iconId2 = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); - var optVal = '0'; + let iconId2 = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); + optVal = '0'; if (val === true || val === 'true') { optVal = '1'; @@ -1723,7 +1779,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'hue': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1751,7 +1807,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'ct': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON')) { val = getState(pageItem.id + '.ON').val; @@ -1768,7 +1824,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'rgb': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1795,7 +1851,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'rgbSingle': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1809,10 +1865,10 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = if (existsState(pageItem.id + '.RGB')) { if (getState(pageItem.id + '.RGB').val != null) { - var hex = getState(pageItem.id + '.RGB').val; - var hexRed = parseInt(hex[1] + hex[2], 16); - var hexGreen = parseInt(hex[3] + hex[4], 16); - var hexBlue = parseInt(hex[5] + hex[6], 16); + let hex = getState(pageItem.id + '.RGB').val; + let hexRed = parseInt(hex[1] + hex[2], 16); + let hexGreen = parseInt(hex[3] + hex[4], 16); + let hexBlue = parseInt(hex[5] + hex[6], 16); let rgb = { red: Math.round(hexRed), green: Math.round(hexGreen), blue: Math.round(hexBlue) }; iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); } @@ -1823,7 +1879,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'dimmer': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1849,16 +1905,18 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'gate': type = 'text'; + let gateState: string; if (existsState(pageItem.id + '.ACTUAL')) { + if (getState(pageItem.id + '.ACTUAL').val == 0 || getState(pageItem.id + '.ACTUAL').val === false) { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage'); iconColor = GetIconColor(pageItem, false, useColors); - var gateState = findLocale('window', 'closed'); + gateState = findLocale('window', 'closed'); } else { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage-open'); iconId = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : Icons.GetIcon('garage-open'); iconColor = GetIconColor(pageItem, true, useColors); - var gateState = findLocale('window', 'opened'); + gateState = findLocale('window', 'opened'); } RegisterEntityWatcher(pageItem.id + '.ACTUAL'); @@ -1866,21 +1924,22 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = } return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + gateState; - + case 'door': case 'window': type = 'text'; + let windowState; if (existsState(pageItem.id + '.ACTUAL')) { if (getState(pageItem.id + '.ACTUAL').val) { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'door' ? Icons.GetIcon('door-open') : Icons.GetIcon('window-open-variant'); iconColor = GetIconColor(pageItem, false, useColors); - var windowState = findLocale('window', 'opened'); + windowState = findLocale('window', 'opened'); } else { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'door' ? Icons.GetIcon('door-closed') : Icons.GetIcon('window-closed-variant'); //iconId = Icons.GetIcon('window-closed-variant'); iconColor = GetIconColor(pageItem, true, useColors); - var windowState = findLocale('window', 'closed'); + windowState = findLocale('window', 'closed'); } RegisterEntityWatcher(pageItem.id + '.ACTUAL'); @@ -1906,7 +1965,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = type = 'text'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'value.temperature' || o.common.role == 'thermostat' ? Icons.GetIcon('thermometer') : Icons.GetIcon('information-outline'); let unit = ''; - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { optVal = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1939,16 +1998,17 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = type = 'button'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock'); iconColor = GetIconColor(pageItem, true, useColors); + let lockState; if (existsState(pageItem.id + '.ACTUAL')) { if (getState(pageItem.id + '.ACTUAL').val) { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock'); iconColor = GetIconColor(pageItem, true, useColors); - var lockState = findLocale('lock', 'UNLOCK'); + lockState = findLocale('lock', 'UNLOCK'); } else { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock-open-variant'); iconColor = GetIconColor(pageItem, false, useColors); - var lockState = findLocale('lock', 'LOCK'); + lockState = findLocale('lock', 'LOCK'); } lockState = pageItem.buttonText !== undefined ? pageItem.buttonText : lockState; RegisterEntityWatcher(pageItem.id + '.ACTUAL'); @@ -2027,7 +2087,9 @@ function findLocale(controlsObject: string, controlsState: string): string { const locale = config.locale; const strJson = getState(NSPanel_Path + 'NSPanel_locales_json').val; - if (Debug) console.log(controlsObject + ' - ' + controlsState); + if (Debug) { + console.log(controlsObject + ' - ' + controlsState); + } try { const obj = JSON.parse(strJson); @@ -2041,7 +2103,9 @@ function findLocale(controlsObject: string, controlsState: string): string { } catch (err) { if (err.message.substring(0, 35) == 'Cannot read properties of undefined') { - if (Debug) console.log('function findLocale: missing translation: ' + controlsObject + ' - ' + controlsState); + if (Debug) { + console.log('function findLocale: missing translation: ' + controlsObject + ' - ' + controlsState); + } } else { console.warn('function findLocale: ' + err.message); } @@ -2085,7 +2149,7 @@ function RegisterEntityWatcher(id: string): void { return; } - subscriptions[id] = (on({ id: id, change: 'any' }, (data) => { + subscriptions[id] = (on({ id: id, change: 'any' }, () => { if (pageId == -1 && config.button1Page != undefined) { SendToPanel({ payload: GeneratePageElements(config.button1Page) }); } @@ -2137,8 +2201,8 @@ function GetUnitOfMeasurement(id: string): string { function GenerateThermoPage(page: PageThermo): Payload[] { try { - var id = page.items[0].id - var out_msgs: Array = []; + let id = page.items[0].id + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardThermo' }); // ioBroker @@ -2166,15 +2230,16 @@ function GenerateThermoPage(page: PageThermo): Payload[] { } let statusStr: String = 'MANU'; let status = ''; - if (existsState(id + '.MODE')) - status = getState(id + '.MODE').val; + if (existsState(id + '.MODE')) { + status = getState(id + '.MODE').val; // FixMe: Variable status is never used! + } //Attribute hinzufügen, wenn im Alias definiert let i_list = Array.prototype.slice.apply($('[state.id="' + id + '.*"]')); + let bt = ['~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~']; if ((i_list.length - 3) != 0) { - var i = 0; - var bt = ['~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~']; + let i = 0; if (o.common.role == 'thermostat') { @@ -2375,7 +2440,7 @@ function GenerateThermoPage(page: PageThermo): Payload[] { payload: 'entityUpd~' + name + '~' // Heading + GetNavigationString(pageId) + '~' // Page Navigation - + id + '~' // internalNameEntiy + + id + '~' // internalNameEntity + currentTemp + config.temperatureUnit + '~' // Ist-Temperatur (String) + destTemp + '~' // Soll-Temperatur (numerisch ohne Komma) + statusStr + '~' // Mode @@ -2383,8 +2448,8 @@ function GenerateThermoPage(page: PageThermo): Payload[] { + maxTemp + '~' // Thermostat Max-Temperatur + stepTemp + '~' // Schritte für Soll (5°C) + icon_res // Icons Status - + findLocale('thermostat', 'Currently') + '~' // Bezeicher vor Aktueller Raumtemperatur - + findLocale('thermostat', 'State') + '~' // Bezeicner vor + + findLocale('thermostat', 'Currently') + '~' // Bezeichner vor Aktueller Raumtemperatur + + findLocale('thermostat', 'State') + '~' // Bezeichner vor + '~' // Bezeichner vor HVAC -- Gibt es nicht mehr + config.temperatureUnit + '~' // Bezeichner hinter Solltemp + '' + '~' // iconTemperature dstTempTwoTempMode @@ -2393,7 +2458,9 @@ function GenerateThermoPage(page: PageThermo): Payload[] { } - if (Debug) console.log(out_msgs); + if (Debug) { + console.log(out_msgs); + } return out_msgs } catch (err) { console.warn('function GenerateThermoPage: ' + err.message); @@ -2402,9 +2469,9 @@ function GenerateThermoPage(page: PageThermo): Payload[] { function GenerateMediaPage(page: PageMedia): Payload[] { try { - var id = page.items[0].id + let id = page.items[0].id - var out_msgs: Array = []; + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardMedia' }); if (existsObject(id)) { @@ -2416,24 +2483,24 @@ function GenerateMediaPage(page: PageMedia): Payload[] { let v1Adapter = vInstance.split('.'); let v2Adapter = v1Adapter[0]; - //Alexa + neue Adpter/Player + //Alexa + neue Adapter/Player let media_icon = Icons.GetIcon('playlist-music'); //Spotify-Premium if (v2Adapter == 'spotify-premium') { media_icon = Icons.GetIcon('spotify'); name = getState(id + '.CONTEXT_DESCRIPTION').val; - let nameLenght = name.length; + let nameLength = name.length; if (name.substring(0,9) == 'Playlist:') { - let nameLenght = name.length; - name = name.slice(10, nameLenght); + let nameLength = name.length; + name = name.slice(10, nameLength); } else if (name.substring(0,6) == 'Album:') { - let nameLenght = name.length; - name = name.slice(10, nameLenght); + let nameLength = name.length; + name = name.slice(10, nameLength); } else if (name.substring(0,6) == 'Track') { name = 'Spotify-Premium'; } - if (nameLenght == 0) { + if (nameLength == 0) { name = 'Spotify-Premium'; } author = getState(id + '.ARTIST').val + ' | ' + getState(id + '.ALBUM').val; @@ -2462,8 +2529,8 @@ function GenerateMediaPage(page: PageMedia): Payload[] { //Logitech Squeezebox RPC if (v2Adapter == 'squeezeboxrpc') { media_icon = Icons.GetIcon('dlna'); - let nameLenght = name.length; - if (nameLenght == 0) { + let nameLength = name.length; + if (nameLength == 0) { name = 'Squeezebox RPC'; author = 'no music to control'; } @@ -2472,16 +2539,16 @@ function GenerateMediaPage(page: PageMedia): Payload[] { //Alexa2 if (v2Adapter == 'alexa2') { media_icon = Icons.GetIcon('playlist-music'); - let nameLenght = name.length; - if (nameLenght == 0) { + let nameLength = name.length; + if (nameLength == 0) { name = 'Alexa Player'; author = 'no music to control'; } } let volume = getState(id + '.VOLUME').val; - var iconplaypause = Icons.GetIcon('pause'); //pause - var onoffbutton = 1374; + let iconplaypause = Icons.GetIcon('pause'); //pause + let onoffbutton = 1374; //Für alle Player if (getState(id + '.STATE').val) { @@ -2499,7 +2566,9 @@ function GenerateMediaPage(page: PageMedia): Payload[] { iconplaypause = Icons.GetIcon('play'); //play } - if (Debug) console.log(v2Adapter); + if (Debug) { + console.log(v2Adapter); + } let currentSpeaker = 'kein Speaker gefunden'; @@ -2517,10 +2586,10 @@ function GenerateMediaPage(page: PageMedia): Payload[] { //------------------------------------------------------------------------------------------------------------- // nachfolgend alle Alexa-Devices (ist Online / Player- und Commands-Verzeichnis vorhanden) auflisten und verketten // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter - let speakerlist = ''; + let speakerList = ''; if (page.items[0].speakerList.length > 0) { for (let i_index in page.items[0].speakerList) { - speakerlist = speakerlist + page.items[0].speakerList[i_index] + '?'; + speakerList = speakerList + page.items[0].speakerList[i_index] + '?'; } } else { let i_list = Array.prototype.slice.apply($('[state.id="' + page.items[0].adapterPlayerInstance + 'Echo-Devices.*.Info.name"]')); @@ -2531,11 +2600,11 @@ function GenerateMediaPage(page: PageMedia): Payload[] { if (getState(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.online'].join(''))).val && existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Player'].join(''))) && existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Commands'].join('')))) { - speakerlist = speakerlist + getState(i).val + '?'; + speakerList = speakerList + getState(i).val + '?'; } } } - speakerlist = speakerlist.substring(0, speakerlist.length - 1); + speakerList = speakerList.substring(0, speakerList.length - 1); //-------------------------------------------------------------------------------------------------------------- out_msgs.push({ @@ -2549,11 +2618,13 @@ function GenerateMediaPage(page: PageMedia): Payload[] { volume + '~' + //volume iconplaypause + '~' + //playpauseicon currentSpeaker + '~' + //currentSpeaker - speakerlist + '~' + //speakerList-seperated-by-? + speakerList + '~' + //speakerList-seperated-by-? onoffbutton }); //On/Off Button Color } - if (Debug) console.log(out_msgs); + if (Debug) { + console.log(out_msgs); + } return out_msgs } catch (err) { console.warn('function GenerateMediaPage: ' + err.message); @@ -2563,11 +2634,11 @@ function GenerateMediaPage(page: PageMedia): Payload[] { function GenerateAlarmPage(page: PageAlarm): Payload[] { try { activePage = page; - var id = page.items[0].id + let id = page.items[0].id - var out_msgs: Array = []; + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardAlarm' }); - var nsPath = NSPanel_Alarm_Path + 'Alarm.'; + let nsPath = NSPanel_Alarm_Path + 'Alarm.'; if (existsState(nsPath + 'AlarmPin') == false || existsState(nsPath + 'AlarmState') == false || existsState(nsPath + 'AlarmType') == false || existsState(nsPath + 'PIN_Failed') == false || existsState(nsPath + 'PANEL') == false) { createState(nsPath + 'AlarmPin', '0000', { type: 'string' }, function () { setState(nsPath + 'AlarmPin', '0000') }); @@ -2578,17 +2649,19 @@ function GenerateAlarmPage(page: PageAlarm): Payload[] { } if (existsState(nsPath + 'AlarmPin') && existsState(nsPath + 'AlarmState') && existsState(nsPath + 'AlarmType')) { - //var entityPin = getState(nsPath + 'AlarmPin').val; - var entityState = getState(nsPath + 'AlarmState').val; - //var entityType = getState(nsPath + 'AlarmType').val; - var arm1: string, arm2: string, arm3: string, arm4: string; - var arm1ActionName: string, arm2ActionName: string, arm3ActionName: string, arm4ActionName: string; - var icon = '0'; - var iconcolor = 63488; - var numpadStatus = 'disable'; - var flashing = 'disable'; + //let entityPin = getState(nsPath + 'AlarmPin').val; + let entityState = getState(nsPath + 'AlarmState').val; + //let entityType = getState(nsPath + 'AlarmType').val; + let arm1: string, arm2: string, arm3: string, arm4: string; + let arm1ActionName: string, arm2ActionName: string, arm3ActionName: string, arm4ActionName: string; + let icon = '0'; + let iconcolor = 63488; + let numpadStatus = 'disable'; + let flashing = 'disable'; - if (Debug) console.log(id); + if (Debug) { + console.log(id); + } if (entityState == 'armed' || entityState == 'triggered') { arm1 = 'Deaktivieren'; //arm1*~* @@ -2655,7 +2728,9 @@ function GenerateAlarmPage(page: PageAlarm): Payload[] { flashing }); //flashing* - if (Debug) console.log(out_msgs); + if (Debug) { + console.log(out_msgs); + } return out_msgs } } catch (err) { @@ -2667,37 +2742,39 @@ function GenerateQRPage(page: PageQR): Payload[] { try { activePage = page; - var id = page.items[0].id - var out_msgs: Array = []; + let id = page.items[0].id + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardQR' }); let o = getObject(id) - var heading = page.heading !== undefined ? page.heading : o.common.name.de - var textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;' - var hiddenPWD = false; + let heading = page.heading !== undefined ? page.heading : o.common.name.de + let textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;' + let hiddenPWD = false; if (page.items[0].hidePassword !== undefined && page.items[0].hidePassword == true) { hiddenPWD = true } const tempstr = textQR.split(';'); + let optionalValue1; + let optionalValue2 for (let w = 0; w < tempstr.length - 1; w++) { if (tempstr[w].substring(0, 1) == 'S') { - var optionalValue1 = tempstr[w].slice(2); + optionalValue1 = tempstr[w].slice(2); } if (tempstr[w].substring(0, 1) == 'P') { - var optionalValue2 = tempstr[w].slice(2); + optionalValue2 = tempstr[w].slice(2); } } - var type1 = 'text'; - var internalName1 = 'SSID'; - var iconId1 = Icons.GetIcon('wifi'); - var displayName1 = 'SSID'; - var type2 = 'text'; - var internalName2 = 'Passwort'; - var iconId2 = Icons.GetIcon('key'); - var displayName2 = 'Passwort'; + let type1 = 'text'; + let internalName1 = 'SSID'; + let iconId1 = Icons.GetIcon('wifi'); + let displayName1 = 'SSID'; + let type2 = 'text'; + let internalName2 = 'Passwort'; + let iconId2 = Icons.GetIcon('key'); + let displayName2 = 'Passwort'; if (hiddenPWD) { type2 = 'disable'; @@ -2736,12 +2813,15 @@ function GeneratePowerPage(page: PagePower): Payload[] { try { activePage = page; - if (Debug) console.log(page.items[0].id); + if (Debug) { + console.log(page.items[0].id); + } - var demoMode = false; + let demoMode = false; + let id; try { - var id = page.items[0].id + id = page.items[0].id } catch (err) { console.log("Kein PageItem definiert - cardPower Demo-Modus aktiv"); demoMode = true; @@ -2755,11 +2835,11 @@ function GeneratePowerPage(page: PagePower): Payload[] { const obj = JSON.parse((getState(page.items[0].id + '.ACTUAL').val)); - var out_msgs: Array = []; + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardPower' }); //Demo Data if no pageItem present - let array_icon_color = [White, MSGreen, MSYellow, MSGreen, MSYellow, MSGreen, MSRed]; + let array_icon_color = [White, MSGreen, MSYellow, MSGreen, MSYellow, MSGreen, MSRed]; let array_icon = ['home', 'battery-charging-60', 'solar-power-variant', 'wind-turbine', 'shape', 'transmission-tower', 'car']; let array_powerspeed = ['', '-1', '2', '4', '1', '1', '5']; let array_powerstate = ['', '0,5 kW', '0,9 kW', '2,8 kW', '0,2 kW', '0,1 kW', '4,6 kW']; @@ -2790,7 +2870,7 @@ function GeneratePowerPage(page: PagePower): Payload[] { payload: 'entityUpd~' + //entityUpd~* heading + '~' + //internalNameEntity*~* GetNavigationString(pageId) + '~' + //navigation*~* - rgb_dec565(array_icon_color[0]) + '~' + // icon_color~ Mitte + rgb_dec565(array_icon_color[0]) + '~' + // icon_color~ Mitte Icons.GetIcon(array_icon[0]) + '~' + // icon~ Mitte array_powerspeed[0] + '~' + // entity.state~ Mitte power_string @@ -2839,8 +2919,8 @@ function toggleState(id: string): boolean { function HandleButtonEvent(words): void { try { - var id = words[2] - var buttonAction = words[3]; + let id = words[2] + let buttonAction = words[3]; if (Debug) { console.log(words[0] + ' - ' + words[1] + ' - ' + words[2] + ' - ' + words[3] + ' - ' + words[4] + ' - PageId: ' + pageId); @@ -2851,7 +2931,11 @@ function HandleButtonEvent(words): void { return; } - if (Debug) console.log(buttonAction); + if (Debug) { + console.log(buttonAction); + } + + let pageNum:number = 0; switch (buttonAction) { case 'bUp': @@ -2864,13 +2948,13 @@ function HandleButtonEvent(words): void { GeneratePage(config.pages[pageId]); break; case 'bNext': - var pageNum = (((pageId + 1) % config.pages.length) + config.pages.length) % config.pages.length; + pageNum = (((pageId + 1) % config.pages.length) + config.pages.length) % config.pages.length; pageId = pageNum; UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case 'bPrev': - var pageNum = (((pageId - 1) % config.pages.length) + config.pages.length) % config.pages.length; + pageNum = (((pageId - 1) % config.pages.length) + config.pages.length) % config.pages.length; pageId = pageNum; UnsubscribeWatcher(); if (activePage != undefined && activePage.parent != undefined) { @@ -2895,7 +2979,9 @@ function HandleButtonEvent(words): void { GeneratePage(config.pages[pageId]); } } else { - if (Debug) console.log('bExit: ' + words[4] + ' - ' + pageId); + if (Debug) { + console.log('bExit: ' + words[4] + ' - ' + pageId); + } setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyHeading', ''); setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyText', ''); GeneratePage(activePage); @@ -2915,7 +3001,7 @@ function HandleButtonEvent(words): void { break; case 'OnOff': if (existsObject(id)) { - var action = false + let action = false if (words[4] == '1') action = true; let o = getObject(id); @@ -2939,7 +3025,7 @@ function HandleButtonEvent(words): void { break; case 'button': if (existsObject(id)) { - var action = false + let action = false if (words[4] == '1') action = true; let o = getObject(id); @@ -3033,7 +3119,7 @@ function HandleButtonEvent(words): void { (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); timeoutSlider = setTimeout(async function () { let pageItem = findPageItem(id); - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValueColorTemp, pageItem.maxValueColorTemp)); setIfExists(id + '.TEMPERATURE', (colorTempK)); } else { @@ -3044,8 +3130,12 @@ function HandleButtonEvent(words): void { case 'colorWheel': let colorCoordinates = words[4].split('|'); let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]); - if (Debug) console.log(rgb); - if (Debug) console.log(getHue(rgb.red, rgb.green, rgb.blue)); + if (Debug) { + console.log(rgb); + } + if (Debug) { + console.log(getHue(rgb.red, rgb.green, rgb.blue)); + } let o = getObject(id); switch (o.common.role) { case 'hue': @@ -3061,13 +3151,15 @@ function HandleButtonEvent(words): void { if (pageItem.colormode == "xy") { //Für z.B. Deconz XY setIfExists(id + ".RGB", rgb_to_cie(rgb.red, rgb.green, rgb.blue)); - if (Debug) console.log(rgb_to_cie(rgb.red, rgb.green, rgb.blue)); + if (Debug) { + console.log(rgb_to_cie(rgb.red, rgb.green, rgb.blue)); + } } else { //Für RGB - setIfExists(id + ".RGB", ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue)); + setIfExists(id + ".RGB", ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue)); } - break; + break; } break; case 'tempUpd': @@ -3119,7 +3211,7 @@ function HandleButtonEvent(words): void { switch (deviceAdapter) { case 'spotify-premium': - var strDeviceID = spotifyGetDeviceID(words[4]); + let strDeviceID = spotifyGetDeviceID(words[4]); setState(adapterInstance + 'devices.' + strDeviceID + ".useForPlayback", true); break; case 'alexa2': @@ -3187,7 +3279,7 @@ function HandleButtonEvent(words): void { } GeneratePage(config.pages[pageId]); } else { - var HVACMode = 0; + let HVACMode = 0; switch (words[4]) { case 'POWER': HVACMode = 0; @@ -3276,8 +3368,12 @@ function HandleButtonEvent(words): void { },250) break; case 'D1': // Alarm-Page Alarm Deaktivieren - if (Debug) console.log('D1: ' + getState(id + '.PIN').val); - if (Debug) console.log(words[4]); + if (Debug) { + console.log('D1: ' + getState(id + '.PIN').val); + } + if (Debug) { + console.log(words[4]); + } if (words[4] != '') { if (getState(id + '.PIN').val == words[4]) { setIfExists(id + '.PIN', '0000'); @@ -3299,13 +3395,15 @@ function HandleButtonEvent(words): void { } } catch (err) { console.log('function HandleButtonEvent: ' + err.message); - } + } } function GetNavigationString(pageId: number): string { try { - if (Debug) console.log(pageId); + if (Debug) { + console.log(pageId); + } if (activePage.subPage) return '1|0'; @@ -3329,14 +3427,14 @@ function GetNavigationString(pageId: number): string { function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { try { - var out_msgs: Array = []; + let out_msgs: Array = []; let id = pageItem.id if (existsObject(id)) { - var o = getObject(id) - var val: (boolean | number) = 0; + let o = getObject(id) + let val: (boolean | number) = 0; let icon = Icons.GetIcon('lightbulb'); - var iconColor = rgb_dec565(config.defaultColor); + let iconColor = rgb_dec565(config.defaultColor); if (type == 'popupLight') { let switchVal = '0'; @@ -3385,7 +3483,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } if (val === true) { - var iconColor = GetIconColor(pageItem, val, false); + let iconColor = GetIconColor(pageItem, val, false); switchVal = '1' } @@ -3452,7 +3550,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; if (existsState(id + '.HUE')) { if (getState(id + '.HUE').val != null) { colorMode = 'enable'; @@ -3463,10 +3561,10 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } } - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); } else { colorTemp = 100 - getState(id + '.TEMPERATURE').val; @@ -3518,7 +3616,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; if (existsState(id + '.RED') && existsState(id + '.GREEN') && existsState(id + '.BLUE')) { if (getState(id + '.RED').val != null && getState(id + '.GREEN').val != null && getState(id + '.BLUE').val != null) { colorMode = 'enable'; @@ -3528,7 +3626,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } } - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { @@ -3583,24 +3681,24 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; if (existsState(id + '.RGB')) { if (getState(id + '.RGB').val != null) { colorMode = 'enable'; - var hex = getState(id + '.RGB').val; - var hexRed = parseInt(hex[1] + hex[2], 16); - var hexGreen = parseInt(hex[3] + hex[4], 16); - var hexBlue = parseInt(hex[5] + hex[6], 16); + let hex = getState(id + '.RGB').val; + let hexRed = parseInt(hex[1] + hex[2], 16); + let hexGreen = parseInt(hex[3] + hex[4], 16); + let hexBlue = parseInt(hex[5] + hex[6], 16); let rgb = { red: Math.round(hexRed), green: Math.round(hexGreen), blue: Math.round(hexBlue) } iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); //RegisterDetailEntityWatcher(id + '.HUE', pageItem, type); } } - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); } else { colorTemp = 100 - getState(id + '.TEMPERATURE').val; @@ -3652,12 +3750,12 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); } else { colorTemp = 100 - getState(id + '.TEMPERATURE').val; @@ -3693,7 +3791,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { val = getState(id + '.SET').val; RegisterDetailEntityWatcher(id + '.SET', pageItem, type); } - var tilt_position: any = 'disabled' + let tilt_position: any = 'disabled' if (existsState(id + '.TILT_ACTUAL')) { tilt_position = getState(id + '.TILT_ACTUAL').val; RegisterDetailEntityWatcher(id + '.TILT_ACTUAL', pageItem, type); @@ -3795,7 +3893,7 @@ function HandleScreensaver(): void { function HandleScreensaverUpdate(): void { try { if (screensaverEnabled && config.weatherEntity != null && existsObject(config.weatherEntity)) { - var icon = getState(config.weatherEntity + '.ICON').val; + let icon = getState(config.weatherEntity + '.ICON').val; let temperature = existsState(config.weatherEntity + '.ACTUAL') ? getState(config.weatherEntity + '.ACTUAL').val : @@ -3810,16 +3908,20 @@ function HandleScreensaverUpdate(): void { + temperature + ' ' + config.temperatureUnit + '~'; vwIconColor[0] = GetAccuWeatherIconColor(parseInt(icon)); - if (Debug) console.log(GetAccuWeatherIconColor(parseInt(icon))); + if (Debug) { + console.log(GetAccuWeatherIconColor(parseInt(icon))); + } if (weatherForecast) { - // Accu-Weather Forecast Tag 2 - Tag 5 -- Wenn weatherForecast = true + // AccuWeather Forecast Tag 2 - Tag 5 -- Wenn weatherForecast = true for (let i = 2; i < 6; i++) { let TempMax = getState('accuweather.0.Summary.TempMax_d' + i).val; let DayOfWeek = getState('accuweather.0.Summary.DayOfWeek_d' + i).val; let WeatherIcon = GetAccuWeatherIcon(getState('accuweather.0.Summary.WeatherIcon_d' + i).val); vwIconColor[i-1] = GetAccuWeatherIconColor(getState('accuweather.0.Summary.WeatherIcon_d' + i).val); - if (Debug) console.log(vwIconColor[i-1]); + if (Debug) { + console.log(vwIconColor[i - 1]); + } payloadString += DayOfWeek + '~' + Icons.GetIcon(WeatherIcon) + '~' + TempMax + ' ' + config.temperatureUnit + '~'; } } else { @@ -3864,7 +3966,9 @@ function HandleScreensaverUpdate(): void { } } let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[1] = rgb_dec565(colorScale0); @@ -3936,7 +4040,9 @@ function HandleScreensaverUpdate(): void { } } let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[2] = rgb_dec565(colorScale0); @@ -4008,7 +4114,9 @@ function HandleScreensaverUpdate(): void { } } let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[3] = rgb_dec565(colorScale0); @@ -4080,7 +4188,9 @@ function HandleScreensaverUpdate(): void { } } let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[4] = rgb_dec565(colorScale0); @@ -4443,9 +4553,9 @@ function GetBlendedColor(percentage: number): RGB { } function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { - var r: number = InterpolateNum(color1.red, color2.red, fraction); - var g: number = InterpolateNum(color1.green, color2.green, fraction); - var b: number = InterpolateNum(color1.blue, color2.blue, fraction); + 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) }; } @@ -4467,7 +4577,7 @@ function rad2deg(rad) { } function ColorToHex(color) { - var hexadecimal = color.toString(16); + let hexadecimal = color.toString(16); return hexadecimal.length == 1 ? '0' + hexadecimal : hexadecimal; } @@ -4497,14 +4607,14 @@ function hsv2rgb(hue: number, saturation: number, value: number) { function getHue(red: number, green: number, blue: number) { - var min = Math.min(Math.min(red, green), blue); - var max = Math.max(Math.max(red, green), blue); + let min = Math.min(Math.min(red, green), blue); + let max = Math.max(Math.max(red, green), blue); if (min == max) { return 0; } - var hue = 0; + let hue = 0; if (max == red) { hue = (green - blue) / (max - min); @@ -4522,9 +4632,9 @@ function getHue(red: number, green: number, blue: number) { } function pos_to_color(x: number, y: number): RGB { - var r = 160 / 2; - var x = Math.round((x - r) / r * 100) / 100; - var y = Math.round((r - y) / r * 100) / 100; + let r = 160 / 2; + x = Math.round((x - r) / r * 100) / 100; + y = Math.round((r - y) / r * 100) / 100; r = Math.sqrt(x * x + y * y); let sat = 0 @@ -4534,8 +4644,8 @@ function pos_to_color(x: number, y: number): RGB { sat = r; } - var hsv = rad2deg(Math.atan2(y, x)); - var rgb = hsv2rgb(hsv, sat, 1); + let hsv = rad2deg(Math.atan2(y, x)); + let rgb = hsv2rgb(hsv, sat, 1); return { red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) }; } @@ -4563,10 +4673,10 @@ function rgb_to_cie(red, green, blue) function spotifyGetDeviceID(vDeviceString) { const availableDeviceIDs = getState("spotify-premium.0.devices.availableDeviceListIds").val; const availableDeviceNames = getState("spotify-premium.0.devices.availableDeviceListString").val; - var arrayDeviceListIds = availableDeviceIDs.split(";"); - var arrayDeviceListSting = availableDeviceNames.split(";"); - var indexPos = arrayDeviceListSting.indexOf(vDeviceString); - var strDevID = arrayDeviceListIds[indexPos]; + let arrayDeviceListIds = availableDeviceIDs.split(";"); + let arrayDeviceListSting = availableDeviceNames.split(";"); + let indexPos = arrayDeviceListSting.indexOf(vDeviceString); + let strDevID = arrayDeviceListIds[indexPos]; return strDevID; } @@ -4592,37 +4702,37 @@ type Page = { interface PageEntities extends Page { type: 'cardEntities', items: PageItem[], -}; +} interface PageGrid extends Page { type: 'cardGrid', items: PageItem[], -}; +} interface PageThermo extends Page { type: 'cardThermo', items: PageItem[], -}; +} interface PageMedia extends Page { type: 'cardMedia', items: PageItem[], -}; +} interface PageAlarm extends Page { type: 'cardAlarm', items: PageItem[], -}; +} interface PageQR extends Page { type: 'cardQR', items: PageItem[], -}; +} interface PagePower extends Page { type: 'cardPower', items: PageItem[], -}; +} type PageItem = { id: string, @@ -4687,7 +4797,7 @@ type Config = { subPages: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower)[], button1Page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower | null), button2Page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower| null), -}; +} type ScreenSaverElement = { ScreensaverEntity: string | null, From f3ead1a15be5848b35ecb651895382ce1091259b Mon Sep 17 00:00:00 2001 From: Jens Hartlep Date: Thu, 27 Oct 2022 22:02:57 +0200 Subject: [PATCH 14/15] added changelog --- ioBroker/NsPanelTs.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 389ea749..22890ca3 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -62,6 +62,7 @@ ReleaseNotes: - 25.10.2022 - v3.5.0 Add New Parameters to popUpNotify / Layout 2 - 26.10.2022 - v3.5.0.1 Fix Thermostat for tado Support (by Sternmiere) - 27.10.2022 - v3.5.0.1 Add VirtualDevice Gate + - 27.10.2022 - v3.5.0.2 Applied Boy Scout Rule (Fixed some typos, changed var to let, fixed min/max colorTemp Bug) Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden Tasmota Konsole: From ded566a33829b78339db28ae1de8b70ef1b8f765 Mon Sep 17 00:00:00 2001 From: Jens Hartlep Date: Fri, 28 Oct 2022 07:07:15 +0200 Subject: [PATCH 15/15] Boy Scout Rule on second script Forgot to raise the version on top of the script and forgot to apply the changes made in the NsPanelTs to the NsPanelTs_without_Examples file. --- ioBroker/NsPanelTs.ts | 2 +- ioBroker/NsPanelTs_without_Examples.ts | 1328 +++++++++++++----------- 2 files changed, 704 insertions(+), 626 deletions(-) diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 22890ca3..b8c66cf4 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------- -TypeScript v3.5.0.1 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf +TypeScript v3.5.0.2 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf - abgestimmt auf TFT 43 / v3.5.0 / BerryDriver 4 / Tasmota 12.2.0 @joBr99 Projekt: https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker diff --git a/ioBroker/NsPanelTs_without_Examples.ts b/ioBroker/NsPanelTs_without_Examples.ts index 365896d7..7174ac0e 100644 --- a/ioBroker/NsPanelTs_without_Examples.ts +++ b/ioBroker/NsPanelTs_without_Examples.ts @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------- -TypeScript v3.5.0.1 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf +TypeScript v3.5.0.2 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf - abgestimmt auf TFT 43 / v3.5.0 / BerryDriver 4 / Tasmota 12.2.0 @joBr99 Projekt: https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker @@ -46,7 +46,7 @@ ReleaseNotes: - 13.09.2022 - v3.3.1.3 Hinzufügen von SpotifyPremium, Sonos und Chromecast (Google home) zur cardMedia-Logik - 15.09.2022 - V3.4.0 - BugFix Dimmode - 15.09.2022 - V3.4.0 - Colormode für Screensaver + AutoColor WeatherForecast - - 16.09.2022 - v3.4.0.1 Visualisierung der Relay Zustände (MRIcons) im Screensaver + Bugfix Screensaver MRIcon2 + - 16.09.2022 - v3.4.0.1 Visualisierung der Relay Zustände (MRIcons) im Screensaver + Bugfix Screensaver MRIcon2 - 17.09.2022 - v3.4.0.2 Bugfix for screensaver icons with scaled colors - 17.09.2022 - v3.4.0.3 Bugfix bNext / bPrev by joBr99 - 18.09.2022 - v3.4.0.4 Add On/Off Colors in config.mrIcon1ScreensaverEntity and config.mrIcon2ScreensaverEntity @@ -60,71 +60,72 @@ ReleaseNotes: - 08.10.2022 - v3.5.0 Add Tilt-Slider and TILT_Fucntions (Open/Stop/Close) to Blinds/Cover/Shutter popUp - 12.10.2022 - v3.5.0 Add PageNavigation via Datapoint - 25.10.2022 - v3.5.0 Add New Parameters to popUpNotify / Layout 2 - - 26.10.2022 - v3.5.0.1 Fix Thermostat for tado Support (by Sternmiere) - - 27.10.2022 - v3.5.0.1 Add VirtualDevice Gate + - 26.10.2022 - v3.5.0.1 Fix Thermostat for tado Support (by Sternmiere) + - 27.10.2022 - v3.5.0.1 Add VirtualDevice Gate + - 27.10.2022 - v3.5.0.2 Applied Boy Scout Rule (Fixed some typos, changed var to let, fixed min/max colorTemp Bug) -Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Releais) genutzt werden -Tasmota Konsole: +Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden +Tasmota Konsole: Rule2 on Button1#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button2"} endon Rule2 1 (Rule aktivieren) - Rule2 0 (Rule deaktivieren) + Rule2 0 (Rule deaktivieren) Mögliche Seiten-Ansichten: screensaver Page - wird nach definiertem Zeitraum (config) mit Dimm-Modus aktiv (Uhrzeit, Datum, Aktuelle Temperatur mit Symbol) - (die 4 kleineren Icons können als Wetter-Vorschau + 4Tage (Symbol + Höschsttemperatur) oder zur Anzeige definierter Infos konfiguriert werden) + (die 4 kleineren Icons können als Wetter-Vorschau + 4Tage (Symbol + Höchsttemperatur) oder zur Anzeige definierter Infos konfiguriert werden) cardEntities Page - 4 vertikale angeordnete Steuerelemente - auch als Subpage cardGrid Page - 6 horizontal angeordnete Steuerelemente in 2 Reihen a 3 Steuerelemente - auch als Subpage cardThermo Page - Thermostat mit Solltemperatur, Isttemperatur, Mode - Weitere Eigenschaften können im Alias definiert werden - cardMedia Page - Mediaplayer - Ausnahme: Alias sollte mit Alias-Manager automatisch über Alexa-Verzeichnes Player angelegt werden + cardMedia Page - Mediaplayer - Ausnahme: Alias sollte mit Alias-Manager automatisch über Alexa-Verzeichnis Player angelegt werden cardAlarm Page - Alarmseite mit Zustand und Tastenfeld - cardPower Page - Energiefluss + cardPower Page - Energiefluss Popup-Pages: - popupLight Page - in Abhängigkeit zum gewählten Alias werden "Helligkeit", "Farb-Temperatur" und "Farbauswahl" bereitgestellt - popupShutter Page - die Shutter-Potition (Rollo, Jalousie, Markise, Leinwand, etc.) kann über einen Slider verändert werden. + popupLight Page - in Abhängigkeit zum gewählten Alias werden "Helligkeit", "Farbtemperatur" und "Farbauswahl" bereitgestellt + popupShutter Page - die Shutter-Position (Rollo, Jalousie, Markise, Leinwand, etc.) kann über einen Slider verändert werden. popupNotify Page - Info - Seite mit Headline Text und Buttons - Intern für manuelle Updates / Extern zur Befüllung von Datenpunkten unter 0_userdata screensaver Notify - Über zwei externe Datenpunkte in 0_userdata können "Headline" und "Text" an den Screensaver zur Info gesendet werden -Mögliche Aliase: (Vorzugsweise mit ioBroker-Adapter "Geräte verwalten" konfigurieren, da SET, GET, ACTUAL, etc. verwendet werden) +Mögliche Aliase: (Vorzugsweise mit ioBroker-Adapter "Geräte verwalten" konfigurieren, da SET, GET, ACTUAL, etc. verwendet werden) Info - Werte aus Datenpunkt Schieberegler - Slider numerische Werte (SET/ACTUAL) - Lautstärke - Volume (SET/ACTUAL) und MUTE - Lautstärke-Gruppe - analog Lautstärke + Lautstärke - Volume (SET/ACTUAL) und MUTE + Lautstärke-Gruppe - analog Lautstärke Licht - An/Aus (Schalter) Steckdose - An/Aus (Schalter) Dimmer - An/Aus, Brightness - Farbtemperatur - An/Aus, Farbtemperatur und Brightness - HUE-Licht - Zum Schalten von Color-Leuchtmitteln über HUE-Wert, Brightness, Farbtemperatur, An/Aus (HUE kann auch fehlen) - RGB-Licht - RGB-Leuchtmitteln/Stripes welche Rot/Grün/ und Blau separat benötigen (Tasmota, WifiLight, etc.) + Brightness, Farbtemperatur - RGB-Licht-einzeln - RGB-Leuchtmitteln/Stripes welche HEX-Farbwerte benötigen (Tasmota, WifiLight, etc.) + Brightness, Farbtemperatur - Jalousien - Up, Stop, Down, Position - Fenster - Sensor open - Tür - Sensor open + Farbtemperatur - An/Aus, Farbtemperatur und Brightness + HUE-Licht - Zum Schalten von Color-Leuchtmitteln über HUE-Wert, Brightness, Farbtemperatur, An/Aus (HUE kann auch fehlen) + RGB-Licht - RGB-Leuchtmitteln/Stripes welche Rot/Grün/ und Blau separat benötigen (Tasmota, WifiLight, etc.) + Brightness, Farbtemperatur + RGB-Licht-einzeln - RGB-Leuchtmitteln/Stripes welche HEX-Farbwerte benötigen (Tasmota, WifiLight, etc.) + Brightness, Farbtemperatur + Jalousien - Up, Stop, Down, Position + Fenster - Sensor open + Tür - Sensor open Verschluss - Türschloss SET/ACTUAL/OPEN Taste - Für Szenen oder Radiosender, etc. --> Nur Funktionsaufruf - Kein Taster wie MonoButton - True/False Tastensensor - analog Taste - Thermostat - Aktuelle Raumtemperatur, Setpoint, etc. + Thermostat - Aktuelle Raumtemperatur, Setpoint, etc. Klimaanlage - Buttons zur Steuerung der Klimaanlage im unteren Bereich - Temperatur - Anzeige von Temperture - Datenpunkten, ananlog Info - Feuchtigkeit - Anzeige von Humidity - Datenpunkten, ananlog Info - Medien - Steuerung von Alexa - Über Alias-Manager im Verzeichnis Player automatisch anlegen (Geräte-Manager funktioniert nicht) - Wettervorhersage - Aktuelle Außen-Temperatur (Temp) und aktuelles Accu-Wheather-Icon (Icon) für Screensaver + Temperatur - Anzeige von Temperatur - Datenpunkten, analog Info + Feuchtigkeit - Anzeige von Humidity - Datenpunkten, analog Info + Medien - Steuerung von Alexa - Über Alias-Manager im Verzeichnis Player automatisch anlegen (Geräte-Manager funktioniert nicht) + Wettervorhersage - Aktuelle Außen-Temperatur (Temp) und aktuelles AccuWeather-Icon (Icon) für Screensaver Interne Sonoff-Sensoren (über Tasmota): - ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden --> SetOption146 1 - Temperatur - Raumtemperatur - wird in 0_userdata.0. abgelegt, kann als Alias importieert werden - (!!! Achtung: der interne Sonoff-Sensor liefert keine exakten Daten, da das NSPanel-Board und der ESP selbst Hitze produzieren !!! + ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importiert werden --> SetOption146 1 + Temperatur - Raumtemperatur - wird in 0_userdata.0. abgelegt, kann als Alias importiert werden + (!!! Achtung: der interne Sonoff-Sensor liefert keine exakten Daten, da das NSPanel-Board und der ESP selbst Hitze produzieren !!! ggf. Offset einplanen oder besser einen externen Sensor über Zigbee etc. verwenden) Timestamp - wird in 0_userdata.0. Zeitpunkt der letzten Sensorübertragung -Tasmota-Status0 - (zyklische Ausführung) +Tasmota-Status0 - (zyklische Ausführung) liefert relevanten Tasmota-Informationen und kann bei Bedarf in "function get_tasmota_status0()" erweitert werden. Daten werden in 0_userdata.0. abgelegt Erforderliche Adapter: - Accu-Wheater: - Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver + AccuWeather: - Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia Geräte verwalten - Für Erstellung der Aliase - Alias-Manager - !!! ausschießlich für MEDIA-Alias + Alias-Manager - !!! ausschließlich für MEDIA-Alias MQTT-Adapter - Für Kommunikation zwischen Skript und Tasmota JavaScript-Adapter @@ -132,10 +133,12 @@ Upgrades in Konsole: Tasmota BerryDriver : Backlog UpdateDriverVersion https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; Restart 1 TFT EU STABLE Version : FlashNextion http://nspanel.pky.eu/lovelace-ui/github/nspanel-v3.5.0.tft --------------------------------------------------------------------------------------- -*/ -var Icons = new IconsSelector(); -var timeoutSlider: any; -var manually_Update = false; +*/ +import { config } from './NsPanelTs' + +let Icons = new IconsSelector(); +let timeoutSlider: any; +let manually_Update = false; const NSPanel_Path = '0_userdata.0.NSPanel.1.'; const NSPanel_Alarm_Path = '0_userdata.0.NSPanel.'; //Neuer Pfad für gemeinsame Nutzung durch mehrere Panels (bei Nutzung der cardAlarm) @@ -144,7 +147,7 @@ const Debug = false; // Variablen zur Steuerung der Wettericons auf dem Screensaver (Steuerung in 0_userdata.0.XPANELX.ScreensaverInfo) // Wenn weatherForecastTimer auf true, dann Wechsel zwischen Datenpunkten und Wettervorhersage (30 Sekunden nach Minute (Zeit)) // Wenn weatherForecastTimer auf false, dann Möglichkeit über weatherForecast, ob Datenpunkte oder Wettervorhersage (true = WeatherForecast/false = Datenpunkte) -var weatherForecast: boolean; //Änderung zum Video --> Einstellung siehe Wiki +let weatherForecast: boolean; // Änderung zum Video --> Einstellung siehe Wiki const HMIOff: RGB = { red: 68, green: 115, blue: 158 }; // Blau-Off - Original Entity Off const HMIDark: RGB = { red: 29, green: 29, blue: 29 }; // Original Background Color @@ -220,7 +223,7 @@ const swSnowyRainy: RGB = { red: 150, green: 150, blue: 255}; const swSunny: RGB = { red: 255, green: 255, blue: 0}; const swWindy: RGB = { red: 150, green: 150, blue: 150}; -var vwIconColor = []; +let vwIconColor = []; //-- Anfang der Variablen für Seitengestaltung -- Aliase erforderlich ---------------- @@ -228,41 +231,6 @@ var vwIconColor = []; //-- ENDE der Variablen für Seitengestaltung -- Aliase erforderlich ------------------ -export const config: Config = { - panelRecvTopic: 'mqtt.0.SmartHome.NSPanel_1.tele.RESULT', // anpassen - panelSendTopic: 'mqtt.0.SmartHome.NSPanel_1.cmnd.CustomSend', // anpassen - firstScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Hourly.h0.PrecipitationProbability', ScreensaverEntityIcon: 'weather-pouring', ScreensaverEntityText: 'Regen', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100} }, - secondScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.WindSpeed', ScreensaverEntityIcon: 'weather-windy', ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: 'km/h', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 120} }, - thirdScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.UVIndex', ScreensaverEntityIcon: 'solar-power', ScreensaverEntityText: 'UV', ScreensaverEntityUnitText: '', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 9} }, - fourthScreensaverEntity: { ScreensaverEntity: 'accuweather.0.Current.RelativeHumidity', ScreensaverEntityIcon: 'water-percent', ScreensaverEntityText: 'Luft', ScreensaverEntityUnitText: '%', ScreensaverEntityIconColor: {'val_min': 0, 'val_max': 100, 'val_best': 65} }, - alternativeScreensaverLayout: false, - autoWeatherColorScreensaverLayout: true, - //!!!! Achtung anpassen !!!! - mrIcon1ScreensaverEntity: { ScreensaverEntity: 'mqtt.0.SmartHome.NSPanel_1.stat.POWER1', ScreensaverEntityIcon: 'light-switch', ScreensaverEntityOnColor: On, ScreensaverEntityOffColor: Off }, - mrIcon2ScreensaverEntity: { ScreensaverEntity: 'mqtt.0.SmartHome.NSPanel_1.stat.POWER2', ScreensaverEntityIcon: 'lightbulb', ScreensaverEntityOnColor: On, ScreensaverEntityOffColor: Off }, - timeoutScreensaver: 20, - dimmode: 20, - active: 100, //Standard-Brightness TFT - screenSaverDoubleClick: true, - locale: 'de-DE', // en-US, de-DE, nl-NL, da-DK, es-ES, fr-FR, it-IT, ru-RU, etc. - timeFormat: '%H:%M', // currently not used - dateFormat: '%A, %d. %B %Y', // currently not used - weatherEntity: 'alias.0.Wetter', // Dieser Alias muss erstellt werden, damit die 4 kleineren Icons (Wetter oder DP) angezeigt werden können - defaultOffColor: Off, - defaultOnColor: On, - defaultColor: Off, - defaultBackgroundColor: Black, //New Parameter - temperatureUnit: '°C', - pages: [ - - ], - subPages: [ - - ], - button1Page: null, //Beispiel-Seite auf Button 1, wenn Rule2 definiert - Wenn nicht definiert --> button1Page: null, - button2Page: null //Beispiel-Seite auf Button 2, wenn Rule2 definiert - Wenn nicht definiert --> button1Page: null, -}; - // _________________________________ Ab hier keine Konfiguration mehr _____________________________________ const request = require('request'); @@ -296,37 +264,45 @@ on({id: [].concat([NSPanel_Path + 'PageNavi']), change: "any"}, async function ( function ScreensaverDimmode(timeDimMode: DimMode) { try { - if (Debug) console.log(rgb_dec565(HMIDark)) - if (Debug) console.log('Dimmode='+ timeDimMode.dimmodeOn) + if (Debug) { + console.log(rgb_dec565(HMIDark)) + } + if (Debug) { + console.log('Dimmode=' + timeDimMode.dimmodeOn) + } if (timeDimMode.dimmodeOn != undefined ? timeDimMode.dimmodeOn : false) { if (compareTime(timeDimMode.timeNight != undefined ? timeDimMode.timeNight : '22:00', timeDimMode.timeDay != undefined ? timeDimMode.timeDay : '07:00', 'not between', undefined)) { SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); - if (Debug) console.log('Day Payload: ' + 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active ) + if (Debug) { + console.log('Day Payload: ' + 'dimmode~' + timeDimMode.brightnessDay + '~' + config.active) + } } else { SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); - if (Debug) console.log('Night Payload: ' + 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active ) + if (Debug) { + console.log('Night Payload: ' + 'dimmode~' + timeDimMode.brightnessNight + '~' + config.active) + } } } else { SendToPanel({ payload: 'dimmode~' + config.dimmode + '~' + config.active + '~' + rgb_dec565(config.defaultBackgroundColor) }); } } catch (err) { console.warn('function ScreensaverDimmode: ' + err.message); - } + } } async function InitWeatherForecast() { try { //----Möglichkeit, im Screensaver zwischen Accu-Weather Forecast oder selbstdefinierten Werten zu wählen--------------------------------- - if (existsState(NSPanel_Path + "ScreensaverInfo.weatherForecast") == false || - existsState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer") == false || - existsState(NSPanel_Path + "ScreensaverInfo.entityChangeTime") == false) { + if (existsState(NSPanel_Path + "ScreensaverInfo.weatherForecast") == false || + existsState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer") == false || + existsState(NSPanel_Path + "ScreensaverInfo.entityChangeTime") == false) { await createStateAsync(NSPanel_Path + "ScreensaverInfo.weatherForecast", true, { type: 'boolean' }); await createStateAsync(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer", true, { type: 'boolean' }); await createStateAsync(NSPanel_Path + "ScreensaverInfo.entityChangeTime", 60, { type: 'number' }); - }; + } } catch (err) { console.warn('function InitWeatherForecast: ' + err.message); - } + } } InitWeatherForecast(); @@ -378,7 +354,7 @@ async function InitDimmode() { ScreensaverDimmode(timeDimMode); } catch (err) { console.warn('function InitDimmode: ' + err.message); - } + } } InitDimmode(); @@ -401,10 +377,10 @@ const popupNotifyButton2TextColor = NSPanel_Path + 'popupNotify.popupNotifyButto const popupNotifyButton2Text = NSPanel_Path + 'popupNotify.popupNotifyButton2Text'; const popupNotifySleepTimeout = NSPanel_Path + 'popupNotify.popupNotifySleepTimeout'; // in sek. / wenn 0, dann bleibt die Nachricht stehen const popupNotifyAction = NSPanel_Path + 'popupNotify.popupNotifyAction'; // Antwort aus dem Panel true/false -const popupNotifyLayout = NSPanel_Path + 'popupNotify.popupNotifyLayout'; -const popupNotifyFontIdText = NSPanel_Path + 'popupNotify.popupNotifyFontIdText'; 1 - 5 -const popupNotifyIcon = NSPanel_Path + 'popupNotify.popupNotifyIcon'; 1 - 5 -const popupNotifyIconColor = NSPanel_Path + 'popupNotify.popupNotifyIconColor'; 1 - 5 +const popupNotifyLayout = NSPanel_Path + 'popupNotify.popupNotifyLayout'; +const popupNotifyFontIdText = NSPanel_Path + 'popupNotify.popupNotifyFontIdText'; // 1 - 5 +const popupNotifyIcon = NSPanel_Path + 'popupNotify.popupNotifyIcon'; // 1 - 5 +const popupNotifyIconColor = NSPanel_Path + 'popupNotify.popupNotifyIconColor'; // 1 - 5 async function InitPopupNotify() { try { @@ -419,14 +395,14 @@ async function InitPopupNotify() { } await createStateAsync(popupNotifyHeading, { type: 'string' }); - await createStateAsync(popupNotifyHeadingColor, { type: 'string' }); + await createStateAsync(popupNotifyHeadingColor, { type: 'string' }); await createStateAsync(popupNotifyText, { type: 'string' }); - await createStateAsync(popupNotifyTextColor, { type: 'string' }); + await createStateAsync(popupNotifyTextColor, { type: 'string' }); await createStateAsync(popupNotifyInternalName, { type: 'string' }); await createStateAsync(popupNotifyButton1Text, { type: 'string' }); - await createStateAsync(popupNotifyButton1TextColor, { type: 'string' }); + await createStateAsync(popupNotifyButton1TextColor, { type: 'string' }); await createStateAsync(popupNotifyButton2Text, { type: 'string' }); - await createStateAsync(popupNotifyButton2TextColor, { type: 'string' }); + await createStateAsync(popupNotifyButton2TextColor, { type: 'string' }); await createStateAsync(popupNotifySleepTimeout, { type: 'number' }); await createStateAsync(popupNotifyAction, { type: 'boolean' }); await createStateAsync(popupNotifyLayout, { type: 'number' }); @@ -447,10 +423,10 @@ async function InitPopupNotify() { }); // popupNotify - Notification an separate Seite - on({ id: [popupNotifyInternalName], change: 'ne' }, async (obj) => { - - var notification : string = '' - + on({ id: [popupNotifyInternalName], change: 'ne' }, async () => { + + let notification: string; + let v_popupNotifyHeadingColor = (getState(popupNotifyHeadingColor).val != null) ? getState(popupNotifyHeadingColor).val : '65504'// Farbe Headline - gelb 65504 let v_popupNotifyButton1TextColor = (getState(popupNotifyButton1TextColor).val != null) ? getState(popupNotifyButton1TextColor).val : '63488'// Farbe Headline - gelb 65504 let v_popupNotifyButton2TextColor = (getState(popupNotifyButton2TextColor).val != null) ? getState(popupNotifyButton2TextColor).val : '2016'// Farbe Headline - gelb 65504 @@ -460,22 +436,22 @@ async function InitPopupNotify() { let v_popupNotifyIcon = (getState(popupNotifyIcon).val != null) ? getState(popupNotifyIcon).val : 'alert' notification = 'entityUpdateDetail' + '~' - + getState(popupNotifyInternalName).val + '~' - + getState(popupNotifyHeading).val + '~' - + v_popupNotifyHeadingColor + '~' - + getState(popupNotifyButton1Text).val + '~' - + v_popupNotifyButton1TextColor + '~' - + getState(popupNotifyButton2Text).val + '~' - + v_popupNotifyButton2TextColor + '~' - + getState(popupNotifyText).val + '~' - + v_popupNotifyTextColor + '~' - + getState(popupNotifySleepTimeout).val; + + getState(popupNotifyInternalName).val + '~' + + getState(popupNotifyHeading).val + '~' + + v_popupNotifyHeadingColor + '~' + + getState(popupNotifyButton1Text).val + '~' + + v_popupNotifyButton1TextColor + '~' + + getState(popupNotifyButton2Text).val + '~' + + v_popupNotifyButton2TextColor + '~' + + getState(popupNotifyText).val + '~' + + v_popupNotifyTextColor + '~' + + getState(popupNotifySleepTimeout).val; if (getState(popupNotifyLayout).val == 2) { notification = notification + '~' - + v_popupNotifyFontIdText + '~' - + Icons.GetIcon(v_popupNotifyIcon) + '~' - + v_popupNotifyIconColor; + + v_popupNotifyFontIdText + '~' + + Icons.GetIcon(v_popupNotifyIcon) + '~' + + v_popupNotifyIconColor; } setIfExists(config.panelSendTopic, 'pageType~popupNotify'); @@ -484,7 +460,7 @@ async function InitPopupNotify() { }); } catch (err) { console.warn('function InitPopupNotify: ' + err.message); - } + } } InitPopupNotify(); @@ -502,40 +478,40 @@ schedule('* * * * *', () => { SendTime(); } catch (err) { console.warn('schedule: ' + err.message); - } + } }); -//Wechsel zwischen Screensaver Enities und WeatherForecast +//Wechsel zwischen Screensaver Entities und WeatherForecast schedule('*/' + getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val + ' * * * * *', () => { try { - //WeatherForcast true/false Umschaltung verzögert + //WeatherForecast true/false Umschaltung verzögert if (getState(NSPanel_Path + "ScreensaverInfo.popupNotifyHeading").val == '' && getState(NSPanel_Path + "ScreensaverInfo.popupNotifyText").val == '' && getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val == true && getState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer").val == true) { - setStateDelayed(NSPanel_Path + "ScreensaverInfo.weatherForecast", false, (getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val / 2 * 1000), false); + setStateDelayed(NSPanel_Path + "ScreensaverInfo.weatherForecast", false, (getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val / 2 * 1000), false); } else if (getState(NSPanel_Path + "ScreensaverInfo.popupNotifyHeading").val == '' && getState(NSPanel_Path + "ScreensaverInfo.popupNotifyText").val == '' && getState(NSPanel_Path + "ScreensaverInfo.weatherForecast").val == false && getState(NSPanel_Path + "ScreensaverInfo.weatherForecastTimer").val == true) { setStateDelayed(NSPanel_Path + "ScreensaverInfo.weatherForecast", true, (getState(NSPanel_Path + 'ScreensaverInfo.entityChangeTime').val / 2 * 1000), false); } } catch (err) { console.warn('schedule: ' + err.message); - } + } }); function InitHWButton1Color() { try { if (config.mrIcon1ScreensaverEntity.ScreensaverEntity != null || config.mrIcon1ScreensaverEntity.ScreensaverEntity != undefined) { - on({id: config.mrIcon1ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) { + on({id: config.mrIcon1ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function () { HandleScreensaverUpdate(); }); } } catch (err) { console.warn('function InitHWButton1Color: ' + err.message); - } + } } InitHWButton1Color(); function InitHWButton2Color() { try { if (config.mrIcon2ScreensaverEntity.ScreensaverEntity != null || config.mrIcon2ScreensaverEntity.ScreensaverEntity != undefined) { - on({id: config.mrIcon2ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function (obj) { + on({id: config.mrIcon2ScreensaverEntity.ScreensaverEntity, change: "ne"}, async function () { HandleScreensaverUpdate(); }); } @@ -578,7 +554,9 @@ check_updates(); function get_locales() { try { - if (Debug) console.log('Requesting locales'); + if (Debug) { + console.log('Requesting locales'); + } request({ url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/ioBroker/ioBroker_NSPanel_locales.json', headers: { @@ -596,7 +574,7 @@ function get_locales() { }); } catch (err) { console.error('error requesting locales in function get_locales: ' + err.message); - } + } } async function check_updates() { @@ -604,13 +582,17 @@ async function check_updates() { const desired_display_firmware_version = 43; const berry_driver_version = 4; - if (Debug) console.log('Check-Updates'); + if (Debug) { + console.log('Check-Updates'); + } // Tasmota-Firmware-Vergleich if (existsObject(NSPanel_Path + 'Tasmota_Firmware.currentVersion') && existsObject(NSPanel_Path + 'Tasmota_Firmware.onlineVersion')) { if (getState(NSPanel_Path + 'Tasmota_Firmware.currentVersion').val !== getState(NSPanel_Path + 'Tasmota_Firmware.onlineVersion').val) { if (existsState(NSPanel_Path + 'NSPanel_autoUpdate')) { if (getState(NSPanel_Path + 'NSPanel_autoUpdate').val) { - if (Debug) console.log('Auto-Updates eingeschaltet - Update wird durchgeführt'); + if (Debug) { + console.log('Auto-Updates eingeschaltet - Update wird durchgeführt'); + } // Tasmota Upgrade durchführen update_tasmota_firmware(); // Aktuelle Tasmota Version = Online Tasmota Version @@ -618,7 +600,9 @@ async function check_updates() { await setStateAsync(NSPanel_Path + 'Tasmota_Firmware.currentVersion', { val: getState(NSPanel_Path + 'Tasmota_Firmware.onlineVersion').val, ack: true }); } else { // Auf Tasmota-Updates hinweisen - if (Debug) console.log('Automatische Updates aus'); + if (Debug) { + console.log('Automatische Updates aus'); + } const InternalName = 'TasmotaFirmwareUpdate'; const Headline = 'Tasmota-Firmware Update'; @@ -636,7 +620,9 @@ async function check_updates() { } } } else { - if (Debug) console.log('Tasmota-Version auf NSPanel aktuell'); + if (Debug) { + console.log('Tasmota-Version auf NSPanel aktuell'); + } } } @@ -650,10 +636,14 @@ async function check_updates() { // Aktuelle Berry-Driver Version = Online Berry-Driver Version await setStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', { val: getState(NSPanel_Path + 'Berry_Driver.onlineVersion').val, ack: true }); - if (Debug) console.log('Berry-Driver automatisch aktualisiert'); + if (Debug) { + console.log('Berry-Driver automatisch aktualisiert'); + } } else { //Auf BerryDriver-Update hinweisen - if (Debug) console.log('Automatische Updates aus'); + if (Debug) { + console.log('Automatische Updates aus'); + } const InternalName = 'BerryDriverUpdate'; const Headline = 'Berry-Driver Update'; @@ -671,7 +661,9 @@ async function check_updates() { } } } else { - if (Debug) console.log('Berry-Driver auf NSPanel aktuell'); + if (Debug) { + console.log('Berry-Driver auf NSPanel aktuell'); + } } } @@ -685,10 +677,14 @@ async function check_updates() { // Aktuelle TFT-Firmware Version = Online TFT-Firmware Version await setStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { val: getState(NSPanel_Path + 'Display_Firmware.onlineVersion').val, ack: true }); - if (Debug) console.log('Display_Firmware automatisch aktualisiert'); + if (Debug) { + console.log('Display_Firmware automatisch aktualisiert'); + } } else { // Auf TFT-Firmware hinweisen - if (Debug) console.log('Automatische Updates aus'); + if (Debug) { + console.log('Automatische Updates aus'); + } const InternalName = 'TFTFirmwareUpdate'; const Headline = 'TFT-Firmware Update'; @@ -706,7 +702,9 @@ async function check_updates() { } } } else { - if (Debug) console.log('Display_Firmware auf NSPanel aktuell'); + if (Debug) { + console.log('Display_Firmware auf NSPanel aktuell'); + } } } } catch (err) { @@ -720,7 +718,9 @@ on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async if (!val) { manually_Update = false; - if (Debug) console.log('Es wurde Button1 gedrückt'); + if (Debug) { + console.log('Es wurde Button1 gedrückt'); + } } else if (val) { if (manually_Update) { const internalName = getState(NSPanel_Path + 'popupNotify.popupNotifyInternalName').val; @@ -734,7 +734,9 @@ on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async } } - if (Debug) console.log('Es wurde Button2 gedrückt'); + if (Debug) { + console.log('Es wurde Button2 gedrückt'); + } } } catch (err) { console.warn('Trigger popupNotifyAction: ' + err.message); @@ -763,7 +765,9 @@ function get_current_tasmota_ip_address() { const infoObjId = config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESULT'.length) + 'INFO2'; const infoObj = JSON.parse(getState(infoObjId).val); - if (Debug) console.log(`get_current_tasmota_ip_address: ${infoObj.Info2.IPAddress}`); + if (Debug) { + console.log(`get_current_tasmota_ip_address: ${infoObj.Info2.IPAddress}`); + } return infoObj.Info2.IPAddress; } catch (err) { @@ -773,7 +777,9 @@ function get_current_tasmota_ip_address() { function get_online_tasmota_firmware_version() { try { - if (Debug) console.log('Requesting tasmota firmware version'); + if (Debug) { + console.log('Requesting tasmota firmware version'); + } request({ url: 'https://api.github.com/repositories/80286288/releases/latest', headers: { @@ -798,7 +804,9 @@ function get_online_tasmota_firmware_version() { function get_current_berry_driver_version() { try { - if (Debug) console.log('Requesting current berry driver version'); + if (Debug) { + console.log('Requesting current berry driver version'); + } request({ url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=GetDriverVersion`, headers: { @@ -819,7 +827,9 @@ function get_current_berry_driver_version() { function get_tasmota_status0() { try { - if (Debug) console.log('Requesting tasmota status0'); + if (Debug) { + console.log('Requesting tasmota status0'); + } request({ url: `http://${get_current_tasmota_ip_address()}/cm?cmnd=Status0`, headers: { @@ -864,7 +874,9 @@ function get_tasmota_status0() { function get_online_berry_driver_version() { try { - if (Debug) console.log('Requesting online berry driver version'); + if (Debug) { + console.log('Requesting online berry driver version'); + } request({ url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be', headers: { @@ -888,7 +900,9 @@ function get_online_berry_driver_version() { function check_version_tft_firmware() { try { - if (Debug) console.log('Requesting online TFT version'); + if (Debug) { + console.log('Requesting online TFT version'); + } request({ url: 'https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/latest', headers: { @@ -897,9 +911,9 @@ function check_version_tft_firmware() { }, async (error, response, result) => { if (result) { try { - var NSPanel_JSON = JSON.parse(result); // JSON Resultat in Variable Schreiben - var NSPanelTagName = NSPanel_JSON.tag_name; // created_at; published_at; name ; draft ; prerelease - var NSPanelVersion = NSPanelTagName.replace(/v/i, ''); // Aus Variable überflüssiges "v" filtern und in Release-Variable schreiben + let NSPanel_JSON = JSON.parse(result); // JSON Resultat in Variable Schreiben + let NSPanelTagName = NSPanel_JSON.tag_name; // created_at; published_at; name ; draft ; prerelease + let NSPanelVersion = NSPanelTagName.replace(/v/i, ''); // Aus Variable überflüssiges "v" filtern und in Release-Variable schreiben await createStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { type: 'string' }); await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { val: NSPanelVersion, ack: true }); @@ -915,7 +929,9 @@ function check_version_tft_firmware() { function check_online_display_firmware() { try { - if (Debug) console.log('Requesting online firmware version'); + if (Debug) { + console.log('Requesting online firmware version'); + } request({ url: 'https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py', headers: { @@ -941,8 +957,8 @@ function check_online_display_firmware() { on({ id: config.panelRecvTopic }, async (obj) => { if (obj.state.val.startsWith('\{"CustomRecv":')) { try { - var json = JSON.parse(obj.state.val); - var split = json.CustomRecv.split(','); + let json = JSON.parse(obj.state.val); + let split = json.CustomRecv.split(','); if (split[0] == 'event' && split[1] == 'startup') { await createStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { type: 'string' }); await createStateAsync(NSPanel_Path + 'NSPanel_Version', { type: 'string' }); @@ -963,7 +979,7 @@ function update_berry_driver_version() { headers: { 'User-Agent': 'ioBroker' } - }, async function (error, response, result) { + }, async function () { }); } catch (err) { @@ -980,7 +996,7 @@ function update_tft_firmware() { headers: { 'User-Agent': 'ioBroker' } - }, async function (error, response, result) { + }, async function () { await createStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { type: 'string' }); await setStateAsync(NSPanel_Path + 'TFT_Firmware.onlineVersion', { val: tft_version, ack: true }); }); @@ -996,7 +1012,7 @@ function update_tasmota_firmware() { headers: { 'User-Agent': 'ioBroker' } - }, async function (error, response, result) { + }, async function () { }); } catch (err) { console.warn('error at function update_tasmota_firmware: ' + err.message); @@ -1005,7 +1021,7 @@ function update_tasmota_firmware() { //------------------End Update Functions // Only monitor the extra nodes if present -var updateArray: string[] = []; +let updateArray: string[] = []; if (config.firstScreensaverEntity !== null && config.firstScreensaverEntity.ScreensaverEntity != null && existsState(config.firstScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.firstScreensaverEntity.ScreensaverEntity) @@ -1029,9 +1045,9 @@ on({ id: config.panelRecvTopic }, function (obj) { try { if (obj.state.val.startsWith('\{"CustomRecv":')) { try { - var json = JSON.parse(obj.state.val); + let json = JSON.parse(obj.state.val); - var split = json.CustomRecv.split(','); + let split = json.CustomRecv.split(','); HandleMessage(split[0], split[1], parseInt(split[2]), split); } catch (err) { console.warn(err.message); @@ -1045,9 +1061,11 @@ on({ id: config.panelRecvTopic }, function (obj) { function SendToPanel(val: Payload | Payload[]): void { try { if (Array.isArray(val)) { - val.forEach(function (id, i) { + val.forEach(function (id) { setState(config.panelSendTopic, id.payload); - if (Debug) console.log(id.payload); + if (Debug) { + console.log(id.payload); + } }); } else { setState(config.panelSendTopic, val.payload); @@ -1060,7 +1078,9 @@ function SendToPanel(val: Payload | Payload[]): void { 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) console.log(activePage); + if (Debug) { + console.log(activePage); + } if (NSPanel_Path == getState(NSPanel_Alarm_Path + 'Alarm.PANEL').val) { GeneratePage(activePage); } @@ -1091,17 +1111,22 @@ function HandleMessage(typ: string, method: string, page: number, words: Array { pageItem = sp.items.find(e => e.id === searching); - if (pageItem !== undefined) { - return false; - } - return true; + + return pageItem === undefined; }); return pageItem; @@ -1166,7 +1189,7 @@ function GeneratePage(page: Page): void { } function HandleHardwareButton(method: string): void { - try { + try { let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | PageQR | PagePower); if (config.button1Page !== null && method == 'button1') { page = config.button1Page; @@ -1216,7 +1239,7 @@ function SendTime(): void { function GenerateEntitiesPage(page: PageEntities): Payload[] { try { - var out_msgs: Array = []; + let out_msgs: Array; out_msgs = [{ payload: 'pageType~cardEntities' }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs @@ -1227,8 +1250,7 @@ function GenerateEntitiesPage(page: PageEntities): Payload[] { function GenerateGridPage(page: PageGrid): Payload[] { try { - var out_msgs: Array = []; - out_msgs = [{ payload: 'pageType~cardGrid' }] + let out_msgs: Array = [{ payload: 'pageType~cardGrid' }]; out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } catch (err) { @@ -1280,17 +1302,17 @@ function GeneratePageElements(page: Page): string { function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string { try { - var iconId = '0'; + let iconId = '0'; if (pageItem.id == 'delete') { return '~delete~~~~~'; } - var name: string; - var type: string; + let name: string; + let type: string; // ioBroker if (existsObject(pageItem.id) || pageItem.navigate === true) { - var iconColor = rgb_dec565(config.defaultColor); + let iconColor = rgb_dec565(config.defaultColor); if (pageItem.navigate) { type = 'button'; @@ -1301,7 +1323,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = } let o = getObject(pageItem.id) - var val = null; + let val = null; if (existsState(pageItem.id + '.GET')) { val = getState(pageItem.id + '.GET').val; @@ -1314,13 +1336,15 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = // Fallback if no name is given name = pageItem.name !== undefined ? pageItem.name : o.common.name.de; + let optVal = '0'; + switch (o.common.role) { case 'socket': case 'light': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); - var iconId2 = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); - var optVal = '0'; + let iconId2 = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : o.common.role == 'socket' ? Icons.GetIcon('power-socket-de') : Icons.GetIcon('lightbulb'); + optVal = '0'; if (val === true || val === 'true') { optVal = '1'; @@ -1339,7 +1363,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'hue': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1351,7 +1375,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = iconColor = GetIconColor(pageItem, existsState(pageItem.id + '.DIMMER') ? 100 - getState(pageItem.id + '.DIMMER').val : true, useColors); } - if (pageItem.interpolateColor != undefined && pageItem.interpolateColor == true) { + if (pageItem.interpolateColor != undefined && pageItem.interpolateColor == true) { if (existsState(pageItem.id + '.HUE')) { if (getState(pageItem.id + '.HUE').val != null) { let huecolor = hsv2rgb(getState(pageItem.id + '.HUE').val, 1, 1); @@ -1367,7 +1391,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'ct': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON')) { val = getState(pageItem.id + '.ON').val; @@ -1384,7 +1408,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'rgb': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1411,7 +1435,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'rgbSingle': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1425,10 +1449,10 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = if (existsState(pageItem.id + '.RGB')) { if (getState(pageItem.id + '.RGB').val != null) { - var hex = getState(pageItem.id + '.RGB').val; - var hexRed = parseInt(hex[1] + hex[2], 16); - var hexGreen = parseInt(hex[3] + hex[4], 16); - var hexBlue = parseInt(hex[5] + hex[6], 16); + let hex = getState(pageItem.id + '.RGB').val; + let hexRed = parseInt(hex[1] + hex[2], 16); + let hexGreen = parseInt(hex[3] + hex[4], 16); + let hexBlue = parseInt(hex[5] + hex[6], 16); let rgb = { red: Math.round(hexRed), green: Math.round(hexGreen), blue: Math.round(hexBlue) }; iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); } @@ -1439,7 +1463,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = case 'dimmer': type = 'light'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lightbulb'); - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { val = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1463,40 +1487,43 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~'; - case 'gate': + case 'gate': type = 'text'; + let gateState: string; if (existsState(pageItem.id + '.ACTUAL')) { + if (getState(pageItem.id + '.ACTUAL').val == 0 || getState(pageItem.id + '.ACTUAL').val === false) { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage'); iconColor = GetIconColor(pageItem, false, useColors); - var gateState = findLocale('window', 'closed'); + gateState = findLocale('window', 'closed'); } else { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('garage-open'); iconId = pageItem.icon2 !== undefined ? Icons.GetIcon(pageItem.icon2) : Icons.GetIcon('garage-open'); iconColor = GetIconColor(pageItem, true, useColors); - var gateState = findLocale('window', 'opened'); + gateState = findLocale('window', 'opened'); } - + RegisterEntityWatcher(pageItem.id + '.ACTUAL'); - + } - + return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + gateState; case 'door': case 'window': type = 'text'; + let windowState; if (existsState(pageItem.id + '.ACTUAL')) { if (getState(pageItem.id + '.ACTUAL').val) { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'door' ? Icons.GetIcon('door-open') : Icons.GetIcon('window-open-variant'); iconColor = GetIconColor(pageItem, false, useColors); - var windowState = findLocale('window', 'opened'); + windowState = findLocale('window', 'opened'); } else { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'door' ? Icons.GetIcon('door-closed') : Icons.GetIcon('window-closed-variant'); //iconId = Icons.GetIcon('window-closed-variant'); iconColor = GetIconColor(pageItem, true, useColors); - var windowState = findLocale('window', 'closed'); + windowState = findLocale('window', 'closed'); } RegisterEntityWatcher(pageItem.id + '.ACTUAL'); @@ -1522,7 +1549,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = type = 'text'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == 'value.temperature' || o.common.role == 'thermostat' ? Icons.GetIcon('thermometer') : Icons.GetIcon('information-outline'); let unit = ''; - var optVal = '0'; + optVal = '0'; if (existsState(pageItem.id + '.ON_ACTUAL')) { optVal = getState(pageItem.id + '.ON_ACTUAL').val; @@ -1555,16 +1582,17 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = type = 'button'; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock'); iconColor = GetIconColor(pageItem, true, useColors); + let lockState; if (existsState(pageItem.id + '.ACTUAL')) { if (getState(pageItem.id + '.ACTUAL').val) { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock'); iconColor = GetIconColor(pageItem, true, useColors); - var lockState = findLocale('lock', 'UNLOCK'); + lockState = findLocale('lock', 'UNLOCK'); } else { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('lock-open-variant'); iconColor = GetIconColor(pageItem, false, useColors); - var lockState = findLocale('lock', 'LOCK'); + lockState = findLocale('lock', 'LOCK'); } lockState = pageItem.buttonText !== undefined ? pageItem.buttonText : lockState; RegisterEntityWatcher(pageItem.id + '.ACTUAL'); @@ -1643,7 +1671,9 @@ function findLocale(controlsObject: string, controlsState: string): string { const locale = config.locale; const strJson = getState(NSPanel_Path + 'NSPanel_locales_json').val; - if (Debug) console.log(controlsObject + ' - ' + controlsState); + if (Debug) { + console.log(controlsObject + ' - ' + controlsState); + } try { const obj = JSON.parse(strJson); @@ -1657,8 +1687,10 @@ function findLocale(controlsObject: string, controlsState: string): string { } catch (err) { if (err.message.substring(0, 35) == 'Cannot read properties of undefined') { - if (Debug) console.log('function findLocale: missing translation: ' + controlsObject + ' - ' + controlsState); - } else { + if (Debug) { + console.log('function findLocale: missing translation: ' + controlsObject + ' - ' + controlsState); + } + } else { console.warn('function findLocale: ' + err.message); } return controlsState; @@ -1677,11 +1709,11 @@ function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: value = value < minValue ? minValue : value; return rgb_dec565( - Interpolate( - pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor, - pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor, - scale(value, minValue, maxValue, 0, 1) - ) + Interpolate( + pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor, + pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor, + scale(value, minValue, maxValue, 0, 1) + ) ); } @@ -1701,7 +1733,7 @@ function RegisterEntityWatcher(id: string): void { return; } - subscriptions[id] = (on({ id: id, change: 'any' }, (data) => { + subscriptions[id] = (on({ id: id, change: 'any' }, () => { if (pageId == -1 && config.button1Page != undefined) { SendToPanel({ payload: GeneratePageElements(config.button1Page) }); } @@ -1753,8 +1785,8 @@ function GetUnitOfMeasurement(id: string): string { function GenerateThermoPage(page: PageThermo): Payload[] { try { - var id = page.items[0].id - var out_msgs: Array = []; + let id = page.items[0].id + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardThermo' }); // ioBroker @@ -1782,15 +1814,16 @@ function GenerateThermoPage(page: PageThermo): Payload[] { } let statusStr: String = 'MANU'; let status = ''; - if (existsState(id + '.MODE')) - status = getState(id + '.MODE').val; + if (existsState(id + '.MODE')) { + status = getState(id + '.MODE').val; // FixMe: Variable status is never used! + } //Attribute hinzufügen, wenn im Alias definiert let i_list = Array.prototype.slice.apply($('[state.id="' + id + '.*"]')); + let bt = ['~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~']; if ((i_list.length - 3) != 0) { - var i = 0; - var bt = ['~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~', '~~~~']; + let i = 0; if (o.common.role == 'thermostat') { @@ -1838,9 +1871,9 @@ function GenerateThermoPage(page: PageThermo): Payload[] { for (let i_index in i_list) { let thermostatState = i_list[i_index].split('.'); if ( - thermostatState[thermostatState.length - 1] != 'SET' && - thermostatState[thermostatState.length - 1] != 'ACTUAL' && - thermostatState[thermostatState.length - 1] != 'MODE' + thermostatState[thermostatState.length - 1] != 'SET' && + thermostatState[thermostatState.length - 1] != 'ACTUAL' && + thermostatState[thermostatState.length - 1] != 'MODE' ) { i++; @@ -1989,27 +2022,29 @@ function GenerateThermoPage(page: PageThermo): Payload[] { out_msgs.push({ payload: 'entityUpd~' - + name + '~' // Heading - + GetNavigationString(pageId) + '~' // Page Navigation - + id + '~' // internalNameEntiy - + currentTemp + config.temperatureUnit + '~' // Ist-Temperatur (String) - + destTemp + '~' // Soll-Temperatur (numerisch ohne Komma) - + statusStr + '~' // Mode - + minTemp + '~' // Thermostat Min-Temperatur - + maxTemp + '~' // Thermostat Max-Temperatur - + stepTemp + '~' // Schritte für Soll (5°C) - + icon_res // Icons Status - + findLocale('thermostat', 'Currently') + '~' // Bezeicher vor Aktueller Raumtemperatur - + findLocale('thermostat', 'State') + '~' // Bezeicner vor - + '~' // Bezeichner vor HVAC -- Gibt es nicht mehr - + config.temperatureUnit + '~' // Bezeichner hinter Solltemp - + '' + '~' // iconTemperature dstTempTwoTempMode - + '' // dstTempTwoTempMode + + name + '~' // Heading + + GetNavigationString(pageId) + '~' // Page Navigation + + id + '~' // internalNameEntity + + currentTemp + config.temperatureUnit + '~' // Ist-Temperatur (String) + + destTemp + '~' // Soll-Temperatur (numerisch ohne Komma) + + statusStr + '~' // Mode + + minTemp + '~' // Thermostat Min-Temperatur + + maxTemp + '~' // Thermostat Max-Temperatur + + stepTemp + '~' // Schritte für Soll (5°C) + + icon_res // Icons Status + + findLocale('thermostat', 'Currently') + '~' // Bezeichner vor Aktueller Raumtemperatur + + findLocale('thermostat', 'State') + '~' // Bezeichner vor + + '~' // Bezeichner vor HVAC -- Gibt es nicht mehr + + config.temperatureUnit + '~' // Bezeichner hinter Solltemp + + '' + '~' // iconTemperature dstTempTwoTempMode + + '' // dstTempTwoTempMode }); } - if (Debug) console.log(out_msgs); + if (Debug) { + console.log(out_msgs); + } return out_msgs } catch (err) { console.warn('function GenerateThermoPage: ' + err.message); @@ -2018,38 +2053,38 @@ function GenerateThermoPage(page: PageThermo): Payload[] { function GenerateMediaPage(page: PageMedia): Payload[] { try { - var id = page.items[0].id - - var out_msgs: Array = []; + let id = page.items[0].id + + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardMedia' }); if (existsObject(id)) { let name = getState(id + '.ALBUM').val; let title = getState(id + '.TITLE').val; let author = getState(id + '.ARTIST').val; - + let vInstance = page.items[0].adapterPlayerInstance; let v1Adapter = vInstance.split('.'); let v2Adapter = v1Adapter[0]; - //Alexa + neue Adpter/Player + //Alexa + neue Adapter/Player let media_icon = Icons.GetIcon('playlist-music'); //Spotify-Premium if (v2Adapter == 'spotify-premium') { media_icon = Icons.GetIcon('spotify'); name = getState(id + '.CONTEXT_DESCRIPTION').val; - let nameLenght = name.length; + let nameLength = name.length; if (name.substring(0,9) == 'Playlist:') { - let nameLenght = name.length; - name = name.slice(10, nameLenght); + let nameLength = name.length; + name = name.slice(10, nameLength); } else if (name.substring(0,6) == 'Album:') { - let nameLenght = name.length; - name = name.slice(10, nameLenght); - } else if (name.substring(0,6) == 'Track') { + let nameLength = name.length; + name = name.slice(10, nameLength); + } else if (name.substring(0,6) == 'Track') { name = 'Spotify-Premium'; } - if (nameLenght == 0) { + if (nameLength == 0) { name = 'Spotify-Premium'; } author = getState(id + '.ARTIST').val + ' | ' + getState(id + '.ALBUM').val; @@ -2057,7 +2092,7 @@ function GenerateMediaPage(page: PageMedia): Payload[] { author = getState(id + '.ARTIST').val; } if ((getState(id + '.ARTIST').val).length == 0) { - author = 'no music to control'; + author = 'no music to control'; } } @@ -2068,36 +2103,36 @@ function GenerateMediaPage(page: PageMedia): Payload[] { let nameLenght = name.length; if (nameLenght == 0) { name = 'Sonos Player'; - } + } author = getState(id + '.ARTIST').val + ' | ' + getState(id + '.ALBUM').val; if ((getState(id + '.ARTIST').val).length == 0) { - author = 'no music to control'; + author = 'no music to control'; } } //Logitech Squeezebox RPC if (v2Adapter == 'squeezeboxrpc') { media_icon = Icons.GetIcon('dlna'); - let nameLenght = name.length; - if (nameLenght == 0) { + let nameLength = name.length; + if (nameLength == 0) { name = 'Squeezebox RPC'; author = 'no music to control'; - } + } } //Alexa2 if (v2Adapter == 'alexa2') { media_icon = Icons.GetIcon('playlist-music'); - let nameLenght = name.length; - if (nameLenght == 0) { + let nameLength = name.length; + if (nameLength == 0) { name = 'Alexa Player'; - author = 'no music to control'; - } + author = 'no music to control'; + } } - + let volume = getState(id + '.VOLUME').val; - var iconplaypause = Icons.GetIcon('pause'); //pause - var onoffbutton = 1374; + let iconplaypause = Icons.GetIcon('pause'); //pause + let onoffbutton = 1374; //Für alle Player if (getState(id + '.STATE').val) { @@ -2115,14 +2150,16 @@ function GenerateMediaPage(page: PageMedia): Payload[] { iconplaypause = Icons.GetIcon('play'); //play } - if (Debug) console.log(v2Adapter); + if (Debug) { + console.log(v2Adapter); + } let currentSpeaker = 'kein Speaker gefunden'; if (v2Adapter == 'alexa2') { currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', page.items[0].mediaDevice, '.Info.name'].join(''))).val; } else if (v2Adapter == 'spotify-premium') { - currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'player.device.name'].join(''))).val; + currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'player.device.name'].join(''))).val; } else if (v2Adapter == 'sonos') { currentSpeaker = getState(([page.items[0].adapterPlayerInstance, 'root.', page.items[0].mediaDevice, '.members'].join(''))).val; } else if (v2Adapter == 'squeezeboxrpc') { @@ -2133,10 +2170,10 @@ function GenerateMediaPage(page: PageMedia): Payload[] { //------------------------------------------------------------------------------------------------------------- // nachfolgend alle Alexa-Devices (ist Online / Player- und Commands-Verzeichnis vorhanden) auflisten und verketten // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter - let speakerlist = ''; + let speakerList = ''; if (page.items[0].speakerList.length > 0) { for (let i_index in page.items[0].speakerList) { - speakerlist = speakerlist + page.items[0].speakerList[i_index] + '?'; + speakerList = speakerList + page.items[0].speakerList[i_index] + '?'; } } else { let i_list = Array.prototype.slice.apply($('[state.id="' + page.items[0].adapterPlayerInstance + 'Echo-Devices.*.Info.name"]')); @@ -2145,31 +2182,33 @@ function GenerateMediaPage(page: PageMedia): Payload[] { let deviceId = i; deviceId = deviceId.split('.'); if (getState(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.online'].join(''))).val && - existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Player'].join(''))) && - existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Commands'].join('')))) { - speakerlist = speakerlist + getState(i).val + '?'; + existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Player'].join(''))) && + existsObject(([page.items[0].adapterPlayerInstance, 'Echo-Devices.', deviceId[3], '.Commands'].join('')))) { + speakerList = speakerList + getState(i).val + '?'; } } } - speakerlist = speakerlist.substring(0, speakerlist.length - 1); + speakerList = speakerList.substring(0, speakerList.length - 1); //-------------------------------------------------------------------------------------------------------------- out_msgs.push({ payload: 'entityUpd~' + //entityUpd - name + '~' + //heading - GetNavigationString(pageId) + '~' + //navigation - id + '~' + //internalNameEntiy - media_icon + '~' + //icon - title + '~' + //title - author + '~' + //author - volume + '~' + //volume - iconplaypause + '~' + //playpauseicon - currentSpeaker + '~' + //currentSpeaker - speakerlist + '~' + //speakerList-seperated-by-? - onoffbutton + name + '~' + //heading + GetNavigationString(pageId) + '~' + //navigation + id + '~' + //internalNameEntiy + media_icon + '~' + //icon + title + '~' + //title + author + '~' + //author + volume + '~' + //volume + iconplaypause + '~' + //playpauseicon + currentSpeaker + '~' + //currentSpeaker + speakerList + '~' + //speakerList-seperated-by-? + onoffbutton }); //On/Off Button Color } - if (Debug) console.log(out_msgs); + if (Debug) { + console.log(out_msgs); + } return out_msgs } catch (err) { console.warn('function GenerateMediaPage: ' + err.message); @@ -2179,11 +2218,11 @@ function GenerateMediaPage(page: PageMedia): Payload[] { function GenerateAlarmPage(page: PageAlarm): Payload[] { try { activePage = page; - var id = page.items[0].id - - var out_msgs: Array = []; + let id = page.items[0].id + + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardAlarm' }); - var nsPath = NSPanel_Alarm_Path + 'Alarm.'; + let nsPath = NSPanel_Alarm_Path + 'Alarm.'; if (existsState(nsPath + 'AlarmPin') == false || existsState(nsPath + 'AlarmState') == false || existsState(nsPath + 'AlarmType') == false || existsState(nsPath + 'PIN_Failed') == false || existsState(nsPath + 'PANEL') == false) { createState(nsPath + 'AlarmPin', '0000', { type: 'string' }, function () { setState(nsPath + 'AlarmPin', '0000') }); @@ -2194,17 +2233,19 @@ function GenerateAlarmPage(page: PageAlarm): Payload[] { } if (existsState(nsPath + 'AlarmPin') && existsState(nsPath + 'AlarmState') && existsState(nsPath + 'AlarmType')) { - //var entityPin = getState(nsPath + 'AlarmPin').val; - var entityState = getState(nsPath + 'AlarmState').val; - //var entityType = getState(nsPath + 'AlarmType').val; - var arm1: string, arm2: string, arm3: string, arm4: string; - var arm1ActionName: string, arm2ActionName: string, arm3ActionName: string, arm4ActionName: string; - var icon = '0'; - var iconcolor = 63488; - var numpadStatus = 'disable'; - var flashing = 'disable'; + //let entityPin = getState(nsPath + 'AlarmPin').val; + let entityState = getState(nsPath + 'AlarmState').val; + //let entityType = getState(nsPath + 'AlarmType').val; + let arm1: string, arm2: string, arm3: string, arm4: string; + let arm1ActionName: string, arm2ActionName: string, arm3ActionName: string, arm4ActionName: string; + let icon = '0'; + let iconcolor = 63488; + let numpadStatus = 'disable'; + let flashing = 'disable'; - if (Debug) console.log(id); + if (Debug) { + console.log(id); + } if (entityState == 'armed' || entityState == 'triggered') { arm1 = 'Deaktivieren'; //arm1*~* @@ -2255,23 +2296,25 @@ function GenerateAlarmPage(page: PageAlarm): Payload[] { out_msgs.push({ payload: 'entityUpd~' + //entityUpd~* - id + '~' + //internalNameEntity*~* - GetNavigationString(pageId) + '~' + //navigation*~* --> hiddenCards - arm1 + '~' + //arm1*~* - arm1ActionName + '~' + //arm1ActionName*~* - arm2 + '~' + //arm2*~* - arm2ActionName + '~' + //arm2ActionName*~* - arm3 + '~' + //arm3*~* - arm3ActionName + '~' + //arm3ActionName*~* - arm4 + '~' + //arm4*~* - arm4ActionName + '~' + //arm4ActionName*~* - icon + '~' + //icon*~* - iconcolor + '~' + //iconcolor*~* - numpadStatus + '~' + //numpadStatus*~* - flashing + id + '~' + //internalNameEntity*~* + GetNavigationString(pageId) + '~' + //navigation*~* --> hiddenCards + arm1 + '~' + //arm1*~* + arm1ActionName + '~' + //arm1ActionName*~* + arm2 + '~' + //arm2*~* + arm2ActionName + '~' + //arm2ActionName*~* + arm3 + '~' + //arm3*~* + arm3ActionName + '~' + //arm3ActionName*~* + arm4 + '~' + //arm4*~* + arm4ActionName + '~' + //arm4ActionName*~* + icon + '~' + //icon*~* + iconcolor + '~' + //iconcolor*~* + numpadStatus + '~' + //numpadStatus*~* + flashing }); //flashing* - if (Debug) console.log(out_msgs); + if (Debug) { + console.log(out_msgs); + } return out_msgs } } catch (err) { @@ -2283,37 +2326,39 @@ function GenerateQRPage(page: PageQR): Payload[] { try { activePage = page; - var id = page.items[0].id - var out_msgs: Array = []; + let id = page.items[0].id + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardQR' }); let o = getObject(id) - var heading = page.heading !== undefined ? page.heading : o.common.name.de - var textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;' - var hiddenPWD = false; + let heading = page.heading !== undefined ? page.heading : o.common.name.de + let textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;' + let hiddenPWD = false; if (page.items[0].hidePassword !== undefined && page.items[0].hidePassword == true) { hiddenPWD = true } const tempstr = textQR.split(';'); + let optionalValue1; + let optionalValue2 for (let w = 0; w < tempstr.length - 1; w++) { if (tempstr[w].substring(0, 1) == 'S') { - var optionalValue1 = tempstr[w].slice(2); + optionalValue1 = tempstr[w].slice(2); } if (tempstr[w].substring(0, 1) == 'P') { - var optionalValue2 = tempstr[w].slice(2); + optionalValue2 = tempstr[w].slice(2); } } - var type1 = 'text'; - var internalName1 = 'SSID'; - var iconId1 = Icons.GetIcon('wifi'); - var displayName1 = 'SSID'; - var type2 = 'text'; - var internalName2 = 'Passwort'; - var iconId2 = Icons.GetIcon('key'); - var displayName2 = 'Passwort'; + let type1 = 'text'; + let internalName1 = 'SSID'; + let iconId1 = Icons.GetIcon('wifi'); + let displayName1 = 'SSID'; + let type2 = 'text'; + let internalName2 = 'Passwort'; + let iconId2 = Icons.GetIcon('key'); + let displayName2 = 'Passwort'; if (hiddenPWD) { type2 = 'disable'; @@ -2323,21 +2368,21 @@ function GenerateQRPage(page: PageQR): Payload[] { out_msgs.push({ payload: 'entityUpd~' + //entityUpd - heading + '~' + //heading - GetNavigationString(pageId) + '~' + //navigation - textQR + '~' + //textQR - type1 + '~' + //type - internalName1 + '~' + //internalName - iconId1 + '~' + //iconId - 65535 + '~' + //iconColor - displayName1 + '~' + //displayName - optionalValue1 + '~' + //optionalValue - type2 + '~' + //type - internalName2 + '~' + //internalName - iconId2 + '~' + //iconId - 65535 + '~' + //iconColor - displayName2 + '~' + //displayName - optionalValue2 + heading + '~' + //heading + GetNavigationString(pageId) + '~' + //navigation + textQR + '~' + //textQR + type1 + '~' + //type + internalName1 + '~' + //internalName + iconId1 + '~' + //iconId + 65535 + '~' + //iconColor + displayName1 + '~' + //displayName + optionalValue1 + '~' + //optionalValue + type2 + '~' + //type + internalName2 + '~' + //internalName + iconId2 + '~' + //iconId + 65535 + '~' + //iconColor + displayName2 + '~' + //displayName + optionalValue2 }); //optionalValue //entityUpd,heading,navigation,textQR[,type,internalName,iconId,displayName,optionalValue]x2 @@ -2352,30 +2397,33 @@ function GeneratePowerPage(page: PagePower): Payload[] { try { activePage = page; - if (Debug) console.log(page.items[0].id); + if (Debug) { + console.log(page.items[0].id); + } - var demoMode = false; + let demoMode = false; + let id; - try { - var id = page.items[0].id + try { + id = page.items[0].id } catch (err) { console.log("Kein PageItem definiert - cardPower Demo-Modus aktiv"); demoMode = true; - } + } let heading = 'cardPower Example'; if (demoMode != true) { let o = getObject(id) - heading = page.heading !== undefined ? page.heading : o.common.name.de - } + heading = page.heading !== undefined ? page.heading : o.common.name.de + } const obj = JSON.parse((getState(page.items[0].id + '.ACTUAL').val)); - var out_msgs: Array = []; + let out_msgs: Array = []; out_msgs.push({ payload: 'pageType~cardPower' }); //Demo Data if no pageItem present - let array_icon_color = [White, MSGreen, MSYellow, MSGreen, MSYellow, MSGreen, MSRed]; + let array_icon_color = [White, MSGreen, MSYellow, MSGreen, MSYellow, MSGreen, MSRed]; let array_icon = ['home', 'battery-charging-60', 'solar-power-variant', 'wind-turbine', 'shape', 'transmission-tower', 'car']; let array_powerspeed = ['', '-1', '2', '4', '1', '1', '5']; let array_powerstate = ['', '0,5 kW', '0,9 kW', '2,8 kW', '0,2 kW', '0,1 kW', '4,6 kW']; @@ -2388,11 +2436,11 @@ function GeneratePowerPage(page: PagePower): Payload[] { array_icon[obji + 1] = obj[obji].icon; array_powerspeed[obji + 1] = obj[obji].speed; array_powerstate[obji + 1] = obj[obji].value + ' ' + obj[obji].unit ; - } + } } let power_string : any = ''; - + for (let i = 1; i < 7; i++ ) { power_string = power_string + rgb_dec565(array_icon_color[i]) + '~'; // icon_color~ power_string = power_string + Icons.GetIcon(array_icon[i]) + '~'; // icon~ @@ -2400,16 +2448,16 @@ function GeneratePowerPage(page: PagePower): Payload[] { power_string = power_string + array_powerstate[i] + '~'; // entity.state~ } - power_string = power_string.substring(0, power_string.length - 1); + power_string = power_string.substring(0, power_string.length - 1); out_msgs.push({ payload: 'entityUpd~' + //entityUpd~* - heading + '~' + //internalNameEntity*~* - GetNavigationString(pageId) + '~' + //navigation*~* - rgb_dec565(array_icon_color[0]) + '~' + // icon_color~ Mitte - Icons.GetIcon(array_icon[0]) + '~' + // icon~ Mitte - array_powerspeed[0] + '~' + // entity.state~ Mitte - power_string + heading + '~' + //internalNameEntity*~* + GetNavigationString(pageId) + '~' + //navigation*~* + rgb_dec565(array_icon_color[0]) + '~' + // icon_color~ Mitte + Icons.GetIcon(array_icon[0]) + '~' + // icon~ Mitte + array_powerspeed[0] + '~' + // entity.state~ Mitte + power_string }); return out_msgs @@ -2437,7 +2485,7 @@ function setIfExists(id: string, value: any, type: string | null = null): boolea return false; } catch (err) { console.warn('function setIfExists: ' + err.message); - } + } } function toggleState(id: string): boolean { @@ -2450,13 +2498,13 @@ function toggleState(id: string): boolean { return false; } catch (err) { console.warn('function toggleState: ' + err.message); - } + } } function HandleButtonEvent(words): void { try { - var id = words[2] - var buttonAction = words[3]; + let id = words[2] + let buttonAction = words[3]; if (Debug) { console.log(words[0] + ' - ' + words[1] + ' - ' + words[2] + ' - ' + words[3] + ' - ' + words[4] + ' - PageId: ' + pageId); @@ -2467,7 +2515,11 @@ function HandleButtonEvent(words): void { return; } - if (Debug) console.log(buttonAction); + if (Debug) { + console.log(buttonAction); + } + + let pageNum:number = 0; switch (buttonAction) { case 'bUp': @@ -2480,13 +2532,13 @@ function HandleButtonEvent(words): void { GeneratePage(config.pages[pageId]); break; case 'bNext': - var pageNum = (((pageId + 1) % config.pages.length) + config.pages.length) % config.pages.length; + pageNum = (((pageId + 1) % config.pages.length) + config.pages.length) % config.pages.length; pageId = pageNum; UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case 'bPrev': - var pageNum = (((pageId - 1) % config.pages.length) + config.pages.length) % config.pages.length; + pageNum = (((pageId - 1) % config.pages.length) + config.pages.length) % config.pages.length; pageId = pageNum; UnsubscribeWatcher(); if (activePage != undefined && activePage.parent != undefined) { @@ -2511,7 +2563,9 @@ function HandleButtonEvent(words): void { GeneratePage(config.pages[pageId]); } } else { - if (Debug) console.log('bExit: ' + words[4] + ' - ' + pageId); + if (Debug) { + console.log('bExit: ' + words[4] + ' - ' + pageId); + } setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyHeading', ''); setIfExists(NSPanel_Path + 'ScreensaverInfo.popupNotifyText', ''); GeneratePage(activePage); @@ -2531,7 +2585,7 @@ function HandleButtonEvent(words): void { break; case 'OnOff': if (existsObject(id)) { - var action = false + let action = false if (words[4] == '1') action = true; let o = getObject(id); @@ -2555,7 +2609,7 @@ function HandleButtonEvent(words): void { break; case 'button': if (existsObject(id)) { - var action = false + let action = false if (words[4] == '1') action = true; let o = getObject(id); @@ -2607,7 +2661,7 @@ function HandleButtonEvent(words): void { break; case 'tiltClose': setIfExists(id + '.TILT_CLOSE', true); - break; + break; case 'tiltSlider': (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); timeoutSlider = setTimeout(async function () { @@ -2649,7 +2703,7 @@ function HandleButtonEvent(words): void { (function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })(); timeoutSlider = setTimeout(async function () { let pageItem = findPageItem(id); - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValueColorTemp, pageItem.maxValueColorTemp)); setIfExists(id + '.TEMPERATURE', (colorTempK)); } else { @@ -2660,8 +2714,12 @@ function HandleButtonEvent(words): void { case 'colorWheel': let colorCoordinates = words[4].split('|'); let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]); - if (Debug) console.log(rgb); - if (Debug) console.log(getHue(rgb.red, rgb.green, rgb.blue)); + if (Debug) { + console.log(rgb); + } + if (Debug) { + console.log(getHue(rgb.red, rgb.green, rgb.blue)); + } let o = getObject(id); switch (o.common.role) { case 'hue': @@ -2673,17 +2731,19 @@ function HandleButtonEvent(words): void { setIfExists(id + '.BLUE', rgb.blue); break; case 'rgbSingle': - let pageItem = findPageItem(id); + let pageItem = findPageItem(id); if (pageItem.colormode == "xy") { //Für z.B. Deconz XY setIfExists(id + ".RGB", rgb_to_cie(rgb.red, rgb.green, rgb.blue)); - if (Debug) console.log(rgb_to_cie(rgb.red, rgb.green, rgb.blue)); + if (Debug) { + console.log(rgb_to_cie(rgb.red, rgb.green, rgb.blue)); + } } else { //Für RGB - setIfExists(id + ".RGB", ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue)); + setIfExists(id + ".RGB", ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue)); } - break; + break; } break; case 'tempUpd': @@ -2692,7 +2752,7 @@ function HandleButtonEvent(words): void { case 'media-back': setIfExists(id + '.PREV', true); setTimeout(function(){ - GeneratePage(activePage); + GeneratePage(activePage); },3000) break; case 'media-pause': @@ -2715,13 +2775,13 @@ function HandleButtonEvent(words): void { } } setTimeout(function(){ - GeneratePage(activePage); + GeneratePage(activePage); },3000) break; case 'media-next': setIfExists(id + '.NEXT', true); setTimeout(function(){ - GeneratePage(activePage); + GeneratePage(activePage); },3000) break; case 'volumeSlider': @@ -2735,7 +2795,7 @@ function HandleButtonEvent(words): void { switch (deviceAdapter) { case 'spotify-premium': - var strDeviceID = spotifyGetDeviceID(words[4]); + let strDeviceID = spotifyGetDeviceID(words[4]); setState(adapterInstance + 'devices.' + strDeviceID + ".useForPlayback", true); break; case 'alexa2': @@ -2754,7 +2814,7 @@ function HandleButtonEvent(words): void { break; case 'chromecast': break; - } + } break; case 'media-OnOff': let pageItemTem = findPageItem(id); @@ -2780,19 +2840,19 @@ function HandleButtonEvent(words): void { switch (words[4]) { case 'BOOT': setIfExists(words[2] + '.' + 'BOOST', !getState(words[2] + '.' + 'BOOST').val) - break; + break; case 'PART': setIfExists(words[2] + '.' + 'PARTY', !getState(words[2] + '.' + 'PARTY').val) - break; + break; case 'AUTT': setIfExists(words[2] + '.' + 'AUTOMATIC', !getState(words[2] + '.' + 'AUTOMATIC').val) - break; + break; case 'MANT': setIfExists(words[2] + '.' + 'MANUAL', !getState(words[2] + '.' + 'MANUAL').val) - break; + break; case 'VACT': setIfExists(words[2] + '.' + 'VACATION', !getState(words[2] + '.' + 'VACATION').val) - break; + break; } let modes = ['BOOT', 'PART', 'AUTT', 'MANT', 'VACT'] let modesDP = ['BOOST', 'PARTY', 'AUTOMATIC', 'MANUAL', 'VACATION'] @@ -2803,7 +2863,7 @@ function HandleButtonEvent(words): void { } GeneratePage(config.pages[pageId]); } else { - var HVACMode = 0; + let HVACMode = 0; switch (words[4]) { case 'POWER': HVACMode = 0; @@ -2855,8 +2915,8 @@ function HandleButtonEvent(words): void { setIfExists(id + '.PANEL', NSPanel_Path); } setTimeout(function(){ - GeneratePage(activePage); - },250) + GeneratePage(activePage); + },250) break; case 'A2': // Alarm-Page Alarm 2 aktivieren if (words[4] != '') { @@ -2866,8 +2926,8 @@ function HandleButtonEvent(words): void { setIfExists(id + '.PANEL', NSPanel_Path); } setTimeout(function(){ - GeneratePage(activePage); - },250) + GeneratePage(activePage); + },250) break; case 'A3': // Alarm-Page Alarm 3 aktivieren if (words[4] != '') { @@ -2877,8 +2937,8 @@ function HandleButtonEvent(words): void { setIfExists(id + '.PANEL', NSPanel_Path); } setTimeout(function(){ - GeneratePage(activePage); - },250) + GeneratePage(activePage); + },250) break; case 'A4': // Alarm-Page Alarm 4 aktivieren if (words[4] != '') { @@ -2888,12 +2948,16 @@ function HandleButtonEvent(words): void { setIfExists(id + '.PANEL', NSPanel_Path); } setTimeout(function(){ - GeneratePage(activePage); - },250) + GeneratePage(activePage); + },250) break; case 'D1': // Alarm-Page Alarm Deaktivieren - if (Debug) console.log('D1: ' + getState(id + '.PIN').val); - if (Debug) console.log(words[4]); + if (Debug) { + console.log('D1: ' + getState(id + '.PIN').val); + } + if (Debug) { + console.log(words[4]); + } if (words[4] != '') { if (getState(id + '.PIN').val == words[4]) { setIfExists(id + '.PIN', '0000'); @@ -2906,7 +2970,7 @@ function HandleButtonEvent(words): void { } setIfExists(id + '.PANEL', NSPanel_Path); setTimeout(function(){ - GeneratePage(activePage); + GeneratePage(activePage); },500) } break; @@ -2915,13 +2979,15 @@ function HandleButtonEvent(words): void { } } catch (err) { console.log('function HandleButtonEvent: ' + err.message); - } + } } function GetNavigationString(pageId: number): string { try { - if (Debug) console.log(pageId); + if (Debug) { + console.log(pageId); + } if (activePage.subPage) return '1|0'; @@ -2940,19 +3006,19 @@ function GetNavigationString(pageId: number): string { } } catch (err) { console.log('function GetNavigationString: ' + err.message); - } + } } function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { try { - var out_msgs: Array = []; + let out_msgs: Array = []; let id = pageItem.id if (existsObject(id)) { - var o = getObject(id) - var val: (boolean | number) = 0; + let o = getObject(id) + let val: (boolean | number) = 0; let icon = Icons.GetIcon('lightbulb'); - var iconColor = rgb_dec565(config.defaultColor); + let iconColor = rgb_dec565(config.defaultColor); if (type == 'popupLight') { let switchVal = '0'; @@ -2977,16 +3043,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { out_msgs.push({ payload: 'entityUpdateDetail' + '~' // entityUpdateDetail - + id + '~' - + icon + '~' // iconId - + iconColor + '~' // iconColor - + switchVal + '~' // buttonState - + 'disable' + '~' // sliderBrightnessPos - + 'disable' + '~' // sliderColorTempPos - + 'disable' + '~' // colorMode - + '' + '~' // Color-Bezeichnung - + findLocale('lights', 'Temperature') + '~' // Temperature-Bezeichnung - + findLocale('lights', 'Brightness') + + id + '~' + + icon + '~' // iconId + + iconColor + '~' // iconColor + + switchVal + '~' // buttonState + + 'disable' + '~' // sliderBrightnessPos + + 'disable' + '~' // sliderColorTempPos + + 'disable' + '~' // colorMode + + '' + '~' // Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' // Temperature-Bezeichnung + + findLocale('lights', 'Brightness') }); // Brightness-Bezeichnung } @@ -3001,7 +3067,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } if (val === true) { - var iconColor = GetIconColor(pageItem, val, false); + let iconColor = GetIconColor(pageItem, val, false); switchVal = '1' } @@ -3026,16 +3092,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { out_msgs.push({ payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' - + icon + '~' //iconId - + iconColor + '~' //iconColor - + switchVal + '~' //buttonState - + brightness + '~' //sliderBrightnessPos - + 'disable' + '~' //sliderColorTempPos - + 'disable' + '~' //colorMod - + '' + '~' //Color-Bezeichnung - + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung - + findLocale('lights', 'Brightness') + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + 'disable' + '~' //sliderColorTempPos + + 'disable' + '~' //colorMod + + '' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') }); //Brightness-Bezeichnung console.log('light.' + id) @@ -3068,7 +3134,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; if (existsState(id + '.HUE')) { if (getState(id + '.HUE').val != null) { colorMode = 'enable'; @@ -3079,10 +3145,10 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } } - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); } else { colorTemp = 100 - getState(id + '.TEMPERATURE').val; @@ -3095,16 +3161,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { out_msgs.push({ payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' - + icon + '~' //iconId - + iconColor + '~' //iconColor - + switchVal + '~' //buttonState - + brightness + '~' //sliderBrightnessPos - + colorTemp + '~' //sliderColorTempPos - + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) - + 'Color' + '~' //Color-Bezeichnung - + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung - + findLocale('lights', 'Brightness') + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') }); //Brightness-Bezeichnung } @@ -3134,7 +3200,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; if (existsState(id + '.RED') && existsState(id + '.GREEN') && existsState(id + '.BLUE')) { if (getState(id + '.RED').val != null && getState(id + '.GREEN').val != null && getState(id + '.BLUE').val != null) { colorMode = 'enable'; @@ -3144,7 +3210,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } } - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { @@ -3160,16 +3226,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { out_msgs.push({ payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' - + icon + '~' //iconId - + iconColor + '~' //iconColor - + switchVal + '~' //buttonState - + brightness + '~' //sliderBrightnessPos - + colorTemp + '~' //sliderColorTempPos - + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) - + 'Color' + '~' //Color-Bezeichnung - + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung - + findLocale('lights', 'Brightness') + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') }); //Brightness-Bezeichnung } @@ -3199,24 +3265,24 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; if (existsState(id + '.RGB')) { if (getState(id + '.RGB').val != null) { colorMode = 'enable'; - var hex = getState(id + '.RGB').val; - var hexRed = parseInt(hex[1] + hex[2], 16); - var hexGreen = parseInt(hex[3] + hex[4], 16); - var hexBlue = parseInt(hex[5] + hex[6], 16); + let hex = getState(id + '.RGB').val; + let hexRed = parseInt(hex[1] + hex[2], 16); + let hexGreen = parseInt(hex[3] + hex[4], 16); + let hexBlue = parseInt(hex[5] + hex[6], 16); let rgb = { red: Math.round(hexRed), green: Math.round(hexGreen), blue: Math.round(hexBlue) } iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? rgb : config.defaultOnColor); //RegisterDetailEntityWatcher(id + '.HUE', pageItem, type); } } - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); } else { colorTemp = 100 - getState(id + '.TEMPERATURE').val; @@ -3229,16 +3295,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { out_msgs.push({ payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' - + icon + '~' //iconId - + iconColor + '~' //iconColor - + switchVal + '~' //buttonState - + brightness + '~' //sliderBrightnessPos - + colorTemp + '~' //sliderColorTempPos - + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) - + 'Color' + '~' //Color-Bezeichnung - + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung - + findLocale('lights', 'Brightness') + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') }); //Brightness-Bezeichnung } @@ -3268,12 +3334,12 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { iconColor = GetIconColor(pageItem, false, true); } - var colorMode = 'disable'; + let colorMode = 'disable'; - var colorTemp = 0; + let colorTemp = 0; if (existsState(id + '.TEMPERATURE')) { if (getState(id + '.TEMPERATURE').val != null) { - if (pageItem.minValueColorTemp !== undefined && pageItem.minValueColorTemp !== undefined) { + if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) { colorTemp = Math.trunc(scale(getState(id + '.TEMPERATURE').val, pageItem.minValueColorTemp, pageItem.maxValueColorTemp, 0, 100)); } else { colorTemp = 100 - getState(id + '.TEMPERATURE').val; @@ -3286,16 +3352,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { out_msgs.push({ payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' - + icon + '~' //iconId - + iconColor + '~' //iconColor - + switchVal + '~' //buttonState - + brightness + '~' //sliderBrightnessPos - + colorTemp + '~' //sliderColorTempPos - + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) - + 'Color' + '~' //Color-Bezeichnung - + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung - + findLocale('lights', 'Brightness') + + id + '~' + + icon + '~' //iconId + + iconColor + '~' //iconColor + + switchVal + '~' //buttonState + + brightness + '~' //sliderBrightnessPos + + colorTemp + '~' //sliderColorTempPos + + colorMode + '~' //colorMode (if hue-alias without hue-datapoint, then disable) + + 'Color' + '~' //Color-Bezeichnung + + findLocale('lights', 'Temperature') + '~' //Temperature-Bezeichnung + + findLocale('lights', 'Brightness') }); //Brightness-Bezeichnung } } @@ -3309,7 +3375,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { val = getState(id + '.SET').val; RegisterDetailEntityWatcher(id + '.SET', pageItem, type); } - var tilt_position: any = 'disabled' + let tilt_position: any = 'disabled' if (existsState(id + '.TILT_ACTUAL')) { tilt_position = getState(id + '.TILT_ACTUAL').val; RegisterDetailEntityWatcher(id + '.TILT_ACTUAL', pageItem, type); @@ -3319,7 +3385,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } let textSecondRow = ''; - let icon_id = icon; + let icon_id = icon; let icon_up = Icons.GetIcon('arrow-up'); let icon_stop = Icons.GetIcon('stop'); let icon_down = Icons.GetIcon('arrow-down'); @@ -3352,25 +3418,25 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { out_msgs.push({ payload: 'entityUpdateDetail' + '~' //entityUpdateDetail - + id + '~' //entity_id - + val + '~' //Shutterposition - + textSecondRow + '~' //pos_status 2.line - + findLocale('blinds', 'Position') + '~' //pos_translation - + icon_id + '~' //{icon_id}~ - + icon_up + '~' //{icon_up}~ - + icon_stop + '~' //{icon_stop}~ - + icon_down + '~' //{icon_down}~ - + icon_up_status + '~' //{icon_up_status}~ - + icon_stop_status + '~' //{icon_stop_status}~ - + icon_down_status + '~' //{icon_down_status}~ - + textTilt + '~' //{textTilt}~ - + iconTiltLeft + '~' //{iconTiltLeft}~ - + iconTiltStop + '~' //{iconTiltStop}~ - + iconTiltRight + '~' //{iconTiltRight}~ - + iconTiltLeftStatus + '~' //{iconTiltLeftStatus}~ - + iconTiltStopStatus + '~' //{iconTiltStopStatus}~ - + iconTiltRightStatus + '~' //{iconTiltRightStatus}~ - + tilt_pos //{tilt_pos}") + + id + '~' //entity_id + + val + '~' //Shutterposition + + textSecondRow + '~' //pos_status 2.line + + findLocale('blinds', 'Position') + '~' //pos_translation + + icon_id + '~' //{icon_id}~ + + icon_up + '~' //{icon_up}~ + + icon_stop + '~' //{icon_stop}~ + + icon_down + '~' //{icon_down}~ + + icon_up_status + '~' //{icon_up_status}~ + + icon_stop_status + '~' //{icon_stop_status}~ + + icon_down_status + '~' //{icon_down_status}~ + + textTilt + '~' //{textTilt}~ + + iconTiltLeft + '~' //{iconTiltLeft}~ + + iconTiltStop + '~' //{iconTiltStop}~ + + iconTiltRight + '~' //{iconTiltRight}~ + + iconTiltLeftStatus + '~' //{iconTiltLeftStatus}~ + + iconTiltStopStatus + '~' //{iconTiltStopStatus}~ + + iconTiltRightStatus + '~' //{iconTiltRightStatus}~ + + tilt_pos //{tilt_pos}") }); } } @@ -3379,7 +3445,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } catch (err) { console.log('function GenerateDetailPage: ' + err.message); - } + } } function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number { @@ -3387,7 +3453,7 @@ function scale(number: number, inMin: number, inMax: number, outMin: number, out return (outMax + outMin) - ((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin); } catch (err) { console.log('function scale: ' + err.message); - } + } } function UnsubscribeWatcher(): void { @@ -3398,7 +3464,7 @@ function UnsubscribeWatcher(): void { } } catch (err) { console.log('function UnsubscribeWatcher: ' + err.message); - } + } } function HandleScreensaver(): void { @@ -3411,31 +3477,35 @@ function HandleScreensaver(): void { function HandleScreensaverUpdate(): void { try { if (screensaverEnabled && config.weatherEntity != null && existsObject(config.weatherEntity)) { - var icon = getState(config.weatherEntity + '.ICON').val; + let icon = getState(config.weatherEntity + '.ICON').val; let temperature = - existsState(config.weatherEntity + '.ACTUAL') ? getState(config.weatherEntity + '.ACTUAL').val : - existsState(config.weatherEntity + '.TEMP') ? getState(config.weatherEntity + '.TEMP').val : 'null'; + existsState(config.weatherEntity + '.ACTUAL') ? getState(config.weatherEntity + '.ACTUAL').val : + existsState(config.weatherEntity + '.TEMP') ? getState(config.weatherEntity + '.TEMP').val : 'null'; if (config.alternativeScreensaverLayout) { temperature = parseInt(Math.round(temperature).toFixed()); } let payloadString = - 'weatherUpdate~' + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + '~' - + temperature + ' ' + config.temperatureUnit + '~'; + 'weatherUpdate~' + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + '~' + + temperature + ' ' + config.temperatureUnit + '~'; vwIconColor[0] = GetAccuWeatherIconColor(parseInt(icon)); - if (Debug) console.log(GetAccuWeatherIconColor(parseInt(icon))); + if (Debug) { + console.log(GetAccuWeatherIconColor(parseInt(icon))); + } if (weatherForecast) { - // Accu-Weather Forecast Tag 2 - Tag 5 -- Wenn weatherForecast = true + // AccuWeather Forecast Tag 2 - Tag 5 -- Wenn weatherForecast = true for (let i = 2; i < 6; i++) { let TempMax = getState('accuweather.0.Summary.TempMax_d' + i).val; let DayOfWeek = getState('accuweather.0.Summary.DayOfWeek_d' + i).val; let WeatherIcon = GetAccuWeatherIcon(getState('accuweather.0.Summary.WeatherIcon_d' + i).val); vwIconColor[i-1] = GetAccuWeatherIconColor(getState('accuweather.0.Summary.WeatherIcon_d' + i).val); - if (Debug) console.log(vwIconColor[i-1]); + if (Debug) { + console.log(vwIconColor[i - 1]); + } payloadString += DayOfWeek + '~' + Icons.GetIcon(WeatherIcon) + '~' + TempMax + ' ' + config.temperatureUnit + '~'; } } else { @@ -3443,7 +3513,7 @@ function HandleScreensaverUpdate(): void { payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity); payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity); payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity); - + const colorScale0: RGB = { red: 99, green: 190, blue: 123 }; const colorScale1: RGB = { red: 129, green: 199, blue: 126 }; const colorScale2: RGB = { red: 161, green: 208, blue: 127 }; @@ -3472,15 +3542,17 @@ function HandleScreensaverUpdate(): void { valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } else { if (valueScale < iconvalbest) { - valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { - valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) } else { - valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } } - let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[1] = rgb_dec565(colorScale0); @@ -3505,7 +3577,7 @@ function HandleScreensaverUpdate(): void { break; case '7': vwIconColor[1] = rgb_dec565(colorScale7); - break; + break; case '8': vwIconColor[1] = rgb_dec565(colorScale8); break; @@ -3515,7 +3587,7 @@ function HandleScreensaverUpdate(): void { case '10': vwIconColor[1] = rgb_dec565(colorScale10); break; - } + } } if (config.firstScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { vwIconColor[1] = rgb_dec565(config.firstScreensaverEntity.ScreensaverEntityIconColor); @@ -3524,7 +3596,7 @@ function HandleScreensaverUpdate(): void { vwIconColor[1] = rgb_dec565(sctF1Icon); } } else { - vwIconColor[1] = rgb_dec565(sctF1Icon); + vwIconColor[1] = rgb_dec565(sctF1Icon); } if (config.secondScreensaverEntity.ScreensaverEntityIconColor != undefined) { @@ -3544,15 +3616,17 @@ function HandleScreensaverUpdate(): void { valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } else { if (valueScale < iconvalbest) { - valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { - valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) } else { - valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } } - let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[2] = rgb_dec565(colorScale0); @@ -3577,7 +3651,7 @@ function HandleScreensaverUpdate(): void { break; case '7': vwIconColor[2] = rgb_dec565(colorScale7); - break; + break; case '8': vwIconColor[2] = rgb_dec565(colorScale8); break; @@ -3587,16 +3661,16 @@ function HandleScreensaverUpdate(): void { case '10': vwIconColor[2] = rgb_dec565(colorScale10); break; - } + } } if (config.secondScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { vwIconColor[2] = rgb_dec565(config.secondScreensaverEntity.ScreensaverEntityIconColor); } } else { - vwIconColor[2] = rgb_dec565(sctF2Icon); + vwIconColor[2] = rgb_dec565(sctF2Icon); } } else { - vwIconColor[2] = rgb_dec565(sctF2Icon); + vwIconColor[2] = rgb_dec565(sctF2Icon); } if (config.thirdScreensaverEntity.ScreensaverEntityIconColor != undefined) { @@ -3616,15 +3690,17 @@ function HandleScreensaverUpdate(): void { valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } else { if (valueScale < iconvalbest) { - valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { - valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) } else { - valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } } - let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[3] = rgb_dec565(colorScale0); @@ -3649,7 +3725,7 @@ function HandleScreensaverUpdate(): void { break; case '7': vwIconColor[3] = rgb_dec565(colorScale7); - break; + break; case '8': vwIconColor[3] = rgb_dec565(colorScale8); break; @@ -3659,16 +3735,16 @@ function HandleScreensaverUpdate(): void { case '10': vwIconColor[3] = rgb_dec565(colorScale10); break; - } + } } if (config.thirdScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { vwIconColor[3] = rgb_dec565(config.thirdScreensaverEntity.ScreensaverEntityIconColor); } } else { - vwIconColor[3] = rgb_dec565(sctF2Icon); + vwIconColor[3] = rgb_dec565(sctF2Icon); } } else { - vwIconColor[3] = rgb_dec565(sctF2Icon); + vwIconColor[3] = rgb_dec565(sctF2Icon); } if (config.fourthScreensaverEntity.ScreensaverEntityIconColor != undefined) { @@ -3688,15 +3764,17 @@ function HandleScreensaverUpdate(): void { valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } else { if (valueScale < iconvalbest) { - valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) + valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10) } else if (valueScale > iconvalbest || iconvalbest != iconvalmin) { - valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0) } else { - valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) + valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0) } } - let valueScaletemp = (Math.round(valueScale)).toFixed(); - if (Debug) console.log(valueScaletemp); + let valueScaletemp = (Math.round(valueScale)).toFixed(); + if (Debug) { + console.log(valueScaletemp); + } switch (valueScaletemp) { case '0': vwIconColor[4] = rgb_dec565(colorScale0); @@ -3721,7 +3799,7 @@ function HandleScreensaverUpdate(): void { break; case '7': vwIconColor[4] = rgb_dec565(colorScale7); - break; + break; case '8': vwIconColor[4] = rgb_dec565(colorScale8); break; @@ -3731,42 +3809,42 @@ function HandleScreensaverUpdate(): void { case '10': vwIconColor[4] = rgb_dec565(colorScale10); break; - } + } } if (config.fourthScreensaverEntity.ScreensaverEntityIconColor.val_min == undefined) { vwIconColor[4] = rgb_dec565(config.fourthScreensaverEntity.ScreensaverEntityIconColor); } } else { - vwIconColor[4] = rgb_dec565(sctF2Icon); + vwIconColor[4] = rgb_dec565(sctF2Icon); } } else { - vwIconColor[4] = rgb_dec565(sctF2Icon); + vwIconColor[4] = rgb_dec565(sctF2Icon); } } //AltLayout if (config.alternativeScreensaverLayout) { - payloadString += parseInt(getState(config.fourthScreensaverEntity.ScreensaverEntity).val) + '~'; + payloadString += parseInt(getState(config.fourthScreensaverEntity.ScreensaverEntity).val) + '~'; payloadString += config.fourthScreensaverEntity.ScreensaverEntityUnitText + '~' } else { - payloadString += '~~' + payloadString += '~~' } - + let hwBtn1Col: any = config.mrIcon1ScreensaverEntity.ScreensaverEntityOffColor; if (config.mrIcon1ScreensaverEntity.ScreensaverEntity != null) { if (typeof (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) == 'string') { let hwBtn1: string = getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val; if (hwBtn1 == 'ON') { - hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor; + hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor; } payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn1Col) + '~'; } else if (typeof (getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val) == 'boolean') { let hwBtn1: boolean = getState(config.mrIcon1ScreensaverEntity.ScreensaverEntity).val; if (hwBtn1) { - hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor; + hwBtn1Col = config.mrIcon1ScreensaverEntity.ScreensaverEntityOnColor; } payloadString += Icons.GetIcon(config.mrIcon1ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn1Col) + '~'; - } + } } else { hwBtn1Col = Black; payloadString += '~~'; @@ -3777,28 +3855,28 @@ function HandleScreensaverUpdate(): void { if (typeof (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) == 'string') { let hwBtn2: string = getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val; if (hwBtn2 == 'ON') { - hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor; + hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor; } payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn2Col) + '~'; } else if (typeof (getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val) == 'boolean') { let hwBtn2: boolean = getState(config.mrIcon2ScreensaverEntity.ScreensaverEntity).val; if (hwBtn2) { - hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor; + hwBtn2Col = config.mrIcon2ScreensaverEntity.ScreensaverEntityOnColor; } payloadString += Icons.GetIcon(config.mrIcon2ScreensaverEntity.ScreensaverEntityIcon) + '~' + rgb_dec565(hwBtn2Col) + '~'; - } + } } else { hwBtn2Col = Black; payloadString += '~~'; } HandleScreensaverColors(); - + SendToPanel({ payload: payloadString }); - + } } catch (err) { console.log('HandleScreensaverUpdate: ' + err.message); - } + } } function HandleScreensaverColors(): void { @@ -3822,34 +3900,34 @@ function HandleScreensaverColors(): void { vwIcon[1] = vwIconColor[1]; vwIcon[2] = vwIconColor[2]; vwIcon[3] = vwIconColor[3]; - vwIcon[4] = vwIconColor[4]; + vwIcon[4] = vwIconColor[4]; } } let payloadString = 'color' + '~' + - rgb_dec565(scbackground) + '~' + //background - rgb_dec565(sctime) + '~' + //time - rgb_dec565(sctimeAMPM) + '~' + //timeAMPM~ - rgb_dec565(scdate) + '~' + //date~ - vwIcon[0] + '~' + //tMainIcon~ rgb_dec565(sctMainIcon) - rgb_dec565(sctMainText) + '~' + //tMainText~ - rgb_dec565(sctForecast1) + '~' + //tForecast1~ - rgb_dec565(sctForecast2) + '~' + //tForecast2~ - rgb_dec565(sctForecast3) + '~' + //tForecast3~ - rgb_dec565(sctForecast4) + '~' + //tForecast4~ - vwIcon[1] + '~' + //tF1Icon~ rgb_dec565(sctF1Icon) - vwIcon[2] + '~' + //tF2Icon~ rgb_dec565(sctF2Icon) - vwIcon[3] + '~' + //tF3Icon~ rgb_dec565(sctF3Icon) - vwIcon[4] + '~' + //tF4Icon~ rgb_dec565(sctF4Icon) - rgb_dec565(sctForecast1Val) + '~' + //tForecast1Val~ - rgb_dec565(sctForecast2Val) + '~' + //tForecast2Val~ - rgb_dec565(sctForecast3Val) + '~' + //tForecast3Val~ - rgb_dec565(sctForecast4Val) + '~' + //tForecast4Val~ - rgb_dec565(scbar) + '~' + //bar~ - rgb_dec565(sctMainIconAlt) + '~' + //tMainIconAlt - rgb_dec565(sctMainTextAlt) + '~' + //tMainTextAlt - rgb_dec565(sctTimeAdd); - //true; + rgb_dec565(scbackground) + '~' + //background + rgb_dec565(sctime) + '~' + //time + rgb_dec565(sctimeAMPM) + '~' + //timeAMPM~ + rgb_dec565(scdate) + '~' + //date~ + vwIcon[0] + '~' + //tMainIcon~ rgb_dec565(sctMainIcon) + rgb_dec565(sctMainText) + '~' + //tMainText~ + rgb_dec565(sctForecast1) + '~' + //tForecast1~ + rgb_dec565(sctForecast2) + '~' + //tForecast2~ + rgb_dec565(sctForecast3) + '~' + //tForecast3~ + rgb_dec565(sctForecast4) + '~' + //tForecast4~ + vwIcon[1] + '~' + //tF1Icon~ rgb_dec565(sctF1Icon) + vwIcon[2] + '~' + //tF2Icon~ rgb_dec565(sctF2Icon) + vwIcon[3] + '~' + //tF3Icon~ rgb_dec565(sctF3Icon) + vwIcon[4] + '~' + //tF4Icon~ rgb_dec565(sctF4Icon) + rgb_dec565(sctForecast1Val) + '~' + //tForecast1Val~ + rgb_dec565(sctForecast2Val) + '~' + //tForecast2Val~ + rgb_dec565(sctForecast3Val) + '~' + //tForecast3Val~ + rgb_dec565(sctForecast4Val) + '~' + //tForecast4Val~ + rgb_dec565(scbar) + '~' + //bar~ + rgb_dec565(sctMainIconAlt) + '~' + //tMainIconAlt + rgb_dec565(sctMainTextAlt) + '~' + //tMainTextAlt + rgb_dec565(sctTimeAdd); + //true; SendToPanel({ payload: payloadString }); } catch (err) { @@ -3957,7 +4035,7 @@ function GetAccuWeatherIconColor(icon: number): number { case 24: // Ice case 30: // Hot case 31: // Cold - return rgb_dec565(swExceptional); // exceptional + return rgb_dec565(swExceptional); // exceptional case 7: // Cloudy case 8: // Dreary (Overcast) @@ -4000,7 +4078,7 @@ function GetAccuWeatherIconColor(icon: number): number { case 26: // Freezing Rain case 39: // Partly Cloudy w/ Showers case 40: // Mostly Cloudy w/ Showers - return rgb_dec565(swRainy); // rainy + return rgb_dec565(swRainy); // rainy case 19: // Flurries case 20: // Mostly Cloudy w/ Flurries @@ -4009,7 +4087,7 @@ function GetAccuWeatherIconColor(icon: number): number { case 23: // Mostly Cloudy w/ Snow case 43: // Mostly Cloudy w/ Flurries case 44: // Mostly Cloudy w/ Snow - return rgb_dec565(swSnowy); // snowy + return rgb_dec565(swSnowy); // snowy case 29: // Rain and Snow return rgb_dec565(swSnowyRainy); // snowy-rainy @@ -4059,9 +4137,9 @@ function GetBlendedColor(percentage: number): RGB { } function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { - var r: number = InterpolateNum(color1.red, color2.red, fraction); - var g: number = InterpolateNum(color1.green, color2.green, fraction); - var b: number = InterpolateNum(color1.blue, color2.blue, fraction); + 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) }; } @@ -4083,7 +4161,7 @@ function rad2deg(rad) { } function ColorToHex(color) { - var hexadecimal = color.toString(16); + let hexadecimal = color.toString(16); return hexadecimal.length == 1 ? '0' + hexadecimal : hexadecimal; } @@ -4102,25 +4180,25 @@ function hsv2rgb(hue: number, saturation: number, value: number) { let chroma = value * saturation; let x = chroma * (1 - Math.abs((hue % 2) - 1)); let rgb = hue <= 1 ? [chroma, x, 0] : - hue <= 2 ? [x, chroma, 0] : - hue <= 3 ? [0, chroma, x] : - hue <= 4 ? [0, x, chroma] : - hue <= 5 ? [x, 0, chroma] : - [chroma, 0, x]; + hue <= 2 ? [x, chroma, 0] : + hue <= 3 ? [0, chroma, x] : + hue <= 4 ? [0, x, chroma] : + hue <= 5 ? [x, 0, chroma] : + [chroma, 0, x]; return rgb.map(v => (v + value - chroma) * 255); } function getHue(red: number, green: number, blue: number) { - var min = Math.min(Math.min(red, green), blue); - var max = Math.max(Math.max(red, green), blue); + let min = Math.min(Math.min(red, green), blue); + let max = Math.max(Math.max(red, green), blue); if (min == max) { return 0; } - var hue = 0; + let hue = 0; if (max == red) { hue = (green - blue) / (max - min); @@ -4138,9 +4216,9 @@ function getHue(red: number, green: number, blue: number) { } function pos_to_color(x: number, y: number): RGB { - var r = 160 / 2; - var x = Math.round((x - r) / r * 100) / 100; - var y = Math.round((r - y) / r * 100) / 100; + let r = 160 / 2; + x = Math.round((x - r) / r * 100) / 100; + y = Math.round((r - y) / r * 100) / 100; r = Math.sqrt(x * x + y * y); let sat = 0 @@ -4150,39 +4228,39 @@ function pos_to_color(x: number, y: number): RGB { sat = r; } - var hsv = rad2deg(Math.atan2(y, x)); - var rgb = hsv2rgb(hsv, sat, 1); + let hsv = rad2deg(Math.atan2(y, x)); + let rgb = hsv2rgb(hsv, sat, 1); return { red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) }; } function rgb_to_cie(red, green, blue) { - //Apply a gamma correction to the RGB values, which makes the color more vivid and more the like the color displayed on the screen of your device - let vred = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); - let vgreen = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); - let vblue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); - - //RGB values to XYZ using the Wide RGB D65 conversion formula - let X = vred * 0.664511 + vgreen * 0.154324 + vblue * 0.162028; - let Y = vred * 0.283881 + vgreen * 0.668433 + vblue * 0.047685; - let Z = vred * 0.000088 + vgreen * 0.072310 + vblue * 0.986039; - - //Calculate the xy values from the XYZ values - let ciex = (X / (X + Y + Z)).toFixed(4); - let ciey = (Y / (X + Y + Z)).toFixed(4); - let cie = "[" + ciex + "," + ciey + "]" - - return cie; + //Apply a gamma correction to the RGB values, which makes the color more vivid and more the like the color displayed on the screen of your device + let vred = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); + let vgreen = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); + let vblue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); + + //RGB values to XYZ using the Wide RGB D65 conversion formula + let X = vred * 0.664511 + vgreen * 0.154324 + vblue * 0.162028; + let Y = vred * 0.283881 + vgreen * 0.668433 + vblue * 0.047685; + let Z = vred * 0.000088 + vgreen * 0.072310 + vblue * 0.986039; + + //Calculate the xy values from the XYZ values + let ciex = (X / (X + Y + Z)).toFixed(4); + let ciey = (Y / (X + Y + Z)).toFixed(4); + let cie = "[" + ciex + "," + ciey + "]" + + return cie; } function spotifyGetDeviceID(vDeviceString) { const availableDeviceIDs = getState("spotify-premium.0.devices.availableDeviceListIds").val; const availableDeviceNames = getState("spotify-premium.0.devices.availableDeviceListString").val; - var arrayDeviceListIds = availableDeviceIDs.split(";"); - var arrayDeviceListSting = availableDeviceNames.split(";"); - var indexPos = arrayDeviceListSting.indexOf(vDeviceString); - var strDevID = arrayDeviceListIds[indexPos]; + let arrayDeviceListIds = availableDeviceIDs.split(";"); + let arrayDeviceListSting = availableDeviceNames.split(";"); + let indexPos = arrayDeviceListSting.indexOf(vDeviceString); + let strDevID = arrayDeviceListIds[indexPos]; return strDevID; } @@ -4208,37 +4286,37 @@ type Page = { interface PageEntities extends Page { type: 'cardEntities', items: PageItem[], -}; +} interface PageGrid extends Page { type: 'cardGrid', items: PageItem[], -}; +} interface PageThermo extends Page { type: 'cardThermo', items: PageItem[], -}; +} interface PageMedia extends Page { type: 'cardMedia', items: PageItem[], -}; +} interface PageAlarm extends Page { type: 'cardAlarm', items: PageItem[], -}; +} interface PageQR extends Page { type: 'cardQR', items: PageItem[], -}; +} interface PagePower extends Page { type: 'cardPower', items: PageItem[], -}; +} type PageItem = { id: string, @@ -4303,7 +4381,7 @@ type Config = { subPages: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower)[], button1Page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower | null), button2Page: (PageThermo | PageMedia | PageAlarm | PageQR | PageEntities | PageGrid | PagePower| null), -}; +} type ScreenSaverElement = { ScreensaverEntity: string | null,