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

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

NEWS

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

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

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

Alexa Shopping List mit Bring synchronisieren

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
164 Beiträge 27 Kommentatoren 33.5k Aufrufe 29 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.
  • Ro75R Ro75

    @fuchsbau sowas

    ebfc2bc4-d102-4658-9c63-27d29d9df132-image.png

    Ro75.

    FuchsbauF Offline
    FuchsbauF Offline
    Fuchsbau
    schrieb am zuletzt editiert von
    #32

    @ro75 Anzeige im VIS, das wäre kein Problem. Ich denke jeher daran mit BRING zu synchronisieren oder in die HA Liste oder TODOIST. Ich muss mal schauen was mir gefällt.

    1 Antwort Letzte Antwort
    0
    • DickenD Offline
      DickenD Offline
      Dicken
      schrieb am zuletzt editiert von
      #33

      @fuchsbau sagte in Alexa Shopping List mit Bring synchronisieren:

      @ro75 Anzeige im VIS, das wäre kein Problem. Ich denke jeher daran mit BRING zu synchronisieren oder in die HA Liste oder TODOIST. Ich muss mal schauen was mir gefällt.

      Jau da überlege ich nächste Woche auch mal wie man das regeln kann.

      Ro75R 1 Antwort Letzte Antwort
      0
      • DickenD Dicken

        @fuchsbau sagte in Alexa Shopping List mit Bring synchronisieren:

        @ro75 Anzeige im VIS, das wäre kein Problem. Ich denke jeher daran mit BRING zu synchronisieren oder in die HA Liste oder TODOIST. Ich muss mal schauen was mir gefällt.

        Jau da überlege ich nächste Woche auch mal wie man das regeln kann.

        Ro75R Online
        Ro75R Online
        Ro75
        schrieb am zuletzt editiert von
        #34

        @dicken ich habe das Problem noch nicht erkannt.? Für unterwegs nutze ich die Alexa-App. Warum sollte ich da was nach Bring oder ToDoIst transferieren?

        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

        DickenD 1 Antwort Letzte Antwort
        0
        • Ro75R Ro75

          @dicken ich habe das Problem noch nicht erkannt.? Für unterwegs nutze ich die Alexa-App. Warum sollte ich da was nach Bring oder ToDoIst transferieren?

          Ro75.

          DickenD Offline
          DickenD Offline
          Dicken
          schrieb am zuletzt editiert von
          #35

          @ro75 Sortierung der Einträge im nachhinein, hatten wir doch oben schon ;) nur weil dir das egal ist wie die reihenfolge in der app ist, muss es ja nicht allen anderen auch egal sein :D

          1 Antwort Letzte Antwort
          0
          • I IOMax

            @mcbirne said in Alexa Shopping List mit Bring synchronisieren:

            Hallo zusammen,

            Hat schon jemand ein Skript zur Synchronisation der Alexa-Einkaufsliste und Bring geschrieben?

            Das würde mich auch interessieren. Am besten in beide Richtungen

            icastillo15I Offline
            icastillo15I Offline
            icastillo15
            schrieb am zuletzt editiert von
            #36

            @iomax @mcBirne

            Hallo zusammen,

            da mich das gleiche Problem betrifft, habe ich mich mal an einem Skript dafür versucht.
            Über den Alexa und Bring Adapter werden jeweils die Listen abgeglichen in beide Richtungen.
            Alles was jeweils in der anderen Liste hinzugefügt wird, wird gesynct. Wenn in der Bring App Dinge als erledigt markiert werden, dann lösche ich diese aus der Alexa Liste komplett raus. Wenn in Alexa Dinge als markiert gesetzt werden, dann wandern die Items in der Bring app unter "zuletetzt verwendet".

            Am wichtigsten war mir aber, dass ich wieder "Alexa füge Birnen auf die Einkaufsliste" sagen kann und die Sachen wieder bei Bring habe :D

            Im ersten Test lief das Skript bei mir ganz gut - gerne mal selbst testen.

            Einfach in Zeile 1 auf die passende bring Liste bei euch anpassen der rest kann so bleiben

            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;
            }
            
            /**
             * 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, 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, 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, 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, bringItem.name);
                            }
                        }
                    }
                }
            
                return newBringList;
            }
            
            
            function doSync(source) {
                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);
            }
            
            
            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();
            
            
            mcBirneM OreiderO FuchsbauF I 4 Antworten Letzte Antwort
            1
            • icastillo15I icastillo15

              @iomax @mcBirne

              Hallo zusammen,

              da mich das gleiche Problem betrifft, habe ich mich mal an einem Skript dafür versucht.
              Über den Alexa und Bring Adapter werden jeweils die Listen abgeglichen in beide Richtungen.
              Alles was jeweils in der anderen Liste hinzugefügt wird, wird gesynct. Wenn in der Bring App Dinge als erledigt markiert werden, dann lösche ich diese aus der Alexa Liste komplett raus. Wenn in Alexa Dinge als markiert gesetzt werden, dann wandern die Items in der Bring app unter "zuletetzt verwendet".

              Am wichtigsten war mir aber, dass ich wieder "Alexa füge Birnen auf die Einkaufsliste" sagen kann und die Sachen wieder bei Bring habe :D

              Im ersten Test lief das Skript bei mir ganz gut - gerne mal selbst testen.

              Einfach in Zeile 1 auf die passende bring Liste bei euch anpassen der rest kann so bleiben

              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;
              }
              
              /**
               * 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, 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, 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, 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, bringItem.name);
                              }
                          }
                      }
                  }
              
                  return newBringList;
              }
              
              
              function doSync(source) {
                  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);
              }
              
              
              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();
              
              
              mcBirneM Offline
              mcBirneM Offline
              mcBirne
              schrieb am zuletzt editiert von
              #37

              @icastillo15
              Vielen Dank für die Bereitstellung des Skripts. Bei den ersten Tests funktioniert es perfekt..

              1 Antwort Letzte Antwort
              0
              • icastillo15I icastillo15

                @iomax @mcBirne

                Hallo zusammen,

                da mich das gleiche Problem betrifft, habe ich mich mal an einem Skript dafür versucht.
                Über den Alexa und Bring Adapter werden jeweils die Listen abgeglichen in beide Richtungen.
                Alles was jeweils in der anderen Liste hinzugefügt wird, wird gesynct. Wenn in der Bring App Dinge als erledigt markiert werden, dann lösche ich diese aus der Alexa Liste komplett raus. Wenn in Alexa Dinge als markiert gesetzt werden, dann wandern die Items in der Bring app unter "zuletetzt verwendet".

                Am wichtigsten war mir aber, dass ich wieder "Alexa füge Birnen auf die Einkaufsliste" sagen kann und die Sachen wieder bei Bring habe :D

                Im ersten Test lief das Skript bei mir ganz gut - gerne mal selbst testen.

                Einfach in Zeile 1 auf die passende bring Liste bei euch anpassen der rest kann so bleiben

                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;
                }
                
                /**
                 * 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, 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, 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, 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, bringItem.name);
                                }
                            }
                        }
                    }
                
                    return newBringList;
                }
                
                
                function doSync(source) {
                    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);
                }
                
                
                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();
                
                
                OreiderO Offline
                OreiderO Offline
                Oreider
                schrieb am zuletzt editiert von
                #38

                @icastillo15

                Vielen Dank!

                Ich teste mit.
                Auf den ersten Blick schaut es super aus!

                1 Antwort Letzte Antwort
                0
                • icastillo15I icastillo15

                  @iomax @mcBirne

                  Hallo zusammen,

                  da mich das gleiche Problem betrifft, habe ich mich mal an einem Skript dafür versucht.
                  Über den Alexa und Bring Adapter werden jeweils die Listen abgeglichen in beide Richtungen.
                  Alles was jeweils in der anderen Liste hinzugefügt wird, wird gesynct. Wenn in der Bring App Dinge als erledigt markiert werden, dann lösche ich diese aus der Alexa Liste komplett raus. Wenn in Alexa Dinge als markiert gesetzt werden, dann wandern die Items in der Bring app unter "zuletetzt verwendet".

                  Am wichtigsten war mir aber, dass ich wieder "Alexa füge Birnen auf die Einkaufsliste" sagen kann und die Sachen wieder bei Bring habe :D

                  Im ersten Test lief das Skript bei mir ganz gut - gerne mal selbst testen.

                  Einfach in Zeile 1 auf die passende bring Liste bei euch anpassen der rest kann so bleiben

                  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;
                  }
                  
                  /**
                   * 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, 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, 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, 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, bringItem.name);
                                  }
                              }
                          }
                      }
                  
                      return newBringList;
                  }
                  
                  
                  function doSync(source) {
                      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);
                  }
                  
                  
                  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
                  schrieb am zuletzt editiert von
                  #39

                  @icastillo15

                  Hi icastillo15,

                  erstmal :+1: für deine tolle Arbeit,
                  Ich hab es eben getestet und bin recht erstaunt wie schnell es Sync.

                  Aber Alexa macht es uns nicht einfach.

                  Alle was ich per Sprache in die Alexa Liste eintrage wird klein geschrieben.
                  Alle was ich per Sprache in Bring eintrage wird Großgeschrieben.

                  Vorlagen Artikel in Bring sind Großgeschrieben und auch die automatische Zuordnung in die Bring Kategorien werden nur mit den Großgeschrieben Artikel erkannt.
                  Bei Alexa kann ich einen identischen Artikel mehrfach in die Liste eintragen. Bring überprüft und trägt den identischen Artikel nur einmal ein. Bring überprüft auch Groß u. Kleinschreibung und es wird der Artikel nur einmal eingetragen. Dadurch entsteht ein Problem, habe ich z.B.: 3-mal Zitronen in der Alexa Liste, so habe ich in der Bring Liste nur 1-mal Zitronen. Lösche ich Zitronen in Bring, wird nur 1-mal Zitronen in Alexa gelöscht. Ergo, da noch 2-mal Zitrone in der Alexa Liste stehen, steht nach kurzer Zeit 1-mal Zitronen wieder in der Bring Liste.

                  Bei identischem Artikel einmal Groß und einmal Kleingeschrieben passiert dasselbe.

                  Wäre es nicht sinnvoller nur in eine Richtung zu synchronisieren. Von der Alexa Liste in die Bring Liste (wenn man nur Bring beim Einkaufen nutz). Irgendwie so, dass alle neu eintragen Artikel in der Alexa Liste, mit Anfangsbuchstaben Großgeschriebene zu Bring synchronisiert werden. Und idealerweise dann direkt in der Alexa Liste gelöscht.

                  Gruß
                  Fuchsbau

                  icastillo15I 1 Antwort Letzte Antwort
                  0
                  • FuchsbauF Fuchsbau

                    @icastillo15

                    Hi icastillo15,

                    erstmal :+1: für deine tolle Arbeit,
                    Ich hab es eben getestet und bin recht erstaunt wie schnell es Sync.

                    Aber Alexa macht es uns nicht einfach.

                    Alle was ich per Sprache in die Alexa Liste eintrage wird klein geschrieben.
                    Alle was ich per Sprache in Bring eintrage wird Großgeschrieben.

                    Vorlagen Artikel in Bring sind Großgeschrieben und auch die automatische Zuordnung in die Bring Kategorien werden nur mit den Großgeschrieben Artikel erkannt.
                    Bei Alexa kann ich einen identischen Artikel mehrfach in die Liste eintragen. Bring überprüft und trägt den identischen Artikel nur einmal ein. Bring überprüft auch Groß u. Kleinschreibung und es wird der Artikel nur einmal eingetragen. Dadurch entsteht ein Problem, habe ich z.B.: 3-mal Zitronen in der Alexa Liste, so habe ich in der Bring Liste nur 1-mal Zitronen. Lösche ich Zitronen in Bring, wird nur 1-mal Zitronen in Alexa gelöscht. Ergo, da noch 2-mal Zitrone in der Alexa Liste stehen, steht nach kurzer Zeit 1-mal Zitronen wieder in der Bring Liste.

                    Bei identischem Artikel einmal Groß und einmal Kleingeschrieben passiert dasselbe.

                    Wäre es nicht sinnvoller nur in eine Richtung zu synchronisieren. Von der Alexa Liste in die Bring Liste (wenn man nur Bring beim Einkaufen nutz). Irgendwie so, dass alle neu eintragen Artikel in der Alexa Liste, mit Anfangsbuchstaben Großgeschriebene zu Bring synchronisiert werden. Und idealerweise dann direkt in der Alexa Liste gelöscht.

                    Gruß
                    Fuchsbau

                    icastillo15I Offline
                    icastillo15I Offline
                    icastillo15
                    schrieb am zuletzt editiert von
                    #40

                    @fuchsbau

                    Danke für die Rückmeldung und das Testen. Mir war das bisher egal, ob Artikel groß oder kleingeschrieben sind aber du hast natürlich Recht. Es schränkt leider etwas Funktionalität ein. Grundsätzlich brauch ich den Sync aber in beide Richtungen, da ich oder meine Freundin gerne auch mal von unterwegs direkt in Bring Sachen hinzufügen und nicht über Alexa. Das sollte dann synchronisiert bleiben.

                    Also du nutzt sowohl Alexa Spracheingabe als auch über die Bring App direkt eine Spracheingabe oder meinst du das über den Alexa Bring Skill? Andernfalls wusste ich noch nicht, dass man auch direkt in Bring eine Spracheingabe hat 😀

                    Als Erweiterung vom Script könnte ich mir vorstellen, dass ich vorher noch vor jedem Sync ein Cleanup einbaue. Der würde dann über alle Alexa Items rübergehen und die Groß-Kleinschreibung erzwingen. Dabei könnte man auch gleich dupletten entfernen. Dann sollte im anschließenden Sync alles reibungslos klappen.

                    Ich schau mir das heute nochmal an wenn ich Zeit finde 🙂 Ansonsten klasse, dass es bei den anderen soweit für ihre Zwecke funktioniert 👍🏻

                    I 1 Antwort Letzte Antwort
                    1
                    • icastillo15I icastillo15

                      @iomax @mcBirne

                      Hallo zusammen,

                      da mich das gleiche Problem betrifft, habe ich mich mal an einem Skript dafür versucht.
                      Über den Alexa und Bring Adapter werden jeweils die Listen abgeglichen in beide Richtungen.
                      Alles was jeweils in der anderen Liste hinzugefügt wird, wird gesynct. Wenn in der Bring App Dinge als erledigt markiert werden, dann lösche ich diese aus der Alexa Liste komplett raus. Wenn in Alexa Dinge als markiert gesetzt werden, dann wandern die Items in der Bring app unter "zuletetzt verwendet".

                      Am wichtigsten war mir aber, dass ich wieder "Alexa füge Birnen auf die Einkaufsliste" sagen kann und die Sachen wieder bei Bring habe :D

                      Im ersten Test lief das Skript bei mir ganz gut - gerne mal selbst testen.

                      Einfach in Zeile 1 auf die passende bring Liste bei euch anpassen der rest kann so bleiben

                      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;
                      }
                      
                      /**
                       * 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, 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, 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, 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, bringItem.name);
                                      }
                                  }
                              }
                          }
                      
                          return newBringList;
                      }
                      
                      
                      function doSync(source) {
                          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);
                      }
                      
                      
                      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();
                      
                      
                      I Offline
                      I Offline
                      IOMax
                      schrieb am zuletzt editiert von IOMax
                      #41

                      @icastillo15 Super, vielen Dank, das klappt schonmal sehr gut!

                      mcBirneM 1 Antwort Letzte Antwort
                      0
                      • icastillo15I icastillo15

                        @fuchsbau

                        Danke für die Rückmeldung und das Testen. Mir war das bisher egal, ob Artikel groß oder kleingeschrieben sind aber du hast natürlich Recht. Es schränkt leider etwas Funktionalität ein. Grundsätzlich brauch ich den Sync aber in beide Richtungen, da ich oder meine Freundin gerne auch mal von unterwegs direkt in Bring Sachen hinzufügen und nicht über Alexa. Das sollte dann synchronisiert bleiben.

                        Also du nutzt sowohl Alexa Spracheingabe als auch über die Bring App direkt eine Spracheingabe oder meinst du das über den Alexa Bring Skill? Andernfalls wusste ich noch nicht, dass man auch direkt in Bring eine Spracheingabe hat 😀

                        Als Erweiterung vom Script könnte ich mir vorstellen, dass ich vorher noch vor jedem Sync ein Cleanup einbaue. Der würde dann über alle Alexa Items rübergehen und die Groß-Kleinschreibung erzwingen. Dabei könnte man auch gleich dupletten entfernen. Dann sollte im anschließenden Sync alles reibungslos klappen.

                        Ich schau mir das heute nochmal an wenn ich Zeit finde 🙂 Ansonsten klasse, dass es bei den anderen soweit für ihre Zwecke funktioniert 👍🏻

                        I Offline
                        I Offline
                        IOMax
                        schrieb am zuletzt editiert von
                        #42

                        @icastillo15 said in Alexa Shopping List mit Bring synchronisieren:

                        Dabei könnte man auch gleich dupletten entfernen. Dann sollte im anschließenden Sync alles reibungslos klappen.

                        Das wäre top!

                        1 Antwort Letzte Antwort
                        0
                        • I IOMax

                          @icastillo15 Super, vielen Dank, das klappt schonmal sehr gut!

                          mcBirneM Offline
                          mcBirneM Offline
                          mcBirne
                          schrieb am zuletzt editiert von
                          #43

                          @iomax so wie ich das sehe reagiert es auf Updates der Listen

                          I 1 Antwort Letzte Antwort
                          0
                          • mcBirneM mcBirne

                            @iomax so wie ich das sehe reagiert es auf Updates der Listen

                            I Offline
                            I Offline
                            IOMax
                            schrieb am zuletzt editiert von
                            #44

                            @mcbirne said in Alexa Shopping List mit Bring synchronisieren:

                            @iomax so wie ich das sehe reagiert es auf Updates der Listen

                            stimmt, habe ich auch gerade gesehen ;)

                            1 Antwort Letzte Antwort
                            0
                            • icastillo15I Offline
                              icastillo15I Offline
                              icastillo15
                              schrieb am zuletzt editiert von icastillo15
                              #45

                              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 K T Christoph1337C 4 Antworten Letzte Antwort
                              8
                              • 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
                                schrieb am zuletzt editiert von
                                #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 Antwort Letzte Antwort
                                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
                                  schrieb am zuletzt editiert von
                                  #47

                                  @icastillo15 Herzlichen Danke für deine Arbeit!

                                  1 Antwort Letzte Antwort
                                  0
                                  • DickenD Offline
                                    DickenD Offline
                                    Dicken
                                    schrieb am zuletzt editiert von
                                    #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 Antwort Letzte Antwort
                                    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
                                      schrieb am zuletzt editiert von
                                      #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 Antwort Letzte Antwort
                                      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
                                        schrieb am zuletzt editiert von
                                        #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 Antwort Letzte Antwort
                                        0
                                        • daniel.driessenD Offline
                                          daniel.driessenD Offline
                                          daniel.driessen
                                          schrieb am zuletzt editiert von 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 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

                                          815

                                          Online

                                          32.4k

                                          Benutzer

                                          81.4k

                                          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