async def fetch_hourly_readings_from_db( station_codes: List[int], date_from: datetime, date_to: datetime) -> List[WeatherStationHourlyReadings]: """ Fetch the hourly readings from the database. """ stations = await wfwx_api.get_stations_by_codes(station_codes) with app.db.database.get_read_session_scope() as session: readings = get_hourly_actuals(session, station_codes, date_from, date_to) station_readings = None result = [] for reading in readings: if station_readings is None or reading.station_code != station_readings.station.code: station = next(station for station in stations if station.code == reading.station_code) station_readings = WeatherStationHourlyReadings( station=station, values=[]) result.append(station_readings) weather_reading = WeatherReading( datetime=reading.weather_date, temperature=get(reading.temperature, reading.temp_valid), relative_humidity=get(reading.relative_humidity, reading.rh_valid), wind_speed=get(reading.wind_speed, reading.wspeed_valid), wind_direction=get(reading.wind_direction, reading.wdir_valid), precipitation=get(reading.precipitation, reading.precip_valid), dewpoint=compute_dewpoint(get(reading.temperature), get(reading.relative_humidity)), ffmc=get(reading.ffmc), isi=get(reading.isi), fwi=get(reading.fwi)) station_readings.values.append(weather_reading) return result
def test_wind_speed_valid(): """ 0 to inf is valid for wind_speed""" low_valid = WeatherReading(temperature=None, relative_humidity=None, wind_speed=0, wind_direction=None, precipitation=None) _, _, low_wind_speed_valid, _, _ = get_valid_flags(low_valid) assert low_wind_speed_valid is True high_valid = WeatherReading(temperature=None, relative_humidity=None, wind_speed=math.inf, wind_direction=None, precipitation=None) _, _, high_wind_speed_valid, _, _ = get_valid_flags(high_valid) assert high_wind_speed_valid is True
def test_rh_invalid(): """ Below 0 and above 100 is invalid for rh""" low_valid = WeatherReading(temperature=None, relative_humidity=-1, wind_speed=None, wind_direction=None, precipitation=None) _, low_rh_invalid, _, _, _ = get_valid_flags(low_valid) assert low_rh_invalid is False high_valid = WeatherReading(temperature=None, relative_humidity=101, wind_speed=None, wind_direction=None, precipitation=None) _, high_rh_invalid, _, _, _ = get_valid_flags(high_valid) assert high_rh_invalid is False
def test_rh_valid(): """ 0 to 100 is valid for rh""" low_valid = WeatherReading(temperature=None, relative_humidity=0, wind_speed=None, wind_direction=None, precipitation=None) _, low_rh_valid, _, _, _ = get_valid_flags(low_valid) assert low_rh_valid is True high_valid = WeatherReading(temperature=None, relative_humidity=100, wind_speed=None, wind_direction=None, precipitation=None) _, high_rh_valid, _, _, _ = get_valid_flags(high_valid) assert high_rh_valid is True
def test_temp_invalid(): """ No temp number is invalid""" test_record = WeatherReading(temperature=None, relative_humidity=None, wind_speed=None, wind_direction=None, precipitation=None) temp_valid, _, _, _, _ = get_valid_flags(test_record) assert temp_valid is False
def test_precip_invalid(): """ Below 0 is invalid for precip""" low_valid = WeatherReading(temperature=None, relative_humidity=None, wind_speed=None, wind_direction=None, precipitation=-1) _, _, _, _, low_precip_invalid = get_valid_flags(low_valid) assert low_precip_invalid is False
def parse_hourly(hourly) -> WeatherReading: """ Transform from the raw hourly json object returned by wf1, to our hourly object. """ timestamp = datetime.fromtimestamp( int(hourly['weatherTimestamp']) / 1000, tz=timezone.utc).isoformat() return WeatherReading( datetime=timestamp, temperature=hourly.get('temperature', None), relative_humidity=hourly.get('relativeHumidity', None), dewpoint=compute_dewpoint(hourly.get( 'temperature'), hourly.get('relativeHumidity')), wind_speed=hourly.get('windSpeed', None), wind_direction=hourly.get('windDirection', None), barometric_pressure=hourly.get('barometricPressure', None), precipitation=hourly.get('precipitation', None), ffmc=hourly.get('fineFuelMoistureCode', None), isi=hourly.get('initialSpreadIndex', None), fwi=hourly.get('fireWeatherIndex', None), observation_valid=hourly.get('observationValidInd'), observation_valid_comment=hourly.get('observationValidComment') )