def test_start_off_with_initial_down_time_equal_to_min_down_time():
    forward_data = pd.DataFrame({
        'interval': [0, 1, 2],
        'nsw-energy': [200, 200, 200]
    })

    p = planner.DispatchPlanner(dispatch_interval=60, planning_horizon=3)

    u = units.GenericUnit(p, initial_dispatch=0.0)
    u.set_service_region('energy', 'nsw')
    u.add_to_market_energy_flow(100.0)
    u.add_primary_energy_source(100.0)
    u.add_unit_minimum_operating_level(min_loading=50.0,
                                       shutdown_ramp_rate=100.0,
                                       start_up_ramp_rate=100.0,
                                       min_up_time=60,
                                       min_down_time=120,
                                       time_in_initial_state=120)

    p.add_regional_market('nsw', 'energy', forward_data)

    p.optimise()

    dispatch = u.get_dispatch()

    expect_dispatch = pd.DataFrame({
        'interval': [0, 1, 2],
        'net_dispatch': [100.0, 100.0, 100.0]
    })

    assert_frame_equal(expect_dispatch, dispatch)
def test_energy_storage_over_two_intervals_with_inelastic_prices():
    forward_data = pd.DataFrame({'interval': [0, 1], 'nsw-energy': [100, 200]})

    p = planner.DispatchPlanner(dispatch_interval=60, planning_horizon=2)

    u = units.GenericUnit(p, initial_dispatch=0.0)
    u.set_service_region('energy', 'nsw')
    u.add_to_market_energy_flow(capacity=100.0)
    u.add_from_market_energy_flow(capacity=100.0)
    u.add_storage(mwh=100.0,
                  initial_mwh=0.0,
                  output_capacity=100.0,
                  input_capacity=100.0,
                  output_efficiency=1.0,
                  input_efficiency=1.0)

    p.add_regional_market('nsw', 'energy', forecast=forward_data)

    p.optimise()

    dispatch = u.get_dispatch()

    expect_dispatch = pd.DataFrame({
        'interval': [0, 1],
        'net_dispatch': [-100.0, 100.0]
    })

    assert_frame_equal(expect_dispatch, dispatch)
def test_energy_storage_over_three_intervals_with_elastic_prices():
    historical_data = pd.DataFrame({
        'interval':
        np.linspace(0, 100, num=101).astype(int),
        'nsw-energy':
        np.linspace(0, 500, num=101),
        'nsw-demand':
        np.linspace(0, 500, num=101)
    })

    forward_data = pd.DataFrame({
        'interval': [0, 1, 2],
        'nsw-demand': [100.0, 400.0, 400.0]
    })

    f = planner.Forecaster()
    f.train(historical_data,
            train_sample_fraction=1.0,
            target_col='nsw-energy')
    price_forecast = f.price_forecast_with_generation_sensitivities(
        forward_data,
        region='nsw',
        market='energy',
        min_delta=-50,
        max_delta=50,
        steps=100)

    p = planner.DispatchPlanner(dispatch_interval=60, planning_horizon=3)

    u = units.GenericUnit(p, initial_dispatch=0.0)
    u.set_service_region('energy', 'nsw')
    u.add_to_market_energy_flow(capacity=50.0)
    u.add_from_market_energy_flow(capacity=50.0)
    u.add_storage(mwh=50.0,
                  initial_mwh=0.0,
                  output_capacity=50.0,
                  input_capacity=50.0,
                  output_efficiency=1.0,
                  input_efficiency=1.0)

    p.add_regional_market('nsw', 'energy', forecast=price_forecast)

    p.optimise()

    dispatch = u.get_dispatch()

    expect_dispatch = pd.DataFrame({
        'interval': [0, 1, 2],
        'net_dispatch': [-50.0, 25.0, 25.0]
    })

    assert_frame_equal(expect_dispatch, dispatch)
def test_initial_down_time_cold_start_costs_should_turn_on():
    forward_data = pd.DataFrame({
        'interval': [0, 1, 2, 3, 4, 5],
        'nsw-energy': [200.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    })

    p = planner.DispatchPlanner(dispatch_interval=60, planning_horizon=6)

    u = units.GenericUnit(p, initial_dispatch=0.0)
    u.set_service_region('energy', 'nsw')
    u.add_to_market_energy_flow(100.0)
    u.add_primary_energy_source(100.0, cost=100.0)

    u.add_unit_minimum_operating_level(min_loading=50.0,
                                       shutdown_ramp_rate=100.0,
                                       start_up_ramp_rate=100.0,
                                       min_up_time=60,
                                       min_down_time=60,
                                       time_in_initial_state=60 * 9)

    hot_start_cost = 100 * 100 - 1
    cold_start_cost = hot_start_cost * 2

    u.add_startup_costs(hot_start_cost=hot_start_cost,
                        cold_start_cost=cold_start_cost,
                        time_to_go_cold=60 * 10)

    p.add_regional_market('nsw', 'energy', forward_data)

    p.optimise()

    dispatch = u.get_dispatch()

    expect_dispatch = pd.DataFrame({
        'interval': [0, 1, 2, 3, 4, 5],
        'net_dispatch': [100.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    })

    assert_frame_equal(expect_dispatch, dispatch)
Exemple #5
0
# Get historical price data for forecast period.
price_data = historical_inputs.get_regional_prices(start_time_forward_data,
                                                   end_time_forward_data,
                                                   raw_data_cache)
price_data = price_data.reset_index(drop=True)
price_data['interval'] = price_data.index

# Do dispatch planning assuming price taker assumption. Planner uses actual historical price data and assumes
# fleet dispatch does not impact price.
price_taker_planner = planner.DispatchPlanner(dispatch_interval=5,
                                              planning_horizon=len(
                                                  forward_data.index))

# Add unit commitment model to dispatch planner
battery_storage = units.GenericUnit(price_taker_planner, initial_dispatch=0.0)
battery_storage.set_service_region('energy', 'nsw')
battery_storage.add_to_market_energy_flow(capacity=1000.0)
battery_storage.add_from_market_energy_flow(capacity=1000.0)
battery_storage.add_storage(mwh=4000.0,
                            initial_mwh=2000.0,
                            output_capacity=1000.0,
                            input_capacity=1000.0,
                            output_efficiency=0.9,
                            input_efficiency=0.9)

price_taker_planner.add_regional_market('nsw',
                                        'energy',
                                        forecast=baseline_forecast)
price_taker_planner.optimise()