mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 04:06:03 +01:00
add source for Berliner Stadtreinigungsbetriebe / bsr.de
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
72
custom_components/waste_collection_schedule/package/wizard/bsr_de.py
Executable file
72
custom_components/waste_collection_schedule/package/wizard/bsr_de.py
Executable 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
41
doc/source/bsr_de.md
Normal 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
13
info.md
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user