Und schon wieder Müllabfuhr-Visualisierung

Begonnen von Vize, 27 Juli 2015, 18:24:33

Vorheriges Thema - Nächstes Thema

Vize

Hallo zusammen,

möchte an dieser Stelle kurz meine (zusammengeklaute ::)) Darstellung für die Müllabfuhr zeigen.

Ziel: Da bei uns immer am gleichen Wochentag der Müll abgeholt wird und nur die Fraktion wechselt (graue Tonne, blaue Tonne, grüne Tonne und gelbe Säcke), reicht mir eine einfache Darstellung mit farbigen Icons für die nächste(n) Tonne(n), die abgeholt werden. Tonnen, die nicht beim nächsten Termin dran sind, sollen nicht angezeigt werden.

Hab es dann folgendermaßen umgesetzt:

1.
Kalenderdatei (ics) mit Calendar eingefügt.
define muellkalender Calendar ical file ./www/muellkalender.ics 86400

2a.
Um die kommenden Termine des Kalenders auszuwerten, erstmal ein notify angelegt:
define no_muelltermine notify muellkalender:modeUpcoming.* { muelltermine("$EVENT") }

2b.
Dummy anlegen, um die Werte vom nachfolgenden Schritt 2c aufzunehmen:
define du_muelltermine dummy

2c.
Folgendes in die 99_myUtils.pm packen:
sub
muelltermine ($)
{
my ($Ereignis) = @_;
my @Ereignisarray = split(/.*:\s/,$Ereignis);
my $Ereignisteil1 = $Ereignisarray[1];
my @uids=split(/;/,$Ereignisteil1);
my $t = time;
my $dtPapier = '';
my $dtGelberSack = '';
my $dtRestmuell = '';
my $dtBiomuell = '';

foreach my $uid (@uids) {
   my $Kalendertext = fhem("get muellkalender summary $uid");
   if ($Kalendertext =~ /Papiertonne/)
   {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtPapier eq '' || ($eventDate < $dtPapier && $eventDate > $t))
      {
         $dtPapier = $eventDate;

         my $dayDiff = floor(($dtPapier - $t) / 60 / 60 / 24 + 1);
         if ($dayDiff >= 0) { fhem("setreading du_muelltermine Papiertonne $dayDiff"); }
      }
   };
   if ($Kalendertext =~ /Gelber Sack/) {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtGelberSack eq '' || ($eventDate < $dtGelberSack && $eventDate > $t))
      {
         $dtGelberSack = $eventDate;

         my $dayDiff = floor(($dtGelberSack - $t) / 60 / 60 / 24 + 1);
         if ($dayDiff >= 0) { fhem("setreading du_muelltermine GelberSack $dayDiff"); }
      }
   };
   if ($Kalendertext =~ /Restabfall/) {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtRestmuell eq '' || ($eventDate < $dtRestmuell && $eventDate > $t))
      {
          $dtRestmuell = $eventDate;

          my $dayDiff = floor(($dtRestmuell - $t) / 60 / 60 / 24 + 1);
          if ($dayDiff >= 0) { fhem("setreading du_muelltermine Restmuell $dayDiff"); }
      }
   };
   if ($Kalendertext =~ /Biotonne/) {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtBiomuell eq '' || ($eventDate < $dtBiomuell && $eventDate > $t))
      {
         $dtBiomuell = $eventDate;

         my $dayDiff = floor(($dtBiomuell - $t) / 60 / 60 / 24 + 1);
         if ($dayDiff >= 0) { fhem("setreading du_muelltermine Biotonne $dayDiff"); }
      };
   };
}
}

Damit werden die Fraktionen und die verbleibenden Tage ermittelt und als reading in den dummy du_muelltermine geschrieben.
Wichtig hierbei, dass die 99_myUtils.pm use Time::Local; im "header" enthält...wenn nicht, einfügen...

3a.
ReadingsGroup anlegen, in der die Tonnensymbole angezeigt werden:
define muellabfuhr readingsGroup du_muelltermine:Restmuell,Biotonne,Papiertonne,GelberSack
Hiermit werden die Symbole nebeneinander in einer Zeile dargestellt.

3b.
Damit nur die Tonnen des nächsten Termins mit passenden Farben angezeigt werden, folgende Attribute setzen:
nonames: 1
valueFormat: { return $VALUE if ($VALUE < 7); return undef; }
valueIcon: { Biotonne => 'dustbin@green', GelberSack => 'bag@yellow', Papiertonne => 'dustbin@blue', Restmuell => 'dustbin@grey' }

Vielleicht kann es ja jemand gebrauchen...
Falls jemand Verbesserungs- und/oder Vereinfachungsvorschläge hat, immer her damit!
Anbei nach zwei screenshots von der anstehenden Leerung der nächsten Woche und der nächsten vier Wochen...bei mouseover über die Symbole in der readingsGroup werden auch noch die verbleibenden Tage bis zur Abfuhr angezeigt.

Gruß
Andreas

**Edith sagt: Da hat sich ein Fehler beim notify eingeschlichen...und schon korrigiert...

Papaloewe

ZitatDa bei uns immer am gleichen Wochentag der Müll abgeholt wird ...

Hallo Vize,

ja, das ist bei mir auch so, nur manchmal verschiebt sich dann doch der Wochentag wegen Feiertagen und so.
Also wenn du jetzt noch den Wochentag vor die Müllsymbole basteln würdest, wäre es perfekt für mich :)

LG
Thomas

Vize

Hallo Thomas,

sorry, aber da bin ich raus. Ist mir für meinen Anwendungsfall zu aufwändig...da im Kalender keine Wochentage stehen, müsste ich die dann erst aus dem Datum umwandeln und in den dummy und die readingsGroup bringen...

Vielleicht kannst du das ja mal selber probieren!? Oder vielleicht kann ja jemand anderes weiterhelfen...

Gruß
Andreas

Vize

Hallo zusammen,

ich möchte hier doch nochmal bezüglich der Wochentage einhaken.

Könnte mir jemand dabei helfen, wie ich aus dem Datum der jeweiligen Müllabfuhrtermine den entsprechenden Wochentag rauskriege?
Diesen würde ich dann gerne analog zu oben als reading in das dummy-Device du_muelltermine schreiben.

Hier mal ein Auszug aus meiner 99_myUtils für die Papiertonne:

package main;

use strict;
use warnings;
use POSIX;
use Time::Local;

sub
myUtils_Initialize($$)
{
  my ($hash) = @_;
}

#
# Abfall Kalender auswerten: "muellkalender"
#

sub
muelltermine ($)
{
my ($Ereignis) = @_;
my @Ereignisarray = split(/.*:\s/,$Ereignis);
my $Ereignisteil1 = $Ereignisarray[1];
my @uids=split(/;/,$Ereignisteil1);
my $t = time;
my $dtPapier = '';

foreach my $uid (@uids) {
   my $Kalendertext = fhem("get muellkalender summary $uid");
   if ($Kalendertext =~ /Papiertonne/)
   {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtPapier eq '' || ($eventDate < $dtPapier && $eventDate > $t))
      {
         $dtPapier = $eventDate;

         my $dayDiff = floor(($dtPapier - $t) / 60 / 60 / 24 + 1);
         if ($dayDiff >= 0) { fhem("setreading du_muelltermine Papiertonne $dayDiff"); }
      }
   };


Nur wie bekomme ich jetzt aus dem Abfuhrdatum zusätzlich den entsprechendenWochentag ermittelt, und wie kann ich den als "Klartext" als reading schreiben, also in etwa so, wenn
if ($dayDiff >= 0) { fhem("setreading du_muelltermine Papiertonne_Tag $WoTag"); }
dann soll das reading Papiertonne_Tag z.B. "Mittwoch" lauten...

Bin für jede Hilfe dankbar!

Gruß
Andreas


Hans Franz

#4
Hallo,
Die Frage finde ich spannend. Habe dazu das gefunden:

{Day_of_Week_to_Text(Day_of_Week($year,$month,$mday))}

evtl. vorher
use Date::Calc qw(Today Decode_Language Language
                   Day_of_Week Day_of_Week_to_Text   
                   Add_Delta_YMD);

Language(Decode_Language("Deutsch"));


fhem scheint das, ausser Decode_Language("Deutsch"), aber schon zu können.

Gruß
Hans

Edith:
War bei mir nur in meiner Testversion schon vorhanden. use Date::Calc muss wohl in der sub angegeben werden.
Raspi
CUL, Nano-CUL
FHT8V, FHT80B, S300TH
WM1000WZ, ELRO
LW12, LD382,DS18B20

Vize

Hallo Hans,

danke für die Infos.

Hab aber nochmal weiter recherchiert und eine Lösung gefunden:

in der sub muelltermine folgendes ergänzen:
my $Wochentag = '';
my @Wochentage = qw(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag);


Dann noch für jede Abfallfraktion (hier Beispiel Papier) dieses ergänzen:
my $wd = (localtime $dtPapier)[6];
$Wochentag = $wd;
my $WoTag = sprintf("%s", $Wochentage[$Wochentag]);
if ($dayDiff >= 0) { fhem("setreading du_muelltermine Papiertonne_Tag $WoTag"); }


Und schon habe ich zusätzliche readings im dummy du_muelltermine mit den Wochentagen...

Gruß
Andreas

kvo1

Hi Vize
danke , das muss ich mir die nächsten tage mal ansehen, sowas wollte ich auch noch machen !

kvo1
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Vize

Hallo zusammen,

ich bräuchte nochmal Hilfe...

Wie beschrieben, lasse ich mir nun auch die Wochentage zur Müllabfuhr in das entsprechende dummy (du_muelltermine) schreiben.
Siehe screenshot "Abfuhr1".

Wenn ich nun die readingsGroup so erweitere (DEF):
du_muelltermine:Restmuell,Biotonne,Papiertonne,GelberSack
du_muelltermine:Restmuell_Tag,Biotonne_Tag,Papiertonne_Tag,GelberSack_Tag


werden mir wie gehabt, nur Tonnensymbole für die Abfuhr der kommenden Woche angezeigt, jedoch darunter die Wochentage für alle Fraktionen.
Siehe screenshot "Abfuhr2".

Im Attribut valueFormat steht:
{ return $VALUE if ($VALUE <= 7); return undef; }

Kann ich das irgendwie anpassen, damit die Wochentage auch nur dann angezeigt werden, wenn ein Tonnensymbol angezeigt wird bzw. der nächste Termin in weniger als 7 Tagen ist?

Wenn ja, wie?

Bin für jede Hilfe dankbar!

Gruß
Andreas

Vize

Mahlzeit,

im logfile steht nun auch noch:
[Tue Aug 11 20:56:03 2015] fhem.pl: Argument "Mittwoch" isn't numeric in numeric le (<=) at (eval 28564) line 1.

Die Fehlermeldung taucht nun alle 4-5 min wieder auf...

Ich denke mal das bezieht sich hierauf, oder?
{ return $VALUE if ($VALUE <= 7); return undef; }

Gruß
Andreas

Vize

Moin,

so habe eine Lösung für mein letztes Problem mit den zu viel angezeigten Wochentagen und der Fehlermeldung im logfile gefunden. Wahrscheinlich nicht sehr elegant, aber funktioniert.

Wenn es interessiert, kann ich heute Abend mal den entsprechenden code posten...

Vielleicht trudeln ja bis dahin noch weitere Lösungsvorschläge von euch ein?!?  ;)

Gruß
Andreas

kvo1

ZitatWenn es interessiert, kann ich heute Abend mal den entsprechenden code posten...

ja bitte  ;)
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Vize

Wird aber frühestens Sonntag Abend was...Wochenende ist schon komplett ausgebucht...  ;) 8)

Gruß
Andreas

BlackStone

#12
Da kann ich auch nur sagen, ja bitte.
und könnte man das Datum evtl., über den Tonnen anzeigen lassen, sozusagen zentriert über allen Symbolen?

bin Grade erst dabei mich in fhem reinzufuchsen, und bin immer wieder begeistert, was man so anstellen kann, (hab mir z.b. einen Fenster Öffner mit funksteckdose gekoppelt, tut in der Garage dienst.^^!

ist das :

{ return $VALUE if ($VALUE <= 7); return undef; }

nicht ein vergleich Srting mit integer ? das könnte den fehler im log erklären.

müsste glaube ich so gehen.:

{ return $VALUE if (int $VALUE <= 7); return undef; }



edit: hab das mit dem Datum hinbekommen.

habe wie aus den Code von Vize aus Post 1 genommen,
die readingsGroup nach Post 7 erweitert. dann hatte ich das gleiche wie dort im screen.

dann habe ich die Code Zeile
if ($dayDiff >= 0) { fhem("setreading du_muelltermine Restmuell $dayDiff"); }

nach fhem("setreading du_muelltermine Restmuell $dayDiff"); geändert, dann sind zwar alle Tonnen da, jedoch mit dem entsprechendem Datum aus der ICE Datei, d.h. das  passt auch wenn es nicht zu sehen ist.
darunter noch eine Zeile mit
fhem("setreading du_muelltermine Papiertonne_Tag $SplitDt[0]");
und das Datum ist drin.


Tante edtit sagt:/

Ich habe mal weiter grfriemelt.

nun schaut es so aus bei mir.

fhem.cfg

define muellkalender Calendar ical file ./www/muellkalender.ics 86400
define no_muelltermine notify muellkalender:modeUpcoming.* { muelltermine("$EVENT") }
define du_muelltermine dummy
define muellabfuhr readingsGroup du_muelltermine:Restmuell,Biotonne,Papiertonne,GelberSack\
du_muelltermine:Restmuell_Tag,Biotonne_Tag,Papiertonne_Tag,GelberSack_Tag\
du_muelltermine:Restmuell_dTag,Biotonne_dTag,Papiertonne_dTag,GelberSack_dTag
attr muellabfuhr nonames 1
attr muellabfuhr valueIcon { Biotonne => 'dustbin@green', GelberSack => 'dustbin@yellow', Papiertonne => 'dustbin@blue', Restmuell => 'dustbin@grey', Nix => 'dustbin@white' }

der eintrag Nix naja, soll als dummy herhalten, um inhalte auszublenden, aber das will noch nicht so. ist also wirkungslos im code.

und in der 99_myUtils.pm

##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;

use strict;
use warnings;
use POSIX;
use Time::Local;

sub
myUtils_Initialize($$)
{
  my ($hash) = @_;
}

# Enter you functions below _this_ line.

sub
muelltermine ($)
{
my ($Ereignis) = @_;
my @Ereignisarray = split(/.*:\s/,$Ereignis);
my $Ereignisteil1 = $Ereignisarray[1];
my @uids=split(/;/,$Ereignisteil1);
my $t = time;
my $dtPapier = '';
my $dtGelberSack = '';
my $dtRestmuell = '';
my $dtBiomuell = '';
my @days = qw/So Mo Di Mi Do Fr Sa/;


foreach my $uid (@uids) {




   my $Kalendertext = fhem("get muellkalender summary $uid");

   
   
   if ($Kalendertext =~ /Blaue Tonne/)
   {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtPapier eq '' || ($eventDate < $dtPapier && $eventDate > $t))
      {
         $dtPapier = $eventDate;
         my $dayDiff = floor(($dtPapier - $t) / 60 / 60 / 24 + 1);
         my $date = $SplitDt[0];
         my @date = split /\./,$date;
         my $wday = $days[(localtime(timelocal(0,0,0,$date[0],$date[1]-1,$date[2]-1900)))[6]];
         fhem("setreading du_muelltermine Papiertonne $dayDiff");
         fhem("setreading du_muelltermine Papiertonne_Tag $wday");
         fhem("setreading du_muelltermine Papiertonne_dTag $SplitDt[0]");
      }
   };
   if ($Kalendertext =~ /Gelbe Tonne/) {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtGelberSack eq '' || ($eventDate < $dtGelberSack && $eventDate > $t))
      {
         $dtGelberSack = $eventDate;

         my $dayDiff = floor(($dtGelberSack - $t) / 60 / 60 / 24 + 1);
         my $date = $SplitDt[0];
         my @date = split /\./,$date;
         my $wday = $days[(localtime(timelocal(0,0,0,$date[0],$date[1]-1,$date[2]-1900)))[6]];
         fhem("setreading du_muelltermine GelberSack $dayDiff");
         fhem("setreading du_muelltermine GelberSack_Tag $wday");
         fhem("setreading du_muelltermine GelberSack_dTag $SplitDt[0]");
      }
   };
   if ($Kalendertext =~ /Reststoff/) {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtRestmuell eq '' || ($eventDate < $dtRestmuell && $eventDate > $t))
      {
          $dtRestmuell = $eventDate;

          my $dayDiff = floor(($dtRestmuell - $t) / 60 / 60 / 24 + 1);
          my $date = $SplitDt[0];
          my @date = split /\./,$date;
          my $wday = $days[(localtime(timelocal(0,0,0,$date[0],$date[1]-1,$date[2]-1900)))[6]];
          fhem("setreading du_muelltermine Restmuell $dayDiff");
          fhem("setreading du_muelltermine Restmuell_Tag $wday");
          fhem("setreading du_muelltermine Restmuell_dTag $SplitDt[0]");
      }
   };
   if ($Kalendertext =~ /Biotonne/) {
      my $dt = fhem("get muellkalender start $uid");
      my @SplitDt = split(/ /,$dt);
      my @SplitDate = split(/\./,$SplitDt[0]);
      my $eventDate = timelocal(0,0,0,$SplitDate[0],$SplitDate[1]-1,$SplitDate[2]);;
      if ($dtBiomuell eq '' || ($eventDate < $dtBiomuell && $eventDate > $t))
      {
         $dtBiomuell = $eventDate;

         my $dayDiff = floor(($dtBiomuell - $t) / 60 / 60 / 24 + 1);
         my $date = $SplitDt[0];
         my @date = split /\./,$date;
         my $wday = $days[(localtime(timelocal(0,0,0,$date[0],$date[1]-1,$date[2]-1900)))[6]];
         fhem("setreading du_muelltermine Biotonne $dayDiff");
         fhem("setreading du_muelltermine Biotonne_Tag $wday");
         fhem("setreading du_muelltermine Biotonne_dTag $SplitDt[0]");
      };
   };
}
}

