diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts index 991037f1..55edb63e 100644 --- a/ioBroker/NsPanelTs.ts +++ b/ioBroker/NsPanelTs.ts @@ -1,109 +1,228 @@ /*----------------------------------------------------------------------- joBr99 Projekt: https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker +- abgestimmt auf TFT 34 / v2.8.2 (LATEST) / BerryDriver 4 / Tasmota 11.1.0 + 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) Mögliche Aliase: - Info - Werte aus Datenpunkt - 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 - Taste - Für Szenen oder Radiosender, etc. --> Nur Funktionsaufruf - Kein Taster wie MonoButton - True/False - ??? wahrscheinlich wäre Tastensensor besser geeignet, um Alias-Taste langfristig für einen MonoButton (Taster) zu verwenden ??? - Thermostat - Aktuelle Raumtemperatur, Setpoint, etc. - Feuchtigkeit - Anzeige von Humidity - Datenpunkten, ananlog Info - Medien - Steuerung von Alexa - Über Alias-Manager im Verzeichnis Player automatisch anlegen (Geräte-Manager funktioniert nicht) - Wetter - Aktuelle Außen-Temperatur und aktuelles Accu-Wheather-Icon für Screensaver + 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. + 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 + +Erforderliche Adapter: + Accu-Wheater: - Bei Nutzung der Wetterfunktionen im Screensaver + Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia + +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/lui-release.tft +TFT EU DEV Version : FlashNextion http://nspanel.pky.eu/lui.tft --------------------------------------------------------------------------------------- */ + var Icons = new IconsSelector(); -var timeoutSlider; +var timeoutSlider: any; +var NSPanel_Path = "0_userdata.0.NSPanel.1." +var Debug = false; const Months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]; const Days = ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]; -const Red: RGB = { red: 255, green: 0, blue: 0 }; -const White: RGB = { red: 255, green: 255, blue: 255 }; -const Yellow: RGB = { red: 253, green: 216, blue: 53 }; -const Green: RGB = { red: 96, green: 176, blue: 62 } -const Brown: RGB = { red: 120, green: 80, blue: 59 } -const Gray: RGB = { red: 69, green: 69, blue: 69 } -const Off: RGB = { red: 68, green: 115, blue: 158 }; +//const Off: RGB = { red: 68, green: 115, blue: 158 }; //Blau-Off +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 BatteryFull: RGB = { red: 96, green: 176, blue: 62 } -const BatteryEmpty: RGB = { red: 179, green: 45, blue: 25 } +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 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 }; +//----------------------Begin Dimmode +//Screensaver nachts auf dunkel ("brightnessNight: z.B. 2") oder aus ("brightnessNight:0") +if (existsState(NSPanel_Path + "NSPanel_Dimmode_brightnessDay") == false || existsState(NSPanel_Path + "NSPanel_Dimmode_hourDay") == false || existsState(NSPanel_Path + "NSPanel_Dimmode_brightnessNight") == false || existsState(NSPanel_Path + "NSPanel_Dimmode_hourNight") == false) { + createState(NSPanel_Path + "NSPanel_Dimmode_brightnessDay", 8, {type: 'number'}, function() {setState(NSPanel_Path + "NSPanel_Dimmode_brightnessDay", 8)}); + createState(NSPanel_Path + "NSPanel_Dimmode_hourDay", 7, {type: 'number'}, function() {setState(NSPanel_Path + "NSPanel_Dimmode_hourDay", 7)}); + createState(NSPanel_Path + "NSPanel_Dimmode_brightnessNight", 1, {type: 'number'}, function() {setState(NSPanel_Path + "NSPanel_Dimmode_brightnessNight", 1)}); + createState(NSPanel_Path + "NSPanel_Dimmode_hourNight", 22, {type: 'number'}, function() {setState(NSPanel_Path + "NSPanel_Dimmode_hourNight", 22)}); +} +var vBrightnessDay = getState(NSPanel_Path + "NSPanel_Dimmode_brightnessDay").val; +var vBrightnessNight = getState(NSPanel_Path + "NSPanel_Dimmode_brightnessNight").val; +var vTimeDay = getState(NSPanel_Path + "NSPanel_Dimmode_hourDay").val; +if (vTimeDay < 10) { + var TimeDay = "0" + vTimeDay.toString() + ":00"; +} else { + var TimeDay = vTimeDay.toString() + ":00"; +} +var vTimeNight = getState(NSPanel_Path + "NSPanel_Dimmode_hourNight").val; +if (vTimeNight < 10) { + var TimeNight = "0" + vTimeNight.toString() + ":00"; +} else { + var TimeNight = vTimeNight.toString() + ":00"; +} +var timeDimMode = {dimmodeOn: true, brightnessDay: vBrightnessDay, brightnessNight: vBrightnessNight, timeDay: TimeDay, timeNight: TimeNight}; +//--------------------End Dimmode -//----Ability to choose between Accu-Weather Forcast or self-defined values in the screensaver--------------------------------- +//----Möglichkeit, im Screensaver zwischen Accu-Weather Forecast oder selbstdefinierten Werten zu wählen--------------------------------- var weatherForecast = true; //true = WheatherForecast 5 Days --- false = Config --> firstScreensaverEntity - fourthScreensaverEntity ... -//Alexa2-Instanz +//Alexa-Instanz var alexaInstanz = "alexa2.0" -var alexaDevice = "G0XXXXXXXXXXXXXX"; //Primär zu steuendes Device -//If alexaSpeakerList is defined, then entries are used, otherwise all relevant devices from the ioBroker Alexa2 adapter -const alexaSpeakerList = []; //Example ["Echo Spot Buero","Überall","Gartenhaus","Esszimmer","Heimkino"]; +var alexaDevice = "G070RR1075220388"; //Primär zu steuerndes Device (Seriennummer) + +// Wenn alexaSpeakerList definiert, dann werden Einträge verwendet, sonst alle relevanten Devices aus Alexa-Instanz +// Speakerwechsel funktioniert nicht bei Radio/TuneIn sonden bei Playlists +//const alexaSpeakerList = []; //Beispiel ["Echo Spot Buero","Überall","Gartenhaus","Esszimmer","Heimkino"]; +const alexaSpeakerList = ["Echo Spot Buero","Überall","Gartenhaus","Esszimmer","Heimkino","Echo Dot Küche"]; //Datenpunkte für Nachricht an Screensaver -var popupNotifyHeading = "0_userdata.0.WzDisplay.popupNotifyHeading"; -var popupNotifyText = "0_userdata.0.WzDisplay.popupNotifyText"; +var popupNotifyHeading = NSPanel_Path + "popupNotifyHeading"; +var popupNotifyText = NSPanel_Path + "popupNotifyText"; + +var tasmotaOTAURL = "http://ota.tasmota.com/tasmota32/release/tasmota32-DE.bin" + +//cardAlarm - Konfiguration +// .... var Test_Licht: PageEntities = { "type": "cardEntities", "heading": "Color Aliase", "useColor": true, + "subPage": false, "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: 70, 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 Wohnen: PageEntities = +var Test_Funktionen: PageEntities = { "type": "cardEntities", - "heading": "Haus", + "heading": "Sonstige Aliase", "useColor": true, + "subPage": false, "items": [ - { id: "alias.0.Stern", name: "Sternsteckdose"}, - { id: "alias.0.Erker"}, - { id: "alias.0.Küche", interpolateColor: true }, - { id: "alias.0.Wand" } + { id: "alias.0.NSPanel_1.TestLautstärke", offColor: MSRed /*if mute=true*/, onColor: MSGreen ,name: "Echo Spot Büro", minValue: 0, maxValue: 100}, + { id: "alias.0.NSPanel_1.TestTemperatur",name: "Temperatur außen", icon: "thermometer", onColor: White}, + { id: "alias.0.NSPanel_1.TestFeuchtigkeit", name: "Luftfeuchte außen", icon: "water-percent", unit: "%H", onColor: White}, + { id: "alias.0.NSPanel_1.TestInfo", name: "Windstärke", icon: "wind-power-outline", offColor: MSRed, onColor: MSGreen, unit: "bft", minValue: 0, maxValue: 12, interpolateColor: true, useColor: true} ] }; -var Strom: PageEntities = +var Buero_Seite_1: PageEntities = { "type": "cardEntities", - "heading": "Strom", + "heading": "Büro", "useColor": true, + "subPage": false, "items": [ - { id: "alias.0.Netz", icon: "flash", interpolateColor: true, offColor: BatteryFull, onColor: Red, minValue: -1000, maxValue: 1000 }, - { id: "alias.0.Hausverbrauch", icon: "flash", interpolateColor: true, offColor: BatteryFull, onColor: Red, maxValue: 1000 }, - { id: "alias.0.Pv", icon: "solar-power", interpolateColor: true, offColor: Off, onColor: BatteryFull, maxValue: 1000 }, - { id: "alias.0.Batterie", icon: "battery-medium", interpolateColor: true, offColor: BatteryEmpty, onColor: BatteryFull } + { 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", offColor: MSRed, onColor: MSGreen} ] }; -var Müll: PageEntities = +var Fenster_1: PageEntities = { "type": "cardEntities", - "heading": "Müllkalender", + "heading": "Fenster und Türen", "useColor": true, + "subPage": false, "items": [ - { id: "alias.0.WzNsPanel.Müll.Bio_Tonne" ,unit:"Tage", icon: "trash-can",onColor: Brown}, - { id: "alias.0.WzNsPanel.Müll.Graue_Tonne" ,unit:"Tage",icon: "trash-can",onColor: Gray}, - { id: "alias.0.WzNsPanel.Müll.Grüne_Tonne" ,unit:"Tage",icon: "trash-can",onColor: Green}, - { id: "alias.0.WzNsPanel.Müll.Gelbe_Tonne" ,unit:"Tage",icon: "trash-can",onColor: Yellow} + { 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.TestDoorlock", offColor: MSRed, onColor: MSGreen, name: "Türschloss"}, + ] +}; + +var Button_1: PageEntities = +{ + "type": "cardEntities", + "heading": "Button Aliase", + "useColor": true, + "subPage": false, + "items": [ + { id: "alias.0.NSPanel_1.TestTastensensor", name: "Tastensensor (FFN)"}, + { id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "Taste (NDR2)", onColor: colorRadio}, + ] +}; + +var Subpages_1: PageEntities = +{ + "type": "cardEntities", + "heading": "Test Subpages", + "useColor": true, + "subPage": false, + "items": [ + { navigate: true, id: "Abfall", onColor: White, name: "Abfallkalender"}, + { navigate: true, id: "Buero_Seite_2", onColor: White, name: "Büro Card Grid"} + ] +}; + +//Subpage 1 von Subpages_1 +var Abfall: PageEntities = +{ + "type": "cardEntities", + "heading": "Abfallkalender", + "useColor": true, + "subPage": true, + "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 Buero_Seite_2: PageGrid = +{ + "type": "cardGrid", + "heading": "Büro 2", + "useColor": true, + "subPage": true, + "items": [ + { id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"}, + { 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.Radio.TuneIn", icon: "play", onColor: White} ] }; @@ -112,40 +231,121 @@ var Alexa: PageMedia = "type": "cardMedia", "heading": "Alexa", "useColor": true, + "subPage": false, "items": [{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }] }; +var Buero_Themostat: PageThermo = +{ + "type": "cardThermo", + "heading": "Thermostat", + "useColor": true, + "subPage": false, + "items": [{ id: "alias.0.NSPanel_1.Thermostat_Büro" }] +}; + +var Buero_Alarm: PageAlarm = +{ + "type": "cardAlarm", + "heading": "Alarm", + "useColor": true, + "subPage": false, + "items": [{ id: "alias.0.NSPanel_1.Alarm" }] +}; + var button1Page: PageGrid = { "type": "cardGrid", "heading": "Radio", "useColor": true, + "subPage": false, "items": [ - { id: "alias.0.Radio.NJoy" }, - { id: "alias.0.Radio.Delta_Radio" }, - { id: "alias.0.Radio.NDR2" }, + { id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio}, + { id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio}, + { id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio}, + { id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio}, + { id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify}, + { id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa} ] }; - var button2Page: PageEntities = { "type": "cardEntities", - "heading": "Knopf2", + "heading": "Büro", "useColor": true, + "subPage": false, "items": [ - { id: "alias.0.Schlafen" }, - { id: "alias.0.Stern" } + { id: "alias.0.NSPanel_1.Schreibtischlampe"}, + { id: "alias.0.NSPanel_1.Deckenbeleuchtung"} + ] +}; + +//Subpages 2 (+ Info) +var Service: PageEntities = +{ + "type": "cardEntities", + "heading": "NSPanel Service", + "useColor": true, + "subPage": false, + "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, + "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, + "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, + "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}, ] }; export const config: Config = { - panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT", - panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend", - firstScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.HUMIDITY", ScreensaverEntityIcon: "water-percent", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "%" }, - secondScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.PRECIPITATION_CHANCE", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" }, - thirdScreensaverEntity: { ScreensaverEntity: "alias.0.Batterie.ACTUAL", ScreensaverEntityIcon: "battery-medium", ScreensaverEntityText: "Batterie", ScreensaverEntityUnitText: "%" }, - fourthScreensaverEntity: { ScreensaverEntity: "alias.0.Pv.ACTUAL", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "PV", ScreensaverEntityUnitText: "W" }, + panelRecvTopic: "mqtt.0.SmartHome.NSPanel_1.tele.RESULT", //anpassen + panelSendTopic: "mqtt.0.SmartHome.NSPanel_1.cmnd.CustomSend", //anpassen + firstScreensaverEntity: { ScreensaverEntity: "hmip.0.devices.3014F711A000185BE9922BCF.channels.1.humidity", ScreensaverEntityIcon: "water-percent", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "%" }, + secondScreensaverEntity: { ScreensaverEntity: "accuweather.0.Daily.Day1.Day.PrecipitationProbability", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" }, + thirdScreensaverEntity: { ScreensaverEntity: "0_userdata.0.Wetter.Windstaerke_homaticIP", ScreensaverEntityIcon: "weather-windy", ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: "bft" }, + fourthScreensaverEntity: { ScreensaverEntity: "accuweather.0.Current.UVIndex", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "UV", ScreensaverEntityUnitText: "" }, timeoutScreensaver: 15, dimmode: 8, screenSaverDoubleClick: false, @@ -158,28 +358,35 @@ export const config: Config = { defaultColor: Off, temperatureUnit: "°C", pages: [ - //Test_Licht, - Wohnen, - Strom, - Müll, + Buero_Seite_1, + Button_1, + Test_Licht, + Test_Funktionen, + Fenster_1, + Subpages_1, Alexa, - { - "type": "cardThermo", - "heading": "Thermostat", - "useColor": true, - "items": [{ id: "alias.0.WzNsPanel", name: "Wohnzimmer" }] - } + Buero_Themostat, + Buero_Alarm, + Service ], button1Page: button1Page, button2Page: button2Page }; -// _________________________________ End configuration _____________________________________ +// _________________________________ Ab hier keine Konfiguration mehr _____________________________________ + +//Notification an Screensaver +on({id: [popupNotifyHeading, popupNotifyText], change: "ne"}, async function (obj) { + setState(config.panelSendTopic,(['notify~',getState(popupNotifyHeading).val,'~',getState(popupNotifyText).val].join(''))); +}); var subscriptions: any = {}; var screensaverEnabled : boolean = false; var pageId = 0; +//Neu für Subpages +var subPage_open = false; + schedule("* * * * *", function () { SendTime(); }); @@ -187,6 +394,197 @@ schedule("0 * * * *", function () { SendDate(); }); +//3:30 Uhr Startup durchführen und aktuelle TFT-Version empfangen +schedule({hour: 3, minute: 30}, function () { + setState(config.panelSendTopic, 'pageType~pageStartup'); +}); + +//Updates vergleichen aktuell alle 30 Minuten +schedule("*/30 * * * *", function () { + get_tasmota_status0(); + get_panel_update_data(); + check_updates(); +}); + +//Mit Start auf Updates checken +setState(config.panelSendTopic, 'pageType~pageStartup'); +get_tasmota_status0() +get_panel_update_data(); +check_updates(); + +//------------------Begin Update Functions +function 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) { + //Tasmota Upgrade durchführen + update_tasmota_firmware() + //Aktuelle Tasmota Version = Online Tasmota Version + setState(NSPanel_Path + "Tasmota_Firmware.currentVersion", getState(NSPanel_Path + "Tasmota_Firmware.onlineVersion").val); + } + } + } else { + if (Debug) console.log("Tasmota-Version auf NSPanel aktuell"); + } + } + //Tasmota-Berry-Driver-Vergleich + if (existsObject(NSPanel_Path + "Berry_Driver.currentVersion") && existsObject(NSPanel_Path + "Berry_Driver.onlineVersion")) { + if (getState(NSPanel_Path + "Berry_Driver.currentVersion").val !== getState(NSPanel_Path + "Berry_Driver.onlineVersion").val) { + 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 + setState(NSPanel_Path + "Berry_Driver.currentVersion", getState(NSPanel_Path + "Berry_Driver.onlineVersion").val); + } + } + } else { + if (Debug) console.log("Berry-Driver auf NSPanel aktuell"); + } + } + //TFT-Firmware-Vergleich + if (existsObject(NSPanel_Path + "Display_Firmware.currentVersion") && existsObject(NSPanel_Path + "Display_Firmware.onlineVersion")) { + if (getState(NSPanel_Path + "Display_Firmware.currentVersion").val !== getState(NSPanel_Path + "Display_Firmware.onlineVersion").val) { + 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 + setState(NSPanel_Path + "Display_Firmware.currentVersion", getState(NSPanel_Path + "Display_Firmware.onlineVersion").val); + } + } + } else { + if (Debug) console.log("Display_Firmware auf NSPanel aktuell"); + } + } +} + +function get_panel_update_data() { + createState(NSPanel_Path + "NSPanel_autoUpdate", false, {read: true, write: true, name: "Auto-Updater", type: "boolean", def: false}); + createState(NSPanel_Path + "NSPanel_ipAddress"); + setIfExists(NSPanel_Path + "NSPanel_ipAddress", get_current_tasmota_ip_address()); + get_online_tasmota_firmware_version(); + get_current_berry_driver_version(); + get_online_berry_driver_version(); + check_version_tft_firmware(); + check_online_display_firmware(); +} + +function get_current_tasmota_ip_address() { + let mqttInfo2 = config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 6) + "INFO2"; + let Tasmota_Info2 = JSON.parse(getState(mqttInfo2).val); + return Tasmota_Info2.Info2.IPAddress; +} + +function get_online_tasmota_firmware_version() { + exec('curl -X GET -k \'https://api.github.com/repositories/80286288/releases/latest\'', function (error, result, stderr){ //GitAPI aufruf für JSON Inhalt von Latest Tasmota Release + var Tasmota_JSON = JSON.parse(result) //JSON Resultat in Variable Schreiben + var TasmotaTagName = Tasmota_JSON.tag_name //JSON nach "tag_name" filtern und in Variable schreiben + var TasmotaVersionOnline = TasmotaTagName.replace(/v/i, ""); //Aus Variable überflüssiges "v" filtern und in Release-Variable schreiben + createState(NSPanel_Path + "Tasmota_Firmware.onlineVersion"); + setIfExists(NSPanel_Path + "Tasmota_Firmware.onlineVersion", TasmotaVersionOnline); + }); +} + +function get_current_berry_driver_version() { + require("request")((['http://',get_current_tasmota_ip_address(),'/cm?cmnd=GetDriverVersion'].join('')), async function (error, response, result) { + createState(NSPanel_Path + "Berry_Driver.currentVersion"); + setIfExists(NSPanel_Path + 'Berry_Driver.currentVersion', getAttr(result, 'nlui_driver_version')); + }); +} + +function get_tasmota_status0() { + require("request")((['http://',get_current_tasmota_ip_address(),'/cm?cmnd=Status0'].join('')), async function (error, response, result) { + createState(NSPanel_Path + "Tasmota_Firmware.currentVersion"); + createState(NSPanel_Path + "Tasmota.Uptime"); + createState(NSPanel_Path + "Tasmota.Version"); + createState(NSPanel_Path + "Tasmota.Hardware"); + createState(NSPanel_Path + "Tasmota.Wifi.AP"); + createState(NSPanel_Path + "Tasmota.Wifi.SSId"); + createState(NSPanel_Path + "Tasmota.Wifi.BSSId"); + createState(NSPanel_Path + "Tasmota.Wifi.Channel"); + createState(NSPanel_Path + "Tasmota.Wifi.Mode"); + createState(NSPanel_Path + "Tasmota.Wifi.RSSI"); + createState(NSPanel_Path + "Tasmota.Wifi.Signal"); + + var Tasmota_JSON = JSON.parse(result) + let tasmoVersion = Tasmota_JSON.StatusFWR.Version.split("("); + setIfExists(NSPanel_Path + "Tasmota_Firmware.currentVersion", tasmoVersion[0]); + setIfExists(NSPanel_Path + "Tasmota.Uptime", Tasmota_JSON.StatusPRM.Uptime); + setIfExists(NSPanel_Path + "Tasmota.Version", Tasmota_JSON.StatusFWR.Version); + setIfExists(NSPanel_Path + "Tasmota.Hardware", Tasmota_JSON.StatusFWR.Hardware); + setIfExists(NSPanel_Path + "Tasmota.Wifi.AP", Tasmota_JSON.StatusSTS.Wifi.AP); + setIfExists(NSPanel_Path + "Tasmota.Wifi.SSId", Tasmota_JSON.StatusSTS.Wifi.SSId); + setIfExists(NSPanel_Path + "Tasmota.Wifi.BSSId", Tasmota_JSON.StatusSTS.Wifi.BSSId); + setIfExists(NSPanel_Path + "Tasmota.Wifi.Channel", Tasmota_JSON.StatusSTS.Wifi.Channel); + setIfExists(NSPanel_Path + "Tasmota.Wifi.Mode", Tasmota_JSON.StatusSTS.Wifi.Mode); + setIfExists(NSPanel_Path + "Tasmota.Wifi.RSSI", Tasmota_JSON.StatusSTS.Wifi.RSSI); + setIfExists(NSPanel_Path + "Tasmota.Wifi.Signal", Tasmota_JSON.StatusSTS.Wifi.Signal); + }); +} + +function get_online_berry_driver_version() { + exec('curl https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be', function (error, result, stderr){ + if (result) { + let BerryDriverVersionOnline = result.substring((result.indexOf("version_of_this_script = ") + 24), result.indexOf("version_of_this_script = ") + 27).replace(/\s+/g, ''); + createState(NSPanel_Path + "Berry_Driver.onlineVersion"); + setIfExists(NSPanel_Path + 'Berry_Driver.onlineVersion', BerryDriverVersionOnline); + } + }); +} + +function check_version_tft_firmware() { + exec('curl -X GET -k \'https://api.github.com/repos/joBr99/nspanel-lovelace-ui/releases/latest\'', function (error, result, stderr){ //GitAPI aufruf für JSON Inhalt von Latest Tasmota Release + 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 + createState(NSPanel_Path + "TFT_Firmware.currentVersion"); + setIfExists(NSPanel_Path + 'TFT_Firmware.currentVersion', NSPanelVersion); + }); +} + +function check_online_display_firmware() { + exec('curl https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py', function (error, result, stderr){ + if (result) { + let desired_display_firmware_version = result.substring((result.indexOf("desired_display_firmware_version =") + 34), result.indexOf("desired_display_firmware_version =") + 38).replace(/\s+/g, ''); + createState(NSPanel_Path + "Display_Firmware.onlineVersion"); + setIfExists(NSPanel_Path + 'Display_Firmware.onlineVersion', desired_display_firmware_version); + } + }); +} + +on({ id: config.panelRecvTopic }, function (obj) { + if (obj.state.val.startsWith('\{"CustomRecv":')) { + var json = JSON.parse(obj.state.val); + var split = json.CustomRecv.split(","); + if (split[0] == "event" && split[1] == "startup") { + createState(NSPanel_Path + 'Display_Firmware.currentVersion',{ type:'string'}); + createState(NSPanel_Path + 'NSPanel_Version',{ type:'string'}); + setIfExists(NSPanel_Path + 'Display_Firmware.currentVersion',split[2]); + setIfExists(NSPanel_Path + 'NSPanel_Version',split[3]); + } + } +}); + +function update_berry_driver_version() { + require("request")((['http://',get_current_tasmota_ip_address(),'/cm?cmnd=Backlog UpdateDriverVersion https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; Restart 1'].join('')), async function (error, response, result) { + }); +} + +function update_tft_firmware() { + require("request")((['http://',get_current_tasmota_ip_address(),'/cm?cmnd=FlashNextion http://nspanel.pky.eu/lui.tft'].join('')), async function (error, response, result) { + }); +} + +function update_tasmota_firmware() { + require("request")((['http://',get_current_tasmota_ip_address(),'/cm?cmnd=Upgrade 1'].join('')), async function (error, response, result) { + }); +} + +//------------------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)) { @@ -201,12 +599,12 @@ if (config.thirdScreensaverEntity !== null && config.thirdScreensaverEntity.Scre if (config.fourthScreensaverEntity !== null && config.fourthScreensaverEntity.ScreensaverEntity != null && existsState(config.fourthScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.fourthScreensaverEntity.ScreensaverEntity) } - if (updateArray.length > 0) { on(updateArray, function () { HandleScreensaverUpdate(); }) } + on({ id: config.panelRecvTopic }, function (obj) { if (obj.state.val.startsWith('\{"CustomRecv":')) { var json = JSON.parse(obj.state.val); @@ -220,6 +618,7 @@ function SendToPanel(val: Payload | Payload[]): void { if (Array.isArray(val)) { val.forEach(function (id, i) { setState(config.panelSendTopic, id.payload); + if (Debug) console.log(id.payload); }); } else @@ -238,7 +637,7 @@ function HandleMessage(typ: string, method: string, page: number, words: Arraypage)); break; + case "cardAlarm": + SendToPanel(GenerateAlarmPage(page)); + break; } } function HandleHardwareButton(method: string): void { - let page: (PageThermo | PageMedia | PageEntities | PageGrid); + let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid); if (config.button1Page !== null && method == "button1") { page = config.button1Page; pageId = -1; @@ -324,6 +726,20 @@ function SendTime(): void { min = "0" + d.getMinutes().toString(); } SendToPanel({ payload: "time~" + hr + ":" + min }); + + ScreensaverDimmode(); +} + +function ScreensaverDimmode() { + if (timeDimMode.dimmodeOn != undefined ? timeDimMode.dimmodeOn : false) { + if (compareTime(timeDimMode.timeNight != undefined ? timeDimMode.timeNight : "23:00", timeDimMode.timeDay != undefined ? timeDimMode.timeDay : "06:00", "not between", null)) { + SendToPanel({ payload: "dimmode~" + timeDimMode.brightnessDay}); + } else { + SendToPanel({ payload: "dimmode~" + timeDimMode.brightnessNight}); + } + } else { + SendToPanel({ payload: "dimmode~" + config.dimmode }); + } } function GenerateEntitiesPage(page: PageEntities): Payload[] { @@ -346,6 +762,9 @@ function GeneratePageElements(page: Page): string { case "cardThermo": maxItems = 1; break; + case "cardAlarm": + maxItems = 1; + break; case "cardMedia": maxItems = 1; break; @@ -356,14 +775,26 @@ function GeneratePageElements(page: Page): string { maxItems = 6; break; } - let pageData = "entityUpd~" + page.heading + "~" + GetNavigationString(pageId) + + let pageData = "entityUpd~" + page.heading + "~" + GetNavigationString(pageId); + +//--------------------------------------Subpage---------------- + if (page.subPage) { + subPage_open = true; + pageData = "entityUpd~" + page.heading + "~" + "1|0"; + } +//--------------------------------------------------------- for (let index = 0; index < maxItems; index++) { if (page.items[index] !== undefined) { pageData += CreateEntity(page.items[index], index + 1, page.useColor); } +/* else { - pageData += CreateEntity({ id: "delete" }, index + 1); + pageData += CreateEntity({ id: "delete" }, index + 1); + //muss das wirklich? Wo erforderlich wird es mitgegeben! + } +*/ } return pageData; } @@ -375,11 +806,21 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = } var name: string; var type: string; + // ioBroker - if (existsObject(pageItem.id)) { + 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; - name = pageItem.name !== undefined ? pageItem.name : o.common.name.de if (existsState(pageItem.id + ".GET")) { val = getState(pageItem.id + ".GET").val; @@ -389,13 +830,15 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = val = getState(pageItem.id + ".SET").val; RegisterEntityWatcher(pageItem.id + ".SET"); } - var iconColor = rgb_dec565(config.defaultColor); + + name = pageItem.name !== undefined ? pageItem.name : o.common.name.de switch (o.common.role) { - case "socket": + 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"); + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == "socket" ? Icons.GetIcon("power-socket-de") : Icons.GetIcon("lightbulb"); var optVal = "0" if (val === true || val === "true") { @@ -406,7 +849,10 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; - +/*--------------------------------------------------------- + case "wled": + type = "number" +----------------------------------------------------------*/ case "hue": type = "light" @@ -428,7 +874,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = 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", pageItem, type); + //RegisterDetailEntityWatcher(id + ".HUE"); } } @@ -508,7 +954,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; - + case "dimmer": type = "light" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("lightbulb"); @@ -527,15 +973,15 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = } 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")) { @@ -552,12 +998,19 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = 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.door": + case "sensor.window": case "thermostat": @@ -584,18 +1037,92 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = 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"); - let buttonText = pageItem.name !== undefined ? pageItem.name : "PRESS"; iconColor = GetIconColor(pageItem, true, useColors); - return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + + iconColor + "~" + name + "~" + buttonText; + 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 = "UNLOCK" + } else { + iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("lock-open-variant"); + iconColor = GetIconColor(pageItem, false, useColors); + var lockState = "LOCK" + } + 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~~~~~" } @@ -616,7 +1143,7 @@ function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: )); } - if ((pageItem.useColor || useColors) && ((typeof (value) === "boolean" && value) || value > (pageItem.minValueBrightness !== undefined ? pageItem.minValueBrightness : 0) || value > (pageItem.minValue !== undefined ? pageItem.minValue : 0))) { + 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) } @@ -637,7 +1164,6 @@ function RegisterEntityWatcher(id: string): void { })) } - function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void { if (subscriptions.hasOwnProperty(id)) { return; @@ -683,15 +1209,15 @@ function GenerateThermoPage(page: PageThermo): Payload[] { let status = "" if (existsState(id + ".MODE")) status = getState(id + ".MODE").val; - let minTemp = 180 //Min Temp 5°C + let minTemp = 50 //Min Temp 5°C let maxTemp = 300 //Max Temp 30°C let stepTemp = 5 - //Dynamically add attributes if defined in alias + //Attribute hinzufügen, wenn im Alias definiert var thermButton = 0; let i_list = Array.prototype.slice.apply($('[state.id="' + id + '.*"]')); if ((i_list.length - 3) != 0) { - console.log(i_list.length -3) + if (Debug) console.log(i_list.length -3); if ((i_list.length -3)%2 == 0) { if ((i_list.length - 3) == 2) { thermButton = 6; @@ -715,92 +1241,94 @@ 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") { + 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~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("water-percent") + "~65504~1~" + "HUMIDITY" + "~"; } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) { - bt[i-1] = Icons.GetIcon("water-percent") + "~63488~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("water-percent") + "~63488~1~" + "HUMIDITY" + "~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) { - bt[i-1] = Icons.GetIcon("water-percent") + "~65504~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("water-percent") + "~65504~1~" + "HUMIDITY" + "~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) { - bt[i-1] = Icons.GetIcon("water-percent") + "~63488~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("water-percent") + "~63488~1~" + "HUMIDITY" + "~"; } } 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~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("battery-low") + "~63488~1~" + "LOWBAT" + "~"; } else { - bt[i-1] = Icons.GetIcon("battery-high") + "~2016~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("battery-high") + "~2016~1~" + "LOWBAT" + "~"; } } 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("fire") + "~60897~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("fire") + "~60897~1~" + "MAINTAIN" + "~"; } else { - bt[i-1] = Icons.GetIcon("fire") + "~33840~0~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("fire") + "~33840~0~" + "MAINTAIN" + "~"; } } 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~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("wifi-off") + "~63488~1~" + "UNREACH" + "~"; } else { - bt[i-1] = Icons.GetIcon("wifi") + "~2016~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("wifi") + "~2016~1~" + "UNREACH" + "~"; } } 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~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("power-standby") + "~2016~1~" + "POWER" + "~"; } else { - bt[i-1] = Icons.GetIcon("power-standby") + "~33840~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("power-standby") + "~33840~1~" + "POWER" + "~"; } } 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~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("alert-circle") + "~63488~1~" + "ERROR" + "~"; } else { - bt[i-1] = Icons.GetIcon("alert-circle") + "~33840~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("alert-circle") + "~33840~1~" + "ERROR" + "~"; } } 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~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("briefcase-check") + "~2016~1~" + "WORKING" + "~"; } else { - bt[i-1] = Icons.GetIcon("briefcase-check") + "~33840~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("briefcase-check") + "~33840~1~" + "WORKING" + "~"; } } else i--; break; case "BOOST": if (existsState(id + ".BOOST") && getState(id + ".BOOST").val != null) { if (getState(id + ".BOOST").val) { - bt[i-1] = Icons.GetIcon("fast-forward-60") + "~2016~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("fast-forward-60") + "~2016~1~" + "BOOST" + "~"; } else { - bt[i-1] = Icons.GetIcon("fast-forward-60") + "~33840~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("fast-forward-60") + "~33840~1~" + "BOOST" + "~"; } } else i--; break; case "PARTY": if (existsState(id + ".PARTY") && getState(id + ".PARTY").val != null) { if (getState(id + ".PARTY").val) { - bt[i-1] = Icons.GetIcon("party-popper") + "~2016~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("party-popper") + "~2016~1~" + "PARTY" + "~"; } else { - bt[i-1] = Icons.GetIcon("party-popper") + "~33840~1~bt" + (i-1) + "~"; + bt[i-1] = Icons.GetIcon("party-popper") + "~33840~1~" + "PARTY" + "~"; } } else i--; break; @@ -821,6 +1349,7 @@ function GenerateThermoPage(page: PageThermo): Payload[] { out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res}) } + if (Debug) console.log(out_msgs); return out_msgs } @@ -829,7 +1358,8 @@ function GenerateMediaPage(page: PageMedia): Payload[] { var out_msgs: Array = []; out_msgs.push({ payload: "pageType~cardMedia" }); if (existsObject(id)) { - let name = getState(id + ".ALBUM").val; + + let name = getState(id + ".ALBUM").val; let media_icon = Icons.GetIcon("playlist-music"); let title = getState(id + ".TITLE").val; let author = getState(id + ".ARTIST").val; @@ -843,7 +1373,6 @@ function GenerateMediaPage(page: PageMedia): Payload[] { iconplaypause = Icons.GetIcon("play"); //play } let currentSpeaker = getState(([alexaInstanz,'.Echo-Devices.',alexaDevice,'.Info.name'].join(''))).val; - //console.log(id); //------------------------------------------------------------------------------------------------------------- // nachfolgend alle Alexa-Devices (ist Online / Player- und Commands-Verzeichnis vorhanden) auflisten und verketten @@ -852,14 +1381,14 @@ function GenerateMediaPage(page: PageMedia): Payload[] { if (alexaSpeakerList.length > 0) { for (let i_index in alexaSpeakerList) { speakerlist = speakerlist + alexaSpeakerList[i_index] + "?"; - } + } } else { let i_list = Array.prototype.slice.apply($('[state.id="' + alexaInstanz + '.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(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.online'].join(''))).val && + if (getState(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.online'].join(''))).val && existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) && existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) { speakerlist = speakerlist + getState(i).val + "?"; @@ -868,19 +1397,91 @@ function GenerateMediaPage(page: PageMedia): Payload[] { } speakerlist = speakerlist.substring(0,speakerlist.length-1); //-------------------------------------------------------------------------------------------------------------- - out_msgs.push({ payload: "entityUpd~" + - name + "~" + - id + "~" + - id + "~" + //???? - media_icon + "~" + - title + "~" + - author + "~" + - volume + "~" + - iconplaypause + "~" + - currentSpeaker + "~" + - speakerlist + "~" + - onoffbutton}); + + 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 +} + +function GenerateAlarmPage(page: PageAlarm): Payload[] { + var id = page.items[0].id + var out_msgs: Array = []; + out_msgs.push({ payload: "pageType~cardAlarm" }); + + var armed: boolean = true; + + if (armed) { + var arm1 = "Deaktivieren"; //arm1*~* + var arm1ActionName = "D1"; //arm1ActionName*~* + var arm2 = ""; //arm2*~* + var arm2ActionName = ""; //arm2ActionName*~* + var arm3 = ""; //arm3*~* + var arm3ActionName = ""; //arm3ActionName*~* + var arm4 = ""; //arm4*~* + var arm4ActionName = ""; //arm4ActionName*~* + var icon = Icons.GetIcon("shield-home"); //icon*~* + var iconcolor = 63488; //iconcolor*~* + var numpadStatus = 1; //numpadStatus*~* + var flashing = "disable"; //flashing* + } + else { + var arm1 = "Alarm 1"; //arm1*~* + var arm1ActionName = "A1"; //arm1ActionName*~* + var arm2 = "Alarm 2"; //arm2*~* + var arm2ActionName = "A2"; //arm2ActionName*~* + var arm3 = "Alarm 3"; //arm3*~* + var arm3ActionName = "A3"; //arm3ActionName*~* + var arm4 = "Alarm 4"; //arm4*~* + var arm4ActionName = "A4"; //arm4ActionName*~* + var icon = Icons.GetIcon("shield-off"); //icon*~* + var iconcolor = 2016; //iconcolor*~* + var numpadStatus = 1; //numpadStatus*~* + var flashing = "disable"; //flashing* + } + + flashing = "disable" + var entityState = "arming" + if (entityState == "arming" || entityState == "pending") { + iconcolor = rgb_dec565({ red: 243, green: 179, blue: 0 }); + icon = Icons.GetIcon("shield"); + flashing = "enable" + } + if (entityState == "triggered") { + iconcolor = rgb_dec565({ red: 223, green: 76, blue: 30 }); + icon = Icons.GetIcon("bell-ring"); + flashing = "enable" + } + + 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*~* 39=Disarmed 35=Shield_Home, 40 + iconcolor + "~" + //iconcolor*~* 2016=green 63488=red + numpadStatus + "~" + //numpadStatus*~* + flashing}); //flashing* + + if (Debug) console.log(out_msgs); + return out_msgs } @@ -914,6 +1515,15 @@ function HandleButtonEvent(words): void { let id = words[2] let 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; + } + switch (buttonAction) { case "bNext": var pageNum = ((pageId + 1) % config.pages.length); @@ -926,22 +1536,31 @@ function HandleButtonEvent(words): void { pageId = Math.abs(pageNum); UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); + +//-------------Subpage + if (subPage_open) { + subPage_open = false; + HandleButtonEvent(['event','buttonPress2','cardEntities','bNext']) + } +//-------------------------------- break; case "bExit": if (config.screenSaverDoubleClick) { - if (words[4] == 2) + if (words[4] == 2) { GeneratePage(config.pages[pageId]); - } - else + } + } else { GeneratePage(config.pages[pageId]); + } break; case "OnOff": if (existsObject(id)) { var action = false if (words[4] == "1") - action = true + action = true; let o = getObject(id) switch (o.common.role) { + case "socket": case "light": setIfExists(id + ".SET", action); break; @@ -968,13 +1587,20 @@ function HandleButtonEvent(words): void { setIfExists(id + ".CLOSE", true) break; case "button": - toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET") + let obj = getObject(id); + switch (obj.common.role) { + case "lock": + case "button": + toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET"); + break; + case "buttonSensor": + toggleState(id + ".ACTUAL"); + } 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])); - //console.log("PositionSlider feuert"); }, 250); break; case "brightnessSlider": @@ -983,14 +1609,12 @@ function HandleButtonEvent(words): void { if (existsObject(id)) { let o = getObject(id); let pageItem = config.pages[pageId].items.find(e => e.id === id); - //console.log(o.common.role); 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])); setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4])); } break; @@ -1040,6 +1664,9 @@ function HandleButtonEvent(words): void { setIfExists(id + ".RGB", ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue)); } break; + case "tempUpd": + setIfExists(id + ".SET", parseInt(words[4]) / 10) + break; case "media-back": setIfExists(id + ".PREV", true) break; @@ -1048,7 +1675,7 @@ function HandleButtonEvent(words): void { setIfExists(id + ".PAUSE", true) } else { setIfExists(id + ".PLAY", true) - } + } break; case "media-next": setIfExists(id + ".NEXT", true) @@ -1071,13 +1698,34 @@ function HandleButtonEvent(words): void { case "media-OnOff": setIfExists(id + ".STOP", true) break; - case "tempUpd": - setIfExists(id + ".SET", parseInt(words[4]) / 10) + case "hvac_action": + if (words[4] == "POWER" || words[4] == "BOOST" || words[4] == "PARTY") { + setIfExists(words[2] + "." + words[4], !getState(words[2] + "." + words[4]).val) + } 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 + console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); + break; + case "A2": //Alarm-Page Alarm 2 aktivieren + console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); + break; + case "A3": //Alarm-Page Alarm 3 aktivieren + console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); + break; + case "A4": //Alarm-Page Alarm 4 aktivieren + console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); + break; + case "D1": //Alarm-Page Alarm Deaktivieren + console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); + break; default: break; } } + function GetNavigationString(pageId: number): string { switch (pageId) { case 0: @@ -1104,7 +1752,7 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { if (type == "popupLight") { let switchVal = "0" let brightness = 0; - if (o.common.role == "light") { + if (o.common.role == "light" || o.common.role == "socket") { if (existsState(id + ".GET")) { val = getState(id + ".GET").val; RegisterDetailEntityWatcher(id + ".GET", pageItem, type); @@ -1114,12 +1762,25 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { 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, false); + iconColor = GetIconColor(pageItem, true, true); + } else { + iconColor = GetIconColor(pageItem, false, true); } - out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" + "~Color~Temperature~Brightness" }) + out_msgs.push({ payload: "entityUpdateDetail" + "~" //entityUpdateDetail + + icon + "~" //iconId + + iconColor + "~" //iconColor + + switchVal + "~" //buttonState + + "disable" + "~" //sliderBrightnessPos + + "disable" + "~" //sliderColorTempPos + + "disable" + "~" //colorMode + + "Color" + "~" //Color-Bezeichnung + + "Temperature" + "~" //Temperature-Bezeichnung + + "Brightness" }) //Brightness-Bezeichnung } //Dimmer @@ -1156,12 +1817,20 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { } RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type); - - let colorTemp = "disable" - let colorMode = "disable" - out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode + "~Color~Temperature~Brightness" }) + out_msgs.push({ payload: "entityUpdateDetail" + "~" //entityUpdateDetail + + icon + "~" //iconId + + iconColor + "~" //iconColor + + switchVal + "~" //buttonState + + brightness + "~" //sliderBrightnessPos + + "disable" + "~" //sliderColorTempPos + + "disable" + "~" //colorMod + + "Color" + "~" //Color-Bezeichnung + + "Temperature" + "~" //Temperature-Bezeichnung + + "Brightness" }) //Brightness-Bezeichnung + } + //HUE-Licht if (o.common.role == "hue") { @@ -1213,7 +1882,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { console.warn("Alias-Datenpunkt: " + id + ".TEMPERATURE could not be read"); } - out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode + "~Color~Temperature~Brightness" }) + out_msgs.push({ payload: "entityUpdateDetail" + "~" //entityUpdateDetail + + icon + "~" //iconId + + iconColor + "~" //iconColor + + switchVal + "~" //buttonState + + brightness + "~" //sliderBrightnessPos + + colorTemp + "~" //sliderColorTempPos + + colorMode + "~" //colorMode (if hue-alias without hue-datapoint, then disable) + + "Color" + "~" //Color-Bezeichnung + + "Temperature" + "~" //Temperature-Bezeichnung + + "Brightness" }) //Brightness-Bezeichnung } //RGB-Licht @@ -1266,7 +1944,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { console.warn("Alias-Datenpunkt: " + id + ".TEMPERATURE could not be read"); } - out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode + "~Color~Temperature~Brightness" }) + out_msgs.push({ payload: "entityUpdateDetail" + "~" //entityUpdateDetail + + icon + "~" //iconId + + iconColor + "~" //iconColor + + switchVal + "~" //buttonState + + brightness + "~" //sliderBrightnessPos + + colorTemp + "~" //sliderColorTempPos + + colorMode + "~" //colorMode (if hue-alias without hue-datapoint, then disable) + + "Color" + "~" //Color-Bezeichnung + + "Temperature" + "~" //Temperature-Bezeichnung + + "Brightness" }) //Brightness-Bezeichnung } //RGB-Licht-einzeln (HEX) @@ -1323,7 +2010,16 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { console.warn("Alias-Datenpunkt: " + id + ".TEMPERATURE could not be read"); } - out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode + "~Color~Temperature~Brightness" }) + out_msgs.push({ payload: "entityUpdateDetail" + "~" //entityUpdateDetail + + icon + "~" //iconId + + iconColor + "~" //iconColor + + switchVal + "~" //buttonState + + brightness + "~" //sliderBrightnessPos + + colorTemp + "~" //sliderColorTempPos + + colorMode + "~" //colorMode (if hue-alias without hue-datapoint, then disable) + + "Color" + "~" //Color-Bezeichnung + + "Temperature" + "~" //Temperature-Bezeichnung + + "Brightness" }) //Brightness-Bezeichnung) } //Farbtemperatur @@ -1368,12 +2064,22 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { console.warn("Alias-Datenpunkt: " + id + ".TEMPERATURE could not be read"); } - out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode + "~Color~Temperature~Brightness" }) + out_msgs.push({ payload: "entityUpdateDetail" + "~" //entityUpdateDetail + + icon + "~" //iconId + + iconColor + "~" //iconColor + + switchVal + "~" //buttonState + + brightness + "~" //sliderBrightnessPos + + colorTemp + "~" //sliderColorTempPos + + colorMode + "~" //colorMode (if hue-alias without hue-datapoint, then disable) + + "Color" + "~" //Color-Bezeichnung + + "Temperature" + "~" //Temperature-Bezeichnung + + "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); @@ -1381,7 +2087,10 @@ function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { val = getState(id + ".SET").val; RegisterDetailEntityWatcher(id + ".SET", pageItem, type); } - out_msgs.push({ payload: "entityUpdateDetail~" + val + "~~Position" }) + out_msgs.push({ payload: "entityUpdateDetail" + "~" //entityUpdateDetail + + val + "~" //Shutterposition + + "" + "~" + + "Position"}) //Position-Bezeichnung } } return out_msgs @@ -1407,15 +2116,16 @@ function HandleScreensaver(): void { function HandleScreensaverUpdate(): void { if (screensaverEnabled && config.weatherEntity != null && existsObject(config.weatherEntity)) { var icon = getState(config.weatherEntity + ".ICON").val; - + let temperature: string = existsState(config.weatherEntity + ".ACTUAL") ? getState(config.weatherEntity + ".ACTUAL").val : existsState(config.weatherEntity + ".TEMP") ? getState(config.weatherEntity + ".TEMP").val : "null"; - + let payloadString = "weatherUpdate~" + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + "~" + temperature + " " + config.temperatureUnit + "~" - + +/*-------------------------------------------------------------------------------------------------------------------------------------*/ if (weatherForecast == true) { // Accu-Weather Forecast Tag 2 - Tag 5 -- Wenn weatherForecast = true for (let i = 2; i < 6; i++) { @@ -1432,7 +2142,7 @@ function HandleScreensaverUpdate(): void { payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity); payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity); } - +/*-------------------------------------------------------------------------------------------------------------------------------------*/ SendToPanel({ payload: payloadString }); } } @@ -1522,6 +2232,21 @@ function GetAccuWeatherIcon(icon: number): string { } } +//------------------Begin Read Internal Sensor Data +on({ id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 6) + "SENSOR" }, function (obj) { + let mqttSensor = config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 6) + "SENSOR"; + let Tasmota_Sensor = JSON.parse(getState(mqttSensor).val); + createState(NSPanel_Path + 'Sensor.Time'); + createState(NSPanel_Path + 'Sensor.TempUnit'); + createState(NSPanel_Path + 'Sensor.ANALOG.Temperature'); + createState(NSPanel_Path + 'Sensor.ESP32.Temperature'); + setIfExists(NSPanel_Path + 'Sensor.Time', Tasmota_Sensor.Time); + setIfExists(NSPanel_Path + 'Sensor.TempUnit', "°" + Tasmota_Sensor.TempUnit); + setIfExists(NSPanel_Path + 'Sensor.ANALOG.Temperature', Tasmota_Sensor.ANALOG.Temperature1); + setIfExists(NSPanel_Path + 'Sensor.ESP32.Temperature', Tasmota_Sensor.ESP32.Temperature); +}); +//------------------End Read Internal Sensor Data + function GetBlendedColor(percentage: number): RGB { if (percentage < 50) return Interpolate(config.defaultOffColor, config.defaultOnColor, percentage / 50.0); @@ -1543,6 +2268,10 @@ 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))); } +/* 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; } @@ -1556,6 +2285,12 @@ 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; @@ -1566,29 +2301,37 @@ function hsv2rgb(hue: number, saturation: number, value: number) { 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 { +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; @@ -1600,8 +2343,10 @@ function pos_to_color(x: number, y: number): RGB { } 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]) }; } @@ -1619,14 +2364,15 @@ type Page = { type: string, heading: string, items: PageItem[], - useColor: boolean + useColor: boolean, + subPage: boolean, }; interface PageEntities extends Page { type: "cardEntities", items: PageItem[], - }; + interface PageGrid extends Page { type: "cardGrid", items: PageItem[], @@ -1642,6 +2388,11 @@ interface PageMedia extends Page { items: PageItem[], }; +interface PageAlarm extends Page { + type: "cardAlarm", + items: PageItem[], +}; + type PageItem = { id: string, icon: (string | undefined), @@ -1656,7 +2407,17 @@ type PageItem = { minValue: (number | undefined), maxValue: (number | undefined), name: (string | undefined), - unit: (string | undefined) + buttonText: (string | undefined), + unit: (string | undefined), + navigate: (boolean | undefined), +} + +type DimMode = { + dimmodeOn: (boolean | undefined), + brightnessDay: (number | undefined), + brightnessNight: (number | undefined), + timeDay: (string | undefined), + timeNight: (string | undefined) } type Config = { @@ -1678,9 +2439,9 @@ type Config = { defaultColor: RGB, defaultOnColor: RGB, defaultOffColor: RGB, - pages: (PageThermo | PageMedia | PageEntities | PageGrid)[], - button1Page: (PageThermo | PageMedia | PageEntities | PageGrid | null), - button2Page: (PageThermo | PageMedia | PageEntities | PageGrid | null), + pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[], + button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), + button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), }; type ScreenSaverElement = {