Repository: mampfes/hacs_waste_collection_schedule

Issue:
Add support for Trier/Irrel Rheinland Pfalz
Hey friends, hope you are doing well.

I want just too ask if it could be possible to add:

https://www.art-trier.de/eo/cms?_sprache=de&_bereich=artikel&_aktion=detail&idartikel=408001

Irrel and maybe more from the ART. 

This would be awesome. 

Thanks very much. 

Can I also buy a beer? Can we donate to this little project? 




Discussion:
Please try [ics](https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/ics.md) source.
Since I lived for a few years in this area, I just created an initial version of a native source for the ART Trier. The implementation is mostly done, I just need to test it with some more edge cases (there are quite a few for this source sadly) and write the documentation on how to set it up. I hope to come up with a pull request before Christmas. I will keep you posted about my progress.

Resolving patch:
diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/art_trier_de.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/art_trier_de.py
new file mode 100644
--- /dev/null
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/art_trier_de.py
@@ -0,0 +1,81 @@
+import contextlib
+from datetime import datetime
+from urllib.parse import quote
+from typing import Optional
+
+import requests
+from waste_collection_schedule import Collection  # type: ignore[attr-defined]
+from waste_collection_schedule.service.ICS import ICS
+
+TITLE = "Abfall ART Trier"
+DESCRIPTION = "Source for waste collection of ART Trier."
+URL = "https://www.art-trier.de"
+TEST_CASES = {
+    "Trier": {
+        "zip_code": "54296",
+        "district": "Stadt Trier, Universitätsring",
+    },  # # https://www.art-trier.de/ics-feed/54296_trier_universitaetsring_1-1800.ics
+    "Schweich": {
+        "zip_code": "54338",
+        "district": "Schweich (inkl. Issel)",
+    },  # https://www.art-trier.de/ics-feed/54338_schweich_inkl_issel_1-1800.ics
+    "Dreis": {
+        "zip_code": "54518",
+        "district": "Dreis",
+    },  # https://www.art-trier.de/ics-feed/54518_dreis_1-1800.ics
+    "Wittlich Marktplatz": {
+        "zip_code": "54516",
+        "district": "Wittlich, Marktplatz",
+    },  # https://www.art-trier.de/ics-feed/54516_wittlich_marktplatz_1-1800.ics
+    "Wittlich Wengerohr": {
+        "zip_code": "54516",
+        "district": "Wittlich-Wengerohr",
+    },  # https://www.art-trier.de/ics-feed/54516_wittlich%2Dwengerohr_1-1800.ics
+}
+
+API_URL = "https://www.art-trier.de/ics-feed"
+REMINDER_DAY = (
+    "0"  # The calendar event should be on the same day as the waste collection
+)
+REMINDER_TIME = "0600"  # The calendar event should start on any hour of the correct day, so this does not matter much
+ICON_MAP = {
+    "Altpapier": "mdi:package-variant",
+    "Restmüll": "mdi:trash-can",
+    "Gelber Sack": "mdi:recycle",
+}
+SPECIAL_CHARS = {
+    ord("ä"): "ae",
+    ord("ü"): "ue",
+    ord("ö"): "oe",
+    ord("ß"): "ss",
+    ord("("): "",
+    ord(")"): "",
+    ord("."): "",
+}
+
+
+class Source:
+    def __init__(self, district: str, zip_code: str):
+        self._district = quote(
+            district.lower()
+            .removeprefix("stadt ")
+            .replace(" ", "_")
+            .replace(",", "")
+            .translate(SPECIAL_CHARS)
+            .strip()
+        )
+        self._zip_code = zip_code
+        self._ics = ICS(regex=r"^A.R.T. Abfuhrtermin: (.*)", split_at=r" & ")
+
+    def fetch(self):
+        url = f"{API_URL}/{self._zip_code}_{self._district}_{REMINDER_DAY}-{REMINDER_TIME}.ics"
+
+        r = requests.get(url)
+        schedule = self._ics.convert(r.text)
+
+        return [
+            Collection(
+                date=entry[0], t=entry[1], icon=ICON_MAP.get(entry[1], "mdi:trash-can")
+            )
+            for entry in schedule
+        ]


Test patch: