Dubletten aus Alexa Einkaufsliste entfernen

Begonnen von thorschtn, 15 März 2019, 15:35:10

Vorheriges Thema - Nächstes Thema

thorschtn

Ich nutze seit einer ganzen Weile die Amazon Alexa Einkaufsliste, synchronisiert mit Any.do und auch angezeigt in FHEM/Smartvisu.

Jetzt liegt die Liste dank Michael Winklers echodevice-Modul standardmäßig komma-separiert in einem Reading des echodevice vor und kann so auch angezeigt werden.

Da die ganze Familie die Liste aktiv nutzt, entstehen natürlich regelmäßig Duplikate auf dem Einkaufszettel. Das gleiche gilt, wenn die Kinder wiederholt Spezialitäten auf die Liste setzen und die Eltern nach zwei Tagen immer noch kein Lammfilet oder Eiskonfekt eingekauft haben.

Diese Duplikate wollte ich - wenn ich die Liste eh schon in FHEM habe, löschen. Und zwar sowohl in der angezeigten Liste, als auch in Amazon/Any.do, damit ich auch mobil im Laden keine Duplikate mehr auf der Liste (bzw. da dann in der Any.do-App) habe.

Dazu habe ich mir eine kleine Routine gebastelt, die
- Duplikate entfernt (in FHEM),
- Duplikate entfernt (bei Amazon),
- die im Reading vorliegende Kleinschreibung korrigiert,
- ein Leerzeichen nach dem Komma einfügt und
- das ganze für die Ausgabe in einem neuen Userreading ablegt.

Aus
setstate echodevice 2019-03-15 14:56:35 list_SHOPPING_ITEM
eiskonfekt,eiskonfekt,tomate,gurke,katzenstreu,meersalzbutter,kleine_apfelschorlen,eiskonfekt,ameisenfallen

wird damit
setstate echodevice 2019-03-15 14:57:23 list_mySHOPPING_ITEM
Tomate, Gurke, Katzenstreu, Meersalzbutter, Kleine_apfelschorlen, Eiskonfekt, Ameisenfallen


Hier der Code, falls jemand Interesse hat:


