From 51488d5f4f1b6c8d7c2fc681d09fb787223abf8c Mon Sep 17 00:00:00 2001 From: Zach Herb <38711280+zzznz27@users.noreply.github.com> Date: Tue, 9 Jul 2024 02:17:28 +1000 Subject: [PATCH] Update to Hawkesbury NSW GOV AU Integration (#2232) * Fixed Integration to work with recent api chagnes * Documentation Update * removed print statement * reformatting --------- Co-authored-by: Zach Herberstein Co-authored-by: 5ila5 <5ila5@users.noreply.github.com> --- .../translations/en.json | 6 +- .../source/hawkesbury_nsw_gov_au.py | 59 +++++++++++++------ doc/source/hawkesbury_nsw_gov_au.md | 5 ++ 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/custom_components/waste_collection_schedule/translations/en.json b/custom_components/waste_collection_schedule/translations/en.json index c581c60b7..f72dc8d9d 100644 --- a/custom_components/waste_collection_schedule/translations/en.json +++ b/custom_components/waste_collection_schedule/translations/en.json @@ -258,7 +258,8 @@ "interval": "Interval", "bill_number": "Bill Number", "values": "Values", - "property_no": "Property No" + "property_no": "Property No", + "postCode": "Post Code" }, "data_description": { "calendar_title": "A more readable, or user-friendly, name for the waste calendar. If nothing is provided, the name returned by the source will be used." @@ -500,7 +501,8 @@ "interval": "Interval", "bill_number": "Bill Number", "values": "Values", - "property_no": "Property No" + "property_no": "Property No", + "postCode": "Post Code" } } }, diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/hawkesbury_nsw_gov_au.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/hawkesbury_nsw_gov_au.py index ca49e4819..e359c76c7 100644 --- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/hawkesbury_nsw_gov_au.py +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/hawkesbury_nsw_gov_au.py @@ -14,21 +14,24 @@ "suburb": "south windsor", "street": "George Street", "houseNo": 539, + "postCode": 2756, }, "Windsor, catherine street 7": { "suburb": "Windsor", "street": "catherine st", "houseNo": 7, + "postCode": 2756, }, "Kurrajong, Bells Line Of Road 1052 ": { "suburb": "Kurrajong HILLS", "street": "Bells Line Of Road", "houseNo": 1052, - } + "postCode": 2758, + }, } API_URL = "https://data.hawkesbury.nsw.gov.au/api" _LOGGER = logging.getLogger(__name__) -ICON_MAP = { # Optional: Dict of waste types and suitable mdi icons +ICON_MAP = { # Optional: Dict of waste types and suitable mdi icons "DOMESTIC": "mdi:trash-can", "RECYCLE": "mdi:recycle", "ORGANIC": "mdi:leaf", @@ -52,21 +55,24 @@ class Source: - def __init__(self, suburb, street, houseNo): + def __init__(self, suburb, street, houseNo, postCode): self._suburb = suburb.upper() self._street = street self._houseNo = str(houseNo) self._url = API_URL + self._postCode = postCode def get_data(self, bin_prefix: str, fields) -> list[Collection]: entries: list[Collection] = [] - frequency = int(fields.get(f'{bin_prefix}_schedule')) + frequency = int(fields.get(f"{bin_prefix}_schedule", 0)) if frequency == 0: return entries - base_string = fields.get(f'{bin_prefix}_week1', dt.datetime.min.strftime('%Y-%m-%d')) - basedate = dt.datetime.strptime(base_string, "%Y-%m-%d") + base_string = fields.get( + f"{bin_prefix}_week1", dt.datetime.min.strftime("%Y-%m-%d") + ) + basedate = parse_date_field(base_string) # Get number of days between basedate and a year from now days = ((dt.datetime.now() + dt.timedelta(days=365)) - basedate).days @@ -81,27 +87,44 @@ def fetch(self): # check address values are not abbreviated address = self._street for key in STREETNAMES.keys(): - regex = r"\b{}\b".format(key.lower()) + regex = rf"\b{key.lower()}\b" address = re.sub( - pattern=regex, - repl=STREETNAMES[key], - string=address.lower()) + pattern=regex, repl=STREETNAMES[key], string=address.lower() + ) # get list of suburbs r = requests.get( - f"{self._url}/records/1.0/search/?sort=gisaddress&refine.gisaddress={self._houseNo} {address.title()} {self._suburb}&rows=1&dataset=bin-collection-days&timezone=Australia/Sydney&lang=en") + f"{self._url}/records/1.0/search/", + params={ + "sort": "gisaddress", + "refine.gisaddress": f"{self._houseNo} {address.title()} {self._suburb} NSW {self._postCode}", + "rows": 1, + "dataset": "bin-collection-days", + "timezone": "Australia/Sydney", + "lang": "en", + }, + ) data = json.loads(r.text) # Check if house record was found - if len(data['records']) == 0: + if len(data["records"]) == 0: raise Exception(f"House not found: {self._houseNo}") - + # get collection schedule - record = data['records'][-1] - garbagebin_entries = self.get_data('garbagebin', record['fields']) - recyclebin_entries = self.get_data('recyclebin', record['fields']) - organicbin_entries = self.get_data('organicbin', record['fields']) + record = data["records"][-1] + garbagebin_entries = self.get_data("garbagebin", record["fields"]) + recyclebin_entries = self.get_data("recyclebin", record["fields"]) + organicbin_entries = self.get_data("organicbin", record["fields"]) entries = garbagebin_entries + recyclebin_entries + organicbin_entries return entries - + + +def parse_date_field(date_string): + formats = ["%Y-%m-%d %H:%M:%S", "%Y-%m-%d"] + for fmt in formats: + try: + return dt.datetime.strptime(date_string, fmt) + except ValueError: + continue + raise ValueError(f"Unrecognized date format: {date_string}") diff --git a/doc/source/hawkesbury_nsw_gov_au.md b/doc/source/hawkesbury_nsw_gov_au.md index 5c50f8427..224356a79 100644 --- a/doc/source/hawkesbury_nsw_gov_au.md +++ b/doc/source/hawkesbury_nsw_gov_au.md @@ -12,6 +12,7 @@ waste_collection_schedule: suburb: SUBURB street: STREET houseNo: HOUSENO + postCode: POSTCODE ``` ### Configuration Variables @@ -24,6 +25,9 @@ waste_collection_schedule: **houseNo** *(string) (required)* +**postCode** +*(string) (required)* + ## Example ```yaml @@ -34,6 +38,7 @@ waste_collection_schedule: suburb: South Windsor street: George Street houseNo: 539 + postCode: 2756 ``` ## How to get the source arguments