Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • 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

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. Selektor $ Datenpunkte refresh Problem

NEWS

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

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

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

Selektor $ Datenpunkte refresh Problem

Geplant Angeheftet Gesperrt Verschoben JavaScript
javascript
6 Beiträge 2 Kommentatoren 588 Aufrufe 1 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • zaunermaxZ Offline
    zaunermaxZ Offline
    zaunermax
    schrieb am zuletzt editiert von
    #1

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

    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 :thinking_face:

    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 :thinking_face:

    // 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 :raised_hands:

    paul53P 1 Antwort Letzte Antwort
    0
    • zaunermaxZ zaunermax

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

      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 :thinking_face:

      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 :thinking_face:

      // 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 :raised_hands:

      paul53P Offline
      paul53P Offline
      paul53
      schrieb am zuletzt editiert von paul53
      #2

      @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
      });
      

      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

      zaunermaxZ 1 Antwort Letzte Antwort
      0
      • paul53P 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
        });
        
        zaunermaxZ Offline
        zaunermaxZ Offline
        zaunermax
        schrieb am zuletzt editiert von
        #3

        @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.

        paul53P 3 Antworten Letzte Antwort
        0
        • zaunermaxZ zaunermax

          @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.

          paul53P Offline
          paul53P Offline
          paul53
          schrieb am zuletzt editiert von
          #4

          @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.

          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 Antwort Letzte Antwort
          0
          • zaunermaxZ zaunermax

            @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.

            paul53P Offline
            paul53P Offline
            paul53
            schrieb am zuletzt editiert von paul53
            #5

            @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);
            

            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 Antwort Letzte Antwort
            0
            • zaunermaxZ zaunermax

              @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.

              paul53P Offline
              paul53P Offline
              paul53
              schrieb am zuletzt editiert von paul53
              #6

              @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
              });
              

              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 Antwort Letzte Antwort
              0
              Antworten
              • In einem neuen Thema antworten
              Anmelden zum Antworten
              • Älteste zuerst
              • Neuste zuerst
              • Meiste Stimmen


              Support us

              ioBroker
              Community Adapters
              Donate

              617

              Online

              32.5k

              Benutzer

              81.6k

              Themen

              1.3m

              Beiträge
              Community
              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
              ioBroker Community 2014-2025
              logo
              • Anmelden

              • Du hast noch kein Konto? Registrieren

              • Anmelden oder registrieren, um zu suchen
              • Erster Beitrag
                Letzter Beitrag
              0
              • Home
              • Aktuell
              • Tags
              • Ungelesen 0
              • Kategorien
              • Unreplied
              • Beliebt
              • GitHub
              • Docu
              • Hilfe