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

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. Alexa Shopping List mit Bring synchronisieren

NEWS

  • Monatsrückblick Januar/Februar 2026 ist online!
    BluefoxB
    Bluefox
    16
    1
    330

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    17
    1
    4.8k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    1.3k

Alexa Shopping List mit Bring synchronisieren

Scheduled Pinned Locked Moved Skripten / Logik
182 Posts 31 Posters 38.3k Views 32 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.
  • icastillo15I icastillo15

    Hallo zusammen,

    ich habe mein Script nochmal aktualisiert. Es werden in Alexa nun automatisch alle Duplikate sofort wieder gelöscht. Außerdem wird nun erzwungen, dass Artikel mit einem Großbuchstaben beginnen.

    Viel Spaß damit und gerne wieder testen :-)

    Kleiner Nachtrag: wenn ich über Alexa Dinge hinzufüge und dann in Bring als erledigt markiere, dann werden diese bei mir in Alexa nicht mehr gelöscht. Das muss ich mir nochmal ansehen - könnte an den Zeitstempeln liegen.

    Nachtrag 2: ging doch - mein Adapter war nur offline 😎

    const bringBaseId = 'bring.0.0f0c420c-3298-4911-91f5-7ed0fbbfd36e';
    const alexa2BaseId = 'alexa2.0.Lists.SHOPPING_LIST';
    
    const bringListId = bringBaseId + '.content';
    const bringListCompletedId = bringBaseId + '.recentContent';
    const bringAddToList = bringBaseId + '.saveItem';
    const bringCompleteItem = bringBaseId + '.moveToRecentContent';
    const alexaAddToList = alexa2BaseId + '.#New';
    const alexaListId = alexa2BaseId + '.json';
    
    //switch off to silence:
    const printDebug = true;
    
    function debug(msg) {
        if (printDebug) {
            log(msg)
        }
    }
    
    const TodoItemStatus = {
        NeedsAction: 'needs_action',
        Completed: 'completed',
    };
    
    /**
     * @typedef bringItem
     * @type {object}
     * @property {string} specification
     * @property {string} name
     * @property {string} status
     * @property {boolean} [found] - keep track if found or not.
     */
    
    /**
     * @typedef alexaItem
     * @type {object}
     * @property {string} value
     * @property {string} id
     * @property {boolean} completed
     * @property {number} updatedDateTime
     * @property {boolean} [found] - keep track if found or not.
     */
    
    /**
     * Compare alexaItem complete and bringItem status -> returns true if same status.
     * @param {Array<alexaItem>} alexaList
     * @param {Array<bringItem>} list
     * @returns {boolean} true if same status.
    */
    function compareCompleted(alexaItem, bringItem) {
        if (alexaItem.completed && bringItem.status !== TodoItemStatus.Completed) {
            return false;
        }
        if (!alexaItem.completed && bringItem.status !== TodoItemStatus.NeedsAction) {
            return false;
        }
        return true;
    }
    
    function ListCleaner(Eintrag='') {
        const arr = Eintrag.split(' ');
        for (let i = 0; i < arr.length; i++) {
            arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
        }
        return arr.join(' ');
    }
    
    /**
     * sync lists
     * @param {Array<alexaItem>} alexaList
     * @param {Array<bringItem>} list
     * @param {number} timestampBring
     * @param {string} msource
     * @param {Array<bringItem>} recentList
     * @returns {Array<bringItem>} new bring List
     */
    function syncLists(alexaList, list, timestampBring, msource, recentList) {
        const newBringList = [];
        var empty = true;
        for (const alexaItem of alexaList) {
    
            for (const bringItem of list) {
                empty = false;
    
                if (bringItem.name === alexaItem.value) {
                    alexaItem.found = true;
                    bringItem.found = true;
    
    
                    //found item. Update completed state from 'newer' list: 
                    bringItem.status = TodoItemStatus.NeedsAction;
                    if (alexaItem.updatedDateTime > timestampBring) {
                        if (alexaItem.value !== bringItem.name || !compareCompleted(alexaItem, bringItem)) {
    
                            if (msource === 'Alexa') {
                               debug('Updating Bring item: ' + bringItem.name + ' from Alexa');
                               setState(bringCompleteItem, ListCleaner(bringItem.name));
                            }                   
                        }
                    
                    } else {
                        //keep bring:
    
                        //update alexa:
                        if (!compareCompleted(alexaItem, bringItem)) {
                            if (msource === 'Bring') {
                                bringItem.status = TodoItemStatus.Completed;
                                debug('Update  Alexa item: ' + alexaItem.value + ' to ' + (bringItem.status === TodoItemStatus.Completed ? 'done' : 'undone') + ' from Bring.');
                                setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItem.status === TodoItemStatus.Completed);
                            } 
                        }
                    }
                }
            }
    
            for (const bringItemCompleted of recentList) {
                if (bringItemCompleted.name === alexaItem.value) {
                    alexaItem.found = true;
                    bringItemCompleted.found = true;
    
                    //found item. Update completed state from 'newer' list: 
                    bringItemCompleted.status = TodoItemStatus.Completed;
                    if (alexaItem.updatedDateTime > timestampBring) {
                        if (alexaItem.value !== bringItemCompleted.name || !compareCompleted(alexaItem, bringItemCompleted)) {
    
                            if (msource === 'Alexa') {
                               debug('Adding Bring item: ' + bringItemCompleted.name + ' from Alexa');
                               setState(bringAddToList, ListCleaner(bringItemCompleted.name));
                            }                   
                        }
                    
                    } else {
                        //keep bring:
    
                        //update alexa:
                        if (!compareCompleted(alexaItem, bringItemCompleted)) {
                            bringItemCompleted.status = TodoItemStatus.Completed;
                            if (msource === 'Bring') {
                                debug('Delete  Alexa item: ' + alexaItem.value + ' from Bring.');
                                //setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItemCompleted.status === TodoItemStatus.Completed);
                                setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                            } 
                        }
                    }
                }
            }
    
    
            if (!alexaItem.found) {
                //alexa item not found:
                if (alexaItem.completed) {
                    debug('Delete ' + alexaItem.value + ' because done and not in Bring list.');
                    setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                } else {
                    if (msource === 'Alexa') {
                        debug('Adding ' + alexaItem.value + ' to Bring list');
                        setState(bringAddToList, ListCleaner(alexaItem.value));
                    }
                }
            }
    
            if (empty === true) {
                if (alexaItem.updatedDateTime < timestampBring) {
                    debug('Delete ' + alexaItem.value + ' from Alexa list because Bring list is all done.');
                    setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                }
            }
        
        }
    
        for (const bringItem of list) {
            if (!bringItem.found) {
                if (bringItem.status === TodoItemStatus.Completed) {
                    //debug('Remove from bring item:  ' + bringItem.name + ' because done and not on alexa list');
                    //Not executed since I want to keep the recent items inside bring app
                } else {
                    if (msource === 'Bring') {
                        debug('Adding ' + bringItem.name + ' to Alexa list.');
                        setState(alexaAddToList, ListCleaner(bringItem.name));
                    }
                }
            }
        }
    
        return newBringList;
    }
    
    
    function doSync(source) {
        eliminateDuplicated();
        const alexaList = JSON.parse(getState(alexaListId).val);
        const state = getState(bringListId);
        const bringList = JSON.parse(state.val);
        const state2 = getState(bringListCompletedId);
        const bringListCompleted = JSON.parse(state2.val);
    
        syncLists(alexaList, bringList, state.ts, source, bringListCompleted);
    }
    
    function eliminateDuplicated() {
        var myAlexaList = JSON.parse(getState(alexaListId).val);
        var arrayWithDuplicates = [];
    
        for(var alexaItem of myAlexaList) {
            var obj = {};
            obj["value"] = ListCleaner(alexaItem.value);
            obj["id"] = alexaItem.id;
            arrayWithDuplicates.push(obj);       
        }
    
        const lookup = arrayWithDuplicates.reduce((a, e) => {
        a[e.value] = ++a[e.value] || 0;
        return a;
        }, {});
    
        const
            getKey = o => keys.map(k => o[k]).join('|'),
            keys = ['value'],
            myarray = arrayWithDuplicates.filter(e => lookup[e.value]),
            hash = Object.create(null),
            duplicates = myarray.filter(o =>
                (k => (hash[k] = (hash[k] || 0) + 1) > 1)
                (getKey(o))
            );
    
        for(var item of duplicates) {
            debug('Delete  Alexa item: ' + item.value + ' because duplicated.');
            setState(`${alexa2BaseId}.items.${item.id}.#delete`, true);
        }
    }
    
    on({id: bringListId, change: 'any'}, e => {
        debug('Update triggered from Bring');
        doSync('Bring');
    });
    
    on({id: alexaListId, change: 'any'}, e => {
        debug('Update triggered from Alexa');
        doSync('Alexa');
    });
    
    doSync();
    
    
    FuchsbauF Offline
    FuchsbauF Offline
    Fuchsbau
    wrote on last edited by
    #46

    @icastillo15
    Chapeau icastillo15, :+1: :clap:
    ich habe es eben getestet und es läuft hervorragen.
    Es ist genial das du es geschafft hast mit der Duplikate Erkennung und Korrektur zur Großschreibung.

    Mit der Bring Spracheingabe, meinte ich übrigens das Alexa Bring Skill. Das wir mit deinem Skript, jetzt nicht mehr benötigt.

    Jetzt könne wir nur hoffen, das Amazon die Lücke, das die Einkaufsliste ausgelesen und bearbeite werden kann, nicht schlisst.

    Von meiner Seite ein großes Dankeschön. :handshake:

    Gruß Fuchsbau

    1 Reply Last reply
    0
    • icastillo15I icastillo15

      Hallo zusammen,

      ich habe mein Script nochmal aktualisiert. Es werden in Alexa nun automatisch alle Duplikate sofort wieder gelöscht. Außerdem wird nun erzwungen, dass Artikel mit einem Großbuchstaben beginnen.

      Viel Spaß damit und gerne wieder testen :-)

      Kleiner Nachtrag: wenn ich über Alexa Dinge hinzufüge und dann in Bring als erledigt markiere, dann werden diese bei mir in Alexa nicht mehr gelöscht. Das muss ich mir nochmal ansehen - könnte an den Zeitstempeln liegen.

      Nachtrag 2: ging doch - mein Adapter war nur offline 😎

      const bringBaseId = 'bring.0.0f0c420c-3298-4911-91f5-7ed0fbbfd36e';
      const alexa2BaseId = 'alexa2.0.Lists.SHOPPING_LIST';
      
      const bringListId = bringBaseId + '.content';
      const bringListCompletedId = bringBaseId + '.recentContent';
      const bringAddToList = bringBaseId + '.saveItem';
      const bringCompleteItem = bringBaseId + '.moveToRecentContent';
      const alexaAddToList = alexa2BaseId + '.#New';
      const alexaListId = alexa2BaseId + '.json';
      
      //switch off to silence:
      const printDebug = true;
      
      function debug(msg) {
          if (printDebug) {
              log(msg)
          }
      }
      
      const TodoItemStatus = {
          NeedsAction: 'needs_action',
          Completed: 'completed',
      };
      
      /**
       * @typedef bringItem
       * @type {object}
       * @property {string} specification
       * @property {string} name
       * @property {string} status
       * @property {boolean} [found] - keep track if found or not.
       */
      
      /**
       * @typedef alexaItem
       * @type {object}
       * @property {string} value
       * @property {string} id
       * @property {boolean} completed
       * @property {number} updatedDateTime
       * @property {boolean} [found] - keep track if found or not.
       */
      
      /**
       * Compare alexaItem complete and bringItem status -> returns true if same status.
       * @param {Array<alexaItem>} alexaList
       * @param {Array<bringItem>} list
       * @returns {boolean} true if same status.
      */
      function compareCompleted(alexaItem, bringItem) {
          if (alexaItem.completed && bringItem.status !== TodoItemStatus.Completed) {
              return false;
          }
          if (!alexaItem.completed && bringItem.status !== TodoItemStatus.NeedsAction) {
              return false;
          }
          return true;
      }
      
      function ListCleaner(Eintrag='') {
          const arr = Eintrag.split(' ');
          for (let i = 0; i < arr.length; i++) {
              arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
          }
          return arr.join(' ');
      }
      
      /**
       * sync lists
       * @param {Array<alexaItem>} alexaList
       * @param {Array<bringItem>} list
       * @param {number} timestampBring
       * @param {string} msource
       * @param {Array<bringItem>} recentList
       * @returns {Array<bringItem>} new bring List
       */
      function syncLists(alexaList, list, timestampBring, msource, recentList) {
          const newBringList = [];
          var empty = true;
          for (const alexaItem of alexaList) {
      
              for (const bringItem of list) {
                  empty = false;
      
                  if (bringItem.name === alexaItem.value) {
                      alexaItem.found = true;
                      bringItem.found = true;
      
      
                      //found item. Update completed state from 'newer' list: 
                      bringItem.status = TodoItemStatus.NeedsAction;
                      if (alexaItem.updatedDateTime > timestampBring) {
                          if (alexaItem.value !== bringItem.name || !compareCompleted(alexaItem, bringItem)) {
      
                              if (msource === 'Alexa') {
                                 debug('Updating Bring item: ' + bringItem.name + ' from Alexa');
                                 setState(bringCompleteItem, ListCleaner(bringItem.name));
                              }                   
                          }
                      
                      } else {
                          //keep bring:
      
                          //update alexa:
                          if (!compareCompleted(alexaItem, bringItem)) {
                              if (msource === 'Bring') {
                                  bringItem.status = TodoItemStatus.Completed;
                                  debug('Update  Alexa item: ' + alexaItem.value + ' to ' + (bringItem.status === TodoItemStatus.Completed ? 'done' : 'undone') + ' from Bring.');
                                  setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItem.status === TodoItemStatus.Completed);
                              } 
                          }
                      }
                  }
              }
      
              for (const bringItemCompleted of recentList) {
                  if (bringItemCompleted.name === alexaItem.value) {
                      alexaItem.found = true;
                      bringItemCompleted.found = true;
      
                      //found item. Update completed state from 'newer' list: 
                      bringItemCompleted.status = TodoItemStatus.Completed;
                      if (alexaItem.updatedDateTime > timestampBring) {
                          if (alexaItem.value !== bringItemCompleted.name || !compareCompleted(alexaItem, bringItemCompleted)) {
      
                              if (msource === 'Alexa') {
                                 debug('Adding Bring item: ' + bringItemCompleted.name + ' from Alexa');
                                 setState(bringAddToList, ListCleaner(bringItemCompleted.name));
                              }                   
                          }
                      
                      } else {
                          //keep bring:
      
                          //update alexa:
                          if (!compareCompleted(alexaItem, bringItemCompleted)) {
                              bringItemCompleted.status = TodoItemStatus.Completed;
                              if (msource === 'Bring') {
                                  debug('Delete  Alexa item: ' + alexaItem.value + ' from Bring.');
                                  //setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItemCompleted.status === TodoItemStatus.Completed);
                                  setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                              } 
                          }
                      }
                  }
              }
      
      
              if (!alexaItem.found) {
                  //alexa item not found:
                  if (alexaItem.completed) {
                      debug('Delete ' + alexaItem.value + ' because done and not in Bring list.');
                      setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                  } else {
                      if (msource === 'Alexa') {
                          debug('Adding ' + alexaItem.value + ' to Bring list');
                          setState(bringAddToList, ListCleaner(alexaItem.value));
                      }
                  }
              }
      
              if (empty === true) {
                  if (alexaItem.updatedDateTime < timestampBring) {
                      debug('Delete ' + alexaItem.value + ' from Alexa list because Bring list is all done.');
                      setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                  }
              }
          
          }
      
          for (const bringItem of list) {
              if (!bringItem.found) {
                  if (bringItem.status === TodoItemStatus.Completed) {
                      //debug('Remove from bring item:  ' + bringItem.name + ' because done and not on alexa list');
                      //Not executed since I want to keep the recent items inside bring app
                  } else {
                      if (msource === 'Bring') {
                          debug('Adding ' + bringItem.name + ' to Alexa list.');
                          setState(alexaAddToList, ListCleaner(bringItem.name));
                      }
                  }
              }
          }
      
          return newBringList;
      }
      
      
      function doSync(source) {
          eliminateDuplicated();
          const alexaList = JSON.parse(getState(alexaListId).val);
          const state = getState(bringListId);
          const bringList = JSON.parse(state.val);
          const state2 = getState(bringListCompletedId);
          const bringListCompleted = JSON.parse(state2.val);
      
          syncLists(alexaList, bringList, state.ts, source, bringListCompleted);
      }
      
      function eliminateDuplicated() {
          var myAlexaList = JSON.parse(getState(alexaListId).val);
          var arrayWithDuplicates = [];
      
          for(var alexaItem of myAlexaList) {
              var obj = {};
              obj["value"] = ListCleaner(alexaItem.value);
              obj["id"] = alexaItem.id;
              arrayWithDuplicates.push(obj);       
          }
      
          const lookup = arrayWithDuplicates.reduce((a, e) => {
          a[e.value] = ++a[e.value] || 0;
          return a;
          }, {});
      
          const
              getKey = o => keys.map(k => o[k]).join('|'),
              keys = ['value'],
              myarray = arrayWithDuplicates.filter(e => lookup[e.value]),
              hash = Object.create(null),
              duplicates = myarray.filter(o =>
                  (k => (hash[k] = (hash[k] || 0) + 1) > 1)
                  (getKey(o))
              );
      
          for(var item of duplicates) {
              debug('Delete  Alexa item: ' + item.value + ' because duplicated.');
              setState(`${alexa2BaseId}.items.${item.id}.#delete`, true);
          }
      }
      
      on({id: bringListId, change: 'any'}, e => {
          debug('Update triggered from Bring');
          doSync('Bring');
      });
      
      on({id: alexaListId, change: 'any'}, e => {
          debug('Update triggered from Alexa');
          doSync('Alexa');
      });
      
      doSync();
      
      
      K Offline
      K Offline
      kai.bauder
      wrote on last edited by
      #47

      @icastillo15 Herzlichen Danke für deine Arbeit!

      1 Reply Last reply
      0
      • DickenD Offline
        DickenD Offline
        Dicken
        wrote on last edited by
        #48

        @icastillo15 Danke für deine Arbeit :)

        Doofe Frage: Hab bisher immer AnyList oder ToDoist benutzt, gibt es bei Bring! nicht die Möglichkeit die Einzelnen Artikel zu sortieren? Also kann man nur die Kategorien sortieren?

        icastillo15I 1 Reply Last reply
        0
        • DickenD Dicken

          @icastillo15 Danke für deine Arbeit :)

          Doofe Frage: Hab bisher immer AnyList oder ToDoist benutzt, gibt es bei Bring! nicht die Möglichkeit die Einzelnen Artikel zu sortieren? Also kann man nur die Kategorien sortieren?

          icastillo15I Offline
          icastillo15I Offline
          icastillo15
          wrote on last edited by
          #49

          @dicken

          Genau - nach meinem Stand kannst du nur die Kategorien tauschen. Mir reicht das mit der Kachelansicht dann aber völlig als Übersicht. Aber meistens habe ich auch nur kleinere Listen und keine Rieseneinkäufe - wenn nicht gerade Weihnachten ist. Das ist dann wohl sehr individuell 😀

          DickenD 1 Reply Last reply
          0
          • icastillo15I icastillo15

            @dicken

            Genau - nach meinem Stand kannst du nur die Kategorien tauschen. Mir reicht das mit der Kachelansicht dann aber völlig als Übersicht. Aber meistens habe ich auch nur kleinere Listen und keine Rieseneinkäufe - wenn nicht gerade Weihnachten ist. Das ist dann wohl sehr individuell 😀

            DickenD Offline
            DickenD Offline
            Dicken
            wrote on last edited by
            #50

            @icastillo15 schade, na vllt ergibt sich ja noch eine Lösung mit todoist. In den Augen meiner Frau bin natürlich erstmal ich schuld wenn irgendwas nicht mehr so geht wie vorher :D Aber ich geb die Hoffnung nicht aus und versuch mich vllt mal selber an einem Script :)

            1 Reply Last reply
            0
            • daniel.driessenD Offline
              daniel.driessenD Offline
              daniel.driessen
              wrote on last edited by daniel.driessen
              #51

              Hallo zusammen,

              da mich die Änderung seitens Amazon auch nervt habe ich auch mal auf die schnelle ein kleines TypeScript zusammengebastelt.
              Es ist mit Sicherheit noch nicht perfekt, aber ein Anfang. Da ich es gerade erst fertig gestellt habe, hatte ich auch noch nicht die Möglichkeit und Zeit es ausgiebig zu testen.
              Gerne stelle ich es aber hier allen Interessierten zur Verfügung.

              Zusätzliche Info:
              Der Code-Dokumentationsblock am Anfang des Scripts gibt eine genauere Beschreibung des Scripts.
              Nachdem Ihr den Inhalt der Textdatei in ein neues TypeScript kopiert habt, sollte es denke ich reichen die 5 Werte im Code-Block "SCRIPT SETUP" anzupassen.
              JavaScript und TypeScript sind recht neu für mich und mit Sicherheit habe ich auch ungewollt das eine oder andere potentielle Problem ins Script eingebaut.
              Ihr dürft mir natürlich gerne feedback geben.

              P.S. Ich habe gerade erst gesehen das @icastillo15 ebenfalls etwas gebastelt hat. Hätte ich mal erst hier gelesen, dann hätte ich mir meine Arbeit vielleicht sparen können.
              :laughing: Ich werde sein Script auf jeden Fall in den nächsten Tagen ebenfalls mal testen.
              Vielleicht kann ich ja was lernen.

              Grüße

              Daniel

              Script-File:
              Shopping-List Sync.txt

              Maetzi87M E 2 Replies Last reply
              0
              • mricegM Offline
                mricegM Offline
                mriceg
                wrote on last edited by
                #52

                Moin. Weiß hier jemand, ob ein Adapter für Anylist oder Todoist in Arbeit ist?

                Ich finde es zwar super, dass hier eine Lösung für den Sync zwischen Alexa und Bring erstellt wurde, aber leider gibt es für Bring kein Android-Widget, was für mich (bzw. meine Frau) ein großes Problem ist.

                DickenD 1 Reply Last reply
                0
                • mricegM mriceg

                  Moin. Weiß hier jemand, ob ein Adapter für Anylist oder Todoist in Arbeit ist?

                  Ich finde es zwar super, dass hier eine Lösung für den Sync zwischen Alexa und Bring erstellt wurde, aber leider gibt es für Bring kein Android-Widget, was für mich (bzw. meine Frau) ein großes Problem ist.

                  DickenD Offline
                  DickenD Offline
                  Dicken
                  wrote on last edited by
                  #53

                  @mriceg siehe hier ;)

                  mricegM 1 Reply Last reply
                  0
                  • DickenD Dicken

                    @mriceg siehe hier ;)

                    mricegM Offline
                    mricegM Offline
                    mriceg
                    wrote on last edited by
                    #54

                    @dicken Danke, aber damit wird m.E. nicht die Todoist oder Anylist-Liste synchronisiert. Alle anderen Lösungen haben Nachteile, die wir möglichst vermeiden möchten. Das Widget der Alexa-Shoppinglist aktualisiert sich z.B. viel zu langsam und manchmal einige Stunden gar nicht. Die Bring-App hat kein Widget.

                    Ro75R DickenD 2 Replies Last reply
                    0
                    • mricegM mriceg

                      @dicken Danke, aber damit wird m.E. nicht die Todoist oder Anylist-Liste synchronisiert. Alle anderen Lösungen haben Nachteile, die wir möglichst vermeiden möchten. Das Widget der Alexa-Shoppinglist aktualisiert sich z.B. viel zu langsam und manchmal einige Stunden gar nicht. Die Bring-App hat kein Widget.

                      Ro75R Offline
                      Ro75R Offline
                      Ro75
                      wrote on last edited by
                      #55

                      @mriceg sagte in Alexa Shopping List mit Bring synchronisieren:

                      Alexa-Shoppinglist aktualisiert sich z.B. viel zu langsam

                      welches meinst du?

                      Ro75.

                      SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

                      mricegM 1 Reply Last reply
                      0
                      • mricegM mriceg

                        @dicken Danke, aber damit wird m.E. nicht die Todoist oder Anylist-Liste synchronisiert. Alle anderen Lösungen haben Nachteile, die wir möglichst vermeiden möchten. Das Widget der Alexa-Shoppinglist aktualisiert sich z.B. viel zu langsam und manchmal einige Stunden gar nicht. Die Bring-App hat kein Widget.

                        DickenD Offline
                        DickenD Offline
                        Dicken
                        wrote on last edited by
                        #56

                        @mriceg naja übergangsweise läuft es bei mir eigentlich ganz gut. Ist halt eine Notlösung bis es was besseres gibt :)

                        1 Reply Last reply
                        0
                        • Ro75R Ro75

                          @mriceg sagte in Alexa Shopping List mit Bring synchronisieren:

                          Alexa-Shoppinglist aktualisiert sich z.B. viel zu langsam

                          welches meinst du?

                          Ro75.

                          mricegM Offline
                          mricegM Offline
                          mriceg
                          wrote on last edited by
                          #57

                          @ro75 said in Alexa Shopping List mit Bring synchronisieren:

                          welches meinst du?

                          Das Widget von der Alexa-App

                          Ro75R 1 Reply Last reply
                          0
                          • mricegM mriceg

                            @ro75 said in Alexa Shopping List mit Bring synchronisieren:

                            welches meinst du?

                            Das Widget von der Alexa-App

                            Ro75R Offline
                            Ro75R Offline
                            Ro75
                            wrote on last edited by
                            #58

                            @mriceg mh, die Android - App reagiert bei mir sofort und auch im iobroker. Oder was meinst du?

                            Ro75.

                            SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

                            mricegM 1 Reply Last reply
                            0
                            • Ro75R Ro75

                              @mriceg mh, die Android - App reagiert bei mir sofort und auch im iobroker. Oder was meinst du?

                              Ro75.

                              mricegM Offline
                              mricegM Offline
                              mriceg
                              wrote on last edited by
                              #59

                              @ro75 Ich meine die Alexa-App. Was ist denn bei dieser Lösung mit oneWay gemeint?

                              1 Reply Last reply
                              0
                              • DickenD Offline
                                DickenD Offline
                                Dicken
                                wrote on last edited by
                                #60

                                @mriceg Die Eintragungen werden automatisch auf die Todoist App gesetzt. Aber wenn du sie dort als erledigt markierst, bleiben sie halt in der alexa einkaufsliste. Was mir aber relativ egal is, guck ich ja eh nicht drauf.

                                mricegM Marc BeckmannM 2 Replies Last reply
                                1
                                • DickenD Dicken

                                  @mriceg Die Eintragungen werden automatisch auf die Todoist App gesetzt. Aber wenn du sie dort als erledigt markierst, bleiben sie halt in der alexa einkaufsliste. Was mir aber relativ egal is, guck ich ja eh nicht drauf.

                                  mricegM Offline
                                  mricegM Offline
                                  mriceg
                                  wrote on last edited by
                                  #61

                                  @dicken Ok. Das stimmt, in der Alexa-App ist es dann ja egal. Hauptsache, sie werden nicht immer wieder neu hinzugefügt. Ich werde das mal ausprobieren. Vielen Dank.

                                  mricegM 1 Reply Last reply
                                  0
                                  • Ro75R Offline
                                    Ro75R Offline
                                    Ro75
                                    wrote on last edited by
                                    #62

                                    @mriceg sagte in Alexa Shopping List mit Bring synchronisieren:

                                    oneWay

                                    Keine Ahnung.

                                    Ro75.

                                    SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

                                    1 Reply Last reply
                                    0
                                    • mricegM mriceg

                                      @dicken Ok. Das stimmt, in der Alexa-App ist es dann ja egal. Hauptsache, sie werden nicht immer wieder neu hinzugefügt. Ich werde das mal ausprobieren. Vielen Dank.

                                      mricegM Offline
                                      mricegM Offline
                                      mriceg
                                      wrote on last edited by mriceg
                                      #63

                                      @Dicken Bei dem json muss vermutlich in Zeile 26 der API-Token von todoist hinterlegt werden, oder? Was muss sonst noch angepasst werden?

                                      Kann man da nicht einbauen, dass der Eintrag auf der Alexa-Liste gelöscht wird, sobald er nach todoist übertragen wurde?

                                      Edit:
                                      OK, habe alles hinbekommen. Der API-Token muss in Zeile 27 hinter Bearer. In Zeile 20 muss noch die Projekt-ID eingetragen werden.

                                      M 1 Reply Last reply
                                      0
                                      • DickenD Offline
                                        DickenD Offline
                                        Dicken
                                        wrote on last edited by
                                        #64

                                        @mriceg ok super.

                                        Ich hab Keine Ahnung, das geht bestimmt irgendwie, aber das script ist nicht von mir. Ich nutz es ja auch nur :)

                                        1 Reply Last reply
                                        0
                                        • icastillo15I icastillo15

                                          Hallo zusammen,

                                          ich habe mein Script nochmal aktualisiert. Es werden in Alexa nun automatisch alle Duplikate sofort wieder gelöscht. Außerdem wird nun erzwungen, dass Artikel mit einem Großbuchstaben beginnen.

                                          Viel Spaß damit und gerne wieder testen :-)

                                          Kleiner Nachtrag: wenn ich über Alexa Dinge hinzufüge und dann in Bring als erledigt markiere, dann werden diese bei mir in Alexa nicht mehr gelöscht. Das muss ich mir nochmal ansehen - könnte an den Zeitstempeln liegen.

                                          Nachtrag 2: ging doch - mein Adapter war nur offline 😎

                                          const bringBaseId = 'bring.0.0f0c420c-3298-4911-91f5-7ed0fbbfd36e';
                                          const alexa2BaseId = 'alexa2.0.Lists.SHOPPING_LIST';
                                          
                                          const bringListId = bringBaseId + '.content';
                                          const bringListCompletedId = bringBaseId + '.recentContent';
                                          const bringAddToList = bringBaseId + '.saveItem';
                                          const bringCompleteItem = bringBaseId + '.moveToRecentContent';
                                          const alexaAddToList = alexa2BaseId + '.#New';
                                          const alexaListId = alexa2BaseId + '.json';
                                          
                                          //switch off to silence:
                                          const printDebug = true;
                                          
                                          function debug(msg) {
                                              if (printDebug) {
                                                  log(msg)
                                              }
                                          }
                                          
                                          const TodoItemStatus = {
                                              NeedsAction: 'needs_action',
                                              Completed: 'completed',
                                          };
                                          
                                          /**
                                           * @typedef bringItem
                                           * @type {object}
                                           * @property {string} specification
                                           * @property {string} name
                                           * @property {string} status
                                           * @property {boolean} [found] - keep track if found or not.
                                           */
                                          
                                          /**
                                           * @typedef alexaItem
                                           * @type {object}
                                           * @property {string} value
                                           * @property {string} id
                                           * @property {boolean} completed
                                           * @property {number} updatedDateTime
                                           * @property {boolean} [found] - keep track if found or not.
                                           */
                                          
                                          /**
                                           * Compare alexaItem complete and bringItem status -> returns true if same status.
                                           * @param {Array<alexaItem>} alexaList
                                           * @param {Array<bringItem>} list
                                           * @returns {boolean} true if same status.
                                          */
                                          function compareCompleted(alexaItem, bringItem) {
                                              if (alexaItem.completed && bringItem.status !== TodoItemStatus.Completed) {
                                                  return false;
                                              }
                                              if (!alexaItem.completed && bringItem.status !== TodoItemStatus.NeedsAction) {
                                                  return false;
                                              }
                                              return true;
                                          }
                                          
                                          function ListCleaner(Eintrag='') {
                                              const arr = Eintrag.split(' ');
                                              for (let i = 0; i < arr.length; i++) {
                                                  arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
                                              }
                                              return arr.join(' ');
                                          }
                                          
                                          /**
                                           * sync lists
                                           * @param {Array<alexaItem>} alexaList
                                           * @param {Array<bringItem>} list
                                           * @param {number} timestampBring
                                           * @param {string} msource
                                           * @param {Array<bringItem>} recentList
                                           * @returns {Array<bringItem>} new bring List
                                           */
                                          function syncLists(alexaList, list, timestampBring, msource, recentList) {
                                              const newBringList = [];
                                              var empty = true;
                                              for (const alexaItem of alexaList) {
                                          
                                                  for (const bringItem of list) {
                                                      empty = false;
                                          
                                                      if (bringItem.name === alexaItem.value) {
                                                          alexaItem.found = true;
                                                          bringItem.found = true;
                                          
                                          
                                                          //found item. Update completed state from 'newer' list: 
                                                          bringItem.status = TodoItemStatus.NeedsAction;
                                                          if (alexaItem.updatedDateTime > timestampBring) {
                                                              if (alexaItem.value !== bringItem.name || !compareCompleted(alexaItem, bringItem)) {
                                          
                                                                  if (msource === 'Alexa') {
                                                                     debug('Updating Bring item: ' + bringItem.name + ' from Alexa');
                                                                     setState(bringCompleteItem, ListCleaner(bringItem.name));
                                                                  }                   
                                                              }
                                                          
                                                          } else {
                                                              //keep bring:
                                          
                                                              //update alexa:
                                                              if (!compareCompleted(alexaItem, bringItem)) {
                                                                  if (msource === 'Bring') {
                                                                      bringItem.status = TodoItemStatus.Completed;
                                                                      debug('Update  Alexa item: ' + alexaItem.value + ' to ' + (bringItem.status === TodoItemStatus.Completed ? 'done' : 'undone') + ' from Bring.');
                                                                      setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItem.status === TodoItemStatus.Completed);
                                                                  } 
                                                              }
                                                          }
                                                      }
                                                  }
                                          
                                                  for (const bringItemCompleted of recentList) {
                                                      if (bringItemCompleted.name === alexaItem.value) {
                                                          alexaItem.found = true;
                                                          bringItemCompleted.found = true;
                                          
                                                          //found item. Update completed state from 'newer' list: 
                                                          bringItemCompleted.status = TodoItemStatus.Completed;
                                                          if (alexaItem.updatedDateTime > timestampBring) {
                                                              if (alexaItem.value !== bringItemCompleted.name || !compareCompleted(alexaItem, bringItemCompleted)) {
                                          
                                                                  if (msource === 'Alexa') {
                                                                     debug('Adding Bring item: ' + bringItemCompleted.name + ' from Alexa');
                                                                     setState(bringAddToList, ListCleaner(bringItemCompleted.name));
                                                                  }                   
                                                              }
                                                          
                                                          } else {
                                                              //keep bring:
                                          
                                                              //update alexa:
                                                              if (!compareCompleted(alexaItem, bringItemCompleted)) {
                                                                  bringItemCompleted.status = TodoItemStatus.Completed;
                                                                  if (msource === 'Bring') {
                                                                      debug('Delete  Alexa item: ' + alexaItem.value + ' from Bring.');
                                                                      //setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItemCompleted.status === TodoItemStatus.Completed);
                                                                      setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                                                                  } 
                                                              }
                                                          }
                                                      }
                                                  }
                                          
                                          
                                                  if (!alexaItem.found) {
                                                      //alexa item not found:
                                                      if (alexaItem.completed) {
                                                          debug('Delete ' + alexaItem.value + ' because done and not in Bring list.');
                                                          setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                                                      } else {
                                                          if (msource === 'Alexa') {
                                                              debug('Adding ' + alexaItem.value + ' to Bring list');
                                                              setState(bringAddToList, ListCleaner(alexaItem.value));
                                                          }
                                                      }
                                                  }
                                          
                                                  if (empty === true) {
                                                      if (alexaItem.updatedDateTime < timestampBring) {
                                                          debug('Delete ' + alexaItem.value + ' from Alexa list because Bring list is all done.');
                                                          setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                                                      }
                                                  }
                                              
                                              }
                                          
                                              for (const bringItem of list) {
                                                  if (!bringItem.found) {
                                                      if (bringItem.status === TodoItemStatus.Completed) {
                                                          //debug('Remove from bring item:  ' + bringItem.name + ' because done and not on alexa list');
                                                          //Not executed since I want to keep the recent items inside bring app
                                                      } else {
                                                          if (msource === 'Bring') {
                                                              debug('Adding ' + bringItem.name + ' to Alexa list.');
                                                              setState(alexaAddToList, ListCleaner(bringItem.name));
                                                          }
                                                      }
                                                  }
                                              }
                                          
                                              return newBringList;
                                          }
                                          
                                          
                                          function doSync(source) {
                                              eliminateDuplicated();
                                              const alexaList = JSON.parse(getState(alexaListId).val);
                                              const state = getState(bringListId);
                                              const bringList = JSON.parse(state.val);
                                              const state2 = getState(bringListCompletedId);
                                              const bringListCompleted = JSON.parse(state2.val);
                                          
                                              syncLists(alexaList, bringList, state.ts, source, bringListCompleted);
                                          }
                                          
                                          function eliminateDuplicated() {
                                              var myAlexaList = JSON.parse(getState(alexaListId).val);
                                              var arrayWithDuplicates = [];
                                          
                                              for(var alexaItem of myAlexaList) {
                                                  var obj = {};
                                                  obj["value"] = ListCleaner(alexaItem.value);
                                                  obj["id"] = alexaItem.id;
                                                  arrayWithDuplicates.push(obj);       
                                              }
                                          
                                              const lookup = arrayWithDuplicates.reduce((a, e) => {
                                              a[e.value] = ++a[e.value] || 0;
                                              return a;
                                              }, {});
                                          
                                              const
                                                  getKey = o => keys.map(k => o[k]).join('|'),
                                                  keys = ['value'],
                                                  myarray = arrayWithDuplicates.filter(e => lookup[e.value]),
                                                  hash = Object.create(null),
                                                  duplicates = myarray.filter(o =>
                                                      (k => (hash[k] = (hash[k] || 0) + 1) > 1)
                                                      (getKey(o))
                                                  );
                                          
                                              for(var item of duplicates) {
                                                  debug('Delete  Alexa item: ' + item.value + ' because duplicated.');
                                                  setState(`${alexa2BaseId}.items.${item.id}.#delete`, true);
                                              }
                                          }
                                          
                                          on({id: bringListId, change: 'any'}, e => {
                                              debug('Update triggered from Bring');
                                              doSync('Bring');
                                          });
                                          
                                          on({id: alexaListId, change: 'any'}, e => {
                                              debug('Update triggered from Alexa');
                                              doSync('Alexa');
                                          });
                                          
                                          doSync();
                                          
                                          
                                          T Offline
                                          T Offline
                                          thorschtn
                                          wrote on last edited by
                                          #65

                                          @icastillo15 cooles Skript!

                                          Das Skript synchronisiert bei mir einwandfrei zwischen Alexa und Bring. Aber immer nur eine zeitlang - danach schreiben weder Alexa2 noch Bring Instanz das Skript zu triggern.

                                          Wenn ich die Instanzen oder den ioBroker neu starte, gehts wieder ne Weile, teilweise aber schon nach ner Stunde nicht mehr.

                                          Im Log steht nichts, die Instanzen werden alle grün angezeigt, hat jemand eine Idee, wo ich nach der Ursache suchen muss? Hat sonst noch jemand ähnliche Probleme?

                                          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

                                          586

                                          Online

                                          32.7k

                                          Users

                                          82.5k

                                          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