Beispiel #1
0
def parse_noon_forecast(station_code, forecast) -> NoonForecast:
    """ Transform from the raw forecast json object returned by wf1, to our noon forecast object.
    """
    timestamp = datetime.fromtimestamp(
        int(forecast['weatherTimestamp']) / 1000, tz=timezone.utc).isoformat()
    noon_forecast = NoonForecast(
        weather_date=timestamp,
        created_at=get_utc_now(),
        wfwx_update_date=forecast.get('updateDate', None),
        station_code=station_code,
        temperature=forecast.get('temperature', math.nan),
        relative_humidity=forecast.get('relativeHumidity', math.nan),
        wind_speed=forecast.get('windSpeed', math.nan),
        wind_direction=forecast.get('windDirection', math.nan),
        precipitation=forecast.get('precipitation', math.nan),
        gc=forecast.get('grasslandCuring', math.nan),
        ffmc=forecast.get('fineFuelMoistureCode', math.nan),
        dmc=forecast.get('duffMoistureCode', math.nan),
        dc=forecast.get('droughtCode', math.nan),
        isi=forecast.get('initialSpreadIndex', math.nan),
        bui=forecast.get('buildUpIndex', math.nan),
        fwi=forecast.get('fireWeatherIndex', math.nan),
    )
    temp_valid, rh_valid, wdir_valid, wspeed_valid, precip_valid = get_valid_flags(noon_forecast)
    noon_forecast.temp_valid = temp_valid
    noon_forecast.rh_valid = rh_valid
    noon_forecast.wdir_valid = wdir_valid
    noon_forecast.wspeed_valid = wspeed_valid
    noon_forecast.precip_valid = precip_valid
    return noon_forecast
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
def parse_hourly_actual(station_code: int, hourly):
    """ Transform from the raw hourly json object returned by wf1, to our hour actual object.
    """
    timestamp = datetime.fromtimestamp(
        int(hourly['weatherTimestamp']) / 1000, tz=timezone.utc).isoformat()
    hourly_actual = HourlyActual(
        weather_date=timestamp,
        station_code=station_code,
        temperature=hourly.get('temperature', math.nan),
        relative_humidity=hourly.get('relativeHumidity', math.nan),
        dewpoint=compute_dewpoint(hourly.get(
            'temperature'), hourly.get('relativeHumidity')),
        wind_speed=hourly.get('windSpeed', math.nan),
        wind_direction=hourly.get('windDirection', math.nan),
        precipitation=hourly.get('precipitation', math.nan),
        ffmc=hourly.get('fineFuelMoistureCode', None),
        isi=hourly.get('initialSpreadIndex', None),
        fwi=hourly.get('fireWeatherIndex', None),
    )
    temp_valid, rh_valid, wdir_valid, wspeed_valid, precip_valid = get_valid_flags(hourly_actual)
    hourly_actual.temp_valid = temp_valid
    hourly_actual.rh_valid = rh_valid
    hourly_actual.wdir_valid = wdir_valid
    hourly_actual.wspeed_valid = wspeed_valid
    hourly_actual.precip_valid = precip_valid

    observation_valid = hourly.get('observationValidInd')
    observation_valid_comment = hourly.get('observationValidComment')
    if observation_valid is None or bool(observation_valid) is False:
        logger.warning("Invalid hourly received from WF1 API for station code %s at time %s: %s",
                       station_code,
                       hourly_actual.weather_date,
                       observation_valid_comment)

    is_obs_invalid = not temp_valid and not rh_valid and not wdir_valid\
        and not wspeed_valid and not precip_valid

    if is_obs_invalid:
        logger.error("Hourly actual not written to DB for station code %s at time %s: %s",
                     station_code, hourly_actual.weather_date,
                     observation_valid_comment)

    # don't write the HourlyActual to our database if every value is invalid. If even one
    # weather variable observed is valid, write the HourlyActual to DB.
    return None if is_obs_invalid else hourly_actual