diff --git a/README.md b/README.md index 6523cabea..0cf97bcc3 100644 --- a/README.md +++ b/README.md @@ -1814,6 +1814,7 @@ If your service provider is not listed, feel free to open a [source request issu Poland - [App Moje Odpady](/doc/source/moje_odpady_pl.md) / moje-odpady.pl +- [Blisko](/doc/source/blisko.md) / gateway.sisms.pl - [Bydgoszcz Pronatura](/doc/source/pronatura_bydgoszcz_pl.md) / pronatura.bydgoszcz.pl - [Czerwonak, Murowana Goślina, Oborniki](/doc/source/eko_tom_pl.md) / eko-tom.pl - [Ecoharmonogram](/doc/source/ecoharmonogram_pl.md) / ecoharmonogram.pl diff --git a/custom_components/waste_collection_schedule/sources.json b/custom_components/waste_collection_schedule/sources.json index d04f7f61f..2e87ef318 100644 --- a/custom_components/waste_collection_schedule/sources.json +++ b/custom_components/waste_collection_schedule/sources.json @@ -11574,6 +11574,12 @@ "default_params": {}, "id": "moje_odpady_pl" }, + { + "title": "Blisko", + "module": "blisko", + "default_params": {}, + "id": "blisko" + }, { "title": "Bydgoszcz Pronatura", "module": "pronatura_bydgoszcz_pl", diff --git a/custom_components/waste_collection_schedule/translations/de.json b/custom_components/waste_collection_schedule/translations/de.json index 4cabd8d6d..c0d2bd9b1 100644 --- a/custom_components/waste_collection_schedule/translations/de.json +++ b/custom_components/waste_collection_schedule/translations/de.json @@ -10097,6 +10097,28 @@ }, "data_description": {} }, + "args_blisko": { + "title": "Quelle konfigurieren", + "description": "Konfiguriere deinen Service Provider. \n\nSee blisko.md for help\n\nMehr details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/blisko.md", + "data": { + "calendar_title": "Kalender Titel", + "formattedId": "Formatted Id", + "regionId": "Region Id" + }, + "data_description": { + "calendar_title": "Ein lesbarerer oder benutzerfreundlicherer Name für den Müllkalender. Wenn nichts angegeben wird, wird der Name der Quelle verwendet." + } + }, + "reconfigure_blisko": { + "title": "Quelle Neu Konfigurieren", + "description": "Konfiguriere deinen Service Provider. \n\nSee blisko.md for help\n\nMehr details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/blisko.md", + "data": { + "calendar_title": "Kalender Titel", + "formattedId": "Formatted Id", + "regionId": "Region Id" + }, + "data_description": {} + }, "args_pronatura_bydgoszcz_pl": { "title": "Quelle konfigurieren", "description": "Konfiguriere deinen Service Provider. Mehr details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/pronatura_bydgoszcz_pl.md", diff --git a/custom_components/waste_collection_schedule/translations/en.json b/custom_components/waste_collection_schedule/translations/en.json index 357dbe9eb..6e8e8756a 100644 --- a/custom_components/waste_collection_schedule/translations/en.json +++ b/custom_components/waste_collection_schedule/translations/en.json @@ -10103,6 +10103,33 @@ }, "data_description": {} }, + "args_blisko": { + "title": "Configure Source", + "description": "Configure your service provider. \n\nSee blisko.md for help\n\nMore details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/blisko.md.", + "data": { + "calendar_title": "Calendar Title", + "formattedId": "Formatted Id", + "regionId": "Region Id" + }, + "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.", + "formattedId": "Formatted ID of city/street and houseId", + "regionId": "ID of instance owner" + } + }, + "reconfigure_blisko": { + "title": "Reconfigure Source", + "description": "Configure your service provider. \n\nSee blisko.md for help\n\nMore details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/blisko.md.", + "data": { + "calendar_title": "Calendar Title", + "formattedId": "Formatted Id", + "regionId": "Region Id" + }, + "data_description": { + "formattedId": "Formatted ID of city/street and houseId", + "regionId": "ID of instance owner" + } + }, "args_pronatura_bydgoszcz_pl": { "title": "Configure Source", "description": "Configure your service provider. More details: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/pronatura_bydgoszcz_pl.md.", diff --git a/custom_components/waste_collection_schedule/translations/it.json b/custom_components/waste_collection_schedule/translations/it.json index 1f9529239..f5e436b5f 100644 --- a/custom_components/waste_collection_schedule/translations/it.json +++ b/custom_components/waste_collection_schedule/translations/it.json @@ -10086,6 +10086,28 @@ }, "data_description": {} }, + "args_blisko": { + "title": "Configurazione Sorgente", + "description": "Compila i campi per ottenere le informazioni sul tuo servizio di raccolta. \n\nSee blisko.md for help\n\nMaggiori informazioni: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/blisko.md.", + "data": { + "calendar_title": "Nome Calendario", + "formattedId": "Formatted Id", + "regionId": "Region Id" + }, + "data_description": { + "calendar_title": "Puoi cambiare il nome del calendario della raccolta dei rifiuti, altrimenti di default verra' utilizzato il nome del tuo fornitore di servizi." + } + }, + "reconfigure_blisko": { + "title": "Riconfigurazione Sorgente", + "description": "Compila i campi per ottenere le informazioni sul tuo servizio di raccolta. \n\nSee blisko.md for help\n\nPer maggiori informazioni: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/blisko.md.", + "data": { + "calendar_title": "Nome Calendario", + "formattedId": "Formatted Id", + "regionId": "Region Id" + }, + "data_description": {} + }, "args_pronatura_bydgoszcz_pl": { "title": "Configurazione Sorgente", "description": "Compila i campi per ottenere le informazioni sul tuo servizio di raccolta. Maggiori informazioni: https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/pronatura_bydgoszcz_pl.md.", diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py b/custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py new file mode 100644 index 000000000..7e6a82acf --- /dev/null +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py @@ -0,0 +1,116 @@ +import requests +import json +from argparse import ArgumentParser + + +def all_houses_per_street(regionId: int, streetId: str): + url = "https://gateway.sisms.pl/akun/api/owners/{region}/streetAddresses/list?streetId={formattedSTREET_ID}" + r = requests.get(url.format( + region=regionId, formattedSTREET_ID=streetId)) + + if r.status_code != 200: + return + return r.json()['data'] + + +def all_houses_per_city_no_streets(regionId: int, townId: str): + url = "https://gateway.sisms.pl/akun/api/owners/{region}/townAddresses/list?townId={formattedTOWN_ID}" + r = requests.get(url.format(region=regionId, formattedTOWN_ID=townId)) + + if r.status_code != 200: + return + + data = r.json()['data'] + return data + + +def all_street_per_city(regionId: int, cityId: str): + url = "https://gateway.sisms.pl/akun/api/owners/{region}/streets/list?townId={formattedTOWN_ID}" + r = requests.get(url.format(region=regionId, formattedTOWN_ID=cityId)) + + if r.status_code != 200: + return + + data = r.json()['data'] + return data + + +def dump_regions(region: int): + url = "https://gateway.sisms.pl/akun/api/owners/{id}/info" + r = requests.get(url.format(id=region)) + if r.status_code != 200: + return + + region_name = r.json()["name"] + + url = "https://gateway.sisms.pl/akun/api/owners/{id}/towns/list" + r = requests.get(url.format(id=region)) + if r.status_code != 200: + return + data = r.json()["data"] + + return {'region_name': region_name, 'cities': data} + + +def fetch_one_city(id: int): + url = "https://gateway.sisms.pl/akun/api/owners/{id}/info" + r = requests.get(url.format(id=id)) + if r.status_code != 200: + return + + data = r.json() + if "TIMETABLE" not in data["tabs"]: + return + + return {'id': id, 'region_name': data['name']} + + +def main(): + parser = ArgumentParser() + parser.add_argument('--regionmax', type=int, default=300) + parser.add_argument('--street', type=str, help='formattedId') + parser.add_argument('--city', type=str, help='formattedId') + parser.add_argument('--region', type=int) + parser.add_argument('--dumpregions', action='store_true') + args = parser.parse_args() + + if args.region and args.street: + streets_json = all_houses_per_street( + args.region, args.street) + if streets_json: + print(json.dumps(streets_json, indent=2)) + else: + print("No houeses for region {} and city {}".format( + args.region, args.city)) + return + + if args.region and args.city: + streets_json = all_street_per_city(args.region, args.city) + if streets_json: + print(json.dumps(streets_json, indent=2)) + else: + print("No streets for region {} and cityId {}. Dumping house addresses".format( + args.region, args.city)) + print(json.dumps(all_houses_per_city_no_streets( + args.region, args.city), indent=2)) + + return + + if args.region: + region_json = (dump_regions(args.region)) + if not region_json: + print("Region {region} does not exists".format( + region=args.region)) + else: + print(json.dumps(region_json, indent=2)) + return + + if args.dumpregions: + for i in range(args.regionmax): + data = fetch_one_city(i) + if data: + print(json.dumps(data, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/blisko.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/blisko.py new file mode 100644 index 000000000..25d940f78 --- /dev/null +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/blisko.py @@ -0,0 +1,95 @@ +from waste_collection_schedule import Collection + +from string import Template +import urllib.request +import datetime +import json +import logging + +TITLE = "Blisko" +DESCRIPTION = "Source script for Blisko APP" +URL = "https://gateway.sisms.pl" +COUNTRY = "pl" +TEST_CASES = { + "Gmina Dobra/Grzepnica/Rezydencka": {"regionId": "112", + "formattedId": "32:11:01:2:0774204:42719:32"}, + "Gmina Topólka/Bielki": {"regionId": "40", + "formattedId": "02:17:04:3:0880283:00157:1"}, + "Gmina Topólka/Bielki": {"regionId": "40", + "formattedId": "04:11:07:2:0870362::1"} +} + +API_URL = "https://abc.com/search/" + +ICON_MAP = { + "Zmieszane odpady komunalne": "mdi:trash-can", + "Papier i tektura": "mdi:recycle", + "Odpady biodegradowalne": "mdi:leaf", +} + +# Arguments affecting the configuration GUI # + + +HOW_TO_GET_ARGUMENTS_DESCRIPTION = { + "en": "See blisko.md for help", + "pl": "Zobacz w blisko.md" +} + +PARAM_DESCRIPTIONS = { + "en": { + "regionId": "ID of instance owner", + "formattedId": "Formatted ID of city/street and houseId" + } +} + + +def find_bin_name(binId, json): + for entry in json: + if entry['id'] == binId: + return entry['name'] + raise Exception + + +schedule_url_template = Template( + "https://gateway.sisms.pl/akun/api/owners/${regionId}/timetable/get?\ +unitId=${formattedId}") + + +bins_url_template = Template( + "https://gateway.sisms.pl/akun/api/owners/${regionId}/bins/list?\ +unitId=${formattedId}") + +_LOGGER = logging.getLogger(__name__) + + +class Source: + # argX correspond to the args dict in the source configuration + def __init__(self, regionId: str, formattedId: str): + self._schedule_url = schedule_url_template.safe_substitute( + regionId=regionId, formattedId=formattedId) + self._bins_url = bins_url_template.safe_substitute( + regionId=regionId, formattedId=formattedId) + + def fetch(self): + + entries = [] # List that holds collection schedule + + bins_data = urllib.request.urlopen(self._bins_url) + bins = json.load(bins_data)['data'] + _LOGGER.warn(bins) + timetable_data = urllib.request.urlopen(self._schedule_url) + timetable_json = json.load(timetable_data)["data"] + + for month_data in timetable_json: + for reception in month_data['receptions']: + bin_name = find_bin_name(binId=reception['binId'], json=bins) + entries.append( + Collection( + date=datetime.datetime.strptime( + reception['date'], '%Y-%m-%d').date(), + t=bin_name, + icon=ICON_MAP.get(bin_name), + ) + ) + + return entries diff --git a/doc/source/blisko.md b/doc/source/blisko.md new file mode 100644 index 000000000..46591bb7b --- /dev/null +++ b/doc/source/blisko.md @@ -0,0 +1,213 @@ +# Blisko.App + +Support for schedules provided by [Blisko](https://blisko.co/). + +Blisko app supports mutliple voivodeships and cities. + + +## Configuration via configuration.yaml + +```yaml +waste_collection_schedule: + sources: + - name: blisko + args: + regionId: 112 + formattedId: "32:11:01:2:0774204:42719:32" +``` + +### Configuration Variables + +**regionId** +*(string) (required)* + +**formattedId** +*(string)(required)* + +All arguments must be provided. + +## Example + +```yaml +waste_collection_schedule: + sources: + - name: blisko + args: + regionId: 112 + formattedId: "32:11:01:2:0774204:42719:32" +``` + +## How to get the source arguments + +You have to provide: +* `regionId` - An ID of owner of Blisko instance for your city. +* `formattedId` - An ID of owner of Blisko instance for your city. + +### `regionId` + + +Region ID can be either queried from `Blisko_searcher.py` helper script or find in the list below: + +#### Using Blisko_searcher.py + +``` +$ python custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py --dumpregions +``` + +### From the list + +* 39 Gmina Topólka +* 40 Gmina Strzelin +* 42 Gmina Reda +* 44 Gmina Rumia +* 51 Gmina Złoty Stok +* 61 Klient Szablonowy - Karty Usług +* 73 Gmina Wieluń +* 75 Gmina Łęczyce +* 77 Gmina Kolbudy +* 78 Gmina Polanica-Zdrój +* 81 Gmina Wisznia Mała +* 82 Polkowice +* 83 Gmina Cedry Wielkie +* 84 Gmina i Miasto Nowe Skalmierzyce +* 85 Gmina Chojnów +* 86 Gmina Pajęczno +* 87 Gospodarka Odpadami - Pelplin +* 89 Gmina Szczytna +* 99 ZGPD-7 +* 100 Gmina Mysłakowice +* 101 Gmina Krotoszyce +* 103 Gmina Sobótka +* 104 Gmina Wołów +* 109 Gospodarka Odpadami - Starogard Gdański +* 111 Gmina Inowrocław +* 112 Gmina Dobra +* 114 Gmina Słupno +* 115 Gmina Mielec +* 116 Gmina Bardo +* 117 Gmina Żmigród +* 119 Gmina Stawiguda +* 120 Gmina Starogard Gdański +* 121 Gmina Nowa Ruda +* 122 Gmina Legnickie Pole +* 123 Gmina Brzeziny +* 124 Gmina Zduńska Wola +* 125 Gmina Międzybórz +* 127 Gmina Osiecznica +* 128 Gmina Słupca +* 136 Gmina Grabów nad Prosną +* 140 Gmina Mokrsko +* 142 Strzelce Krajeńskie +* 144 Gmina i Miasto Dzierzgoń +* 145 Gmina Brzeg Dolny +* 146 Gmina Wiązów +* 149 Przedsiębiorstwo Gospodarki Komunalnej w Wołowie Sp. z o.o. +* 150 Gmina Staszów +* 153 Miasto Wałbrzych +* 154 Miasto Rejowiec Fabryczny +* 158 Gmina Grodzisk Mazowiecki +* 159 Gmina Świecie +* 160 Gmina Kozy +* 161 Gmina Gniew +* 162 Gmina Ostrowiec Świętokrzyski +* 163 Gmina Skarszewy +* 164 Gminne Przedsiębiorstwo Komunalne Sp. z o.o. w Skarszewach +* 165 Gmina Porąbka +* 166 Gmina Zbrosławice +* 167 Gmina Szumowo +* 168 KOMUS +* 169 Miasto i Gmina Łasin +* 170 Zakład Gospodarki Komunalnej Sp. z o.o. +* 171 Gmina Kamionka Wielka +* 172 Gmina Czernichów +* 173 Gmina Świdnica +* 174 Klient Szablonowy - Ekostrażnik +* 175 Gmina Daleszyce +* 177 Gmina Nowy Staw +* 178 Gmina Przeworno +* 179 Gmina Pruszcz +* 181 Gmina Władysławowo +* 182 Gmina Czechowice- Dziedzice +* 183 ABRUKO PLUS +* 184 Miasto i Gmina Morawica +* 185 Gmina Wilkowice +* 186 Gmina Wojcieszków +* 187 Gmina Gorzyce +* 188 Gmina Miedziana Góra +* 189 Gmina Mogilany +* 190 Gmina Gościno +* 191 Gmina Ulan-Majorat +* 192 Gmina Wąchock +* 193 Gmina Wodzisław +* 194 Miasto Malbork +* 195 Gmina Grodków +* 196 Gmina Zaleszany +* 197 Gmina Gać +* 198 Gmina Kluczbork +* 199 Miasto Inowrocław +* 200 Ekologiczny Związek Gmin Dorzecza Koprzywianki +* 201 Gmina Miejska Kowal +* 202 Gmina Kruszwica +* 203 Gmina Przykładowa +* 204 Gmina Radoszyce +* 205 Gmina Osiek +* 206 Gmina Pawłowice +* 208 Gmina Gaworzyce +* 209 Gmina Lubrza +* 210 Parafia św. Wojciecha Biskupa i Męczennika w Nidzicy +* 211 Gmina Pyskowice +* 212 Gmina Nowa Słupia +* 213 Stowarzyszenie Centrum Wspierania Organizacji Pozarządowych i Inicjatyw Obywatelskich +* 214 Gmina Sośno +* 215 Gmina Dygowo +* 216 Gmina Bartniczka +* 218 Gmina Jeżewo +* 219 Gmina Olsztynek +* 220 Gmina Krzanowice +* 221 Gmina Wierzchlas +* 222 Gmina Miejska Hrubieszów +* 223 Miasto Rydułtowy +* 224 Gmina Gorlice +* 225 Gmina Sztum + + + +### `formattedId` + +Formatted ID must be queried from using `Blisko_searcher.py`. + +1) First figure out the `regionId`. + +2) Dump all cities in the region + +``` +$ python custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py --region 112 +``` + +3) Dump all streets for the city: + +``` +$ python custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py --region 112 --city 32:11:01:2:0774204 +``` + +If there is no streets for given city `Blisko_searcher.py` will dump house numbers. Use its id as `formattedId`. ( `04:11:07:2:0870362::1` for example). + + + +3) Dump all houses number for street: + +``` +$ python custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py --region 112 --street 32:11:01:2:0774204:42719 +``` + +4) Find your house number `id`. This is `formattedId` to be used in configuration. + +See example: +``` +$ python custom_components/waste_collection_schedule/waste_collection_schedule/service/Blisko_searcher.py --region 112 --street 32:11:01:2:0774204:42719 + +... +': '99'}, {'id': '32:11:01:2:0774204:42719:100', 'kind': 'STREET_ADDRESS', 'number': '100'}, {'id': '32:11:01:2:0774204:42719:101', 'kind': 'STREET_ADDRESS', 'number': '101'}, {'id': '32:11:01:2:0774204:42719:102', 'kind': 'STREET_ADDRESS', 'number': '102'}, {'id': '32:11:01:2:0774204:42719:103', 'kind': 'STREET_ADDRESS', 'number': '103'}, {'id': '32:11:01:2:0774204:42719:104', 'kind': 'STREET_ADDRESS', 'number': '104'}, {'id': '32:11:01:2:0774204:42719:105', 'kind': 'STREET_ADDRESS', 'number': '105'}, {'id': '32:11:01:2:0774204:42719:106', 'kind': 'STREET_ADDRESS', 'number': '106'}, {'id': '32:11:01:2:0774204:42719:107', 'kind': 'STREET_ADDRESS', 'number': '107'}] +``` + +So for house `107` in `regionId` 112 and with on specific street `formattedId` is `32:11:01:2:0774204:42719:107`. diff --git a/info.md b/info.md index f0990caf4..ff638a447 100644 --- a/info.md +++ b/info.md @@ -33,7 +33,7 @@ Waste collection schedules from service provider web sites are updated daily, de | Netherlands | 's-Hertogenbosch, ACV Group, Afval Wijzer, Afvalstoffendienst.nl, Alpen an den Rijn, Altena, Area Afval, Avalex, Avri, Bar Afvalbeheer, Bernheze, Circulus, Cyclus NV, Dar, Den Haag, Edam-Volendam, 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, 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, Czerwonak, Murowana Goślina, Oborniki, Ecoharmonogram, Gmina Miękinia, Koziegłowy/Objezierze/Oborniki, MPGK Katowice, Poznań, Warsaw, Wrocław | +| Poland | App Moje Odpady, Blisko, Bydgoszcz Pronatura, Czerwonak, Murowana Goślina, Oborniki, Ecoharmonogram, Gmina Miękinia, Koziegłowy/Objezierze/Oborniki, MPGK Katowice, Poznań, Warsaw, Wrocław | | Slovakia | fcc Environment | | Slovenia | Moji odpadki, Ljubljana, Snaga Maribor | | Sweden | Affärsverken, Avfallsapp.se - Multi Source, Boden, Borås Energi och Miljö, EDPEvent - Multi Source, Gästrike Återvinnare, Jönköping - June Avfall & Miljö, Kretslopp Sydost, Kristianstad Renhållning, Landskrona - Svalövs Renhållning, Lerum Vatten och Avlopp, Linköping - Tekniska Verken, Luleå, Lund Waste Collection, Mölndal, Norrtalje Vatten & Avfall, North / Middle Bohuslän - Rambo AB, Region Gotland, Ronneby Miljöteknik, Roslagsvatten, Samverkan Återvinning Miljö (SÅM), Skellefteå, SRV Återvinning, SSAM (Deprecated), SSAM Södra Smalånds Avfall & Miljö, Sysav Sophämntning, Söderköping, Uppsala Vatten, Uppsala Vatten och Avfall AB (Deprecated), VA Syd Sophämntning, VIVAB Sophämtning, Västervik Miljö & Energi |