mirror of
https://github.com/jdejaegh/python-irceline.git
synced 2025-06-26 19:35:40 +02:00
Merge pull request #4 from jdejaegh/use_feature_value_belaqi
Use FeatureValue for some BelAQI functions
This commit is contained in:
commit
7fe28b7783
4 changed files with 30 additions and 21 deletions
|
@ -67,7 +67,7 @@ async def get_current_belaqi():
|
|||
position=(50.85, 4.35) # (lat, lon) for Brussels
|
||||
)
|
||||
|
||||
print(f"Current BelAQI index for Brussels: {result}")
|
||||
print(f"Current BelAQI index for Brussels: {result.get('value')}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -6,7 +6,7 @@ from datetime import datetime, date
|
|||
from typing import Tuple, Dict, Final
|
||||
|
||||
from .api import IrcelineRioClient, IrcelineForecastClient
|
||||
from .data import BelAqiIndex, RioFeature, ForecastFeature
|
||||
from .data import BelAqiIndex, RioFeature, ForecastFeature, FeatureValue
|
||||
|
||||
# Ratio values from Figure 2 at
|
||||
# https://www.irceline.be/en/air-quality/measurements/air-quality-index-november-2022/info_nov2022
|
||||
|
@ -117,7 +117,7 @@ def belaqi_index_hourly(pm10: float, pm25: float, o3: float, no2: float) -> BelA
|
|||
|
||||
|
||||
async def belaqi_index_rio_hourly(rio_client: IrcelineRioClient, position: Tuple[float, float],
|
||||
timestamp: datetime | None = None) -> BelAqiIndex:
|
||||
timestamp: datetime | None = None) -> FeatureValue:
|
||||
"""
|
||||
Get current BelAQI index value for the given position using the rio_client
|
||||
Raise ValueError if one or more components are not available
|
||||
|
@ -128,25 +128,30 @@ async def belaqi_index_rio_hourly(rio_client: IrcelineRioClient, position: Tuple
|
|||
"""
|
||||
if timestamp is None:
|
||||
timestamp = datetime.utcnow()
|
||||
|
||||
features = [RioFeature.PM10_HMEAN, RioFeature.PM25_HMEAN, RioFeature.O3_HMEAN, RioFeature.NO2_HMEAN]
|
||||
|
||||
components = await rio_client.get_data(
|
||||
timestamp=timestamp,
|
||||
features=[RioFeature.PM10_HMEAN,
|
||||
RioFeature.PM25_HMEAN,
|
||||
RioFeature.O3_HMEAN,
|
||||
RioFeature.NO2_HMEAN],
|
||||
features=features,
|
||||
position=position
|
||||
)
|
||||
|
||||
return belaqi_index_hourly(
|
||||
ts = min([components.get(f, {}).get('timestamp') for f in features
|
||||
if components.get(f, {}).get('timestamp') is not None])
|
||||
|
||||
belaqi = belaqi_index_hourly(
|
||||
pm10=components.get(RioFeature.PM10_HMEAN, {}).get('value', -1),
|
||||
pm25=components.get(RioFeature.PM25_HMEAN, {}).get('value', -1),
|
||||
o3=components.get(RioFeature.O3_HMEAN, {}).get('value', -1),
|
||||
no2=components.get(RioFeature.NO2_HMEAN, {}).get('value', -1)
|
||||
)
|
||||
|
||||
return FeatureValue(timestamp=ts, value=belaqi)
|
||||
|
||||
|
||||
async def belaqi_index_forecast_daily(forecast_client: IrcelineForecastClient, position: Tuple[float, float],
|
||||
timestamp: date | None = None) -> Dict[date, BelAqiIndex | None]:
|
||||
timestamp: date | None = None) -> Dict[date, FeatureValue]:
|
||||
"""
|
||||
Get forecasted BelAQI index value for the given position using the forecast_client.
|
||||
Data is downloaded for the given day and the four next days
|
||||
|
@ -169,15 +174,19 @@ async def belaqi_index_forecast_daily(forecast_client: IrcelineForecastClient, p
|
|||
|
||||
result = dict()
|
||||
|
||||
for _, day in components.keys():
|
||||
days = {day for _, day in components.keys()}
|
||||
timestamps = {v.get('timestamp') for v in components.values() if v.get('timestamp') is not None}
|
||||
timestamp = min(timestamps)
|
||||
for day in days:
|
||||
try:
|
||||
result[day] = belaqi_index_daily(
|
||||
belaqi = belaqi_index_daily(
|
||||
pm10=components.get((ForecastFeature.PM10_DMEAN, day), {}).get('value', -1),
|
||||
pm25=components.get((ForecastFeature.PM25_DMEAN, day), {}).get('value', -1),
|
||||
o3=components.get((ForecastFeature.O3_MAXHMEAN, day), {}).get('value', -1) * O3_MAX_HMEAN_TO_MAX8HMEAN,
|
||||
no2=components.get((ForecastFeature.NO2_MAXHMEAN, day), {}).get('value', -1) * NO2_MAX_HMEAN_TO_DMEAN
|
||||
)
|
||||
result[day] = FeatureValue(timestamp=timestamp, value=belaqi)
|
||||
except (ValueError, TypeError):
|
||||
result[day] = None
|
||||
result[day] = FeatureValue(timestamp=timestamp, value=None)
|
||||
|
||||
return result
|
||||
|
|
|
@ -37,12 +37,6 @@ class ForecastFeature(IrcelineFeature):
|
|||
PM25_DMEAN = 'chimere_pm25_dmean'
|
||||
|
||||
|
||||
class FeatureValue(TypedDict):
|
||||
# Timestamp at which the value was computed
|
||||
timestamp: datetime | date
|
||||
value: int | float | None
|
||||
|
||||
|
||||
class BelAqiIndex(Enum):
|
||||
EXCELLENT = 1
|
||||
VERY_GOOD = 2
|
||||
|
@ -54,3 +48,9 @@ class BelAqiIndex(Enum):
|
|||
BAD = 8
|
||||
VERY_BAD = 9
|
||||
HORRIBLE = 10
|
||||
|
||||
|
||||
class FeatureValue(TypedDict):
|
||||
# Timestamp at which the value was computed
|
||||
timestamp: datetime | date
|
||||
value: int | float | BelAqiIndex | None
|
||||
|
|
|
@ -231,7 +231,7 @@ async def test_belaqi_index_forecast():
|
|||
|
||||
assert set(result.keys()) == expected_days
|
||||
for v in result.values():
|
||||
assert v == BelAqiIndex.MODERATE
|
||||
assert v.get('value') == BelAqiIndex.MODERATE
|
||||
|
||||
|
||||
async def test_belaqi_index_forecast_missing_day():
|
||||
|
@ -244,7 +244,7 @@ async def test_belaqi_index_forecast_missing_day():
|
|||
expected_days = {date(2024, 6, 21) + timedelta(days=i) for i in range(5)}
|
||||
assert set(result.keys()) == expected_days
|
||||
for v in result.values():
|
||||
assert v is None
|
||||
assert v.get('value') is None
|
||||
|
||||
|
||||
@freeze_time(datetime.fromisoformat("2024-06-23T12:30:09.581Z"))
|
||||
|
@ -254,7 +254,7 @@ async def test_belaqi_index_actual():
|
|||
pos = (50.55, 4.85)
|
||||
|
||||
result = await belaqi_index_rio_hourly(client, pos)
|
||||
assert result == BelAqiIndex.GOOD
|
||||
assert result.get('value') == BelAqiIndex.GOOD
|
||||
|
||||
|
||||
@freeze_time(datetime.fromisoformat("2024-06-23T12:30:09.581Z"))
|
||||
|
|
Loading…
Add table
Reference in a new issue