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. Skripten / Logik
  4. Blockly
  5. Homematic IP Wand und Heizkörperthermostate

NEWS

  • Wartung am 15.11. – Forum ab 22:00 Uhr nicht erreichbar
    BluefoxB
    Bluefox
    12
    2
    276

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

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

Homematic IP Wand und Heizkörperthermostate

Homematic IP Wand und Heizkörperthermostate

Scheduled Pinned Locked Moved Blockly
20 Posts 3 Posters 785 Views 1 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.
  • J jwerlsdf

    @tt-tom
    Über die CCU3 nicht über die App

    T Offline
    T Offline
    TT-Tom
    wrote on last edited by TT-Tom
    #4

    @jwerlsdf
    dann kann ich dir da leider nicht weiter helfen.
    Ich nutze den HMIP Adapter und die App.
    Ich würde es bei mir so machen. Mit einem Wandthermostat eine ganz normal Regelung inkl. Fensterschalter. Vom zweiten Wandthermostat würde ich auf den Setpoint triggern und den Wert in den Setpoint des Wandthermostat1 schreiben.

    Gruß Tom
    https://github.com/tt-tom17
    Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

    NSPanel Script Wiki
    https://github.com/joBr99/nspanel-lovelace-ui/wiki

    NSPanel Adapter Wiki
    https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

    1 Reply Last reply
    0
    • J jwerlsdf

      Hallo,
      ich habe folgender Aufbau:
      Zwei Wandthermostate,
      zwei Heizkörperthermostate und Fensterkontaktschalter.

      Wandthermostat 1 soll die Temperaturmessung übernehmen

      Über Wandthermostat 1 und 2 soll die manuelle Regelung vorgenommen werden. Dementsprechend muss, wenn ich WT1 manuell ändere in WT2 der Wert entsprechend angepasst werden und umgekehrt.

      Leider geht eine Direktverknüpfung mit diesem Szenario nicht mit homematic.
      Wie muss ich nun die Programmierung vornehmen? Steuere ich die Ventile maximal für einen vorgegeben Zeitpunkt mit auf? Welche Datenpunkte benötige ich? Würde mir bitte jemand auf die Sprünge helfen?

      paul53P Offline
      paul53P Offline
      paul53
      wrote on last edited by
      #5

      @jwerlsdf sagte: WT1 manuell ändere in WT2 der Wert entsprechend angepasst werden und umgekehrt.

      Versuche es mal mit Javascript:

      // IDs anpassen!
      const idSoll1 = 'hm-rpc.0.abc.1.SET_POINT_TEMPERATURE';
      const idSoll2 = 'hm-rpc.0.xyz.1.SET_POINT_TEMPERATURE';
      
      on(idSoll1, function(dp) {
          if(dp.state.c != scriptName) setState(idSoll2, dp.state.val);
      });
      
      on(idSoll2, function(dp) {
          if(dp.state.c != scriptName) setState(idSoll1, dp.state.val);
      });
      

      Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
      Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

      T 1 Reply Last reply
      0
      • paul53P paul53

        @jwerlsdf sagte: WT1 manuell ändere in WT2 der Wert entsprechend angepasst werden und umgekehrt.

        Versuche es mal mit Javascript:

        // IDs anpassen!
        const idSoll1 = 'hm-rpc.0.abc.1.SET_POINT_TEMPERATURE';
        const idSoll2 = 'hm-rpc.0.xyz.1.SET_POINT_TEMPERATURE';
        
        on(idSoll1, function(dp) {
            if(dp.state.c != scriptName) setState(idSoll2, dp.state.val);
        });
        
        on(idSoll2, function(dp) {
            if(dp.state.c != scriptName) setState(idSoll1, dp.state.val);
        });
        
        T Offline
        T Offline
        TT-Tom
        wrote on last edited by
        #6

        @paul53
        das habe ich mir auch gedacht, aber wieder verworfen. Es könnte zu einer Schleife Kommen, da sich gegenseitig sehen und beschreiben.

        Gruß Tom
        https://github.com/tt-tom17
        Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

        NSPanel Script Wiki
        https://github.com/joBr99/nspanel-lovelace-ui/wiki

        NSPanel Adapter Wiki
        https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

        paul53P 1 Reply Last reply
        0
        • T TT-Tom

          @paul53
          das habe ich mir auch gedacht, aber wieder verworfen. Es könnte zu einer Schleife Kommen, da sich gegenseitig sehen und beschreiben.

          paul53P Offline
          paul53P Offline
          paul53
          wrote on last edited by paul53
          #7

          @tt-tom sagte: Es könnte zu einer Schleife Kommen

          Das soll die Prüfung

          if(dp.state.c != scriptName)
          

          verhindern.

          Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
          Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

          T 1 Reply Last reply
          1
          • paul53P paul53

            @tt-tom sagte: Es könnte zu einer Schleife Kommen

            Das soll die Prüfung

            if(dp.state.c != scriptName)
            

            verhindern.

            T Offline
            T Offline
            TT-Tom
            wrote on last edited by
            #8

            @paul53

            jo so könnte es funktionieren.
            Ich kenne da die Regelung der CCU nicht, ob diese da auf getrennte SetPoints arbeitet. Im HMIP Adapter hat man eine Gruppe diese vereint alle Geräte der Regelung und man hat dann einen DP für SetPoint der in die Reglung dann geht.

            Gruß Tom
            https://github.com/tt-tom17
            Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

            NSPanel Script Wiki
            https://github.com/joBr99/nspanel-lovelace-ui/wiki

            NSPanel Adapter Wiki
            https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

            paul53P 1 Reply Last reply
            0
            • T TT-Tom

              @paul53

              jo so könnte es funktionieren.
              Ich kenne da die Regelung der CCU nicht, ob diese da auf getrennte SetPoints arbeitet. Im HMIP Adapter hat man eine Gruppe diese vereint alle Geräte der Regelung und man hat dann einen DP für SetPoint der in die Reglung dann geht.

              paul53P Offline
              paul53P Offline
              paul53
              wrote on last edited by paul53
              #9

              @tt-tom sagte: Gruppe diese vereint alle Geräte der Regelung

              Kann man zwei WT in eine Gruppe aufnehmen?
              Die Regelung erfolgt in den HKT. Davon können mehrere in einer Gruppe sein.

              Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
              Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

              T 1 Reply Last reply
              0
              • paul53P paul53

                @tt-tom sagte: Gruppe diese vereint alle Geräte der Regelung

                Kann man zwei WT in eine Gruppe aufnehmen?
                Die Regelung erfolgt in den HKT. Davon können mehrere in einer Gruppe sein.

                T Offline
                T Offline
                TT-Tom
                wrote on last edited by
                #10

                @paul53
                muss ich glatt mal testen, ob die HMIP Cloud so was kann.
                Macht aber in meinen Augen kein Sinn, ein Sollwertgeber reicht in der Regelung, dieser sendet den Setpoint an die Ventile.
                Gebe nachher Rückmeldung.

                Gruß Tom
                https://github.com/tt-tom17
                Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                NSPanel Script Wiki
                https://github.com/joBr99/nspanel-lovelace-ui/wiki

                NSPanel Adapter Wiki
                https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                paul53P 1 Reply Last reply
                0
                • T TT-Tom

                  @paul53
                  muss ich glatt mal testen, ob die HMIP Cloud so was kann.
                  Macht aber in meinen Augen kein Sinn, ein Sollwertgeber reicht in der Regelung, dieser sendet den Setpoint an die Ventile.
                  Gebe nachher Rückmeldung.

                  paul53P Offline
                  paul53P Offline
                  paul53
                  wrote on last edited by paul53
                  #11

                  @jwerlsdf Weshalb hast du zwei WT, die den gleichen Sollwert vorgeben sollen?

                  Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                  Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                  T J 2 Replies Last reply
                  0
                  • paul53P paul53

                    @jwerlsdf Weshalb hast du zwei WT, die den gleichen Sollwert vorgeben sollen?

                    T Offline
                    T Offline
                    TT-Tom
                    wrote on last edited by
                    #12

                    @paul53

                    ich bin nicht der Ersteller des Thread, das ist @jwerlsdf. Er hat das in den Ring geworfen.

                    zwei Wandthermostate in einem Raum geht bei der HMIP App nicht, was ich mir schon gedacht habe. Macht ja auch kein Sinn.

                    Gruß Tom
                    https://github.com/tt-tom17
                    Wenn meine Hilfe erfolgreich war, benutze bitte das Voting unten rechts im Beitrag

                    NSPanel Script Wiki
                    https://github.com/joBr99/nspanel-lovelace-ui/wiki

                    NSPanel Adapter Wiki
                    https://github.com/ticaki/ioBroker.nspanel-lovelace-ui/wiki

                    1 Reply Last reply
                    0
                    • paul53P paul53

                      @jwerlsdf Weshalb hast du zwei WT, die den gleichen Sollwert vorgeben sollen?

                      J Offline
                      J Offline
                      jwerlsdf
                      wrote on last edited by jwerlsdf
                      #13

                      @paul53
                      Ein Wandthermostat ist beim Eingang in den Raum. Leider ist daneben der Kachelofen. Das zweite Thermostat ist gegenüberliegende vom Kamin am Ende des Raumes.
                      Unabhängig vom Zustand des Kamin habe ich bis zu einem Grad Unterschied.
                      Es ist keine Gruppensteuerung mit zwei Wandthermostate möglich über die CCU3.
                      Ich werde mich morgen noch einmal dran setzt.
                      Setpoint ist doch nur den Wert setzten, aber durch den Wert wird doch nicht automatisch das Ventil geöffnet. Ich muss doch mit einem datenpunkt sorgen, dass er das Ventil auffährt und wieder zu fährt, wenn gemessener Wert und Zielwert identisch ist?!

                      paul53P 1 Reply Last reply
                      0
                      • J jwerlsdf

                        @paul53
                        Ein Wandthermostat ist beim Eingang in den Raum. Leider ist daneben der Kachelofen. Das zweite Thermostat ist gegenüberliegende vom Kamin am Ende des Raumes.
                        Unabhängig vom Zustand des Kamin habe ich bis zu einem Grad Unterschied.
                        Es ist keine Gruppensteuerung mit zwei Wandthermostate möglich über die CCU3.
                        Ich werde mich morgen noch einmal dran setzt.
                        Setpoint ist doch nur den Wert setzten, aber durch den Wert wird doch nicht automatisch das Ventil geöffnet. Ich muss doch mit einem datenpunkt sorgen, dass er das Ventil auffährt und wieder zu fährt, wenn gemessener Wert und Zielwert identisch ist?!

                        paul53P Offline
                        paul53P Offline
                        paul53
                        wrote on last edited by paul53
                        #14

                        @jwerlsdf sagte: sorgen, dass er das Ventil auffährt und wieder zu fährt, wenn gemessener Wert und Zielwert identisch ist?!

                        Die HKT enthalten einen PI-Regler, der das Ventil abhängig von der Regelabweichung Messwert - Sollwert steuert.

                        @jwerlsdf sagte in Homematic IP Wand und Heizkörperthermostate:

                        Ein Wandthermostat ist beim Eingang in den Raum. Leider ist daneben der Kachelofen.

                        Wozu benötigt man dieses WT?
                        Man kann den Temperaturmesswert nur von einem WT per Direktverknüpfung zu den HKT auswerten. Dieses WT sollte in der Nähe der Sitzgruppe angeordnet werden.
                        Ein zweites WT ist sinnlos, da man dessen Temperaturmesswert nicht auswerten kann.

                        Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                        Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                        J 1 Reply Last reply
                        1
                        • paul53P paul53

                          @jwerlsdf sagte: sorgen, dass er das Ventil auffährt und wieder zu fährt, wenn gemessener Wert und Zielwert identisch ist?!

                          Die HKT enthalten einen PI-Regler, der das Ventil abhängig von der Regelabweichung Messwert - Sollwert steuert.

                          @jwerlsdf sagte in Homematic IP Wand und Heizkörperthermostate:

                          Ein Wandthermostat ist beim Eingang in den Raum. Leider ist daneben der Kachelofen.

                          Wozu benötigt man dieses WT?
                          Man kann den Temperaturmesswert nur von einem WT per Direktverknüpfung zu den HKT auswerten. Dieses WT sollte in der Nähe der Sitzgruppe angeordnet werden.
                          Ein zweites WT ist sinnlos, da man dessen Temperaturmesswert nicht auswerten kann.

                          J Offline
                          J Offline
                          jwerlsdf
                          wrote on last edited by
                          #15

                          @paul53 said in Homematic IP Wand und Heizkörperthermostate:

                          Wozu benötigt man dieses WT?

                          Ganz einfach. Weil Frau das Thermostat vom Flur aus steuern möchte und nicht jedes Mal ans Ende des Raumes gehen möchte.

                          Ich habe mich nun mit Hilfe von ChatGPT mal herangetastet und es funktioniert nun so wie ich es möchte. Hier die Beschreibung

                          1. Wandthermostat 1 misst die Raumtemperatur.
                          2. An den Wandthermostat 1 und 2 können die Soll-Werte manuell geschrieben werden. Wird an WTH1 der Soll-Wert gesetzt, wird dieser Wert ebenfalls bei WTH2 und bei allen Heizköperthermostaten gesetzt und umgedreht.
                          3. Fensterkontaktschalter: Ist die Tür offen, wird 12 Grad bei allen Geräten eingestellt. Weiterhin wird der window.state auf open gesetzt. Der letztgeschriebene Soll-Wert wird zuvor im folgenden Datenpunkt geschrieben: "0_userdata.0.Raumtemperatur.LastTemp" (Bitte anlegen, wer das Skript benutzen möchte). Wenn nun die Tür wieder geschlossen wird, wird der Soll-Wert von LastTemp benutzt und bei allen Geräten geschrieben.
                          4. Nachtabsenkung: Es können die Tage (Mo-So) mit den Uhrzeiten ausgewählt werden und die Temperatur eingestellt werden.
                          5. Push-Nachricht per Telegram, wenn das Fenster länger als XX Minuten offen ist.

                          To-Do:
                          Ferienmodus mit dem Feiertage-Adapter verknüpfen.

                          Hier nun das Skript. PS. Das Thema ist doch eher nun bei Java aufgehoben als hier bei Blockly.

                          // === KONSTANTEN ===
                          const THERMOSTAT_1 = 'hm-rpc.1.001CDD89B76720.1.SET_POINT_TEMPERATURE';
                          const THERMOSTAT_2 = 'hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE';
                          const HEIZKOERPER_1 = 'hm-rpc.1.002A9F29AE0076.1.SET_POINT_TEMPERATURE';
                          const HEIZKOERPER_2 = 'hm-rpc.1.002A9F29AE007E.1.SET_POINT_TEMPERATURE';
                          
                          const FENSTERKONTAKTE = [
                             'hm-rpc.1.00109F29B2DA40.1.STATE',
                             // weitere Fensterkontakte hier eintragen
                          ];
                          
                          const LAST_TEMP = '0_userdata.0.Raumtemperatur.LastTemp';
                          const FENSTER_OFFEN_TEMP = 12;
                          
                          // === NACHTABSENKUNG ===
                          const NACHTABSENKUNG = {
                             Montag:    { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                             Dienstag:  { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                             Mittwoch:  { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                             Donnerstag:{ aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                             Freitag:   { aktiv: true, absenkZeit: '23:30', rueckZeit: '09:00' },
                             Samstag:   { aktiv: true, absenkZeit: '23:30', rueckZeit: '06:00' },
                             Sonntag:   { aktiv: true, absenkZeit: '22:30', rueckZeit: '06:00' },
                          };
                          const NACHT_ABSENK_TEMP = 19;
                          const NACHT_RUECK_TEMP = 21;
                          
                          // === FENSTER-ÜBERWACHUNG (Telegram Warnung bei langem Öffnen) ===
                          const ENABLE_LONG_OPEN_WARNING = true;
                          const LONG_OPEN_MINUTES = 10;
                          const PUSH_MESSAGE_TARGET = 'telegram.0';
                          const PUSH_RECIPIENTS = [];  // Empfänger: Leer = alle, sonst User IDs als Array: ['123456789', '987654321']
                          
                          // === LOGGING ===
                          // Log-Level: 0 = keine Logs, 1 = nur Push, 2 = alle Infos
                          const LOG_LEVEL = 0;
                          function logInfo(msg, level = 2) {
                             if (LOG_LEVEL >= level) console.log(`[Info] ${msg}`);
                          }
                          
                          // === CACHE ===
                          const cache = {};
                          const CACHE_TIMEOUT = 3000;
                          function setCached(id, value) {
                             if (cache[id]?.timer) clearTimeout(cache[id].timer);
                             cache[id] = {
                                 value,
                                 timer: setTimeout(() => delete cache[id], CACHE_TIMEOUT)
                             };
                          }
                          function isCached(id, value) {
                             return cache[id]?.value === value;
                          }
                          
                          // === HELPER ===
                          function writeIfChanged(id, value) {
                             const current = getState(id)?.val;
                             if (Number(current) !== Number(value)) {
                                 setState(id, value);
                                 setCached(id, value);
                                 logInfo(`[Write] ${id} gesetzt auf ${value} (alt: ${current})`);
                             }
                          }
                          
                          function getWindowStateId(tempId) {
                             return tempId.replace('SET_POINT_TEMPERATURE', 'WINDOW_STATE');
                          }
                          
                          function isWindowOpen() {
                             for (const id of FENSTERKONTAKTE) {
                                 const val = getState(id)?.val;
                                 if (val === true || val === 1 || val === 'true') {
                                     return true;
                                 }
                             }
                             return false;
                          }
                          
                          // === SYNC WANDTHERMOSTATE UND HEIZKÖRPER ===
                          function syncThermostats(source, target) {
                             on({ id: source, change: "ne" }, (obj) => {
                                 const newValue = obj.state.val;
                          
                                 if (isWindowOpen()) {
                                     logInfo(`[Sync] Änderung ignoriert – Fenster offen: ${source} → ${newValue}°C`);
                                     return;
                                 }
                          
                                 if (isCached(source, newValue)) return;
                          
                                 logInfo(`[Sync] Änderung erkannt bei ${source}: ${newValue}°C`);
                          
                                 writeIfChanged(target, newValue);
                                 writeIfChanged(HEIZKOERPER_1, newValue);
                                 writeIfChanged(HEIZKOERPER_2, newValue);
                          
                                 setState(LAST_TEMP, newValue);
                             });
                          }
                          
                          // === FENSTER-LOGIK ===
                          let longOpenTimer = null;
                          let longOpenNotified = false;
                          
                          function startLongOpenTimer() {
                             if (!ENABLE_LONG_OPEN_WARNING || longOpenTimer) return;
                             longOpenNotified = false;
                             longOpenTimer = setTimeout(() => {
                                 if (isWindowOpen()) {
                                     sendPush(`🚪 Das Fenster ist seit über ${LONG_OPEN_MINUTES} Minuten geöffnet!`);
                                     longOpenNotified = true;
                                 }
                             }, LONG_OPEN_MINUTES * 60 * 1000);
                             logInfo(`[Fenster-Überwachung] Timer gestartet (${LONG_OPEN_MINUTES} Min.)`);
                          }
                          
                          function stopLongOpenTimer() {
                             if (longOpenTimer) {
                                 clearTimeout(longOpenTimer);
                                 longOpenTimer = null;
                                 logInfo(`[Fenster-Überwachung] Timer gestoppt.`);
                             }
                             longOpenNotified = false;
                          }
                          
                          function sendPush(msg) {
                             if (!PUSH_MESSAGE_TARGET) return;
                             logInfo(`[Push] Sende Nachricht: ${msg}`, 1);
                          
                             if (Array.isArray(PUSH_RECIPIENTS) && PUSH_RECIPIENTS.length) {
                                 PUSH_RECIPIENTS.forEach(userId => {
                                     sendTo(PUSH_MESSAGE_TARGET, "send", {
                                         user: userId,
                                         text: msg
                                     });
                                 });
                             } else {
                                 sendTo(PUSH_MESSAGE_TARGET, "send", {
                                     text: msg
                                 });
                             }
                          }
                          
                          function handleWindowChange() {
                             const open = isWindowOpen();
                             logInfo(`[Fensterstatus] Fenster ist jetzt: ${open ? 'OFFEN' : 'GESCHLOSSEN'}`);
                          
                             if (open) {
                                 const currentTemp = getState(THERMOSTAT_1)?.val;
                                 if (typeof currentTemp === 'number') {
                                     setState(LAST_TEMP, currentTemp);
                                     logInfo(`[Fenster] Offen – Sollwert gespeichert: ${currentTemp}°C`);
                                 } else {
                                     logInfo(`[Fenster] Offen – Keine gültige Temperatur zum Speichern gefunden: ${currentTemp}`);
                                 }
                          
                                 [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                     writeIfChanged(id, FENSTER_OFFEN_TEMP);
                                     const windowStateId = getWindowStateId(id);
                                     writeIfChanged(windowStateId, 1);
                                 });
                          
                                 startLongOpenTimer();
                             } else {
                                 let savedTemp = getState(LAST_TEMP)?.val;
                                 if (typeof savedTemp !== 'number') savedTemp = 21;
                          
                                 logInfo(`[Fenster] Geschlossen – Wiederherstellung auf: ${savedTemp}°C`);
                          
                                 [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                     writeIfChanged(id, savedTemp);
                                     const windowStateId = getWindowStateId(id);
                                     writeIfChanged(windowStateId, 0);
                                 });
                          
                                 stopLongOpenTimer();
                             }
                          }
                          
                          FENSTERKONTAKTE.forEach(id => {
                             on({ id: id, change: "ne" }, (obj) => {
                                 logInfo(`[Event] Fensterkontakt ${id} geändert: ${obj.state.val}`);
                                 handleWindowChange();
                             });
                          });
                          
                          // === NACHTABSENKUNG ===
                          function getWeekdayName(dayIndex) {
                             return ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'][dayIndex];
                          }
                          
                          function scheduleNightMode() {
                             const now = new Date();
                             const dayIndex = now.getDay();
                             const dayName = getWeekdayName(dayIndex);
                             const config = NACHTABSENKUNG[dayName];
                          
                             if (!config?.aktiv) {
                                 logInfo(`[Nachtabsenkung] Für ${dayName} deaktiviert.`);
                                 scheduleNextNightMode();
                                 return;
                             }
                          
                             const [abHour, abMinute] = config.absenkZeit.split(':').map(Number);
                             const [rueckHour, rueckMinute] = config.rueckZeit.split(':').map(Number);
                          
                             const absenkTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), abHour, abMinute);
                             const rueckTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), rueckHour, rueckMinute);
                          
                             if (rueckTime <= absenkTime) rueckTime.setDate(rueckTime.getDate() + 1);
                          
                             const timeUntilDown = (absenkTime - now > 0) ? (absenkTime - now) : (absenkTime.getTime() + 24*60*60*1000 - now.getTime());
                             const timeUntilUp = (rueckTime - now > 0) ? (rueckTime - now) : (rueckTime.getTime() + 24*60*60*1000 - now.getTime());
                          
                             setTimeout(() => {
                                 if (!isWindowOpen()) {
                                     logInfo(`[Nachtabsenkung] Absenkung auf ${NACHT_ABSENK_TEMP}°C (${dayName})`);
                                     [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                         writeIfChanged(id, NACHT_ABSENK_TEMP);
                                     });
                                 } else {
                                     logInfo(`[Nachtabsenkung] Absenkung übersprungen wegen offenem Fenster (${dayName})`);
                                 }
                                 scheduleNextNightMode();
                             }, timeUntilDown);
                          
                             setTimeout(() => {
                                 if (!isWindowOpen()) {
                                     logInfo(`[Nachtabsenkung] Rückkehr auf ${NACHT_RUECK_TEMP}°C (${dayName})`);
                                     [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                         writeIfChanged(id, NACHT_RUECK_TEMP);
                                     });
                                 } else {
                                     logInfo(`[Nachtabsenkung] Rückkehr übersprungen wegen offenem Fenster (${dayName})`);
                                 }
                                 scheduleNextNightMode();
                             }, timeUntilUp);
                          
                             logInfo(`[Nachtabsenkung] Zeitplan gesetzt für ${dayName}: Absenkzeit ${config.absenkZeit}, Rückkehrzeit ${config.rueckZeit}`);
                          }
                          
                          function scheduleNextNightMode() {
                             const now = new Date();
                             now.setHours(0, 0, 0, 0);
                             now.setDate(now.getDate() + 1);
                             const nextDay = now.getDay();
                             setTimeout(scheduleNightMode, 24*60*60*1000); // Jeden Tag neu planen
                          }
                          
                          scheduleNightMode();
                          
                          // === SYNC THERMOSTATE ===
                          syncThermostats(THERMOSTAT_1, THERMOSTAT_2);
                          syncThermostats(THERMOSTAT_2, THERMOSTAT_1);
                          
                          // --- Skript Ende ---
                          
                          

                          paul53P 2 Replies Last reply
                          0
                          • J jwerlsdf

                            @paul53 said in Homematic IP Wand und Heizkörperthermostate:

                            Wozu benötigt man dieses WT?

                            Ganz einfach. Weil Frau das Thermostat vom Flur aus steuern möchte und nicht jedes Mal ans Ende des Raumes gehen möchte.

                            Ich habe mich nun mit Hilfe von ChatGPT mal herangetastet und es funktioniert nun so wie ich es möchte. Hier die Beschreibung

                            1. Wandthermostat 1 misst die Raumtemperatur.
                            2. An den Wandthermostat 1 und 2 können die Soll-Werte manuell geschrieben werden. Wird an WTH1 der Soll-Wert gesetzt, wird dieser Wert ebenfalls bei WTH2 und bei allen Heizköperthermostaten gesetzt und umgedreht.
                            3. Fensterkontaktschalter: Ist die Tür offen, wird 12 Grad bei allen Geräten eingestellt. Weiterhin wird der window.state auf open gesetzt. Der letztgeschriebene Soll-Wert wird zuvor im folgenden Datenpunkt geschrieben: "0_userdata.0.Raumtemperatur.LastTemp" (Bitte anlegen, wer das Skript benutzen möchte). Wenn nun die Tür wieder geschlossen wird, wird der Soll-Wert von LastTemp benutzt und bei allen Geräten geschrieben.
                            4. Nachtabsenkung: Es können die Tage (Mo-So) mit den Uhrzeiten ausgewählt werden und die Temperatur eingestellt werden.
                            5. Push-Nachricht per Telegram, wenn das Fenster länger als XX Minuten offen ist.

                            To-Do:
                            Ferienmodus mit dem Feiertage-Adapter verknüpfen.

                            Hier nun das Skript. PS. Das Thema ist doch eher nun bei Java aufgehoben als hier bei Blockly.

                            // === KONSTANTEN ===
                            const THERMOSTAT_1 = 'hm-rpc.1.001CDD89B76720.1.SET_POINT_TEMPERATURE';
                            const THERMOSTAT_2 = 'hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE';
                            const HEIZKOERPER_1 = 'hm-rpc.1.002A9F29AE0076.1.SET_POINT_TEMPERATURE';
                            const HEIZKOERPER_2 = 'hm-rpc.1.002A9F29AE007E.1.SET_POINT_TEMPERATURE';
                            
                            const FENSTERKONTAKTE = [
                               'hm-rpc.1.00109F29B2DA40.1.STATE',
                               // weitere Fensterkontakte hier eintragen
                            ];
                            
                            const LAST_TEMP = '0_userdata.0.Raumtemperatur.LastTemp';
                            const FENSTER_OFFEN_TEMP = 12;
                            
                            // === NACHTABSENKUNG ===
                            const NACHTABSENKUNG = {
                               Montag:    { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                               Dienstag:  { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                               Mittwoch:  { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                               Donnerstag:{ aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                               Freitag:   { aktiv: true, absenkZeit: '23:30', rueckZeit: '09:00' },
                               Samstag:   { aktiv: true, absenkZeit: '23:30', rueckZeit: '06:00' },
                               Sonntag:   { aktiv: true, absenkZeit: '22:30', rueckZeit: '06:00' },
                            };
                            const NACHT_ABSENK_TEMP = 19;
                            const NACHT_RUECK_TEMP = 21;
                            
                            // === FENSTER-ÜBERWACHUNG (Telegram Warnung bei langem Öffnen) ===
                            const ENABLE_LONG_OPEN_WARNING = true;
                            const LONG_OPEN_MINUTES = 10;
                            const PUSH_MESSAGE_TARGET = 'telegram.0';
                            const PUSH_RECIPIENTS = [];  // Empfänger: Leer = alle, sonst User IDs als Array: ['123456789', '987654321']
                            
                            // === LOGGING ===
                            // Log-Level: 0 = keine Logs, 1 = nur Push, 2 = alle Infos
                            const LOG_LEVEL = 0;
                            function logInfo(msg, level = 2) {
                               if (LOG_LEVEL >= level) console.log(`[Info] ${msg}`);
                            }
                            
                            // === CACHE ===
                            const cache = {};
                            const CACHE_TIMEOUT = 3000;
                            function setCached(id, value) {
                               if (cache[id]?.timer) clearTimeout(cache[id].timer);
                               cache[id] = {
                                   value,
                                   timer: setTimeout(() => delete cache[id], CACHE_TIMEOUT)
                               };
                            }
                            function isCached(id, value) {
                               return cache[id]?.value === value;
                            }
                            
                            // === HELPER ===
                            function writeIfChanged(id, value) {
                               const current = getState(id)?.val;
                               if (Number(current) !== Number(value)) {
                                   setState(id, value);
                                   setCached(id, value);
                                   logInfo(`[Write] ${id} gesetzt auf ${value} (alt: ${current})`);
                               }
                            }
                            
                            function getWindowStateId(tempId) {
                               return tempId.replace('SET_POINT_TEMPERATURE', 'WINDOW_STATE');
                            }
                            
                            function isWindowOpen() {
                               for (const id of FENSTERKONTAKTE) {
                                   const val = getState(id)?.val;
                                   if (val === true || val === 1 || val === 'true') {
                                       return true;
                                   }
                               }
                               return false;
                            }
                            
                            // === SYNC WANDTHERMOSTATE UND HEIZKÖRPER ===
                            function syncThermostats(source, target) {
                               on({ id: source, change: "ne" }, (obj) => {
                                   const newValue = obj.state.val;
                            
                                   if (isWindowOpen()) {
                                       logInfo(`[Sync] Änderung ignoriert – Fenster offen: ${source} → ${newValue}°C`);
                                       return;
                                   }
                            
                                   if (isCached(source, newValue)) return;
                            
                                   logInfo(`[Sync] Änderung erkannt bei ${source}: ${newValue}°C`);
                            
                                   writeIfChanged(target, newValue);
                                   writeIfChanged(HEIZKOERPER_1, newValue);
                                   writeIfChanged(HEIZKOERPER_2, newValue);
                            
                                   setState(LAST_TEMP, newValue);
                               });
                            }
                            
                            // === FENSTER-LOGIK ===
                            let longOpenTimer = null;
                            let longOpenNotified = false;
                            
                            function startLongOpenTimer() {
                               if (!ENABLE_LONG_OPEN_WARNING || longOpenTimer) return;
                               longOpenNotified = false;
                               longOpenTimer = setTimeout(() => {
                                   if (isWindowOpen()) {
                                       sendPush(`🚪 Das Fenster ist seit über ${LONG_OPEN_MINUTES} Minuten geöffnet!`);
                                       longOpenNotified = true;
                                   }
                               }, LONG_OPEN_MINUTES * 60 * 1000);
                               logInfo(`[Fenster-Überwachung] Timer gestartet (${LONG_OPEN_MINUTES} Min.)`);
                            }
                            
                            function stopLongOpenTimer() {
                               if (longOpenTimer) {
                                   clearTimeout(longOpenTimer);
                                   longOpenTimer = null;
                                   logInfo(`[Fenster-Überwachung] Timer gestoppt.`);
                               }
                               longOpenNotified = false;
                            }
                            
                            function sendPush(msg) {
                               if (!PUSH_MESSAGE_TARGET) return;
                               logInfo(`[Push] Sende Nachricht: ${msg}`, 1);
                            
                               if (Array.isArray(PUSH_RECIPIENTS) && PUSH_RECIPIENTS.length) {
                                   PUSH_RECIPIENTS.forEach(userId => {
                                       sendTo(PUSH_MESSAGE_TARGET, "send", {
                                           user: userId,
                                           text: msg
                                       });
                                   });
                               } else {
                                   sendTo(PUSH_MESSAGE_TARGET, "send", {
                                       text: msg
                                   });
                               }
                            }
                            
                            function handleWindowChange() {
                               const open = isWindowOpen();
                               logInfo(`[Fensterstatus] Fenster ist jetzt: ${open ? 'OFFEN' : 'GESCHLOSSEN'}`);
                            
                               if (open) {
                                   const currentTemp = getState(THERMOSTAT_1)?.val;
                                   if (typeof currentTemp === 'number') {
                                       setState(LAST_TEMP, currentTemp);
                                       logInfo(`[Fenster] Offen – Sollwert gespeichert: ${currentTemp}°C`);
                                   } else {
                                       logInfo(`[Fenster] Offen – Keine gültige Temperatur zum Speichern gefunden: ${currentTemp}`);
                                   }
                            
                                   [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                       writeIfChanged(id, FENSTER_OFFEN_TEMP);
                                       const windowStateId = getWindowStateId(id);
                                       writeIfChanged(windowStateId, 1);
                                   });
                            
                                   startLongOpenTimer();
                               } else {
                                   let savedTemp = getState(LAST_TEMP)?.val;
                                   if (typeof savedTemp !== 'number') savedTemp = 21;
                            
                                   logInfo(`[Fenster] Geschlossen – Wiederherstellung auf: ${savedTemp}°C`);
                            
                                   [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                       writeIfChanged(id, savedTemp);
                                       const windowStateId = getWindowStateId(id);
                                       writeIfChanged(windowStateId, 0);
                                   });
                            
                                   stopLongOpenTimer();
                               }
                            }
                            
                            FENSTERKONTAKTE.forEach(id => {
                               on({ id: id, change: "ne" }, (obj) => {
                                   logInfo(`[Event] Fensterkontakt ${id} geändert: ${obj.state.val}`);
                                   handleWindowChange();
                               });
                            });
                            
                            // === NACHTABSENKUNG ===
                            function getWeekdayName(dayIndex) {
                               return ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'][dayIndex];
                            }
                            
                            function scheduleNightMode() {
                               const now = new Date();
                               const dayIndex = now.getDay();
                               const dayName = getWeekdayName(dayIndex);
                               const config = NACHTABSENKUNG[dayName];
                            
                               if (!config?.aktiv) {
                                   logInfo(`[Nachtabsenkung] Für ${dayName} deaktiviert.`);
                                   scheduleNextNightMode();
                                   return;
                               }
                            
                               const [abHour, abMinute] = config.absenkZeit.split(':').map(Number);
                               const [rueckHour, rueckMinute] = config.rueckZeit.split(':').map(Number);
                            
                               const absenkTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), abHour, abMinute);
                               const rueckTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), rueckHour, rueckMinute);
                            
                               if (rueckTime <= absenkTime) rueckTime.setDate(rueckTime.getDate() + 1);
                            
                               const timeUntilDown = (absenkTime - now > 0) ? (absenkTime - now) : (absenkTime.getTime() + 24*60*60*1000 - now.getTime());
                               const timeUntilUp = (rueckTime - now > 0) ? (rueckTime - now) : (rueckTime.getTime() + 24*60*60*1000 - now.getTime());
                            
                               setTimeout(() => {
                                   if (!isWindowOpen()) {
                                       logInfo(`[Nachtabsenkung] Absenkung auf ${NACHT_ABSENK_TEMP}°C (${dayName})`);
                                       [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                           writeIfChanged(id, NACHT_ABSENK_TEMP);
                                       });
                                   } else {
                                       logInfo(`[Nachtabsenkung] Absenkung übersprungen wegen offenem Fenster (${dayName})`);
                                   }
                                   scheduleNextNightMode();
                               }, timeUntilDown);
                            
                               setTimeout(() => {
                                   if (!isWindowOpen()) {
                                       logInfo(`[Nachtabsenkung] Rückkehr auf ${NACHT_RUECK_TEMP}°C (${dayName})`);
                                       [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                           writeIfChanged(id, NACHT_RUECK_TEMP);
                                       });
                                   } else {
                                       logInfo(`[Nachtabsenkung] Rückkehr übersprungen wegen offenem Fenster (${dayName})`);
                                   }
                                   scheduleNextNightMode();
                               }, timeUntilUp);
                            
                               logInfo(`[Nachtabsenkung] Zeitplan gesetzt für ${dayName}: Absenkzeit ${config.absenkZeit}, Rückkehrzeit ${config.rueckZeit}`);
                            }
                            
                            function scheduleNextNightMode() {
                               const now = new Date();
                               now.setHours(0, 0, 0, 0);
                               now.setDate(now.getDate() + 1);
                               const nextDay = now.getDay();
                               setTimeout(scheduleNightMode, 24*60*60*1000); // Jeden Tag neu planen
                            }
                            
                            scheduleNightMode();
                            
                            // === SYNC THERMOSTATE ===
                            syncThermostats(THERMOSTAT_1, THERMOSTAT_2);
                            syncThermostats(THERMOSTAT_2, THERMOSTAT_1);
                            
                            // --- Skript Ende ---
                            
                            

                            paul53P Offline
                            paul53P Offline
                            paul53
                            wrote on last edited by paul53
                            #16

                            @jwerlsdf sagte: Weil Frau das Thermostat vom Flur aus steuern möchte

                            Also WT2 als reiner Sollwertsteller. Dann kannst du es so machen wie gezeigt.

                            Den Rest macht die Bildung einer Gruppe (Direktverknüpfungen) mit WT1, den HKT und den Fensterkontakten. Das Wochenprogramm enthält dann die Gruppe.

                            @jwerlsdf sagte in Homematic IP Wand und Heizkörperthermostate:

                            Push-Nachricht per Telegram, wenn das Fenster länger als XX Minuten offen ist.

                            Das muss per Skript erfolgen.

                            @jwerlsdf sagte in Homematic IP Wand und Heizkörperthermostate:

                            Ferienmodus mit dem Feiertage-Adapter verknüpfen.

                            Per Skript das Wochenprogramm in der Gruppe wechseln.

                            Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                            Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                            1 Reply Last reply
                            0
                            • J jwerlsdf

                              @paul53 said in Homematic IP Wand und Heizkörperthermostate:

                              Wozu benötigt man dieses WT?

                              Ganz einfach. Weil Frau das Thermostat vom Flur aus steuern möchte und nicht jedes Mal ans Ende des Raumes gehen möchte.

                              Ich habe mich nun mit Hilfe von ChatGPT mal herangetastet und es funktioniert nun so wie ich es möchte. Hier die Beschreibung

                              1. Wandthermostat 1 misst die Raumtemperatur.
                              2. An den Wandthermostat 1 und 2 können die Soll-Werte manuell geschrieben werden. Wird an WTH1 der Soll-Wert gesetzt, wird dieser Wert ebenfalls bei WTH2 und bei allen Heizköperthermostaten gesetzt und umgedreht.
                              3. Fensterkontaktschalter: Ist die Tür offen, wird 12 Grad bei allen Geräten eingestellt. Weiterhin wird der window.state auf open gesetzt. Der letztgeschriebene Soll-Wert wird zuvor im folgenden Datenpunkt geschrieben: "0_userdata.0.Raumtemperatur.LastTemp" (Bitte anlegen, wer das Skript benutzen möchte). Wenn nun die Tür wieder geschlossen wird, wird der Soll-Wert von LastTemp benutzt und bei allen Geräten geschrieben.
                              4. Nachtabsenkung: Es können die Tage (Mo-So) mit den Uhrzeiten ausgewählt werden und die Temperatur eingestellt werden.
                              5. Push-Nachricht per Telegram, wenn das Fenster länger als XX Minuten offen ist.

                              To-Do:
                              Ferienmodus mit dem Feiertage-Adapter verknüpfen.

                              Hier nun das Skript. PS. Das Thema ist doch eher nun bei Java aufgehoben als hier bei Blockly.

                              // === KONSTANTEN ===
                              const THERMOSTAT_1 = 'hm-rpc.1.001CDD89B76720.1.SET_POINT_TEMPERATURE';
                              const THERMOSTAT_2 = 'hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE';
                              const HEIZKOERPER_1 = 'hm-rpc.1.002A9F29AE0076.1.SET_POINT_TEMPERATURE';
                              const HEIZKOERPER_2 = 'hm-rpc.1.002A9F29AE007E.1.SET_POINT_TEMPERATURE';
                              
                              const FENSTERKONTAKTE = [
                                 'hm-rpc.1.00109F29B2DA40.1.STATE',
                                 // weitere Fensterkontakte hier eintragen
                              ];
                              
                              const LAST_TEMP = '0_userdata.0.Raumtemperatur.LastTemp';
                              const FENSTER_OFFEN_TEMP = 12;
                              
                              // === NACHTABSENKUNG ===
                              const NACHTABSENKUNG = {
                                 Montag:    { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                                 Dienstag:  { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                                 Mittwoch:  { aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                                 Donnerstag:{ aktiv: true, absenkZeit: '22:30', rueckZeit: '09:00' },
                                 Freitag:   { aktiv: true, absenkZeit: '23:30', rueckZeit: '09:00' },
                                 Samstag:   { aktiv: true, absenkZeit: '23:30', rueckZeit: '06:00' },
                                 Sonntag:   { aktiv: true, absenkZeit: '22:30', rueckZeit: '06:00' },
                              };
                              const NACHT_ABSENK_TEMP = 19;
                              const NACHT_RUECK_TEMP = 21;
                              
                              // === FENSTER-ÜBERWACHUNG (Telegram Warnung bei langem Öffnen) ===
                              const ENABLE_LONG_OPEN_WARNING = true;
                              const LONG_OPEN_MINUTES = 10;
                              const PUSH_MESSAGE_TARGET = 'telegram.0';
                              const PUSH_RECIPIENTS = [];  // Empfänger: Leer = alle, sonst User IDs als Array: ['123456789', '987654321']
                              
                              // === LOGGING ===
                              // Log-Level: 0 = keine Logs, 1 = nur Push, 2 = alle Infos
                              const LOG_LEVEL = 0;
                              function logInfo(msg, level = 2) {
                                 if (LOG_LEVEL >= level) console.log(`[Info] ${msg}`);
                              }
                              
                              // === CACHE ===
                              const cache = {};
                              const CACHE_TIMEOUT = 3000;
                              function setCached(id, value) {
                                 if (cache[id]?.timer) clearTimeout(cache[id].timer);
                                 cache[id] = {
                                     value,
                                     timer: setTimeout(() => delete cache[id], CACHE_TIMEOUT)
                                 };
                              }
                              function isCached(id, value) {
                                 return cache[id]?.value === value;
                              }
                              
                              // === HELPER ===
                              function writeIfChanged(id, value) {
                                 const current = getState(id)?.val;
                                 if (Number(current) !== Number(value)) {
                                     setState(id, value);
                                     setCached(id, value);
                                     logInfo(`[Write] ${id} gesetzt auf ${value} (alt: ${current})`);
                                 }
                              }
                              
                              function getWindowStateId(tempId) {
                                 return tempId.replace('SET_POINT_TEMPERATURE', 'WINDOW_STATE');
                              }
                              
                              function isWindowOpen() {
                                 for (const id of FENSTERKONTAKTE) {
                                     const val = getState(id)?.val;
                                     if (val === true || val === 1 || val === 'true') {
                                         return true;
                                     }
                                 }
                                 return false;
                              }
                              
                              // === SYNC WANDTHERMOSTATE UND HEIZKÖRPER ===
                              function syncThermostats(source, target) {
                                 on({ id: source, change: "ne" }, (obj) => {
                                     const newValue = obj.state.val;
                              
                                     if (isWindowOpen()) {
                                         logInfo(`[Sync] Änderung ignoriert – Fenster offen: ${source} → ${newValue}°C`);
                                         return;
                                     }
                              
                                     if (isCached(source, newValue)) return;
                              
                                     logInfo(`[Sync] Änderung erkannt bei ${source}: ${newValue}°C`);
                              
                                     writeIfChanged(target, newValue);
                                     writeIfChanged(HEIZKOERPER_1, newValue);
                                     writeIfChanged(HEIZKOERPER_2, newValue);
                              
                                     setState(LAST_TEMP, newValue);
                                 });
                              }
                              
                              // === FENSTER-LOGIK ===
                              let longOpenTimer = null;
                              let longOpenNotified = false;
                              
                              function startLongOpenTimer() {
                                 if (!ENABLE_LONG_OPEN_WARNING || longOpenTimer) return;
                                 longOpenNotified = false;
                                 longOpenTimer = setTimeout(() => {
                                     if (isWindowOpen()) {
                                         sendPush(`🚪 Das Fenster ist seit über ${LONG_OPEN_MINUTES} Minuten geöffnet!`);
                                         longOpenNotified = true;
                                     }
                                 }, LONG_OPEN_MINUTES * 60 * 1000);
                                 logInfo(`[Fenster-Überwachung] Timer gestartet (${LONG_OPEN_MINUTES} Min.)`);
                              }
                              
                              function stopLongOpenTimer() {
                                 if (longOpenTimer) {
                                     clearTimeout(longOpenTimer);
                                     longOpenTimer = null;
                                     logInfo(`[Fenster-Überwachung] Timer gestoppt.`);
                                 }
                                 longOpenNotified = false;
                              }
                              
                              function sendPush(msg) {
                                 if (!PUSH_MESSAGE_TARGET) return;
                                 logInfo(`[Push] Sende Nachricht: ${msg}`, 1);
                              
                                 if (Array.isArray(PUSH_RECIPIENTS) && PUSH_RECIPIENTS.length) {
                                     PUSH_RECIPIENTS.forEach(userId => {
                                         sendTo(PUSH_MESSAGE_TARGET, "send", {
                                             user: userId,
                                             text: msg
                                         });
                                     });
                                 } else {
                                     sendTo(PUSH_MESSAGE_TARGET, "send", {
                                         text: msg
                                     });
                                 }
                              }
                              
                              function handleWindowChange() {
                                 const open = isWindowOpen();
                                 logInfo(`[Fensterstatus] Fenster ist jetzt: ${open ? 'OFFEN' : 'GESCHLOSSEN'}`);
                              
                                 if (open) {
                                     const currentTemp = getState(THERMOSTAT_1)?.val;
                                     if (typeof currentTemp === 'number') {
                                         setState(LAST_TEMP, currentTemp);
                                         logInfo(`[Fenster] Offen – Sollwert gespeichert: ${currentTemp}°C`);
                                     } else {
                                         logInfo(`[Fenster] Offen – Keine gültige Temperatur zum Speichern gefunden: ${currentTemp}`);
                                     }
                              
                                     [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                         writeIfChanged(id, FENSTER_OFFEN_TEMP);
                                         const windowStateId = getWindowStateId(id);
                                         writeIfChanged(windowStateId, 1);
                                     });
                              
                                     startLongOpenTimer();
                                 } else {
                                     let savedTemp = getState(LAST_TEMP)?.val;
                                     if (typeof savedTemp !== 'number') savedTemp = 21;
                              
                                     logInfo(`[Fenster] Geschlossen – Wiederherstellung auf: ${savedTemp}°C`);
                              
                                     [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                         writeIfChanged(id, savedTemp);
                                         const windowStateId = getWindowStateId(id);
                                         writeIfChanged(windowStateId, 0);
                                     });
                              
                                     stopLongOpenTimer();
                                 }
                              }
                              
                              FENSTERKONTAKTE.forEach(id => {
                                 on({ id: id, change: "ne" }, (obj) => {
                                     logInfo(`[Event] Fensterkontakt ${id} geändert: ${obj.state.val}`);
                                     handleWindowChange();
                                 });
                              });
                              
                              // === NACHTABSENKUNG ===
                              function getWeekdayName(dayIndex) {
                                 return ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'][dayIndex];
                              }
                              
                              function scheduleNightMode() {
                                 const now = new Date();
                                 const dayIndex = now.getDay();
                                 const dayName = getWeekdayName(dayIndex);
                                 const config = NACHTABSENKUNG[dayName];
                              
                                 if (!config?.aktiv) {
                                     logInfo(`[Nachtabsenkung] Für ${dayName} deaktiviert.`);
                                     scheduleNextNightMode();
                                     return;
                                 }
                              
                                 const [abHour, abMinute] = config.absenkZeit.split(':').map(Number);
                                 const [rueckHour, rueckMinute] = config.rueckZeit.split(':').map(Number);
                              
                                 const absenkTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), abHour, abMinute);
                                 const rueckTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), rueckHour, rueckMinute);
                              
                                 if (rueckTime <= absenkTime) rueckTime.setDate(rueckTime.getDate() + 1);
                              
                                 const timeUntilDown = (absenkTime - now > 0) ? (absenkTime - now) : (absenkTime.getTime() + 24*60*60*1000 - now.getTime());
                                 const timeUntilUp = (rueckTime - now > 0) ? (rueckTime - now) : (rueckTime.getTime() + 24*60*60*1000 - now.getTime());
                              
                                 setTimeout(() => {
                                     if (!isWindowOpen()) {
                                         logInfo(`[Nachtabsenkung] Absenkung auf ${NACHT_ABSENK_TEMP}°C (${dayName})`);
                                         [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                             writeIfChanged(id, NACHT_ABSENK_TEMP);
                                         });
                                     } else {
                                         logInfo(`[Nachtabsenkung] Absenkung übersprungen wegen offenem Fenster (${dayName})`);
                                     }
                                     scheduleNextNightMode();
                                 }, timeUntilDown);
                              
                                 setTimeout(() => {
                                     if (!isWindowOpen()) {
                                         logInfo(`[Nachtabsenkung] Rückkehr auf ${NACHT_RUECK_TEMP}°C (${dayName})`);
                                         [THERMOSTAT_1, THERMOSTAT_2, HEIZKOERPER_1, HEIZKOERPER_2].forEach(id => {
                                             writeIfChanged(id, NACHT_RUECK_TEMP);
                                         });
                                     } else {
                                         logInfo(`[Nachtabsenkung] Rückkehr übersprungen wegen offenem Fenster (${dayName})`);
                                     }
                                     scheduleNextNightMode();
                                 }, timeUntilUp);
                              
                                 logInfo(`[Nachtabsenkung] Zeitplan gesetzt für ${dayName}: Absenkzeit ${config.absenkZeit}, Rückkehrzeit ${config.rueckZeit}`);
                              }
                              
                              function scheduleNextNightMode() {
                                 const now = new Date();
                                 now.setHours(0, 0, 0, 0);
                                 now.setDate(now.getDate() + 1);
                                 const nextDay = now.getDay();
                                 setTimeout(scheduleNightMode, 24*60*60*1000); // Jeden Tag neu planen
                              }
                              
                              scheduleNightMode();
                              
                              // === SYNC THERMOSTATE ===
                              syncThermostats(THERMOSTAT_1, THERMOSTAT_2);
                              syncThermostats(THERMOSTAT_2, THERMOSTAT_1);
                              
                              // --- Skript Ende ---
                              
                              

                              paul53P Offline
                              paul53P Offline
                              paul53
                              wrote on last edited by paul53
                              #17

                              @jwerlsdf sagte: Das Thema ist doch eher nun bei Java aufgehoben als hier bei Blockly.

                              Die 3 Skriptfunktionen lassen sich auch per Blockly realisieren, etwa so:

                              Blockly_temp.JPG

                              Für längere Abwesenheit (Reise) kann man den Party-/Urlaubs-Modus in der Gruppe einstellen.

                              Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                              Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                              J 1 Reply Last reply
                              0
                              • paul53P paul53

                                @jwerlsdf sagte: Das Thema ist doch eher nun bei Java aufgehoben als hier bei Blockly.

                                Die 3 Skriptfunktionen lassen sich auch per Blockly realisieren, etwa so:

                                Blockly_temp.JPG

                                Für längere Abwesenheit (Reise) kann man den Party-/Urlaubs-Modus in der Gruppe einstellen.

                                J Offline
                                J Offline
                                jwerlsdf
                                wrote on last edited by jwerlsdf
                                #18

                                @paul53
                                Ich probiere auch mal deine Variante aus. Ist "Sollwert" der Datenpunkt "hm-rpc.XXX.SET_POINT_TEMPERATURE"?

                                Hat sich erledigt. Vielen Dank Paul! Habe noch dein Skript angepasst, sodass beim WT2, wenn Fenster offen, die 12 Grad und Fenster Auf Symbol angezeigt wird und wenn das Fenster zu ist, der SOll-Wert von der Gruppe genommen wird, ohne das eine Schleife passiert.

                                Hier das Skript.

                                <xml xmlns="https://developers.google.com/blockly/xml">
                                 <variables>
                                   <variable type="timeout" id="timeout">timeout</variable>
                                 </variables>
                                 <block type="comment" id="{Y]#=u$1OQZm-ay49]cq" x="-712" y="-387">
                                   <field name="COMMENT">Gruppe (Terrasse)</field>
                                   <next>
                                     <block type="on" id="pT757H3*3srntxuFOR#;">
                                       <field name="OID">hm-rpc.1.001CDD89B76720.1.SET_POINT_TEMPERATURE</field>
                                       <field name="CONDITION">ne</field>
                                       <field name="ACK_CONDITION"></field>
                                       <statement name="STATEMENT">
                                         <block type="controls_if" id="l45luZ?V}LQmwdr?1D}4">
                                           <value name="IF0">
                                             <block type="logic_compare" id="s61Zr|3x-%uV{}i.Pf-Q">
                                               <field name="OP">NEQ</field>
                                               <value name="A">
                                                 <block type="on_source" id="z+t9x/,qe+BZ!J8!kKnt">
                                                   <field name="ATTR">state.c</field>
                                                 </block>
                                               </value>
                                               <value name="B">
                                                 <block type="global_var" id="%n~bb})e4*EQtG_d~9B#">
                                                   <field name="VAR">scriptName</field>
                                                 </block>
                                               </value>
                                             </block>
                                           </value>
                                           <statement name="DO0">
                                             <block type="comment" id="G=yl+ANln9:e/4a2^d/E">
                                               <field name="COMMENT">WT2</field>
                                               <next>
                                                 <block type="control" id="TZH@F3tJ5HOIq?h5unYQ">
                                                   <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                   <field name="OID">hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE</field>
                                                   <field name="WITH_DELAY">FALSE</field>
                                                   <value name="VALUE">
                                                     <block type="on_source" id=":v_SIj~}U3301{tWSU}:">
                                                       <field name="ATTR">state.val</field>
                                                     </block>
                                                   </value>
                                                 </block>
                                               </next>
                                             </block>
                                           </statement>
                                         </block>
                                       </statement>
                                       <next>
                                         <block type="comment" id="a9HXs6g6*}6tjCsIg[6_">
                                           <field name="COMMENT">WT2 (Eingang)</field>
                                           <next>
                                             <block type="on" id="wO?$=+.c5c[SX9Hid3ZW">
                                               <field name="OID">hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE</field>
                                               <field name="CONDITION">ne</field>
                                               <field name="ACK_CONDITION"></field>
                                               <statement name="STATEMENT">
                                                 <block type="controls_if" id="cPS(.,FSSO8gV[wif)SE">
                                                   <value name="IF0">
                                                     <block type="logic_multi_and" id="$VLZun|6I$hDr2,Q*`oC">
                                                       <mutation xmlns="http://www.w3.org/1999/xhtml" items="2"></mutation>
                                                       <value name="AND0">
                                                         <block type="logic_compare" id="/*S+cbX}G]T[qCob=V_Z">
                                                           <field name="OP">NEQ</field>
                                                           <value name="A">
                                                             <block type="on_source" id=":47h_L5M/2zz~KXB(UcW">
                                                               <field name="ATTR">state.c</field>
                                                             </block>
                                                           </value>
                                                           <value name="B">
                                                             <block type="global_var" id="c-|mC)qb)1#dx[z97yrt">
                                                               <field name="VAR">scriptName</field>
                                                             </block>
                                                           </value>
                                                         </block>
                                                       </value>
                                                       <value name="AND1">
                                                         <block type="logic_compare" id="rBE?}M`jfY/0y@oXmNJi">
                                                           <field name="OP">EQ</field>
                                                           <value name="A">
                                                             <block type="get_value" id="[5]%)7@^7_d*n?ihQiU%">
                                                               <field name="ATTR">val</field>
                                                               <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                             </block>
                                                           </value>
                                                           <value name="B">
                                                             <block type="math_number" id="wk2?0_%9AJ`NbSiCnN.6">
                                                               <field name="NUM">0</field>
                                                             </block>
                                                           </value>
                                                         </block>
                                                       </value>
                                                     </block>
                                                   </value>
                                                   <statement name="DO0">
                                                     <block type="comment" id="NA%$CR?mka9`lHpk3ke{">
                                                       <field name="COMMENT">Gruppe</field>
                                                       <next>
                                                         <block type="control" id="B4%#e4rz{mF%w)=Ooq@O">
                                                           <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                           <field name="OID">hm-rpc.1.001CDD89B76720.1.SET_POINT_TEMPERATURE</field>
                                                           <field name="WITH_DELAY">FALSE</field>
                                                           <value name="VALUE">
                                                             <block type="on_source" id="*l}`+Wbi5#8Y.CG3)dsz">
                                                               <field name="ATTR">state.val</field>
                                                             </block>
                                                           </value>
                                                           <next>
                                                             <block type="control" id="gzP#;{cO%TE2a(w;#:Yl">
                                                               <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                               <field name="OID">hm-rpc.1.002A9F29AE0076.1.SET_POINT_TEMPERATURE</field>
                                                               <field name="WITH_DELAY">FALSE</field>
                                                               <value name="VALUE">
                                                                 <block type="on_source" id="W807ER2:9`]h-:^te,C5">
                                                                   <field name="ATTR">state.val</field>
                                                                 </block>
                                                               </value>
                                                               <next>
                                                                 <block type="control" id="TH*M%dJAR!e8lg#^vV]%">
                                                                   <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                   <field name="OID">hm-rpc.1.002A9F29AE007E.1.SET_POINT_TEMPERATURE</field>
                                                                   <field name="WITH_DELAY">FALSE</field>
                                                                   <value name="VALUE">
                                                                     <block type="on_source" id="/6J?g/gf/J03[k,GJTHD">
                                                                       <field name="ATTR">state.val</field>
                                                                     </block>
                                                                   </value>
                                                                 </block>
                                                               </next>
                                                             </block>
                                                           </next>
                                                         </block>
                                                       </next>
                                                     </block>
                                                   </statement>
                                                 </block>
                                               </statement>
                                               <next>
                                                 <block type="on" id="IRA(~4ty|7Mi[bo%ADB*">
                                                   <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                   <field name="CONDITION">ne</field>
                                                   <field name="ACK_CONDITION"></field>
                                                   <statement name="STATEMENT">
                                                     <block type="controls_if" id="-CDUSoG=eSok?ew6a|7$">
                                                       <mutation elseif="1"></mutation>
                                                       <value name="IF0">
                                                         <block type="logic_compare" id="~%Uryn_d%Vg5xf|nNiAr">
                                                           <field name="OP">EQ</field>
                                                           <value name="A">
                                                             <block type="get_value" id="(bq/Zx#~}i5z]SF#_q+1">
                                                               <field name="ATTR">val</field>
                                                               <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                             </block>
                                                           </value>
                                                           <value name="B">
                                                             <block type="math_number" id="P(/sOpOc]^5,1hL5N]HK">
                                                               <field name="NUM">1</field>
                                                             </block>
                                                           </value>
                                                         </block>
                                                       </value>
                                                       <statement name="DO0">
                                                         <block type="comment" id="Gc%nO;%^0.t-7DmJzo#a">
                                                           <field name="COMMENT">WT2</field>
                                                           <next>
                                                             <block type="control" id="4T0~IV5n30U[[-l]7m6_">
                                                               <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                               <field name="OID">hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE</field>
                                                               <field name="WITH_DELAY">FALSE</field>
                                                               <value name="VALUE">
                                                                 <block type="math_number" id="i_GLDxR[.0xI]yYEz2ox">
                                                                   <field name="NUM">12</field>
                                                                 </block>
                                                               </value>
                                                               <next>
                                                                 <block type="control" id="cY%oiFRJaFQkz^9?|d2d">
                                                                   <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                   <field name="OID">hm-rpc.1.001CDD89B76724.1.WINDOW_STATE</field>
                                                                   <field name="WITH_DELAY">FALSE</field>
                                                                   <value name="VALUE">
                                                                     <block type="math_number" id="~tq`s)J(6e@--d+p}u^;">
                                                                       <field name="NUM">1</field>
                                                                     </block>
                                                                   </value>
                                                                 </block>
                                                               </next>
                                                             </block>
                                                           </next>
                                                         </block>
                                                       </statement>
                                                       <value name="IF1">
                                                         <block type="logic_compare" id="Q7;K6ggUo-Rxpy%I5DW{">
                                                           <field name="OP">EQ</field>
                                                           <value name="A">
                                                             <block type="get_value" id="PTYt;vydFkO8qKs[!8_#">
                                                               <field name="ATTR">val</field>
                                                               <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                             </block>
                                                           </value>
                                                           <value name="B">
                                                             <block type="math_number" id="@iUwEkzhmne`v{awbrV{">
                                                               <field name="NUM">0</field>
                                                             </block>
                                                           </value>
                                                         </block>
                                                       </value>
                                                       <statement name="DO1">
                                                         <block type="control" id="@%E~;21$:RGnxXmAuX0?">
                                                           <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                           <field name="OID">hm-rpc.1.001CDD89B76724.1.WINDOW_STATE</field>
                                                           <field name="WITH_DELAY">FALSE</field>
                                                           <value name="VALUE">
                                                             <block type="math_number" id="se~_sx}@GZ|lin,RMVFk">
                                                               <field name="NUM">0</field>
                                                             </block>
                                                           </value>
                                                         </block>
                                                       </statement>
                                                     </block>
                                                   </statement>
                                                 </block>
                                               </next>
                                             </block>
                                           </next>
                                         </block>
                                       </next>
                                     </block>
                                   </next>
                                 </block>
                                 <block type="on_ext" id="tBRS+crN0bIA*b9?V;{," x="163" y="-262">
                                   <mutation xmlns="http://www.w3.org/1999/xhtml" items="1"></mutation>
                                   <field name="CONDITION">ne</field>
                                   <field name="ACK_CONDITION"></field>
                                   <value name="OID0">
                                     <shadow type="field_oid" id="6a:*dBd4Rn:lWwGQiJpP">
                                       <field name="oid">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                     </shadow>
                                   </value>
                                   <statement name="STATEMENT">
                                     <block type="controls_if" id="0P[vT/#03AT-eA9X2Lr^">
                                       <mutation elseif="1"></mutation>
                                       <value name="IF0">
                                         <block type="logic_negate" id="_nTB0N(;-ir0*n.5[jHl">
                                           <value name="BOOL">
                                             <block type="get_value" id="~t3^`/nsUyEy2Ok:hI%!">
                                               <field name="ATTR">val</field>
                                               <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                             </block>
                                           </value>
                                         </block>
                                       </value>
                                       <statement name="DO0">
                                         <block type="timeouts_cleartimeout" id="^]4b94]%+YeX_8*0:b1C">
                                           <field name="NAME">timeout</field>
                                         </block>
                                       </statement>
                                       <value name="IF1">
                                         <block type="logic_negate" id="GKgV-_`H7ypD+5^WYVyp">
                                           <value name="BOOL">
                                             <block type="timeouts_gettimeout" id="I?3m1sX~Q1LB*PI{Nhe0">
                                               <field name="NAME">timeout</field>
                                             </block>
                                           </value>
                                         </block>
                                       </value>
                                       <statement name="DO1">
                                         <block type="timeouts_settimeout" id="yMgaU*:?me{t3CVn|4$5">
                                           <field name="NAME">timeout</field>
                                           <field name="DELAY">10</field>
                                           <field name="UNIT">min</field>
                                           <statement name="STATEMENT">
                                             <block type="telegram" id="]J:G_X3{e3Qmq6]Y6n],">
                                               <field name="INSTANCE"></field>
                                               <field name="LOG"></field>
                                               <field name="SILENT">FALSE</field>
                                               <field name="PARSEMODE">default</field>
                                               <field name="ESCAPING">FALSE</field>
                                               <field name="DISABLE_WEB_PAGE_PREVIEW">FALSE</field>
                                               <value name="MESSAGE">
                                                 <shadow type="text" id="pfWG1cd=-*gqOPi6m2a,">
                                                   <field name="TEXT">Die Wohnzimmertür ist seit 10 Minuten offen.</field>
                                                 </shadow>
                                               </value>
                                             </block>
                                           </statement>
                                         </block>
                                       </statement>
                                     </block>
                                   </statement>
                                 </block>
                                </xml>
                                

                                Die Nachtabsenkung habe ich tatsächlich über die CCU gemacht. Urlaubmodus mache ich wie angezeigt. WIe gesagt, Danke Paul!

                                paul53P 1 Reply Last reply
                                0
                                • J jwerlsdf

                                  @paul53
                                  Ich probiere auch mal deine Variante aus. Ist "Sollwert" der Datenpunkt "hm-rpc.XXX.SET_POINT_TEMPERATURE"?

                                  Hat sich erledigt. Vielen Dank Paul! Habe noch dein Skript angepasst, sodass beim WT2, wenn Fenster offen, die 12 Grad und Fenster Auf Symbol angezeigt wird und wenn das Fenster zu ist, der SOll-Wert von der Gruppe genommen wird, ohne das eine Schleife passiert.

                                  Hier das Skript.

                                  <xml xmlns="https://developers.google.com/blockly/xml">
                                   <variables>
                                     <variable type="timeout" id="timeout">timeout</variable>
                                   </variables>
                                   <block type="comment" id="{Y]#=u$1OQZm-ay49]cq" x="-712" y="-387">
                                     <field name="COMMENT">Gruppe (Terrasse)</field>
                                     <next>
                                       <block type="on" id="pT757H3*3srntxuFOR#;">
                                         <field name="OID">hm-rpc.1.001CDD89B76720.1.SET_POINT_TEMPERATURE</field>
                                         <field name="CONDITION">ne</field>
                                         <field name="ACK_CONDITION"></field>
                                         <statement name="STATEMENT">
                                           <block type="controls_if" id="l45luZ?V}LQmwdr?1D}4">
                                             <value name="IF0">
                                               <block type="logic_compare" id="s61Zr|3x-%uV{}i.Pf-Q">
                                                 <field name="OP">NEQ</field>
                                                 <value name="A">
                                                   <block type="on_source" id="z+t9x/,qe+BZ!J8!kKnt">
                                                     <field name="ATTR">state.c</field>
                                                   </block>
                                                 </value>
                                                 <value name="B">
                                                   <block type="global_var" id="%n~bb})e4*EQtG_d~9B#">
                                                     <field name="VAR">scriptName</field>
                                                   </block>
                                                 </value>
                                               </block>
                                             </value>
                                             <statement name="DO0">
                                               <block type="comment" id="G=yl+ANln9:e/4a2^d/E">
                                                 <field name="COMMENT">WT2</field>
                                                 <next>
                                                   <block type="control" id="TZH@F3tJ5HOIq?h5unYQ">
                                                     <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                     <field name="OID">hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE</field>
                                                     <field name="WITH_DELAY">FALSE</field>
                                                     <value name="VALUE">
                                                       <block type="on_source" id=":v_SIj~}U3301{tWSU}:">
                                                         <field name="ATTR">state.val</field>
                                                       </block>
                                                     </value>
                                                   </block>
                                                 </next>
                                               </block>
                                             </statement>
                                           </block>
                                         </statement>
                                         <next>
                                           <block type="comment" id="a9HXs6g6*}6tjCsIg[6_">
                                             <field name="COMMENT">WT2 (Eingang)</field>
                                             <next>
                                               <block type="on" id="wO?$=+.c5c[SX9Hid3ZW">
                                                 <field name="OID">hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE</field>
                                                 <field name="CONDITION">ne</field>
                                                 <field name="ACK_CONDITION"></field>
                                                 <statement name="STATEMENT">
                                                   <block type="controls_if" id="cPS(.,FSSO8gV[wif)SE">
                                                     <value name="IF0">
                                                       <block type="logic_multi_and" id="$VLZun|6I$hDr2,Q*`oC">
                                                         <mutation xmlns="http://www.w3.org/1999/xhtml" items="2"></mutation>
                                                         <value name="AND0">
                                                           <block type="logic_compare" id="/*S+cbX}G]T[qCob=V_Z">
                                                             <field name="OP">NEQ</field>
                                                             <value name="A">
                                                               <block type="on_source" id=":47h_L5M/2zz~KXB(UcW">
                                                                 <field name="ATTR">state.c</field>
                                                               </block>
                                                             </value>
                                                             <value name="B">
                                                               <block type="global_var" id="c-|mC)qb)1#dx[z97yrt">
                                                                 <field name="VAR">scriptName</field>
                                                               </block>
                                                             </value>
                                                           </block>
                                                         </value>
                                                         <value name="AND1">
                                                           <block type="logic_compare" id="rBE?}M`jfY/0y@oXmNJi">
                                                             <field name="OP">EQ</field>
                                                             <value name="A">
                                                               <block type="get_value" id="[5]%)7@^7_d*n?ihQiU%">
                                                                 <field name="ATTR">val</field>
                                                                 <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                               </block>
                                                             </value>
                                                             <value name="B">
                                                               <block type="math_number" id="wk2?0_%9AJ`NbSiCnN.6">
                                                                 <field name="NUM">0</field>
                                                               </block>
                                                             </value>
                                                           </block>
                                                         </value>
                                                       </block>
                                                     </value>
                                                     <statement name="DO0">
                                                       <block type="comment" id="NA%$CR?mka9`lHpk3ke{">
                                                         <field name="COMMENT">Gruppe</field>
                                                         <next>
                                                           <block type="control" id="B4%#e4rz{mF%w)=Ooq@O">
                                                             <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                             <field name="OID">hm-rpc.1.001CDD89B76720.1.SET_POINT_TEMPERATURE</field>
                                                             <field name="WITH_DELAY">FALSE</field>
                                                             <value name="VALUE">
                                                               <block type="on_source" id="*l}`+Wbi5#8Y.CG3)dsz">
                                                                 <field name="ATTR">state.val</field>
                                                               </block>
                                                             </value>
                                                             <next>
                                                               <block type="control" id="gzP#;{cO%TE2a(w;#:Yl">
                                                                 <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                 <field name="OID">hm-rpc.1.002A9F29AE0076.1.SET_POINT_TEMPERATURE</field>
                                                                 <field name="WITH_DELAY">FALSE</field>
                                                                 <value name="VALUE">
                                                                   <block type="on_source" id="W807ER2:9`]h-:^te,C5">
                                                                     <field name="ATTR">state.val</field>
                                                                   </block>
                                                                 </value>
                                                                 <next>
                                                                   <block type="control" id="TH*M%dJAR!e8lg#^vV]%">
                                                                     <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                     <field name="OID">hm-rpc.1.002A9F29AE007E.1.SET_POINT_TEMPERATURE</field>
                                                                     <field name="WITH_DELAY">FALSE</field>
                                                                     <value name="VALUE">
                                                                       <block type="on_source" id="/6J?g/gf/J03[k,GJTHD">
                                                                         <field name="ATTR">state.val</field>
                                                                       </block>
                                                                     </value>
                                                                   </block>
                                                                 </next>
                                                               </block>
                                                             </next>
                                                           </block>
                                                         </next>
                                                       </block>
                                                     </statement>
                                                   </block>
                                                 </statement>
                                                 <next>
                                                   <block type="on" id="IRA(~4ty|7Mi[bo%ADB*">
                                                     <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                     <field name="CONDITION">ne</field>
                                                     <field name="ACK_CONDITION"></field>
                                                     <statement name="STATEMENT">
                                                       <block type="controls_if" id="-CDUSoG=eSok?ew6a|7$">
                                                         <mutation elseif="1"></mutation>
                                                         <value name="IF0">
                                                           <block type="logic_compare" id="~%Uryn_d%Vg5xf|nNiAr">
                                                             <field name="OP">EQ</field>
                                                             <value name="A">
                                                               <block type="get_value" id="(bq/Zx#~}i5z]SF#_q+1">
                                                                 <field name="ATTR">val</field>
                                                                 <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                               </block>
                                                             </value>
                                                             <value name="B">
                                                               <block type="math_number" id="P(/sOpOc]^5,1hL5N]HK">
                                                                 <field name="NUM">1</field>
                                                               </block>
                                                             </value>
                                                           </block>
                                                         </value>
                                                         <statement name="DO0">
                                                           <block type="comment" id="Gc%nO;%^0.t-7DmJzo#a">
                                                             <field name="COMMENT">WT2</field>
                                                             <next>
                                                               <block type="control" id="4T0~IV5n30U[[-l]7m6_">
                                                                 <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                 <field name="OID">hm-rpc.1.001CDD89B76724.1.SET_POINT_TEMPERATURE</field>
                                                                 <field name="WITH_DELAY">FALSE</field>
                                                                 <value name="VALUE">
                                                                   <block type="math_number" id="i_GLDxR[.0xI]yYEz2ox">
                                                                     <field name="NUM">12</field>
                                                                   </block>
                                                                 </value>
                                                                 <next>
                                                                   <block type="control" id="cY%oiFRJaFQkz^9?|d2d">
                                                                     <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                                     <field name="OID">hm-rpc.1.001CDD89B76724.1.WINDOW_STATE</field>
                                                                     <field name="WITH_DELAY">FALSE</field>
                                                                     <value name="VALUE">
                                                                       <block type="math_number" id="~tq`s)J(6e@--d+p}u^;">
                                                                         <field name="NUM">1</field>
                                                                       </block>
                                                                     </value>
                                                                   </block>
                                                                 </next>
                                                               </block>
                                                             </next>
                                                           </block>
                                                         </statement>
                                                         <value name="IF1">
                                                           <block type="logic_compare" id="Q7;K6ggUo-Rxpy%I5DW{">
                                                             <field name="OP">EQ</field>
                                                             <value name="A">
                                                               <block type="get_value" id="PTYt;vydFkO8qKs[!8_#">
                                                                 <field name="ATTR">val</field>
                                                                 <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                                               </block>
                                                             </value>
                                                             <value name="B">
                                                               <block type="math_number" id="@iUwEkzhmne`v{awbrV{">
                                                                 <field name="NUM">0</field>
                                                               </block>
                                                             </value>
                                                           </block>
                                                         </value>
                                                         <statement name="DO1">
                                                           <block type="control" id="@%E~;21$:RGnxXmAuX0?">
                                                             <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                             <field name="OID">hm-rpc.1.001CDD89B76724.1.WINDOW_STATE</field>
                                                             <field name="WITH_DELAY">FALSE</field>
                                                             <value name="VALUE">
                                                               <block type="math_number" id="se~_sx}@GZ|lin,RMVFk">
                                                                 <field name="NUM">0</field>
                                                               </block>
                                                             </value>
                                                           </block>
                                                         </statement>
                                                       </block>
                                                     </statement>
                                                   </block>
                                                 </next>
                                               </block>
                                             </next>
                                           </block>
                                         </next>
                                       </block>
                                     </next>
                                   </block>
                                   <block type="on_ext" id="tBRS+crN0bIA*b9?V;{," x="163" y="-262">
                                     <mutation xmlns="http://www.w3.org/1999/xhtml" items="1"></mutation>
                                     <field name="CONDITION">ne</field>
                                     <field name="ACK_CONDITION"></field>
                                     <value name="OID0">
                                       <shadow type="field_oid" id="6a:*dBd4Rn:lWwGQiJpP">
                                         <field name="oid">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                       </shadow>
                                     </value>
                                     <statement name="STATEMENT">
                                       <block type="controls_if" id="0P[vT/#03AT-eA9X2Lr^">
                                         <mutation elseif="1"></mutation>
                                         <value name="IF0">
                                           <block type="logic_negate" id="_nTB0N(;-ir0*n.5[jHl">
                                             <value name="BOOL">
                                               <block type="get_value" id="~t3^`/nsUyEy2Ok:hI%!">
                                                 <field name="ATTR">val</field>
                                                 <field name="OID">hm-rpc.1.00109F29B2DA40.1.STATE</field>
                                               </block>
                                             </value>
                                           </block>
                                         </value>
                                         <statement name="DO0">
                                           <block type="timeouts_cleartimeout" id="^]4b94]%+YeX_8*0:b1C">
                                             <field name="NAME">timeout</field>
                                           </block>
                                         </statement>
                                         <value name="IF1">
                                           <block type="logic_negate" id="GKgV-_`H7ypD+5^WYVyp">
                                             <value name="BOOL">
                                               <block type="timeouts_gettimeout" id="I?3m1sX~Q1LB*PI{Nhe0">
                                                 <field name="NAME">timeout</field>
                                               </block>
                                             </value>
                                           </block>
                                         </value>
                                         <statement name="DO1">
                                           <block type="timeouts_settimeout" id="yMgaU*:?me{t3CVn|4$5">
                                             <field name="NAME">timeout</field>
                                             <field name="DELAY">10</field>
                                             <field name="UNIT">min</field>
                                             <statement name="STATEMENT">
                                               <block type="telegram" id="]J:G_X3{e3Qmq6]Y6n],">
                                                 <field name="INSTANCE"></field>
                                                 <field name="LOG"></field>
                                                 <field name="SILENT">FALSE</field>
                                                 <field name="PARSEMODE">default</field>
                                                 <field name="ESCAPING">FALSE</field>
                                                 <field name="DISABLE_WEB_PAGE_PREVIEW">FALSE</field>
                                                 <value name="MESSAGE">
                                                   <shadow type="text" id="pfWG1cd=-*gqOPi6m2a,">
                                                     <field name="TEXT">Die Wohnzimmertür ist seit 10 Minuten offen.</field>
                                                   </shadow>
                                                 </value>
                                               </block>
                                             </statement>
                                           </block>
                                         </statement>
                                       </block>
                                     </statement>
                                   </block>
                                  </xml>
                                  

                                  Die Nachtabsenkung habe ich tatsächlich über die CCU gemacht. Urlaubmodus mache ich wie angezeigt. WIe gesagt, Danke Paul!

                                  paul53P Offline
                                  paul53P Offline
                                  paul53
                                  wrote on last edited by paul53
                                  #19

                                  @jwerlsdf sagte: Hier das Skript.

                                  Ist die Gruppe nicht ein virtuelles Device unter einer eigenen HM-RPC-Instanz (Port 9292)?

                                  Die Reaktion auf den Fensterkontakt kann man vereinfachen (nur ein Trigger!):

                                  Blockly_temp.JPG

                                  Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                                  Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                                  J 1 Reply Last reply
                                  0
                                  • paul53P paul53

                                    @jwerlsdf sagte: Hier das Skript.

                                    Ist die Gruppe nicht ein virtuelles Device unter einer eigenen HM-RPC-Instanz (Port 9292)?

                                    Die Reaktion auf den Fensterkontakt kann man vereinfachen (nur ein Trigger!):

                                    Blockly_temp.JPG

                                    J Offline
                                    J Offline
                                    jwerlsdf
                                    wrote on last edited by
                                    #20

                                    @paul53 said in Homematic IP Wand und Heizkörperthermostate:

                                    Die Reaktion auf den Fensterkontakt kann man vereinfachen (nur ein Trigger!):

                                    Stimmt. Habe ich entsprechend geändert.

                                    "Ist die Gruppe nicht ein virtuelles Device unter einer eigenen HM-RPC-Instanz?"
                                    Habe ich leider nicht gefunden. Aber passt schon. So funktioniert es nun wenigstens.

                                    1 Reply 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

                                    196

                                    Online

                                    32.4k

                                    Users

                                    81.3k

                                    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