def test_weather_forecasts_are_shifted_by_one_hour(self): historical_weather_range_datetimes = [] hour = hour_now() def stub_weather_task(start, end): if start < hour: historical_weather_range_datetimes.append(start) historical_weather_range_datetimes.append(end) return weather_report_range(start, end) prepare_prediction( no_historical_data, self.stub_generation_task, stub_weather_task, self.model_params, hour, ) weather_reports_and_forecasts = WeatherForecast.query.order_by( WeatherForecast.timestamp ).all() # Rely on LRU cache of weather_report_range raw_weather_data = weather_report_range(*historical_weather_range_datetimes) # check that weather report is present AND shifted by one hour # (re-interpreted as forecast for time t+1) assert ( weather_reports_and_forecasts[0].temperature == raw_weather_data.ix[1, "temperature"] )
def test_missing_data_in_window(self): hour = hour_now() self._insert_full_historical_data(hour, 48) self._delete_generation_reports(hour, 1) with pytest.raises(ValueError): hours_past = 25 window = generation_and_weather_lookback(hour, hours_past)
def test_window_fully_backed_by_historical_data(self): hour = hour_now() self._insert_full_historical_data(hour, 48) hours_past = 25 window = generation_and_weather_lookback(hour, hours_past) self._expect_generation_and_weather_window(window, hours_past)
def prepare_prediction(control_area, city_name, hours_past, hours_predict): """ Prepares database for forecast at the current point in time. """ model = ModelParameters(hours_past, hours_predict) hour = hour_now() generation = partial(generation_task, app.config["BA_NAME"], control_area) weather = partial(weather_task, app.config["WEATHER_API_TOKEN"], city_name) prepare_prediction_task(historical_data, generation, weather, model, hour) print(f"Prepared database for prediction at {hour}")
def test_window_partially_backed_by_historical_data(self): hour = hour_now() self._insert_full_historical_data(hour, 48) self._insert_generation_prediction(hour - timedelta(hours=1)) self._delete_generation_reports(hour, 1) hours_past = 25 window = generation_and_weather_lookback(hour, hours_past) self._expect_generation_and_weather_window(window, hours_past)
def test_forecast_preparation(self): assert len(GenerationReport.query.all()) == 0 assert len(WeatherForecast.query.all()) == 0 hour = hour_now() prepare_prediction( no_historical_data, self.stub_generation_task, self.stub_weather_task, self.model_params, hour, ) generation_reports = GenerationReport.query.order_by( GenerationReport.timestamp ).all() weather_reports_and_forecasts = WeatherForecast.query.order_by( WeatherForecast.timestamp ).all() assert len(generation_reports) == 26 if hour.minute == 0 and hour.second == 0 and hour.microsecond == 0: assert ( len(weather_reports_and_forecasts) == self.model_params.hours_past + self.model_params.hours_predict ) else: assert ( len(weather_reports_and_forecasts) == self.model_params.hours_past + self.model_params.hours_predict + 1 ) # running preparation task again should not update any data generation_reports_copy = generation_reports.copy() weather_reports_copy = weather_reports_and_forecasts.copy() prepare_prediction( db_historical_data, self.stub_generation_task, self.stub_weather_task, self.model_params, hour, ) generation_reports = GenerationReport.query.order_by( GenerationReport.timestamp ).all() weather_reports_and_forecasts = WeatherForecast.query.order_by( WeatherForecast.timestamp ).all() assert generation_reports_copy == generation_reports assert weather_reports_copy == weather_reports_and_forecasts
def test_prediction(self): model = ModelParameters(app.config["MODEL_LOOKBACK"], 1) hour = hour_now() labels = MODEL_FEATURES sample_row = (0.5, 0.5, 1023.0, 1.0, 22.0, 5.0) sample = pd.DataFrame.from_records([sample_row], columns=labels) window = pd.concat([sample] * model.hours_past) prediction_t1 = predict(window, hour) assert ( prediction_t1.renewables_ratio > 0 and prediction_t1.renewables_ratio < 1.0 )
@click.option("--hours_predict", default=6) def prepare_prediction(control_area, city_name, hours_past, hours_predict): """ Prepares database for forecast at the current point in time. """ model = ModelParameters(hours_past, hours_predict) hour = hour_now() generation = partial(generation_task, app.config["BA_NAME"], control_area) weather = partial(weather_task, app.config["WEATHER_API_TOKEN"], city_name) prepare_prediction_task(historical_data, generation, weather, model, hour) print(f"Prepared database for prediction at {hour}") @app.cli.command() @click.option("--city_name", default="Berlin") @click.option("--prediction_time", default=hour_now()) @click.option("--hours_past", default=27) @click.option("--hours_predict", default=1) def predict(city_name, prediction_time, hours_past, hours_predict): """ Makes a prediction at the given point in time based on the generation and weather data available in the database. Stores the prediction in the database. By default, prediction is performed for the current hour. If another prediction time is used, the given time string is interpreted as UTC, e.g. "2018-08-08T19:00". hours_past must align with the pre-trained prediction model. """ model = ModelParameters(hours_past, hours_predict) hour = (
def test_empty_db(self): hour = hour_now() with pytest.raises(ValueError): hours_past = 25 window = generation_and_weather_lookback(hour, hours_past)
def test_historical_data_present(self): generation_reports, weather_forecasts = full_historical_data( hour_now(), 48) assert (is_historical_data_present(generation_reports, weather_forecasts, 48) == True)
def test_historical_data_missing(self): generation_reports, weather_forecasts = partial_historical_data( hour_now(), 48) assert (is_historical_data_present(generation_reports, weather_forecasts, 48) == False)