env-canada 0.11.0__py3-none-any.whl → 0.11.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- env_canada/constants.py +1 -1
- env_canada/ec_weather.py +55 -35
- {env_canada-0.11.0.dist-info → env_canada-0.11.1.dist-info}/METADATA +1 -1
- {env_canada-0.11.0.dist-info → env_canada-0.11.1.dist-info}/RECORD +7 -7
- {env_canada-0.11.0.dist-info → env_canada-0.11.1.dist-info}/WHEEL +0 -0
- {env_canada-0.11.0.dist-info → env_canada-0.11.1.dist-info}/licenses/LICENSE +0 -0
- {env_canada-0.11.0.dist-info → env_canada-0.11.1.dist-info}/top_level.txt +0 -0
env_canada/constants.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
USER_AGENT = "env_canada/0.11.
|
1
|
+
USER_AGENT = "env_canada/0.11.1"
|
env_canada/ec_weather.py
CHANGED
@@ -240,7 +240,7 @@ def validate_station(station):
|
|
240
240
|
raise vol.Invalid(
|
241
241
|
'Station ID must be of the form "XX/s0000###", "s0000###" or 1-3 digits'
|
242
242
|
)
|
243
|
-
return station
|
243
|
+
return station
|
244
244
|
|
245
245
|
|
246
246
|
def _parse_timestamp(time_str: str | None) -> datetime | None:
|
@@ -385,10 +385,13 @@ class ECWeather:
|
|
385
385
|
self.hourly_forecasts = []
|
386
386
|
self.forecast_time = ""
|
387
387
|
self.site_list = []
|
388
|
+
self._station_resolved = False
|
389
|
+
self._station_tuple = (
|
390
|
+
None # Internal storage for (province_code, station_number)
|
391
|
+
)
|
388
392
|
|
389
393
|
if "station_id" in kwargs and kwargs["station_id"] is not None:
|
390
|
-
|
391
|
-
self.station_id = kwargs["station_id"] # Store raw input temporarily
|
394
|
+
self.station_id = kwargs["station_id"] # Keep as string for external API
|
392
395
|
self.lat = None
|
393
396
|
self.lon = None
|
394
397
|
else:
|
@@ -413,43 +416,57 @@ class ECWeather:
|
|
413
416
|
self.metadata.cache_returned_on_update = 0
|
414
417
|
raise ECWeatherUpdateFailed(msg) from err
|
415
418
|
|
419
|
+
async def _resolve_station(self) -> None:
|
420
|
+
"""Resolve station ID and coordinates (one-time initialization)."""
|
421
|
+
if self._station_resolved:
|
422
|
+
return
|
423
|
+
|
424
|
+
if not self.site_list:
|
425
|
+
self.site_list = await get_ec_sites()
|
426
|
+
|
427
|
+
if self.station_id:
|
428
|
+
# Convert raw station input to tuple (province_code, station_number)
|
429
|
+
station_number = self.station_id[-3:]
|
430
|
+
province_code = find_province_for_station(self.site_list, station_number)
|
431
|
+
if province_code is None:
|
432
|
+
raise ec_exc.UnknownStationId
|
433
|
+
self._station_tuple = (province_code, station_number)
|
434
|
+
|
435
|
+
# Find lat/lon for the station
|
436
|
+
for site in self.site_list:
|
437
|
+
if (
|
438
|
+
site["Codes"] == f"s0000{self._station_tuple[1].zfill(3)}"
|
439
|
+
and site["Province Codes"] == self._station_tuple[0]
|
440
|
+
):
|
441
|
+
self.lat = site["Latitude"]
|
442
|
+
self.lon = site["Longitude"]
|
443
|
+
break
|
444
|
+
if not self.lat:
|
445
|
+
raise ec_exc.UnknownStationId
|
446
|
+
else:
|
447
|
+
self._station_tuple = closest_site(self.site_list, self.lat, self.lon)
|
448
|
+
if not self._station_tuple:
|
449
|
+
raise ec_exc.UnknownStationId
|
450
|
+
# Set station_id to string format for external API
|
451
|
+
self.station_id = (
|
452
|
+
f"{self._station_tuple[0]}/s0000{self._station_tuple[1].zfill(3)}"
|
453
|
+
)
|
454
|
+
|
455
|
+
self._station_resolved = True
|
456
|
+
|
457
|
+
@property
|
458
|
+
def station_tuple(self):
|
459
|
+
"""Return station ID as a tuple (province_code, station_number) for internal use."""
|
460
|
+
return self._station_tuple
|
461
|
+
|
416
462
|
async def update(self) -> None:
|
417
463
|
"""Get the latest data from Environment Canada."""
|
418
464
|
|
419
465
|
# Clear error at start, any error that is handled will set it
|
420
466
|
self.metadata.last_update_error = ""
|
421
467
|
|
422
|
-
#
|
423
|
-
|
424
|
-
self.site_list = await get_ec_sites()
|
425
|
-
if self.station_id:
|
426
|
-
# Convert raw station input to tuple (province_code, station_number)
|
427
|
-
if isinstance(self.station_id, str):
|
428
|
-
station_number = (
|
429
|
-
self.station_id
|
430
|
-
) # Already normalized by validate_station
|
431
|
-
province_code = find_province_for_station(
|
432
|
-
self.site_list, station_number
|
433
|
-
)
|
434
|
-
if province_code is None:
|
435
|
-
raise ec_exc.UnknownStationId
|
436
|
-
self.station_id = (province_code, station_number)
|
437
|
-
|
438
|
-
# Find lat/lon for the station
|
439
|
-
for site in self.site_list:
|
440
|
-
if (
|
441
|
-
site["Codes"] == f"s0000{self.station_id[1].zfill(3)}"
|
442
|
-
and site["Province Codes"] == self.station_id[0]
|
443
|
-
):
|
444
|
-
self.lat = site["Latitude"]
|
445
|
-
self.lon = site["Longitude"]
|
446
|
-
break
|
447
|
-
if not self.lat:
|
448
|
-
raise ec_exc.UnknownStationId
|
449
|
-
else:
|
450
|
-
self.station_id = closest_site(self.site_list, self.lat, self.lon)
|
451
|
-
if not self.station_id:
|
452
|
-
raise ec_exc.UnknownStationId
|
468
|
+
# Resolve station ID and coordinates if not already done
|
469
|
+
await self._resolve_station()
|
453
470
|
|
454
471
|
LOG.debug(
|
455
472
|
"update(): station %s lat %f lon %f", self.station_id, self.lat, self.lon
|
@@ -460,7 +477,10 @@ class ECWeather:
|
|
460
477
|
async with ClientSession(raise_for_status=True) as session:
|
461
478
|
# Discover the URL for the most recent weather file
|
462
479
|
weather_url = await discover_weather_file_url(
|
463
|
-
session,
|
480
|
+
session,
|
481
|
+
self._station_tuple[0],
|
482
|
+
self._station_tuple[1],
|
483
|
+
self.language,
|
464
484
|
)
|
465
485
|
LOG.debug("Using weather URL: %s", weather_url)
|
466
486
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
env_canada/10x20.pbm,sha256=ClKTs2WUmhUhTHAQzPuGwPTICGVBzCvos5l-vHRBE5M,2463
|
2
2
|
env_canada/10x20.pil,sha256=Oki6-TD7b0xFtfm6vxCKsmpEpsZ5Jaia_0v_aDz8bfE,5143
|
3
3
|
env_canada/__init__.py,sha256=EXzGEHwon-usFzLzuJeISKHlfJdV3DBa0_rR9b_XfvE,405
|
4
|
-
env_canada/constants.py,sha256=
|
4
|
+
env_canada/constants.py,sha256=LIgDz8EI__wlzoI4yz5D9tl-XPoCel8vKk45VON0DIs,33
|
5
5
|
env_canada/ec_aqhi.py,sha256=oE52qfk-AKbHdhTSl5RP3vsWL-50eMRCCRVy9RW-pP4,8080
|
6
6
|
env_canada/ec_cache.py,sha256=zb3n79ul7hUTE0IohDfZbRBLY-siOHPjYzWldMbuPVk,798
|
7
7
|
env_canada/ec_exc.py,sha256=SBJwzmLf94lTx7KYVLfQYrMXYNYUoIxeVXc-BLkuXoE,67
|
@@ -9,9 +9,9 @@ env_canada/ec_historical.py,sha256=qMr4RE6vfNiNa_zFolQ0PQGraok8bQtIVjs_o6sJKD4,1
|
|
9
9
|
env_canada/ec_hydro.py,sha256=JoBe-QVV8GEeZXCNFscIs2R_spgkbxCZpLt7tL6-NUI,4889
|
10
10
|
env_canada/ec_map.py,sha256=936CN6G9ZAY9zQjuph0Xp4f9OwNnHb6qXMnk6M6bE68,15134
|
11
11
|
env_canada/ec_radar.py,sha256=dKZqWJyb66R2EJzAy4K7pii7vPK9FxDKmuW9vA1ADbw,3330
|
12
|
-
env_canada/ec_weather.py,sha256=
|
13
|
-
env_canada-0.11.
|
14
|
-
env_canada-0.11.
|
15
|
-
env_canada-0.11.
|
16
|
-
env_canada-0.11.
|
17
|
-
env_canada-0.11.
|
12
|
+
env_canada/ec_weather.py,sha256=pFcVKBbYKLj01ocjZmy8RiQaf7YVSQOo4id_BbZ7gds,23421
|
13
|
+
env_canada-0.11.1.dist-info/licenses/LICENSE,sha256=BkgGIGgy9sv-OsI7mRi9dIQ3Su0m4IbjpZlfxv8oBbM,1073
|
14
|
+
env_canada-0.11.1.dist-info/METADATA,sha256=c9TtVd3BBxg1sWEdIW9kQBaceHgBWaHSS52tl4ZYsLI,13678
|
15
|
+
env_canada-0.11.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
16
|
+
env_canada-0.11.1.dist-info/top_level.txt,sha256=fw7Pcl9ULBXYvqnAdyBdmwPXW8GSRFmhO0sLZWVfOCc,11
|
17
|
+
env_canada-0.11.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|