Skip to content
  • Home
  • 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
ioBroker Logo

Community Forum

  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. getObject setObject BUG?

NEWS

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

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

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

getObject setObject BUG?

Scheduled Pinned Locked Moved JavaScript
10 Posts 4 Posters 662 Views 5 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 Offline
    J Offline
    j1s2e3
    wrote on last edited by
    #1

    Ich habe ein komisches Verhalten. Sieht wie ein race/concurrency bug aus.

    Folgendes zum reproduzieren:

    2 Datenpunkte unter 0_userdata anlegen:
    // 0_userdata.0.test.test1
    // 0_userdata.0.test.test2
    beide sind im meinem Fall vom Typ device

    1 Raum unter Aufzählungen->Rooms anlegen
    // enum.rooms.test
    id ist test

    dann dieses Skipt ausführen:

    function add2Enum(id, name) {
        let r = getObject(id);
        if (!r.common.members.includes(name)) {
            r.common.members.push(name);
            log('add2Enum: adding ' + name + ' to enum ' + id, 'info');
            setObject(id, r, function (err) {
                if (err) log('add2Enum: adding ' + name + ' to enum ' + id + ' - error=' + err, 'error');
            });
        }
    }
    
    add2Enum('enum.rooms.outdoors', '0_userdata.0.test.test1');
    add2Enum('enum.rooms.outdoors', '0_userdata.0.test.test2');
    

    Skipt soll DP einem Raum zuordnen. Wenn ich beide Aufrufe add2Enum ausführe, dann wird nur test2 dem Raum test zugeordnet. test1, also der erste Aufruf von add2Enum(), nicht. Einzelne Aufrufe, oder zeitlich entzerrte Aufrufe gehen.
    setObject läuft ohne Fehler durch. Hier das Log:

    14:18:20.860	info	javascript.0 (25948) Stop script script.js.common.VirtualDevices.set-get-test
    14:18:26.922	info	javascript.0 (25948) Start javascript script.js.common.VirtualDevices.set-get-test
    14:18:26.930	info	javascript.0 (25948) script.js.common.VirtualDevices.set-get-test: add2Enum: adding 0_userdata.0.test.test1 to enum enum.rooms.test
    14:18:26.931	info	javascript.0 (25948) script.js.common.VirtualDevices.set-get-test: add2Enum: adding 0_userdata.0.test.test2 to enum enum.rooms.test
    14:18:26.931	info	javascript.0 (25948) script.js.common.VirtualDevices.set-get-test: registered 0 subscriptions and 0 schedules
    

    Es scheint so, als ob das setObject für test1 noch nicht abgeschlossen, in die DB geschrieben, ist, wenn im 2. Aufruf von add2Enum() wieder getObject() auf die gleiche id gemacht wird. Das 2. getObject('enum.rooms.outdoors') liefert noch den Zustand vor dem setObject zurück, als test1 noch nicht member von enum.rooms.test war. D.h. obwohl das setObject für test1 erfolgreich war und aus Skript-Sicht abgeschlossen ist, liefert ein zeitlich nahes erneutes getObject, nicht den Zustand zurück, der eben via setObject definiert wurde.

    Wenn ich das Objekt r vom 2. getObject() dumpe, dann ist test1 definitiv nicht unter r.members enthalten.

    Für mich sieht das nach einem Bug aus. In der Javascriptdoku steht auch nichts, dass man nach setObject noch irgendein commit oder sonstwas machen sollte.

    F 1 Reply Last reply
    0
    • J j1s2e3

      Ich habe ein komisches Verhalten. Sieht wie ein race/concurrency bug aus.

      Folgendes zum reproduzieren:

      2 Datenpunkte unter 0_userdata anlegen:
      // 0_userdata.0.test.test1
      // 0_userdata.0.test.test2
      beide sind im meinem Fall vom Typ device

      1 Raum unter Aufzählungen->Rooms anlegen
      // enum.rooms.test
      id ist test

      dann dieses Skipt ausführen:

      function add2Enum(id, name) {
          let r = getObject(id);
          if (!r.common.members.includes(name)) {
              r.common.members.push(name);
              log('add2Enum: adding ' + name + ' to enum ' + id, 'info');
              setObject(id, r, function (err) {
                  if (err) log('add2Enum: adding ' + name + ' to enum ' + id + ' - error=' + err, 'error');
              });
          }
      }
      
      add2Enum('enum.rooms.outdoors', '0_userdata.0.test.test1');
      add2Enum('enum.rooms.outdoors', '0_userdata.0.test.test2');
      

      Skipt soll DP einem Raum zuordnen. Wenn ich beide Aufrufe add2Enum ausführe, dann wird nur test2 dem Raum test zugeordnet. test1, also der erste Aufruf von add2Enum(), nicht. Einzelne Aufrufe, oder zeitlich entzerrte Aufrufe gehen.
      setObject läuft ohne Fehler durch. Hier das Log:

      14:18:20.860	info	javascript.0 (25948) Stop script script.js.common.VirtualDevices.set-get-test
      14:18:26.922	info	javascript.0 (25948) Start javascript script.js.common.VirtualDevices.set-get-test
      14:18:26.930	info	javascript.0 (25948) script.js.common.VirtualDevices.set-get-test: add2Enum: adding 0_userdata.0.test.test1 to enum enum.rooms.test
      14:18:26.931	info	javascript.0 (25948) script.js.common.VirtualDevices.set-get-test: add2Enum: adding 0_userdata.0.test.test2 to enum enum.rooms.test
      14:18:26.931	info	javascript.0 (25948) script.js.common.VirtualDevices.set-get-test: registered 0 subscriptions and 0 schedules
      

      Es scheint so, als ob das setObject für test1 noch nicht abgeschlossen, in die DB geschrieben, ist, wenn im 2. Aufruf von add2Enum() wieder getObject() auf die gleiche id gemacht wird. Das 2. getObject('enum.rooms.outdoors') liefert noch den Zustand vor dem setObject zurück, als test1 noch nicht member von enum.rooms.test war. D.h. obwohl das setObject für test1 erfolgreich war und aus Skript-Sicht abgeschlossen ist, liefert ein zeitlich nahes erneutes getObject, nicht den Zustand zurück, der eben via setObject definiert wurde.

      Wenn ich das Objekt r vom 2. getObject() dumpe, dann ist test1 definitiv nicht unter r.members enthalten.

      Für mich sieht das nach einem Bug aus. In der Javascriptdoku steht auch nichts, dass man nach setObject noch irgendein commit oder sonstwas machen sollte.

      F Offline
      F Offline
      fastfoot
      wrote on last edited by
      #2

      @j1s2e3 sagte in getObject setObject BUG?:

      Für mich sieht das nach einem Bug aus.

      für mich sieht das aus als wärst du in die asynch-Falle getappt. setObject() arbeitet asynchron, das heißt ein Ergebnis wird irgendwann geliefert, in dem Fall nachdem du bereits den 2ten Aufruf gestartet hast. Im Folgenden wird gewartet bis der erste Aufruf beendet ist.

      async function add2Enum(id, name) {
          let r = getObject(id);
          if (!r.common.members.includes(name)) {
              r.common.members.push(name);
              await setObjectAsync(id, r);
              return true;
          }
          return false;
      }
      
      async function main() {
          let res = false;
          res = await add2Enum('enum.rooms.living_room', '0_userdata.0.Forum.test.t1')
          if (res) log('add2Enum: adding ' + '0_userdata.0.Forum.test.t1' + ' to enum ' + 'enum.rooms.living_room' + ' finished', 'info');
      
          res = await add2Enum('enum.rooms.living_room', '0_userdata.0.Forum.test.t2')
          if (res) log('add2Enum: adding ' + '0_userdata.0.Forum.test.t2' + ' to enum ' + 'enum.rooms.living_room' + ' finished', 'info');
      }
      
      main()
      

      iobroker läuft unter Docker auf QNAP TS-451+
      SkriptRecovery: https://forum.iobroker.net/post/930558

      T J 2 Replies Last reply
      1
      • F fastfoot

        @j1s2e3 sagte in getObject setObject BUG?:

        Für mich sieht das nach einem Bug aus.

        für mich sieht das aus als wärst du in die asynch-Falle getappt. setObject() arbeitet asynchron, das heißt ein Ergebnis wird irgendwann geliefert, in dem Fall nachdem du bereits den 2ten Aufruf gestartet hast. Im Folgenden wird gewartet bis der erste Aufruf beendet ist.

        async function add2Enum(id, name) {
            let r = getObject(id);
            if (!r.common.members.includes(name)) {
                r.common.members.push(name);
                await setObjectAsync(id, r);
                return true;
            }
            return false;
        }
        
        async function main() {
            let res = false;
            res = await add2Enum('enum.rooms.living_room', '0_userdata.0.Forum.test.t1')
            if (res) log('add2Enum: adding ' + '0_userdata.0.Forum.test.t1' + ' to enum ' + 'enum.rooms.living_room' + ' finished', 'info');
        
            res = await add2Enum('enum.rooms.living_room', '0_userdata.0.Forum.test.t2')
            if (res) log('add2Enum: adding ' + '0_userdata.0.Forum.test.t2' + ' to enum ' + 'enum.rooms.living_room' + ' finished', 'info');
        }
        
        main()
        
        T Offline
        T Offline
        ticaki
        wrote on last edited by
        #3

        @fastfoot
        Ich würde getObjectAsync() auch noch verwenden, aber nicht nötig

        Weather-Warnings Espresense NSPanel-Lovelace-ui Tagesschau

        Spenden

        F 1 Reply Last reply
        0
        • F fastfoot

          @j1s2e3 sagte in getObject setObject BUG?:

          Für mich sieht das nach einem Bug aus.

          für mich sieht das aus als wärst du in die asynch-Falle getappt. setObject() arbeitet asynchron, das heißt ein Ergebnis wird irgendwann geliefert, in dem Fall nachdem du bereits den 2ten Aufruf gestartet hast. Im Folgenden wird gewartet bis der erste Aufruf beendet ist.

          async function add2Enum(id, name) {
              let r = getObject(id);
              if (!r.common.members.includes(name)) {
                  r.common.members.push(name);
                  await setObjectAsync(id, r);
                  return true;
              }
              return false;
          }
          
          async function main() {
              let res = false;
              res = await add2Enum('enum.rooms.living_room', '0_userdata.0.Forum.test.t1')
              if (res) log('add2Enum: adding ' + '0_userdata.0.Forum.test.t1' + ' to enum ' + 'enum.rooms.living_room' + ' finished', 'info');
          
              res = await add2Enum('enum.rooms.living_room', '0_userdata.0.Forum.test.t2')
              if (res) log('add2Enum: adding ' + '0_userdata.0.Forum.test.t2' + ' to enum ' + 'enum.rooms.living_room' + ' finished', 'info');
          }
          
          main()
          
          J Offline
          J Offline
          j1s2e3
          wrote on last edited by
          #4

          @fastfoot Danke für die Erklärung! Aber woher sollte ich wissen, dass setObject asynchron ist. In der Doku auf github steht da nix zu??? Gibt es irgendwo noch eine "bessere" Doku?

          In deinem Beispiel nimmst Du setObjectAsync(). Da würde ich von einem asynchronem Verhalten ausgehen. Suggeriert ja der Name schon. Aber setObjectAsync() ist wird in der Github-Doku nichtmal erwähnt und die Doku auf Github ist die einzige, welche ich bisher als API-Doku gefunden habe. Welche Doku nimmst Du denn?

          Was ist dann der Unterschied zw. setObject() und setObjectAsync()? Keiner?

          F 1 Reply Last reply
          0
          • J j1s2e3

            @fastfoot Danke für die Erklärung! Aber woher sollte ich wissen, dass setObject asynchron ist. In der Doku auf github steht da nix zu??? Gibt es irgendwo noch eine "bessere" Doku?

            In deinem Beispiel nimmst Du setObjectAsync(). Da würde ich von einem asynchronem Verhalten ausgehen. Suggeriert ja der Name schon. Aber setObjectAsync() ist wird in der Github-Doku nichtmal erwähnt und die Doku auf Github ist die einzige, welche ich bisher als API-Doku gefunden habe. Welche Doku nimmst Du denn?

            Was ist dann der Unterschied zw. setObject() und setObjectAsync()? Keiner?

            F Offline
            F Offline
            fastfoot
            wrote on last edited by
            #5

            @j1s2e3 wenn eine Funktion einen Callback hat ist sie grundsätzlich asynchron. Auch die...Async Funktionen sind erst einmal asynchron(sic!), denn sie liefern ein Promise zurück welches auch nur ein 'Versprechen in die Zukunft' ist. Das synchrone Verhalten erreicht man erst durch await, welches auf die Erfüllung dieses Versprechens wartet. Das beantwortet dann auch deine Frage ob die beiden Funktionen denn gleich sind :-)

            Mit der Doku ist das so eine Sache, die ist auch irgendwie asynchron und liefert ein Versprechen, in der Zukunft gut und vollständig zu sein :-)

            iobroker läuft unter Docker auf QNAP TS-451+
            SkriptRecovery: https://forum.iobroker.net/post/930558

            1 Reply Last reply
            2
            • T ticaki

              @fastfoot
              Ich würde getObjectAsync() auch noch verwenden, aber nicht nötig

              F Offline
              F Offline
              fastfoot
              wrote on last edited by
              #6

              @ticaki sagte in getObject setObject BUG?:

              @fastfoot
              Ich würde getObjectAsync() auch noch verwenden, aber nicht nötig

              da gibt es keinen Grund dazu. Die xxxAsync Funktionen im JS-Adapter sind Versionen der Funktionen ohne Async, welche promisified wurden, um callback-style Funktionen in Promises zu wandeln. Das macht aber nur Sinn wenn man sie mit await verwenden will, was im Falle von getObject() aber nicht notwendig ist, da es hier ohne callback verwendet wird. Oder anders gesagt, das schafft nur overhead, keinen Mehrwert(imho!)

              iobroker läuft unter Docker auf QNAP TS-451+
              SkriptRecovery: https://forum.iobroker.net/post/930558

              T 1 Reply Last reply
              0
              • F fastfoot

                @ticaki sagte in getObject setObject BUG?:

                @fastfoot
                Ich würde getObjectAsync() auch noch verwenden, aber nicht nötig

                da gibt es keinen Grund dazu. Die xxxAsync Funktionen im JS-Adapter sind Versionen der Funktionen ohne Async, welche promisified wurden, um callback-style Funktionen in Promises zu wandeln. Das macht aber nur Sinn wenn man sie mit await verwenden will, was im Falle von getObject() aber nicht notwendig ist, da es hier ohne callback verwendet wird. Oder anders gesagt, das schafft nur overhead, keinen Mehrwert(imho!)

                T Offline
                T Offline
                ticaki
                wrote on last edited by
                #7

                @fastfoot
                Es macht Sinn da die ganze Funktion in dem Fall ohne abonnierte States funktioniert. ;) Ich weiß halt nur nicht, wieso man die nicht abonnieren sollte.

                Weather-Warnings Espresense NSPanel-Lovelace-ui Tagesschau

                Spenden

                paul53P F 2 Replies Last reply
                0
                • T ticaki

                  @fastfoot
                  Es macht Sinn da die ganze Funktion in dem Fall ohne abonnierte States funktioniert. ;) Ich weiß halt nur nicht, wieso man die nicht abonnieren sollte.

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

                  @ticaki sagte: wieso man die nicht abonnieren sollte.

                  Wenn man die States / Objekte abonniert, werden sie mit den synchronen Funktionen aus dem Puffer der Javascript-Instanz geholt, andernfalls aus dem js-controller.

                  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
                  • T ticaki

                    @fastfoot
                    Es macht Sinn da die ganze Funktion in dem Fall ohne abonnierte States funktioniert. ;) Ich weiß halt nur nicht, wieso man die nicht abonnieren sollte.

                    F Offline
                    F Offline
                    fastfoot
                    wrote on last edited by
                    #9

                    @ticaki sagte in getObject setObject BUG?:

                    @fastfoot
                    Es macht Sinn da die ganze Funktion in dem Fall ohne abonnierte States funktioniert. ;) Ich weiß halt nur nicht, wieso man die nicht abonnieren sollte.

                    der TE hat die States aber nunmal abonniert :-)

                    iobroker läuft unter Docker auf QNAP TS-451+
                    SkriptRecovery: https://forum.iobroker.net/post/930558

                    T 1 Reply Last reply
                    0
                    • F fastfoot

                      @ticaki sagte in getObject setObject BUG?:

                      @fastfoot
                      Es macht Sinn da die ganze Funktion in dem Fall ohne abonnierte States funktioniert. ;) Ich weiß halt nur nicht, wieso man die nicht abonnieren sollte.

                      der TE hat die States aber nunmal abonniert :-)

                      T Offline
                      T Offline
                      ticaki
                      wrote on last edited by ticaki
                      #10

                      @fastfoot
                      Das Lesen mehr Leute als nur der TE und ich hätte mir viel ausprobieren erspart, wenn manches vollständiger ausgeführt würde. Doku gibts ja teilweise nur als versprechen. :)

                      Weather-Warnings Espresense NSPanel-Lovelace-ui Tagesschau

                      Spenden

                      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

                      440

                      Online

                      32.4k

                      Users

                      81.4k

                      Topics

                      1.3m

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

                      • Don't have an account? Register

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