Created
July 30, 2018 10:14
-
-
Save sarnau/6bfc02ff7a8623467f75fa558f55f72b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Stadtreinigung Hamburg Abfuhrkalender | |
// von Markus Fritze, loxone@sarnau.com | |
// Version: 30.07.2018 | |
// | |
// Ausgänge: | |
// TQ1: Welche Tonnen werden am nächsten Termin abgeholt | |
// TQ2: Volltext "In xyz Tagen: tonne1, tonne2, ..." | |
// AQ1: In wieviel Tagen wird TQ1 (siehe oben) abgeholt (0 = Heute) | |
// Die folgenden Eingänge geben an in wieviel Tagen die jeweilige Müllsorte | |
// abgeholt wird. Achtung: regelmäßig wird mehr als eine Sorte am Tag abgeholt! | |
// Negative Zahl (-1) heißt: kein Termin gefunden. Dies ist z.B. der Fall bei | |
// Laub (nur im Herbst bis Dezember) und Weihnachtsbäumen (nur im Januar) | |
// AQ2: Restmüll (Schwarze Tonne) | |
// AQ3: Papier (Blaue Tonne) | |
// AQ4: Wertstoff (Gelbe Tonne, Gelber Sack) | |
// AQ5: Bio (Grüne Tonne) | |
// AQ6: Laub (Laubsäcke) | |
// AQ7: Weihnachtsbäume (ja, wirklich) | |
// Der Straßenname, wir müssen die Leerzeichen durch %20 ersetzen. | |
// Umlaute sollten als "ae" "oe", etc. geschrieben werden. | |
char *streetName = "STRASSENNAME"; | |
// Die Hausnummer an. Ein '-' muß als %2D geschrieben werden | |
char *streetNumber = "HAUSNUMMER"; | |
// Nachdem das Program einmal durchlaufen ist, kann man im Log die asId und hnId finden. | |
// Man kann sie dann hier eintragen. Das erspart beim Reboot einen Request und die Nummern | |
// sind für eine gegebene Adresse unveränderlich. | |
int asId = 0; | |
int hnId = 0; | |
char *HTTPPtr; | |
// Zuerst muß die AddressID und die HausnummernID ermittelt werden. Dies braucht nur | |
// beim Reboot geschehen, da sie für eine gegebene Adresse unveränderlich sind. | |
if(asId == 0 || hnId == 0) { | |
char buffer[200]; | |
sprintf(buffer, "/privatkunden/abfuhrkalender/index.html?strasse=%s&hausnummer=%s&bestaetigung=true&mode=search", streetName, streetNumber); | |
//setlogtext(buffer); | |
HTTPPtr = httpget("www.stadtreinigung.hamburg", buffer); | |
//setlogtext(HTTPPtr); | |
char *sp = strstrskip(HTTPPtr, "\"asId\" value=\""); | |
if(sp != NULL) { | |
asId = batoi(sp); | |
sprintf(buffer, "asId = %d", asId); | |
setlogtext(buffer); | |
} else { | |
errorprintf("asId not found"); | |
} | |
sp = strstrskip(HTTPPtr, "\"hnId\" value=\""); | |
if(sp != NULL) { | |
hnId = batoi(sp); | |
sprintf(buffer, "hnId = %d", hnId); | |
setlogtext(buffer); | |
} else { | |
errorprintf("hnId not found"); | |
} | |
free(HTTPPtr); | |
// Falls die IDs nicht ermittelt werden konnten, müssen wir hier aufgeben. | |
if(asId == 0 || hnId == 0) { | |
errorprintf("asId/hnId not found"); | |
exit(); | |
} | |
} | |
// Konvertiere TT.MM.JJJJ String in ein Datum und dann in eine Tagesdifferenz zu Heute. | |
// Dies erlaubt es uns zu sagen: in xxx Tagen. | |
void calcDate(char *date, int *var) | |
{ | |
int day = batoi(date); | |
int month = batoi(date+3); | |
int year = batoi(date+6); | |
int currentTime = getcurrenttime(); | |
int deltaDays = (gettimeval(year, month, day, 0, 0, 0, 0) - gettimeval(getyear(currentTime, 1), getmonth(currentTime, 1), getday(currentTime, 1), 0, 0, 0, 1)) / (60*60*24); | |
// nach 16 Uhr ist es zu spät für die Mülltonne, d.h. wir haben den heutigen Termin verpaßt. | |
if(deltaDays == 0 && gethour(currentTime, 1) >= 16) | |
return; | |
if(*var < 0 || *var > deltaDays) | |
*var = deltaDays; | |
} | |
// Delta-Tage in einen netten String wandeln. Ich vermeide "Übermorgen" um Umlaute | |
// nicht zu nutzen. | |
void calcDateStr(int deltaDays, char *whenBuffer) | |
{ | |
if(deltaDays == 0) { | |
strcpy(whenBuffer, "Heute"); | |
} else if(deltaDays == 1) { | |
strcpy(whenBuffer, "Morgen"); | |
} else if(deltaDays > 1) { | |
sprintf(whenBuffer, "In %d Tagen", deltaDays); | |
} else { // negativ, d.h. keinen Abfuhrtermin gefunden | |
whenBuffer[0] = 0; | |
} | |
} | |
// Hier nun eine Endlosschleife, die alle 3 Stunden einmal durchlaufen wird, d.h. | |
// die Mülltermine werden 8x am Tag neu ermittelt. | |
while(1) { | |
// In Hamburg gibt es 6 verschiedene Abfuhrtermine. Es ist möglich, daß mehr als | |
// eine Tonne an einem Tag abgeholt wird. Eine Überschneidung von Restmüll und | |
// einer anderen Tonne ist sehr üblich. | |
int papiertonne = -1; // einmal pro Monat | |
int restmuell = -1; // je nach Bestellung: wöchentlich bis monatlich | |
int wertstoff = -1; // alle 2 Wochen | |
int bio = -1; // alle 2 Wochen | |
int laub = -1; // Laub ist nur im Herbst | |
// Den folgenden Event kann der Script noch nicht parsen, da er nur im Januar | |
// auftritt und ich dadurch den String momentan nicht ermitteln kann. | |
int weihnachtsbaum = -1; // die Weihnachtsbäume werden nur im Januar abgeholt | |
int i; | |
for(i=0; i<10; ++i) { // 10 Versuche in 60s Abständen die Daten zu lesen, falls das scheitert: in 3h nochmal versuchen | |
// Wir laden die Kalendardaten von der Stadtreinigung Hamburg | |
char buffer[200]; | |
sprintf(buffer, "/privatkunden/abfuhrkalender/Abfuhrtermin.ics?asId=%d&hnId=%d&adresse=%s%%20%s", asId, hnId, streetName, streetNumber); | |
HTTPPtr = httpget("www.stadtreinigung.hamburg", buffer); | |
// Durch den HTTP Request suchen. Alle Beschreibungen folgen dem Schema: | |
// "wird am TT.MM.JJJJ ... ___ ..." | |
char *httpPtr = HTTPPtr; | |
while(httpPtr != NULL) { | |
char *thttpPtr = strstrskip(httpPtr, "wird am "); | |
if(thttpPtr == NULL) | |
thttpPtr = strstrskip(httpPtr, "werden am "); | |
httpPtr = thttpPtr; | |
if(httpPtr == NULL) // Ende erreicht | |
break; | |
char tempEventBuffer[50]; | |
strncpy(tempEventBuffer, httpPtr, 50); tempEventBuffer[49] = 0; | |
if(strstr(tempEventBuffer, "Papier") != NULL) { | |
calcDate(tempEventBuffer, &papiertonne); | |
} else if (strstr(tempEventBuffer, "Rest") != NULL) { | |
calcDate(tempEventBuffer, &restmuell); | |
} else if (strstr(tempEventBuffer, "Wertstoff") != NULL) { | |
calcDate(tempEventBuffer, &wertstoff); | |
} else if (strstr(tempEventBuffer, "Bio") != NULL) { | |
calcDate(tempEventBuffer, &bio); | |
} else if (strstr(tempEventBuffer, "Laub") != NULL) { | |
calcDate(tempEventBuffer, &laub); | |
} | |
// Hier muß noch die Weichnachtsbaumabfuhr nachgetragen werden | |
} | |
free(HTTPPtr); | |
if(restmuell >= 0) // den Termin muß es immer geben, wenn wir den finden, sind die Daten valide | |
break; | |
sleep(60*3); // 3 Minuten Pause vor dem nächsten Versuch | |
} | |
if(restmuell >= 0) { | |
char nextBuffer[150]; // dies ist der Text für den nächsten Termin der Müllabfuhr | |
nextBuffer[0] = 0; | |
int nextDay = -1; // dies ist der nächste Termin der Müllabfuhr | |
setoutput(1, restmuell); | |
if(restmuell >= 0) { | |
strcpy(nextBuffer, "Restmüll"); | |
nextDay = restmuell; // dies ist der nächste Termin der Müllabfuhr | |
} | |
setoutput(2, papiertonne); | |
if(papiertonne >= 0) { | |
if(papiertonne < nextDay) { | |
strcpy(nextBuffer, "Papier"); | |
nextDay = papiertonne; | |
} else if(papiertonne == nextDay) { | |
strcat(nextBuffer, ", Papier"); | |
} | |
} | |
setoutput(3, wertstoff); | |
if(wertstoff >= 0) { | |
if(wertstoff < nextDay) { | |
strcpy(nextBuffer, "Wertstoff"); | |
nextDay = wertstoff; | |
} else if(wertstoff == nextDay) { | |
strcat(nextBuffer, ", Wertstoff"); | |
} | |
} | |
setoutput(4, bio); | |
if(bio >= 0) { | |
if(bio < nextDay) { | |
strcpy(nextBuffer, "Bio"); | |
nextDay = bio; | |
} else if(bio == nextDay) { | |
strcat(nextBuffer, ", Bio"); | |
} | |
} | |
setoutput(5, laub); | |
if(laub >= 0) { | |
if(laub < nextDay) { | |
strcpy(nextBuffer, "Laub"); | |
nextDay = laub; | |
} else if(laub == nextDay) { | |
strcat(nextBuffer, ", Laub"); | |
} | |
} | |
setoutput(6, weihnachtsbaum); | |
if(weihnachtsbaum >= 0) { | |
if(weihnachtsbaum < nextDay) { | |
strcpy(nextBuffer, "Weihnachtsbaum"); | |
nextDay = weihnachtsbaum; | |
} else if(weihnachtsbaum == nextDay) { | |
strcat(nextBuffer, ", Weihnachtsbaum"); | |
} | |
} | |
if(nextDay < 0) { | |
setoutputtext(0, "-"); | |
setoutputtext(1, "Kein Termin"); | |
} else { | |
char dayBuffer[150]; | |
calcDateStr(nextDay, dayBuffer); | |
strcat(dayBuffer, ": "); | |
strcat(dayBuffer, nextBuffer); | |
setoutput(0, nextDay); // Wann wird das nächste mal Müll abgeholt? | |
setoutputtext(0, nextBuffer); // Welche Tonnen werden abgeholt? | |
setoutputtext(1, dayBuffer); // Wann und welche Tonnen werden abgeholt? | |
} | |
} | |
sleeps(60*60*3); // update alle 3 Stunden | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment