add source for Berliner Stadtreinigungsbetriebe / bsr.de

This commit is contained in:
mampfes
2020-05-05 16:42:22 +02:00
parent 7385d6cc57
commit 622230410e
5 changed files with 232 additions and 6 deletions

View File

@@ -30,6 +30,7 @@ Currently the following service providers are supported:
- [AbfallNavi / RegioIT.de](./doc/source/regioit_de.md)
- [AbfallPlus.de / Abfall.IO](./doc/source/abfall_io.md)
- [AWBKoeln.de](./doc/source/awbkoeln_de.md)
- [BSR.de / Berliner Stadtreinigungsbetriebe](./doc/source/bsr_de.md)
- [Generic ICS File](./doc/source/ics.md)
- [Jumomind.de](./doc/source/jumomind_de.md)
- [Stadtreinigung.Hamburg](./doc/source/stadtreinigung_hamburg.md)

View File

@@ -0,0 +1,111 @@
import requests
import datetime
import icalendar
from collections import OrderedDict
import urllib.parse
from ..helpers import CollectionAppointment
DESCRIPTION = "Source for Berliner Stadtreinigungsbetriebe"
URL = "bsr.de"
TEST_CASES = OrderedDict(
[
(
"Bahnhofstr., 12159 Berlin (Tempelhof-Schöneberg)",
{
"abf_strasse": "Bahnhofstr., 12159 Berlin (Tempelhof-Schöneberg)",
"abf_hausnr": 1,
},
),
(
"Am Ried, 13467 Berlin (Reinickendorf)",
{
"abf_strasse": "Am Ried, 13467 Berlin (Reinickendorf)",
"abf_hausnr": "11G",
},
)
]
)
def myquote(s):
# bsr uses strange quoting
return urllib.parse.quote(s, safe=",()")
class Source:
def __init__(self, abf_strasse, abf_hausnr):
self._abf_strasse = abf_strasse
self._abf_hausnr = abf_hausnr
def fetch(self):
# get cookie
r = requests.get("https://www.bsr.de/abfuhrkalender-20520.php")
cookies = r.cookies
# get street name only (without PLZ)
street = self._abf_strasse.split(",")[0]
# start search using string name (without PLZ)
args = {"script": "dynamic_search", "step": 1, "q": street}
r = requests.get(
"https://www.bsr.de/abfuhrkalender_ajax.php", params=args, cookies=cookies
)
# retrieve house number list
args = {"script": "dynamic_search", "step": 2, "q": self._abf_strasse}
r = requests.get(
"https://www.bsr.de/abfuhrkalender_ajax.php", params=args, cookies=cookies
)
args = {
"abf_strasse": street,
"abf_hausnr": self._abf_hausnr,
"tab_control": "Jahr",
"abf_config_weihnachtsbaeume": "",
"abf_config_restmuell": "on",
"abf_config_biogut": "on",
"abf_config_wertstoffe": "on",
"abf_config_laubtonne": "on",
# "abf_selectmonth": "5 2020",
# "abf_datepicker": "28.04.2020",
# "listitems":7,
}
r = requests.post(
"https://www.bsr.de/abfuhrkalender_ajax.php?script=dynamic_kalender_ajax", data=args, cookies=cookies
)
args = {
"script": "dynamic_iCal_ajax",
"abf_strasse": self._abf_strasse,
"abf_hausnr": self._abf_hausnr,
"tab_control": "Jahr",
"abf_config_weihnachtsbaeume": "",
"abf_config_restmuell": "on",
"abf_config_biogut": "on",
"abf_config_wertstoffe": "on",
"abf_config_laubtonne": "on",
# "abf_selectmonth": "5 2020",
# "listitems":7,
}
# create url using private url encoding
encoded = map(lambda key: f"{key}={myquote(str(args[key]))}", args.keys())
url = "https://www.bsr.de/abfuhrkalender_ajax.php?" + "&".join(encoded)
r = requests.get(url, cookies=cookies)
# parse ics file
calender = icalendar.Calendar.from_ical(r.text)
entries = []
for e in calender.walk():
if e.name == "VEVENT":
dtstart = None
if type(e.get("dtstart").dt) == datetime.date:
dtstart = e.get("dtstart").dt
elif type(e.get("dtstart").dt) == datetime.datetime:
dtstart = e.get("dtstart").dt.date()
summary = str(e.get("summary"))
entries.append(CollectionAppointment(dtstart, summary))
return entries

View File

@@ -0,0 +1,72 @@
#!/usr/bin/python3
import inquirer
import requests
import json
def main():
# get cookies
r = requests.get("https://www.bsr.de/abfuhrkalender-20520.php")
cookies = r.cookies
while True:
questions = [inquirer.Text("q", message="Enter search string for street")]
answers = inquirer.prompt(questions)
args = {"script": "dynamic_search", "step": 1, "q": answers["q"]}
r = requests.get(
"https://www.bsr.de/abfuhrkalender_ajax.php", params=args, cookies=cookies
)
data = json.loads(r.text)
if (
len(data) == 1 and data[0]["value"] == "Keine Adresse gefunden"
): # {'value': 'Keine Adresse gefunden'}
print("Search returned no result. Please try again.")
else:
break
street_choices = []
for d in data:
street_choices.append(d["value"])
# select street
questions = [
inquirer.List("abf_strasse", choices=street_choices, message="Select street")
]
answers = inquirer.prompt(questions)
# retrieve house number list
args = {"script": "dynamic_search", "step": 2, "q": answers["abf_strasse"]}
r = requests.get(
"https://www.bsr.de/abfuhrkalender_ajax.php", params=args, cookies=cookies
)
# select house number
data = json.loads(r.text)
house_number_choices = []
for d in data.values():
house_number_choices.append((d["FullStreet"], d["HouseNo"]))
questions = [
inquirer.List(
"abf_hausnr", choices=house_number_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: bsr_de")
print(" args:")
for key, value in answers.items():
print(f" {key}: {value}")
if __name__ == "__main__":
main()

41
doc/source/bsr_de.md Normal file
View File

@@ -0,0 +1,41 @@
# Stadtreinigung.Hamburg
Add support for schedules provided by `Berliner Stadtreinigungsbetriebe`.
## Configuration via configuration.yaml
```yaml
waste_collection_schedule:
sources:
- name: bsr_de
args:
abf_strasse: STRASSE
abf_hausnr: HAUSNR
```
### Configuration Variables
**abf_strasse**<br>
*(string) (required)*
**abf_hausnr**<br>
*(string) (required)*
## Example
```yaml
waste_collection_schedule:
sources:
- name: bsr_de
args:
abf_strasse: "Bahnhofstr., 12159 Berlin (Tempelhof-Schöneberg)"
abf_hausnr: 1
```
## 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/bsr_de.py](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/custom_components/waste_collection_schedule/package/wizard/bsr_de.py).
Just run this script from a shell and answer the questions.

13
info.md
View File

@@ -28,10 +28,11 @@ Alternative details view showing the list of appointment types and their next ev
Currently the following service providers are supported:
- Abfall_Kreis_Tuebingen.de
- AbfallNavi / RegioIT.de
- AbfallPlus.de / Abfall.IO
- AWBKoeln.de
- [Abfall_Kreis_Tuebingen.de]([Abfall_Kreis_Tuebingen.de)
- [AbfallNavi by RegioIT.de](RegioIT.de)
- [AbfallPlus.de](AbfallPlus.de) / [Abfall.IO](Abfall.IO)
- [AWBKoeln.de](AWBKoeln.de)
- [BSR.de / Berliner Stadtreinigungsbetriebe](bsr.de)
- Generic ICS File
- Jumomind.de
- Stadtreinigung.Hamburg
- [Jumomind.de](Jumomind.de)
- [Stadtreinigung.Hamburg](Stadtreinigung.Hamburg)