mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-20 23:04:13 +01:00
Added source for Napier City Council NZ (#2532)
* Added source for Napier City Council NZ * Correctly determine the collection type * reformatting --------- Co-authored-by: Phil Gale <phil.gale@re-leased.com> Co-authored-by: 5ila5 <5ila5@users.noreply.github.com>
This commit is contained in:
@@ -1260,6 +1260,7 @@ If your service provider is not listed, feel free to open a [source request issu
|
||||
- [Hamilton City Council](/doc/source/hcc_govt_nz.md) / fightthelandfill.co.nz
|
||||
- [Horowhenua District Council](/doc/source/horowhenua_govt_nz.md) / horowhenua.govt.nz
|
||||
- [Hutt City Council](/doc/source/toogoodtowaste_co_nz.md) / toogoodtowaste.co.nz
|
||||
- [Napier City Council](/doc/source/napier_govt_nz.md) / napier.govt.nz
|
||||
- [Porirua City](/doc/source/poriruacity_govt_nz.md) / poriruacity.govt.nz
|
||||
- [Rotorua Lakes Council](/doc/source/rotorua_lakes_council_nz.md) / rotorualakescouncil.nz
|
||||
- [Tauranga City Council](/doc/source/tauranga_govt_nz.md) / tauranga.govt.nz
|
||||
|
||||
@@ -6930,6 +6930,11 @@
|
||||
"module": "toogoodtowaste_co_nz",
|
||||
"default_params": {}
|
||||
},
|
||||
{
|
||||
"title": "Napier City Council",
|
||||
"module": "napier_govt_nz",
|
||||
"default_params": {}
|
||||
},
|
||||
{
|
||||
"title": "Porirua City",
|
||||
"module": "poriruacity_govt_nz",
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from waste_collection_schedule import Collection
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
TITLE = "Napier City Council"
|
||||
DESCRIPTION = "Source for Napier City Council"
|
||||
URL = "https://www.napier.govt.nz/"
|
||||
COUNTRY = "nz"
|
||||
API_URL = "https://data.napier.govt.nz/regional/ncc/widgets/collectiondays/do_collectiondays.php"
|
||||
ICON_MAP = {
|
||||
"Rubbish": "mdi:trash-can",
|
||||
"Recycling": "mdi:recycle",
|
||||
}
|
||||
HEADERS = {"User-Agent": "waste-collection-schedule"}
|
||||
|
||||
TEST_CASES = {
|
||||
"Test1": {"address": "4 Sheehan Street"},
|
||||
"Test2": {"address": "25 Bedford Road"},
|
||||
"Test3": {"address": "603 Marine Parade"},
|
||||
"Test4": {"address": "14 Cobden Road"},
|
||||
}
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(self, address):
|
||||
self._address = address
|
||||
|
||||
def fetch_property_details(self):
|
||||
params = {
|
||||
"search": self._address,
|
||||
"council": "shared",
|
||||
"type": "address",
|
||||
}
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://data.napier.govt.nz/regional/shared/widgets/propertysearch/do_search.php",
|
||||
params=params,
|
||||
headers=HEADERS,
|
||||
timeout=10,
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
if not data:
|
||||
raise ValueError(f"Failed to locate address: {self._address}")
|
||||
|
||||
# Check if the response indicates no record was found
|
||||
if data[0].get("id") == "0" and "No record found for your search" in data[
|
||||
0
|
||||
].get("value", ""):
|
||||
raise ValueError(f"No record found for address: {self._address}")
|
||||
|
||||
# Check if there is more than one result
|
||||
if len(data) > 1:
|
||||
raise ValueError(
|
||||
f"Multiple results found for address: {self._address}. Must be a single address only."
|
||||
)
|
||||
|
||||
# Check if the expected keys exist in the first item of the data list
|
||||
if (
|
||||
"valuation_id" not in data[0]
|
||||
or "sufi_id" not in data[0]
|
||||
or "ra_unique_id" not in data[0]
|
||||
):
|
||||
raise ValueError(f"Expected keys not found in the response: {data[0]}")
|
||||
|
||||
valuation_id = data[0]["valuation_id"]
|
||||
sufi_id = data[0]["sufi_id"]
|
||||
ra_unique_id = data[0]["ra_unique_id"]
|
||||
|
||||
return valuation_id, sufi_id, ra_unique_id
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(
|
||||
f"Failed while locating address: {self._address} with error: {e}"
|
||||
)
|
||||
|
||||
def fetch(self):
|
||||
v, s, r = self.fetch_property_details()
|
||||
|
||||
params = {
|
||||
"v": v,
|
||||
"s": s,
|
||||
"r": r,
|
||||
}
|
||||
try:
|
||||
response = requests.get(API_URL, params=params, timeout=10)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
except requests.RequestException as e:
|
||||
raise ValueError(f"API request failed: {e}")
|
||||
|
||||
if not data.get("success", False):
|
||||
raise ValueError("API response indicates failure.")
|
||||
|
||||
html_content = data.get("html", "")
|
||||
if not html_content:
|
||||
_LOGGER.warning("No HTML content found in API response.")
|
||||
raise ValueError("No HTML content in API response.")
|
||||
|
||||
soup = BeautifulSoup(html_content, "html.parser")
|
||||
entries = []
|
||||
|
||||
tables = soup.find_all("table")
|
||||
for table in tables:
|
||||
th = table.find("th")
|
||||
if not th:
|
||||
_LOGGER.warning("No th element found in table.")
|
||||
continue
|
||||
|
||||
collection_type = th.get_text(strip=True).replace(" collection", "")
|
||||
|
||||
rows = table.find_all("tr")
|
||||
for row in rows:
|
||||
cells = row.find_all("td")
|
||||
if not cells:
|
||||
continue
|
||||
|
||||
collection_info = cells[0].get_text(strip=True)
|
||||
if "Every" in collection_info:
|
||||
day = collection_info.split(" ")[1] # Extract the day
|
||||
|
||||
# Calculate the weekday index of the target day
|
||||
target_weekday = datetime.datetime.strptime(day, "%A").weekday()
|
||||
|
||||
today = datetime.date.today()
|
||||
|
||||
# Find the current week's occurrence of the target day
|
||||
today_weekday = today.weekday()
|
||||
days_until_next_occurrence = (
|
||||
target_weekday - today_weekday + 7
|
||||
) % 7
|
||||
|
||||
# Get the date of the next occurrence
|
||||
next_occurrence = today + datetime.timedelta(
|
||||
days=days_until_next_occurrence
|
||||
)
|
||||
|
||||
# Get the past 7 and next 7 occurrences
|
||||
for i in range(-7, 8): # From -7 to 7 inclusive
|
||||
occurrence_date = next_occurrence + datetime.timedelta(weeks=i)
|
||||
|
||||
# Keep the date as datetime.date
|
||||
collection_date = occurrence_date
|
||||
|
||||
entries.append(
|
||||
Collection(
|
||||
date=collection_date,
|
||||
t=collection_type.capitalize(),
|
||||
icon=ICON_MAP.get(
|
||||
collection_type.capitalize(), "mdi:calendar"
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
if not entries:
|
||||
raise ValueError(
|
||||
f"No collection entries found for address: {self._address}"
|
||||
)
|
||||
|
||||
return entries
|
||||
36
doc/source/napier_govt_nz.md
Normal file
36
doc/source/napier_govt_nz.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Napier City Council
|
||||
|
||||
[Source URL](https://www.napier.govt.nz/services/rubbish-and-recycling/collection-days/)
|
||||
|
||||
[API URL](https://data.napier.govt.nz/regional/ncc/widgets/collectiondays/do_collectiondays.php)
|
||||
|
||||
This source provides waste collection schedules for Napier City Council. It uses the Napier Council's API's to fetch waste collection schedules based on the provided address.
|
||||
|
||||
## Configuration via `configuration.yaml`
|
||||
|
||||
To configure the source, add the following to your `configuration.yaml` file:
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: napier_govt_nz
|
||||
args:
|
||||
address: UNIQUE_ADDRESS
|
||||
```
|
||||
|
||||
## Configuration Variables
|
||||
|
||||
**address** (string) (required)
|
||||
The address for which you want to retrieve the waste collection schedule.
|
||||
|
||||
## Example
|
||||
|
||||
An example configuration:
|
||||
|
||||
```yaml
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: napier_govt_nz
|
||||
args:
|
||||
address: 4 Sheehan Street
|
||||
```
|
||||
2
info.md
2
info.md
@@ -30,7 +30,7 @@ Waste collection schedules from service provider web sites are updated daily, de
|
||||
| Lithuania | Kauno švara, Telšių keliai |
|
||||
| Luxembourg | Esch-sur-Alzette, SICA |
|
||||
| Netherlands | 's-Hertogenbosch, ACV Group, Afvalstoffendienst.nl, Alpen an den Rijn, Altena, Area Afval, Avalex, Avri, Bar Afvalbeheer, Bernheze, Circulus, Cyclus NV, Dar, Den Haag, GAD, Gemeente Almere, Gemeente Berkelland, Gemeente Cranendonck, Gemeente Hellendoorn, Gemeente Lingewaard, Gemeente Meppel, Gemeente Middelburg + Vlissingen, Gemeente Peel en Maas, Gemeente Schouwen-Duiveland, Gemeente Sudwest-Fryslan, Gemeente Venray, Gemeente Voorschoten, Gemeente Waalre, Gemeente Westland, Goes, Heusden, HVC Groep, Meerlanden, Mijn Blink, Oisterwijk, PreZero, Purmerend, RAD BV, Rd4, Reinis, Spaarnelanden, Twente Milieu, Vught, Waardlanden, Ximmio, ZRD, Ôffalkalinder van Noardeast-Fryslân & Dantumadiel |
|
||||
| New Zealand | Auckland Council, Christchurch City Council, Dunedin District Council, Gore, Invercargill & Southland, Hamilton City Council, Horowhenua District Council, Hutt City Council, Porirua City, Rotorua Lakes Council, Tauranga City Council, Waipa District Council, Wellington City Council |
|
||||
| New Zealand | Auckland Council, Christchurch City Council, Dunedin District Council, Gore, Invercargill & Southland, Hamilton City Council, Horowhenua District Council, Hutt City Council, Napier City Council, Porirua City, Rotorua Lakes Council, Tauranga City Council, Waipa District Council, Wellington City Council |
|
||||
| Norway | BIR (Bergensområdets Interkommunale Renovasjonsselskap), Fosen Renovasjon, IRiS, Min Renovasjon, Movar IKS, Oslo Kommune, ReMidt Orkland muni, Sandnes Kommune, Stavanger Kommune, Trondheim |
|
||||
| Poland | App Moje Odpady, Bydgoszcz Pronatura, Ecoharmonogram, Gmina Miękinia, Koziegłowy/Objezierze/Oborniki, MPGK Katowice, Poznań, Warsaw, Wrocław |
|
||||
| Slovenia | Moji odpadki, Ljubljana |
|
||||
|
||||
@@ -158,6 +158,7 @@ Currently the following service providers are supported:
|
||||
- [Christchurch](./doc/source/ccc_govt_nz.md)
|
||||
- [Gore, Invercargill & Southland](./doc/source/wastenet_org_nz.md)
|
||||
- [Horowhenua District](./doc/source/horowhenua_govt_nz.md)
|
||||
- [Napier](./doc/source/napier_govt_nz.md)
|
||||
- [Waipa District](./doc/source/waipa_nz.md)
|
||||
- [Wellington](./doc/source/wellington_govt_nz.md)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user