1;


habe da eine ander variante der Wochentags berechnung drin. screen ist auch im anhang.

Vize

#13
Hallo zusammen,

hier noch mal auf die Schnelle meine Variante...

Als erstes lasse ich mir auch nur die Wochentage der Abholung in das dummy du_muelltermine schreiben, die maximal 7 Tage in der Zukunft liegen:
99_myUtils, Beispiel Papier
my $wd = (localtime $dtPapier)[6];
    $Wochentag = $wd;
    my $WoTag = sprintf("%s", $Wochentage[$Wochentag]);
    if ($dayDiff >= 0 && $dayDiff <= 7) { fhem("setreading du_muelltermine Papiertonne_Tag $WoTag"); }
    else { fhem("deletereading du_muelltermine Papiertonne_Tag"); }


Um die besagte Fehlermeldung im log zu den Wochentagen zu vermeiden habe ich
1. in der 99_myUtils noch das hier ergänzt:
sub
muellvalueFormat ($$)
{
my ($READING,$VALUE) = @_;
if ($READING =~ /Tag/) {
  return "%s"; }
elsif ($VALUE <= 7) {
  return "%.0f"; }
else {
  return undef; }
}

und
2. das Attribut valueFormat in der readingsGroup folgendermaßen angepasst:
{ muellvalueFormat ($READING,$VALUE);; }

Damit habe ich dann die Abfuhren der nächsten 7 Tage mit Wochentag (s. a. screenshots)...

@BlackStone: Deine Variante sieht auch interessant aus...werde ich mir wohl auch mal nachbauen...  ;)

So, ich hoffe, ich hab nix vergessen...

Gruß
Andreas

*****
EDIT: im ersten code aus der 99_myUtils eine else-Bedingung zum Löschen des "Tagesreadings" hinzugefügt...sonst bleiben die Wochentage nach Ablauf der Termine stehen...

kvo1

Hallo Vize,

Könnest Du mal Deine gesamte 99_myUtils posten ?

Danke !
kvo1
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB