Skip to content

Commit

Permalink
add Source for the Moje Odpady App
Browse files Browse the repository at this point in the history
  • Loading branch information
5ila5 committed Aug 1, 2024
1 parent 46278da commit c6b1095
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@ If your service provider is not listed, feel free to open a [source request issu
<details>
<summary>Poland</summary>

- [App Moje Odpady](/doc/source/moje_odpady_pl.md) / moje-odpady.pl
- [Bydgoszcz Pronatura](/doc/source/pronatura_bydgoszcz_pl.md) / pronatura.bydgoszcz.pl
- [Ecoharmonogram](/doc/source/ecoharmonogram_pl.md) / ecoharmonogram.pl
- [Gmina Miękinia](/doc/source/gmina_miekinia_pl.md) / api.skycms.com.pl
Expand Down
5 changes: 5 additions & 0 deletions custom_components/waste_collection_schedule/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -6359,6 +6359,11 @@
}
],
"Poland": [
{
"title": "App Moje Odpady",
"module": "moje_odpady_pl",
"default_params": {}
},
{
"title": "Bydgoszcz Pronatura",
"module": "pronatura_bydgoszcz_pl",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,9 @@
"app": "App",
"service_provider": "Service Provider",
"facility_id": "Facility Id",
"abfall": "Abfall"
"abfall": "Abfall",
"english": "English",
"voivodeship": "Voivodeship"
},
"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."
Expand Down Expand Up @@ -526,7 +528,9 @@
"app": "App",
"service_provider": "Service Provider",
"facility_id": "Facility Id",
"abfall": "Abfall"
"abfall": "Abfall",
"english": "English",
"voivodeship": "Voivodeship"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
from datetime import datetime

import requests
from waste_collection_schedule import Collection # type: ignore[attr-defined]

TITLE = "App Moje Odpady"
DESCRIPTION = "Source for App Moje Odpady."
URL = "https://moje-odpady.pl/"
TEST_CASES = {
"Aleksandr\u00f3w woj. \u015bl\u0105skie": {
"city": "Aleksandr\u00f3w",
"voivodeship": "woj. \u015bl\u0105skie",
},
"with address and house_number": {
"city": "BASZKÓWKA",
"voivodeship": "woj. mazowieckie",
"address": "ANTONÓWKI",
"house_number": "Pozosta\u0142e",
},
"english bin types": {
"city": "Marcin\u00f3w",
"voivodeship": "woj. \u0142\u00f3dzkie",
"english": True,
},
}


ICON_MAP = {
"Trash": "mdi:trash-can",
"Glass": "mdi:bottle-soda",
"Bio": "mdi:leaf",
"Paper": "mdi:package-variant",
"Recycle": "mdi:recycle",
}


API_URL = "https://waste24.net/client/api/mywaste/v2/location_cities.php"


def make_comparable(text: str) -> str:
return text.lower().replace(" ", "").replace(".", "")


class Source:
def __init__(
self,
city: str,
voivodeship: str | None = None,
address: str | None = None,
house_number: str | None = None,
english: bool = False,
):
self._city: str = make_comparable(city)
self._voivodeship: str | None = (
make_comparable(voivodeship) if voivodeship else None
)
self._address: str | None = make_comparable(address) if address else None
self._house_number: str | None = (
make_comparable(house_number) if house_number else None
)
self._english: bool = english

self._org_number: int | None = None
self._real_city_name: str | None = None
self._real_address: str | None = None
self._real_house_number: str | None = None

def _fetch_house_number(self):
payload = {
"org": self._org_number,
"city": self._real_city_name,
"address": self._real_address,
}
r = requests.post(
"https://waste24.net/client/api/mywaste/v2/location_addresses_nr.php",
json=payload,
)
r.raise_for_status()
data = r.json()
if len(data) == 0:
return
if len(data) == 1:
self._real_house_number = data[0]["addressNr"]
return

if self._house_number is None:
raise ValueError(
f"House number is required for this address, use one of {[a['nr'] for a in data]}"
)

self._real_house_number = None
for house_number in data:
if make_comparable(house_number["addressNr"]) == self._house_number:
self._real_house_number = house_number["addressNr"]
break

if self._real_house_number is None:
raise ValueError(
f"House number {self._house_number} not found, use one of {[a['nr'] for a in data]}"
)

def _fetch_address(self):
payload = {"org": self._org_number, "city": self._real_city_name}
r = requests.post(
"https://waste24.net/client/api/mywaste/v2/location_addresses.php",
json=payload,
)
r.raise_for_status()

data = r.json()
if self._address is None:
raise ValueError(
f"Address is required for this city, use one of {[a['addressName'] for a in data]}"
)

countOfChilds = None

for address in data:
if make_comparable(address["addressName"]) == self._address:
self._real_address = address["addressName"]
break
if self._real_address is None:
raise ValueError(
f"Address {self._address} not found, use one of {[a['addressName'] for a in data]}"
)

if countOfChilds:
self._fetch_house_number()

def fetch_area(self):
r = requests.post(
"https://waste24.net/client/api/mywaste/v2/location_cities.php"
)
r.raise_for_status()

data = r.json()
city_matches = []

for city in data:
if make_comparable(city["cityName"]) == self._city:
city_matches.append(city)

if not city_matches:
raise ValueError(
f"City {self._city} not found, use one of {[c['cityName'] for c in data]}"
)

self._org_number = None
self._real_city_name = None
countOfChilds = None

if len(city_matches) == 1:
self._org_number = city_matches[0]["org"]
self._real_city_name = city_matches[0]["cityName"]
countOfChilds = city_matches[0]["countOfChilds"]
else:
if self._voivodeship is None:
raise ValueError(
f"Multiple cities found, specify voivodeship, use one of {[c['voivodeship'] for c in city_matches]}"
)
for city in city_matches:
if make_comparable(city["voivodeship"]) == self._voivodeship:
self._org_number = city["org"]
self._real_city_name = city["cityName"]
countOfChilds = city["countOfChilds"]
break
if self._org_number is None:
raise ValueError(
f"City {self._city} in voivodeship {self._voivodeship} not found, use one of {[c['voivodeship'] for c in city_matches]}"
)

if countOfChilds:
self._fetch_address()

def _get_scheduele(self) -> list[Collection]:
payload = {
"org": self._org_number,
"city": self._real_city_name,
"address": self._real_address or "",
"addressNr": self._real_house_number or "",
}
r = requests.post(
"https://waste24.net/client/api/mywaste/v2/schedule_list.php", json=payload
)
r.raise_for_status()
data = r.json()
print(data)
entries = []
for collection in data:
date_ = datetime.strptime(collection["data"], "%Y-%m-%d").date()
for containers in collection["containers"]:
bin_type = containers["containerName"]
if self._english:
bin_type = (
containers.get("containerNameEn", bin_type).strip() or bin_type
)
entries.append(Collection(date_, bin_type, ICON_MAP.get(bin_type)))
return entries

def fetch(self) -> list[Collection]:
fresh_params = False
if self._org_number is None:
self.fetch_area()
try:
return self._get_scheduele()
except Exception:
if fresh_params:
raise
fresh_params = True
self.fetch_area()
return self._get_scheduele()
62 changes: 62 additions & 0 deletions doc/source/moje_odpady_pl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# App Moje Odpady

Support for schedules provided by [App Moje Odpady](https://moje-odpady.pl/), serving multiple municipalities, Poland.

<https://play.google.com/store/apps/details?id=com.mojeodpady>

## Configuration via configuration.yaml

```yaml
waste_collection_schedule:
sources:
- name: moje_odpady_pl
args:
city: CITY
voivodeship: VPICODESHIP (województwo)

```
### Configuration Variables
**city**
*(String) (required)*
**voivodeship**
*(String) (optional)* needed if there are multiple cities with the same name
**address**
*(String) (optional)* only needed if the app asks for an address
**house_number**
*(String) (optional)* rarely needed, only if the app asks for a house number
**english**
*(String) (optional)* if set to "true" the app will return the schedule in English
## Example
```yaml
waste_collection_schedule:
sources:
- name: moje_odpady_pl
args:
city: Aleksandrów
voivodeship: woj. śląskie
english: False # optional parameter
```
```yaml
waste_collection_schedule:
sources:
- name: moje_odpady_pl
args:
city: BASZKÓWKA
voivodeship: woj. mazowieckie
address: ANTONÓWKI
house_number: Pozostałe
english: False # optional parameter
```
## How to get the source argument
The parameters can be found by using the app ([GooglePlay](https://play.google.com/store/apps/details?id=com.mojeodpady&hl=pl), [AppStore](https://apps.apple.com/pl/app/waste-collection-schedule/id1248697353)) and checking the address input form.
2 changes: 1 addition & 1 deletion info.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Waste collection schedules from service provider web sites are updated daily, de
| Netherlands | ACV Group, Alpen an den Rijn, Area Afval, Avalex, Avri, Bar Afvalbeheer, 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, HVC Groep, Meerlanden, Mijn Blink, PreZero, Purmerend, RAD BV, Reinis, Spaarnelanden, Twente Milieu, 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 |
| Norway | BIR (Bergensområdets Interkommunale Renovasjonsselskap), Fosen Renovasjon, IRiS, Min Renovasjon, Movar IKS, Oslo Kommune, ReMidt Orkland muni, Sandnes Kommune, Stavanger Kommune, Trondheim |
| Poland | Bydgoszcz Pronatura, Ecoharmonogram, Gmina Miękinia, Koziegłowy/Objezierze/Oborniki, Poznań, Warsaw, Wrocław |
| Poland | App Moje Odpady, Bydgoszcz Pronatura, Ecoharmonogram, Gmina Miękinia, Koziegłowy/Objezierze/Oborniki, Poznań, Warsaw, Wrocław |
| Slovenia | Moji odpadki, Ljubljana |
| Sweden | Affärsverken, Boden, Borås Energi och Miljö, EDPEvent - Multi Source, Gästrike Återvinnare, Jönköping - June Avfall & Miljö, Landskrona - Svalövs Renhållning, Lerum Vatten och Avlopp, Linköping - Tekniska Verken, Lund Waste Collection, Mölndal, Norrtalje Vatten & Avfall, North / Middle Bohuslän - Rambo AB, Region Gotland, Ronneby Miljöteknik, Samverkan Återvinning Miljö (SÅM), Skellefteå, SRV Återvinning, SSAM (Deprecated), SSAM Södra Smalånds Avfall & Miljö, Sysav Sophämntning, Uppsala Vatten, Uppsala Vatten och Avfall AB (Deprecated), VA Syd Sophämntning, VIVAB Sophämtning |
| Switzerland | A-Region, Alchenstorf, Andwil, Appenzell, Berg, Bühler, Canton of Zürich, Eggersriet, Gais, Gaiserwald, Goldach, Grosswangen, Grub, Heiden, Herisau, Horn, Hundwil, Häggenschwil, Lindau, Lutzenberg, Muolen, Mörschwil, Münchenstein, Münsingen BE, Switzerland, Real Luzern, Rehetobel, Rorschach, Rorschacherberg, Schwellbrunn, Schönengrund, Speicher, Stein, Steinach, Teufen, Thal, Trogen, Tübach, Untereggen, Urnäsch, Wald, Waldkirch, Waldstatt, Wittenbach, Wolfhalden |
Expand Down

0 comments on commit c6b1095

Please sign in to comment.