We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug]: calculating "date 2" on Feb.29 ("now.year + 1" = 2025-02-29 does not exist!)
### I Have A Problem With:

The integration in general

### What's Your Problem

The date calculation for synchronizing the calendar has an error in the leap year (02/29).

### Source (if relevant)

_No response_

### Logs

```Shell
Logger: waste_collection_schedule.source_shell
Source: custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py:136
Integration: waste_collection_schedule (documentation)
First occurred: 08:35:09 (1 occurrences)
Last logged: 08:35:09
fetch failed for source Abfall.IO / AbfallPlus: Traceback (most recent call last): File "/config/custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py", line 134, in fetch entries = self._source.fetch() ^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py", line 145, in fetch date2 = now.replace(year=now.year + 1) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ValueError: day is out of range for month
```


### Relevant Configuration

_No response_

### Checklist Source Error

- [X] Use the example parameters for your source (often available in the documentation) (don't forget to restart Home Assistant after changing the configuration)
- [X] Checked that the website of your service provider is still working
- [X] Tested my attributes on the service provider website (if possible)
- [X] I have tested with the latest version of the integration (master) (for HACS in the 3 dot menu of the integration click on "Redownload" and choose master as version)

### Checklist Sensor Error

- [X] Checked in the Home Assistant Calendar tab if the event names match the types names (if types argument is used)

### Required

- [ ] I have searched past (closed AND opened) issues to see if this bug has already been reported, and it hasn't been.
- [X] I understand that people give their precious time for free, and thus I've done my very best to make this problem as easy as possible to investigate.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py`
Content:
```
1 import datetime
2 import logging
3 import re
4 from html.parser import HTMLParser
5 
6 import requests
7 from waste_collection_schedule import Collection  # type: ignore[attr-defined]
8 from waste_collection_schedule.service.AbfallIO import SERVICE_MAP
9 from waste_collection_schedule.service.ICS import ICS
10 
11 TITLE = "Abfall.IO / AbfallPlus"
12 DESCRIPTION = (
13     "Source for AbfallPlus.de waste collection. Service is hosted on abfall.io."
14 )
15 URL = "https://www.abfallplus.de"
16 COUNTRY = "de"
17 
18 
19 def EXTRA_INFO():
20     return [{"title": s["title"], "url": s["url"]} for s in SERVICE_MAP]
21 
22 
23 TEST_CASES = {
24     "Waldenbuch": {
25         "key": "8215c62763967916979e0e8566b6172e",
26         "f_id_kommune": 2999,
27         "f_id_strasse": 1087,
28         # "f_abfallarten": [50, 53, 31, 299, 328, 325]
29     },
30     "Landshut": {
31         "key": "bd0c2d0177a0849a905cded5cb734a6f",
32         "f_id_kommune": 2655,
33         "f_id_bezirk": 2655,
34         "f_id_strasse": 763,
35         # "f_abfallarten": [31, 17, 19, 218]
36     },
37     "Schoenmackers": {
38         "key": "e5543a3e190cb8d91c645660ad60965f",
39         "f_id_kommune": 3682,
40         "f_id_strasse": "3682adenauerplatz",
41         "f_id_strasse_hnr": "20417",
42         # "f_abfallarten": [691,692,696,695,694,701,700,693,703,704,697,699],
43     },
44     "Freudenstadt": {
45         "key": "595f903540a36fe8610ec39aa3a06f6a",
46         "f_id_kommune": 3447,
47         "f_id_bezirk": 22017,
48         "f_id_strasse": 22155,
49     },
50     "Ludwigshafen am Rhein": {
51         "key": "6efba91e69a5b454ac0ae3497978fe1d",
52         "f_id_kommune": "5916",
53         "f_id_strasse": "5916abteistrasse",
54         "f_id_strasse_hnr": 33,
55     },
56     "Traunstein": {
57         "key": "279cc5db4db838d1cfbf42f6f0176a90",
58         "f_id_kommune": "2911",
59         "f_id_strasse": "2374",
60     },
61     "AWB Limburg-Weilburg": {
62         "key": "0ff491ffdf614d6f34870659c0c8d917",
63         "f_id_kommune": 6031,
64         "f_id_strasse": 621,
65         "f_id_strasse_hnr": 872,
66         "f_abfallarten": [27, 28, 17, 67],
67     },
68     "ALBA Berlin": {
69         "key": "9583a2fa1df97ed95363382c73b41b1b",
70         "f_id_kommune": 3227,
71         "f_id_strasse": 3475,
72         "f_id_strasse_hnr": 185575,
73     },
74 }
75 _LOGGER = logging.getLogger(__name__)
76 
77 MODUS_KEY = "d6c5855a62cf32a4dadbc2831f0f295f"
78 HEADERS = {"user-agent": "Mozilla/5.0 (xxxx Windows NT 10.0; Win64; x64)"}
79 
80 
81 # Parser for HTML input (hidden) text
82 class HiddenInputParser(HTMLParser):
83     def __init__(self):
84         super().__init__()
85         self._args = {}
86 
87     @property
88     def args(self):
89         return self._args
90 
91     def handle_starttag(self, tag, attrs):
92         if tag == "input":
93             d = dict(attrs)
94             if d["type"] == "hidden":
95                 self._args[d["name"]] = d["value"]
96 
97 
98 class Source:
99     def __init__(
100         self,
101         key,
102         f_id_kommune,
103         f_id_strasse,
104         f_id_bezirk=None,
105         f_id_strasse_hnr=None,
106         f_abfallarten=[],
107     ):
108         self._key = key
109         self._kommune = f_id_kommune
110         self._bezirk = f_id_bezirk
111         self._strasse = f_id_strasse
112         self._strasse_hnr = f_id_strasse_hnr
113         self._abfallarten = f_abfallarten  # list of integers
114         self._ics = ICS()
115 
116     def fetch(self):
117         # get token
118         params = {"key": self._key, "modus": MODUS_KEY, "waction": "init"}
119 
120         r = requests.post("https://api.abfall.io", params=params, headers=HEADERS)
121 
122         # add all hidden input fields to form data
123         # There is one hidden field which acts as a token:
124         # It consists of a UUID key and a UUID value.
125         p = HiddenInputParser()
126         p.feed(r.text)
127         args = p.args
128 
129         args["f_id_kommune"] = self._kommune
130         args["f_id_strasse"] = self._strasse
131 
132         if self._bezirk is not None:
133             args["f_id_bezirk"] = self._bezirk
134 
135         if self._strasse_hnr is not None:
136             args["f_id_strasse_hnr"] = self._strasse_hnr
137 
138         for i in range(len(self._abfallarten)):
139             args[f"f_id_abfalltyp_{i}"] = self._abfallarten[i]
140 
141         args["f_abfallarten_index_max"] = len(self._abfallarten)
142         args["f_abfallarten"] = ",".join(map(lambda x: str(x), self._abfallarten))
143 
144         now = datetime.datetime.now()
145         date2 = now.replace(year=now.year + 1)
146         args["f_zeitraum"] = f"{now.strftime('%Y%m%d')}-{date2.strftime('%Y%m%d')}"
147 
148         params = {"key": self._key, "modus": MODUS_KEY, "waction": "export_ics"}
149 
150         # get csv file
151         r = requests.post(
152             "https://api.abfall.io", params=params, data=args, headers=HEADERS
153         )
154 
155         # parse ics file
156         r.encoding = "utf-8"  # requests doesn't guess the encoding correctly
157         ics_file = r.text
158 
159         # Remove all lines starting with <b
160         # This warning are caused for customers which use an extra radiobutton
161         # list to add special waste types:
162         # - AWB Limburg-Weilheim uses this list to select a "Sonderabfall <city>"
163         #   waste type. The warning could be removed by adding the extra config
164         #   option "f_abfallarten" with the following values [27, 28, 17, 67]
165         html_warnings = re.findall(r"\<b.*", ics_file)
166         if html_warnings:
167             ics_file = re.sub(r"\<br.*|\<b.*", "\\r", ics_file)
168             # _LOGGER.warning("Html tags removed from ics file: " + ', '.join(html_warnings))
169 
170         dates = self._ics.convert(ics_file)
171 
172         entries = []
173         for d in dates:
174             entries.append(Collection(d[0], d[1]))
175         return entries
176
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py
--- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py
@@ -142,7 +142,7 @@
         args["f_abfallarten"] = ",".join(map(lambda x: str(x), self._abfallarten))
 
         now = datetime.datetime.now()
-        date2 = now.replace(year=now.year + 1)
+        date2 = now + datetime.timedelta(days=365)
         args["f_zeitraum"] = f"{now.strftime('%Y%m%d')}-{date2.strftime('%Y%m%d')}"
 
         params = {"key": self._key, "modus": MODUS_KEY, "waction": "export_ics"}

{"golden_diff": "diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py\n--- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py\n+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py\n@@ -142,7 +142,7 @@\n         args[\"f_abfallarten\"] = \",\".join(map(lambda x: str(x), self._abfallarten))\n \n         now = datetime.datetime.now()\n-        date2 = now.replace(year=now.year + 1)\n+        date2 = now + datetime.timedelta(days=365)\n         args[\"f_zeitraum\"] = f\"{now.strftime('%Y%m%d')}-{date2.strftime('%Y%m%d')}\"\n \n         params = {\"key\": self._key, \"modus\": MODUS_KEY, \"waction\": \"export_ics\"}\n", "issue": "[Bug]: calculating \"date 2\" on Feb.29 (\"now.year + 1\" = 2025-02-29 does not exist!)\n### I Have A Problem With:\n\nThe integration in general\n\n### What's Your Problem\n\nThe date calculation for synchronizing the calendar has an error in the leap year (02/29).\n\n### Source (if relevant)\n\n_No response_\n\n### Logs\n\n```Shell\nLogger: waste_collection_schedule.source_shell\r\nSource: custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py:136\r\nIntegration: waste_collection_schedule (documentation)\r\nFirst occurred: 08:35:09 (1 occurrences)\r\nLast logged: 08:35:09\r\nfetch failed for source Abfall.IO / AbfallPlus: Traceback (most recent call last): File \"/config/custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py\", line 134, in fetch entries = self._source.fetch() ^^^^^^^^^^^^^^^^^^^^ File \"/config/custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py\", line 145, in fetch date2 = now.replace(year=now.year + 1) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ValueError: day is out of range for month\n```\n\n\n### Relevant Configuration\n\n_No response_\n\n### Checklist Source Error\n\n- [X] Use the example parameters for your source (often available in the documentation) (don't forget to restart Home Assistant after changing the configuration)\n- [X] Checked that the website of your service provider is still working\n- [X] Tested my attributes on the service provider website (if possible)\n- [X] I have tested with the latest version of the integration (master) (for HACS in the 3 dot menu of the integration click on \"Redownload\" and choose master as version)\n\n### Checklist Sensor Error\n\n- [X] Checked in the Home Assistant Calendar tab if the event names match the types names (if types argument is used)\n\n### Required\n\n- [ ] I have searched past (closed AND opened) issues to see if this bug has already been reported, and it hasn't been.\n- [X] I understand that people give their precious time for free, and thus I've done my very best to make this problem as easy as possible to investigate.\n", "before_files": [{"content": "import datetime\nimport logging\nimport re\nfrom html.parser import HTMLParser\n\nimport requests\nfrom waste_collection_schedule import Collection  # type: ignore[attr-defined]\nfrom waste_collection_schedule.service.AbfallIO import SERVICE_MAP\nfrom waste_collection_schedule.service.ICS import ICS\n\nTITLE = \"Abfall.IO / AbfallPlus\"\nDESCRIPTION = (\n    \"Source for AbfallPlus.de waste collection. Service is hosted on abfall.io.\"\n)\nURL = \"https://www.abfallplus.de\"\nCOUNTRY = \"de\"\n\n\ndef EXTRA_INFO():\n    return [{\"title\": s[\"title\"], \"url\": s[\"url\"]} for s in SERVICE_MAP]\n\n\nTEST_CASES = {\n    \"Waldenbuch\": {\n        \"key\": \"8215c62763967916979e0e8566b6172e\",\n        \"f_id_kommune\": 2999,\n        \"f_id_strasse\": 1087,\n        # \"f_abfallarten\": [50, 53, 31, 299, 328, 325]\n    },\n    \"Landshut\": {\n        \"key\": \"bd0c2d0177a0849a905cded5cb734a6f\",\n        \"f_id_kommune\": 2655,\n        \"f_id_bezirk\": 2655,\n        \"f_id_strasse\": 763,\n        # \"f_abfallarten\": [31, 17, 19, 218]\n    },\n    \"Schoenmackers\": {\n        \"key\": \"e5543a3e190cb8d91c645660ad60965f\",\n        \"f_id_kommune\": 3682,\n        \"f_id_strasse\": \"3682adenauerplatz\",\n        \"f_id_strasse_hnr\": \"20417\",\n        # \"f_abfallarten\": [691,692,696,695,694,701,700,693,703,704,697,699],\n    },\n    \"Freudenstadt\": {\n        \"key\": \"595f903540a36fe8610ec39aa3a06f6a\",\n        \"f_id_kommune\": 3447,\n        \"f_id_bezirk\": 22017,\n        \"f_id_strasse\": 22155,\n    },\n    \"Ludwigshafen am Rhein\": {\n        \"key\": \"6efba91e69a5b454ac0ae3497978fe1d\",\n        \"f_id_kommune\": \"5916\",\n        \"f_id_strasse\": \"5916abteistrasse\",\n        \"f_id_strasse_hnr\": 33,\n    },\n    \"Traunstein\": {\n        \"key\": \"279cc5db4db838d1cfbf42f6f0176a90\",\n        \"f_id_kommune\": \"2911\",\n        \"f_id_strasse\": \"2374\",\n    },\n    \"AWB Limburg-Weilburg\": {\n        \"key\": \"0ff491ffdf614d6f34870659c0c8d917\",\n        \"f_id_kommune\": 6031,\n        \"f_id_strasse\": 621,\n        \"f_id_strasse_hnr\": 872,\n        \"f_abfallarten\": [27, 28, 17, 67],\n    },\n    \"ALBA Berlin\": {\n        \"key\": \"9583a2fa1df97ed95363382c73b41b1b\",\n        \"f_id_kommune\": 3227,\n        \"f_id_strasse\": 3475,\n        \"f_id_strasse_hnr\": 185575,\n    },\n}\n_LOGGER = logging.getLogger(__name__)\n\nMODUS_KEY = \"d6c5855a62cf32a4dadbc2831f0f295f\"\nHEADERS = {\"user-agent\": \"Mozilla/5.0 (xxxx Windows NT 10.0; Win64; x64)\"}\n\n\n# Parser for HTML input (hidden) text\nclass HiddenInputParser(HTMLParser):\n    def __init__(self):\n        super().__init__()\n        self._args = {}\n\n    @property\n    def args(self):\n        return self._args\n\n    def handle_starttag(self, tag, attrs):\n        if tag == \"input\":\n            d = dict(attrs)\n            if d[\"type\"] == \"hidden\":\n                self._args[d[\"name\"]] = d[\"value\"]\n\n\nclass Source:\n    def __init__(\n        self,\n        key,\n        f_id_kommune,\n        f_id_strasse,\n        f_id_bezirk=None,\n        f_id_strasse_hnr=None,\n        f_abfallarten=[],\n    ):\n        self._key = key\n        self._kommune = f_id_kommune\n        self._bezirk = f_id_bezirk\n        self._strasse = f_id_strasse\n        self._strasse_hnr = f_id_strasse_hnr\n        self._abfallarten = f_abfallarten  # list of integers\n        self._ics = ICS()\n\n    def fetch(self):\n        # get token\n        params = {\"key\": self._key, \"modus\": MODUS_KEY, \"waction\": \"init\"}\n\n        r = requests.post(\"https://api.abfall.io\", params=params, headers=HEADERS)\n\n        # add all hidden input fields to form data\n        # There is one hidden field which acts as a token:\n        # It consists of a UUID key and a UUID value.\n        p = HiddenInputParser()\n        p.feed(r.text)\n        args = p.args\n\n        args[\"f_id_kommune\"] = self._kommune\n        args[\"f_id_strasse\"] = self._strasse\n\n        if self._bezirk is not None:\n            args[\"f_id_bezirk\"] = self._bezirk\n\n        if self._strasse_hnr is not None:\n            args[\"f_id_strasse_hnr\"] = self._strasse_hnr\n\n        for i in range(len(self._abfallarten)):\n            args[f\"f_id_abfalltyp_{i}\"] = self._abfallarten[i]\n\n        args[\"f_abfallarten_index_max\"] = len(self._abfallarten)\n        args[\"f_abfallarten\"] = \",\".join(map(lambda x: str(x), self._abfallarten))\n\n        now = datetime.datetime.now()\n        date2 = now.replace(year=now.year + 1)\n        args[\"f_zeitraum\"] = f\"{now.strftime('%Y%m%d')}-{date2.strftime('%Y%m%d')}\"\n\n        params = {\"key\": self._key, \"modus\": MODUS_KEY, \"waction\": \"export_ics\"}\n\n        # get csv file\n        r = requests.post(\n            \"https://api.abfall.io\", params=params, data=args, headers=HEADERS\n        )\n\n        # parse ics file\n        r.encoding = \"utf-8\"  # requests doesn't guess the encoding correctly\n        ics_file = r.text\n\n        # Remove all lines starting with <b\n        # This warning are caused for customers which use an extra radiobutton\n        # list to add special waste types:\n        # - AWB Limburg-Weilheim uses this list to select a \"Sonderabfall <city>\"\n        #   waste type. The warning could be removed by adding the extra config\n        #   option \"f_abfallarten\" with the following values [27, 28, 17, 67]\n        html_warnings = re.findall(r\"\\<b.*\", ics_file)\n        if html_warnings:\n            ics_file = re.sub(r\"\\<br.*|\\<b.*\", \"\\\\r\", ics_file)\n            # _LOGGER.warning(\"Html tags removed from ics file: \" + ', '.join(html_warnings))\n\n        dates = self._ics.convert(ics_file)\n\n        entries = []\n        for d in dates:\n            entries.append(Collection(d[0], d[1]))\n        return entries\n", "path": "custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py"}], "after_files": [{"content": "import datetime\nimport logging\nimport re\nfrom html.parser import HTMLParser\n\nimport requests\nfrom waste_collection_schedule import Collection  # type: ignore[attr-defined]\nfrom waste_collection_schedule.service.AbfallIO import SERVICE_MAP\nfrom waste_collection_schedule.service.ICS import ICS\n\nTITLE = \"Abfall.IO / AbfallPlus\"\nDESCRIPTION = (\n    \"Source for AbfallPlus.de waste collection. Service is hosted on abfall.io.\"\n)\nURL = \"https://www.abfallplus.de\"\nCOUNTRY = \"de\"\n\n\ndef EXTRA_INFO():\n    return [{\"title\": s[\"title\"], \"url\": s[\"url\"]} for s in SERVICE_MAP]\n\n\nTEST_CASES = {\n    \"Waldenbuch\": {\n        \"key\": \"8215c62763967916979e0e8566b6172e\",\n        \"f_id_kommune\": 2999,\n        \"f_id_strasse\": 1087,\n        # \"f_abfallarten\": [50, 53, 31, 299, 328, 325]\n    },\n    \"Landshut\": {\n        \"key\": \"bd0c2d0177a0849a905cded5cb734a6f\",\n        \"f_id_kommune\": 2655,\n        \"f_id_bezirk\": 2655,\n        \"f_id_strasse\": 763,\n        # \"f_abfallarten\": [31, 17, 19, 218]\n    },\n    \"Schoenmackers\": {\n        \"key\": \"e5543a3e190cb8d91c645660ad60965f\",\n        \"f_id_kommune\": 3682,\n        \"f_id_strasse\": \"3682adenauerplatz\",\n        \"f_id_strasse_hnr\": \"20417\",\n        # \"f_abfallarten\": [691,692,696,695,694,701,700,693,703,704,697,699],\n    },\n    \"Freudenstadt\": {\n        \"key\": \"595f903540a36fe8610ec39aa3a06f6a\",\n        \"f_id_kommune\": 3447,\n        \"f_id_bezirk\": 22017,\n        \"f_id_strasse\": 22155,\n    },\n    \"Ludwigshafen am Rhein\": {\n        \"key\": \"6efba91e69a5b454ac0ae3497978fe1d\",\n        \"f_id_kommune\": \"5916\",\n        \"f_id_strasse\": \"5916abteistrasse\",\n        \"f_id_strasse_hnr\": 33,\n    },\n    \"Traunstein\": {\n        \"key\": \"279cc5db4db838d1cfbf42f6f0176a90\",\n        \"f_id_kommune\": \"2911\",\n        \"f_id_strasse\": \"2374\",\n    },\n    \"AWB Limburg-Weilburg\": {\n        \"key\": \"0ff491ffdf614d6f34870659c0c8d917\",\n        \"f_id_kommune\": 6031,\n        \"f_id_strasse\": 621,\n        \"f_id_strasse_hnr\": 872,\n        \"f_abfallarten\": [27, 28, 17, 67],\n    },\n    \"ALBA Berlin\": {\n        \"key\": \"9583a2fa1df97ed95363382c73b41b1b\",\n        \"f_id_kommune\": 3227,\n        \"f_id_strasse\": 3475,\n        \"f_id_strasse_hnr\": 185575,\n    },\n}\n_LOGGER = logging.getLogger(__name__)\n\nMODUS_KEY = \"d6c5855a62cf32a4dadbc2831f0f295f\"\nHEADERS = {\"user-agent\": \"Mozilla/5.0 (xxxx Windows NT 10.0; Win64; x64)\"}\n\n\n# Parser for HTML input (hidden) text\nclass HiddenInputParser(HTMLParser):\n    def __init__(self):\n        super().__init__()\n        self._args = {}\n\n    @property\n    def args(self):\n        return self._args\n\n    def handle_starttag(self, tag, attrs):\n        if tag == \"input\":\n            d = dict(attrs)\n            if d[\"type\"] == \"hidden\":\n                self._args[d[\"name\"]] = d[\"value\"]\n\n\nclass Source:\n    def __init__(\n        self,\n        key,\n        f_id_kommune,\n        f_id_strasse,\n        f_id_bezirk=None,\n        f_id_strasse_hnr=None,\n        f_abfallarten=[],\n    ):\n        self._key = key\n        self._kommune = f_id_kommune\n        self._bezirk = f_id_bezirk\n        self._strasse = f_id_strasse\n        self._strasse_hnr = f_id_strasse_hnr\n        self._abfallarten = f_abfallarten  # list of integers\n        self._ics = ICS()\n\n    def fetch(self):\n        # get token\n        params = {\"key\": self._key, \"modus\": MODUS_KEY, \"waction\": \"init\"}\n\n        r = requests.post(\"https://api.abfall.io\", params=params, headers=HEADERS)\n\n        # add all hidden input fields to form data\n        # There is one hidden field which acts as a token:\n        # It consists of a UUID key and a UUID value.\n        p = HiddenInputParser()\n        p.feed(r.text)\n        args = p.args\n\n        args[\"f_id_kommune\"] = self._kommune\n        args[\"f_id_strasse\"] = self._strasse\n\n        if self._bezirk is not None:\n            args[\"f_id_bezirk\"] = self._bezirk\n\n        if self._strasse_hnr is not None:\n            args[\"f_id_strasse_hnr\"] = self._strasse_hnr\n\n        for i in range(len(self._abfallarten)):\n            args[f\"f_id_abfalltyp_{i}\"] = self._abfallarten[i]\n\n        args[\"f_abfallarten_index_max\"] = len(self._abfallarten)\n        args[\"f_abfallarten\"] = \",\".join(map(lambda x: str(x), self._abfallarten))\n\n        now = datetime.datetime.now()\n        date2 = now + datetime.timedelta(days=365)\n        args[\"f_zeitraum\"] = f\"{now.strftime('%Y%m%d')}-{date2.strftime('%Y%m%d')}\"\n\n        params = {\"key\": self._key, \"modus\": MODUS_KEY, \"waction\": \"export_ics\"}\n\n        # get csv file\n        r = requests.post(\n            \"https://api.abfall.io\", params=params, data=args, headers=HEADERS\n        )\n\n        # parse ics file\n        r.encoding = \"utf-8\"  # requests doesn't guess the encoding correctly\n        ics_file = r.text\n\n        # Remove all lines starting with <b\n        # This warning are caused for customers which use an extra radiobutton\n        # list to add special waste types:\n        # - AWB Limburg-Weilheim uses this list to select a \"Sonderabfall <city>\"\n        #   waste type. The warning could be removed by adding the extra config\n        #   option \"f_abfallarten\" with the following values [27, 28, 17, 67]\n        html_warnings = re.findall(r\"\\<b.*\", ics_file)\n        if html_warnings:\n            ics_file = re.sub(r\"\\<br.*|\\<b.*\", \"\\\\r\", ics_file)\n            # _LOGGER.warning(\"Html tags removed from ics file: \" + ', '.join(html_warnings))\n\n        dates = self._ics.convert(ics_file)\n\n        entries = []\n        for d in dates:\n            entries.append(Collection(d[0], d[1]))\n        return entries\n", "path": "custom_components/waste_collection_schedule/waste_collection_schedule/source/abfall_io.py"}]}