Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Selektor $ Datenpunkte refresh Problem

    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

    Selektor $ Datenpunkte refresh Problem

    This topic has been deleted. Only users with topic management privileges can see it.
    • zaunermax
      zaunermax last edited by

      Hi Leute, dies ist mein erster Post, wenn also was nicht ganz konform ist pls have mercy 😜

      Zu aller erst einmal mein usecase:

      Ich möchte ein Skript schreiben, dass auf einen Channel schaut und darauf reagiert, wenn neue Objekte angelegt werden. In dem Fall ein Alexa Device, welches im Channel Alarms die Alarme drin hat. Wenn ich das Skript starte, soll es also alle Datenpunkte im Alarm Channel durchsehen, ob es einen aktiven Alarm gibt. Wenn ja soll ein schedule erstellt werden, der mir das Licht schon 30 Min vor dem Wecker an macht.

      Das Problem

      Jetzt ist mit beim Verwenden des $ selektors aber aufgefallen, dass dieser einmal beim JS-Adapter restart alle Objekte zu merken scheint und sich danach nicht mehr updated. Wenn ich also einen Alarm lösche oder einen neuen hinzufüge, merkt dies der $ Selektor nicht. Sogar wenn ich das Skript neu starte, erkennt der Selektor die neuen Werte nicht. Erst bei einem kompletten Adapter restart werden die neuen Werte erkannt.

      Ist das per design so? Gibts da einen Workaround?

      Trying to fix it

      Wenn ich nun die on() subscribe Funktion mit einer Regex verwende, geht dies einwandfrei neue noch nicht existierende Objekte zu erkennen. Jedoch kann die on methode ja nicht bei script start schon alle Alarme des devices durchsehen, sondern nur auf changes reagieren 🤔

      Let's see the code

      Ich denke ein paar Zeilen code sagen mehr als 1000 worte, deswegen hier mein Skript code:

      const timeSelector = $(`channel[state.id=${ECHO_ALARM_PFAD}.*.time]`);
      
      // gibt mir nur die alarme aus, die zum JS-Adapter restart verfügbar waren
      timeSelector.each(async (val) => {
          const enabledId = val.replace('time', 'enabled');
          const devicePath = val.replace('.time', '');
      
          const enabled = (await getStateAsync(enabledId)).val;
          const time = (await getStateAsync(val)).val.split(':');
          
          removeOrRefreshSchedule(devicePath, time, enabled);
      });
      

      Was allerdings schon funzt ist, wenn das script mal läuft, dann kann ich mit der on Funktion auf neu hinzugefügte Alarme sehr wohl reagieren, doch das problem ist, sobald man das Script restarted, werden die neuen Alarme wieder gelöscht, weil die Datenpunkte ja erst im nachhinein hinzugefügt wurden 🤔

      // das hier funzt einwandfrei wenn man neue datenpunkte added/removed
      on({ id: enabledRegex, change: 'ne' }, async ({ id, state: { val } }) => {
          const timeId = id.replace('enabled', 'time');
          const devicePath = id.replace('.enabled', '');
      
          const time = (await getStateAsync(timeId)).val.split(':');
      
          removeOrRefreshSchedule(devicePath, time, val);
      });
      

      Vielen Dank im Voraus schon mal für eure Antworten 🙌

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

        @zaunermax sagte:

        mit der on Funktion auf neu hinzugefügte Alarme sehr wohl reagieren, doch das problem ist, sobald man das Script restarted, werden die neuen Alarme wieder gelöscht, weil die Datenpunkte ja erst im nachhinein hinzugefügt wurden

        Man kann sich die IDs in einem Array-Datenpunkt merken, der bei jedem neuen Datenpunkt aktualisiert wird. Etwa so:

        const idDps = '...'; // Array
        const idUptime = 'system.adapter.javascript.' + instance + '.uptime';
        const ECHO_ALARM_PFAD = '...';
        var ids = [];
        
        if(getState(idUptime).val < 10) { // Instanz gestartet
            const sel = $(ECHO_ALARM_PFAD + '.*.time');
            for(let id in sel) {
                ids[id] = sel[id];
            }
            setState(idDps, ids, true);
        } else ids = getState(idDps).val;
        
        on({id: /RegExp/}, function(dp) {
            if(!ids.includes(dp.id)) { // DP ist neu
                ids.push(dp.id);
                setState(idDps, ids, true);
            }
            // Auswertung
        });
        
        zaunermax 1 Reply Last reply Reply Quote 0
        • zaunermax
          zaunermax @paul53 last edited by

          @paul53 Ja so in etwa hätte ich das gemacht, nur gibts dann das Problem, dass beim Skript restart wieder die "alten" Datenpunkte auftauchen, also hätte ich einmal alle 5 Alarme gelöscht und 3 neue hinzugefügt, so würde der $ mir die 5 alten bereits gelöschten datenpunkte liefern, solange, bis ich den ganzen JS adapter restarte.

          Da hilfts ja auch nicht, wenn ich mir die Datenpunkte zwischendurch merke, weil ich ja während dem Development das script auch manchmal neu starten muss.

          paul53 3 Replies Last reply Reply Quote 0
          • paul53
            paul53 @zaunermax last edited by

            @zaunermax sagte:

            $ mir die 5 alten bereits gelöschten datenpunkte liefern, solange, bis ich den ganzen JS adapter restarte.

            Ja, gelöschte Datenpunkte triggern nicht mehr.

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

              @zaunermax sagte:

              $ mir die 5 alten bereits gelöschten datenpunkte liefern, solange, bis ich den ganzen JS adapter restarte.

              Man kann die gelöschten Datenpunkte mit deleteObject(id) aus dem Javascript-Puffer löschen, wenn man deren Nicht-Existenz mit der asynchronen Funktion existsState(id) abfragt.

              for(let i = 0; i < ids.length; i++) {
                  existsState(ids[i], function(err, exists) {
                      if(!err && !exists) {
                          deleteObject(ids[i]);
                          ids.splice(i, 1);
                          i--;
                      }
                  });
              }
              setState(idDps, ids, true);
              
              1 Reply Last reply Reply Quote 0
              • paul53
                paul53 @zaunermax last edited by paul53

                @zaunermax
                Habe noch eine Methode getestet, mit der der Javascript-Puffer bei Skriptstart und bei neuen Datenpunkten aktuell gehalten wird.

                const ECHO_ALARM_PFAD = '...';
                const sel = $(ECHO_ALARM_PFAD + '.*.time');
                const ids = [];
                
                sel.each(function(id, i) {
                    existsState(id, function(err, exists) {
                        if(!err) {
                            if(exists) ids.push(id);
                            else deleteObject(id); // in beiden Puffern löschen
                        }
                    });
                });
                
                on({id: /REgExp/}, function(dp) {
                    if(!ids.includes(dp.id)) { // DP ist neu
                        ids.push(dp.id);
                        let obj = {};
                        obj.type = 'state';
                        obj.common = dp.common;
                        obj.native = dp.native;
                        setObject(dp.id, obj); // in objects buffer
                        setState(dp.id, dp.state.val, true); // in states buffer
                    }
                    // Auswertung
                });
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post

                Support us

                ioBroker
                Community Adapters
                Donate

                1.0k
                Online

                31.8k
                Users

                80.0k
                Topics

                1.3m
                Posts

                javascript
                2
                6
                433
                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