Improve meinawb_de, create docs

This commit is contained in:
Andre Basche
2022-12-30 23:36:25 +01:00
parent fdc06a5e04
commit 24220aff05
4 changed files with 107 additions and 34 deletions

View File

@@ -84,6 +84,7 @@ Waste collection schedules in the following formats and countries are supported.
- [Abfallwirtschaft Werra-Meißner-Kreis](/doc/source/zva_wmk_de.md) / zva-wmk.de
- [Abfallwirtschaft Zollernalbkreis](/doc/source/abfall_zollernalbkreis_de.md) / abfallkalender-zak.de
- [Abfallwirtschaftsbetrieb Esslingen](/doc/source/awb_es_de.md) / awb-es.de
- [Abfallwirtschaftsbetrieb Landkreis Ahrweiler](/doc/source/meinawb_de.md) / meinawb.de
- [ART Trier](/doc/source/art_trier_de.md) / art-trier.de
- [AWB Bad Kreuznach](/doc/source/awb_bad_kreuznach_de.md) / app.awb-bad-kreuznach.de
- [AWB Köln](/doc/source/awbkoeln_de.md) / awbkoeln.de

View File

@@ -1,4 +1,5 @@
import html
import logging
import random
import re
import string
@@ -7,58 +8,83 @@ from datetime import datetime
import requests
from waste_collection_schedule import Collection
TITLE = "meinawb.de"
_LOGGER = logging.getLogger(__name__)
TITLE = "Abfallwirtschaftsbetrieb Landkreis Ahrweiler"
URL = "https://www.meinawb.de"
DESCRIPTION = "Bin collection service from Kreis Ahrweiler/Germany"
URL = "https://extdienste01.koblenz.de/WasteManagementAhrweiler/WasteManagementServlet"
API_URL = "https://extdienste01.koblenz.de/WasteManagementAhrweiler/WasteManagementServlet"
city = "Bad Neuenahr-Ahrweiler"
street = "Hauptstrasse"
houseno = "91"
YEAR = "2023"
ICON_MAP = {
"Restabfall": "mdi:trash-can",
"Bioabfall": "mdi:leaf",
"Altpapier": "mdi:package-variant",
"Verpackungen": "mdi:recycle",
"Grünabfall / Weihnachtsbäume": "mdi:forest",
}
TYPES = {
"RM": "Restabfall",
"RG": "Restabfall",
"BM": "Bioabfall",
"PA": "Altpapier",
"GT": "Verpackungen",
"GS": "Grünabfall / Weihnachtsbäume",
}
ICONS = {
"RM": {"icon": "mdi:trash-can", "t": "Restabfall"},
"RG2": {"icon": "mdi:trash-can", "t": "Restabfall Gewerbe / PLUS-Tonne"},
"BM": {"icon": "mdi:leaf", "t": "Bioabfall"},
"PA": {"icon": "mdi:package-variant", "t": "Altpapier"},
"GT": {"icon": "mdi:recycle", "t": "Verpackungen"},
"GS": {"icon": "mdi:forest", "t": "Grünabfall / Weihnachtsbäume"},
TEST_CASES = {
"Oberzissen": {"city": "Oberzissen", "street": "Lindenstrasse", "house_number": "1"},
"Niederzissen": {"city": "Niederzissen", "street": "Brohltalstrasse", "house_number": "189"},
"Bad Neuenahr": {"city": "Bad Neuenahr-Ahrweiler", "street": "Hauptstrasse", "house_number": "91",
"address_suffix": "A"},
}
class Source:
def __init__(self, city, street, house_number):
def __init__(self, city, street, house_number, address_suffix=""):
self._city = city
self._street = street
self._house_number = house_number
self._address_suffix = address_suffix
def __str__(self):
return f"{self._city} {self._street} {self._house_number} {self._address_suffix}"
@staticmethod
def parse_data(data, boundary):
def _parse_data(data, boundary):
result = ""
for key, value in data.items():
result += f'------WebKitFormBoundary{boundary}\r\nContent-Disposition: form-data; name="{key}"\r\n\r\n{value}\r\n'
result += f"------WebKitFormBoundary{boundary}--\r\n"
result += f'------{boundary}\r\nContent-Disposition: form-data; name="{key}"\r\n\r\n{value}\r\n'
result += f"------{boundary}--\r\n"
return result.encode()
@staticmethod
def parse_response_input(text):
def _parse_response_input(text):
parsed = re.findall("<INPUT\\sNAME=\"([^\"]+?)\"\\sID=\"[^\"]+?\"(?:\\sVALUE=\"([^\"]*?)\")?", text)
return {k: v for k, v in parsed}
def fetch(self):
session = requests.Session()
response = session.get(f"{URL}?SubmitAction=wasteDisposalServices&InFrameMode=true", verify=False)
calendars = re.findall('NAME="Zeitraum" VALUE=\"([^\"]+?)\"', response.text)
year = next(html.unescape(t) for t in calendars if YEAR in html.unescape(t))
boundary = "".join(random.sample(string.ascii_letters + string.digits, 16))
headers = {'Content-Type': f'multipart/form-data; boundary=----WebKitFormBoundary{boundary}'}
payload = self.parse_response_input(response.text)
payload.update({"SubmitAction": "CITYCHANGED", "Ort": self._city, "Strasse": "", "Zeitraum": year})
response = session.post(URL, headers=headers, data=self.parse_data(payload, boundary), verify=False)
payload = self.parse_response_input(response.text)
def _get_dates(self, session, payload, calendar):
boundary = "WebKitFormBoundary" + "".join(random.sample(string.ascii_letters + string.digits, 16))
headers = {'Content-Type': f'multipart/form-data; boundary=----{boundary}'}
payload.update({"SubmitAction": "CITYCHANGED", "Ort": self._city, "Strasse": "", "Zeitraum": calendar})
response = session.post(API_URL, headers=headers, data=self._parse_data(payload, boundary))
payload = self._parse_response_input(response.text)
payload.update(
{"SubmitAction": "forward", "Ort": self._city, "Strasse": self._street, "Hausnummer": self._house_number,
"Zeitraum": year})
response = session.post(URL, headers=headers, data=self.parse_data(payload, boundary), verify=False)
dates = re.findall('<P ID="TermineDatum([0-9A-Z]+)_\\d+">[A-Z][a-z]. ([0-9.]{10}) </P>', response.text)
return [Collection(datetime.strptime(date, "%d.%m.%Y").date(), **ICONS[bin_type]) for bin_type, date in dates]
"Hausnummerzusatz": self._address_suffix, "Zeitraum": html.unescape(calendar)})
response = session.post(API_URL, headers=headers, data=self._parse_data(payload, boundary))
if error := re.findall("informationItemsText_1\">([^<]+?)<", response.text):
_LOGGER.warning(f"{self} - {html.unescape(error[0])}")
return []
return re.findall('<P ID="TermineDatum([0-9A-Z]+)_\\d+">[A-Z][a-z]. ([0-9.]{10}) </P>', response.text)
def fetch(self):
session = requests.Session()
response = session.get(f"{API_URL}?SubmitAction=wasteDisposalServices&InFrameMode=true")
payload = self._parse_response_input(response.text)
calendars = re.findall('NAME="Zeitraum" VALUE=\"([^\"]+?)\"', response.text)
dates = [date for calendar in calendars for date in self._get_dates(session, payload, calendar)]
entries = []
for bin_type, date in dates:
name = TYPES[next(x for x in list(TYPES) if x in bin_type)]
entries.append(Collection(datetime.strptime(date, "%d.%m.%Y").date(), name, ICON_MAP[name]))
return entries

