add source for stadtreinigung.hamburg

This commit is contained in:
mampfes
2020-04-19 19:39:26 +02:00
parent b02b710c6d
commit 060d7c264e
5 changed files with 211 additions and 0 deletions

View File

@@ -31,6 +31,7 @@ Currently the following service providers are supported:
- [AbfallPlus.de / Abfall.IO](./doc/source/abfall_io.md)
- [AWBKoeln.de](./doc/source/awbkoeln_de.md)
- [Jumomind.de](./doc/source/jumomind_de.md)
- [Stadtreinigung.Hamburg](./doc/source/stadtreinigung_hamburg.md)
## Configuration via configuration.yaml

View File

@@ -0,0 +1,56 @@
import re
import requests
import datetime
import icalendar
from collections import OrderedDict
from ..helpers import CollectionAppointment
DESCRIPTION = "Source for Stadtreinigung.Hamburg based services."
URL = "https://www.stadtreinigung.hamburg"
TEST_CASES = OrderedDict(
[
(
"Hamburg",
{
"asId": 5087,
"hnId": 113084,
},
),
]
)
class Source:
def __init__(self, asId, hnId):
self._asId = asId
self._hnId = hnId
def fetch(self):
args = {"asId": self._asId, "hnId": self._hnId, "adresse": "MeineAdresse"}
# get ics file
r = requests.post(
f"https://www.stadtreinigung.hamburg/privatkunden/abfuhrkalender/Abfuhrtermin.ics",
data=args,
)
# parse ics file
calender = icalendar.Calendar.from_ical(r.text)
# Summary text contains a lot of blabla. This reg-ex tries to extract the waste type.
regex = re.compile("Erinnerung: Abfuhr (.*) morgen")
entries = []
for e in calender.walk():
if e.name == "VEVENT":
summary = str(e.get("summary"))
match = regex.match(summary)
if match:
summary = match.group(1)
dtstart = e.get("dtstart").dt.date() + datetime.timedelta(days=1) # events are reported 1 day before
summary = summary
entries.append(CollectionAppointment(dtstart, summary))
return entries

View File

@@ -0,0 +1,112 @@
#!/usr/bin/python3
import inquirer
import requests
import json
from html.parser import HTMLParser
# Parser for HTML option list
class OptionParser(HTMLParser):
def __init__(self, select_name):
super().__init__()
self._select_name = select_name
self._within_select = False
self._within_option = False
self._option_name = ""
self._option_value = "-1"
self._choices = []
@property
def choices(self):
return self._choices
def handle_starttag(self, tag, attrs):
if tag == "select":
for attr in attrs:
if attr[0] == "name" and attr[1] == self._select_name:
self._within_select = True
break
elif tag == "option" and self._within_select:
self._within_option = True
for attr in attrs:
if attr[0] == "value":
self._option_value = attr[1]
def handle_endtag(self, tag):
if tag == "select":
self._within_select = False
elif tag == "option":
if (
self._within_select
and self._within_option
and len(self._option_name) > 0
and self._option_value != ""
):
self._choices.append((self._option_name, self._option_value))
self._within_option = False
self._option_name = ""
self._option_value = "-1"
def handle_data(self, data):
if self._within_option:
self._option_name += data
def main():
# search for street
questions = [
inquirer.Text("strasse", message="Enter search string for street name"),
# inquirer.Text("hausnummer", message="Enter search string for building number"),
]
answers = inquirer.prompt(questions)
args = answers
args["hausnummer"] = ""
args["bestaetigung"] = "true"
args["mode"] = "search"
r = requests.post(
"https://www.stadtreinigung.hamburg/privatkunden/abfuhrkalender/index.html",
data=args,
)
# parser HTML option list
parser = OptionParser(select_name="asId")
parser.feed(r.text)
questions = [inquirer.List("asId", choices=parser.choices, message="Select street")]
answers = inquirer.prompt(questions)
# search for building number
args = answers.copy()
args["hausnummer"] = ""
args["bestaetigung"] = "true"
args["mode"] = "search"
r = requests.post(
"https://www.stadtreinigung.hamburg/privatkunden/abfuhrkalender/index.html",
data=args,
)
# parser HTML option list
parser = OptionParser(select_name="hnId")
parser.feed(r.text)
questions = [
inquirer.List("hnId", choices=parser.choices, message="Select house number")
]
answers.update(inquirer.prompt(questions))
print("Copy the following statements into your configuration.yaml:\n")
print("# waste_collection_schedule source configuration")
print("waste_collection_schedule:")
print(" sources:")
print(" - name: stadtreinigung_hamburg")
print(" args:")
print(f" asId: {answers['asId']}")
print(f" hnId: {answers['hnId']}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,41 @@
# Stadtreinigung.Hamburg
Add support for schedules provided by `Stadtreinigung.Hamburg`.
## Configuration via configuration.yaml
```yaml
waste_collection_schedule:
sources:
- name: stadtreinigung_hamburg
args:
asId: ASID
hnId: HNID
```
### Configuration Variables
**asId**<br>
*(string) (required)*
**hnId**<br>
*(string) (required)*
## Example
```yaml
waste_collection_schedule:
sources:
- name: stadtreinigung_hamburg
args:
asId: 5087
hnId: 113084
```
## How to get the source arguments
There is a script with an interactive command line interface which generates the required source configuration:
[https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/custom_components/waste_collection_schedule/package/wizard/stadtreinigung_hamburg.py](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/custom_components/waste_collection_schedule/package/wizard/stadtreinigung_hamburg.py).
Just run this script from a shell and answer the questions.

View File

@@ -33,3 +33,4 @@ Currently the following service providers are supported:
- AbfallPlus.de / Abfall.IO
- AWBKoeln.de
- Jumomind.de
- Stadtreinigung.Hamburg