mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 02:04:22 +01:00
Improve meinawb_de, create docs
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
46
doc/source/meinawb_de.md
Normal 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.
|
||||
2
info.md
2
info.md
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user