From 44feb9e3ef15e5a16d1ee01d3097f716f9dece69 Mon Sep 17 00:00:00 2001 From: mampfes Date: Wed, 27 May 2020 12:19:56 +0200 Subject: [PATCH] add source for abfallnavi.de This source replaces the regioit.de source --- README.md | 3 +- .../package/source/abfallnavi_de.py | 55 +++++++++++ .../package/wizard/abfallnavi_de.py | 99 +++++++++++++++++++ doc/source/abfallnavi_de.md | 45 +++++++++ doc/source/regioit_de.md | 2 + info.md | 3 +- 6 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 custom_components/waste_collection_schedule/package/source/abfallnavi_de.py create mode 100755 custom_components/waste_collection_schedule/package/wizard/abfallnavi_de.py create mode 100644 doc/source/abfallnavi_de.md diff --git a/README.md b/README.md index eb0a7b01..09c8faf7 100644 --- a/README.md +++ b/README.md @@ -28,13 +28,14 @@ Currently the following service providers are supported: - [Abfall.IO / AbfallPlus.de](./doc/source/abfall_io.md) - [Abfall_Kreis_Tuebingen.de](./doc/source/abfall_kreis_tuebingen_de.md) +- [AbfallNavi.de (RegioIT.de)](./doc/source/abfallnavi_de.md) - [Abfallwirtschaft Stuttgart](./doc/source/stuttgard_de.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) - [Muellmax.de](./doc/source/muellmax_de.md) -- [RegioIT.de / AbfallNavi](./doc/source/regioit_de.md) +- [RegioIT.de / AbfallNavi [deprecated]](./doc/source/regioit_de.md) - [Stadtreinigung.Hamburg](./doc/source/stadtreinigung_hamburg.md) ## Configuration via configuration.yaml diff --git a/custom_components/waste_collection_schedule/package/source/abfallnavi_de.py b/custom_components/waste_collection_schedule/package/source/abfallnavi_de.py new file mode 100644 index 00000000..1509805e --- /dev/null +++ b/custom_components/waste_collection_schedule/package/source/abfallnavi_de.py @@ -0,0 +1,55 @@ +import requests +import datetime +import icalendar +import json +from collections import OrderedDict + +from ..helpers import CollectionAppointment + + +DESCRIPTION = "Source for AbfallNavi (= regioit.de) based services" +URL = "https://www.regioit.de" +TEST_CASES = OrderedDict( + [ + ( + "Aachen, Abteiplatz 7", + {"service": "aachen", "strasse": 5985352, "hausnummer": 5985357}, + ), + ("Lindlar, Aggerweg", {"service": "lindlar", "strasse": 56076}), + ("Roetgen, Am Sportplatz 2", {"service": "roe", "strasse": 52073}), + ] +) + + +class Source: + def __init__(self, service, strasse, hausnummer=None): + self._url = f"https://{service}-abfallapp.regioit.de/abfall-app-{service}/rest" + if hausnummer is not None: + self._url += f"/hausnummern/{hausnummer}" + else: + self._url += f"/strassen/{strasse}" + + def fetch(self): + # get fraktionen + r = requests.get(f"{self._url}/fraktionen") + r.encoding = "utf-8" # requests doesn't guess the encoding correctly + fraktionen_list = json.loads(r.text) + fraktionen = {} + for fraktion in fraktionen_list: + fraktionen[fraktion["id"]] = fraktion["name"] + + # retrieve appointments + args = [] + for f in fraktionen.keys(): + args.append(("fraktion", f)) + + r = requests.get(f"{self._url}/termine", params=args) + results = json.loads(r.text) + + entries = [] + for r in results: + date = datetime.datetime.strptime(r["datum"], "%Y-%m-%d").date() + fraktion = fraktionen[r["bezirk"]["fraktionId"]] + entries.append(CollectionAppointment(date, fraktion)) + + return entries diff --git a/custom_components/waste_collection_schedule/package/wizard/abfallnavi_de.py b/custom_components/waste_collection_schedule/package/wizard/abfallnavi_de.py new file mode 100755 index 00000000..f9d09486 --- /dev/null +++ b/custom_components/waste_collection_schedule/package/wizard/abfallnavi_de.py @@ -0,0 +1,99 @@ +#!/usr/bin/python3 + +import inquirer +import requests +import json + + +def main(): + # select service + service_choices = [ + ("Aachen", "aachen"), + ("AWA Entsorgungs GmbH", "zew2"), + ("Bergisch Gladbach", "aw-bgl2"), + ("Bergischer Abfallwirtschaftverbund", "bav"), + ("Dinslaken", "din"), + ("Dorsten", "dorsten"), + ("Gütersloh", "gt2"), + ("Halver", "hlv"), + ("Kreis Coesfeld", "coe"), + ("Kreis Heinsberg", "krhs"), + ("Kreis Pinneberg", "pi"), + ("Kreis Warendorf", "krwaf"), + ("Lindlar", "lindlar"), + ("Lüdenscheid", "stl"), + ("Norderstedt", "nds"), + ("Nürnberg", "nuernberg"), + ("Roetgen", "roe"), + ("EGW Westmünsterland", "wml2"), + ] + questions = [ + inquirer.List( + "service", + choices=service_choices, + message="Select service provider for district [Landkreis]", + ) + ] + answers = inquirer.prompt(questions) + + SERVICE_URL = f"https://{answers['service']}-abfallapp.regioit.de/abfall-app-{answers['service']}" + + # get cities + r = requests.get(f"{SERVICE_URL}/rest/orte") + r.encoding = "utf-8" # requests doesn't guess the encoding correctly + cities = json.loads(r.text) + city_choices = [] + for city in cities: + city_choices.append((city["name"], city["id"])) + + questions = [ + inquirer.List( + "city_id", choices=city_choices, message="Select municipality [Kommune/Ort]" + ) + ] + ort = inquirer.prompt(questions)["city_id"] + + # get streets + r = requests.get(f"{SERVICE_URL}/rest/orte/{ort}/strassen") + r.encoding = "utf-8" # requests doesn't guess the encoding correctly + streets = json.loads(r.text) + street_choices = [] + for street in streets: + street_choices.append((street["name"], street["id"])) + + questions = [ + inquirer.List("strasse", choices=street_choices, message="Select street") + ] + answers.update(inquirer.prompt(questions)) + + # get list of house numbers + r = requests.get(f"{SERVICE_URL}/rest/strassen/{answers['strasse']}") + r.encoding = "utf-8" # requests doesn't guess the encoding correctly + house_numbers = json.loads(r.text) + house_number_choices = [] + for hausNr in house_numbers.get("hausNrList", {}): + # {"id":5985445,"name":"Adalbert-Stifter-Straße","hausNrList":[{"id":5985446,"nr":"1"}, + house_number_choices.append((hausNr["nr"], hausNr["id"])) + + if len(house_number_choices) > 0: + questions = [ + inquirer.List( + "hausnummer", + 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: abfallnavi_de") + print(" args:") + for key, value in answers.items(): + print(f" {key}: {value}") + + +if __name__ == "__main__": + main() diff --git a/doc/source/abfallnavi_de.md b/doc/source/abfallnavi_de.md new file mode 100644 index 00000000..a125c74e --- /dev/null +++ b/doc/source/abfallnavi_de.md @@ -0,0 +1,45 @@ +# AbfallNavi.de + +Support for schedules provided by [Abfallnavi.de](https://www.abfallnavi.de). The service is hosted under [regioit.de](https://regioit.de). + +## Configuration via configuration.yaml + +```yaml +waste_collection_schedule: + sources: + - name: abfallnavi_de + args: + service: SERVICE + strasse: STRASSE + hausnummer: hausnummer +``` + +### Configuration Variables + +**service**
+*(string) (required)* + +**strasse**
+*(integer) (required)* + +**hausnummer**
+*(integer) (optional)* + +## Example + +```yaml +waste_collection_schedule: + sources: + - name: abfallnavi_de + args: + service: lindlar + strasse: 53585 +``` + +## 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/abfallnavi_de.py](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/custom_components/waste_collection_schedule/package/wizard/abfallnavi_de.py). + +Just run this script from a shell and answer the questions. \ No newline at end of file diff --git a/doc/source/regioit_de.md b/doc/source/regioit_de.md index 607448b9..6c539118 100644 --- a/doc/source/regioit_de.md +++ b/doc/source/regioit_de.md @@ -1,5 +1,7 @@ # RegioIT.de / AbfallNavi +NOTE: THIS SOURCE IS DEPRECATED! Use [Abfallnavi.de](./abfallnavi_de.md) instead! + Support for schedules provided by [RegioIT.de](https://www.regioit.de). The official service uses the name **AbfallNavi** instead. ## Configuration via configuration.yaml diff --git a/info.md b/info.md index 4d97aaab..f49650d5 100644 --- a/info.md +++ b/info.md @@ -30,11 +30,12 @@ Currently the following service providers are supported: - [Abfall.IO / AbfallPlus.de](./doc/source/abfall_io.md) - [Abfall_Kreis_Tuebingen.de](./doc/source/abfall_kreis_tuebingen_de.md) +- [AbfallNavi (RegioIT.de)](./doc/source/abfallnavi_de.md) - [Abfallwirtschaft Stuttgart](./doc/source/stuttgard_de.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) - [Muellmax.de](./doc/source/muellmax_de.md) -- [RegioIT.de / AbfallNavi](./doc/source/regioit_de.md) +- [RegioIT.de / AbfallNavi [deprecated]](./doc/source/regioit_de.md) - [Stadtreinigung.Hamburg](./doc/source/stadtreinigung_hamburg.md)