Repository: mampfes/hacs_waste_collection_schedule

Issue:
Telford and Wrekin Calendar stopped working
### I Have A Problem With:

A specific source

### What's Your Problem

Telford and wrekin calendar not showing any dates. looking at the log it looks like that the date format could be wrong.

### Source (if relevant)

telford_gov_uk

### 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: 17:47:44 (2 occurrences)
Last logged: 17:49:26

fetch failed for source Telford and Wrekin Council: 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/telford_gov_uk.py", line 93, in fetch date = datetime.datetime.strptime(datestring, "%A %d %B").date() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/_strptime.py", line 566, in _strptime_datetime return cls(*args) ^^^^^^^^^^ 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

- [X] 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.


Discussion:

Resolving patch:
diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/telford_gov_uk.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/telford_gov_uk.py
--- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/telford_gov_uk.py
+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/telford_gov_uk.py
@@ -1,8 +1,9 @@
-import json
 import datetime
+import json
 import re
+
 import requests
-from waste_collection_schedule import Collection 
+from waste_collection_schedule import Collection
 
 TITLE = "Telford and Wrekin Council"
 DESCRIPTION = "Source for telford.gov.uk, Telford and Wrekin Council, UK"
@@ -11,7 +12,7 @@
 TEST_CASES = {
     "10 Long Row Drive, Lawley": {"uprn": "000452097493"},
     "126 Dunsheath, Telford": {"post_code": "TF3 2DA", "name_number": "126"},
-    "11 Pinewoods, Telford": {"post_code": "TF10 9LN", "name_number": "11"}
+    "11 Pinewoods, Telford": {"post_code": "TF10 9LN", "name_number": "11"},
 }
 
 API_URLS = {
@@ -30,6 +31,7 @@
 # Path to the images provided by the council for the containers
 IMAGEPATH = "https://dac.telford.gov.uk/BinDayFinder/Content/BinIcons/"
 
+
 class Source:
     def __init__(self, post_code=None, name_number=None, uprn=None):
         self._post_code = post_code
@@ -40,73 +42,67 @@ def fetch(self):
         if not self._uprn:
             # look up the UPRN for the address
 
-            params = {
-                "postcode": self._post_code
-            }
-            r = requests.get(
-                API_URLS["address_search"],
-                params=params
-            )
-            
+            params = {"postcode": self._post_code}
+            r = requests.get(API_URLS["address_search"], params=params)
+
             r.raise_for_status()
 
             # Required to parse the returned JSON
             addresses = json.loads(r.json())
-            
-            for property in addresses['properties']:
-                if(property['PrimaryName'].lower() == self._name_number.lower()):
-                    self._uprn=property['UPRN']
+
+            for property in addresses["properties"]:
+                if property["PrimaryName"].lower() == self._name_number.lower():
+                    self._uprn = property["UPRN"]
 
             if not self._uprn:
                 raise Exception(
-                    f"Could not find address {self._post_code} {self._name_number}")
-        
+                    f"Could not find address {self._post_code} {self._name_number}"
+                )
+
         # Get the collection information
 
         params = {"uprn": self._uprn}
 
-        r = requests.get(
-            API_URLS["collection"],
-            params=params
-        )
+        r = requests.get(API_URLS["collection"], params=params)
 
         r.raise_for_status()
 
         x = json.loads(r.json())
-        collections = x['bincollections']
+        collections = x["bincollections"]
 
         entries = []
 
         if collections:
             for collection in collections:
-                    
                 # Parse the data as the council JSON API returns no year for the collections
                 # and so it needs to be calculated to format the date correctly
 
                 today = datetime.date.today()
                 year = today.year
-                
+
                 # Remove nd,rd,th,st from the date so it can be parsed
 
-                datestring = re.sub(r'(\d)(st|nd|rd|th)', r'\1', collection["nextDate"])
-            
-                date = datetime.datetime.strptime(datestring, "%A %d %B").date()
+                datestring = (
+                    re.sub(r"(\d)(st|nd|rd|th)", r"\1", collection["nextDate"])
+                    + " "
+                    + str(year)
+                )
+
+                date = datetime.datetime.strptime(datestring, "%A %d %B %Y").date()
 
                 # Calculate the year. As we only get collections 2 weeks in advance we can assume the current
                 # year unless the month is January in December where it will be next year
 
                 if (date.month == 1) and (today.month == 12):
-                    year=year+1
-
-                date = date.replace(year=year)
+                    date = date.replace(year=year + 1)
 
                 entries.append(
                     Collection(
                         date=date,
                         t=collection["name"],
                         icon=ICON_MAP.get(collection["name"]),
-                        picture=IMAGEPATH+collection["imageURL"]
+                        picture=IMAGEPATH + collection["imageURL"],
                     )
                 )
 
-        return entries
\ No newline at end of file
+        return entries


Test patch: