Skip to content
  • Recent
  • Tags
  • 0 Unread 0
  • Categories
  • Unreplied
  • Popular
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Logo
  1. ioBroker Community Home
  2. Deutsch
  3. Hardware
  4. Sonoff NSPanel

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.1k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    1.8k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    15
    1
    2.1k

Sonoff NSPanel

Scheduled Pinned Locked Moved Hardware
1.5k Posts 78 Posters 636.6k Views 80 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Dexxter

    @armilar said in Sonoff NSPanel:

    @dexxter sagte in Sonoff NSPanel:

    @armilar
    Ich bin grade dran.
    Aktuell passiert es das der Brightnessslider nicht den eingestellten Wert behält.
    Also, ich schiebe den Slider auf 20%.....gehe dann da raus, wieder rein und der Slider steht auf 100%.
    Der Temperaturslider funktioniert wie er soll.
    EDIT: Das verält sich beim "normalen" Dimmer genau so.

    Ich denke, dass da ein ALIAS noch nicht den Datenpunkt erreicht hat. Habe diverse Lampen unterschiedlichster Art und habe das Verhalten nicht 🙄

    Moin @Armilar ,
    ich hab mir das grade noch mal mit frischem Kopf angeschaut.
    Lustigerweise hat der "normale" Dimmer dieses Verhalten heute nicht mehr aber der "hue".
    Jetzt habe ich mir mal den Code angeschaut und das hier gefunden :
    slider_LI.jpg
    Kann es sein das da der .ACTUAL Wert fehlt?
    Greetz Dexxter

    ArmilarA Offline
    ArmilarA Offline
    Armilar
    Most Active Forum Testing
    wrote on last edited by
    #356

    @dexxter habe die Antwort eben noch erweitert

    Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
    https://github.com/joBr99/nspanel-lovelace-ui/wiki

    Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

    D 1 Reply Last reply
    0
    • D Dexxter

      @armilar said in Sonoff NSPanel:

      @dexxter sagte in Sonoff NSPanel:

      @armilar
      Ich bin grade dran.
      Aktuell passiert es das der Brightnessslider nicht den eingestellten Wert behält.
      Also, ich schiebe den Slider auf 20%.....gehe dann da raus, wieder rein und der Slider steht auf 100%.
      Der Temperaturslider funktioniert wie er soll.
      EDIT: Das verält sich beim "normalen" Dimmer genau so.

      Ich denke, dass da ein ALIAS noch nicht den Datenpunkt erreicht hat. Habe diverse Lampen unterschiedlichster Art und habe das Verhalten nicht 🙄

      Moin @Armilar ,
      ich hab mir das grade noch mal mit frischem Kopf angeschaut.
      Lustigerweise hat der "normale" Dimmer dieses Verhalten heute nicht mehr aber der "hue".
      Jetzt habe ich mir mal den Code angeschaut und das hier gefunden :
      slider_LI.jpg
      Kann es sein das da der .ACTUAL Wert fehlt?
      Greetz Dexxter

      ArmilarA Offline
      ArmilarA Offline
      Armilar
      Most Active Forum Testing
      wrote on last edited by
      #357

      @dexxter kannst du aber schnell herausbekommen, wenn du an der Stelle den else-Zweig erweiterst:

                  let brightness = 0;
                  if (existsState(id + ".DIMMER")) {
                      brightness = Math.trunc(scale(getState(id + ".DIMMER").val, 0, 100, 0, 100));
                      RegisterDetailEntityWatcher(id + ".DIMMER", pageItem, type);
                  } else {
                      console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                  }
      

      Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
      https://github.com/joBr99/nspanel-lovelace-ui/wiki

      Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

      1 Reply Last reply
      0
      • J joBr99

        @Great-SUN
        wenn du unbedingt willst, nimm dir das HMI und pass es an, da das Panel keine Transparenz kann (und das ziel von dem projekt ist möglichst nah an dem dashboard von HomeAssistant zu sein) werd ich kein background image einbauen, aber grundsätzlich funktioniert das

        (die meisten icons sind keine bilder sondern text, da sollte es reichen sta auf crop image umzustellen) und bei den wenigen icons die bilder sind, muss du den hintergrund in das bild vom icon reinbasteln

        48834cf8-c8fa-45fa-8193-ad5c9978c688-image.png

        Great SUNG Offline
        Great SUNG Offline
        Great SUN
        wrote on last edited by
        #358

        @jobr99 @Armilar So, jetzt steh ich gerade wie der Ochs vorm Walde... Ich bin mir nicht sicher, ob ich jetzt einfach nur durch oder dumm bin, oder ob ich einfach falsch an die Sache heran gehe...

        Was ich möchte/erwarte:

        • NSPanel hat eine lokale Konfiguration für die Anzeige(n) und Widgets
        • Ich bekomme Änderungen per MQTT (HTTP(S) mit JSON geht auch) geschickt
        • Werte auf dem Display kann ich auch remote (per JSON load oder MQTT syncen)

        Was ich finde:

        • Eine Menge an Doku und Integrationen
        • Zusätzliche Services, die auch wieder irgendwo laufen und quasi als Sync-Server dienen
        • Adapter, die mit vorgefertigten Buttons, Screens etc. das Panel bestücken

        Jetzt die Frage: Kann ich das mit Deiner Firmware @joBr99 oder wo finde ich eine entsprechende Doku für andere Firmwares?
        Bislang kann hab ich in dem NSPanel mit der Orig-Firmware die Widgets im nspanel.be konfiguriert und das hat Änderungen per MQTT geschickt. Der Einfachheit halber habe ich meine Änderungen per NSPSend implementiert, um verschiedenste Anpassungen machen zu können.

        Beispiel:
        Im Wohnzimmer habe 8 Lampen hinter einem Dimmer, die einzeln, als Gruppe etc. schaltbar sind. Der Dimmer muss dafür aber immer einen Mindeststrom liefern, daher habe ich den Schalter vom Widget an die Gruppe für alle Lampen dran und den Slider an den Dimmer.

        Was kann ich jetzt wie mit einer anderen Firmware machen und... Könntet Ihr mir bitte entsprechende Links schicken?

        VIELEN VIELEN LIEBEN DANK !!!

        Great SUNG 1 Reply Last reply
        0
        • Great SUNG Great SUN

          @jobr99 @Armilar So, jetzt steh ich gerade wie der Ochs vorm Walde... Ich bin mir nicht sicher, ob ich jetzt einfach nur durch oder dumm bin, oder ob ich einfach falsch an die Sache heran gehe...

          Was ich möchte/erwarte:

          • NSPanel hat eine lokale Konfiguration für die Anzeige(n) und Widgets
          • Ich bekomme Änderungen per MQTT (HTTP(S) mit JSON geht auch) geschickt
          • Werte auf dem Display kann ich auch remote (per JSON load oder MQTT syncen)

          Was ich finde:

          • Eine Menge an Doku und Integrationen
          • Zusätzliche Services, die auch wieder irgendwo laufen und quasi als Sync-Server dienen
          • Adapter, die mit vorgefertigten Buttons, Screens etc. das Panel bestücken

          Jetzt die Frage: Kann ich das mit Deiner Firmware @joBr99 oder wo finde ich eine entsprechende Doku für andere Firmwares?
          Bislang kann hab ich in dem NSPanel mit der Orig-Firmware die Widgets im nspanel.be konfiguriert und das hat Änderungen per MQTT geschickt. Der Einfachheit halber habe ich meine Änderungen per NSPSend implementiert, um verschiedenste Anpassungen machen zu können.

          Beispiel:
          Im Wohnzimmer habe 8 Lampen hinter einem Dimmer, die einzeln, als Gruppe etc. schaltbar sind. Der Dimmer muss dafür aber immer einen Mindeststrom liefern, daher habe ich den Schalter vom Widget an die Gruppe für alle Lampen dran und den Slider an den Dimmer.

          Was kann ich jetzt wie mit einer anderen Firmware machen und... Könntet Ihr mir bitte entsprechende Links schicken?

          VIELEN VIELEN LIEBEN DANK !!!

          Great SUNG Offline
          Great SUNG Offline
          Great SUN
          wrote on last edited by Great SUN
          #359

          ups... falscher thread 🐶

          ArmilarA 1 Reply Last reply
          0
          • Great SUNG Great SUN

            ups... falscher thread 🐶

            ArmilarA Offline
            ArmilarA Offline
            Armilar
            Most Active Forum Testing
            wrote on last edited by
            #360

            @great-sun sagte in Sonoff NSPanel:

            ups... falscher thread 🐶

            Nee, diesmal nicht. Bezieht sich ja auf Sonoff Panel und nicht auf technisch Fragen zu adressierbaren Stripes 😉

            Zu deinen Erwartungen:

            • NSPanel hat eine lokale Konfiguration für die Anzeige(n) und Widgets
              In der nspanel.be von blakadder lassen sich die Widgets anlegen. Ist auch kein Problem, da diese statisch in der Original Sonoff Firmware sind und der Bezug zum Widget erhalten bleibt. Hier funktioniert das nicht - hier wird alles dynamisch aus dem TypeScript instanziert

            • Ich bekomme Änderungen per MQTT (HTTP(S) mit JSON geht auch) geschickt
              MQTT Payloads über CustomSend (ähnlich NSPSend, jedoch nicht "NSPSend") und Receive

            • Werte auf dem Display kann ich auch remote (per JSON load oder MQTT syncen)
              funktioniert auch hier Prima über MQTT, da die Datenpunkte getriggert werden

            Zu den restlichen Fragen, wo du etwas zu anderer Firmware wissen möchtest kann ich nichts sagen. Da müsstest du schon bei openHAB, etc. googlen, da es aktuell außer der Version von blakadder oder @joBr99 keine weitere ioBroker-Integrationen gibt und die openHAB's da mehr Content haben. Ist dann aber auch nicht JavaScript, sondern Python - was der Grund ist, weshalb wir den Aufwand betreiben. Wenn du etwas anderes findest, dann musst du die Logik natürlich noch bauen.

            Zum Beispiel:
            Warum sollte das nicht gehen? Wenn es jetzt unter dem Sonoff-Panel funktioniert - dann funktioniert das in der lovelace-ui auch. Sind ja "nur" Schalter und Dimmer.
            Was man mit lovelace-ui machen kann, steht hier im Thread. Wo es andere gibt und was die können - Kann ich nicht beantworten.

            VG
            Armilar

            Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
            https://github.com/joBr99/nspanel-lovelace-ui/wiki

            Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

            Great SUNG 1 Reply Last reply
            0
            • ArmilarA Armilar

              @dexxter habe die Antwort eben noch erweitert

              D Offline
              D Offline
              Dexxter
              wrote on last edited by
              #361

              @armilar said in Sonoff NSPanel:

              @dexxter habe die Antwort eben noch erweitert

              Hi @Armilar
              Ich habe eben mal wie Du empfohlen hast den Dimmwert händisch eingegeben und folgendes beobachten können.
              Der Slider wird tatsächlich doch aktualisiert aber genau falsch herum.
              Also wenn ich 5% von Hand eingebe springt der Slider auf 95%
              Bei 20% springt er auf 80% usw.
              Er gibt aber die richtigen Werte raus wenn ich ihn schiebe.
              Also, schiebe ich den Slider auf 20% werden diese auch eingestellt aber der Slider springt dann auf 80%.
              Kurz und knapp......Funktion ist da, Anzeige verkehrt herum.

              ArmilarA 1 Reply Last reply
              0
              • D Dexxter

                @armilar said in Sonoff NSPanel:

                @dexxter habe die Antwort eben noch erweitert

                Hi @Armilar
                Ich habe eben mal wie Du empfohlen hast den Dimmwert händisch eingegeben und folgendes beobachten können.
                Der Slider wird tatsächlich doch aktualisiert aber genau falsch herum.
                Also wenn ich 5% von Hand eingebe springt der Slider auf 95%
                Bei 20% springt er auf 80% usw.
                Er gibt aber die richtigen Werte raus wenn ich ihn schiebe.
                Also, schiebe ich den Slider auf 20% werden diese auch eingestellt aber der Slider springt dann auf 80%.
                Kurz und knapp......Funktion ist da, Anzeige verkehrt herum.

                ArmilarA Offline
                ArmilarA Offline
                Armilar
                Most Active Forum Testing
                wrote on last edited by Armilar
                #362

                @dexxter sagte in Sonoff NSPanel:

                @armilar said in Sonoff NSPanel:

                @dexxter habe die Antwort eben noch erweitert

                Hi @Armilar
                Ich habe eben mal wie Du empfohlen hast den Dimmwert händisch eingegeben und folgendes beobachten können.
                Der Slider wird tatsächlich doch aktualisiert aber genau falsch herum.
                Also wenn ich 5% von Hand eingebe springt der Slider auf 95%
                Bei 20% springt er auf 80% usw.
                Er gibt aber die richtigen Werte raus wenn ich ihn schiebe.
                Also, schiebe ich den Slider auf 20% werden diese auch eingestellt aber der Slider springt dann auf 80%.
                Kurz und knapp......Funktion ist da, Anzeige verkehrt herum.

                Hatte ich gestern auch 😉

                Hab noch Anpassungen gemacht. Dimmer lässt sich auch begrenzen: Beispiel hinterlegt mit 70% maxValue

                var Icons = new IconsSelector();
                
                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 Off: RGB = { red: 68, green: 115, blue: 158 };
                const On: RGB = { red: 253, green: 216, blue: 53 };
                const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                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 };
                
                
                //----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 ...
                
                //Alexa-Instanz
                var alexaInstanz = "alexa2.0"
                var alexaDevice = "G0XXXXXXXXXXXXXX"; //Primär zu steuendes Device
                
                // 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.NSPanel.1.popupNotifyHeading";
                var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                
                var Test_Licht: PageEntities =
                {
                    "type": "cardEntities",
                    "heading": "Büro",
                    "useColor": true,
                    "items": [
                        <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValue: 0, maxValue: 70},
                        <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Light-CT"},
                        <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Light-Color", minValue: 500, maxValue: 6500}
                    ]
                };
                
                var Buero_Seite_1: PageEntities =
                {
                    "type": "cardEntities",
                    "heading": "Büro",
                    "useColor": true,
                    "items": [
                        <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                    ]
                };
                
                var Fenster_1: PageEntities =
                {
                    "type": "cardEntities",
                    "heading": "Fenster und Türen",
                    "useColor": true,
                    "items": [
                        <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                        <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                    ]
                };
                
                var Abfall: PageEntities =
                {
                    "type": "cardEntities",
                    "heading": "Abfallkalender",
                    "useColor": true,
                    "items": [
                        <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                    ]
                };
                
                var Buero_Seite_2: PageGrid =
                {
                    "type": "cardGrid",
                    "heading": "Büro 2",
                    "useColor": true,
                    "items": [
                        <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                        <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                        <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                    ]
                };
                
                var Alexa: PageMedia = 
                {
                    "type": "cardMedia",
                    "heading": "Alexa",
                    "useColor": true,
                    "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                };
                
                var Buero_Themostat: PageThermo = 
                {
                    "type": "cardThermo",
                    "heading": "Thermostat",
                    "useColor": true,
                    "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                };
                
                var Buero_Alarm: PageAlarm = 
                {
                    "type": "cardAlarm",
                    "heading": "Alarm",
                    "useColor": true,
                    "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                };
                
                var button1Page: PageGrid =
                {
                    "type": "cardGrid",
                    "heading": "Radio",
                    "useColor": true,
                    "items": [
                        <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                        <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                        <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                        <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                        <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                        <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                    ]
                };
                
                var button2Page: PageEntities =
                {
                    "type": "cardEntities",
                    "heading": "Büro",
                    "useColor": true,
                    "items": [
                        <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                        <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                    ]
                };
                
                export const config: Config = {
                    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,
                    locale: "de_DE",
                    timeFormat: "%H:%M",
                    dateFormat: "%A, %d. %B %Y",
                    weatherEntity: "alias.0.Wetter.Wetter",
                    defaultOffColor: Off,
                    defaultOnColor: On,
                    defaultColor: Off,
                    temperatureUnit: "°C",
                    pages: [
                            Buero_Seite_1,
                            //Test_Licht,
                            Fenster_1,
                            Abfall,
                            //Buero_Seite_2,
                            Alexa,
                            Buero_Themostat,
                            Buero_Alarm
                    ],
                    button1Page: button1Page,
                    button2Page: button2Page
                };
                
                // _________________________________ 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;
                
                schedule("* * * * *", function () {
                    SendTime();
                });
                schedule("0 * * * *", function () {
                    SendDate();
                });
                
                
                // 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, function () {
                        HandleScreensaverUpdate();
                    })
                }
                on({ id: config.panelRecvTopic }, function (obj) {
                    if (obj.state.val.startsWith('\{"CustomRecv":')) {
                        var json = JSON.parse(obj.state.val);
                
                        var split = json.CustomRecv.split(",");
                        HandleMessage(split[0], split[1], parseInt(split[2]), split);
                    }
                });
                
                function SendToPanel(val: Payload | Payload[]): void {
                    if (Array.isArray(val)) {
                        val.forEach(function (id, i) {
                            setState(config.panelSendTopic, id.payload);
                        });
                    }
                    else
                        setState(config.panelSendTopic, val.payload);
                }
                
                function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                    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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                if (pageItem !== undefined)
                                    SendToPanel(GenerateDetailPage(words[2], pageItem));
                            case "buttonPress2":
                                screensaverEnabled = false;
                                HandleButtonEvent(words);
                                break;
                            case "button1":
                            case "button2":
                                screensaverEnabled = false;
                                HandleHardwareButton(method);
                            default:
                                break;
                        }
                    }
                }
                
                function GeneratePage(page: Page): void {
                    switch (page.type) {
                        case "cardEntities":
                            SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                            break;
                        case "cardThermo":
                            SendToPanel(GenerateThermoPage(<PageThermo>page));
                            break;
                        case "cardGrid":
                            SendToPanel(GenerateGridPage(<PageGrid>page));
                            break;
                        case "cardMedia":
                            SendToPanel(GenerateMediaPage(<PageMedia>page));
                            break;
                        case "cardAlarm":
                            SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                            break;
                    }
                }
                
                function HandleHardwareButton(method: string): void {
                    let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                    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);
                }
                
                function HandleStartupProcess(): void {
                    SendDate();
                    SendTime();
                    SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                    SendToPanel({ payload: "dimmode~" + config.dimmode });
                }
                
                function SendDate(): void {
                    var d = new Date();
                    var day = Days[d.getDay()];
                    var date = d.getDate();
                    var month = Months[d.getMonth()];
                    var year = d.getFullYear();
                    var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                    SendToPanel(<Payload>{ payload: _sendDate });
                }
                
                function SendTime(): void {
                    var d = new Date();
                    var hr = d.getHours().toString();
                    var min = d.getMinutes().toString();
                
                    if (d.getHours() < 10) {
                        hr = "0" + d.getHours().toString();
                    }
                    if (d.getMinutes() < 10) {
                        min = "0" + d.getMinutes().toString();
                    }
                    SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                }
                
                function GenerateEntitiesPage(page: PageEntities): Payload[] {
                    var out_msgs: Array<Payload> = [];
                    out_msgs = [{ payload: "pageType~cardEntities" }]
                    out_msgs.push({ payload: GeneratePageElements(page) });
                    return out_msgs
                }
                
                function GenerateGridPage(page: PageGrid): Payload[] {
                    var out_msgs: Array<Payload> = [];
                    out_msgs = [{ payload: "pageType~cardGrid" }]
                    out_msgs.push({ payload: GeneratePageElements(page) });
                    return out_msgs
                }
                
                function GeneratePageElements(page: Page): string {
                    let maxItems = 0;
                    switch (page.type) {
                        case "cardThermo":
                            maxItems = 1;
                            break;
                        case "cardAlarm":
                            maxItems = 1;
                            break;
                        case "cardMedia":
                            maxItems = 1;
                            break;
                        case "cardEntities":
                            maxItems = 4;
                            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);
                        }
                        else {
                            pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                        }
                    }
                    return pageData;
                }
                
                function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                    var iconId = "0"
                    if (pageItem.id == "delete") {
                        return "~delete~~~~~"
                    }
                    var name: string;
                    var type: string;
                
                    // ioBroker
                    if (existsObject(pageItem.id)) {
                        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;
                            RegisterEntityWatcher(pageItem.id + ".GET");
                        }
                        else if (existsState(pageItem.id + ".SET")) {
                            val = getState(pageItem.id + ".SET").val;
                            RegisterEntityWatcher(pageItem.id + ".SET");
                        }
                        var iconColor = rgb_dec565(config.defaultColor);
                
                        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 optVal = "0"
                
                                if (val === true || val === "true") {
                                    optVal = "1"
                                    iconColor = GetIconColor(pageItem, true, useColors);
                                } else {
                                    iconColor = GetIconColor(pageItem, false, useColors);
                                }
                
                                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 + ".ON") ? getState(pageItem.id + ".ON").val : true, useColors);
                                }
                
                                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") ? 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 = "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 = "closed"
                                    }
                                    RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                }
                                return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                
                            case "info":
                
                            case "humidity":
                
                            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 "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;
                
                            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~~~~~"
                }
                
                function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                    // dimmer
                    if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") {
                        let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100;
                        let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0;
                        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.minValue !== undefined ? pageItem.minValue : 0))) {
                        return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor)
                    }
                    
                    return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor);
                }
                
                function RegisterEntityWatcher(id: string): void {
                    if (subscriptions.hasOwnProperty(id)) {
                        return;
                    }
                    subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                        if(pageId >= 0)
                            SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                        if(pageId == -1 && config.button1Page != undefined)
                            SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                        if(pageId == -2 && config.button2Page != undefined)
                            SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                    }))
                }
                
                function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                    if (subscriptions.hasOwnProperty(id)) {
                        return;
                    }
                    subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                        SendToPanel(GenerateDetailPage(type, pageItem));
                    }))
                }
                
                function GetUnitOfMeasurement(id: string): string {
                    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 "";
                }
                
                function GenerateThermoPage(page: PageThermo): Payload[] {
                    var id = page.items[0].id
                    var out_msgs: Array<Payload> = [];
                    out_msgs.push({ payload: "pageType~cardThermo" });
                
                    // ioBroker
                    if (existsObject(id)) {
                        let o = getObject(id)
                        let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                        let currentTemp = 0;
                        if (existsState(id + ".ACTUAL"))
                            currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                
                        let destTemp = 0;
                        if (existsState(id + ".SET")) {
                            destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                        }
                
                        let status = ""
                        if (existsState(id + ".MODE"))
                            status = getState(id + ".MODE").val;
                        let minTemp = 50 //Min Temp 5°C
                        let maxTemp = 300 //Max Temp 30°C
                        let stepTemp = 5
                
                        //0-4 verwendet bei ungerader Anzahl Parametern
                        let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                        let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                        let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                        let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                        let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                        //5-8 verwendet bei gerader Anzahl Parametern
                        let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                        let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                        let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                        let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                
                        if (existsState(id + ".HUMIDITY")){
                            bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                            if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                            } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                            } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                            } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                            }
                        }
                
                        if (existsState(id + ".MAINTAIN")){
                            if (getState(id + ".MAINTAIN").val >> .1) {
                                bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                            } else {
                                bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                            }
                        }
                
                        if (existsState(id + ".UNREACH")){
                            if (getState(id + ".UNREACH").val) {
                                bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                            } else {
                                bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                            }
                        }
                
                        if (existsState(id + ".LOWBAT")){
                            if (getState(id + ".LOWBAT").val) {
                                bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                            } else {
                                bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                            }
                        }
                
                        let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                
                        out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                    }
                
                    return out_msgs
                }
                
                function GenerateMediaPage(page: PageMedia): Payload[] {
                    var id = page.items[0].id
                    var out_msgs: Array<Payload> = [];
                    out_msgs.push({ payload: "pageType~cardMedia" });
                    if (existsObject(id)) {
                
                        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;
                        let volume = getState(id + ".VOLUME").val;
                        var iconplaypause = Icons.GetIcon("pause"); //pause
                        var onoffbutton = 1374;
                        if (getState(id + ".STATE").val) {
                            onoffbutton = 65535;
                            iconplaypause = Icons.GetIcon("pause"); //pause
                        } else {
                            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
                // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                        let speakerlist = "";
                        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 && 
                                    existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                    existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                        speakerlist = speakerlist + getState(i).val + "?";
                                }
                            }
                        }
                        speakerlist = speakerlist.substring(0,speakerlist.length-1);
                //--------------------------------------------------------------------------------------------------------------
                
                        out_msgs.push({ payload: "entityUpd~" + 
                                                  name + "~" +
                                                  id + "~" +
                                                  id + "~" +         //????
                                                  media_icon + "~" +
                                                  title + "~" +
                                                  author + "~" +
                                                  volume + "~" +
                                                  iconplaypause + "~" +
                                                  currentSpeaker + "~" +
                                                  speakerlist + "~" +
                                                  onoffbutton});
                    }
                
                    return out_msgs
                }
                
                function GenerateAlarmPage(page: PageAlarm): Payload[] {
                    var id = page.items[0].id
                    var out_msgs: Array<Payload> = [];
                    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 = 1;                           //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 = 1;                           //flashing*        
                    }
                        
                    out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                "~" +                      //???
                                                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*
                
                    return out_msgs
                }
                
                function setIfExists(id: string, value: any, type: string | null = null): boolean {
                    if (type === null) {
                        if (existsState(id)) {
                            setState(id, value);
                            return true;
                        }
                    }
                    else {
                        let obj = getObject(id);
                        if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                            setState(id, value);
                            return true;
                        }
                    }
                    return false;
                }
                
                function toggleState(id: string): boolean {
                    let obj = getObject(id);
                    if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                        setState(id, !getState(id).val);
                        return true;
                    }
                    return false;
                }
                
                function HandleButtonEvent(words): void {
                    let id = words[2]
                    let buttonAction = words[3];
                
                    console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                
                    switch (buttonAction) {
                        case "bNext":
                            var pageNum = ((pageId + 1) % config.pages.length);
                            pageId = Math.abs(pageNum);
                            UnsubscribeWatcher();
                            GeneratePage(config.pages[pageId]);
                            break;
                        case "bPrev":
                            var pageNum = ((pageId - 1) % config.pages.length);
                            pageId = Math.abs(pageNum);
                            UnsubscribeWatcher();
                            GeneratePage(config.pages[pageId]);
                            break;
                        case "bExit":
                            if (config.screenSaverDoubleClick) {
                                if (words[4] == 2)
                                    GeneratePage(config.pages[pageId]);
                            }
                            else
                                GeneratePage(config.pages[pageId]);
                            break;
                        case "OnOff":
                            if (existsObject(id)) {
                                var action = false
                                if (words[4] == "1")
                                    action = true
                                let o = getObject(id)
                                switch (o.common.role) {
                                    case "light":
                                        setIfExists(id + ".SET", action);
                                        break;
                                    case "dimmer":
                                        setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                        break;
                                    case "hue": // Armilar
                                        setIfExists(id + ".ON_ACTUAL", action);
                                }
                            }
                            break;
                        case "up":
                            setIfExists(id + ".OPEN", true)
                            break;
                        case "stop":
                            setIfExists(id + ".STOP", true)
                            break;
                        case "down":
                            setIfExists(id + ".CLOSE", true)
                            break;
                        case "button":
                            toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                            break;
                        case "positionSlider":
                            setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                            break;
                        case "brightnessSlider":
                            if (existsObject(id)) {
                                let o = getObject(id);
                                let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                switch (o.common.role) {
                                    case "dimmer":
                                        if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {  
                                            let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValue, pageItem.minValue))
                                            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 "hue":
                                        setIfExists(id + ".DIMMER", parseInt(words[4]));
                                }
                            }
                            break;
                        case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                            let pageItem = config.pages[pageId].items.find(e => e.id === id);
                            if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValue, pageItem.maxValue));
                                setIfExists(id + ".TEMPERATURE", (colorTempK));
                            } else {
                                setIfExists(id + ".TEMPERATURE", 100 - words[4]);
                            }
                            break;
                        case "colorWheel":
                            let colorCoordinates = words[4].split('|');
                            let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                            //console.log(rgb);
                            //console.log(getHue(rgb.red, rgb.green, rgb.blue));
                            setIfExists(id + ".HUE", getHue(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;
                        case "media-pause":
                            if (getState(id + ".STATE").val === true) {
                                setIfExists(id + ".PAUSE", true)
                            } else {
                                setIfExists(id + ".PLAY", true)
                            }
                            break;
                        case "media-next":
                            setIfExists(id + ".NEXT", true)
                            break;
                        case "volumeSlider":
                            setIfExists(id + ".VOLUME", parseInt(words[4]))
                            break;
                        case "speaker-sel":
                            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];
                                if ((getState(i).val) === words[4]){
                                    let deviceId = i;
                                    deviceId = deviceId.split('.');
                                    setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                    alexaDevice = deviceId[3]
                                }
                            }
                            break;
                        case "media-OnOff":
                            setIfExists(id + ".STOP", true)
                            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:
                            return "0|1";
                        case config.pages.length - 1:
                            return "1|0";
                        case -1:
                            return "0|0";
                        default:
                            return "1|1";
                    }
                }
                
                function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                
                    var out_msgs: Array<Payload> = [];
                    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"
                            if (o.common.role == "light") {
                                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);
                                }
                
                                if (val) {
                                    switchVal = "1";
                                    iconColor = GetIconColor(pageItem, true, false);
                                }
                
                                out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                            }
                
                            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"
                                }
                                let brightness = 0;
                                if (existsState(id + ".ACTUAL")) {
                                    if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {
                                        brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, pageItem.minValue, pageItem.maxValue, 100, 0));
                                    } else {
                                        brightness = getState(id + ".ACTUAL").val;
                                    }
                                } else {
                                    console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                }
                                //iconColor = GetIconColor(pageItem, brightness, false);
                                //Farbe muss noch korrekt ermittelt werden
                                if (val === true) {
                                    iconColor = GetIconColor(pageItem, true, true);
                                    switchVal = "1";
                                } else {
                                    iconColor = GetIconColor(pageItem, false, true);
                                }
                
                                RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                
                                let colorTemp = "disable"
                                let colorMode = "disable"
                                //let attr_support_color = attr.supported_color_modes
                                //if (attr_support_color.includes("color_temp"))
                                // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                                out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                            }
                
                            if (o.common.role == "hue") {
                                if (existsState(id + ".ON_ACTUAL")) {
                                    val = getState(id + ".ON_ACTUAL").val;
                                    RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type);
                                }
                
                                //Farbe muss noch korrekt ermittelt werden
                                if (val === true) {
                                    iconColor = GetIconColor(pageItem, true, true);
                                    switchVal = "1";
                                } else {
                                    iconColor = GetIconColor(pageItem, false, true);
                                }
                
                                let brightness = 0;
                                if (existsState(id + ".DIMMER")) {
                                    brightness = Math.trunc(scale2(getState(id + ".DIMMER").val, 0, 100, 0, 100));
                                    RegisterDetailEntityWatcher(id + ".DIMMER", pageItem, type);
                                } else {
                                    console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                }
                
                                var colorMode = "disable";
                                if (existsState(id + ".HUE")) {
                                    if (getState(id + ".HUE").val != null)
                                        colorMode = "enable";  
                                }
                
                                var colorTemp = 0;
                                if (existsState(id + ".TEMPERATURE")) {
                                    if (getState(id + ".TEMPERATURE").val != null) {
                
                                        if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                            colorTemp = Math.trunc(scale(getState(id + ".TEMPERATURE").val, pageItem.minValue, pageItem.maxValue, 0, 100));
                                        } else {
                                            colorTemp = 100 - getState(id + ".TEMPERATURE").val;
                                        }
                                        RegisterDetailEntityWatcher(id + ".TEMPERATURE", pageItem, type);
                                    } 
                                }
                
                                //let attr_support_color = attr.supported_color_modes
                                //if (attr_support_color.includes("color_temp"))
                                //let colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                
                                out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                            }
                
                        }
                
                        if (type == "popupShutter") {
                            if (existsState(id + ".ACTUAL")) {
                                val = getState(id + ".ACTUAL").val;
                                RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                console.log(val);
                            } else if (existsState(id + ".SET")) {
                                val = getState(id + ".SET").val;
                                RegisterDetailEntityWatcher(id + ".SET", pageItem, type);
                                console.log(val);
                            }
                            out_msgs.push({ payload: "entityUpdateDetail~" + val })
                        }
                    }
                    return out_msgs
                }
                
                function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                    return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                }
                
                function scale2(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                    return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
                }
                
                function UnsubscribeWatcher(): void {
                    for (const [key, value] of Object.entries(subscriptions)) {
                        unsubscribe(value);
                        delete subscriptions[key]
                    }
                }
                
                function HandleScreensaver(): void {
                    SendToPanel({ payload: "pageType~screensaver"})
                    UnsubscribeWatcher();
                    HandleScreensaverUpdate();
                }
                
                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++) {
                                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);
                                payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                            }
                        } 
                        else {
                            //In Config definierte Zustände wenn weatherForecast = false
                            payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                            payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                            payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                            payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                        }
                /*-------------------------------------------------------------------------------------------------------------------------------------*/
                 
                        SendToPanel(<Payload>{ payload: payloadString });
                    }
                }
                
                function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                    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 "~~~";
                    }
                }
                
                function GetAccuWeatherIcon(icon: number): string {
                    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";
                    }
                }
                
                function sleep(milliseconds) {
                  const date = Date.now();
                  let currentDate = null;
                  do {
                    currentDate = Date.now();
                  } while (currentDate - date < milliseconds);
                }
                
                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 <RGB>{ 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)));
                }
                
                /* 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;
                }
                
                /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                }
                
                type RGB = {
                    red: number,
                    green: number,
                    blue: number
                };
                
                type Payload = {
                    payload: string;
                };
                
                type Page = {
                    type: string,
                    heading: string,
                    items: PageItem[],
                    useColor: boolean
                };
                
                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[],
                };
                
                type PageItem = {
                    id: string,
                    icon: (string | undefined),
                    onColor: (RGB | undefined),
                    offColor: (RGB | undefined),
                    useColor: (boolean | undefined),
                    interpolateColor: (boolean | undefined),
                    minValue: (number | undefined),
                    maxValue: (number | undefined),
                    name: (string | undefined),
                    unit: (string | undefined)
                }
                
                type Config = {
                    panelRecvTopic: string,
                    panelSendTopic: string,
                    timeoutScreensaver: number,
                    dimmode: number,
                    //brightnessScreensaver:
                    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,
                    defaultColor: RGB,
                    defaultOnColor: RGB,
                    defaultOffColor: RGB,
                    pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                    button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                    button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                };
                
                type ScreenSaverElement = {
                    ScreensaverEntity: string | null,
                    ScreensaverEntityIcon: string | null,
                    ScreensaverEntityText: string | null,
                    ScreensaverEntityUnitText: string | null,
                }
                

                Der Slider liefert seit je her jeden Wert zwischen 0 und 100. Ich versuche die Zwischenwerte zu eliminieren, damit nicht im Worst-Case 100 x der Datenpunkt verändert werden muss. Dann hört das Slider-hüpfen auch bald auf.

                Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
                https://github.com/joBr99/nspanel-lovelace-ui/wiki

                Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                D 1 Reply Last reply
                0
                • ArmilarA Armilar

                  @great-sun sagte in Sonoff NSPanel:

                  ups... falscher thread 🐶

                  Nee, diesmal nicht. Bezieht sich ja auf Sonoff Panel und nicht auf technisch Fragen zu adressierbaren Stripes 😉

                  Zu deinen Erwartungen:

                  • NSPanel hat eine lokale Konfiguration für die Anzeige(n) und Widgets
                    In der nspanel.be von blakadder lassen sich die Widgets anlegen. Ist auch kein Problem, da diese statisch in der Original Sonoff Firmware sind und der Bezug zum Widget erhalten bleibt. Hier funktioniert das nicht - hier wird alles dynamisch aus dem TypeScript instanziert

                  • Ich bekomme Änderungen per MQTT (HTTP(S) mit JSON geht auch) geschickt
                    MQTT Payloads über CustomSend (ähnlich NSPSend, jedoch nicht "NSPSend") und Receive

                  • Werte auf dem Display kann ich auch remote (per JSON load oder MQTT syncen)
                    funktioniert auch hier Prima über MQTT, da die Datenpunkte getriggert werden

                  Zu den restlichen Fragen, wo du etwas zu anderer Firmware wissen möchtest kann ich nichts sagen. Da müsstest du schon bei openHAB, etc. googlen, da es aktuell außer der Version von blakadder oder @joBr99 keine weitere ioBroker-Integrationen gibt und die openHAB's da mehr Content haben. Ist dann aber auch nicht JavaScript, sondern Python - was der Grund ist, weshalb wir den Aufwand betreiben. Wenn du etwas anderes findest, dann musst du die Logik natürlich noch bauen.

                  Zum Beispiel:
                  Warum sollte das nicht gehen? Wenn es jetzt unter dem Sonoff-Panel funktioniert - dann funktioniert das in der lovelace-ui auch. Sind ja "nur" Schalter und Dimmer.
                  Was man mit lovelace-ui machen kann, steht hier im Thread. Wo es andere gibt und was die können - Kann ich nicht beantworten.

                  VG
                  Armilar

                  Great SUNG Offline
                  Great SUNG Offline
                  Great SUN
                  wrote on last edited by
                  #363

                  @armilar Evtl. habe ich mich nicht richtig ausgedrückt...

                  Dass das alles aus iobroker heraus aktiviert wird ist das eine, naja, ok, da muss ich dann mit leben...

                  Das nächste ist dann aber die Kommunikation. Ich möchte das gerne aufgrund der speziellen Anforderungen, die ich habe, alles selbst im Griff haben, weswegen ich keine "Middleware" zur Kommunikation mit dem Panel oder lovelace im ioBroker einsetzen möchte.
                  Ich würde gerne alle Daten weiterhin nur mit MQTT bekommen und dann auch direkt die Widgets aus meinem JavaScript aktualisieren können.
                  Eine Übersetzung des TypeScript auf JavaScript, damit ich die Widgets erstelle, sollte erstmal kein Problem sein.

                  Die Anleitungen scheinen mir aber alle recht speziell auf eine komplette Integration abzuzielen und sind scheinbar nicht dafür gedacht, dass jemand wie ich versteht, wie er selbst kommunizieren kann.

                  Conclusion wäre, wenn das so ist: Damit ich eine alternative Firmware einsetzen kann, muss ich mich durch deren oder den code der bestehenden Integrationen wälzen. Da mir das ohne Beistand wirklich zuviel ist, müsste ich dann doch bei der Orig bleiben.
                  Da ich es aber bevorzugen würde, das nicht zu tun, hatte ich mir erhofft, es gibt auch andere Doku.

                  Deswegen hab ich gedacht, dass ich zu doof bin die richtige Doku zu finden.

                  ArmilarA 1 Reply Last reply
                  0
                  • ArmilarA Armilar

                    @dexxter sagte in Sonoff NSPanel:

                    @armilar said in Sonoff NSPanel:

                    @dexxter habe die Antwort eben noch erweitert

                    Hi @Armilar
                    Ich habe eben mal wie Du empfohlen hast den Dimmwert händisch eingegeben und folgendes beobachten können.
                    Der Slider wird tatsächlich doch aktualisiert aber genau falsch herum.
                    Also wenn ich 5% von Hand eingebe springt der Slider auf 95%
                    Bei 20% springt er auf 80% usw.
                    Er gibt aber die richtigen Werte raus wenn ich ihn schiebe.
                    Also, schiebe ich den Slider auf 20% werden diese auch eingestellt aber der Slider springt dann auf 80%.
                    Kurz und knapp......Funktion ist da, Anzeige verkehrt herum.

                    Hatte ich gestern auch 😉

                    Hab noch Anpassungen gemacht. Dimmer lässt sich auch begrenzen: Beispiel hinterlegt mit 70% maxValue

                    var Icons = new IconsSelector();
                    
                    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 Off: RGB = { red: 68, green: 115, blue: 158 };
                    const On: RGB = { red: 253, green: 216, blue: 53 };
                    const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                    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 };
                    
                    
                    //----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 ...
                    
                    //Alexa-Instanz
                    var alexaInstanz = "alexa2.0"
                    var alexaDevice = "G0XXXXXXXXXXXXXX"; //Primär zu steuendes Device
                    
                    // 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.NSPanel.1.popupNotifyHeading";
                    var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                    
                    var Test_Licht: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Büro",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValue: 0, maxValue: 70},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Light-CT"},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Light-Color", minValue: 500, maxValue: 6500}
                        ]
                    };
                    
                    var Buero_Seite_1: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Büro",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                        ]
                    };
                    
                    var Fenster_1: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Fenster und Türen",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                        ]
                    };
                    
                    var Abfall: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Abfallkalender",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                        ]
                    };
                    
                    var Buero_Seite_2: PageGrid =
                    {
                        "type": "cardGrid",
                        "heading": "Büro 2",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                        ]
                    };
                    
                    var Alexa: PageMedia = 
                    {
                        "type": "cardMedia",
                        "heading": "Alexa",
                        "useColor": true,
                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                    };
                    
                    var Buero_Themostat: PageThermo = 
                    {
                        "type": "cardThermo",
                        "heading": "Thermostat",
                        "useColor": true,
                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                    };
                    
                    var Buero_Alarm: PageAlarm = 
                    {
                        "type": "cardAlarm",
                        "heading": "Alarm",
                        "useColor": true,
                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                    };
                    
                    var button1Page: PageGrid =
                    {
                        "type": "cardGrid",
                        "heading": "Radio",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                        ]
                    };
                    
                    var button2Page: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Büro",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                        ]
                    };
                    
                    export const config: Config = {
                        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,
                        locale: "de_DE",
                        timeFormat: "%H:%M",
                        dateFormat: "%A, %d. %B %Y",
                        weatherEntity: "alias.0.Wetter.Wetter",
                        defaultOffColor: Off,
                        defaultOnColor: On,
                        defaultColor: Off,
                        temperatureUnit: "°C",
                        pages: [
                                Buero_Seite_1,
                                //Test_Licht,
                                Fenster_1,
                                Abfall,
                                //Buero_Seite_2,
                                Alexa,
                                Buero_Themostat,
                                Buero_Alarm
                        ],
                        button1Page: button1Page,
                        button2Page: button2Page
                    };
                    
                    // _________________________________ 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;
                    
                    schedule("* * * * *", function () {
                        SendTime();
                    });
                    schedule("0 * * * *", function () {
                        SendDate();
                    });
                    
                    
                    // 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, function () {
                            HandleScreensaverUpdate();
                        })
                    }
                    on({ id: config.panelRecvTopic }, function (obj) {
                        if (obj.state.val.startsWith('\{"CustomRecv":')) {
                            var json = JSON.parse(obj.state.val);
                    
                            var split = json.CustomRecv.split(",");
                            HandleMessage(split[0], split[1], parseInt(split[2]), split);
                        }
                    });
                    
                    function SendToPanel(val: Payload | Payload[]): void {
                        if (Array.isArray(val)) {
                            val.forEach(function (id, i) {
                                setState(config.panelSendTopic, id.payload);
                            });
                        }
                        else
                            setState(config.panelSendTopic, val.payload);
                    }
                    
                    function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                        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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                    if (pageItem !== undefined)
                                        SendToPanel(GenerateDetailPage(words[2], pageItem));
                                case "buttonPress2":
                                    screensaverEnabled = false;
                                    HandleButtonEvent(words);
                                    break;
                                case "button1":
                                case "button2":
                                    screensaverEnabled = false;
                                    HandleHardwareButton(method);
                                default:
                                    break;
                            }
                        }
                    }
                    
                    function GeneratePage(page: Page): void {
                        switch (page.type) {
                            case "cardEntities":
                                SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                break;
                            case "cardThermo":
                                SendToPanel(GenerateThermoPage(<PageThermo>page));
                                break;
                            case "cardGrid":
                                SendToPanel(GenerateGridPage(<PageGrid>page));
                                break;
                            case "cardMedia":
                                SendToPanel(GenerateMediaPage(<PageMedia>page));
                                break;
                            case "cardAlarm":
                                SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                break;
                        }
                    }
                    
                    function HandleHardwareButton(method: string): void {
                        let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                        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);
                    }
                    
                    function HandleStartupProcess(): void {
                        SendDate();
                        SendTime();
                        SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                        SendToPanel({ payload: "dimmode~" + config.dimmode });
                    }
                    
                    function SendDate(): void {
                        var d = new Date();
                        var day = Days[d.getDay()];
                        var date = d.getDate();
                        var month = Months[d.getMonth()];
                        var year = d.getFullYear();
                        var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                        SendToPanel(<Payload>{ payload: _sendDate });
                    }
                    
                    function SendTime(): void {
                        var d = new Date();
                        var hr = d.getHours().toString();
                        var min = d.getMinutes().toString();
                    
                        if (d.getHours() < 10) {
                            hr = "0" + d.getHours().toString();
                        }
                        if (d.getMinutes() < 10) {
                            min = "0" + d.getMinutes().toString();
                        }
                        SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                    }
                    
                    function GenerateEntitiesPage(page: PageEntities): Payload[] {
                        var out_msgs: Array<Payload> = [];
                        out_msgs = [{ payload: "pageType~cardEntities" }]
                        out_msgs.push({ payload: GeneratePageElements(page) });
                        return out_msgs
                    }
                    
                    function GenerateGridPage(page: PageGrid): Payload[] {
                        var out_msgs: Array<Payload> = [];
                        out_msgs = [{ payload: "pageType~cardGrid" }]
                        out_msgs.push({ payload: GeneratePageElements(page) });
                        return out_msgs
                    }
                    
                    function GeneratePageElements(page: Page): string {
                        let maxItems = 0;
                        switch (page.type) {
                            case "cardThermo":
                                maxItems = 1;
                                break;
                            case "cardAlarm":
                                maxItems = 1;
                                break;
                            case "cardMedia":
                                maxItems = 1;
                                break;
                            case "cardEntities":
                                maxItems = 4;
                                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);
                            }
                            else {
                                pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                            }
                        }
                        return pageData;
                    }
                    
                    function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                        var iconId = "0"
                        if (pageItem.id == "delete") {
                            return "~delete~~~~~"
                        }
                        var name: string;
                        var type: string;
                    
                        // ioBroker
                        if (existsObject(pageItem.id)) {
                            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;
                                RegisterEntityWatcher(pageItem.id + ".GET");
                            }
                            else if (existsState(pageItem.id + ".SET")) {
                                val = getState(pageItem.id + ".SET").val;
                                RegisterEntityWatcher(pageItem.id + ".SET");
                            }
                            var iconColor = rgb_dec565(config.defaultColor);
                    
                            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 optVal = "0"
                    
                                    if (val === true || val === "true") {
                                        optVal = "1"
                                        iconColor = GetIconColor(pageItem, true, useColors);
                                    } else {
                                        iconColor = GetIconColor(pageItem, false, useColors);
                                    }
                    
                                    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 + ".ON") ? getState(pageItem.id + ".ON").val : true, useColors);
                                    }
                    
                                    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") ? 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 = "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 = "closed"
                                        }
                                        RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                    }
                                    return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                    
                                case "info":
                    
                                case "humidity":
                    
                                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 "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;
                    
                                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~~~~~"
                    }
                    
                    function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                        // dimmer
                        if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") {
                            let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100;
                            let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0;
                            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.minValue !== undefined ? pageItem.minValue : 0))) {
                            return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor)
                        }
                        
                        return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor);
                    }
                    
                    function RegisterEntityWatcher(id: string): void {
                        if (subscriptions.hasOwnProperty(id)) {
                            return;
                        }
                        subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                            if(pageId >= 0)
                                SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                            if(pageId == -1 && config.button1Page != undefined)
                                SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                            if(pageId == -2 && config.button2Page != undefined)
                                SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                        }))
                    }
                    
                    function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                        if (subscriptions.hasOwnProperty(id)) {
                            return;
                        }
                        subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                            SendToPanel(GenerateDetailPage(type, pageItem));
                        }))
                    }
                    
                    function GetUnitOfMeasurement(id: string): string {
                        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 "";
                    }
                    
                    function GenerateThermoPage(page: PageThermo): Payload[] {
                        var id = page.items[0].id
                        var out_msgs: Array<Payload> = [];
                        out_msgs.push({ payload: "pageType~cardThermo" });
                    
                        // ioBroker
                        if (existsObject(id)) {
                            let o = getObject(id)
                            let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                            let currentTemp = 0;
                            if (existsState(id + ".ACTUAL"))
                                currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                    
                            let destTemp = 0;
                            if (existsState(id + ".SET")) {
                                destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                            }
                    
                            let status = ""
                            if (existsState(id + ".MODE"))
                                status = getState(id + ".MODE").val;
                            let minTemp = 50 //Min Temp 5°C
                            let maxTemp = 300 //Max Temp 30°C
                            let stepTemp = 5
                    
                            //0-4 verwendet bei ungerader Anzahl Parametern
                            let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                            //5-8 verwendet bei gerader Anzahl Parametern
                            let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                            let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                            let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                            let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                    
                            if (existsState(id + ".HUMIDITY")){
                                bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                }
                            }
                    
                            if (existsState(id + ".MAINTAIN")){
                                if (getState(id + ".MAINTAIN").val >> .1) {
                                    bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                } else {
                                    bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                }
                            }
                    
                            if (existsState(id + ".UNREACH")){
                                if (getState(id + ".UNREACH").val) {
                                    bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                } else {
                                    bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                }
                            }
                    
                            if (existsState(id + ".LOWBAT")){
                                if (getState(id + ".LOWBAT").val) {
                                    bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                } else {
                                    bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                }
                            }
                    
                            let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                    
                            out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                        }
                    
                        return out_msgs
                    }
                    
                    function GenerateMediaPage(page: PageMedia): Payload[] {
                        var id = page.items[0].id
                        var out_msgs: Array<Payload> = [];
                        out_msgs.push({ payload: "pageType~cardMedia" });
                        if (existsObject(id)) {
                    
                            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;
                            let volume = getState(id + ".VOLUME").val;
                            var iconplaypause = Icons.GetIcon("pause"); //pause
                            var onoffbutton = 1374;
                            if (getState(id + ".STATE").val) {
                                onoffbutton = 65535;
                                iconplaypause = Icons.GetIcon("pause"); //pause
                            } else {
                                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
                    // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                            let speakerlist = "";
                            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 && 
                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                            speakerlist = speakerlist + getState(i).val + "?";
                                    }
                                }
                            }
                            speakerlist = speakerlist.substring(0,speakerlist.length-1);
                    //--------------------------------------------------------------------------------------------------------------
                    
                            out_msgs.push({ payload: "entityUpd~" + 
                                                      name + "~" +
                                                      id + "~" +
                                                      id + "~" +         //????
                                                      media_icon + "~" +
                                                      title + "~" +
                                                      author + "~" +
                                                      volume + "~" +
                                                      iconplaypause + "~" +
                                                      currentSpeaker + "~" +
                                                      speakerlist + "~" +
                                                      onoffbutton});
                        }
                    
                        return out_msgs
                    }
                    
                    function GenerateAlarmPage(page: PageAlarm): Payload[] {
                        var id = page.items[0].id
                        var out_msgs: Array<Payload> = [];
                        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 = 1;                           //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 = 1;                           //flashing*        
                        }
                            
                        out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                    id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                    "~" +                      //???
                                                    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*
                    
                        return out_msgs
                    }
                    
                    function setIfExists(id: string, value: any, type: string | null = null): boolean {
                        if (type === null) {
                            if (existsState(id)) {
                                setState(id, value);
                                return true;
                            }
                        }
                        else {
                            let obj = getObject(id);
                            if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                setState(id, value);
                                return true;
                            }
                        }
                        return false;
                    }
                    
                    function toggleState(id: string): boolean {
                        let obj = getObject(id);
                        if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                            setState(id, !getState(id).val);
                            return true;
                        }
                        return false;
                    }
                    
                    function HandleButtonEvent(words): void {
                        let id = words[2]
                        let buttonAction = words[3];
                    
                        console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                    
                        switch (buttonAction) {
                            case "bNext":
                                var pageNum = ((pageId + 1) % config.pages.length);
                                pageId = Math.abs(pageNum);
                                UnsubscribeWatcher();
                                GeneratePage(config.pages[pageId]);
                                break;
                            case "bPrev":
                                var pageNum = ((pageId - 1) % config.pages.length);
                                pageId = Math.abs(pageNum);
                                UnsubscribeWatcher();
                                GeneratePage(config.pages[pageId]);
                                break;
                            case "bExit":
                                if (config.screenSaverDoubleClick) {
                                    if (words[4] == 2)
                                        GeneratePage(config.pages[pageId]);
                                }
                                else
                                    GeneratePage(config.pages[pageId]);
                                break;
                            case "OnOff":
                                if (existsObject(id)) {
                                    var action = false
                                    if (words[4] == "1")
                                        action = true
                                    let o = getObject(id)
                                    switch (o.common.role) {
                                        case "light":
                                            setIfExists(id + ".SET", action);
                                            break;
                                        case "dimmer":
                                            setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                            break;
                                        case "hue": // Armilar
                                            setIfExists(id + ".ON_ACTUAL", action);
                                    }
                                }
                                break;
                            case "up":
                                setIfExists(id + ".OPEN", true)
                                break;
                            case "stop":
                                setIfExists(id + ".STOP", true)
                                break;
                            case "down":
                                setIfExists(id + ".CLOSE", true)
                                break;
                            case "button":
                                toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                break;
                            case "positionSlider":
                                setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                break;
                            case "brightnessSlider":
                                if (existsObject(id)) {
                                    let o = getObject(id);
                                    let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                    switch (o.common.role) {
                                        case "dimmer":
                                            if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {  
                                                let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValue, pageItem.minValue))
                                                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 "hue":
                                            setIfExists(id + ".DIMMER", parseInt(words[4]));
                                    }
                                }
                                break;
                            case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                    let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValue, pageItem.maxValue));
                                    setIfExists(id + ".TEMPERATURE", (colorTempK));
                                } else {
                                    setIfExists(id + ".TEMPERATURE", 100 - words[4]);
                                }
                                break;
                            case "colorWheel":
                                let colorCoordinates = words[4].split('|');
                                let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                //console.log(rgb);
                                //console.log(getHue(rgb.red, rgb.green, rgb.blue));
                                setIfExists(id + ".HUE", getHue(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;
                            case "media-pause":
                                if (getState(id + ".STATE").val === true) {
                                    setIfExists(id + ".PAUSE", true)
                                } else {
                                    setIfExists(id + ".PLAY", true)
                                }
                                break;
                            case "media-next":
                                setIfExists(id + ".NEXT", true)
                                break;
                            case "volumeSlider":
                                setIfExists(id + ".VOLUME", parseInt(words[4]))
                                break;
                            case "speaker-sel":
                                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];
                                    if ((getState(i).val) === words[4]){
                                        let deviceId = i;
                                        deviceId = deviceId.split('.');
                                        setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                        alexaDevice = deviceId[3]
                                    }
                                }
                                break;
                            case "media-OnOff":
                                setIfExists(id + ".STOP", true)
                                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:
                                return "0|1";
                            case config.pages.length - 1:
                                return "1|0";
                            case -1:
                                return "0|0";
                            default:
                                return "1|1";
                        }
                    }
                    
                    function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                    
                        var out_msgs: Array<Payload> = [];
                        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"
                                if (o.common.role == "light") {
                                    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);
                                    }
                    
                                    if (val) {
                                        switchVal = "1";
                                        iconColor = GetIconColor(pageItem, true, false);
                                    }
                    
                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                }
                    
                                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"
                                    }
                                    let brightness = 0;
                                    if (existsState(id + ".ACTUAL")) {
                                        if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {
                                            brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, pageItem.minValue, pageItem.maxValue, 100, 0));
                                        } else {
                                            brightness = getState(id + ".ACTUAL").val;
                                        }
                                    } else {
                                        console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                    }
                                    //iconColor = GetIconColor(pageItem, brightness, false);
                                    //Farbe muss noch korrekt ermittelt werden
                                    if (val === true) {
                                        iconColor = GetIconColor(pageItem, true, true);
                                        switchVal = "1";
                                    } else {
                                        iconColor = GetIconColor(pageItem, false, true);
                                    }
                    
                                    RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                    
                                    let colorTemp = "disable"
                                    let colorMode = "disable"
                                    //let attr_support_color = attr.supported_color_modes
                                    //if (attr_support_color.includes("color_temp"))
                                    // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                }
                    
                                if (o.common.role == "hue") {
                                    if (existsState(id + ".ON_ACTUAL")) {
                                        val = getState(id + ".ON_ACTUAL").val;
                                        RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type);
                                    }
                    
                                    //Farbe muss noch korrekt ermittelt werden
                                    if (val === true) {
                                        iconColor = GetIconColor(pageItem, true, true);
                                        switchVal = "1";
                                    } else {
                                        iconColor = GetIconColor(pageItem, false, true);
                                    }
                    
                                    let brightness = 0;
                                    if (existsState(id + ".DIMMER")) {
                                        brightness = Math.trunc(scale2(getState(id + ".DIMMER").val, 0, 100, 0, 100));
                                        RegisterDetailEntityWatcher(id + ".DIMMER", pageItem, type);
                                    } else {
                                        console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                    }
                    
                                    var colorMode = "disable";
                                    if (existsState(id + ".HUE")) {
                                        if (getState(id + ".HUE").val != null)
                                            colorMode = "enable";  
                                    }
                    
                                    var colorTemp = 0;
                                    if (existsState(id + ".TEMPERATURE")) {
                                        if (getState(id + ".TEMPERATURE").val != null) {
                    
                                            if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                                colorTemp = Math.trunc(scale(getState(id + ".TEMPERATURE").val, pageItem.minValue, pageItem.maxValue, 0, 100));
                                            } else {
                                                colorTemp = 100 - getState(id + ".TEMPERATURE").val;
                                            }
                                            RegisterDetailEntityWatcher(id + ".TEMPERATURE", pageItem, type);
                                        } 
                                    }
                    
                                    //let attr_support_color = attr.supported_color_modes
                                    //if (attr_support_color.includes("color_temp"))
                                    //let colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                    
                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                }
                    
                            }
                    
                            if (type == "popupShutter") {
                                if (existsState(id + ".ACTUAL")) {
                                    val = getState(id + ".ACTUAL").val;
                                    RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                    console.log(val);
                                } else if (existsState(id + ".SET")) {
                                    val = getState(id + ".SET").val;
                                    RegisterDetailEntityWatcher(id + ".SET", pageItem, type);
                                    console.log(val);
                                }
                                out_msgs.push({ payload: "entityUpdateDetail~" + val })
                            }
                        }
                        return out_msgs
                    }
                    
                    function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                        return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                    }
                    
                    function scale2(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                        return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
                    }
                    
                    function UnsubscribeWatcher(): void {
                        for (const [key, value] of Object.entries(subscriptions)) {
                            unsubscribe(value);
                            delete subscriptions[key]
                        }
                    }
                    
                    function HandleScreensaver(): void {
                        SendToPanel({ payload: "pageType~screensaver"})
                        UnsubscribeWatcher();
                        HandleScreensaverUpdate();
                    }
                    
                    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++) {
                                    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);
                                    payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                }
                            } 
                            else {
                                //In Config definierte Zustände wenn weatherForecast = false
                                payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                            }
                    /*-------------------------------------------------------------------------------------------------------------------------------------*/
                     
                            SendToPanel(<Payload>{ payload: payloadString });
                        }
                    }
                    
                    function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                        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 "~~~";
                        }
                    }
                    
                    function GetAccuWeatherIcon(icon: number): string {
                        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";
                        }
                    }
                    
                    function sleep(milliseconds) {
                      const date = Date.now();
                      let currentDate = null;
                      do {
                        currentDate = Date.now();
                      } while (currentDate - date < milliseconds);
                    }
                    
                    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 <RGB>{ 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)));
                    }
                    
                    /* 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;
                    }
                    
                    /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                    }
                    
                    type RGB = {
                        red: number,
                        green: number,
                        blue: number
                    };
                    
                    type Payload = {
                        payload: string;
                    };
                    
                    type Page = {
                        type: string,
                        heading: string,
                        items: PageItem[],
                        useColor: boolean
                    };
                    
                    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[],
                    };
                    
                    type PageItem = {
                        id: string,
                        icon: (string | undefined),
                        onColor: (RGB | undefined),
                        offColor: (RGB | undefined),
                        useColor: (boolean | undefined),
                        interpolateColor: (boolean | undefined),
                        minValue: (number | undefined),
                        maxValue: (number | undefined),
                        name: (string | undefined),
                        unit: (string | undefined)
                    }
                    
                    type Config = {
                        panelRecvTopic: string,
                        panelSendTopic: string,
                        timeoutScreensaver: number,
                        dimmode: number,
                        //brightnessScreensaver:
                        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,
                        defaultColor: RGB,
                        defaultOnColor: RGB,
                        defaultOffColor: RGB,
                        pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                        button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                        button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                    };
                    
                    type ScreenSaverElement = {
                        ScreensaverEntity: string | null,
                        ScreensaverEntityIcon: string | null,
                        ScreensaverEntityText: string | null,
                        ScreensaverEntityUnitText: string | null,
                    }
                    

                    Der Slider liefert seit je her jeden Wert zwischen 0 und 100. Ich versuche die Zwischenwerte zu eliminieren, damit nicht im Worst-Case 100 x der Datenpunkt verändert werden muss. Dann hört das Slider-hüpfen auch bald auf.

                    D Offline
                    D Offline
                    Dexxter
                    wrote on last edited by
                    #364

                    @armilar
                    Also das läuft für mich schon "fast" perfekt 😁
                    Das einzige Problem was ich jetzt noch habe ist das ich ja den Dimmerslider vom Hue Gerät begrenzen muss.
                    Und da dort ja schon minValue und maxValue für die Farbtemperatur vergeben sind wird das so ja nicht gehen.
                    Ich habe mal ein bisschen in Deinem Code rumgepfuscht ( sorry, ich hab da echt keine Ahnung von ) und versucht noch nen anderen Übergabewert hinein zu bekommen.
                    Der nennt sich dann
                    minValueBRI
                    und
                    maxValueBRI.
                    Sollte dann für den Brightnessslider im Hue Gerät sein und dort den Dimmwert begrenzen.
                    So wie ich das verpfuscht habe läuft das Script auch nicht.
                    Wenn Du mal herzlich lachen möchtest dann kannst Du Dir das ja mal anschauen.

                    var Icons = new IconsSelector();
                    
                    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 Off: RGB = { red: 68, green: 115, blue: 158 };
                    const On: RGB = { red: 253, green: 216, blue: 53 };
                    const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                    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 };
                    
                    
                    //----Möglichkeit, im Screensaver zwischen Accu-Weather Forecast oder selbstdefinierten Werten zu wählen---------------------------------
                    var weatherForecast = false; //true = WheatherForecast 5 Days --- false = Config --> firstScreensaverEntity - fourthScreensaverEntity ...
                    
                    //Alexa-Instanz
                    var alexaInstanz = "alexa2.0"
                    var alexaDevice = "G0XXXXXXXXXXXXXX"; //Primär zu steuendes Device
                    
                    // 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.NSPanel.1.popupNotifyHeading";
                    var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                    
                    var Test_Licht: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Büro",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValue: 0, maxValue: 70},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Light-CT"},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Light-Color", minValue: 500, maxValue: 6500}
                        ]
                    };
                    
                    var Buero_Seite_1: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Büro",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.CTmitHUE", name: "Computer Decke", minValue: 500, maxValue: 6500, minValueBRI: 1, maxValueBRI: 70}, //HUE o.a. über --> Alias HUE mit CT ohne Color
                            <PageItem>{ id: "alias.0.COMPUTER_LED", name: "Computer Tisch", minValue: 0, maxValue: 70}, //Dimmer
                            <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                        ]
                    };
                    
                    var Fenster_1: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Fenster und Türen",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                        ]
                    };
                    
                    var Abfall: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Abfallkalender",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                        ]
                    };
                    
                    var Buero_Seite_2: PageGrid =
                    {
                        "type": "cardGrid",
                        "heading": "Büro 2",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                        ]
                    };
                    
                    var Alexa: PageMedia = 
                    {
                        "type": "cardMedia",
                        "heading": "Alexa",
                        "useColor": true,
                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                    };
                    
                    var Buero_Themostat: PageThermo = 
                    {
                        "type": "cardThermo",
                        "heading": "Thermostat",
                        "useColor": true,
                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                    };
                    
                    var Buero_Alarm: PageAlarm = 
                    {
                        "type": "cardAlarm",
                        "heading": "Alarm",
                        "useColor": true,
                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                    };
                    
                    var button1Page: PageGrid =
                    {
                        "type": "cardGrid",
                        "heading": "Radio",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                        ]
                    };
                    
                    var button2Page: PageEntities =
                    {
                        "type": "cardEntities",
                        "heading": "Büro",
                        "useColor": true,
                        "items": [
                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                        ]
                    };
                    
                    export const config: Config = {
                        panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT",       //anpassen
                        panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend",   //anpassen
                        firstScreensaverEntity: { ScreensaverEntity: "hm-rpc.0.000EDA4995B568.1.HUMIDITY", ScreensaverEntityIcon: "water-percent", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "%" },
                        secondScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.PRECIPITATION_CHANCE", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" },
                        thirdScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.Wind_SPEED", ScreensaverEntityIcon: "weather-windy", ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: "bft" },
                        fourthScreensaverEntity: { ScreensaverEntity: "accuweather.0.Current.UVIndex", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "UV", ScreensaverEntityUnitText: "" },
                        timeoutScreensaver: 5,
                        dimmode: 8,
                        screenSaverDoubleClick: false,
                        locale: "de_DE",
                        timeFormat: "%H:%M",
                        dateFormat: "%A, %d. %B %Y",
                        weatherEntity: "alias.0.Wetter",
                        defaultOffColor: Off,
                        defaultOnColor: On,
                        defaultColor: Off,
                        temperatureUnit: "°C",
                        pages: [
                                Buero_Seite_1,
                                //Test_Licht,
                                Fenster_1,
                                Abfall,
                                //Buero_Seite_2,
                                Alexa,
                                Buero_Themostat,
                                Buero_Alarm
                        ],
                        button1Page: button1Page,
                        button2Page: button2Page
                    };
                    
                    // _________________________________ 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;
                    
                    schedule("* * * * *", function () {
                        SendTime();
                    });
                    schedule("0 * * * *", function () {
                        SendDate();
                    });
                    
                    
                    // 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, function () {
                            HandleScreensaverUpdate();
                        })
                    }
                    on({ id: config.panelRecvTopic }, function (obj) {
                        if (obj.state.val.startsWith('\{"CustomRecv":')) {
                            var json = JSON.parse(obj.state.val);
                    
                            var split = json.CustomRecv.split(",");
                            HandleMessage(split[0], split[1], parseInt(split[2]), split);
                        }
                    });
                    
                    function SendToPanel(val: Payload | Payload[]): void {
                        if (Array.isArray(val)) {
                            val.forEach(function (id, i) {
                                setState(config.panelSendTopic, id.payload);
                            });
                        }
                        else
                            setState(config.panelSendTopic, val.payload);
                    }
                    
                    function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                        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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                    if (pageItem !== undefined)
                                        SendToPanel(GenerateDetailPage(words[2], pageItem));
                                case "buttonPress2":
                                    screensaverEnabled = false;
                                    HandleButtonEvent(words);
                                    break;
                                case "button1":
                                case "button2":
                                    screensaverEnabled = false;
                                    HandleHardwareButton(method);
                                default:
                                    break;
                            }
                        }
                    }
                    
                    function GeneratePage(page: Page): void {
                        switch (page.type) {
                            case "cardEntities":
                                SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                break;
                            case "cardThermo":
                                SendToPanel(GenerateThermoPage(<PageThermo>page));
                                break;
                            case "cardGrid":
                                SendToPanel(GenerateGridPage(<PageGrid>page));
                                break;
                            case "cardMedia":
                                SendToPanel(GenerateMediaPage(<PageMedia>page));
                                break;
                            case "cardAlarm":
                                SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                break;
                        }
                    }
                    
                    function HandleHardwareButton(method: string): void {
                        let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                        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);
                    }
                    
                    function HandleStartupProcess(): void {
                        SendDate();
                        SendTime();
                        SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                        SendToPanel({ payload: "dimmode~" + config.dimmode });
                    }
                    
                    function SendDate(): void {
                        var d = new Date();
                        var day = Days[d.getDay()];
                        var date = d.getDate();
                        var month = Months[d.getMonth()];
                        var year = d.getFullYear();
                        var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                        SendToPanel(<Payload>{ payload: _sendDate });
                    }
                    
                    function SendTime(): void {
                        var d = new Date();
                        var hr = d.getHours().toString();
                        var min = d.getMinutes().toString();
                    
                        if (d.getHours() < 10) {
                            hr = "0" + d.getHours().toString();
                        }
                        if (d.getMinutes() < 10) {
                            min = "0" + d.getMinutes().toString();
                        }
                        SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                    }
                    
                    function GenerateEntitiesPage(page: PageEntities): Payload[] {
                        var out_msgs: Array<Payload> = [];
                        out_msgs = [{ payload: "pageType~cardEntities" }]
                        out_msgs.push({ payload: GeneratePageElements(page) });
                        return out_msgs
                    }
                    
                    function GenerateGridPage(page: PageGrid): Payload[] {
                        var out_msgs: Array<Payload> = [];
                        out_msgs = [{ payload: "pageType~cardGrid" }]
                        out_msgs.push({ payload: GeneratePageElements(page) });
                        return out_msgs
                    }
                    
                    function GeneratePageElements(page: Page): string {
                        let maxItems = 0;
                        switch (page.type) {
                            case "cardThermo":
                                maxItems = 1;
                                break;
                            case "cardAlarm":
                                maxItems = 1;
                                break;
                            case "cardMedia":
                                maxItems = 1;
                                break;
                            case "cardEntities":
                                maxItems = 4;
                                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);
                            }
                            else {
                                pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                            }
                        }
                        return pageData;
                    }
                    
                    function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                        var iconId = "0"
                        if (pageItem.id == "delete") {
                            return "~delete~~~~~"
                        }
                        var name: string;
                        var type: string;
                    
                        // ioBroker
                        if (existsObject(pageItem.id)) {
                            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;
                                RegisterEntityWatcher(pageItem.id + ".GET");
                            }
                            else if (existsState(pageItem.id + ".SET")) {
                                val = getState(pageItem.id + ".SET").val;
                                RegisterEntityWatcher(pageItem.id + ".SET");
                            }
                            var iconColor = rgb_dec565(config.defaultColor);
                    
                            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 optVal = "0"
                    
                                    if (val === true || val === "true") {
                                        optVal = "1"
                                        iconColor = GetIconColor(pageItem, true, useColors);
                                    } else {
                                        iconColor = GetIconColor(pageItem, false, useColors);
                                    }
                    
                                    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 + ".ON") ? getState(pageItem.id + ".ON").val : true, useColors);
                                    }
                    
                                    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") ? 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 = "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 = "closed"
                                        }
                                        RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                    }
                                    return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                    
                                case "info":
                    
                                case "humidity":
                    
                                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 "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;
                    
                                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~~~~~"
                    }
                    
                    function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                        // dimmer
                        if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") {
                            let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100;
                            let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0;
                    		let maxValueBRI = pageItem.maxValueBRI !== undefined ? pageItem.maxValueBRI : 100;
                            let minValueBRI = pageItem.minValueBRI !== undefined ? pageItem.minValueBRI : 0;
                            value = value > maxValue ? maxValue : value;
                            value = value < minValue ? minValue : value;
                    		value = value > maxValueBRI ? maxValueBRI : value;
                            value = value < minValueBRI ? minValueBRI : 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),
                    				scale(value, minValueBRI, maxValueBRI, 0, 1)
                                ));
                        }
                    
                        if ((pageItem.useColor || useColors) && ((typeof (value) === "boolean" && value) || value > (pageItem.minValue !== undefined ? pageItem.minValue : 0))) {
                            return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor)
                        }
                        
                        return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor);
                    }
                    
                    function RegisterEntityWatcher(id: string): void {
                        if (subscriptions.hasOwnProperty(id)) {
                            return;
                        }
                        subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                            if(pageId >= 0)
                                SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                            if(pageId == -1 && config.button1Page != undefined)
                                SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                            if(pageId == -2 && config.button2Page != undefined)
                                SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                        }))
                    }
                    
                    function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                        if (subscriptions.hasOwnProperty(id)) {
                            return;
                        }
                        subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                            SendToPanel(GenerateDetailPage(type, pageItem));
                        }))
                    }
                    
                    function GetUnitOfMeasurement(id: string): string {
                        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 "";
                    }
                    
                    function GenerateThermoPage(page: PageThermo): Payload[] {
                        var id = page.items[0].id
                        var out_msgs: Array<Payload> = [];
                        out_msgs.push({ payload: "pageType~cardThermo" });
                    
                        // ioBroker
                        if (existsObject(id)) {
                            let o = getObject(id)
                            let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                            let currentTemp = 0;
                            if (existsState(id + ".ACTUAL"))
                                currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                    
                            let destTemp = 0;
                            if (existsState(id + ".SET")) {
                                destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                            }
                    
                            let status = ""
                            if (existsState(id + ".MODE"))
                                status = getState(id + ".MODE").val;
                            let minTemp = 50 //Min Temp 5°C
                            let maxTemp = 300 //Max Temp 30°C
                            let stepTemp = 5
                    
                            //0-4 verwendet bei ungerader Anzahl Parametern
                            let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                            let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                            //5-8 verwendet bei gerader Anzahl Parametern
                            let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                            let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                            let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                            let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                    
                            if (existsState(id + ".HUMIDITY")){
                                bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                }
                            }
                    
                            if (existsState(id + ".MAINTAIN")){
                                if (getState(id + ".MAINTAIN").val >> .1) {
                                    bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                } else {
                                    bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                }
                            }
                    
                            if (existsState(id + ".UNREACH")){
                                if (getState(id + ".UNREACH").val) {
                                    bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                } else {
                                    bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                }
                            }
                    
                            if (existsState(id + ".LOWBAT")){
                                if (getState(id + ".LOWBAT").val) {
                                    bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                } else {
                                    bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                }
                            }
                    
                            let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                    
                            out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                        }
                    
                        return out_msgs
                    }
                    
                    function GenerateMediaPage(page: PageMedia): Payload[] {
                        var id = page.items[0].id
                        var out_msgs: Array<Payload> = [];
                        out_msgs.push({ payload: "pageType~cardMedia" });
                        if (existsObject(id)) {
                    
                            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;
                            let volume = getState(id + ".VOLUME").val;
                            var iconplaypause = Icons.GetIcon("pause"); //pause
                            var onoffbutton = 1374;
                            if (getState(id + ".STATE").val) {
                                onoffbutton = 65535;
                                iconplaypause = Icons.GetIcon("pause"); //pause
                            } else {
                                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
                    // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                            let speakerlist = "";
                            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 && 
                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                            speakerlist = speakerlist + getState(i).val + "?";
                                    }
                                }
                            }
                            speakerlist = speakerlist.substring(0,speakerlist.length-1);
                    //--------------------------------------------------------------------------------------------------------------
                    
                            out_msgs.push({ payload: "entityUpd~" + 
                                                      name + "~" +
                                                      id + "~" +
                                                      id + "~" +         //????
                                                      media_icon + "~" +
                                                      title + "~" +
                                                      author + "~" +
                                                      volume + "~" +
                                                      iconplaypause + "~" +
                                                      currentSpeaker + "~" +
                                                      speakerlist + "~" +
                                                      onoffbutton});
                        }
                    
                        return out_msgs
                    }
                    
                    function GenerateAlarmPage(page: PageAlarm): Payload[] {
                        var id = page.items[0].id
                        var out_msgs: Array<Payload> = [];
                        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 = 1;                           //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 = 1;                           //flashing*        
                        }
                            
                        out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                    id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                    "~" +                      //???
                                                    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*
                    
                        return out_msgs
                    }
                    
                    function setIfExists(id: string, value: any, type: string | null = null): boolean {
                        if (type === null) {
                            if (existsState(id)) {
                                setState(id, value);
                                return true;
                            }
                        }
                        else {
                            let obj = getObject(id);
                            if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                setState(id, value);
                                return true;
                            }
                        }
                        return false;
                    }
                    
                    function toggleState(id: string): boolean {
                        let obj = getObject(id);
                        if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                            setState(id, !getState(id).val);
                            return true;
                        }
                        return false;
                    }
                    
                    function HandleButtonEvent(words): void {
                        let id = words[2]
                        let buttonAction = words[3];
                    
                        console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                    
                        switch (buttonAction) {
                            case "bNext":
                                var pageNum = ((pageId + 1) % config.pages.length);
                                pageId = Math.abs(pageNum);
                                UnsubscribeWatcher();
                                GeneratePage(config.pages[pageId]);
                                break;
                            case "bPrev":
                                var pageNum = ((pageId - 1) % config.pages.length);
                                pageId = Math.abs(pageNum);
                                UnsubscribeWatcher();
                                GeneratePage(config.pages[pageId]);
                                break;
                            case "bExit":
                                if (config.screenSaverDoubleClick) {
                                    if (words[4] == 2)
                                        GeneratePage(config.pages[pageId]);
                                }
                                else
                                    GeneratePage(config.pages[pageId]);
                                break;
                            case "OnOff":
                                if (existsObject(id)) {
                                    var action = false
                                    if (words[4] == "1")
                                        action = true
                                    let o = getObject(id)
                                    switch (o.common.role) {
                                        case "light":
                                            setIfExists(id + ".SET", action);
                                            break;
                                        case "dimmer":
                                            setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                            break;
                                        case "hue": // Armilar
                                            setIfExists(id + ".ON_ACTUAL", action);
                                    }
                                }
                                break;
                            case "up":
                                setIfExists(id + ".OPEN", true)
                                break;
                            case "stop":
                                setIfExists(id + ".STOP", true)
                                break;
                            case "down":
                                setIfExists(id + ".CLOSE", true)
                                break;
                            case "button":
                                toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                break;
                            case "positionSlider":
                                setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                break;
                            case "brightnessSlider":
                                if (existsObject(id)) {
                                    let o = getObject(id);
                                    let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                    switch (o.common.role) {
                                        case "dimmer":
                                            if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {  
                                                let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValue, pageItem.minValue))
                                                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 "hue":
                    					    if (pageItem.minValueBRI != undefined && pageItem.maxValueBRI != undefined) {  
                                                let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValueBRI, pageItem.minValueBRI))
                                                setIfExists(id + ".DIMMER", parseInt(words[4]));
                                    }
                                }
                                break;
                            case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                    let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValue, pageItem.maxValue));
                                    setIfExists(id + ".TEMPERATURE", (colorTempK));
                                } else {
                                    setIfExists(id + ".TEMPERATURE", 100 - words[4]);
                                }
                                break;
                            case "colorWheel":
                                let colorCoordinates = words[4].split('|');
                                let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                //console.log(rgb);
                                //console.log(getHue(rgb.red, rgb.green, rgb.blue));
                                setIfExists(id + ".HUE", getHue(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;
                            case "media-pause":
                                if (getState(id + ".STATE").val === true) {
                                    setIfExists(id + ".PAUSE", true)
                                } else {
                                    setIfExists(id + ".PLAY", true)
                                }
                                break;
                            case "media-next":
                                setIfExists(id + ".NEXT", true)
                                break;
                            case "volumeSlider":
                                setIfExists(id + ".VOLUME", parseInt(words[4]))
                                break;
                            case "speaker-sel":
                                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];
                                    if ((getState(i).val) === words[4]){
                                        let deviceId = i;
                                        deviceId = deviceId.split('.');
                                        setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                        alexaDevice = deviceId[3]
                                    }
                                }
                                break;
                            case "media-OnOff":
                                setIfExists(id + ".STOP", true)
                                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:
                                return "0|1";
                            case config.pages.length - 1:
                                return "1|0";
                            case -1:
                                return "0|0";
                            default:
                                return "1|1";
                        }
                    }
                    
                    function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                    
                        var out_msgs: Array<Payload> = [];
                        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"
                                if (o.common.role == "light") {
                                    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);
                                    }
                    
                                    if (val) {
                                        switchVal = "1";
                                        iconColor = GetIconColor(pageItem, true, false);
                                    }
                    
                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                }
                    
                                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"
                                    }
                                    let brightness = 0;
                                    if (existsState(id + ".ACTUAL")) {
                                        if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {
                                            brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, pageItem.minValue, pageItem.maxValue, 100, 0));
                                        } else {
                                            brightness = getState(id + ".ACTUAL").val;
                                        }
                                    } else {
                                        console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                    }
                                    //iconColor = GetIconColor(pageItem, brightness, false);
                                    //Farbe muss noch korrekt ermittelt werden
                                    if (val === true) {
                                        iconColor = GetIconColor(pageItem, true, true);
                                        switchVal = "1";
                                    } else {
                                        iconColor = GetIconColor(pageItem, false, true);
                                    }
                    
                                    RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                    
                                    let colorTemp = "disable"
                                    let colorMode = "disable"
                                    //let attr_support_color = attr.supported_color_modes
                                    //if (attr_support_color.includes("color_temp"))
                                    // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                }
                    
                                if (o.common.role == "hue") {
                                    if (existsState(id + ".ON_ACTUAL")) {
                                        val = getState(id + ".ON_ACTUAL").val;
                                        RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type);
                                    }
                    
                                    //Farbe muss noch korrekt ermittelt werden
                                    if (val === true) {
                                        iconColor = GetIconColor(pageItem, true, true);
                                        switchVal = "1";
                                    } else {
                                        iconColor = GetIconColor(pageItem, false, true);
                                    }
                    
                                    let brightness = 0;
                                    if (existsState(id + ".DIMMER")) {
                    					if (pageItem.minValueBRI !== undefined && pageItem.minValueBRI !== undefined) {
                                        brightness = Math.trunc(scale2(getState(id + ".DIMMER").val, 0, 100, 0, 100));
                                        RegisterDetailEntityWatcher(id + ".DIMMER", pageItem, type);
                                    } else {
                                        console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                    }
                    
                                    var colorMode = "disable";
                                    if (existsState(id + ".HUE")) {
                                        if (getState(id + ".HUE").val != null)
                                            colorMode = "enable";  
                                    }
                    
                                    var colorTemp = 0;
                                    if (existsState(id + ".TEMPERATURE")) {
                                        if (getState(id + ".TEMPERATURE").val != null) {
                    
                                            if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                                colorTemp = Math.trunc(scale(getState(id + ".TEMPERATURE").val, pageItem.minValue, pageItem.maxValue, 0, 100));
                                            } else {
                                                colorTemp = 100 - getState(id + ".TEMPERATURE").val;
                                            }
                                            RegisterDetailEntityWatcher(id + ".TEMPERATURE", pageItem, type);
                                        } 
                                    }
                    
                                    //let attr_support_color = attr.supported_color_modes
                                    //if (attr_support_color.includes("color_temp"))
                                    //let colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                    
                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                }
                    
                            }
                    
                            if (type == "popupShutter") {
                                if (existsState(id + ".ACTUAL")) {
                                    val = getState(id + ".ACTUAL").val;
                                    RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                    console.log(val);
                                } else if (existsState(id + ".SET")) {
                                    val = getState(id + ".SET").val;
                                    RegisterDetailEntityWatcher(id + ".SET", pageItem, type);
                                    console.log(val);
                                }
                                out_msgs.push({ payload: "entityUpdateDetail~" + val })
                            }
                        }
                        return out_msgs
                    }
                    
                    function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                        return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                    }
                    
                    function scale2(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                        return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
                    }
                    
                    function UnsubscribeWatcher(): void {
                        for (const [key, value] of Object.entries(subscriptions)) {
                            unsubscribe(value);
                            delete subscriptions[key]
                        }
                    }
                    
                    function HandleScreensaver(): void {
                        SendToPanel({ payload: "pageType~screensaver"})
                        UnsubscribeWatcher();
                        HandleScreensaverUpdate();
                    }
                    
                    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++) {
                                    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);
                                    payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                }
                            } 
                            else {
                                //In Config definierte Zustände wenn weatherForecast = false
                                payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                            }
                    /*-------------------------------------------------------------------------------------------------------------------------------------*/
                     
                            SendToPanel(<Payload>{ payload: payloadString });
                        }
                    }
                    
                    function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                        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 "~~~";
                        }
                    }
                    
                    function GetAccuWeatherIcon(icon: number): string {
                        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";
                        }
                    }
                    
                    function sleep(milliseconds) {
                      const date = Date.now();
                      let currentDate = null;
                      do {
                        currentDate = Date.now();
                      } while (currentDate - date < milliseconds);
                    }
                    
                    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 <RGB>{ 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)));
                    }
                    
                    /* 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;
                    }
                    
                    /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                    }
                    
                    type RGB = {
                        red: number,
                        green: number,
                        blue: number
                    };
                    
                    type Payload = {
                        payload: string;
                    };
                    
                    type Page = {
                        type: string,
                        heading: string,
                        items: PageItem[],
                        useColor: boolean
                    };
                    
                    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[],
                    };
                    
                    type PageItem = {
                        id: string,
                        icon: (string | undefined),
                        onColor: (RGB | undefined),
                        offColor: (RGB | undefined),
                        useColor: (boolean | undefined),
                        interpolateColor: (boolean | undefined),
                        minValue: (number | undefined),
                        maxValue: (number | undefined),
                        name: (string | undefined),
                        unit: (string | undefined)
                    }
                    
                    type Config = {
                        panelRecvTopic: string,
                        panelSendTopic: string,
                        timeoutScreensaver: number,
                        dimmode: number,
                        //brightnessScreensaver:
                        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,
                        defaultColor: RGB,
                        defaultOnColor: RGB,
                        defaultOffColor: RGB,
                        pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                        button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                        button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                    };
                    
                    type ScreenSaverElement = {
                        ScreensaverEntity: string | null,
                        ScreensaverEntityIcon: string | null,
                        ScreensaverEntityText: string | null,
                        ScreensaverEntityUnitText: string | null,
                    }
                    
                    ArmilarA 2 Replies Last reply
                    0
                    • Great SUNG Great SUN

                      @armilar Evtl. habe ich mich nicht richtig ausgedrückt...

                      Dass das alles aus iobroker heraus aktiviert wird ist das eine, naja, ok, da muss ich dann mit leben...

                      Das nächste ist dann aber die Kommunikation. Ich möchte das gerne aufgrund der speziellen Anforderungen, die ich habe, alles selbst im Griff haben, weswegen ich keine "Middleware" zur Kommunikation mit dem Panel oder lovelace im ioBroker einsetzen möchte.
                      Ich würde gerne alle Daten weiterhin nur mit MQTT bekommen und dann auch direkt die Widgets aus meinem JavaScript aktualisieren können.
                      Eine Übersetzung des TypeScript auf JavaScript, damit ich die Widgets erstelle, sollte erstmal kein Problem sein.

                      Die Anleitungen scheinen mir aber alle recht speziell auf eine komplette Integration abzuzielen und sind scheinbar nicht dafür gedacht, dass jemand wie ich versteht, wie er selbst kommunizieren kann.

                      Conclusion wäre, wenn das so ist: Damit ich eine alternative Firmware einsetzen kann, muss ich mich durch deren oder den code der bestehenden Integrationen wälzen. Da mir das ohne Beistand wirklich zuviel ist, müsste ich dann doch bei der Orig bleiben.
                      Da ich es aber bevorzugen würde, das nicht zu tun, hatte ich mir erhofft, es gibt auch andere Doku.

                      Deswegen hab ich gedacht, dass ich zu doof bin die richtige Doku zu finden.

                      ArmilarA Offline
                      ArmilarA Offline
                      Armilar
                      Most Active Forum Testing
                      wrote on last edited by
                      #365

                      @great-sun sagte in Sonoff NSPanel:

                      @armilar Evtl. habe ich mich nicht richtig ausgedrückt...

                      Dass das alles aus iobroker heraus aktiviert wird ist das eine, naja, ok, da muss ich dann mit leben...

                      Das nächste ist dann aber die Kommunikation. Ich möchte das gerne aufgrund der speziellen Anforderungen, die ich habe, alles selbst im Griff haben, weswegen ich keine "Middleware" zur Kommunikation mit dem Panel oder lovelace im ioBroker einsetzen möchte.
                      Ich würde gerne alle Daten weiterhin nur mit MQTT bekommen und dann auch direkt die Widgets aus meinem JavaScript aktualisieren können.
                      Eine Übersetzung des TypeScript auf JavaScript, damit ich die Widgets erstelle, sollte erstmal kein Problem sein.

                      Die Anleitungen scheinen mir aber alle recht speziell auf eine komplette Integration abzuzielen und sind scheinbar nicht dafür gedacht, dass jemand wie ich versteht, wie er selbst kommunizieren kann.

                      Conclusion wäre, wenn das so ist: Damit ich eine alternative Firmware einsetzen kann, muss ich mich durch deren oder den code der bestehenden Integrationen wälzen. Da mir das ohne Beistand wirklich zuviel ist, müsste ich dann doch bei der Orig bleiben.
                      Da ich es aber bevorzugen würde, das nicht zu tun, hatte ich mir erhofft, es gibt auch andere Doku.

                      Deswegen hab ich gedacht, dass ich zu doof bin die richtige Doku zu finden.

                      Nee, nicht falsch verstehen - ich habe "kein" lovelace auf meinem ioBroker am laufen. Da macht das NSPanel mit der Firmware von @joBr99
                      Mit zum Beispiel dem TypeScript was hier permanent auftaucht + der icons kannst du bereits alles steuern.

                      Reines Customizing in der TypeScript und @britzelpuf wird auch noch einen Adapter schreiben. Dann bauchst du auch kein TypeScript mehr und kannst die Config im Adapter machen.

                      Wie man das Panel flasht, haben wir ein paar Posts vorher schon aufgezeigt. Ebenso wie die Upgrades laufen

                      Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
                      https://github.com/joBr99/nspanel-lovelace-ui/wiki

                      Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                      Great SUNG 1 Reply Last reply
                      0
                      • D Dexxter

                        @armilar
                        Also das läuft für mich schon "fast" perfekt 😁
                        Das einzige Problem was ich jetzt noch habe ist das ich ja den Dimmerslider vom Hue Gerät begrenzen muss.
                        Und da dort ja schon minValue und maxValue für die Farbtemperatur vergeben sind wird das so ja nicht gehen.
                        Ich habe mal ein bisschen in Deinem Code rumgepfuscht ( sorry, ich hab da echt keine Ahnung von ) und versucht noch nen anderen Übergabewert hinein zu bekommen.
                        Der nennt sich dann
                        minValueBRI
                        und
                        maxValueBRI.
                        Sollte dann für den Brightnessslider im Hue Gerät sein und dort den Dimmwert begrenzen.
                        So wie ich das verpfuscht habe läuft das Script auch nicht.
                        Wenn Du mal herzlich lachen möchtest dann kannst Du Dir das ja mal anschauen.

                        var Icons = new IconsSelector();
                        
                        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 Off: RGB = { red: 68, green: 115, blue: 158 };
                        const On: RGB = { red: 253, green: 216, blue: 53 };
                        const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                        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 };
                        
                        
                        //----Möglichkeit, im Screensaver zwischen Accu-Weather Forecast oder selbstdefinierten Werten zu wählen---------------------------------
                        var weatherForecast = false; //true = WheatherForecast 5 Days --- false = Config --> firstScreensaverEntity - fourthScreensaverEntity ...
                        
                        //Alexa-Instanz
                        var alexaInstanz = "alexa2.0"
                        var alexaDevice = "G0XXXXXXXXXXXXXX"; //Primär zu steuendes Device
                        
                        // 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.NSPanel.1.popupNotifyHeading";
                        var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                        
                        var Test_Licht: PageEntities =
                        {
                            "type": "cardEntities",
                            "heading": "Büro",
                            "useColor": true,
                            "items": [
                                <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValue: 0, maxValue: 70},
                                <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Light-CT"},
                                <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Light-Color", minValue: 500, maxValue: 6500}
                            ]
                        };
                        
                        var Buero_Seite_1: PageEntities =
                        {
                            "type": "cardEntities",
                            "heading": "Büro",
                            "useColor": true,
                            "items": [
                                <PageItem>{ id: "alias.0.CTmitHUE", name: "Computer Decke", minValue: 500, maxValue: 6500, minValueBRI: 1, maxValueBRI: 70}, //HUE o.a. über --> Alias HUE mit CT ohne Color
                                <PageItem>{ id: "alias.0.COMPUTER_LED", name: "Computer Tisch", minValue: 0, maxValue: 70}, //Dimmer
                                <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                            ]
                        };
                        
                        var Fenster_1: PageEntities =
                        {
                            "type": "cardEntities",
                            "heading": "Fenster und Türen",
                            "useColor": true,
                            "items": [
                                <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                                <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                            ]
                        };
                        
                        var Abfall: PageEntities =
                        {
                            "type": "cardEntities",
                            "heading": "Abfallkalender",
                            "useColor": true,
                            "items": [
                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                            ]
                        };
                        
                        var Buero_Seite_2: PageGrid =
                        {
                            "type": "cardGrid",
                            "heading": "Büro 2",
                            "useColor": true,
                            "items": [
                                <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                                <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                                <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                            ]
                        };
                        
                        var Alexa: PageMedia = 
                        {
                            "type": "cardMedia",
                            "heading": "Alexa",
                            "useColor": true,
                            "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                        };
                        
                        var Buero_Themostat: PageThermo = 
                        {
                            "type": "cardThermo",
                            "heading": "Thermostat",
                            "useColor": true,
                            "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                        };
                        
                        var Buero_Alarm: PageAlarm = 
                        {
                            "type": "cardAlarm",
                            "heading": "Alarm",
                            "useColor": true,
                            "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                        };
                        
                        var button1Page: PageGrid =
                        {
                            "type": "cardGrid",
                            "heading": "Radio",
                            "useColor": true,
                            "items": [
                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                            ]
                        };
                        
                        var button2Page: PageEntities =
                        {
                            "type": "cardEntities",
                            "heading": "Büro",
                            "useColor": true,
                            "items": [
                                <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                            ]
                        };
                        
                        export const config: Config = {
                            panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT",       //anpassen
                            panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend",   //anpassen
                            firstScreensaverEntity: { ScreensaverEntity: "hm-rpc.0.000EDA4995B568.1.HUMIDITY", ScreensaverEntityIcon: "water-percent", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "%" },
                            secondScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.PRECIPITATION_CHANCE", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" },
                            thirdScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.Wind_SPEED", ScreensaverEntityIcon: "weather-windy", ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: "bft" },
                            fourthScreensaverEntity: { ScreensaverEntity: "accuweather.0.Current.UVIndex", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "UV", ScreensaverEntityUnitText: "" },
                            timeoutScreensaver: 5,
                            dimmode: 8,
                            screenSaverDoubleClick: false,
                            locale: "de_DE",
                            timeFormat: "%H:%M",
                            dateFormat: "%A, %d. %B %Y",
                            weatherEntity: "alias.0.Wetter",
                            defaultOffColor: Off,
                            defaultOnColor: On,
                            defaultColor: Off,
                            temperatureUnit: "°C",
                            pages: [
                                    Buero_Seite_1,
                                    //Test_Licht,
                                    Fenster_1,
                                    Abfall,
                                    //Buero_Seite_2,
                                    Alexa,
                                    Buero_Themostat,
                                    Buero_Alarm
                            ],
                            button1Page: button1Page,
                            button2Page: button2Page
                        };
                        
                        // _________________________________ 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;
                        
                        schedule("* * * * *", function () {
                            SendTime();
                        });
                        schedule("0 * * * *", function () {
                            SendDate();
                        });
                        
                        
                        // 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, function () {
                                HandleScreensaverUpdate();
                            })
                        }
                        on({ id: config.panelRecvTopic }, function (obj) {
                            if (obj.state.val.startsWith('\{"CustomRecv":')) {
                                var json = JSON.parse(obj.state.val);
                        
                                var split = json.CustomRecv.split(",");
                                HandleMessage(split[0], split[1], parseInt(split[2]), split);
                            }
                        });
                        
                        function SendToPanel(val: Payload | Payload[]): void {
                            if (Array.isArray(val)) {
                                val.forEach(function (id, i) {
                                    setState(config.panelSendTopic, id.payload);
                                });
                            }
                            else
                                setState(config.panelSendTopic, val.payload);
                        }
                        
                        function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                            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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                        if (pageItem !== undefined)
                                            SendToPanel(GenerateDetailPage(words[2], pageItem));
                                    case "buttonPress2":
                                        screensaverEnabled = false;
                                        HandleButtonEvent(words);
                                        break;
                                    case "button1":
                                    case "button2":
                                        screensaverEnabled = false;
                                        HandleHardwareButton(method);
                                    default:
                                        break;
                                }
                            }
                        }
                        
                        function GeneratePage(page: Page): void {
                            switch (page.type) {
                                case "cardEntities":
                                    SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                    break;
                                case "cardThermo":
                                    SendToPanel(GenerateThermoPage(<PageThermo>page));
                                    break;
                                case "cardGrid":
                                    SendToPanel(GenerateGridPage(<PageGrid>page));
                                    break;
                                case "cardMedia":
                                    SendToPanel(GenerateMediaPage(<PageMedia>page));
                                    break;
                                case "cardAlarm":
                                    SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                    break;
                            }
                        }
                        
                        function HandleHardwareButton(method: string): void {
                            let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                            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);
                        }
                        
                        function HandleStartupProcess(): void {
                            SendDate();
                            SendTime();
                            SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                            SendToPanel({ payload: "dimmode~" + config.dimmode });
                        }
                        
                        function SendDate(): void {
                            var d = new Date();
                            var day = Days[d.getDay()];
                            var date = d.getDate();
                            var month = Months[d.getMonth()];
                            var year = d.getFullYear();
                            var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                            SendToPanel(<Payload>{ payload: _sendDate });
                        }
                        
                        function SendTime(): void {
                            var d = new Date();
                            var hr = d.getHours().toString();
                            var min = d.getMinutes().toString();
                        
                            if (d.getHours() < 10) {
                                hr = "0" + d.getHours().toString();
                            }
                            if (d.getMinutes() < 10) {
                                min = "0" + d.getMinutes().toString();
                            }
                            SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                        }
                        
                        function GenerateEntitiesPage(page: PageEntities): Payload[] {
                            var out_msgs: Array<Payload> = [];
                            out_msgs = [{ payload: "pageType~cardEntities" }]
                            out_msgs.push({ payload: GeneratePageElements(page) });
                            return out_msgs
                        }
                        
                        function GenerateGridPage(page: PageGrid): Payload[] {
                            var out_msgs: Array<Payload> = [];
                            out_msgs = [{ payload: "pageType~cardGrid" }]
                            out_msgs.push({ payload: GeneratePageElements(page) });
                            return out_msgs
                        }
                        
                        function GeneratePageElements(page: Page): string {
                            let maxItems = 0;
                            switch (page.type) {
                                case "cardThermo":
                                    maxItems = 1;
                                    break;
                                case "cardAlarm":
                                    maxItems = 1;
                                    break;
                                case "cardMedia":
                                    maxItems = 1;
                                    break;
                                case "cardEntities":
                                    maxItems = 4;
                                    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);
                                }
                                else {
                                    pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                                }
                            }
                            return pageData;
                        }
                        
                        function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                            var iconId = "0"
                            if (pageItem.id == "delete") {
                                return "~delete~~~~~"
                            }
                            var name: string;
                            var type: string;
                        
                            // ioBroker
                            if (existsObject(pageItem.id)) {
                                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;
                                    RegisterEntityWatcher(pageItem.id + ".GET");
                                }
                                else if (existsState(pageItem.id + ".SET")) {
                                    val = getState(pageItem.id + ".SET").val;
                                    RegisterEntityWatcher(pageItem.id + ".SET");
                                }
                                var iconColor = rgb_dec565(config.defaultColor);
                        
                                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 optVal = "0"
                        
                                        if (val === true || val === "true") {
                                            optVal = "1"
                                            iconColor = GetIconColor(pageItem, true, useColors);
                                        } else {
                                            iconColor = GetIconColor(pageItem, false, useColors);
                                        }
                        
                                        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 + ".ON") ? getState(pageItem.id + ".ON").val : true, useColors);
                                        }
                        
                                        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") ? 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 = "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 = "closed"
                                            }
                                            RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                        }
                                        return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                        
                                    case "info":
                        
                                    case "humidity":
                        
                                    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 "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;
                        
                                    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~~~~~"
                        }
                        
                        function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                            // dimmer
                            if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") {
                                let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100;
                                let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0;
                        		let maxValueBRI = pageItem.maxValueBRI !== undefined ? pageItem.maxValueBRI : 100;
                                let minValueBRI = pageItem.minValueBRI !== undefined ? pageItem.minValueBRI : 0;
                                value = value > maxValue ? maxValue : value;
                                value = value < minValue ? minValue : value;
                        		value = value > maxValueBRI ? maxValueBRI : value;
                                value = value < minValueBRI ? minValueBRI : 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),
                        				scale(value, minValueBRI, maxValueBRI, 0, 1)
                                    ));
                            }
                        
                            if ((pageItem.useColor || useColors) && ((typeof (value) === "boolean" && value) || value > (pageItem.minValue !== undefined ? pageItem.minValue : 0))) {
                                return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor)
                            }
                            
                            return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor);
                        }
                        
                        function RegisterEntityWatcher(id: string): void {
                            if (subscriptions.hasOwnProperty(id)) {
                                return;
                            }
                            subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                                if(pageId >= 0)
                                    SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                                if(pageId == -1 && config.button1Page != undefined)
                                    SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                                if(pageId == -2 && config.button2Page != undefined)
                                    SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                            }))
                        }
                        
                        function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                            if (subscriptions.hasOwnProperty(id)) {
                                return;
                            }
                            subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                                SendToPanel(GenerateDetailPage(type, pageItem));
                            }))
                        }
                        
                        function GetUnitOfMeasurement(id: string): string {
                            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 "";
                        }
                        
                        function GenerateThermoPage(page: PageThermo): Payload[] {
                            var id = page.items[0].id
                            var out_msgs: Array<Payload> = [];
                            out_msgs.push({ payload: "pageType~cardThermo" });
                        
                            // ioBroker
                            if (existsObject(id)) {
                                let o = getObject(id)
                                let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                                let currentTemp = 0;
                                if (existsState(id + ".ACTUAL"))
                                    currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                        
                                let destTemp = 0;
                                if (existsState(id + ".SET")) {
                                    destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                                }
                        
                                let status = ""
                                if (existsState(id + ".MODE"))
                                    status = getState(id + ".MODE").val;
                                let minTemp = 50 //Min Temp 5°C
                                let maxTemp = 300 //Max Temp 30°C
                                let stepTemp = 5
                        
                                //0-4 verwendet bei ungerader Anzahl Parametern
                                let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                                let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                                let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                                let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                                let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                                //5-8 verwendet bei gerader Anzahl Parametern
                                let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                                let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                                let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                                let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                        
                                if (existsState(id + ".HUMIDITY")){
                                    bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                    if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                        bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                    } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                        bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                    } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                        bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                    } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                        bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                    }
                                }
                        
                                if (existsState(id + ".MAINTAIN")){
                                    if (getState(id + ".MAINTAIN").val >> .1) {
                                        bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                    } else {
                                        bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                    }
                                }
                        
                                if (existsState(id + ".UNREACH")){
                                    if (getState(id + ".UNREACH").val) {
                                        bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                    } else {
                                        bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                    }
                                }
                        
                                if (existsState(id + ".LOWBAT")){
                                    if (getState(id + ".LOWBAT").val) {
                                        bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                    } else {
                                        bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                    }
                                }
                        
                                let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                        
                                out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                            }
                        
                            return out_msgs
                        }
                        
                        function GenerateMediaPage(page: PageMedia): Payload[] {
                            var id = page.items[0].id
                            var out_msgs: Array<Payload> = [];
                            out_msgs.push({ payload: "pageType~cardMedia" });
                            if (existsObject(id)) {
                        
                                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;
                                let volume = getState(id + ".VOLUME").val;
                                var iconplaypause = Icons.GetIcon("pause"); //pause
                                var onoffbutton = 1374;
                                if (getState(id + ".STATE").val) {
                                    onoffbutton = 65535;
                                    iconplaypause = Icons.GetIcon("pause"); //pause
                                } else {
                                    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
                        // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                                let speakerlist = "";
                                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 && 
                                            existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                            existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                                speakerlist = speakerlist + getState(i).val + "?";
                                        }
                                    }
                                }
                                speakerlist = speakerlist.substring(0,speakerlist.length-1);
                        //--------------------------------------------------------------------------------------------------------------
                        
                                out_msgs.push({ payload: "entityUpd~" + 
                                                          name + "~" +
                                                          id + "~" +
                                                          id + "~" +         //????
                                                          media_icon + "~" +
                                                          title + "~" +
                                                          author + "~" +
                                                          volume + "~" +
                                                          iconplaypause + "~" +
                                                          currentSpeaker + "~" +
                                                          speakerlist + "~" +
                                                          onoffbutton});
                            }
                        
                            return out_msgs
                        }
                        
                        function GenerateAlarmPage(page: PageAlarm): Payload[] {
                            var id = page.items[0].id
                            var out_msgs: Array<Payload> = [];
                            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 = 1;                           //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 = 1;                           //flashing*        
                            }
                                
                            out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                        id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                        "~" +                      //???
                                                        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*
                        
                            return out_msgs
                        }
                        
                        function setIfExists(id: string, value: any, type: string | null = null): boolean {
                            if (type === null) {
                                if (existsState(id)) {
                                    setState(id, value);
                                    return true;
                                }
                            }
                            else {
                                let obj = getObject(id);
                                if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                    setState(id, value);
                                    return true;
                                }
                            }
                            return false;
                        }
                        
                        function toggleState(id: string): boolean {
                            let obj = getObject(id);
                            if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                                setState(id, !getState(id).val);
                                return true;
                            }
                            return false;
                        }
                        
                        function HandleButtonEvent(words): void {
                            let id = words[2]
                            let buttonAction = words[3];
                        
                            console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                        
                            switch (buttonAction) {
                                case "bNext":
                                    var pageNum = ((pageId + 1) % config.pages.length);
                                    pageId = Math.abs(pageNum);
                                    UnsubscribeWatcher();
                                    GeneratePage(config.pages[pageId]);
                                    break;
                                case "bPrev":
                                    var pageNum = ((pageId - 1) % config.pages.length);
                                    pageId = Math.abs(pageNum);
                                    UnsubscribeWatcher();
                                    GeneratePage(config.pages[pageId]);
                                    break;
                                case "bExit":
                                    if (config.screenSaverDoubleClick) {
                                        if (words[4] == 2)
                                            GeneratePage(config.pages[pageId]);
                                    }
                                    else
                                        GeneratePage(config.pages[pageId]);
                                    break;
                                case "OnOff":
                                    if (existsObject(id)) {
                                        var action = false
                                        if (words[4] == "1")
                                            action = true
                                        let o = getObject(id)
                                        switch (o.common.role) {
                                            case "light":
                                                setIfExists(id + ".SET", action);
                                                break;
                                            case "dimmer":
                                                setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                                break;
                                            case "hue": // Armilar
                                                setIfExists(id + ".ON_ACTUAL", action);
                                        }
                                    }
                                    break;
                                case "up":
                                    setIfExists(id + ".OPEN", true)
                                    break;
                                case "stop":
                                    setIfExists(id + ".STOP", true)
                                    break;
                                case "down":
                                    setIfExists(id + ".CLOSE", true)
                                    break;
                                case "button":
                                    toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                    break;
                                case "positionSlider":
                                    setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                    break;
                                case "brightnessSlider":
                                    if (existsObject(id)) {
                                        let o = getObject(id);
                                        let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                        switch (o.common.role) {
                                            case "dimmer":
                                                if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {  
                                                    let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValue, pageItem.minValue))
                                                    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 "hue":
                        					    if (pageItem.minValueBRI != undefined && pageItem.maxValueBRI != undefined) {  
                                                    let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValueBRI, pageItem.minValueBRI))
                                                    setIfExists(id + ".DIMMER", parseInt(words[4]));
                                        }
                                    }
                                    break;
                                case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                    let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                    if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                        let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValue, pageItem.maxValue));
                                        setIfExists(id + ".TEMPERATURE", (colorTempK));
                                    } else {
                                        setIfExists(id + ".TEMPERATURE", 100 - words[4]);
                                    }
                                    break;
                                case "colorWheel":
                                    let colorCoordinates = words[4].split('|');
                                    let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                    //console.log(rgb);
                                    //console.log(getHue(rgb.red, rgb.green, rgb.blue));
                                    setIfExists(id + ".HUE", getHue(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;
                                case "media-pause":
                                    if (getState(id + ".STATE").val === true) {
                                        setIfExists(id + ".PAUSE", true)
                                    } else {
                                        setIfExists(id + ".PLAY", true)
                                    }
                                    break;
                                case "media-next":
                                    setIfExists(id + ".NEXT", true)
                                    break;
                                case "volumeSlider":
                                    setIfExists(id + ".VOLUME", parseInt(words[4]))
                                    break;
                                case "speaker-sel":
                                    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];
                                        if ((getState(i).val) === words[4]){
                                            let deviceId = i;
                                            deviceId = deviceId.split('.');
                                            setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                            alexaDevice = deviceId[3]
                                        }
                                    }
                                    break;
                                case "media-OnOff":
                                    setIfExists(id + ".STOP", true)
                                    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:
                                    return "0|1";
                                case config.pages.length - 1:
                                    return "1|0";
                                case -1:
                                    return "0|0";
                                default:
                                    return "1|1";
                            }
                        }
                        
                        function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                        
                            var out_msgs: Array<Payload> = [];
                            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"
                                    if (o.common.role == "light") {
                                        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);
                                        }
                        
                                        if (val) {
                                            switchVal = "1";
                                            iconColor = GetIconColor(pageItem, true, false);
                                        }
                        
                                        out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                    }
                        
                                    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"
                                        }
                                        let brightness = 0;
                                        if (existsState(id + ".ACTUAL")) {
                                            if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {
                                                brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, pageItem.minValue, pageItem.maxValue, 100, 0));
                                            } else {
                                                brightness = getState(id + ".ACTUAL").val;
                                            }
                                        } else {
                                            console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                        }
                                        //iconColor = GetIconColor(pageItem, brightness, false);
                                        //Farbe muss noch korrekt ermittelt werden
                                        if (val === true) {
                                            iconColor = GetIconColor(pageItem, true, true);
                                            switchVal = "1";
                                        } else {
                                            iconColor = GetIconColor(pageItem, false, true);
                                        }
                        
                                        RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                        
                                        let colorTemp = "disable"
                                        let colorMode = "disable"
                                        //let attr_support_color = attr.supported_color_modes
                                        //if (attr_support_color.includes("color_temp"))
                                        // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                                        out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                    }
                        
                                    if (o.common.role == "hue") {
                                        if (existsState(id + ".ON_ACTUAL")) {
                                            val = getState(id + ".ON_ACTUAL").val;
                                            RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type);
                                        }
                        
                                        //Farbe muss noch korrekt ermittelt werden
                                        if (val === true) {
                                            iconColor = GetIconColor(pageItem, true, true);
                                            switchVal = "1";
                                        } else {
                                            iconColor = GetIconColor(pageItem, false, true);
                                        }
                        
                                        let brightness = 0;
                                        if (existsState(id + ".DIMMER")) {
                        					if (pageItem.minValueBRI !== undefined && pageItem.minValueBRI !== undefined) {
                                            brightness = Math.trunc(scale2(getState(id + ".DIMMER").val, 0, 100, 0, 100));
                                            RegisterDetailEntityWatcher(id + ".DIMMER", pageItem, type);
                                        } else {
                                            console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                        }
                        
                                        var colorMode = "disable";
                                        if (existsState(id + ".HUE")) {
                                            if (getState(id + ".HUE").val != null)
                                                colorMode = "enable";  
                                        }
                        
                                        var colorTemp = 0;
                                        if (existsState(id + ".TEMPERATURE")) {
                                            if (getState(id + ".TEMPERATURE").val != null) {
                        
                                                if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                                    colorTemp = Math.trunc(scale(getState(id + ".TEMPERATURE").val, pageItem.minValue, pageItem.maxValue, 0, 100));
                                                } else {
                                                    colorTemp = 100 - getState(id + ".TEMPERATURE").val;
                                                }
                                                RegisterDetailEntityWatcher(id + ".TEMPERATURE", pageItem, type);
                                            } 
                                        }
                        
                                        //let attr_support_color = attr.supported_color_modes
                                        //if (attr_support_color.includes("color_temp"))
                                        //let colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                        
                                        out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                    }
                        
                                }
                        
                                if (type == "popupShutter") {
                                    if (existsState(id + ".ACTUAL")) {
                                        val = getState(id + ".ACTUAL").val;
                                        RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                        console.log(val);
                                    } else if (existsState(id + ".SET")) {
                                        val = getState(id + ".SET").val;
                                        RegisterDetailEntityWatcher(id + ".SET", pageItem, type);
                                        console.log(val);
                                    }
                                    out_msgs.push({ payload: "entityUpdateDetail~" + val })
                                }
                            }
                            return out_msgs
                        }
                        
                        function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                            return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                        }
                        
                        function scale2(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                            return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
                        }
                        
                        function UnsubscribeWatcher(): void {
                            for (const [key, value] of Object.entries(subscriptions)) {
                                unsubscribe(value);
                                delete subscriptions[key]
                            }
                        }
                        
                        function HandleScreensaver(): void {
                            SendToPanel({ payload: "pageType~screensaver"})
                            UnsubscribeWatcher();
                            HandleScreensaverUpdate();
                        }
                        
                        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++) {
                                        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);
                                        payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                    }
                                } 
                                else {
                                    //In Config definierte Zustände wenn weatherForecast = false
                                    payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                    payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                    payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                    payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                                }
                        /*-------------------------------------------------------------------------------------------------------------------------------------*/
                         
                                SendToPanel(<Payload>{ payload: payloadString });
                            }
                        }
                        
                        function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                            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 "~~~";
                            }
                        }
                        
                        function GetAccuWeatherIcon(icon: number): string {
                            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";
                            }
                        }
                        
                        function sleep(milliseconds) {
                          const date = Date.now();
                          let currentDate = null;
                          do {
                            currentDate = Date.now();
                          } while (currentDate - date < milliseconds);
                        }
                        
                        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 <RGB>{ 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)));
                        }
                        
                        /* 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;
                        }
                        
                        /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                        }
                        
                        type RGB = {
                            red: number,
                            green: number,
                            blue: number
                        };
                        
                        type Payload = {
                            payload: string;
                        };
                        
                        type Page = {
                            type: string,
                            heading: string,
                            items: PageItem[],
                            useColor: boolean
                        };
                        
                        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[],
                        };
                        
                        type PageItem = {
                            id: string,
                            icon: (string | undefined),
                            onColor: (RGB | undefined),
                            offColor: (RGB | undefined),
                            useColor: (boolean | undefined),
                            interpolateColor: (boolean | undefined),
                            minValue: (number | undefined),
                            maxValue: (number | undefined),
                            name: (string | undefined),
                            unit: (string | undefined)
                        }
                        
                        type Config = {
                            panelRecvTopic: string,
                            panelSendTopic: string,
                            timeoutScreensaver: number,
                            dimmode: number,
                            //brightnessScreensaver:
                            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,
                            defaultColor: RGB,
                            defaultOnColor: RGB,
                            defaultOffColor: RGB,
                            pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                            button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                            button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                        };
                        
                        type ScreenSaverElement = {
                            ScreensaverEntity: string | null,
                            ScreensaverEntityIcon: string | null,
                            ScreensaverEntityText: string | null,
                            ScreensaverEntityUnitText: string | null,
                        }
                        
                        ArmilarA Offline
                        ArmilarA Offline
                        Armilar
                        Most Active Forum Testing
                        wrote on last edited by
                        #366

                        @dexxter sehe ich mir morgen mal an. Musste mal die Stadt verlassen 😉 und bin nur noch mobil

                        Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
                        https://github.com/joBr99/nspanel-lovelace-ui/wiki

                        Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                        D 1 Reply Last reply
                        0
                        • ArmilarA Armilar

                          @dexxter sehe ich mir morgen mal an. Musste mal die Stadt verlassen 😉 und bin nur noch mobil

                          D Offline
                          D Offline
                          Dexxter
                          wrote on last edited by
                          #367

                          @armilar
                          Alles klar, dann wünsch ich Dir mal noch einen schönen RestSonntag 😊

                          1 Reply Last reply
                          0
                          • ArmilarA Armilar

                            @great-sun sagte in Sonoff NSPanel:

                            @armilar Evtl. habe ich mich nicht richtig ausgedrückt...

                            Dass das alles aus iobroker heraus aktiviert wird ist das eine, naja, ok, da muss ich dann mit leben...

                            Das nächste ist dann aber die Kommunikation. Ich möchte das gerne aufgrund der speziellen Anforderungen, die ich habe, alles selbst im Griff haben, weswegen ich keine "Middleware" zur Kommunikation mit dem Panel oder lovelace im ioBroker einsetzen möchte.
                            Ich würde gerne alle Daten weiterhin nur mit MQTT bekommen und dann auch direkt die Widgets aus meinem JavaScript aktualisieren können.
                            Eine Übersetzung des TypeScript auf JavaScript, damit ich die Widgets erstelle, sollte erstmal kein Problem sein.

                            Die Anleitungen scheinen mir aber alle recht speziell auf eine komplette Integration abzuzielen und sind scheinbar nicht dafür gedacht, dass jemand wie ich versteht, wie er selbst kommunizieren kann.

                            Conclusion wäre, wenn das so ist: Damit ich eine alternative Firmware einsetzen kann, muss ich mich durch deren oder den code der bestehenden Integrationen wälzen. Da mir das ohne Beistand wirklich zuviel ist, müsste ich dann doch bei der Orig bleiben.
                            Da ich es aber bevorzugen würde, das nicht zu tun, hatte ich mir erhofft, es gibt auch andere Doku.

                            Deswegen hab ich gedacht, dass ich zu doof bin die richtige Doku zu finden.

                            Nee, nicht falsch verstehen - ich habe "kein" lovelace auf meinem ioBroker am laufen. Da macht das NSPanel mit der Firmware von @joBr99
                            Mit zum Beispiel dem TypeScript was hier permanent auftaucht + der icons kannst du bereits alles steuern.

                            Reines Customizing in der TypeScript und @britzelpuf wird auch noch einen Adapter schreiben. Dann bauchst du auch kein TypeScript mehr und kannst die Config im Adapter machen.

                            Wie man das Panel flasht, haben wir ein paar Posts vorher schon aufgezeigt. Ebenso wie die Upgrades laufen

                            Great SUNG Offline
                            Great SUNG Offline
                            Great SUN
                            wrote on last edited by Great SUN
                            #368

                            @armilar @joBr99 : OK, also... ich hab jetzt alles soweit fertig gemacht, aber ich komme zu einem Problem, das vielleicht auch keines ist..

                            15:49:23.163 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 0, "time_elapsed": 0}}
                            15:49:28.010 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 1, "time_elapsed": 5}}
                            15:49:32.434 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 2, "time_elapsed": 9}}
                            15:49:37.691 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 3, "time_elapsed": 14}}
                            15:50:13.769 MQT: tele/tasmota_0CD9C0/STATE = {"Time":"2022-04-24T15:50:13","Uptime":"0T00:15:09","UptimeSec":909,"Heap":166,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":20,"MqttCount":1,"Berry":{"HeapUsed":14,"Objects":223},"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SVGCast2","BSSId":"F0:2F:74:55:CF:E0","Channel":10,"Mode":"11n","RSSI":100,"Signal":-46,"LinkCount":1,"Downtime":"0T00:00:03"}}
                            15:50:13.782 MQT: tele/tasmota_0CD9C0/SENSOR = {"Time":"2022-04-24T15:50:13","ANALOG":{"Temperature1":2.0},"ESP32":{"Temperature":38.9},"TempUnit":"C"}
                            15:55:13.761 MQT: tele/tasmota_0CD9C0/STATE = {"Time":"2022-04-24T15:55:13","Uptime":"0T00:20:09","UptimeSec":1209,"Heap":166,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":20,"MqttCount":1,"Berry":{"HeapUsed":14,"Objects":223},"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SVGCast2","BSSId":"F0:2F:74:55:CF:E0","Channel":10,"Mode":"11n","RSSI":100,"Signal":-50,"LinkCount":1,"Downtime":"0T00:00:03"}}
                            15:55:13.781 MQT: tele/tasmota_0CD9C0/SENSOR = {"Time":"2022-04-24T15:55:13","ANALOG":{"Temperature1":2.4},"ESP32":{"Temperature":38.3},"TempUnit":"C"}
                            

                            Ist das normal, dass der nach 3 % dann ewig braucht, bis er wieder was von sich gibt?
                            Der steht jetzt bei etwa 10min auf den 3%...

                            Die Tasmota Console reagiert aber noch, Status0 funktioniert und kommt zurück.

                            Great SUNG 1 Reply Last reply
                            0
                            • Great SUNG Great SUN

                              @armilar @joBr99 : OK, also... ich hab jetzt alles soweit fertig gemacht, aber ich komme zu einem Problem, das vielleicht auch keines ist..

                              15:49:23.163 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 0, "time_elapsed": 0}}
                              15:49:28.010 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 1, "time_elapsed": 5}}
                              15:49:32.434 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 2, "time_elapsed": 9}}
                              15:49:37.691 MQT: tele/tasmota_0CD9C0/RESULT = {"Flashing":{"complete": 3, "time_elapsed": 14}}
                              15:50:13.769 MQT: tele/tasmota_0CD9C0/STATE = {"Time":"2022-04-24T15:50:13","Uptime":"0T00:15:09","UptimeSec":909,"Heap":166,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":20,"MqttCount":1,"Berry":{"HeapUsed":14,"Objects":223},"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SVGCast2","BSSId":"F0:2F:74:55:CF:E0","Channel":10,"Mode":"11n","RSSI":100,"Signal":-46,"LinkCount":1,"Downtime":"0T00:00:03"}}
                              15:50:13.782 MQT: tele/tasmota_0CD9C0/SENSOR = {"Time":"2022-04-24T15:50:13","ANALOG":{"Temperature1":2.0},"ESP32":{"Temperature":38.9},"TempUnit":"C"}
                              15:55:13.761 MQT: tele/tasmota_0CD9C0/STATE = {"Time":"2022-04-24T15:55:13","Uptime":"0T00:20:09","UptimeSec":1209,"Heap":166,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":20,"MqttCount":1,"Berry":{"HeapUsed":14,"Objects":223},"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"SVGCast2","BSSId":"F0:2F:74:55:CF:E0","Channel":10,"Mode":"11n","RSSI":100,"Signal":-50,"LinkCount":1,"Downtime":"0T00:00:03"}}
                              15:55:13.781 MQT: tele/tasmota_0CD9C0/SENSOR = {"Time":"2022-04-24T15:55:13","ANALOG":{"Temperature1":2.4},"ESP32":{"Temperature":38.3},"TempUnit":"C"}
                              

                              Ist das normal, dass der nach 3 % dann ewig braucht, bis er wieder was von sich gibt?
                              Der steht jetzt bei etwa 10min auf den 3%...

                              Die Tasmota Console reagiert aber noch, Status0 funktioniert und kommt zurück.

                              Great SUNG Offline
                              Great SUNG Offline
                              Great SUN
                              wrote on last edited by
                              #369

                              Also, da geht gar nichts mehr. Nicht einmal ein Reset 😞

                              Jemand ne Ahnung, wie ich das wieder unbricked bekomme?

                              ArmilarA 1 Reply Last reply
                              0
                              • Great SUNG Great SUN

                                Also, da geht gar nichts mehr. Nicht einmal ein Reset 😞

                                Jemand ne Ahnung, wie ich das wieder unbricked bekomme?

                                ArmilarA Offline
                                ArmilarA Offline
                                Armilar
                                Most Active Forum Testing
                                wrote on last edited by Armilar
                                #370

                                @great-sun sagte in Sonoff NSPanel:

                                Also, da geht gar nichts mehr. Nicht einmal ein Reset 😞

                                Jemand ne Ahnung, wie ich das wieder unbricked bekomme?

                                um 17:00 Uhr war die Tasmota-Konsole noch da - ist das immer noch so?
                                Falls ja,

                                • lösch mal in "Verwalte Dateisystem" (Tasmota Konsolen) alle Files raus. autoexec.be/bec
                                • lege die "autoexec.be": https://github.com/joBr99/nspanel-lovelace-ui/blob/main/tasmota/autoexec.be neu an
                                • "FlashNextion http://nspanel.pky.eu/lui.tft" in der Tasmota Konsole ausführen

                                Falls nein, (dann ist dein Tasmota wohl hin; Der ESP32 wird sicher noch okay sein)

                                • Panel neu mit Tasmota tasmota32-nspanel.bin neu flashen
                                • die 3 Punkte unter "Falls ja" ausführen

                                Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
                                https://github.com/joBr99/nspanel-lovelace-ui/wiki

                                Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                                Great SUNG 2 Replies Last reply
                                0
                                • ArmilarA Armilar

                                  @great-sun sagte in Sonoff NSPanel:

                                  Also, da geht gar nichts mehr. Nicht einmal ein Reset 😞

                                  Jemand ne Ahnung, wie ich das wieder unbricked bekomme?

                                  um 17:00 Uhr war die Tasmota-Konsole noch da - ist das immer noch so?
                                  Falls ja,

                                  • lösch mal in "Verwalte Dateisystem" (Tasmota Konsolen) alle Files raus. autoexec.be/bec
                                  • lege die "autoexec.be": https://github.com/joBr99/nspanel-lovelace-ui/blob/main/tasmota/autoexec.be neu an
                                  • "FlashNextion http://nspanel.pky.eu/lui.tft" in der Tasmota Konsole ausführen

                                  Falls nein, (dann ist dein Tasmota wohl hin; Der ESP32 wird sicher noch okay sein)

                                  • Panel neu mit Tasmota tasmota32-nspanel.bin neu flashen
                                  • die 3 Punkte unter "Falls ja" ausführen
                                  Great SUNG Offline
                                  Great SUNG Offline
                                  Great SUN
                                  wrote on last edited by
                                  #371

                                  @armilar Tasmota ist alles noch da. Mach ich dann heute Abend oder so mal.

                                  Vielen lieben Dank!

                                  1 Reply Last reply
                                  0
                                  • D Dexxter

                                    @armilar
                                    Also das läuft für mich schon "fast" perfekt 😁
                                    Das einzige Problem was ich jetzt noch habe ist das ich ja den Dimmerslider vom Hue Gerät begrenzen muss.
                                    Und da dort ja schon minValue und maxValue für die Farbtemperatur vergeben sind wird das so ja nicht gehen.
                                    Ich habe mal ein bisschen in Deinem Code rumgepfuscht ( sorry, ich hab da echt keine Ahnung von ) und versucht noch nen anderen Übergabewert hinein zu bekommen.
                                    Der nennt sich dann
                                    minValueBRI
                                    und
                                    maxValueBRI.
                                    Sollte dann für den Brightnessslider im Hue Gerät sein und dort den Dimmwert begrenzen.
                                    So wie ich das verpfuscht habe läuft das Script auch nicht.
                                    Wenn Du mal herzlich lachen möchtest dann kannst Du Dir das ja mal anschauen.

                                    var Icons = new IconsSelector();
                                    
                                    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 Off: RGB = { red: 68, green: 115, blue: 158 };
                                    const On: RGB = { red: 253, green: 216, blue: 53 };
                                    const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                                    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 };
                                    
                                    
                                    //----Möglichkeit, im Screensaver zwischen Accu-Weather Forecast oder selbstdefinierten Werten zu wählen---------------------------------
                                    var weatherForecast = false; //true = WheatherForecast 5 Days --- false = Config --> firstScreensaverEntity - fourthScreensaverEntity ...
                                    
                                    //Alexa-Instanz
                                    var alexaInstanz = "alexa2.0"
                                    var alexaDevice = "G0XXXXXXXXXXXXXX"; //Primär zu steuendes Device
                                    
                                    // 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.NSPanel.1.popupNotifyHeading";
                                    var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                                    
                                    var Test_Licht: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Büro",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValue: 0, maxValue: 70},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Light-CT"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Light-Color", minValue: 500, maxValue: 6500}
                                        ]
                                    };
                                    
                                    var Buero_Seite_1: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Büro",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.CTmitHUE", name: "Computer Decke", minValue: 500, maxValue: 6500, minValueBRI: 1, maxValueBRI: 70}, //HUE o.a. über --> Alias HUE mit CT ohne Color
                                            <PageItem>{ id: "alias.0.COMPUTER_LED", name: "Computer Tisch", minValue: 0, maxValue: 70}, //Dimmer
                                            <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                                        ]
                                    };
                                    
                                    var Fenster_1: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Fenster und Türen",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                                        ]
                                    };
                                    
                                    var Abfall: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Abfallkalender",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                                        ]
                                    };
                                    
                                    var Buero_Seite_2: PageGrid =
                                    {
                                        "type": "cardGrid",
                                        "heading": "Büro 2",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                                        ]
                                    };
                                    
                                    var Alexa: PageMedia = 
                                    {
                                        "type": "cardMedia",
                                        "heading": "Alexa",
                                        "useColor": true,
                                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                                    };
                                    
                                    var Buero_Themostat: PageThermo = 
                                    {
                                        "type": "cardThermo",
                                        "heading": "Thermostat",
                                        "useColor": true,
                                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                                    };
                                    
                                    var Buero_Alarm: PageAlarm = 
                                    {
                                        "type": "cardAlarm",
                                        "heading": "Alarm",
                                        "useColor": true,
                                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                                    };
                                    
                                    var button1Page: PageGrid =
                                    {
                                        "type": "cardGrid",
                                        "heading": "Radio",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                                        ]
                                    };
                                    
                                    var button2Page: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Büro",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                                        ]
                                    };
                                    
                                    export const config: Config = {
                                        panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT",       //anpassen
                                        panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend",   //anpassen
                                        firstScreensaverEntity: { ScreensaverEntity: "hm-rpc.0.000EDA4995B568.1.HUMIDITY", ScreensaverEntityIcon: "water-percent", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "%" },
                                        secondScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.PRECIPITATION_CHANCE", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" },
                                        thirdScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.Wind_SPEED", ScreensaverEntityIcon: "weather-windy", ScreensaverEntityText: "Wind", ScreensaverEntityUnitText: "bft" },
                                        fourthScreensaverEntity: { ScreensaverEntity: "accuweather.0.Current.UVIndex", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "UV", ScreensaverEntityUnitText: "" },
                                        timeoutScreensaver: 5,
                                        dimmode: 8,
                                        screenSaverDoubleClick: false,
                                        locale: "de_DE",
                                        timeFormat: "%H:%M",
                                        dateFormat: "%A, %d. %B %Y",
                                        weatherEntity: "alias.0.Wetter",
                                        defaultOffColor: Off,
                                        defaultOnColor: On,
                                        defaultColor: Off,
                                        temperatureUnit: "°C",
                                        pages: [
                                                Buero_Seite_1,
                                                //Test_Licht,
                                                Fenster_1,
                                                Abfall,
                                                //Buero_Seite_2,
                                                Alexa,
                                                Buero_Themostat,
                                                Buero_Alarm
                                        ],
                                        button1Page: button1Page,
                                        button2Page: button2Page
                                    };
                                    
                                    // _________________________________ 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;
                                    
                                    schedule("* * * * *", function () {
                                        SendTime();
                                    });
                                    schedule("0 * * * *", function () {
                                        SendDate();
                                    });
                                    
                                    
                                    // 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, function () {
                                            HandleScreensaverUpdate();
                                        })
                                    }
                                    on({ id: config.panelRecvTopic }, function (obj) {
                                        if (obj.state.val.startsWith('\{"CustomRecv":')) {
                                            var json = JSON.parse(obj.state.val);
                                    
                                            var split = json.CustomRecv.split(",");
                                            HandleMessage(split[0], split[1], parseInt(split[2]), split);
                                        }
                                    });
                                    
                                    function SendToPanel(val: Payload | Payload[]): void {
                                        if (Array.isArray(val)) {
                                            val.forEach(function (id, i) {
                                                setState(config.panelSendTopic, id.payload);
                                            });
                                        }
                                        else
                                            setState(config.panelSendTopic, val.payload);
                                    }
                                    
                                    function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                                        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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                                    if (pageItem !== undefined)
                                                        SendToPanel(GenerateDetailPage(words[2], pageItem));
                                                case "buttonPress2":
                                                    screensaverEnabled = false;
                                                    HandleButtonEvent(words);
                                                    break;
                                                case "button1":
                                                case "button2":
                                                    screensaverEnabled = false;
                                                    HandleHardwareButton(method);
                                                default:
                                                    break;
                                            }
                                        }
                                    }
                                    
                                    function GeneratePage(page: Page): void {
                                        switch (page.type) {
                                            case "cardEntities":
                                                SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                                break;
                                            case "cardThermo":
                                                SendToPanel(GenerateThermoPage(<PageThermo>page));
                                                break;
                                            case "cardGrid":
                                                SendToPanel(GenerateGridPage(<PageGrid>page));
                                                break;
                                            case "cardMedia":
                                                SendToPanel(GenerateMediaPage(<PageMedia>page));
                                                break;
                                            case "cardAlarm":
                                                SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                                break;
                                        }
                                    }
                                    
                                    function HandleHardwareButton(method: string): void {
                                        let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                                        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);
                                    }
                                    
                                    function HandleStartupProcess(): void {
                                        SendDate();
                                        SendTime();
                                        SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                                        SendToPanel({ payload: "dimmode~" + config.dimmode });
                                    }
                                    
                                    function SendDate(): void {
                                        var d = new Date();
                                        var day = Days[d.getDay()];
                                        var date = d.getDate();
                                        var month = Months[d.getMonth()];
                                        var year = d.getFullYear();
                                        var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                                        SendToPanel(<Payload>{ payload: _sendDate });
                                    }
                                    
                                    function SendTime(): void {
                                        var d = new Date();
                                        var hr = d.getHours().toString();
                                        var min = d.getMinutes().toString();
                                    
                                        if (d.getHours() < 10) {
                                            hr = "0" + d.getHours().toString();
                                        }
                                        if (d.getMinutes() < 10) {
                                            min = "0" + d.getMinutes().toString();
                                        }
                                        SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                                    }
                                    
                                    function GenerateEntitiesPage(page: PageEntities): Payload[] {
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs = [{ payload: "pageType~cardEntities" }]
                                        out_msgs.push({ payload: GeneratePageElements(page) });
                                        return out_msgs
                                    }
                                    
                                    function GenerateGridPage(page: PageGrid): Payload[] {
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs = [{ payload: "pageType~cardGrid" }]
                                        out_msgs.push({ payload: GeneratePageElements(page) });
                                        return out_msgs
                                    }
                                    
                                    function GeneratePageElements(page: Page): string {
                                        let maxItems = 0;
                                        switch (page.type) {
                                            case "cardThermo":
                                                maxItems = 1;
                                                break;
                                            case "cardAlarm":
                                                maxItems = 1;
                                                break;
                                            case "cardMedia":
                                                maxItems = 1;
                                                break;
                                            case "cardEntities":
                                                maxItems = 4;
                                                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);
                                            }
                                            else {
                                                pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                                            }
                                        }
                                        return pageData;
                                    }
                                    
                                    function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                                        var iconId = "0"
                                        if (pageItem.id == "delete") {
                                            return "~delete~~~~~"
                                        }
                                        var name: string;
                                        var type: string;
                                    
                                        // ioBroker
                                        if (existsObject(pageItem.id)) {
                                            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;
                                                RegisterEntityWatcher(pageItem.id + ".GET");
                                            }
                                            else if (existsState(pageItem.id + ".SET")) {
                                                val = getState(pageItem.id + ".SET").val;
                                                RegisterEntityWatcher(pageItem.id + ".SET");
                                            }
                                            var iconColor = rgb_dec565(config.defaultColor);
                                    
                                            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 optVal = "0"
                                    
                                                    if (val === true || val === "true") {
                                                        optVal = "1"
                                                        iconColor = GetIconColor(pageItem, true, useColors);
                                                    } else {
                                                        iconColor = GetIconColor(pageItem, false, useColors);
                                                    }
                                    
                                                    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 + ".ON") ? getState(pageItem.id + ".ON").val : true, useColors);
                                                    }
                                    
                                                    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") ? 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 = "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 = "closed"
                                                        }
                                                        RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                                    }
                                                    return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                                    
                                                case "info":
                                    
                                                case "humidity":
                                    
                                                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 "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;
                                    
                                                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~~~~~"
                                    }
                                    
                                    function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                                        // dimmer
                                        if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") {
                                            let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100;
                                            let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0;
                                    		let maxValueBRI = pageItem.maxValueBRI !== undefined ? pageItem.maxValueBRI : 100;
                                            let minValueBRI = pageItem.minValueBRI !== undefined ? pageItem.minValueBRI : 0;
                                            value = value > maxValue ? maxValue : value;
                                            value = value < minValue ? minValue : value;
                                    		value = value > maxValueBRI ? maxValueBRI : value;
                                            value = value < minValueBRI ? minValueBRI : 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),
                                    				scale(value, minValueBRI, maxValueBRI, 0, 1)
                                                ));
                                        }
                                    
                                        if ((pageItem.useColor || useColors) && ((typeof (value) === "boolean" && value) || value > (pageItem.minValue !== undefined ? pageItem.minValue : 0))) {
                                            return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor)
                                        }
                                        
                                        return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor);
                                    }
                                    
                                    function RegisterEntityWatcher(id: string): void {
                                        if (subscriptions.hasOwnProperty(id)) {
                                            return;
                                        }
                                        subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                                            if(pageId >= 0)
                                                SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                                            if(pageId == -1 && config.button1Page != undefined)
                                                SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                                            if(pageId == -2 && config.button2Page != undefined)
                                                SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                                        }))
                                    }
                                    
                                    function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                                        if (subscriptions.hasOwnProperty(id)) {
                                            return;
                                        }
                                        subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                                            SendToPanel(GenerateDetailPage(type, pageItem));
                                        }))
                                    }
                                    
                                    function GetUnitOfMeasurement(id: string): string {
                                        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 "";
                                    }
                                    
                                    function GenerateThermoPage(page: PageThermo): Payload[] {
                                        var id = page.items[0].id
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs.push({ payload: "pageType~cardThermo" });
                                    
                                        // ioBroker
                                        if (existsObject(id)) {
                                            let o = getObject(id)
                                            let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                                            let currentTemp = 0;
                                            if (existsState(id + ".ACTUAL"))
                                                currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                                    
                                            let destTemp = 0;
                                            if (existsState(id + ".SET")) {
                                                destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                                            }
                                    
                                            let status = ""
                                            if (existsState(id + ".MODE"))
                                                status = getState(id + ".MODE").val;
                                            let minTemp = 50 //Min Temp 5°C
                                            let maxTemp = 300 //Max Temp 30°C
                                            let stepTemp = 5
                                    
                                            //0-4 verwendet bei ungerader Anzahl Parametern
                                            let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                                            //5-8 verwendet bei gerader Anzahl Parametern
                                            let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                                            let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                                            let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                                            let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                                    
                                            if (existsState(id + ".HUMIDITY")){
                                                bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                                if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                }
                                            }
                                    
                                            if (existsState(id + ".MAINTAIN")){
                                                if (getState(id + ".MAINTAIN").val >> .1) {
                                                    bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                                } else {
                                                    bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                                }
                                            }
                                    
                                            if (existsState(id + ".UNREACH")){
                                                if (getState(id + ".UNREACH").val) {
                                                    bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                                } else {
                                                    bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                                }
                                            }
                                    
                                            if (existsState(id + ".LOWBAT")){
                                                if (getState(id + ".LOWBAT").val) {
                                                    bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                                } else {
                                                    bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                                }
                                            }
                                    
                                            let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                                    
                                            out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                                        }
                                    
                                        return out_msgs
                                    }
                                    
                                    function GenerateMediaPage(page: PageMedia): Payload[] {
                                        var id = page.items[0].id
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs.push({ payload: "pageType~cardMedia" });
                                        if (existsObject(id)) {
                                    
                                            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;
                                            let volume = getState(id + ".VOLUME").val;
                                            var iconplaypause = Icons.GetIcon("pause"); //pause
                                            var onoffbutton = 1374;
                                            if (getState(id + ".STATE").val) {
                                                onoffbutton = 65535;
                                                iconplaypause = Icons.GetIcon("pause"); //pause
                                            } else {
                                                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
                                    // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                                            let speakerlist = "";
                                            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 && 
                                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                                            speakerlist = speakerlist + getState(i).val + "?";
                                                    }
                                                }
                                            }
                                            speakerlist = speakerlist.substring(0,speakerlist.length-1);
                                    //--------------------------------------------------------------------------------------------------------------
                                    
                                            out_msgs.push({ payload: "entityUpd~" + 
                                                                      name + "~" +
                                                                      id + "~" +
                                                                      id + "~" +         //????
                                                                      media_icon + "~" +
                                                                      title + "~" +
                                                                      author + "~" +
                                                                      volume + "~" +
                                                                      iconplaypause + "~" +
                                                                      currentSpeaker + "~" +
                                                                      speakerlist + "~" +
                                                                      onoffbutton});
                                        }
                                    
                                        return out_msgs
                                    }
                                    
                                    function GenerateAlarmPage(page: PageAlarm): Payload[] {
                                        var id = page.items[0].id
                                        var out_msgs: Array<Payload> = [];
                                        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 = 1;                           //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 = 1;                           //flashing*        
                                        }
                                            
                                        out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                                    id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                                    "~" +                      //???
                                                                    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*
                                    
                                        return out_msgs
                                    }
                                    
                                    function setIfExists(id: string, value: any, type: string | null = null): boolean {
                                        if (type === null) {
                                            if (existsState(id)) {
                                                setState(id, value);
                                                return true;
                                            }
                                        }
                                        else {
                                            let obj = getObject(id);
                                            if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                                setState(id, value);
                                                return true;
                                            }
                                        }
                                        return false;
                                    }
                                    
                                    function toggleState(id: string): boolean {
                                        let obj = getObject(id);
                                        if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                                            setState(id, !getState(id).val);
                                            return true;
                                        }
                                        return false;
                                    }
                                    
                                    function HandleButtonEvent(words): void {
                                        let id = words[2]
                                        let buttonAction = words[3];
                                    
                                        console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                                    
                                        switch (buttonAction) {
                                            case "bNext":
                                                var pageNum = ((pageId + 1) % config.pages.length);
                                                pageId = Math.abs(pageNum);
                                                UnsubscribeWatcher();
                                                GeneratePage(config.pages[pageId]);
                                                break;
                                            case "bPrev":
                                                var pageNum = ((pageId - 1) % config.pages.length);
                                                pageId = Math.abs(pageNum);
                                                UnsubscribeWatcher();
                                                GeneratePage(config.pages[pageId]);
                                                break;
                                            case "bExit":
                                                if (config.screenSaverDoubleClick) {
                                                    if (words[4] == 2)
                                                        GeneratePage(config.pages[pageId]);
                                                }
                                                else
                                                    GeneratePage(config.pages[pageId]);
                                                break;
                                            case "OnOff":
                                                if (existsObject(id)) {
                                                    var action = false
                                                    if (words[4] == "1")
                                                        action = true
                                                    let o = getObject(id)
                                                    switch (o.common.role) {
                                                        case "light":
                                                            setIfExists(id + ".SET", action);
                                                            break;
                                                        case "dimmer":
                                                            setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                                            break;
                                                        case "hue": // Armilar
                                                            setIfExists(id + ".ON_ACTUAL", action);
                                                    }
                                                }
                                                break;
                                            case "up":
                                                setIfExists(id + ".OPEN", true)
                                                break;
                                            case "stop":
                                                setIfExists(id + ".STOP", true)
                                                break;
                                            case "down":
                                                setIfExists(id + ".CLOSE", true)
                                                break;
                                            case "button":
                                                toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                                break;
                                            case "positionSlider":
                                                setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                                break;
                                            case "brightnessSlider":
                                                if (existsObject(id)) {
                                                    let o = getObject(id);
                                                    let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                                    switch (o.common.role) {
                                                        case "dimmer":
                                                            if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {  
                                                                let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValue, pageItem.minValue))
                                                                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 "hue":
                                    					    if (pageItem.minValueBRI != undefined && pageItem.maxValueBRI != undefined) {  
                                                                let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValueBRI, pageItem.minValueBRI))
                                                                setIfExists(id + ".DIMMER", parseInt(words[4]));
                                                    }
                                                }
                                                break;
                                            case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                                let pageItem = config.pages[pageId].items.find(e => e.id === id);
                                                if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                                    let colorTempK = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.minValue, pageItem.maxValue));
                                                    setIfExists(id + ".TEMPERATURE", (colorTempK));
                                                } else {
                                                    setIfExists(id + ".TEMPERATURE", 100 - words[4]);
                                                }
                                                break;
                                            case "colorWheel":
                                                let colorCoordinates = words[4].split('|');
                                                let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                                //console.log(rgb);
                                                //console.log(getHue(rgb.red, rgb.green, rgb.blue));
                                                setIfExists(id + ".HUE", getHue(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;
                                            case "media-pause":
                                                if (getState(id + ".STATE").val === true) {
                                                    setIfExists(id + ".PAUSE", true)
                                                } else {
                                                    setIfExists(id + ".PLAY", true)
                                                }
                                                break;
                                            case "media-next":
                                                setIfExists(id + ".NEXT", true)
                                                break;
                                            case "volumeSlider":
                                                setIfExists(id + ".VOLUME", parseInt(words[4]))
                                                break;
                                            case "speaker-sel":
                                                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];
                                                    if ((getState(i).val) === words[4]){
                                                        let deviceId = i;
                                                        deviceId = deviceId.split('.');
                                                        setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                                        alexaDevice = deviceId[3]
                                                    }
                                                }
                                                break;
                                            case "media-OnOff":
                                                setIfExists(id + ".STOP", true)
                                                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:
                                                return "0|1";
                                            case config.pages.length - 1:
                                                return "1|0";
                                            case -1:
                                                return "0|0";
                                            default:
                                                return "1|1";
                                        }
                                    }
                                    
                                    function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                                    
                                        var out_msgs: Array<Payload> = [];
                                        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"
                                                if (o.common.role == "light") {
                                                    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);
                                                    }
                                    
                                                    if (val) {
                                                        switchVal = "1";
                                                        iconColor = GetIconColor(pageItem, true, false);
                                                    }
                                    
                                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                                }
                                    
                                                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"
                                                    }
                                                    let brightness = 0;
                                                    if (existsState(id + ".ACTUAL")) {
                                                        if (pageItem.minValue != undefined && pageItem.maxValue != undefined) {
                                                            brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, pageItem.minValue, pageItem.maxValue, 100, 0));
                                                        } else {
                                                            brightness = getState(id + ".ACTUAL").val;
                                                        }
                                                    } else {
                                                        console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                                    }
                                                    //iconColor = GetIconColor(pageItem, brightness, false);
                                                    //Farbe muss noch korrekt ermittelt werden
                                                    if (val === true) {
                                                        iconColor = GetIconColor(pageItem, true, true);
                                                        switchVal = "1";
                                                    } else {
                                                        iconColor = GetIconColor(pageItem, false, true);
                                                    }
                                    
                                                    RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                                    
                                                    let colorTemp = "disable"
                                                    let colorMode = "disable"
                                                    //let attr_support_color = attr.supported_color_modes
                                                    //if (attr_support_color.includes("color_temp"))
                                                    // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                }
                                    
                                                if (o.common.role == "hue") {
                                                    if (existsState(id + ".ON_ACTUAL")) {
                                                        val = getState(id + ".ON_ACTUAL").val;
                                                        RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type);
                                                    }
                                    
                                                    //Farbe muss noch korrekt ermittelt werden
                                                    if (val === true) {
                                                        iconColor = GetIconColor(pageItem, true, true);
                                                        switchVal = "1";
                                                    } else {
                                                        iconColor = GetIconColor(pageItem, false, true);
                                                    }
                                    
                                                    let brightness = 0;
                                                    if (existsState(id + ".DIMMER")) {
                                    					if (pageItem.minValueBRI !== undefined && pageItem.minValueBRI !== undefined) {
                                                        brightness = Math.trunc(scale2(getState(id + ".DIMMER").val, 0, 100, 0, 100));
                                                        RegisterDetailEntityWatcher(id + ".DIMMER", pageItem, type);
                                                    } else {
                                                        console.warn("Datenpunkt: " + id + ".DIMMER kann nicht gelesen werden");
                                                    }
                                    
                                                    var colorMode = "disable";
                                                    if (existsState(id + ".HUE")) {
                                                        if (getState(id + ".HUE").val != null)
                                                            colorMode = "enable";  
                                                    }
                                    
                                                    var colorTemp = 0;
                                                    if (existsState(id + ".TEMPERATURE")) {
                                                        if (getState(id + ".TEMPERATURE").val != null) {
                                    
                                                            if (pageItem.minValue !== undefined && pageItem.minValue !== undefined) {
                                                                colorTemp = Math.trunc(scale(getState(id + ".TEMPERATURE").val, pageItem.minValue, pageItem.maxValue, 0, 100));
                                                            } else {
                                                                colorTemp = 100 - getState(id + ".TEMPERATURE").val;
                                                            }
                                                            RegisterDetailEntityWatcher(id + ".TEMPERATURE", pageItem, type);
                                                        } 
                                                    }
                                    
                                                    //let attr_support_color = attr.supported_color_modes
                                                    //if (attr_support_color.includes("color_temp"))
                                                    //let colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
                                    
                                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                }
                                    
                                            }
                                    
                                            if (type == "popupShutter") {
                                                if (existsState(id + ".ACTUAL")) {
                                                    val = getState(id + ".ACTUAL").val;
                                                    RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type);
                                                    console.log(val);
                                                } else if (existsState(id + ".SET")) {
                                                    val = getState(id + ".SET").val;
                                                    RegisterDetailEntityWatcher(id + ".SET", pageItem, type);
                                                    console.log(val);
                                                }
                                                out_msgs.push({ payload: "entityUpdateDetail~" + val })
                                            }
                                        }
                                        return out_msgs
                                    }
                                    
                                    function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                                        return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                                    }
                                    
                                    function scale2(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                                        return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
                                    }
                                    
                                    function UnsubscribeWatcher(): void {
                                        for (const [key, value] of Object.entries(subscriptions)) {
                                            unsubscribe(value);
                                            delete subscriptions[key]
                                        }
                                    }
                                    
                                    function HandleScreensaver(): void {
                                        SendToPanel({ payload: "pageType~screensaver"})
                                        UnsubscribeWatcher();
                                        HandleScreensaverUpdate();
                                    }
                                    
                                    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++) {
                                                    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);
                                                    payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                                }
                                            } 
                                            else {
                                                //In Config definierte Zustände wenn weatherForecast = false
                                                payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                                payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                                payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                                payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                                            }
                                    /*-------------------------------------------------------------------------------------------------------------------------------------*/
                                     
                                            SendToPanel(<Payload>{ payload: payloadString });
                                        }
                                    }
                                    
                                    function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                                        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 "~~~";
                                        }
                                    }
                                    
                                    function GetAccuWeatherIcon(icon: number): string {
                                        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";
                                        }
                                    }
                                    
                                    function sleep(milliseconds) {
                                      const date = Date.now();
                                      let currentDate = null;
                                      do {
                                        currentDate = Date.now();
                                      } while (currentDate - date < milliseconds);
                                    }
                                    
                                    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 <RGB>{ 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)));
                                    }
                                    
                                    /* 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;
                                    }
                                    
                                    /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                                    }
                                    
                                    type RGB = {
                                        red: number,
                                        green: number,
                                        blue: number
                                    };
                                    
                                    type Payload = {
                                        payload: string;
                                    };
                                    
                                    type Page = {
                                        type: string,
                                        heading: string,
                                        items: PageItem[],
                                        useColor: boolean
                                    };
                                    
                                    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[],
                                    };
                                    
                                    type PageItem = {
                                        id: string,
                                        icon: (string | undefined),
                                        onColor: (RGB | undefined),
                                        offColor: (RGB | undefined),
                                        useColor: (boolean | undefined),
                                        interpolateColor: (boolean | undefined),
                                        minValue: (number | undefined),
                                        maxValue: (number | undefined),
                                        name: (string | undefined),
                                        unit: (string | undefined)
                                    }
                                    
                                    type Config = {
                                        panelRecvTopic: string,
                                        panelSendTopic: string,
                                        timeoutScreensaver: number,
                                        dimmode: number,
                                        //brightnessScreensaver:
                                        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,
                                        defaultColor: RGB,
                                        defaultOnColor: RGB,
                                        defaultOffColor: RGB,
                                        pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                                        button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                        button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                    };
                                    
                                    type ScreenSaverElement = {
                                        ScreensaverEntity: string | null,
                                        ScreensaverEntityIcon: string | null,
                                        ScreensaverEntityText: string | null,
                                        ScreensaverEntityUnitText: string | null,
                                    }
                                    
                                    ArmilarA Offline
                                    ArmilarA Offline
                                    Armilar
                                    Most Active Forum Testing
                                    wrote on last edited by Armilar
                                    #372

                                    @dexxter

                                    Deine eigenen Versuche waren im Prinzip nicht schlecht. Wenn du den "type PageItem" entsprechend erweitert hättest (sehr weit unten), hätte es sogar fast funktioniert.

                                    Habe jetzt zusätzlich minValueBrightness/maxValueBrightness und minValueColorTemp/maxValueColorTemp neu hinzugefügt. Wir würden irgendwann mit den Bezeichnern durcheinander kommen. minValue und maxValue können weiterhin verwendet werden, um z.B. Infos zu visualisieren (Batteriezustand, etc.)

                                    Wie im Beispiel (Alias HUE, Brightness auf 70% begrenzt, Farbtemperatur zwischen 500 und 6500K):

                                    <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Light-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500},
                                    

                                    Das Ergebnis (vollständiges TypeScript):

                                    var Icons = new IconsSelector();
                                    
                                    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 Off: RGB = { red: 68, green: 115, blue: 158 }; //Blau-Off
                                    const Off: RGB = { red: 253, green: 128, blue: 0 }; //Orange-Off
                                    const On: RGB = { red: 253, green: 216, blue: 53 };
                                    const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                                    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 };
                                    
                                    
                                    //----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 ...
                                    
                                    //Alexa-Instanz
                                    var alexaInstanz = "alexa2.0"
                                    var alexaDevice = "G0XXXXXXXXXXXXXXX"; //Primär zu steuendes Device
                                    
                                    // 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.NSPanel.1.popupNotifyHeading";
                                    var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                                    
                                    var Test_Licht: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Büro",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", interpolateColor: true},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestRGBLicht", name: "RGB-Licht", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Licht-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Licht-Color", minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true}
                                        ]
                                    };
                                    
                                    var Buero_Seite_1: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Büro",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", interpolateColor: true},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                                        ]
                                    };
                                    
                                    var Fenster_1: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Fenster und Türen",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                                        ]
                                    };
                                    
                                    var Abfall: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Abfallkalender",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                                        ]
                                    };
                                    
                                    var Buero_Seite_2: PageGrid =
                                    {
                                        "type": "cardGrid",
                                        "heading": "Büro 2",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                                            <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                                        ]
                                    };
                                    
                                    var Alexa: PageMedia = 
                                    {
                                        "type": "cardMedia",
                                        "heading": "Alexa",
                                        "useColor": true,
                                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                                    };
                                    
                                    var Buero_Themostat: PageThermo = 
                                    {
                                        "type": "cardThermo",
                                        "heading": "Thermostat",
                                        "useColor": true,
                                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                                    };
                                    
                                    var Buero_Alarm: PageAlarm = 
                                    {
                                        "type": "cardAlarm",
                                        "heading": "Alarm",
                                        "useColor": true,
                                        "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                                    };
                                    
                                    var button1Page: PageGrid =
                                    {
                                        "type": "cardGrid",
                                        "heading": "Radio",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                                        ]
                                    };
                                    
                                    var button2Page: PageEntities =
                                    {
                                        "type": "cardEntities",
                                        "heading": "Büro",
                                        "useColor": true,
                                        "items": [
                                            <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                            <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                                        ]
                                    };
                                    
                                    export const config: Config = {
                                        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,
                                        locale: "de_DE",
                                        timeFormat: "%H:%M",
                                        dateFormat: "%A, %d. %B %Y",
                                        weatherEntity: "alias.0.Wetter.Wetter",
                                        defaultOffColor: Off,
                                        defaultOnColor: On,
                                        defaultColor: Off,
                                        temperatureUnit: "°C",
                                        pages: [
                                                Buero_Seite_1,
                                                Test_Licht,
                                                Fenster_1,
                                                Abfall,
                                                Buero_Seite_2,
                                                Alexa,
                                                Buero_Themostat,
                                                Buero_Alarm
                                        ],
                                        button1Page: button1Page,
                                        button2Page: button2Page
                                    };
                                    
                                    // _________________________________ 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;
                                    
                                    schedule("* * * * *", function () {
                                        SendTime();
                                    });
                                    schedule("0 * * * *", function () {
                                        SendDate();
                                    });
                                    
                                    
                                    // 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, function () {
                                            HandleScreensaverUpdate();
                                        })
                                    }
                                    on({ id: config.panelRecvTopic }, function (obj) {
                                        if (obj.state.val.startsWith('\{"CustomRecv":')) {
                                            var json = JSON.parse(obj.state.val);
                                    
                                            var split = json.CustomRecv.split(",");
                                            HandleMessage(split[0], split[1], parseInt(split[2]), split);
                                        }
                                    });
                                    
                                    function SendToPanel(val: Payload | Payload[]): void {
                                        if (Array.isArray(val)) {
                                            val.forEach(function (id, i) {
                                                setState(config.panelSendTopic, id.payload);
                                            });
                                        }
                                        else
                                            setState(config.panelSendTopic, val.payload);
                                    }
                                    
                                    function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                                        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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                                    if (pageItem !== undefined)
                                                        SendToPanel(GenerateDetailPage(words[2], pageItem));
                                                case "buttonPress2":
                                                    screensaverEnabled = false;
                                                    HandleButtonEvent(words);
                                                    break;
                                                case "button1":
                                                case "button2":
                                                    screensaverEnabled = false;
                                                    HandleHardwareButton(method);
                                                default:
                                                    break;
                                            }
                                        }
                                    }
                                    
                                    function GeneratePage(page: Page): void {
                                        switch (page.type) {
                                            case "cardEntities":
                                                SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                                break;
                                            case "cardThermo":
                                                SendToPanel(GenerateThermoPage(<PageThermo>page));
                                                break;
                                            case "cardGrid":
                                                SendToPanel(GenerateGridPage(<PageGrid>page));
                                                break;
                                            case "cardMedia":
                                                SendToPanel(GenerateMediaPage(<PageMedia>page));
                                                break;
                                            case "cardAlarm":
                                                SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                                break;
                                        }
                                    }
                                    
                                    function HandleHardwareButton(method: string): void {
                                        let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                                        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);
                                    }
                                    
                                    function HandleStartupProcess(): void {
                                        SendDate();
                                        SendTime();
                                        SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                                        SendToPanel({ payload: "dimmode~" + config.dimmode });
                                    }
                                    
                                    function SendDate(): void {
                                        var d = new Date();
                                        var day = Days[d.getDay()];
                                        var date = d.getDate();
                                        var month = Months[d.getMonth()];
                                        var year = d.getFullYear();
                                        var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                                        SendToPanel(<Payload>{ payload: _sendDate });
                                    }
                                    
                                    function SendTime(): void {
                                        var d = new Date();
                                        var hr = d.getHours().toString();
                                        var min = d.getMinutes().toString();
                                    
                                        if (d.getHours() < 10) {
                                            hr = "0" + d.getHours().toString();
                                        }
                                        if (d.getMinutes() < 10) {
                                            min = "0" + d.getMinutes().toString();
                                        }
                                        SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                                    }
                                    
                                    function GenerateEntitiesPage(page: PageEntities): Payload[] {
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs = [{ payload: "pageType~cardEntities" }]
                                        out_msgs.push({ payload: GeneratePageElements(page) });
                                        return out_msgs
                                    }
                                    
                                    function GenerateGridPage(page: PageGrid): Payload[] {
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs = [{ payload: "pageType~cardGrid" }]
                                        out_msgs.push({ payload: GeneratePageElements(page) });
                                        return out_msgs
                                    }
                                    
                                    function GeneratePageElements(page: Page): string {
                                        let maxItems = 0;
                                        switch (page.type) {
                                            case "cardThermo":
                                                maxItems = 1;
                                                break;
                                            case "cardAlarm":
                                                maxItems = 1;
                                                break;
                                            case "cardMedia":
                                                maxItems = 1;
                                                break;
                                            case "cardEntities":
                                                maxItems = 4;
                                                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);
                                            }
                                            else {
                                                pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                                            }
                                        }
                                        return pageData;
                                    }
                                    
                                    function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                                        var iconId = "0"
                                        if (pageItem.id == "delete") {
                                            return "~delete~~~~~"
                                        }
                                        var name: string;
                                        var type: string;
                                    
                                        // ioBroker
                                        if (existsObject(pageItem.id)) {
                                            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;
                                                RegisterEntityWatcher(pageItem.id + ".GET");
                                            }
                                            else if (existsState(pageItem.id + ".SET")) {
                                                val = getState(pageItem.id + ".SET").val;
                                                RegisterEntityWatcher(pageItem.id + ".SET");
                                            }
                                            var iconColor = rgb_dec565(config.defaultColor);
                                    
                                            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 optVal = "0"
                                    
                                                    if (val === true || val === "true") {
                                                        optVal = "1"
                                                        iconColor = GetIconColor(pageItem, true, useColors);
                                                    } else {
                                                        iconColor = GetIconColor(pageItem, false, useColors);
                                                    }
                                    
                                                    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 (existsState(pageItem.id + ".HUE")) {
                                                        if (getState(pageItem.id + ".HUE").val != null) {
                                                            let huecolor = hsv2rgb(getState(pageItem.id + ".HUE").val,1,1);
                                                            let rgb = <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);
                                                        } 
                                                    }
                                    
                                                    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 = <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 "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 = "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 = "closed"
                                                        }
                                                        RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                                    }
                                                    return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                                    
                                                case "info":
                                    
                                                case "humidity":
                                    
                                                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 "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;
                                    
                                                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~~~~~"
                                    }
                                    
                                    function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                                        // 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);
                                    }
                                    
                                    function RegisterEntityWatcher(id: string): void {
                                        if (subscriptions.hasOwnProperty(id)) {
                                            return;
                                        }
                                        subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                                            if(pageId >= 0)
                                                SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                                            if(pageId == -1 && config.button1Page != undefined)
                                                SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                                            if(pageId == -2 && config.button2Page != undefined)
                                                SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                                        }))
                                    }
                                    
                                    function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                                        if (subscriptions.hasOwnProperty(id)) {
                                            return;
                                        }
                                        subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                                            SendToPanel(GenerateDetailPage(type, pageItem));
                                        }))
                                    }
                                    
                                    function GetUnitOfMeasurement(id: string): string {
                                        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 "";
                                    }
                                    
                                    function GenerateThermoPage(page: PageThermo): Payload[] {
                                        var id = page.items[0].id
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs.push({ payload: "pageType~cardThermo" });
                                    
                                        // ioBroker
                                        if (existsObject(id)) {
                                            let o = getObject(id)
                                            let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                                            let currentTemp = 0;
                                            if (existsState(id + ".ACTUAL"))
                                                currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                                    
                                            let destTemp = 0;
                                            if (existsState(id + ".SET")) {
                                                destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                                            }
                                    
                                            let status = ""
                                            if (existsState(id + ".MODE"))
                                                status = getState(id + ".MODE").val;
                                            let minTemp = 50 //Min Temp 5°C
                                            let maxTemp = 300 //Max Temp 30°C
                                            let stepTemp = 5
                                    
                                            //0-4 verwendet bei ungerader Anzahl Parametern
                                            let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                                            let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                                            //5-8 verwendet bei gerader Anzahl Parametern
                                            let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                                            let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                                            let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                                            let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                                    
                                            if (existsState(id + ".HUMIDITY")){
                                                bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                                if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                                    bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                }
                                            }
                                    
                                            if (existsState(id + ".MAINTAIN")){
                                                if (getState(id + ".MAINTAIN").val >> .1) {
                                                    bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                                } else {
                                                    bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                                }
                                            }
                                    
                                            if (existsState(id + ".UNREACH")){
                                                if (getState(id + ".UNREACH").val) {
                                                    bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                                } else {
                                                    bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                                }
                                            }
                                    
                                            if (existsState(id + ".LOWBAT")){
                                                if (getState(id + ".LOWBAT").val) {
                                                    bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                                } else {
                                                    bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                                }
                                            }
                                    
                                            let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                                    
                                            out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                                        }
                                    
                                        return out_msgs
                                    }
                                    
                                    function GenerateMediaPage(page: PageMedia): Payload[] {
                                        var id = page.items[0].id
                                        var out_msgs: Array<Payload> = [];
                                        out_msgs.push({ payload: "pageType~cardMedia" });
                                        if (existsObject(id)) {
                                    
                                            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;
                                            let volume = getState(id + ".VOLUME").val;
                                            var iconplaypause = Icons.GetIcon("pause"); //pause
                                            var onoffbutton = 1374;
                                            if (getState(id + ".STATE").val) {
                                                onoffbutton = 65535;
                                                iconplaypause = Icons.GetIcon("pause"); //pause
                                            } else {
                                                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
                                    // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                                            let speakerlist = "";
                                            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 && 
                                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                                        existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                                            speakerlist = speakerlist + getState(i).val + "?";
                                                    }
                                                }
                                            }
                                            speakerlist = speakerlist.substring(0,speakerlist.length-1);
                                    //--------------------------------------------------------------------------------------------------------------
                                    
                                            out_msgs.push({ payload: "entityUpd~" + 
                                                                      name + "~" +
                                                                      id + "~" +
                                                                      id + "~" +         //????
                                                                      media_icon + "~" +
                                                                      title + "~" +
                                                                      author + "~" +
                                                                      volume + "~" +
                                                                      iconplaypause + "~" +
                                                                      currentSpeaker + "~" +
                                                                      speakerlist + "~" +
                                                                      onoffbutton});
                                        }
                                    
                                        return out_msgs
                                    }
                                    
                                    function GenerateAlarmPage(page: PageAlarm): Payload[] {
                                        var id = page.items[0].id
                                        var out_msgs: Array<Payload> = [];
                                        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 = 1;                           //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 = 1;                           //flashing*        
                                        }
                                            
                                        out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                                    id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                                    "~" +                      //???
                                                                    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*
                                    
                                        return out_msgs
                                    }
                                    
                                    function setIfExists(id: string, value: any, type: string | null = null): boolean {
                                        if (type === null) {
                                            if (existsState(id)) {
                                                setState(id, value);
                                                return true;
                                            }
                                        }
                                        else {
                                            let obj = getObject(id);
                                            if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                                setState(id, value);
                                                return true;
                                            }
                                        }
                                        return false;
                                    }
                                    
                                    function toggleState(id: string): boolean {
                                        let obj = getObject(id);
                                        if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                                            setState(id, !getState(id).val);
                                            return true;
                                        }
                                        return false;
                                    }
                                    
                                    function HandleButtonEvent(words): void {
                                        let id = words[2]
                                        let buttonAction = words[3];
                                    
                                        //console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                                    
                                        switch (buttonAction) {
                                            case "bNext":
                                                var pageNum = ((pageId + 1) % config.pages.length);
                                                pageId = Math.abs(pageNum);
                                                UnsubscribeWatcher();
                                                GeneratePage(config.pages[pageId]);
                                                break;
                                            case "bPrev":
                                                var pageNum = ((pageId - 1) % config.pages.length);
                                                pageId = Math.abs(pageNum);
                                                UnsubscribeWatcher();
                                                GeneratePage(config.pages[pageId]);
                                                break;
                                            case "bExit":
                                                if (config.screenSaverDoubleClick) {
                                                    if (words[4] == 2)
                                                        GeneratePage(config.pages[pageId]);
                                                }
                                                else
                                                    GeneratePage(config.pages[pageId]);
                                                break;
                                            case "OnOff":
                                                if (existsObject(id)) {
                                                    var action = false
                                                    if (words[4] == "1")
                                                        action = true
                                                    let o = getObject(id)
                                                    switch (o.common.role) {
                                                        case "light":
                                                            setIfExists(id + ".SET", action);
                                                            break;
                                                        case "dimmer":
                                                            setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                                            break;
                                                        case "hue": // Armilar
                                                            setIfExists(id + ".ON_ACTUAL", action);
                                                    }
                                                }
                                                break;
                                            case "up":
                                                setIfExists(id + ".OPEN", true)
                                                break;
                                            case "stop":
                                                setIfExists(id + ".STOP", true)
                                                break;
                                            case "down":
                                                setIfExists(id + ".CLOSE", true)
                                                break;
                                            case "button":
                                                toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                                break;
                                            case "positionSlider":
                                                setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                                break;
                                            case "brightnessSlider":
                                                if (existsObject(id)) {
                                                    let o = getObject(id);
                                                    let pageItem = config.pages[pageId].items.find(e => e.id === 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 "hue":
                                    
                                                        case "rgb":
                                                            setIfExists(id + ".DIMMER", parseInt(words[4]));
                                                    }
                                                }
                                                break;
                                            case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                                let pageItem = config.pages[pageId].items.find(e => e.id === 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]);
                                                }
                                                break;
                                            case "colorWheel":
                                                let colorCoordinates = words[4].split('|');
                                                let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                                //console.log(rgb);
                                                //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 "tempUpd":
                                                setIfExists(id + ".SET", parseInt(words[4]) / 10)
                                                break;
                                            case "media-back":
                                                setIfExists(id + ".PREV", true)
                                                break;
                                            case "media-pause":
                                                if (getState(id + ".STATE").val === true) {
                                                    setIfExists(id + ".PAUSE", true)
                                                } else {
                                                    setIfExists(id + ".PLAY", true)
                                                }
                                                break;
                                            case "media-next":
                                                setIfExists(id + ".NEXT", true)
                                                break;
                                            case "volumeSlider":
                                                setIfExists(id + ".VOLUME", parseInt(words[4]))
                                                break;
                                            case "speaker-sel":
                                                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];
                                                    if ((getState(i).val) === words[4]){
                                                        let deviceId = i;
                                                        deviceId = deviceId.split('.');
                                                        setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                                        alexaDevice = deviceId[3]
                                                    }
                                                }
                                                break;
                                            case "media-OnOff":
                                                setIfExists(id + ".STOP", true)
                                                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:
                                                return "0|1";
                                            case config.pages.length - 1:
                                                return "1|0";
                                            case -1:
                                                return "0|0";
                                            default:
                                                return "1|1";
                                        }
                                    }
                                    
                                    function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                                    
                                        var out_msgs: Array<Payload> = [];
                                        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") {
                                                    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);
                                                    }
                                    
                                                    if (val) {
                                                        switchVal = "1";
                                                        iconColor = GetIconColor(pageItem, true, false);
                                                    }
                                    
                                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                                }
                                    
                                                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);
                                                    
                                                    let colorTemp = "disable"
                                                    let colorMode = "disable"
                                    
                                                    out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                }
                                                //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                }
                                    
                                                //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                }
                                    
                                            }
                                    
                                            if (type == "popupShutter") {
                                                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);
                                                }
                                                out_msgs.push({ payload: "entityUpdateDetail~" + val })
                                            }
                                        }
                                        return out_msgs
                                    }
                                    
                                    function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                                        return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                                    }
                                    
                                    function UnsubscribeWatcher(): void {
                                        for (const [key, value] of Object.entries(subscriptions)) {
                                            unsubscribe(value);
                                            delete subscriptions[key]
                                        }
                                    }
                                    
                                    function HandleScreensaver(): void {
                                        SendToPanel({ payload: "pageType~screensaver"})
                                        UnsubscribeWatcher();
                                        HandleScreensaverUpdate();
                                    }
                                    
                                    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++) {
                                                    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);
                                                    payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                                }
                                            } 
                                            else {
                                                //In Config definierte Zustände wenn weatherForecast = false
                                                payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                                payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                                payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                                payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                                            }
                                    /*-------------------------------------------------------------------------------------------------------------------------------------*/
                                     
                                            SendToPanel(<Payload>{ payload: payloadString });
                                        }
                                    }
                                    
                                    function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                                        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 "~~~";
                                        }
                                    }
                                    
                                    function GetAccuWeatherIcon(icon: number): string {
                                        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";
                                        }
                                    }
                                    
                                    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 <RGB>{ 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)));
                                    }
                                    
                                    /* 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;
                                    }
                                    
                                    /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                                    }
                                    
                                    type RGB = {
                                        red: number,
                                        green: number,
                                        blue: number
                                    };
                                    
                                    type Payload = {
                                        payload: string;
                                    };
                                    
                                    type Page = {
                                        type: string,
                                        heading: string,
                                        items: PageItem[],
                                        useColor: boolean
                                    };
                                    
                                    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[],
                                    };
                                    
                                    type PageItem = {
                                        id: string,
                                        icon: (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),
                                        unit: (string | undefined)
                                    }
                                    
                                    type Config = {
                                        panelRecvTopic: string,
                                        panelSendTopic: string,
                                        timeoutScreensaver: number,
                                        dimmode: number,
                                        //brightnessScreensaver:
                                        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,
                                        defaultColor: RGB,
                                        defaultOnColor: RGB,
                                        defaultOffColor: RGB,
                                        pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                                        button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                        button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                    };
                                    
                                    type ScreenSaverElement = {
                                        ScreensaverEntity: string | null,
                                        ScreensaverEntityIcon: string | null,
                                        ScreensaverEntityText: string | null,
                                        ScreensaverEntityUnitText: string | null,
                                    }
                                    

                                    P.S.: Der Alias-Typ "RGB-Licht" sollte jetzt auch gehen...

                                    Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
                                    https://github.com/joBr99/nspanel-lovelace-ui/wiki

                                    Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                                    D 1 Reply Last reply
                                    0
                                    • ArmilarA Armilar

                                      @dexxter

                                      Deine eigenen Versuche waren im Prinzip nicht schlecht. Wenn du den "type PageItem" entsprechend erweitert hättest (sehr weit unten), hätte es sogar fast funktioniert.

                                      Habe jetzt zusätzlich minValueBrightness/maxValueBrightness und minValueColorTemp/maxValueColorTemp neu hinzugefügt. Wir würden irgendwann mit den Bezeichnern durcheinander kommen. minValue und maxValue können weiterhin verwendet werden, um z.B. Infos zu visualisieren (Batteriezustand, etc.)

                                      Wie im Beispiel (Alias HUE, Brightness auf 70% begrenzt, Farbtemperatur zwischen 500 und 6500K):

                                      <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Light-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500},
                                      

                                      Das Ergebnis (vollständiges TypeScript):

                                      var Icons = new IconsSelector();
                                      
                                      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 Off: RGB = { red: 68, green: 115, blue: 158 }; //Blau-Off
                                      const Off: RGB = { red: 253, green: 128, blue: 0 }; //Orange-Off
                                      const On: RGB = { red: 253, green: 216, blue: 53 };
                                      const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                                      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 };
                                      
                                      
                                      //----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 ...
                                      
                                      //Alexa-Instanz
                                      var alexaInstanz = "alexa2.0"
                                      var alexaDevice = "G0XXXXXXXXXXXXXXX"; //Primär zu steuendes Device
                                      
                                      // 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.NSPanel.1.popupNotifyHeading";
                                      var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                                      
                                      var Test_Licht: PageEntities =
                                      {
                                          "type": "cardEntities",
                                          "heading": "Büro",
                                          "useColor": true,
                                          "items": [
                                              <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", interpolateColor: true},
                                              <PageItem>{ id: "alias.0.NSPanel_1.TestRGBLicht", name: "RGB-Licht", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                              <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Licht-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true},
                                              <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Licht-Color", minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true}
                                          ]
                                      };
                                      
                                      var Buero_Seite_1: PageEntities =
                                      {
                                          "type": "cardEntities",
                                          "heading": "Büro",
                                          "useColor": true,
                                          "items": [
                                              <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", interpolateColor: true},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                                          ]
                                      };
                                      
                                      var Fenster_1: PageEntities =
                                      {
                                          "type": "cardEntities",
                                          "heading": "Fenster und Türen",
                                          "useColor": true,
                                          "items": [
                                              <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                                          ]
                                      };
                                      
                                      var Abfall: PageEntities =
                                      {
                                          "type": "cardEntities",
                                          "heading": "Abfallkalender",
                                          "useColor": true,
                                          "items": [
                                              <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                                          ]
                                      };
                                      
                                      var Buero_Seite_2: PageGrid =
                                      {
                                          "type": "cardGrid",
                                          "heading": "Büro 2",
                                          "useColor": true,
                                          "items": [
                                              <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                                              <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                                          ]
                                      };
                                      
                                      var Alexa: PageMedia = 
                                      {
                                          "type": "cardMedia",
                                          "heading": "Alexa",
                                          "useColor": true,
                                          "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                                      };
                                      
                                      var Buero_Themostat: PageThermo = 
                                      {
                                          "type": "cardThermo",
                                          "heading": "Thermostat",
                                          "useColor": true,
                                          "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                                      };
                                      
                                      var Buero_Alarm: PageAlarm = 
                                      {
                                          "type": "cardAlarm",
                                          "heading": "Alarm",
                                          "useColor": true,
                                          "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                                      };
                                      
                                      var button1Page: PageGrid =
                                      {
                                          "type": "cardGrid",
                                          "heading": "Radio",
                                          "useColor": true,
                                          "items": [
                                              <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                                          ]
                                      };
                                      
                                      var button2Page: PageEntities =
                                      {
                                          "type": "cardEntities",
                                          "heading": "Büro",
                                          "useColor": true,
                                          "items": [
                                              <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                              <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                                          ]
                                      };
                                      
                                      export const config: Config = {
                                          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,
                                          locale: "de_DE",
                                          timeFormat: "%H:%M",
                                          dateFormat: "%A, %d. %B %Y",
                                          weatherEntity: "alias.0.Wetter.Wetter",
                                          defaultOffColor: Off,
                                          defaultOnColor: On,
                                          defaultColor: Off,
                                          temperatureUnit: "°C",
                                          pages: [
                                                  Buero_Seite_1,
                                                  Test_Licht,
                                                  Fenster_1,
                                                  Abfall,
                                                  Buero_Seite_2,
                                                  Alexa,
                                                  Buero_Themostat,
                                                  Buero_Alarm
                                          ],
                                          button1Page: button1Page,
                                          button2Page: button2Page
                                      };
                                      
                                      // _________________________________ 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;
                                      
                                      schedule("* * * * *", function () {
                                          SendTime();
                                      });
                                      schedule("0 * * * *", function () {
                                          SendDate();
                                      });
                                      
                                      
                                      // 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, function () {
                                              HandleScreensaverUpdate();
                                          })
                                      }
                                      on({ id: config.panelRecvTopic }, function (obj) {
                                          if (obj.state.val.startsWith('\{"CustomRecv":')) {
                                              var json = JSON.parse(obj.state.val);
                                      
                                              var split = json.CustomRecv.split(",");
                                              HandleMessage(split[0], split[1], parseInt(split[2]), split);
                                          }
                                      });
                                      
                                      function SendToPanel(val: Payload | Payload[]): void {
                                          if (Array.isArray(val)) {
                                              val.forEach(function (id, i) {
                                                  setState(config.panelSendTopic, id.payload);
                                              });
                                          }
                                          else
                                              setState(config.panelSendTopic, val.payload);
                                      }
                                      
                                      function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                                          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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                                      if (pageItem !== undefined)
                                                          SendToPanel(GenerateDetailPage(words[2], pageItem));
                                                  case "buttonPress2":
                                                      screensaverEnabled = false;
                                                      HandleButtonEvent(words);
                                                      break;
                                                  case "button1":
                                                  case "button2":
                                                      screensaverEnabled = false;
                                                      HandleHardwareButton(method);
                                                  default:
                                                      break;
                                              }
                                          }
                                      }
                                      
                                      function GeneratePage(page: Page): void {
                                          switch (page.type) {
                                              case "cardEntities":
                                                  SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                                  break;
                                              case "cardThermo":
                                                  SendToPanel(GenerateThermoPage(<PageThermo>page));
                                                  break;
                                              case "cardGrid":
                                                  SendToPanel(GenerateGridPage(<PageGrid>page));
                                                  break;
                                              case "cardMedia":
                                                  SendToPanel(GenerateMediaPage(<PageMedia>page));
                                                  break;
                                              case "cardAlarm":
                                                  SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                                  break;
                                          }
                                      }
                                      
                                      function HandleHardwareButton(method: string): void {
                                          let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                                          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);
                                      }
                                      
                                      function HandleStartupProcess(): void {
                                          SendDate();
                                          SendTime();
                                          SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                                          SendToPanel({ payload: "dimmode~" + config.dimmode });
                                      }
                                      
                                      function SendDate(): void {
                                          var d = new Date();
                                          var day = Days[d.getDay()];
                                          var date = d.getDate();
                                          var month = Months[d.getMonth()];
                                          var year = d.getFullYear();
                                          var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                                          SendToPanel(<Payload>{ payload: _sendDate });
                                      }
                                      
                                      function SendTime(): void {
                                          var d = new Date();
                                          var hr = d.getHours().toString();
                                          var min = d.getMinutes().toString();
                                      
                                          if (d.getHours() < 10) {
                                              hr = "0" + d.getHours().toString();
                                          }
                                          if (d.getMinutes() < 10) {
                                              min = "0" + d.getMinutes().toString();
                                          }
                                          SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                                      }
                                      
                                      function GenerateEntitiesPage(page: PageEntities): Payload[] {
                                          var out_msgs: Array<Payload> = [];
                                          out_msgs = [{ payload: "pageType~cardEntities" }]
                                          out_msgs.push({ payload: GeneratePageElements(page) });
                                          return out_msgs
                                      }
                                      
                                      function GenerateGridPage(page: PageGrid): Payload[] {
                                          var out_msgs: Array<Payload> = [];
                                          out_msgs = [{ payload: "pageType~cardGrid" }]
                                          out_msgs.push({ payload: GeneratePageElements(page) });
                                          return out_msgs
                                      }
                                      
                                      function GeneratePageElements(page: Page): string {
                                          let maxItems = 0;
                                          switch (page.type) {
                                              case "cardThermo":
                                                  maxItems = 1;
                                                  break;
                                              case "cardAlarm":
                                                  maxItems = 1;
                                                  break;
                                              case "cardMedia":
                                                  maxItems = 1;
                                                  break;
                                              case "cardEntities":
                                                  maxItems = 4;
                                                  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);
                                              }
                                              else {
                                                  pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                                              }
                                          }
                                          return pageData;
                                      }
                                      
                                      function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                                          var iconId = "0"
                                          if (pageItem.id == "delete") {
                                              return "~delete~~~~~"
                                          }
                                          var name: string;
                                          var type: string;
                                      
                                          // ioBroker
                                          if (existsObject(pageItem.id)) {
                                              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;
                                                  RegisterEntityWatcher(pageItem.id + ".GET");
                                              }
                                              else if (existsState(pageItem.id + ".SET")) {
                                                  val = getState(pageItem.id + ".SET").val;
                                                  RegisterEntityWatcher(pageItem.id + ".SET");
                                              }
                                              var iconColor = rgb_dec565(config.defaultColor);
                                      
                                              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 optVal = "0"
                                      
                                                      if (val === true || val === "true") {
                                                          optVal = "1"
                                                          iconColor = GetIconColor(pageItem, true, useColors);
                                                      } else {
                                                          iconColor = GetIconColor(pageItem, false, useColors);
                                                      }
                                      
                                                      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 (existsState(pageItem.id + ".HUE")) {
                                                          if (getState(pageItem.id + ".HUE").val != null) {
                                                              let huecolor = hsv2rgb(getState(pageItem.id + ".HUE").val,1,1);
                                                              let rgb = <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);
                                                          } 
                                                      }
                                      
                                                      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 = <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 "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 = "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 = "closed"
                                                          }
                                                          RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                                      }
                                                      return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                                      
                                                  case "info":
                                      
                                                  case "humidity":
                                      
                                                  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 "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;
                                      
                                                  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~~~~~"
                                      }
                                      
                                      function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                                          // 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);
                                      }
                                      
                                      function RegisterEntityWatcher(id: string): void {
                                          if (subscriptions.hasOwnProperty(id)) {
                                              return;
                                          }
                                          subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                                              if(pageId >= 0)
                                                  SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                                              if(pageId == -1 && config.button1Page != undefined)
                                                  SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                                              if(pageId == -2 && config.button2Page != undefined)
                                                  SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                                          }))
                                      }
                                      
                                      function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                                          if (subscriptions.hasOwnProperty(id)) {
                                              return;
                                          }
                                          subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                                              SendToPanel(GenerateDetailPage(type, pageItem));
                                          }))
                                      }
                                      
                                      function GetUnitOfMeasurement(id: string): string {
                                          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 "";
                                      }
                                      
                                      function GenerateThermoPage(page: PageThermo): Payload[] {
                                          var id = page.items[0].id
                                          var out_msgs: Array<Payload> = [];
                                          out_msgs.push({ payload: "pageType~cardThermo" });
                                      
                                          // ioBroker
                                          if (existsObject(id)) {
                                              let o = getObject(id)
                                              let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                                              let currentTemp = 0;
                                              if (existsState(id + ".ACTUAL"))
                                                  currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                                      
                                              let destTemp = 0;
                                              if (existsState(id + ".SET")) {
                                                  destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                                              }
                                      
                                              let status = ""
                                              if (existsState(id + ".MODE"))
                                                  status = getState(id + ".MODE").val;
                                              let minTemp = 50 //Min Temp 5°C
                                              let maxTemp = 300 //Max Temp 30°C
                                              let stepTemp = 5
                                      
                                              //0-4 verwendet bei ungerader Anzahl Parametern
                                              let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                                              let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                                              let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                                              let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                                              let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                                              //5-8 verwendet bei gerader Anzahl Parametern
                                              let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                                              let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                                              let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                                              let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                                      
                                              if (existsState(id + ".HUMIDITY")){
                                                  bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                                  if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                                      bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                  } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                                      bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                  } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                                      bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                  } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                                      bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                  }
                                              }
                                      
                                              if (existsState(id + ".MAINTAIN")){
                                                  if (getState(id + ".MAINTAIN").val >> .1) {
                                                      bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                                  } else {
                                                      bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                                  }
                                              }
                                      
                                              if (existsState(id + ".UNREACH")){
                                                  if (getState(id + ".UNREACH").val) {
                                                      bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                                  } else {
                                                      bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                                  }
                                              }
                                      
                                              if (existsState(id + ".LOWBAT")){
                                                  if (getState(id + ".LOWBAT").val) {
                                                      bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                                  } else {
                                                      bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                                  }
                                              }
                                      
                                              let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                                      
                                              out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                                          }
                                      
                                          return out_msgs
                                      }
                                      
                                      function GenerateMediaPage(page: PageMedia): Payload[] {
                                          var id = page.items[0].id
                                          var out_msgs: Array<Payload> = [];
                                          out_msgs.push({ payload: "pageType~cardMedia" });
                                          if (existsObject(id)) {
                                      
                                              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;
                                              let volume = getState(id + ".VOLUME").val;
                                              var iconplaypause = Icons.GetIcon("pause"); //pause
                                              var onoffbutton = 1374;
                                              if (getState(id + ".STATE").val) {
                                                  onoffbutton = 65535;
                                                  iconplaypause = Icons.GetIcon("pause"); //pause
                                              } else {
                                                  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
                                      // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                                              let speakerlist = "";
                                              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 && 
                                                          existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                                          existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                                              speakerlist = speakerlist + getState(i).val + "?";
                                                      }
                                                  }
                                              }
                                              speakerlist = speakerlist.substring(0,speakerlist.length-1);
                                      //--------------------------------------------------------------------------------------------------------------
                                      
                                              out_msgs.push({ payload: "entityUpd~" + 
                                                                        name + "~" +
                                                                        id + "~" +
                                                                        id + "~" +         //????
                                                                        media_icon + "~" +
                                                                        title + "~" +
                                                                        author + "~" +
                                                                        volume + "~" +
                                                                        iconplaypause + "~" +
                                                                        currentSpeaker + "~" +
                                                                        speakerlist + "~" +
                                                                        onoffbutton});
                                          }
                                      
                                          return out_msgs
                                      }
                                      
                                      function GenerateAlarmPage(page: PageAlarm): Payload[] {
                                          var id = page.items[0].id
                                          var out_msgs: Array<Payload> = [];
                                          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 = 1;                           //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 = 1;                           //flashing*        
                                          }
                                              
                                          out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                                      id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                                      "~" +                      //???
                                                                      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*
                                      
                                          return out_msgs
                                      }
                                      
                                      function setIfExists(id: string, value: any, type: string | null = null): boolean {
                                          if (type === null) {
                                              if (existsState(id)) {
                                                  setState(id, value);
                                                  return true;
                                              }
                                          }
                                          else {
                                              let obj = getObject(id);
                                              if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                                  setState(id, value);
                                                  return true;
                                              }
                                          }
                                          return false;
                                      }
                                      
                                      function toggleState(id: string): boolean {
                                          let obj = getObject(id);
                                          if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                                              setState(id, !getState(id).val);
                                              return true;
                                          }
                                          return false;
                                      }
                                      
                                      function HandleButtonEvent(words): void {
                                          let id = words[2]
                                          let buttonAction = words[3];
                                      
                                          //console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                                      
                                          switch (buttonAction) {
                                              case "bNext":
                                                  var pageNum = ((pageId + 1) % config.pages.length);
                                                  pageId = Math.abs(pageNum);
                                                  UnsubscribeWatcher();
                                                  GeneratePage(config.pages[pageId]);
                                                  break;
                                              case "bPrev":
                                                  var pageNum = ((pageId - 1) % config.pages.length);
                                                  pageId = Math.abs(pageNum);
                                                  UnsubscribeWatcher();
                                                  GeneratePage(config.pages[pageId]);
                                                  break;
                                              case "bExit":
                                                  if (config.screenSaverDoubleClick) {
                                                      if (words[4] == 2)
                                                          GeneratePage(config.pages[pageId]);
                                                  }
                                                  else
                                                      GeneratePage(config.pages[pageId]);
                                                  break;
                                              case "OnOff":
                                                  if (existsObject(id)) {
                                                      var action = false
                                                      if (words[4] == "1")
                                                          action = true
                                                      let o = getObject(id)
                                                      switch (o.common.role) {
                                                          case "light":
                                                              setIfExists(id + ".SET", action);
                                                              break;
                                                          case "dimmer":
                                                              setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                                              break;
                                                          case "hue": // Armilar
                                                              setIfExists(id + ".ON_ACTUAL", action);
                                                      }
                                                  }
                                                  break;
                                              case "up":
                                                  setIfExists(id + ".OPEN", true)
                                                  break;
                                              case "stop":
                                                  setIfExists(id + ".STOP", true)
                                                  break;
                                              case "down":
                                                  setIfExists(id + ".CLOSE", true)
                                                  break;
                                              case "button":
                                                  toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                                  break;
                                              case "positionSlider":
                                                  setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                                  break;
                                              case "brightnessSlider":
                                                  if (existsObject(id)) {
                                                      let o = getObject(id);
                                                      let pageItem = config.pages[pageId].items.find(e => e.id === 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 "hue":
                                      
                                                          case "rgb":
                                                              setIfExists(id + ".DIMMER", parseInt(words[4]));
                                                      }
                                                  }
                                                  break;
                                              case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                                  let pageItem = config.pages[pageId].items.find(e => e.id === 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]);
                                                  }
                                                  break;
                                              case "colorWheel":
                                                  let colorCoordinates = words[4].split('|');
                                                  let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                                  //console.log(rgb);
                                                  //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 "tempUpd":
                                                  setIfExists(id + ".SET", parseInt(words[4]) / 10)
                                                  break;
                                              case "media-back":
                                                  setIfExists(id + ".PREV", true)
                                                  break;
                                              case "media-pause":
                                                  if (getState(id + ".STATE").val === true) {
                                                      setIfExists(id + ".PAUSE", true)
                                                  } else {
                                                      setIfExists(id + ".PLAY", true)
                                                  }
                                                  break;
                                              case "media-next":
                                                  setIfExists(id + ".NEXT", true)
                                                  break;
                                              case "volumeSlider":
                                                  setIfExists(id + ".VOLUME", parseInt(words[4]))
                                                  break;
                                              case "speaker-sel":
                                                  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];
                                                      if ((getState(i).val) === words[4]){
                                                          let deviceId = i;
                                                          deviceId = deviceId.split('.');
                                                          setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                                          alexaDevice = deviceId[3]
                                                      }
                                                  }
                                                  break;
                                              case "media-OnOff":
                                                  setIfExists(id + ".STOP", true)
                                                  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:
                                                  return "0|1";
                                              case config.pages.length - 1:
                                                  return "1|0";
                                              case -1:
                                                  return "0|0";
                                              default:
                                                  return "1|1";
                                          }
                                      }
                                      
                                      function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                                      
                                          var out_msgs: Array<Payload> = [];
                                          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") {
                                                      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);
                                                      }
                                      
                                                      if (val) {
                                                          switchVal = "1";
                                                          iconColor = GetIconColor(pageItem, true, false);
                                                      }
                                      
                                                      out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                                  }
                                      
                                                  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);
                                                      
                                                      let colorTemp = "disable"
                                                      let colorMode = "disable"
                                      
                                                      out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                  }
                                                  //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                  }
                                      
                                                  //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                  }
                                      
                                              }
                                      
                                              if (type == "popupShutter") {
                                                  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);
                                                  }
                                                  out_msgs.push({ payload: "entityUpdateDetail~" + val })
                                              }
                                          }
                                          return out_msgs
                                      }
                                      
                                      function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                                          return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                                      }
                                      
                                      function UnsubscribeWatcher(): void {
                                          for (const [key, value] of Object.entries(subscriptions)) {
                                              unsubscribe(value);
                                              delete subscriptions[key]
                                          }
                                      }
                                      
                                      function HandleScreensaver(): void {
                                          SendToPanel({ payload: "pageType~screensaver"})
                                          UnsubscribeWatcher();
                                          HandleScreensaverUpdate();
                                      }
                                      
                                      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++) {
                                                      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);
                                                      payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                                  }
                                              } 
                                              else {
                                                  //In Config definierte Zustände wenn weatherForecast = false
                                                  payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                                  payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                                  payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                                  payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                                              }
                                      /*-------------------------------------------------------------------------------------------------------------------------------------*/
                                       
                                              SendToPanel(<Payload>{ payload: payloadString });
                                          }
                                      }
                                      
                                      function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                                          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 "~~~";
                                          }
                                      }
                                      
                                      function GetAccuWeatherIcon(icon: number): string {
                                          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";
                                          }
                                      }
                                      
                                      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 <RGB>{ 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)));
                                      }
                                      
                                      /* 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;
                                      }
                                      
                                      /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                                      }
                                      
                                      type RGB = {
                                          red: number,
                                          green: number,
                                          blue: number
                                      };
                                      
                                      type Payload = {
                                          payload: string;
                                      };
                                      
                                      type Page = {
                                          type: string,
                                          heading: string,
                                          items: PageItem[],
                                          useColor: boolean
                                      };
                                      
                                      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[],
                                      };
                                      
                                      type PageItem = {
                                          id: string,
                                          icon: (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),
                                          unit: (string | undefined)
                                      }
                                      
                                      type Config = {
                                          panelRecvTopic: string,
                                          panelSendTopic: string,
                                          timeoutScreensaver: number,
                                          dimmode: number,
                                          //brightnessScreensaver:
                                          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,
                                          defaultColor: RGB,
                                          defaultOnColor: RGB,
                                          defaultOffColor: RGB,
                                          pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                                          button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                          button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                      };
                                      
                                      type ScreenSaverElement = {
                                          ScreensaverEntity: string | null,
                                          ScreensaverEntityIcon: string | null,
                                          ScreensaverEntityText: string | null,
                                          ScreensaverEntityUnitText: string | null,
                                      }
                                      

                                      P.S.: Der Alias-Typ "RGB-Licht" sollte jetzt auch gehen...

                                      D Offline
                                      D Offline
                                      Dexxter
                                      wrote on last edited by
                                      #373

                                      @armilar
                                      Kann es sein das Du den case "hue" vergessen hast?
                                      minValueBrightness und maxValueBrightness funktionieren beim Dimmer super aber beim Hue
                                      haben sie keine Funktion.
                                      slider_LI.jpg

                                      kann das vielleicht daran liegen?

                                      ArmilarA 1 Reply Last reply
                                      0
                                      • D Dexxter

                                        @armilar
                                        Kann es sein das Du den case "hue" vergessen hast?
                                        minValueBrightness und maxValueBrightness funktionieren beim Dimmer super aber beim Hue
                                        haben sie keine Funktion.
                                        slider_LI.jpg

                                        kann das vielleicht daran liegen?

                                        ArmilarA Offline
                                        ArmilarA Offline
                                        Armilar
                                        Most Active Forum Testing
                                        wrote on last edited by Armilar
                                        #374

                                        @dexxter sagte in Sonoff NSPanel:

                                        @armilar
                                        Kann es sein das Du den case "hue" vergessen hast?
                                        minValueBrightness und maxValueBrightness funktionieren beim Dimmer super aber beim Hue
                                        haben sie keine Funktion.
                                        slider_LI.jpg

                                        kann das vielleicht daran liegen?

                                        Ist wohl so 👍
                                        Habe den RBG-Licht-einzeln (HEX) gleich mit eingebaut

                                        var Icons = new IconsSelector();
                                        
                                        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 Off: RGB = { red: 68, green: 115, blue: 158 }; //Blau-Off
                                        const Off: RGB = { red: 253, green: 128, blue: 0 }; //Orange-Off
                                        const On: RGB = { red: 253, green: 216, blue: 53 };
                                        const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                                        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 };
                                        
                                        
                                        //----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 ...
                                        
                                        //Alexa-Instanz
                                        var alexaInstanz = "alexa2.0"
                                        var alexaDevice = "G0XXXXXXXXXXXXXXXX"; //Primär zu steuendes Device
                                        
                                        // 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.NSPanel.1.popupNotifyHeading";
                                        var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                                        
                                        var Test_Licht: PageEntities =
                                        {
                                            "type": "cardEntities",
                                            "heading": "Büro",
                                            "useColor": true,
                                            "items": [
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestRGBLichteinzeln", name: "RGB-Licht Hex-Color", interpolateColor: true},
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestRGBLicht", name: "RGB-Licht", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Licht-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true},
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Licht-Color", minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true}
                                            ]
                                        };
                                        
                                        var Buero_Seite_1: PageEntities =
                                        {
                                            "type": "cardEntities",
                                            "heading": "Büro",
                                            "useColor": true,
                                            "items": [
                                                <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", interpolateColor: true},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                                            ]
                                        };
                                        
                                        var Fenster_1: PageEntities =
                                        {
                                            "type": "cardEntities",
                                            "heading": "Fenster und Türen",
                                            "useColor": true,
                                            "items": [
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                                            ]
                                        };
                                        
                                        var Abfall: PageEntities =
                                        {
                                            "type": "cardEntities",
                                            "heading": "Abfallkalender",
                                            "useColor": true,
                                            "items": [
                                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                                            ]
                                        };
                                        
                                        var Buero_Seite_2: PageGrid =
                                        {
                                            "type": "cardGrid",
                                            "heading": "Büro 2",
                                            "useColor": true,
                                            "items": [
                                                <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                                                <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                                            ]
                                        };
                                        
                                        var Alexa: PageMedia = 
                                        {
                                            "type": "cardMedia",
                                            "heading": "Alexa",
                                            "useColor": true,
                                            "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                                        };
                                        
                                        var Buero_Themostat: PageThermo = 
                                        {
                                            "type": "cardThermo",
                                            "heading": "Thermostat",
                                            "useColor": true,
                                            "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                                        };
                                        
                                        var Buero_Alarm: PageAlarm = 
                                        {
                                            "type": "cardAlarm",
                                            "heading": "Alarm",
                                            "useColor": true,
                                            "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                                        };
                                        
                                        var button1Page: PageGrid =
                                        {
                                            "type": "cardGrid",
                                            "heading": "Radio",
                                            "useColor": true,
                                            "items": [
                                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                                            ]
                                        };
                                        
                                        var button2Page: PageEntities =
                                        {
                                            "type": "cardEntities",
                                            "heading": "Büro",
                                            "useColor": true,
                                            "items": [
                                                <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                                <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                                            ]
                                        };
                                        
                                        export const config: Config = {
                                            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,
                                            locale: "de_DE",
                                            timeFormat: "%H:%M",
                                            dateFormat: "%A, %d. %B %Y",
                                            weatherEntity: "alias.0.Wetter.Wetter",
                                            defaultOffColor: Off,
                                            defaultOnColor: On,
                                            defaultColor: Off,
                                            temperatureUnit: "°C",
                                            pages: [
                                                    Buero_Seite_1,
                                                    Test_Licht,
                                                    Fenster_1,
                                                    Abfall,
                                                    Buero_Seite_2,
                                                    Alexa,
                                                    Buero_Themostat,
                                                    Buero_Alarm
                                            ],
                                            button1Page: button1Page,
                                            button2Page: button2Page
                                        };
                                        
                                        // _________________________________ 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;
                                        
                                        schedule("* * * * *", function () {
                                            SendTime();
                                        });
                                        schedule("0 * * * *", function () {
                                            SendDate();
                                        });
                                        
                                        
                                        // 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, function () {
                                                HandleScreensaverUpdate();
                                            })
                                        }
                                        on({ id: config.panelRecvTopic }, function (obj) {
                                            if (obj.state.val.startsWith('\{"CustomRecv":')) {
                                                var json = JSON.parse(obj.state.val);
                                        
                                                var split = json.CustomRecv.split(",");
                                                HandleMessage(split[0], split[1], parseInt(split[2]), split);
                                            }
                                        });
                                        
                                        function SendToPanel(val: Payload | Payload[]): void {
                                            if (Array.isArray(val)) {
                                                val.forEach(function (id, i) {
                                                    setState(config.panelSendTopic, id.payload);
                                                });
                                            }
                                            else
                                                setState(config.panelSendTopic, val.payload);
                                        }
                                        
                                        function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                                            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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                                        if (pageItem !== undefined)
                                                            SendToPanel(GenerateDetailPage(words[2], pageItem));
                                                    case "buttonPress2":
                                                        screensaverEnabled = false;
                                                        HandleButtonEvent(words);
                                                        break;
                                                    case "button1":
                                                    case "button2":
                                                        screensaverEnabled = false;
                                                        HandleHardwareButton(method);
                                                    default:
                                                        break;
                                                }
                                            }
                                        }
                                        
                                        function GeneratePage(page: Page): void {
                                            switch (page.type) {
                                                case "cardEntities":
                                                    SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                                    break;
                                                case "cardThermo":
                                                    SendToPanel(GenerateThermoPage(<PageThermo>page));
                                                    break;
                                                case "cardGrid":
                                                    SendToPanel(GenerateGridPage(<PageGrid>page));
                                                    break;
                                                case "cardMedia":
                                                    SendToPanel(GenerateMediaPage(<PageMedia>page));
                                                    break;
                                                case "cardAlarm":
                                                    SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                                    break;
                                            }
                                        }
                                        
                                        function HandleHardwareButton(method: string): void {
                                            let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                                            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);
                                        }
                                        
                                        function HandleStartupProcess(): void {
                                            SendDate();
                                            SendTime();
                                            SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                                            SendToPanel({ payload: "dimmode~" + config.dimmode });
                                        }
                                        
                                        function SendDate(): void {
                                            var d = new Date();
                                            var day = Days[d.getDay()];
                                            var date = d.getDate();
                                            var month = Months[d.getMonth()];
                                            var year = d.getFullYear();
                                            var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                                            SendToPanel(<Payload>{ payload: _sendDate });
                                        }
                                        
                                        function SendTime(): void {
                                            var d = new Date();
                                            var hr = d.getHours().toString();
                                            var min = d.getMinutes().toString();
                                        
                                            if (d.getHours() < 10) {
                                                hr = "0" + d.getHours().toString();
                                            }
                                            if (d.getMinutes() < 10) {
                                                min = "0" + d.getMinutes().toString();
                                            }
                                            SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                                        }
                                        
                                        function GenerateEntitiesPage(page: PageEntities): Payload[] {
                                            var out_msgs: Array<Payload> = [];
                                            out_msgs = [{ payload: "pageType~cardEntities" }]
                                            out_msgs.push({ payload: GeneratePageElements(page) });
                                            return out_msgs
                                        }
                                        
                                        function GenerateGridPage(page: PageGrid): Payload[] {
                                            var out_msgs: Array<Payload> = [];
                                            out_msgs = [{ payload: "pageType~cardGrid" }]
                                            out_msgs.push({ payload: GeneratePageElements(page) });
                                            return out_msgs
                                        }
                                        
                                        function GeneratePageElements(page: Page): string {
                                            let maxItems = 0;
                                            switch (page.type) {
                                                case "cardThermo":
                                                    maxItems = 1;
                                                    break;
                                                case "cardAlarm":
                                                    maxItems = 1;
                                                    break;
                                                case "cardMedia":
                                                    maxItems = 1;
                                                    break;
                                                case "cardEntities":
                                                    maxItems = 4;
                                                    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);
                                                }
                                                else {
                                                    pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                                                }
                                            }
                                            return pageData;
                                        }
                                        
                                        function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                                            var iconId = "0"
                                            if (pageItem.id == "delete") {
                                                return "~delete~~~~~"
                                            }
                                            var name: string;
                                            var type: string;
                                        
                                            // ioBroker
                                            if (existsObject(pageItem.id)) {
                                                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;
                                                    RegisterEntityWatcher(pageItem.id + ".GET");
                                                }
                                                else if (existsState(pageItem.id + ".SET")) {
                                                    val = getState(pageItem.id + ".SET").val;
                                                    RegisterEntityWatcher(pageItem.id + ".SET");
                                                }
                                                var iconColor = rgb_dec565(config.defaultColor);
                                        
                                                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 optVal = "0"
                                        
                                                        if (val === true || val === "true") {
                                                            optVal = "1"
                                                            iconColor = GetIconColor(pageItem, true, useColors);
                                                        } else {
                                                            iconColor = GetIconColor(pageItem, false, useColors);
                                                        }
                                        
                                                        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 (existsState(pageItem.id + ".HUE")) {
                                                            if (getState(pageItem.id + ".HUE").val != null) {
                                                                let huecolor = hsv2rgb(getState(pageItem.id + ".HUE").val,1,1);
                                                                let rgb = <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);
                                                            } 
                                                        }
                                        
                                                        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 = <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 = <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 = "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 = "closed"
                                                            }
                                                            RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                                        }
                                                        return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                                        
                                                    case "info":
                                        
                                                    case "humidity":
                                        
                                                    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 "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;
                                        
                                                    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~~~~~"
                                        }
                                        
                                        function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                                            // 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);
                                        }
                                        
                                        function RegisterEntityWatcher(id: string): void {
                                            if (subscriptions.hasOwnProperty(id)) {
                                                return;
                                            }
                                            subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                                                if(pageId >= 0)
                                                    SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                                                if(pageId == -1 && config.button1Page != undefined)
                                                    SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                                                if(pageId == -2 && config.button2Page != undefined)
                                                    SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                                            }))
                                        }
                                        
                                        function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                                            if (subscriptions.hasOwnProperty(id)) {
                                                return;
                                            }
                                            subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                                                SendToPanel(GenerateDetailPage(type, pageItem));
                                            }))
                                        }
                                        
                                        function GetUnitOfMeasurement(id: string): string {
                                            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 "";
                                        }
                                        
                                        function GenerateThermoPage(page: PageThermo): Payload[] {
                                            var id = page.items[0].id
                                            var out_msgs: Array<Payload> = [];
                                            out_msgs.push({ payload: "pageType~cardThermo" });
                                        
                                            // ioBroker
                                            if (existsObject(id)) {
                                                let o = getObject(id)
                                                let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                                                let currentTemp = 0;
                                                if (existsState(id + ".ACTUAL"))
                                                    currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                                        
                                                let destTemp = 0;
                                                if (existsState(id + ".SET")) {
                                                    destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                                                }
                                        
                                                let status = ""
                                                if (existsState(id + ".MODE"))
                                                    status = getState(id + ".MODE").val;
                                                let minTemp = 50 //Min Temp 5°C
                                                let maxTemp = 300 //Max Temp 30°C
                                                let stepTemp = 5
                                        
                                                //0-4 verwendet bei ungerader Anzahl Parametern
                                                let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                                                let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                                                let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                                                let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                                                let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                                                //5-8 verwendet bei gerader Anzahl Parametern
                                                let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                                                let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                                                let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                                                let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                                        
                                                if (existsState(id + ".HUMIDITY")){
                                                    bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                                    if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                                        bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                    } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                                        bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                    } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                                        bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                    } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                                        bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                    }
                                                }
                                        
                                                if (existsState(id + ".MAINTAIN")){
                                                    if (getState(id + ".MAINTAIN").val >> .1) {
                                                        bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                                    } else {
                                                        bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                                    }
                                                }
                                        
                                                if (existsState(id + ".UNREACH")){
                                                    if (getState(id + ".UNREACH").val) {
                                                        bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                                    } else {
                                                        bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                                    }
                                                }
                                        
                                                if (existsState(id + ".LOWBAT")){
                                                    if (getState(id + ".LOWBAT").val) {
                                                        bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                                    } else {
                                                        bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                                    }
                                                }
                                        
                                                let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                                        
                                                out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                                            }
                                        
                                            return out_msgs
                                        }
                                        
                                        function GenerateMediaPage(page: PageMedia): Payload[] {
                                            var id = page.items[0].id
                                            var out_msgs: Array<Payload> = [];
                                            out_msgs.push({ payload: "pageType~cardMedia" });
                                            if (existsObject(id)) {
                                        
                                                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;
                                                let volume = getState(id + ".VOLUME").val;
                                                var iconplaypause = Icons.GetIcon("pause"); //pause
                                                var onoffbutton = 1374;
                                                if (getState(id + ".STATE").val) {
                                                    onoffbutton = 65535;
                                                    iconplaypause = Icons.GetIcon("pause"); //pause
                                                } else {
                                                    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
                                        // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                                                let speakerlist = "";
                                                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 && 
                                                            existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                                            existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                                                speakerlist = speakerlist + getState(i).val + "?";
                                                        }
                                                    }
                                                }
                                                speakerlist = speakerlist.substring(0,speakerlist.length-1);
                                        //--------------------------------------------------------------------------------------------------------------
                                        
                                                out_msgs.push({ payload: "entityUpd~" + 
                                                                          name + "~" +
                                                                          id + "~" +
                                                                          id + "~" +         //????
                                                                          media_icon + "~" +
                                                                          title + "~" +
                                                                          author + "~" +
                                                                          volume + "~" +
                                                                          iconplaypause + "~" +
                                                                          currentSpeaker + "~" +
                                                                          speakerlist + "~" +
                                                                          onoffbutton});
                                            }
                                        
                                            return out_msgs
                                        }
                                        
                                        function GenerateAlarmPage(page: PageAlarm): Payload[] {
                                            var id = page.items[0].id
                                            var out_msgs: Array<Payload> = [];
                                            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 = 1;                           //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 = 1;                           //flashing*        
                                            }
                                                
                                            out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                                        id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                                        "~" +                      //???
                                                                        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*
                                        
                                            return out_msgs
                                        }
                                        
                                        function setIfExists(id: string, value: any, type: string | null = null): boolean {
                                            if (type === null) {
                                                if (existsState(id)) {
                                                    setState(id, value);
                                                    return true;
                                                }
                                            }
                                            else {
                                                let obj = getObject(id);
                                                if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                                    setState(id, value);
                                                    return true;
                                                }
                                            }
                                            return false;
                                        }
                                        
                                        function toggleState(id: string): boolean {
                                            let obj = getObject(id);
                                            if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                                                setState(id, !getState(id).val);
                                                return true;
                                            }
                                            return false;
                                        }
                                        
                                        function HandleButtonEvent(words): void {
                                            let id = words[2]
                                            let buttonAction = words[3];
                                        
                                            //console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                                        
                                            switch (buttonAction) {
                                                case "bNext":
                                                    var pageNum = ((pageId + 1) % config.pages.length);
                                                    pageId = Math.abs(pageNum);
                                                    UnsubscribeWatcher();
                                                    GeneratePage(config.pages[pageId]);
                                                    break;
                                                case "bPrev":
                                                    var pageNum = ((pageId - 1) % config.pages.length);
                                                    pageId = Math.abs(pageNum);
                                                    UnsubscribeWatcher();
                                                    GeneratePage(config.pages[pageId]);
                                                    break;
                                                case "bExit":
                                                    if (config.screenSaverDoubleClick) {
                                                        if (words[4] == 2)
                                                            GeneratePage(config.pages[pageId]);
                                                    }
                                                    else
                                                        GeneratePage(config.pages[pageId]);
                                                    break;
                                                case "OnOff":
                                                    if (existsObject(id)) {
                                                        var action = false
                                                        if (words[4] == "1")
                                                            action = true
                                                        let o = getObject(id)
                                                        switch (o.common.role) {
                                                            case "light":
                                                                setIfExists(id + ".SET", action);
                                                                break;
                                                            case "dimmer":
                                                                setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                                                break;
                                                            case "rgb":
                                                            case "rgbSingle":
                                                            case "hue": // Armilar
                                                                setIfExists(id + ".ON_ACTUAL", action);
                                                        }
                                                    }
                                                    break;
                                                case "up":
                                                    setIfExists(id + ".OPEN", true)
                                                    break;
                                                case "stop":
                                                    setIfExists(id + ".STOP", true)
                                                    break;
                                                case "down":
                                                    setIfExists(id + ".CLOSE", true)
                                                    break;
                                                case "button":
                                                    toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                                    break;
                                                case "positionSlider":
                                                    setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                                    break;
                                                case "brightnessSlider":
                                                    if (existsObject(id)) {
                                                        let o = getObject(id);
                                                        let pageItem = config.pages[pageId].items.find(e => e.id === 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 "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])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                                                }
                                                                break;
                                                        }
                                                    }
                                                    break;
                                                case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                                    let pageItem = config.pages[pageId].items.find(e => e.id === 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]);
                                                    }
                                                    break;
                                                case "colorWheel":
                                                    let colorCoordinates = words[4].split('|');
                                                    let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                                    //console.log(rgb);
                                                    //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":
                                                            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;
                                                case "media-pause":
                                                    if (getState(id + ".STATE").val === true) {
                                                        setIfExists(id + ".PAUSE", true)
                                                    } else {
                                                        setIfExists(id + ".PLAY", true)
                                                    }
                                                    break;
                                                case "media-next":
                                                    setIfExists(id + ".NEXT", true)
                                                    break;
                                                case "volumeSlider":
                                                    setIfExists(id + ".VOLUME", parseInt(words[4]))
                                                    break;
                                                case "speaker-sel":
                                                    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];
                                                        if ((getState(i).val) === words[4]){
                                                            let deviceId = i;
                                                            deviceId = deviceId.split('.');
                                                            setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                                            alexaDevice = deviceId[3]
                                                        }
                                                    }
                                                    break;
                                                case "media-OnOff":
                                                    setIfExists(id + ".STOP", true)
                                                    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:
                                                    return "0|1";
                                                case config.pages.length - 1:
                                                    return "1|0";
                                                case -1:
                                                    return "0|0";
                                                default:
                                                    return "1|1";
                                            }
                                        }
                                        
                                        function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                                        
                                            var out_msgs: Array<Payload> = [];
                                            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") {
                                                        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);
                                                        }
                                        
                                                        if (val) {
                                                            switchVal = "1";
                                                            iconColor = GetIconColor(pageItem, true, false);
                                                        }
                                        
                                                        out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                                    }
                                        
                                                    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);
                                                        
                                                        let colorTemp = "disable"
                                                        let colorMode = "disable"
                                        
                                                        out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                    }
                                                    //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                    }
                                        
                                                    //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                    }
                                        
                                                    //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                    }
                                        
                                                }
                                        
                                                if (type == "popupShutter") {
                                                    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);
                                                    }
                                                    out_msgs.push({ payload: "entityUpdateDetail~" + val })
                                                }
                                            }
                                            return out_msgs
                                        }
                                        
                                        function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                                            return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                                        }
                                        
                                        function UnsubscribeWatcher(): void {
                                            for (const [key, value] of Object.entries(subscriptions)) {
                                                unsubscribe(value);
                                                delete subscriptions[key]
                                            }
                                        }
                                        
                                        function HandleScreensaver(): void {
                                            SendToPanel({ payload: "pageType~screensaver"})
                                            UnsubscribeWatcher();
                                            HandleScreensaverUpdate();
                                        }
                                        
                                        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++) {
                                                        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);
                                                        payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                                    }
                                                } 
                                                else {
                                                    //In Config definierte Zustände wenn weatherForecast = false
                                                    payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                                    payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                                    payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                                    payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                                                }
                                        /*-------------------------------------------------------------------------------------------------------------------------------------*/
                                         
                                                SendToPanel(<Payload>{ payload: payloadString });
                                            }
                                        }
                                        
                                        function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                                            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 "~~~";
                                            }
                                        }
                                        
                                        function GetAccuWeatherIcon(icon: number): string {
                                            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";
                                            }
                                        }
                                        
                                        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 <RGB>{ 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)));
                                        }
                                        
                                        /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                                        }
                                        
                                        type RGB = {
                                            red: number,
                                            green: number,
                                            blue: number
                                        };
                                        
                                        type Payload = {
                                            payload: string;
                                        };
                                        
                                        type Page = {
                                            type: string,
                                            heading: string,
                                            items: PageItem[],
                                            useColor: boolean
                                        };
                                        
                                        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[],
                                        };
                                        
                                        type PageItem = {
                                            id: string,
                                            icon: (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),
                                            unit: (string | undefined)
                                        }
                                        
                                        type Config = {
                                            panelRecvTopic: string,
                                            panelSendTopic: string,
                                            timeoutScreensaver: number,
                                            dimmode: number,
                                            //brightnessScreensaver:
                                            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,
                                            defaultColor: RGB,
                                            defaultOnColor: RGB,
                                            defaultOffColor: RGB,
                                            pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                                            button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                            button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                        };
                                        
                                        type ScreenSaverElement = {
                                            ScreensaverEntity: string | null,
                                            ScreensaverEntityIcon: string | null,
                                            ScreensaverEntityText: string | null,
                                            ScreensaverEntityUnitText: string | null,
                                        }
                                        

                                        Installationsanleitung, Tipps, Alias-Definitionen, FAQ für das Sonoff NSPanel mit lovelace UI unter ioBroker
                                        https://github.com/joBr99/nspanel-lovelace-ui/wiki

                                        Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                                        D 1 Reply Last reply
                                        0
                                        • ArmilarA Armilar

                                          @dexxter sagte in Sonoff NSPanel:

                                          @armilar
                                          Kann es sein das Du den case "hue" vergessen hast?
                                          minValueBrightness und maxValueBrightness funktionieren beim Dimmer super aber beim Hue
                                          haben sie keine Funktion.
                                          slider_LI.jpg

                                          kann das vielleicht daran liegen?

                                          Ist wohl so 👍
                                          Habe den RBG-Licht-einzeln (HEX) gleich mit eingebaut

                                          var Icons = new IconsSelector();
                                          
                                          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 Off: RGB = { red: 68, green: 115, blue: 158 }; //Blau-Off
                                          const Off: RGB = { red: 253, green: 128, blue: 0 }; //Orange-Off
                                          const On: RGB = { red: 253, green: 216, blue: 53 };
                                          const MSRed: RGB = { red: 251, green: 105, blue: 98 };
                                          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 };
                                          
                                          
                                          //----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 ...
                                          
                                          //Alexa-Instanz
                                          var alexaInstanz = "alexa2.0"
                                          var alexaDevice = "G0XXXXXXXXXXXXXXXX"; //Primär zu steuendes Device
                                          
                                          // 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.NSPanel.1.popupNotifyHeading";
                                          var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
                                          
                                          var Test_Licht: PageEntities =
                                          {
                                              "type": "cardEntities",
                                              "heading": "Büro",
                                              "useColor": true,
                                              "items": [
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestRGBLichteinzeln", name: "RGB-Licht Hex-Color", interpolateColor: true},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestRGBLicht", name: "RGB-Licht", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestCTmitHUE", name: "HUE-Licht-CT", minValueBrightness: 0, maxValueBrightness: 70, minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestHUELicht", name: "HUE-Licht-Color", minValueColorTemp: 500, maxValueColorTemp: 6500, interpolateColor: true}
                                              ]
                                          };
                                          
                                          var Buero_Seite_1: PageEntities =
                                          {
                                              "type": "cardEntities",
                                              "heading": "Büro",
                                              "useColor": true,
                                              "items": [
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", interpolateColor: true},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Testlampe2", name: "Filamentlampe", minValueBrightness: 0, maxValueBrightness: 70, interpolateColor: true},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen}
                                              ]
                                          };
                                          
                                          var Fenster_1: PageEntities =
                                          {
                                              "type": "cardEntities",
                                              "heading": "Fenster und Türen",
                                              "useColor": true,
                                              "items": [
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Haustuer", offColor: MSRed, onColor: MSGreen, name: "Haustür"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", onColor: White, name: "IKEA Fyrtur"}
                                              ]
                                          };
                                          
                                          var Abfall: PageEntities =
                                          {
                                              "type": "cardEntities",
                                              "heading": "Abfallkalender",
                                              "useColor": true,
                                              "items": [
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event1",icon: "trash-can"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event2",icon: "trash-can"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event3",icon: "trash-can"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Abfall.event4",icon: "trash-can"}
                                              ]
                                          };
                                          
                                          var Buero_Seite_2: PageGrid =
                                          {
                                              "type": "cardGrid",
                                              "heading": "Büro 2",
                                              "useColor": true,
                                              "items": [
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe", name: "Schreibtisch"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung", name: "Deckenlampe"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestFenster", offColor: MSRed, onColor: MSGreen, name: "Büro Fenster"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Luftreiniger", icon: "power", offColor: MSRed, onColor: MSGreen},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.TestBlind", icon: "projector-screen", onColor: White, name: "Beamer"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Radio.TuneIn", icon: "play", onColor: White}
                                              ]
                                          };
                                          
                                          var Alexa: PageMedia = 
                                          {
                                              "type": "cardMedia",
                                              "heading": "Alexa",
                                              "useColor": true,
                                              "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
                                          };
                                          
                                          var Buero_Themostat: PageThermo = 
                                          {
                                              "type": "cardThermo",
                                              "heading": "Thermostat",
                                              "useColor": true,
                                              "items": [<PageItem>{ id: "alias.0.NSPanel_1.Thermostat_Büro" }]
                                          };
                                          
                                          var Buero_Alarm: PageAlarm = 
                                          {
                                              "type": "cardAlarm",
                                              "heading": "Alarm",
                                              "useColor": true,
                                              "items": [<PageItem>{ id: "alias.0.NSPanel_1.Alarm" }]
                                          };
                                          
                                          var button1Page: PageGrid =
                                          {
                                              "type": "cardGrid",
                                              "heading": "Radio",
                                              "useColor": true,
                                              "items": [
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Radio.FFN", icon: "radio", name: "FFN", onColor: colorRadio},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Radio.Antenne" , icon: "radio", name: "Antenne Nds.", onColor: colorRadio},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Radio.NDR2", icon: "radio", name: "NDR2", onColor: colorRadio},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Radio.Bob", icon: "radio", name: "Radio BOB", onColor: colorRadio},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Radio.Spotify", icon: "spotify", name: "Party Playlist", onColor: colorSpotify},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Radio.Alexa", icon: "playlist-music", name: "Playlist 2021", onColor: colorAlexa}
                                              ]
                                          };
                                          
                                          var button2Page: PageEntities =
                                          {
                                              "type": "cardEntities",
                                              "heading": "Büro",
                                              "useColor": true,
                                              "items": [
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Schreibtischlampe"},
                                                  <PageItem>{ id: "alias.0.NSPanel_1.Deckenbeleuchtung"}
                                              ]
                                          };
                                          
                                          export const config: Config = {
                                              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,
                                              locale: "de_DE",
                                              timeFormat: "%H:%M",
                                              dateFormat: "%A, %d. %B %Y",
                                              weatherEntity: "alias.0.Wetter.Wetter",
                                              defaultOffColor: Off,
                                              defaultOnColor: On,
                                              defaultColor: Off,
                                              temperatureUnit: "°C",
                                              pages: [
                                                      Buero_Seite_1,
                                                      Test_Licht,
                                                      Fenster_1,
                                                      Abfall,
                                                      Buero_Seite_2,
                                                      Alexa,
                                                      Buero_Themostat,
                                                      Buero_Alarm
                                              ],
                                              button1Page: button1Page,
                                              button2Page: button2Page
                                          };
                                          
                                          // _________________________________ 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;
                                          
                                          schedule("* * * * *", function () {
                                              SendTime();
                                          });
                                          schedule("0 * * * *", function () {
                                              SendDate();
                                          });
                                          
                                          
                                          // 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, function () {
                                                  HandleScreensaverUpdate();
                                              })
                                          }
                                          on({ id: config.panelRecvTopic }, function (obj) {
                                              if (obj.state.val.startsWith('\{"CustomRecv":')) {
                                                  var json = JSON.parse(obj.state.val);
                                          
                                                  var split = json.CustomRecv.split(",");
                                                  HandleMessage(split[0], split[1], parseInt(split[2]), split);
                                              }
                                          });
                                          
                                          function SendToPanel(val: Payload | Payload[]): void {
                                              if (Array.isArray(val)) {
                                                  val.forEach(function (id, i) {
                                                      setState(config.panelSendTopic, id.payload);
                                                  });
                                              }
                                              else
                                                  setState(config.panelSendTopic, val.payload);
                                          }
                                          
                                          function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void {
                                              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 = config.pages[pageId].items.find(e => e.id === words[3]);
                                                          if (pageItem !== undefined)
                                                              SendToPanel(GenerateDetailPage(words[2], pageItem));
                                                      case "buttonPress2":
                                                          screensaverEnabled = false;
                                                          HandleButtonEvent(words);
                                                          break;
                                                      case "button1":
                                                      case "button2":
                                                          screensaverEnabled = false;
                                                          HandleHardwareButton(method);
                                                      default:
                                                          break;
                                                  }
                                              }
                                          }
                                          
                                          function GeneratePage(page: Page): void {
                                              switch (page.type) {
                                                  case "cardEntities":
                                                      SendToPanel(GenerateEntitiesPage(<PageEntities>page));
                                                      break;
                                                  case "cardThermo":
                                                      SendToPanel(GenerateThermoPage(<PageThermo>page));
                                                      break;
                                                  case "cardGrid":
                                                      SendToPanel(GenerateGridPage(<PageGrid>page));
                                                      break;
                                                  case "cardMedia":
                                                      SendToPanel(GenerateMediaPage(<PageMedia>page));
                                                      break;
                                                  case "cardAlarm":
                                                      SendToPanel(GenerateAlarmPage(<PageAlarm>page));
                                                      break;
                                              }
                                          }
                                          
                                          function HandleHardwareButton(method: string): void {
                                              let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid);
                                              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);
                                          }
                                          
                                          function HandleStartupProcess(): void {
                                              SendDate();
                                              SendTime();
                                              SendToPanel({ payload: "timeout~" + config.timeoutScreensaver });
                                              SendToPanel({ payload: "dimmode~" + config.dimmode });
                                          }
                                          
                                          function SendDate(): void {
                                              var d = new Date();
                                              var day = Days[d.getDay()];
                                              var date = d.getDate();
                                              var month = Months[d.getMonth()];
                                              var year = d.getFullYear();
                                              var _sendDate = "date~" + day + " " + date + " " + month + " " + year;
                                              SendToPanel(<Payload>{ payload: _sendDate });
                                          }
                                          
                                          function SendTime(): void {
                                              var d = new Date();
                                              var hr = d.getHours().toString();
                                              var min = d.getMinutes().toString();
                                          
                                              if (d.getHours() < 10) {
                                                  hr = "0" + d.getHours().toString();
                                              }
                                              if (d.getMinutes() < 10) {
                                                  min = "0" + d.getMinutes().toString();
                                              }
                                              SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min });
                                          }
                                          
                                          function GenerateEntitiesPage(page: PageEntities): Payload[] {
                                              var out_msgs: Array<Payload> = [];
                                              out_msgs = [{ payload: "pageType~cardEntities" }]
                                              out_msgs.push({ payload: GeneratePageElements(page) });
                                              return out_msgs
                                          }
                                          
                                          function GenerateGridPage(page: PageGrid): Payload[] {
                                              var out_msgs: Array<Payload> = [];
                                              out_msgs = [{ payload: "pageType~cardGrid" }]
                                              out_msgs.push({ payload: GeneratePageElements(page) });
                                              return out_msgs
                                          }
                                          
                                          function GeneratePageElements(page: Page): string {
                                              let maxItems = 0;
                                              switch (page.type) {
                                                  case "cardThermo":
                                                      maxItems = 1;
                                                      break;
                                                  case "cardAlarm":
                                                      maxItems = 1;
                                                      break;
                                                  case "cardMedia":
                                                      maxItems = 1;
                                                      break;
                                                  case "cardEntities":
                                                      maxItems = 4;
                                                      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);
                                                  }
                                                  else {
                                                      pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1);
                                                  }
                                              }
                                              return pageData;
                                          }
                                          
                                          function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string {
                                              var iconId = "0"
                                              if (pageItem.id == "delete") {
                                                  return "~delete~~~~~"
                                              }
                                              var name: string;
                                              var type: string;
                                          
                                              // ioBroker
                                              if (existsObject(pageItem.id)) {
                                                  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;
                                                      RegisterEntityWatcher(pageItem.id + ".GET");
                                                  }
                                                  else if (existsState(pageItem.id + ".SET")) {
                                                      val = getState(pageItem.id + ".SET").val;
                                                      RegisterEntityWatcher(pageItem.id + ".SET");
                                                  }
                                                  var iconColor = rgb_dec565(config.defaultColor);
                                          
                                                  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 optVal = "0"
                                          
                                                          if (val === true || val === "true") {
                                                              optVal = "1"
                                                              iconColor = GetIconColor(pageItem, true, useColors);
                                                          } else {
                                                              iconColor = GetIconColor(pageItem, false, useColors);
                                                          }
                                          
                                                          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 (existsState(pageItem.id + ".HUE")) {
                                                              if (getState(pageItem.id + ".HUE").val != null) {
                                                                  let huecolor = hsv2rgb(getState(pageItem.id + ".HUE").val,1,1);
                                                                  let rgb = <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);
                                                              } 
                                                          }
                                          
                                                          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 = <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 = <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 = "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 = "closed"
                                                              }
                                                              RegisterEntityWatcher(pageItem.id + ".ACTUAL");
                                                          }
                                                          return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState;
                                          
                                                      case "info":
                                          
                                                      case "humidity":
                                          
                                                      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 "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;
                                          
                                                      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~~~~~"
                                          }
                                          
                                          function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number {
                                              // 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);
                                          }
                                          
                                          function RegisterEntityWatcher(id: string): void {
                                              if (subscriptions.hasOwnProperty(id)) {
                                                  return;
                                              }
                                              subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
                                                  if(pageId >= 0)
                                                      SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) });
                                                  if(pageId == -1 && config.button1Page != undefined)
                                                      SendToPanel({ payload: GeneratePageElements(config.button1Page) });
                                                  if(pageId == -2 && config.button2Page != undefined)
                                                      SendToPanel({ payload: GeneratePageElements(config.button2Page) });
                                              }))
                                          }
                                          
                                          function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void {
                                              if (subscriptions.hasOwnProperty(id)) {
                                                  return;
                                              }
                                              subscriptions[id] = (on({ id: id, change: 'any' }, function () {
                                                  SendToPanel(GenerateDetailPage(type, pageItem));
                                              }))
                                          }
                                          
                                          function GetUnitOfMeasurement(id: string): string {
                                              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 "";
                                          }
                                          
                                          function GenerateThermoPage(page: PageThermo): Payload[] {
                                              var id = page.items[0].id
                                              var out_msgs: Array<Payload> = [];
                                              out_msgs.push({ payload: "pageType~cardThermo" });
                                          
                                              // ioBroker
                                              if (existsObject(id)) {
                                                  let o = getObject(id)
                                                  let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de
                                                  let currentTemp = 0;
                                                  if (existsState(id + ".ACTUAL"))
                                                      currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10;
                                          
                                                  let destTemp = 0;
                                                  if (existsState(id + ".SET")) {
                                                      destTemp = getState(id + ".SET").val.toFixed(2) * 10;
                                                  }
                                          
                                                  let status = ""
                                                  if (existsState(id + ".MODE"))
                                                      status = getState(id + ".MODE").val;
                                                  let minTemp = 50 //Min Temp 5°C
                                                  let maxTemp = 300 //Max Temp 30°C
                                                  let stepTemp = 5
                                          
                                                  //0-4 verwendet bei ungerader Anzahl Parametern
                                                  let bt0 = "~~~~"; //verwendet bei ungleichen Parametern
                                                  let bt1 = "~~~~"; //verwendet bei ungleichen Parametern
                                                  let bt2 = "~~~~"; //verwendet bei ungleichen Parametern
                                                  let bt3 = "~~~~"; //verwendet bei ungleichen Parametern
                                                  let bt4 = "~~~~"; //verwendet bei ungleichen Parametern
                                                  //5-8 verwendet bei gerader Anzahl Parametern
                                                  let bt5 = Icons.GetIcon("water-percent") + "~0~1~~";    
                                                  let bt6 = Icons.GetIcon("fire") + "~0~1~~";             
                                                  let bt7 = Icons.GetIcon("wifi") + "~0~1~~";             
                                                  let bt8 = Icons.GetIcon("battery-high") + "~0~1~~";     
                                          
                                                  if (existsState(id + ".HUMIDITY")){
                                                      bt5 =  Icons.GetIcon("water-percent") + "~2016~1~bt8~";
                                                      if (parseInt(getState(id + ".HUMIDITY").val) < 40) {
                                                          bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                      } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) {
                                                          bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                      } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) {
                                                          bt5 =  Icons.GetIcon("water-percent") + "~65504~1~bt8~";
                                                      } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) {
                                                          bt5 =  Icons.GetIcon("water-percent") + "~63488~1~bt8~";
                                                      }
                                                  }
                                          
                                                  if (existsState(id + ".MAINTAIN")){
                                                      if (getState(id + ".MAINTAIN").val >> .1) {
                                                          bt6 =  Icons.GetIcon("fire") + "~60897~1~bt8~";
                                                      } else {
                                                          bt6 =  Icons.GetIcon("fire") + "~33840~0~bt8~";
                                                      }
                                                  }
                                          
                                                  if (existsState(id + ".UNREACH")){
                                                      if (getState(id + ".UNREACH").val) {
                                                          bt7 =  Icons.GetIcon("wifi-off") + "~63488~1~bt8~";
                                                      } else {
                                                          bt7 =  Icons.GetIcon("wifi") + "~2016~1~bt8~";
                                                      }
                                                  }
                                          
                                                  if (existsState(id + ".LOWBAT")){
                                                      if (getState(id + ".LOWBAT").val) {
                                                          bt8 =  Icons.GetIcon("battery-low") + "~63488~1~bt8~";
                                                      } else {
                                                          bt8 =  Icons.GetIcon("battery-high") + "~2016~1~bt8~";
                                                      }
                                                  }
                                          
                                                  let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8;
                                          
                                                  out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res})
                                              }
                                          
                                              return out_msgs
                                          }
                                          
                                          function GenerateMediaPage(page: PageMedia): Payload[] {
                                              var id = page.items[0].id
                                              var out_msgs: Array<Payload> = [];
                                              out_msgs.push({ payload: "pageType~cardMedia" });
                                              if (existsObject(id)) {
                                          
                                                  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;
                                                  let volume = getState(id + ".VOLUME").val;
                                                  var iconplaypause = Icons.GetIcon("pause"); //pause
                                                  var onoffbutton = 1374;
                                                  if (getState(id + ".STATE").val) {
                                                      onoffbutton = 65535;
                                                      iconplaypause = Icons.GetIcon("pause"); //pause
                                                  } else {
                                                      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
                                          // Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
                                                  let speakerlist = "";
                                                  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 && 
                                                              existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
                                                              existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
                                                                  speakerlist = speakerlist + getState(i).val + "?";
                                                          }
                                                      }
                                                  }
                                                  speakerlist = speakerlist.substring(0,speakerlist.length-1);
                                          //--------------------------------------------------------------------------------------------------------------
                                          
                                                  out_msgs.push({ payload: "entityUpd~" + 
                                                                            name + "~" +
                                                                            id + "~" +
                                                                            id + "~" +         //????
                                                                            media_icon + "~" +
                                                                            title + "~" +
                                                                            author + "~" +
                                                                            volume + "~" +
                                                                            iconplaypause + "~" +
                                                                            currentSpeaker + "~" +
                                                                            speakerlist + "~" +
                                                                            onoffbutton});
                                              }
                                          
                                              return out_msgs
                                          }
                                          
                                          function GenerateAlarmPage(page: PageAlarm): Payload[] {
                                              var id = page.items[0].id
                                              var out_msgs: Array<Payload> = [];
                                              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 = 1;                           //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 = 1;                           //flashing*        
                                              }
                                                  
                                              out_msgs.push({ payload:    "entityUpd~" +             //entityUpd~*
                                                                          id + "~" +                 //internalNameEntity*~* //navigation*~*
                                                                          "~" +                      //???
                                                                          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*
                                          
                                              return out_msgs
                                          }
                                          
                                          function setIfExists(id: string, value: any, type: string | null = null): boolean {
                                              if (type === null) {
                                                  if (existsState(id)) {
                                                      setState(id, value);
                                                      return true;
                                                  }
                                              }
                                              else {
                                                  let obj = getObject(id);
                                                  if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) {
                                                      setState(id, value);
                                                      return true;
                                                  }
                                              }
                                              return false;
                                          }
                                          
                                          function toggleState(id: string): boolean {
                                              let obj = getObject(id);
                                              if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") {
                                                  setState(id, !getState(id).val);
                                                  return true;
                                              }
                                              return false;
                                          }
                                          
                                          function HandleButtonEvent(words): void {
                                              let id = words[2]
                                              let buttonAction = words[3];
                                          
                                              //console.log(words[0] + " - " + words[1] + " - " + words[2] + " - " + words[3] + " - " + words[4] + " - PageId: " + pageId);
                                          
                                              switch (buttonAction) {
                                                  case "bNext":
                                                      var pageNum = ((pageId + 1) % config.pages.length);
                                                      pageId = Math.abs(pageNum);
                                                      UnsubscribeWatcher();
                                                      GeneratePage(config.pages[pageId]);
                                                      break;
                                                  case "bPrev":
                                                      var pageNum = ((pageId - 1) % config.pages.length);
                                                      pageId = Math.abs(pageNum);
                                                      UnsubscribeWatcher();
                                                      GeneratePage(config.pages[pageId]);
                                                      break;
                                                  case "bExit":
                                                      if (config.screenSaverDoubleClick) {
                                                          if (words[4] == 2)
                                                              GeneratePage(config.pages[pageId]);
                                                      }
                                                      else
                                                          GeneratePage(config.pages[pageId]);
                                                      break;
                                                  case "OnOff":
                                                      if (existsObject(id)) {
                                                          var action = false
                                                          if (words[4] == "1")
                                                              action = true
                                                          let o = getObject(id)
                                                          switch (o.common.role) {
                                                              case "light":
                                                                  setIfExists(id + ".SET", action);
                                                                  break;
                                                              case "dimmer":
                                                                  setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action);
                                                                  break;
                                                              case "rgb":
                                                              case "rgbSingle":
                                                              case "hue": // Armilar
                                                                  setIfExists(id + ".ON_ACTUAL", action);
                                                          }
                                                      }
                                                      break;
                                                  case "up":
                                                      setIfExists(id + ".OPEN", true)
                                                      break;
                                                  case "stop":
                                                      setIfExists(id + ".STOP", true)
                                                      break;
                                                  case "down":
                                                      setIfExists(id + ".CLOSE", true)
                                                      break;
                                                  case "button":
                                                      toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET")
                                                      break;
                                                  case "positionSlider":
                                                      setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                                      break;
                                                  case "brightnessSlider":
                                                      if (existsObject(id)) {
                                                          let o = getObject(id);
                                                          let pageItem = config.pages[pageId].items.find(e => e.id === 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 "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])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
                                                                  }
                                                                  break;
                                                          }
                                                      }
                                                      break;
                                                  case "colorTempSlider": // Armilar - Slider tickt verkehrt - Hell = 0 / Dunkel = 100 -> Korrektur
                                                      let pageItem = config.pages[pageId].items.find(e => e.id === 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]);
                                                      }
                                                      break;
                                                  case "colorWheel":
                                                      let colorCoordinates = words[4].split('|');
                                                      let rgb = pos_to_color(colorCoordinates[0], colorCoordinates[1]);
                                                      //console.log(rgb);
                                                      //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":
                                                              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;
                                                  case "media-pause":
                                                      if (getState(id + ".STATE").val === true) {
                                                          setIfExists(id + ".PAUSE", true)
                                                      } else {
                                                          setIfExists(id + ".PLAY", true)
                                                      }
                                                      break;
                                                  case "media-next":
                                                      setIfExists(id + ".NEXT", true)
                                                      break;
                                                  case "volumeSlider":
                                                      setIfExists(id + ".VOLUME", parseInt(words[4]))
                                                      break;
                                                  case "speaker-sel":
                                                      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];
                                                          if ((getState(i).val) === words[4]){
                                                              let deviceId = i;
                                                              deviceId = deviceId.split('.');
                                                              setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
                                                              alexaDevice = deviceId[3]
                                                          }
                                                      }
                                                      break;
                                                  case "media-OnOff":
                                                      setIfExists(id + ".STOP", true)
                                                      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:
                                                      return "0|1";
                                                  case config.pages.length - 1:
                                                      return "1|0";
                                                  case -1:
                                                      return "0|0";
                                                  default:
                                                      return "1|1";
                                              }
                                          }
                                          
                                          function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] {
                                          
                                              var out_msgs: Array<Payload> = [];
                                              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") {
                                                          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);
                                                          }
                                          
                                                          if (val) {
                                                              switchVal = "1";
                                                              iconColor = GetIconColor(pageItem, true, false);
                                                          }
                                          
                                                          out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" })
                                                      }
                                          
                                                      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);
                                                          
                                                          let colorTemp = "disable"
                                                          let colorMode = "disable"
                                          
                                                          out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                      }
                                                      //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                      }
                                          
                                                      //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                      }
                                          
                                                      //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 = <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~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode })
                                                      }
                                          
                                                  }
                                          
                                                  if (type == "popupShutter") {
                                                      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);
                                                      }
                                                      out_msgs.push({ payload: "entityUpdateDetail~" + val })
                                                  }
                                              }
                                              return out_msgs
                                          }
                                          
                                          function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
                                              return (outMax+outMin)-((number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin);
                                          }
                                          
                                          function UnsubscribeWatcher(): void {
                                              for (const [key, value] of Object.entries(subscriptions)) {
                                                  unsubscribe(value);
                                                  delete subscriptions[key]
                                              }
                                          }
                                          
                                          function HandleScreensaver(): void {
                                              SendToPanel({ payload: "pageType~screensaver"})
                                              UnsubscribeWatcher();
                                              HandleScreensaverUpdate();
                                          }
                                          
                                          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++) {
                                                          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);
                                                          payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
                                                      }
                                                  } 
                                                  else {
                                                      //In Config definierte Zustände wenn weatherForecast = false
                                                      payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
                                                      payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
                                                      payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
                                                      payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
                                                  }
                                          /*-------------------------------------------------------------------------------------------------------------------------------------*/
                                           
                                                  SendToPanel(<Payload>{ payload: payloadString });
                                              }
                                          }
                                          
                                          function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string {
                                              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 "~~~";
                                              }
                                          }
                                          
                                          function GetAccuWeatherIcon(icon: number): string {
                                              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";
                                              }
                                          }
                                          
                                          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 <RGB>{ 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)));
                                          }
                                          
                                          /* 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 <RGB>{ red: Math.round(rgb[0]), green: Math.round(rgb[1]), blue: Math.round(rgb[2]) };
                                          }
                                          
                                          type RGB = {
                                              red: number,
                                              green: number,
                                              blue: number
                                          };
                                          
                                          type Payload = {
                                              payload: string;
                                          };
                                          
                                          type Page = {
                                              type: string,
                                              heading: string,
                                              items: PageItem[],
                                              useColor: boolean
                                          };
                                          
                                          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[],
                                          };
                                          
                                          type PageItem = {
                                              id: string,
                                              icon: (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),
                                              unit: (string | undefined)
                                          }
                                          
                                          type Config = {
                                              panelRecvTopic: string,
                                              panelSendTopic: string,
                                              timeoutScreensaver: number,
                                              dimmode: number,
                                              //brightnessScreensaver:
                                              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,
                                              defaultColor: RGB,
                                              defaultOnColor: RGB,
                                              defaultOffColor: RGB,
                                              pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[],
                                              button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                              button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null),
                                          };
                                          
                                          type ScreenSaverElement = {
                                              ScreensaverEntity: string | null,
                                              ScreensaverEntityIcon: string | null,
                                              ScreensaverEntityText: string | null,
                                              ScreensaverEntityUnitText: string | null,
                                          }
                                          
                                          D Offline
                                          D Offline
                                          Dexxter
                                          wrote on last edited by Dexxter
                                          #375

                                          @armilar
                                          Perfekt, so läuft es bei mir super 👍 😊
                                          Vielen Dank bis hier hin, ich hoffe ich bin Dir nicht zu sehr auf die Nerven gegangen.
                                          Code lesen und verstehen wird bei mir langsam besser aber vom schreiben bin ich noch meilenweit entfernt😏
                                          Jetzt spinnt zwar mein Controller etwas rum aber das hat mit dem Code nix zu tun.
                                          Ist es eigentlich möglich mit dem Alexa case auch etwas anderes zu steuern?
                                          Ich bin nämlich in der Teufel Raumfeld ecke unterwegs.

                                          EDIT: Hat schon jemand das Panel einbauen wollen? Ich hab meins gestern eingebaut und das passt ja mal so gar nicht in eine normale UP Dose!
                                          Ich musste echt ein paar Stücke der Dose raus schneiden bevor ich das Ding rein bekommen hab 😕

                                          ArmilarA 2 Replies Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          635

                                          Online

                                          32.4k

                                          Users

                                          81.4k

                                          Topics

                                          1.3m

                                          Posts
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Recent
                                          • Tags
                                          • Unread 0
                                          • Categories
                                          • Unreplied
                                          • Popular
                                          • GitHub
                                          • Docu
                                          • Hilfe