46
doc/source/meinawb_de.md Normal file
View File

@@ -0,0 +1,46 @@
# Abfallwirtschaftsbetrieb Landkreis Ahrweiler (AWB)
Support for schedules provided by [Abfallwirtschaftsbetrieb Landkreis Ahrweiler](https://www.meinawb.de/) located in Rhineland Palatinate, Germany.
## Configuration via configuration.yaml
```yaml
waste_collection_schedule:
sources:
- name: meinawb_de
args:
city: CITY
street: STREET
house_number: HNR
address_suffix: HNR_SUFFIX
```
### Configuration Variables
**city**
*(string) (required)*
**street**
*(string) (required)*
**house_number**
*(integer) (required)*
**address_suffix**
*(string) (optional) (default: "")*
## Example
```yaml
waste_collection_schedule:
sources:
- name: meinawb_de
args:
city: Oberzissen
street: Ackerstrasse
address_suffix: 1
```
## How to get the source arguments
The arguments are your address. The input validation is a bit petty, so make sure you write it exactly like in the [web form](https://www.meinawb.de/abfuhrtermine). For troubleshooting, have a look in the home assistant logs.

View File

@@ -20,7 +20,7 @@ Waste collection schedules from service provider web sites are updated daily, de
| Austria | Burgenländischer Müllverband, infeo, Stadtservice Korneuburg, Umweltprofis, WSZ Moosburg |
| Belgium | Hygea, Recycle! |
| Canada | City of Toronto |
| Germany | Abfall Stuttgart, Abfall.IO / AbfallPlus, Abfallkalender Würzburg, AbfallNavi (RegioIT.de), Abfalltermine Forchheim, Abfallwirtschaft Alb-Donau-Kreis, Abfallwirtschaft Landkreis Harburg, Abfallwirtschaft Landkreis Wolfenbüttel, Abfallwirtschaft Neckar-Odenwald-Kreis, Abfallwirtschaft Rendsburg, Abfallwirtschaft Südholstein, Abfallwirtschaft Werra-Meißner-Kreis, Abfallwirtschaft Zollernalbkreis, Abfallwirtschaftsbetrieb Esslingen, ART Trier, AWB Bad Kreuznach, AWB Köln, AWB Oldenburg, AWIDO Online, Berlin Recycling, Berliner Stadtreinigungsbetriebe, Bielefeld, Bogenschütz Entsorgung, Bürgerportal, C-Trace, EGN Abfallkalender, Jumomind, KAEV Niederlausitz, Kreiswirtschaftsbetriebe Goslar, KV Cochem-Zell, KWU Entsorgung Landkreis Oder-Spree, Landkreis Erlangen-Höchstadt, Landkreis Nordwestmecklenburg, Landkreis Rhön Grabfeld, Landkreis Schwäbisch Hall, Landkreis Wittmund, MZV Bidenkopf, Müllmax, Neunkirchen Siegerland, RegioEntsorgung Städteregion Aachen, Rhein-Hunsrück Entsorgung (RHE), Sector 27 - Datteln, Marl, Oer-Erkenschwick, Stadt Willich, Stadtreinigung Dresden, Stadtreinigung Hamburg, Stadtreinigung Leipzig, StadtService Brühl, Städteservice Raunheim Rüsselsheim, Südbrandenburgischer Abfallzweckverband, Wermelskirchen, Wolfsburger Abfallwirtschaft und Straßenreinigung |
| Germany | Abfall Stuttgart, Abfall.IO / AbfallPlus, Abfallkalender Würzburg, AbfallNavi (RegioIT.de), Abfalltermine Forchheim, Abfallwirtschaft Alb-Donau-Kreis, Abfallwirtschaft Landkreis Harburg, Abfallwirtschaft Landkreis Wolfenbüttel, Abfallwirtschaft Neckar-Odenwald-Kreis, Abfallwirtschaft Rendsburg, Abfallwirtschaft Südholstein, Abfallwirtschaft Werra-Meißner-Kreis, Abfallwirtschaft Zollernalbkreis, Abfallwirtschaftsbetrieb Esslingen, Abfallwirtschaftsbetrieb Landkreis Ahrweiler, ART Trier, AWB Bad Kreuznach, AWB Köln, AWB Oldenburg, AWIDO Online, Berlin Recycling, Berliner Stadtreinigungsbetriebe, Bielefeld, Bogenschütz Entsorgung, Bürgerportal, C-Trace, EGN Abfallkalender, Jumomind, KAEV Niederlausitz, Kreiswirtschaftsbetriebe Goslar, KV Cochem-Zell, KWU Entsorgung Landkreis Oder-Spree, Landkreis Erlangen-Höchstadt, Landkreis Nordwestmecklenburg, Landkreis Rhön Grabfeld, Landkreis Schwäbisch Hall, Landkreis Wittmund, MZV Bidenkopf, Müllmax, Neunkirchen Siegerland, RegioEntsorgung Städteregion Aachen, Rhein-Hunsrück Entsorgung (RHE), Sector 27 - Datteln, Marl, Oer-Erkenschwick, Stadt Willich, Stadtreinigung Dresden, Stadtreinigung Hamburg, Stadtreinigung Leipzig, StadtService Brühl, Städteservice Raunheim Rüsselsheim, Südbrandenburgischer Abfallzweckverband, Wermelskirchen, Wolfsburger Abfallwirtschaft und Straßenreinigung |
| Lithuania | Kauno švara |
| Netherlands | ACV Group, Alpen an den Rijn, Area Afval, Avalex, Avri, Bar Afvalbeheer, Cyclus NV, Dar, Den Haag, GAD, Gemeente Almere, Gemeente Berkelland, Gemeente Cranendonck, Gemeente Hellendoorn, Gemeente Lingewaard, Gemeente Meppel, Gemeente Middelburg + Vlissingen, Gemeente Peel en Maas, Gemeente Schouwen-Duiveland, Gemeente Sudwest-Fryslan, Gemeente Venray, Gemeente Voorschoten, Gemeente Wallre, Gemeente Westland, HVC Groep, Meerlanden, Mijn Blink, PreZero, Purmerend, RAD BV, Reinigingsbedrijf Midden Nederland, Reinis, Spaarne Landen, Stadswerk 072, Twente Milieu, Waardlanden, Ximmio, ZRD |
| New Zealand | Auckland Council, Christchurch City Council, Gore, Invercargill & Southland, Horowhenua District Council, Waipa District Council, Wellington City Council |