mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 04:06:03 +01:00
add awg_de
This commit is contained in:
@@ -1150,6 +1150,7 @@ If your service provider is not listed, feel free to open a [source request issu
|
||||
- [Würzburg](/doc/source/app_abfallplus_de.md) / Abfall+ App: wuerzburg
|
||||
- [ZAH Hildesheim](/doc/ics/zah_hildesheim_de.md) / zah-hildesheim.de
|
||||
- [ZAK Kempten](/doc/source/app_abfallplus_de.md) / Abfall+ App: abfallappzak
|
||||
- [ZAW Donau-Wald](/doc/source/awg_de.md) / awg.de
|
||||
- [ZAW-SR](/doc/source/app_abfallplus_de.md) / Abfall+ App: zawsr
|
||||
- [ZEW Zweckverband Entsorgungsregion West](/doc/source/abfallnavi_de.md) / zew-entsorgung.de
|
||||
- [ZfA Iserlohn](/doc/ics/zfa_iserlohn_de.md) / zfa-iserlohn.de
|
||||
|
||||
@@ -6420,6 +6420,11 @@
|
||||
"app_id": "de.k4systems.abfallappzak"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "ZAW Donau-Wald",
|
||||
"module": "awg_de",
|
||||
"default_params": {}
|
||||
},
|
||||
{
|
||||
"title": "ZAW-SR",
|
||||
"module": "app_abfallplus_de",
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
# This is a nearly 1:1 copy of the original file waste_collection_schedule/waste_collection_schedule/source/meinawb_de.py
|
||||
|
||||
import html
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
import string
|
||||
|
||||
import requests
|
||||
from waste_collection_schedule import Collection
|
||||
from waste_collection_schedule.service.ICS import ICS
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
TITLE = "ZAW Donau-Wald"
|
||||
DESCRIPTION = "Source for ZAW Donau-Wald."
|
||||
URL = "https://www.awg.de/"
|
||||
TEST_CASES = {
|
||||
"Achslach Aign 1 ": {"city": "Achslach", "street": "Aign", "hnr": "1"},
|
||||
"Böbrach Bärnerauweg 10A": {
|
||||
"city": "Böbrach",
|
||||
"street": "Bärnerauweg",
|
||||
"hnr": 10,
|
||||
"addition": "A",
|
||||
},
|
||||
"Am Bäckergütl 1, 94094 Malching": {
|
||||
"city": "Malching",
|
||||
"street": "Am Bäckergütl",
|
||||
"hnr": 1,
|
||||
"addition": "",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
ICON_MAP = {
|
||||
"Biotonne": "mdi:leaf",
|
||||
"Papiertonne": "mdi:package-variant",
|
||||
"Restmuelltonne": "mdi:trash-can",
|
||||
"Restmüllcontainer": "mdi:trash-can",
|
||||
"Papiercontainer": "mdi:package-variant",
|
||||
}
|
||||
|
||||
|
||||
API_URL = (
|
||||
"https://wastemanagement.awg.de/WasteManagementDonauwald/WasteManagementServlet"
|
||||
)
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(self, city, street, hnr, addition=""):
|
||||
self._city = city
|
||||
self._street = street
|
||||
self._house_number = hnr
|
||||
self._address_suffix = addition
|
||||
self._boundary = "WebKitFormBoundary" + "".join(
|
||||
random.sample(string.ascii_letters + string.digits, 16)
|
||||
)
|
||||
self._ics = ICS()
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f"{self._city} {self._street} {self._house_number} {self._address_suffix}"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _parse_data(data, boundary):
|
||||
result = ""
|
||||
for key, value in data.items():
|
||||
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):
|
||||
parsed = re.findall(
|
||||
'<INPUT\\sNAME="([^"]+?)"\\sID="[^"]+?"(?:\\sVALUE="([^"]*?)")?', text
|
||||
)
|
||||
return {k: v for k, v in parsed}
|
||||
|
||||
def _address(self):
|
||||
return {
|
||||
"Ort": self._city,
|
||||
"Strasse": self._street,
|
||||
"Hausnummer": self._house_number,
|
||||
"Hausnummerzusatz": self._address_suffix,
|
||||
}
|
||||
|
||||
def _headers(self):
|
||||
return {"Content-Type": f"multipart/form-data; boundary=----{self._boundary}"}
|
||||
|
||||
def _payload(self, last_request, action="", period="", **kwargs):
|
||||
payload = self._parse_response_input(last_request)
|
||||
payload.update({"SubmitAction": action, **kwargs})
|
||||
if period:
|
||||
payload.update({"Zeitraum": html.unescape(period)})
|
||||
return self._parse_data(payload, self._boundary)
|
||||
|
||||
def _get_dates(self, session, init_request, calendar=""):
|
||||
kwargs = {"Ort": self._city, "Strasse": ""}
|
||||
payload = self._payload(
|
||||
init_request, action="CITYCHANGED", period=calendar, **kwargs
|
||||
)
|
||||
city_response = session.post(API_URL, headers=self._headers(), data=payload)
|
||||
payload = self._payload(
|
||||
city_response.text, action="forward", period=calendar, **self._address()
|
||||
)
|
||||
final_response = session.post(API_URL, headers=self._headers(), data=payload)
|
||||
|
||||
payload = self._payload(
|
||||
final_response.text,
|
||||
action="filedownload_ICAL",
|
||||
period=calendar,
|
||||
**self._address(),
|
||||
)
|
||||
|
||||
ics_response = session.post(API_URL, headers=self._headers(), data=payload)
|
||||
return self._ics.convert(ics_response.text)
|
||||
|
||||
def fetch(self):
|
||||
session = requests.Session()
|
||||
init_request = session.get(
|
||||
f"{API_URL}?SubmitAction=wasteDisposalServices&InFrameMode=true"
|
||||
).text
|
||||
if calendars := re.findall('NAME="Zeitraum" VALUE="([^"]+?)"', init_request):
|
||||
dates = [
|
||||
date
|
||||
for calendar in calendars
|
||||
for date in self._get_dates(session, init_request, calendar)
|
||||
]
|
||||
else:
|
||||
dates = self._get_dates(session, init_request)
|
||||
entries = []
|
||||
for date, bin_type in dates:
|
||||
entries.append(
|
||||
Collection(date, bin_type.strip(), ICON_MAP.get(bin_type.strip()))
|
||||
)
|
||||
return entries
|
||||
58
doc/source/awg_de.md
Normal file
58
doc/source/awg_de.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# ZAW Donau-Wald
|
||||
|
||||
Support for schedules provided by [ZAW Donau-Wald](https://www.awg.de/), serving Regen, Deggendorf, Freyung-Grafenau, Passau, Germany.
|
||||
|
||||
## Configuration via configuration.yaml
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: awg_de
|
||||
args:
|
||||
city: CITY (Ort)
|
||||
street: STREET (Straße)
|
||||
hnr: "HOUSE NUMBER (Hausnummer)"
|
||||
addition: ADDITION (Hausnummerzusatz)
|
||||
|
||||
```
|
||||
|
||||
### Configuration Variables
|
||||
|
||||
**city**
|
||||
*(String) (required)*
|
||||
|
||||
**street**
|
||||
*(String) (required)*
|
||||
|
||||
**hnr**
|
||||
*(String) (required)*
|
||||
|
||||
**addition**
|
||||
*(String) (optional)*
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: awg_de
|
||||
args:
|
||||
city: Achslach
|
||||
street: Aign
|
||||
hnr: "1"
|
||||
```
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: awg_de
|
||||
args:
|
||||
city: Böbrach
|
||||
street: Bärnerauweg
|
||||
hnr: 10
|
||||
addition: "A"
|
||||
```
|
||||
|
||||
## How to get the source argument
|
||||
|
||||
Find the parameter of your address using [https://www.awg.de/abfallentsorgung/abfuhrkalender](https://www.awg.de/abfallentsorgung/abfuhrkalender) and write them exactly like on the web page.
|
||||
Reference in New Issue
Block a user