################################################################
###                        Alexa Einkaufsliste               ###
### Duplikate raus, Duplikate in Amazon löschen, Leerzeichen ###
### ergänzen, Großbuchstaben am Anfang, neues UserReading    ###
################################################################
sub splitShoppingList(){
my $echodevice = "echodevice";
my @Liste = split(',', ReadingsVal($echodevice,"list_SHOPPING_ITEM",undef));
my %uniqe=();
# für jeden Eintrag
for my $i (reverse (0..$#Liste))
{
  # einen String generieren, der "eindeutig" ist
my $line=$Liste[$i];
  # entferne die Zeile wenn sie schon einmal gefunden wurde
  if($uniqe{$line}){
# lösche Eintrag in Array
splice(@Liste, $i,1);
# lösche Eintrag auf Amazon
fhem("set $echodevice item_shopping_delete $line");
} else {
# Anfangsbuchstabe gross
$Liste[$i] = ucfirst($Liste[$i]);
}
  # setze diese Zeile als gefunden;
  $uniqe{$line}++;
}
# neues Reading schreiben und Komma durch Komma Leerzeichen ersetzen
my $Liste_neu = join(", ", @Liste);
fhem("setreading $echodevice list_mySHOPPING_ITEM $Liste_neu");
}

NUC - FHEM & HA
MapleCUN, Homematic, 433MHz, AB440, 1-Wire Bewässerung & Pool, Jarolift (Signalduino), Signal Messenger, Denon AVR, LG WebOS, AmazonEcho, Jura S90 (ESP8266), Sonoff, Xiaomi Mii Sauger, Worx SO500i

KernSani

Interessante Idee, werde ich mal ûbernehmen (und noch eine Regex einbauen, die".*Lego.*" entfernt ;-)


Kurz, weil mobil
RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

TomLee

#2
Hi,

Danke für deine Routine.

Hier meine Lösung alle Werte der Einkaufsliste untereinander (Einkaufsliste halt) in ein Text-File zu schreiben und nach dem ausdrucken die Liste zu löschen, vielleicht kannst ja du oder andere mal was mit anfangen.

defmod du_Echo_Einkaufsliste dummy
attr du_Echo_Einkaufsliste alexaName Einkaufsliste
attr du_Echo_Einkaufsliste genericDeviceType switch
attr du_Echo_Einkaufsliste room Alexacontrol,Echo
attr du_Echo_Einkaufsliste setList on off


defmod doif_Echo_Einkaufsliste DOIF ([du_Echo_Einkaufsliste] eq "on")(\
{system("lpr -P HL2035 -o media=Custom.95x138mm /tmp/einkaufsliste.txt")},\
setstate du_Echo_Einkaufsliste off,\
{my @array = split(",",ReadingsVal("Echo","list_SHOPPING_ITEM",""));;\
foreach my $sk (@array)\
{fhem ("set Echo item_shopping_delete $sk")}})\


defmod not_Echo_Einkaufsliste notify Echo:list_SHOPPING_ITEM:.* { eval ( FileWrite({FileName=>"/tmp/einkaufsliste.txt", ForceType=>"file", NoNL => 0 }, split (/\,/,$EVTPART1)) )}
attr not_Echo_Einkaufsliste room Echo


Gruß

Thomas

thorschtn

#3
Ausdrucken tun wir eher nicht, da bei uns immer der gerade einkauft, der spontan Zeit hat. Daher ist die Synchronisation mit der Any.do App für uns ideal.

Allerdings bringt ich Deine Liste auf ne ganz andere Idee. Wir machen Großeinkäufe in der Regel in nicht mehr als 5 Geschäften, immer je nachdem, wo wir gerade sind, aber immer nahezu alles in einem Laden. Jetzt stehen die Artikel in der Amazon-Liste wahllos untereinander. Inzwischen ohne Duplikate, aber trotzdem durcheinander.

Jetzt könnte ich mir doch eigentlich über die Geokoordinaten den Laden ermitteln, in dem ich gerade einkaufe und dann unmittelbar beim betreten des Ladens die Einkaufsliste passend nach der Reihenfolge der Warengruppen in dem jeweiligen Laden sortieren....

Edit: Die Sortierfunktion werde ich wohl eher nicht implementieren. Das kann Any.do nämlich schon von Haus aus (und da ich die sortierte Liste eh erst im Laden brauche, spare ich mir den Aufwand, das in FHEM zu machen).
NUC - FHEM & HA
MapleCUN, Homematic, 433MHz, AB440, 1-Wire Bewässerung & Pool, Jarolift (Signalduino), Signal Messenger, Denon AVR, LG WebOS, AmazonEcho, Jura S90 (ESP8266), Sonoff, Xiaomi Mii Sauger, Worx SO500i

thorschtn

So, nachdem das Löschen von Dubletten auf der Alexa Einkaufsliste mittels FHEM ja so schön funktioniert, habe ich jetzt auch mal das Entfernen von Einträgen dazu gebastelt.

Da das Löschen einzelner Einträge per Sprachebefehl nativ über Alexa immer noch nicht möglich ist, ich aber auch nicht Bring o.ä. nutzen möchte, weil ich dazu dann im Sprachbefehl jedes mal explizit die App nennen müsste, lasse ich FHEM jetzt einen Eintrag löschen (ich brauche die Funktion ja lediglich gelegentlich, wenn ich etwas versehentlich auf die Liste gesetzt habe, unterwegs nutze ich die Any.do-App).

Alexa - setze Tomaten auf die Einkausliste. --- Alexa setze keine Tomaten auf die Einkaufsliste.

"Keine Tomaten" löscht dann den Eintrag "Tomaten" (und sich selbst). Nicht schön, aber läuft. Elegantere Ideen nehme ich gerne entgegen. ;-)


################################################################
### Alexa Einkaufsliste ###
### Duplikate raus, Duplikate in Amazon löschen, Leerzeichen ###
### ergänzen, Großbuchstaben am Anfang, neues UserReading ###
### Artikel mittels "setze kein(e) .... auf die ###
### Einkaufsliste" löschen ###
################################################################

sub splitShoppingList(){
my $echodevice = "echodevice";
my @Liste = split(',', ReadingsVal($echodevice,"list_SHOPPING_ITEM",undef));
my %uniqe=();
my $DeleteItem="";
# für jeden Eintrag
for my $i (reverse (0..$#Liste))
{
# einen String generieren, der "eindeutig" ist
my $line=$Liste[$i];
# entferne die Zeile wenn sie schon einmal gefunden wurde
if($uniqe{$line}){
# lösche Eintrag in Array
splice(@Liste, $i,1);
# lösche Eintrag auf Amazon
fhem("set $echodevice item_shopping_delete $line");
} else {
# Prüfen ob Löschauftrag
($a,$b)=split(/_/,$Liste[$i]); # Problem: Teilt bei jedem "_" und nicht nur beim ersten
#Log 1,"[AmazonEinkaufsliste] Liste: $Liste[$i] - A: $a - B: $b";
if (ucfirst($a) eq "Kein" or ucfirst($a) eq "Keine" or ucfirst($a) eq "Keinen"){
# lösche Eintrag "Kein ..." in Array
splice(@Liste, $i,1);
# lösche Eintrag "Kein xyz" auf Amazon
fhem("set $echodevice item_shopping_delete $line");
# lösche Eintrag "xyz" auf Amazon
fhem("set $echodevice item_shopping_delete $b");
$b = ucfirst($b);
fhem("set $echodevice item_shopping_delete $b");
# Log 1,"[AmazonEinkaufsliste] Loeschen! $line --- $b";
} else {
# Anfangsbuchstabe gross für Smartvisu
$Liste[$i] = ucfirst($Liste[$i]);
# Log 1,"[AmazonEinkaufsliste] Listitem: $Liste[$i]";
}
}
# setze diese Zeile als gefunden;
$uniqe{$line}++;
}
# neues Reading schreiben und Komma durch Komma Leerzeichen ersetzen
my $Liste_neu = join(", ", @Liste);
fhem("setreading $echodevice list_mySHOPPING_ITEM $Liste_neu");
}
NUC - FHEM & HA
MapleCUN, Homematic, 433MHz, AB440, 1-Wire Bewässerung & Pool, Jarolift (Signalduino), Signal Messenger, Denon AVR, LG WebOS, AmazonEcho, Jura S90 (ESP8266), Sonoff, Xiaomi Mii Sauger, Worx SO500i