Create a gist now

Instantly share code, notes, and snippets.

Embed
Loxone Programm um die Müllabfuhrtermine der Stadtreinigung Hamburg einzubinden
// Stadtreinigung Hamburg Abfuhrkalender
// von Markus Fritze, loxone@sarnau.com
//
// Eingaenge:
// ACHTUNG: Weil Loxone keine bequeme Moeglichkeit bietet Text fuer Eingaenge zu definieren, habe ich
// den Strassennamen und die Hausnummer unten direkt definiert. Einfach STRASSE mit dem Strassennamen und
// 999 mit der Hausnummer ersetzen.
// TI1 = Strassenname ohne Umlaute (ae,oe,ue,ss)
// TI2 = Hausnummer
//
// Ausgaenge:
// TQ1: Welche Tonnen werden am naechsten Termin abgeholt
// TQ2: Volltext "In xyz Tagen: tonne1, tonne2, ..."
// AQ1: In wieviel Tagen wird TQ1 (siehe oben) abgeholt (0 = Heute)
// Die folgenden Eingaenge geben an in wieviel Tagen die jeweilige Muellsorte
// abgeholt wird. Achtung: regelmaessig wird mehr als eine Sorte am Tag abgeholt!
// Negative Zahl (-1) heisst: kein Termin gefunden. Dies ist z.B. der Fall bei
// Laub (nur im Herbst bis Dezember) und Weihnachtsbaeumen (nur im Januar)
// AQ2: Restmuell (Schwarze Tonne)
// AQ3: Papier (Blaue Tonne)
// AQ4: Wertstoff (Gelbe Tonne, Gelber Sack)
// AQ5: Bio (Gruene Tonne)
// AQ6: Laub (Laubsaecke)
// AQ7: Weihnachtsbaeume (ehm, ja)
// Der Strassenname liegt an TI1 an, wir muessen die Leerzeichen durch %20 ersetzen.
// Umlaute sollten als "ae" "oe", etc. geschrieben werden.
char *streetName = "STRASSE";//getinputtext(0);
// An TI2 liegt die Hausnummer an.
char *streetNumber = "999";//getinputtext(1);
char street[100];
char *streetP = street;
while(*streetName) {
if(*streetName == ' ' ) {
*streetP++ = '%';
*streetP++ = '2';
*streetP++ = '0';
++streetName;
} else {
*streetP++ = *streetName++;
}
}
int asId = 0;
int hnId = 0;
char buffer[200];
char *httpPtr;
// Zuerst muss die AddressID und die HausnummernID ermittelt werden. Dies braucht nur
// beim Reboot geschehen, da sie für eine gegebene Adresse unveraenderlich sind.
if(1) { // Um diesen Request einfach komplett abzuriegeln, einfach auf if(0) setzen. Nicht vergessen asId und hnId richtig zu setzen!
sprintf(buffer, "/privatkunden/abfuhrkalender/index.html?asId&strasse=%s&hnId&hausnummer=%s&bestaetigung=true&mode=search&suche=Abfuhrtermine%20suchen", street, 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, muessen 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);
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 6 Stunden einmal durchlaufen wird, d.h.
// die Muelltermine werden 4x am Tag neu ermittelt.
while(1) {
// Wir laden die Kalendardaten von der Stadtreinigung Hamburg
sprintf(buffer, "/privatkunden/abfuhrkalender/Abfuhrtermin.ics?asId=%d&hnId=%d&adresse=%s%%20%s", asId, hnId, street, streetNumber);
httpPtr = httpget("www.stadtreinigung.hamburg", buffer);
// In Hamburg gibt es 6 verschiedene Abfuhrtermine. Es ist moeglich, dass mehr als
// eine Tonne an einem Tag abgeholt wird. Eine Ueberschneidung von Restmuell und
// einer anderen Tonne ist sehr ueblich.
int papiertonne = -1; // einmal pro Monat
int restmuell = -1; // je nach Bestellung: woechentlich bis monatlich
int wertstoff = -1; // alle 2 Wochen
int bio = -1; // alle 2 Wochen
// Diese beiden Events kann der Script noch nicht parsen, da sie nur im Herbst/Januar
// auftreten und ich dadurch momentan den String nicht ermitteln kann.
int laub = -1; // Laub ist nur im Herbst
int weihnachtsbaum = -1; // die Weihnachtsbaeume werden nur im Januar abgeholt
// Durch den HTTP Request suchen. Alle Beschreibungen folgen dem Schema:
// "wird am TT.MM.JJJJ ... ___ ..."
while(httpPtr != NULL) {
httpPtr = strstrskip(httpPtr, "wird am ");
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);
}
// Hier muessen noch Laub und Weichnachtsbaum nachgetragen werden
}
char nextBuffer[150]; // dies ist der Text fuer den naechsten Termin der Muellabfuhr
nextBuffer[0] = 0;
int nextDay = -1; // dies ist der naechste Termin der Muellabfuhr
setoutput(1, restmuell);
if(papiertonne >= 0) {
strcpy(nextBuffer, "Restmuell");
nextDay = restmuell; // dies ist der naechste Termin der Muellabfuhr
}
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 naechste mal Muell abgeholt?
setoutputtext(0, nextBuffer); // Welche Tonnen werden abgeholt?
setoutputtext(1, dayBuffer); // Wann und welche Tonnen werden abgeholt?
}
free(httpPtr);
sleeps(60*60*6); // update alle 6 Stunden
}
@sarnau

This comment has been minimized.

Show comment
Hide comment
@sarnau

sarnau Apr 2, 2018

Ich habe auch noch einen UTC Bug gefixt. Nach Mitternacht bis 2-3 Uhr morgens war der Termin falsch.

Owner

sarnau commented Apr 2, 2018

Ich habe auch noch einen UTC Bug gefixt. Nach Mitternacht bis 2-3 Uhr morgens war der Termin falsch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment