Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. XML-RPC fault - Fehler abfangen?

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    XML-RPC fault - Fehler abfangen?

    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      skorpil @Homoran last edited by

      Diese Art von Kommunikationsfehlern bei Homematic IP treten immer wieder in unregelmäßigen Abständen auf. Eine Systematik dahinter konnte ich nicht entdecken. Ich würde gerne die Schalt Befehle immer dann noch einmal senden, wenn ein solcher Kommunikationsfehler auftritt. Wie kann ich ein Skript erstellen, dass auf den Kommunikationsfehler reagiert?

      Homoran 1 Reply Last reply Reply Quote 0
      • Homoran
        Homoran Global Moderator Administrators @skorpil last edited by

        @skorpil keine Ahnung!
        wird der Schaltbefehl denn nie ausgeführt wenn diese Meldung kommt?

        S 1 Reply Last reply Reply Quote 0
        • S
          skorpil @Homoran last edited by

          @homoran nein, der Schalt Befehl wird nie ausgeführt. Daher würde ich ja gerne auf den Fehler reagieren und den Befehl nochmals senden.

          Was hältst du davon, wenn ich die Frage nochmals im unter Forum Javascript stelle?

          Homoran 1 Reply Last reply Reply Quote 0
          • Homoran
            Homoran Global Moderator Administrators @skorpil last edited by

            @skorpil sagte in XML-RPC fault - Fehler abfangen?:

            der Schalt Befehl wird nie ausgeführt.

            also müsstest du "nur" prüfen ob nach 1 sec der Wert ist wie er sein soll.?!

            1 Reply Last reply Reply Quote 1
            • haus-automatisierung
              haus-automatisierung Developer Most Active @skorpil last edited by

              @skorpil sagte in XML-RPC fault - Fehler abfangen?:

              kann ich den Fehler gegebenenfalls mit einem Skript abfangen?

              Klar, mit dem onLog-Baustein in Blockly. Dann schauen, ob der gesuchte Text darin vorkommt. Habe ich mit einem ähnlichen Beispiel im Kurs erklärt 🙂

              haus-automatisierung 1 Reply Last reply Reply Quote 1
              • haus-automatisierung
                haus-automatisierung Developer Most Active @haus-automatisierung last edited by

                z.B.

                Screenshot 2024-08-06 at 10.18.40.png

                S 1 Reply Last reply Reply Quote 0
                • S
                  skorpil @haus-automatisierung last edited by skorpil

                  @haus-automatisierung dann muss ich noch mal in den Kurs hinein schauen, den habe ich ja gebucht. Trotzdem noch eine Frage, geht das auch außerhalb von blockly mit einem normalen Java Skript? Denn ich arbeite mit blockly nicht.

                  haus-automatisierung 1 Reply Last reply Reply Quote 0
                  • haus-automatisierung
                    haus-automatisierung Developer Most Active @skorpil last edited by

                    @skorpil sagte in XML-RPC fault - Fehler abfangen?:

                    geht das auch außerhalb von blocky mit einem normalen Java Skript?

                    Klar, da Blockly einfach nur JavaScript generiert 🙂

                    https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#onlog

                    S 1 Reply Last reply Reply Quote 1
                    • S
                      skorpil @haus-automatisierung last edited by

                      @haus-automatisierung ich werde mich daran mal versuchen und meine Lösung hier zeigen

                      1 Reply Last reply Reply Quote 0
                      • S
                        skorpil last edited by

                        mit Hilfe von KI habe ich folgendes Script zum erneuten Senden des Schaltbefehls (max. 3 mal, jeweils nach 5 sec) erstellt, wenn ein Kommunikationsfehler auftritt. Jetzt muß ich abwarten und sehen, wie es reagiert

                        // Warteschlange zur Speicherung der Schaltbefehl-Meldungen
                        let setValueQueue = [];
                        
                        // Verwenden der onLog-Anweisung, um Logmeldungen zu überwachen
                        onLog('error', function (obj) {
                            const logMessage = obj.message;
                            const source = obj.from;
                        
                            // Überprüfen, ob die Quelle 'hm-rpc.1' ist
                            if (source === 'hm-rpc.1') {
                        
                                // Prüfen, ob die Logmeldung ein Schaltbefehl ist
                                if (logMessage.includes('xmlrpc -> setValue')) {
                                    // Schaltbefehl in die Warteschlange speichern
                                    setValueQueue.push({ message: logMessage });
                                }
                        
                                // Prüfen, ob die Logmeldung ein Kommunikationsfehler ist
                                if (logMessage.includes('Cannot call setValue: XML-RPC fault: Generic error (TIMEOUT)')) {
                                    // Prüfen, ob es einen gespeicherten Schaltbefehl gibt, der zu diesem Fehler passt
                                    if (setValueQueue.length > 0) {
                                        // Die älteste Schaltbefehl-Meldung aus der Warteschlange holen
                                        const lastSetValueLogEntry = setValueQueue.shift();
                        
                                        // Extrahiere die Gerätedaten aus dem Schaltbefehl
                                        const match = lastSetValueLogEntry.message.match(/xmlrpc -> setValue ["(.+?):(\d+)","(.+?)",(true|false)] BOOL/);
                        
                                        if (match) {
                                            const deviceAddress = match[1]; // Adresse des Geräts
                                            const channel = match[2]; // Kanal des Geräts
                                            const stateName = match[3]; // Zustandsname (z.B. "STATE")
                                            const value = match[4] === 'true'; // Wert, den der Zustand annehmen soll
                        
                                            // Befehl mit Verzögerung und Wiederholungslogik senden
                                            sendCommandWithRetry(deviceAddress, channel, stateName, value, 3);
                                        }
                                    } else {
                                        log('Kein zugehöriger Schaltbefehl für den Kommunikationsfehler gefunden.', 'warn');
                                    }
                                }
                            }
                        });
                        
                        // Funktion, um den Schaltbefehl mit Wiederholungslogik zu senden
                        function sendCommandWithRetry(deviceAddress, channel, stateName, value, retries) {
                            const stateId = `hm-rpc.1.${deviceAddress}:${channel}.${stateName}`;
                        
                            const attemptToSendCommand = (remainingRetries) => {
                                // Befehl senden
                                setState(stateId, value, false, (err) => {
                                    if (err) {
                                        log(`Fehler beim Senden des Befehls für ${stateId}: ${err}`, 'error');
                        
                                        if (remainingRetries > 0) {
                                            log(`Wiederhole den Befehl in 5 Sekunden (${remainingRetries} Versuche verbleibend).`);
                                            // Erneut versuchen, nachdem eine Verzögerung von 5 Sekunden abgewartet wurde
                                            setTimeout(() => attemptToSendCommand(remainingRetries - 1), 5000); // 5000 ms = 5 Sekunden
                                        } else {
                                            log(`Maximale Anzahl an Wiederholungen erreicht für ${stateId}. Befehl wird nicht erneut gesendet.`, 'error');
                                        }
                                    } else {
                                        log(`Befehl erfolgreich gesendet für ${stateId}`);
                                    }
                                });
                            };
                        
                            // Erste Ausführung des Befehls
                            attemptToSendCommand(retries);
                        }
                        
                        
                        1 Reply Last reply Reply Quote 0
                        • paul53
                          paul53 @skorpil last edited by paul53

                          @skorpil sagte: kann ich den Fehler gegebenenfalls mit einem Skript abfangen?

                          Ich gehe mal davon aus, dass es immer wieder die gleichen Aktoren betrifft und der Adapter bei Kommunikationsstörung den betreffenden Wert nicht bestätigt (ack = false). Dann kann man bei nicht bestätigter Änderung eine Wiederholung anstoßen, die bei Bestätigung des Wertes abgebrochen wird.
                          Skript für einen Aktor mit Wiederholung nach 1 s und 5 s:

                          const idAktor = 'hm-rpc.1.00021D89A1B3E0.3.STATE';
                          
                          var soll = getState(idAktor).val;
                          var timer1 = null;
                          var timer5 = null;
                          
                          on({id: idAktor}, function(dp) {
                              if(dp.state.ack) {
                                  if(dp.state.val == soll) {
                                      clearTimeout(timer1);
                                      clearTimeout(timer5);
                                  }
                              } else if(dp.state.val != soll) {
                                  soll = dp.state.val;
                                  timer1 = setTimeout(function() {setState(idAktor, soll);}, 1000);
                                  timer5 = setTimeout(function() {setState(idAktor, soll);}, 5000);
                              }
                          });
                          
                          S 2 Replies Last reply Reply Quote 1
                          • S
                            skorpil @paul53 last edited by

                            @paul53 ja, es sind immer wieder meine homematic IP Geräte. Keine Ahnung, warum! Das ist ein guter Vorschlag, ich werde auch diese Variante prüfen. Dankeschön.

                            1 Reply Last reply Reply Quote 0
                            • S
                              skorpil @paul53 last edited by skorpil

                              @paul53 ich würde Dein Script gerne "generalisieren". Hier mal mein Versuch:

                              // Funktion, um relevante STATE-IDs im hm-rpc.1-Adapter zu ermitteln
                              function getRelevantDeviceIds() {
                                  const ids = [];
                                  const states = $('state[id=hm-rpc.1.*.STATE]'); // Verwenden von Selektoren, um alle STATE-IDs zu finden
                              
                                  states.each(function (id, i) {
                                      // Prüfen, ob die STATE-ID den Kanal 3 oder 4 betrifft
                                      const parts = id.split('.');
                                      const channel = parts[parts.length - 2];  // Extrahiere die Kanalnummer
                                      if (channel === '3' || channel === '4') {
                                          ids.push(id);
                                      }
                                  });
                              
                                  return ids;
                              }
                              
                              // Hauptfunktion, um für alle relevanten Geräte-IDs das Skript zu implementieren
                              function setupListeners() {
                                  const deviceIds = getRelevantDeviceIds();
                              
                                  // Einmalige Auflistung der relevanten STATE-IDs beim Start des Skripts
                                  log('Relevante STATE-IDs im Adapter hm-rpc.1:', 'info');
                                  deviceIds.forEach(id => log(id, 'info'));
                              
                                  log('Anzahl der überwachten Geräte: ' + deviceIds.length, 'info');  // Log für die Anzahl der Geräte
                              
                                  deviceIds.forEach(idAktor => {
                                      var soll = getState(idAktor).val;
                                      log('Initialer Soll-Wert für ' + idAktor + ': ' + soll, 'debug');  // Debug-Log für den initialen Soll-Wert
                              
                                      var timer1 = null;
                                      var timer5 = null;
                              
                                      // Ereignislistener für Zustandsänderungen des Gerätes
                                      on({id: idAktor}, function(dp) {
                                          log('Zustandsänderung bei ' + idAktor + ': ' + dp.state.val, 'debug');  // Debug-Log für Zustandsänderungen
                              
                                          if (dp.state.ack) {
                                              if (dp.state.val == soll) {
                                                  log('Zustand bestätigt und entspricht dem Soll-Wert bei ' + idAktor, 'debug');  // Debug-Log bei bestätigtem Zustand
                                                  clearTimeout(timer1);
                                                  clearTimeout(timer5);
                                              }
                                          } else if (dp.state.val != soll) {
                                              log('Neuer Soll-Wert für ' + idAktor + ': ' + dp.state.val, 'debug');  // Debug-Log für neuen Soll-Wert
                                              soll = dp.state.val;
                                              timer1 = setTimeout(function() { 
                                                  setState(idAktor, soll); 
                                                  log('Soll-Wert nach 1 Sekunde gesetzt bei ' + idAktor + ': ' + soll, 'debug');  // Debug-Log nach 1 Sekunde
                                              }, 1000);
                                              timer5 = setTimeout(function() { 
                                                  setState(idAktor, soll); 
                                                  log('Soll-Wert nach 5 Sekunden gesetzt bei ' + idAktor + ': ' + soll, 'debug');  // Debug-Log nach 5 Sekunden
                                              }, 5000);
                                          }
                                      });
                                  });
                              }
                              
                              // Skriptausführung starten
                              setupListeners();
                              
                              

                              Ich habe allerdings festgestellt, daß sich bei HMIP Zwischensteckern der relevante State im Kanal 3 findet, bei den HMIP Lichtschaltern im Kanal 4. Fällt Dir irgendeine Möglichkeit ein, im IObroker die für die Schaltung relevanten Kanäle zu ermitteln? Dummerweise gibt es auch in anderen Kanälen "States".Z.B. beim Zwischenstecker in Kanal 4. So dass "States" nicht trennscharf sind.

                              Der Einfachheit halber kann man natürlich alle States in Kanal 3 und 4 überwachen. Aber bei HMIP Lichtschaltern ist das ja nicht relevant, obwohl es eben da einen state gibt.

                              Ideal wäre es, nur die States zu überwachen, die wirklich relevant sind.

                              Homoran 1 Reply Last reply Reply Quote 0
                              • Homoran
                                Homoran Global Moderator Administrators @skorpil last edited by

                                @skorpil HmIP arbeitet mit virtuellen Kanälen!
                                der jeweils erste in dem der State vorkommt dient nur der Anzeige des Gesamtergebnisses der Verknüpfungen der anderen virtuellen Kanäle.
                                nur diese lassen sich auch steuern

                                S 1 Reply Last reply Reply Quote 0
                                • S
                                  skorpil @Homoran last edited by

                                  @homoran Dankeschön. Und welchen muss ich dann steuern? (denn ich vermute, dass mein Problem mit den Fehlermeldungen vielleicht damit zusammen hängt, dass ich den falschen Kanal steuere?)

                                  Homoran P 2 Replies Last reply Reply Quote 0
                                  • Homoran
                                    Homoran Global Moderator Administrators @skorpil last edited by

                                    @skorpil sagte in XML-RPC fault - Fehler abfangen?:

                                    Und welchen muss ich dann steuern?

                                    kommt auf deine Konfiguration an.
                                    so kannst du beim Dimmer z.b. an einem Kanal normal dimmen, am anderen Kanal einen "Faktor" einstellen, so dass es nachts nicht gar so hell wird.

                                    1 Reply Last reply Reply Quote 0
                                    • P
                                      peterfido @skorpil last edited by

                                      @skorpil Was hast Du als HMIP Zentrale, und wie ist das Netzwerk dahin aufgebaut?

                                      Der oben genannte Workaround mit dem Prüfen nach einer Sekunde kann helfen, wäre dann aber nicht die Beseitigung der Ursache.

                                      Wenn das instabil läuft, könntest Du alle Sollwerte unter 0_userdata nochmal abbilden und per Skript regelmäßig schauen, ob Ist=Soll und wenn nicht, dann nochmal den Wert setzen. Bleibt allerdings eine Krücke.

                                      S 1 Reply Last reply Reply Quote 0
                                      • S
                                        skorpil @peterfido last edited by skorpil

                                        @peterfido Dankeschön. Ich habe als Zentrale eine Raspberrymatic. Und unter rpc.1 läuft hmip. Unter nicht reproduzierbaren Umständen, in unregelmäßigen Abständen habe ich dann immer wieder Kommunikationsfehler. Der iobroker läuft unter Debian in VirtualDub (hervorragend!)

                                        Mir ist bewusst, dass das alles Workarounds sind und die Ursache nicht beseitigt wird. Aber dazu müsste ich ja erst mal die Ursache erkennen.

                                        1 Reply Last reply Reply Quote 0
                                        • First post
                                          Last post

                                        Support us

                                        ioBroker
                                        Community Adapters
                                        Donate

                                        777
                                        Online

                                        31.8k
                                        Users

                                        80.0k
                                        Topics

                                        1.3m
                                        Posts

                                        5
                                        22
                                        1291
                                        Loading More Posts
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        Community
                                        Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                        The ioBroker Community 2014-2023
                                        logo