Exemplo n.º 1
0
inelastive_load.maximumPower = -50000  # Remember that a load is a negative power [kW]
inelastive_load.minimumPower = -200000  # Assume twice the average PNNL load [kW]
inelastive_load_model = OpenLoopRichlandLoadPredictor(weather_service)
inelastive_load_model.name = 'InelasticLoadModel'
inelastive_load_model.defaultPower = -100420  # [kW]
inelastive_load_model.defaultVertices = [Vertex(float("inf"), 0.0, -100420.0)]
inelastive_load_model.object = inelastive_load
inelastive_load.model = inelastive_load_model
city_market.localAssets.extend([inelastive_load])

# Add Market
market = Market()
market.name = 'dayAhead'
market.commitment = False
market.converged = False
market.defaultPrice = 0.0428  # [$/kWh]
market.dualityGapThreshold = duality_gap_threshold  # [0.02 = 2#]
market.initialMarketState = MarketState.Inactive
market.marketOrder = 1  # This is first and only market
market.intervalsToClear = 1  # Only one interval at a time
market.futureHorizon = timedelta(
    hours=24)  # Projects 24 hourly future intervals
market.intervalDuration = timedelta(hours=1)  # [h] Intervals are 1 h long
market.marketClearingInterval = timedelta(hours=1)  # [h]
market.marketClearingTime = Timer.get_cur_time().replace(
    hour=0, minute=0, second=0, microsecond=0)  # Aligns with top of hour
market.nextMarketClearingTime = market.marketClearingTime + timedelta(hours=1)
city_market.markets.append(market)

# Add Campus
campus_model = Neighbor()
Exemplo n.º 2
0
def test_get_extended_prices():
    print("Running test_get_extended_prices()")
    """
    This base method uses the following prioritization to populate the price horizon needed by this local asset:
        1. Actual marginal prices offered by the market.
        2. Actual marginal prices in prior sequential markets that are similar to the market.
        3. Actual marginal prices in prior markets that are being corrected by the market.
        4. Modeled prices using the market's price model
        5. The market's default price value.
        6. Nothing
    """
    # ******************************************************************************************************************
    print("  Case 1. Actual marginal prices offered by the market."
          )  # *****************************************
    # The test setup is such that the local asset should use Methods 1 to find an existing marginal price in its market.
    now = datetime.now()
    # test_asset = LocalAsset()
    test_asset_model = LocalAsset()
    # test_asset = test_asset_model
    # test_asset_model.object = test_asset
    test_asset_model.schedulingHorizon = timedelta(hours=0.5)
    test_market = Market()
    test_interval = TimeInterval(now, timedelta(hours=1), test_market, now,
                                 now)
    price = 3.14159
    test_price = IntervalValue(None, test_interval, test_market, 'test', price)
    test_market.timeIntervals = [test_interval]
    test_market.marginalPrices = [test_price]
    test_mtn = TransactiveNode()
    test_mtn.markets = [test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert datetime.now() + test_asset_model.schedulingHorizon \
           < test_market.timeIntervals[0].startTime + test_market.intervalDuration, \
        'For this test, the existing marginal price intervals should not extend beyond the scheduling horizon.'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as cause:
        print("  The case encountered errors.", cause)
        price_set = []

    assert len(price_set) == 1, 'An unexpected number of prices was found'
    assert price_set[0].value == price, 'The price was no correct'

    # ******************************************************************************************************************
    print(
        "  Case 2. Actual marginal prices in prior sequential market that is similar to the market."
    )  # ****
    # The test setup is such that the local asset should sequentially use Methods 1, & 2 to find two marginal prices.
    now = datetime.now()

    test_asset_model = LocalAsset()

    test_asset_model.schedulingHorizon = timedelta(
        hours=1.5)  # Should cause asset to use prior market

    test_market = Market()

    test_interval0 = TimeInterval(now, timedelta(hours=1), test_market, now,
                                  now)
    price0 = 3.14159
    test_price0 = IntervalValue(None, test_interval0, test_market, 'test',
                                price0)
    test_market.timeIntervals = [test_interval0]
    test_market.marginalPrices = [test_price0]
    test_market.marketSeriesName = "Test Market"
    test_market.marketClearingTime = now

    prior_market = Market()
    test_interval1 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now)
    test_interval2 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now + timedelta(hours=1))
    price1 = 10
    test_price1 = IntervalValue(None, test_interval1, prior_market, 'test',
                                price1)
    test_price2 = IntervalValue(None, test_interval2, prior_market, 'test',
                                price1)
    prior_market.timeIntervals = [test_interval1, test_interval2]
    prior_market.marginalPrices = [test_price1, test_price2]
    prior_market.marketSeriesName = test_market.marketSeriesName
    prior_market.marketClearingTime = test_market.marketClearingTime - timedelta(
        hours=1)

    test_market.priorMarketInSeries = prior_market  # Important pointer to preceding market interval in market series.

    test_mtn = TransactiveNode()
    test_mtn.markets = [prior_market, test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert len(prior_market.marginalPrices
               ) == 2, "The prior market should have had two prices"
    assert test_market.marketSeriesName == prior_market.marketSeriesName, 'The market names must be the same'
    assert test_market.priorMarketInSeries == prior_market, "The market must point to its predecessor in market series"

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as result:
        print("  The case encountered errors.", result)

    assert len(price_set) == 2, 'An unexpected number of prices was found'
    assert price_set[0].value == price0, 'The first price was not correct'
    assert price_set[1].value == price1, 'The second price was not correct'

    # ******************************************************************************************************************
    print(
        "  Case 3. Actual marginal prices in prior markets that are being corrected by the market."
    )  # *******
    # The test setup is such that the local asset should sequentially use Methods 1, 2, & 3 to find three marginal
    # prices.
    now = datetime.now()
    # test_asset = LocalAsset()
    test_asset_model = LocalAsset()
    # test_asset.model = test_asset_model
    # test_asset_model.object = test_asset
    test_asset_model.schedulingHorizon = timedelta(
        hours=2.5)  # Should cause asset to use prior market

    test_market = Market()

    test_interval0 = TimeInterval(now, timedelta(hours=1), test_market, now,
                                  now)
    price0 = 3.14159
    test_price0 = IntervalValue(None, test_interval0, test_market, 'test',
                                price0)
    test_market.timeIntervals = [test_interval0]
    test_market.marginalPrices = [test_price0]
    test_market.marketSeriesName = "Test Market"
    test_market.marketClearingTime = now

    prior_market = Market()
    test_interval1 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now)
    test_interval2 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now + timedelta(hours=1))
    price1 = 10
    test_price1 = IntervalValue(None, test_interval1, prior_market, 'test',
                                price1)
    test_price2 = IntervalValue(None, test_interval2, prior_market, 'test',
                                price1)
    prior_market.timeIntervals = [test_interval1, test_interval2]
    prior_market.marginalPrices = [test_price1, test_price2]
    prior_market.marketSeriesName = test_market.marketSeriesName
    prior_market.marketClearingTime = test_market.marketClearingTime - timedelta(
        hours=1)

    test_market.priorMarketInSeries = prior_market

    corrected_market = Market()
    price2 = 20
    test_interval3 = TimeInterval(now, timedelta(hours=1), corrected_market,
                                  now, now + timedelta(hours=2))
    test_price3 = IntervalValue(None, test_interval1, corrected_market, 'test',
                                price2)
    test_price4 = IntervalValue(None, test_interval2, corrected_market, 'test',
                                price2)
    test_price5 = IntervalValue(None, test_interval3, corrected_market, 'test',
                                price2)
    corrected_market.timeIntervals = [
        test_interval1, test_interval2, test_interval3
    ]
    corrected_market.marginalPrices = [test_price3, test_price4, test_price5]
    corrected_market.marketSeriesName = "Corrected Market"
    corrected_market.marketClearingTime = test_market.marketClearingTime - timedelta(
        hours=2)
    corrected_market.intervalDuration = timedelta(hours=1)

    test_market.priorRefinedMarket = corrected_market

    test_mtn = TransactiveNode()
    test_mtn.markets = [corrected_market, prior_market, test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert len(prior_market.marginalPrices
               ) == 2, "The prior market should have had two prices"
    assert len(corrected_market.marginalPrices
               ) == 3, 'The corrected market should have three prices'
    assert test_market.marketSeriesName == prior_market.marketSeriesName, 'The market names must be the same'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as result:
        print("  The case encountered errors.", result)
        price_set = []

    assert len(price_set) == 3, 'An unexpected number of prices was found'
    assert price_set[0].value == price0, 'The first price was not correct'
    assert price_set[1].value == price1, 'The second price was not correct'
    assert price_set[2].value == price2, 'The third price was not correct'

    # ******************************************************************************************************************
    print("  Case 4. Modeled prices using the market's price model."
          )  # ***********************************************
    # The test setup is such that the local asset should use Methods 1 & 4 to find four marginal prices.
    now = datetime.now()
    test_asset_model = LocalAsset()
    test_asset_model.schedulingHorizon = timedelta(
        hours=3.5)  # Should cause asset to use prior market

    test_market = Market()

    test_interval0 = TimeInterval(now, timedelta(hours=1), test_market, now,
                                  now)
    price0 = 3.14159
    test_price0 = IntervalValue(None, test_interval0, test_market, 'test',
                                price0)
    test_market.timeIntervals = [test_interval0]
    test_market.marginalPrices = [test_price0]
    test_market.marketSeriesName = "Test Market"
    test_market.marketClearingTime = now
    test_market.priorMarketInSeries = None
    test_market.priorRefinedMarket = None
    avg_price = 30
    std_price = 0.1
    test_market.priceModel = [avg_price, std_price
                              ] * 24  # Critical to this test
    test_mtn = TransactiveNode()
    test_mtn.markets = [test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert len(test_market.priceModel
               ) == 48, 'A price model must exist for all 2 * 24 hours'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as result:
        print("  The case encountered errors.", result)
        price_set = []

    # 200207DJH: The assignment of modeled prices now completes the prior successful method to the top of the next hour.
    #            Thereafter, modeled prices are assigned through the top of the hour that exceeds the scheduling
    #            horizon. Therefore, there is some variability in the count of
    assert len(price_set) == 4 or len(price_set) == 5, \
        ('An unexpected number', len(price_set), ' of prices was found')
    assert price_set[0].value == price0, 'The first price was not correct'
    assert all([price_set[x].value == avg_price for x in range(1, len(price_set))]), \
        'Prices 1 - 4 were not correct'

    # ******************************************************************************************************************
    print("  Case 5. The market's default price value."
          )  # ************************************************************

    test_asset_model = LocalAsset()

    test_asset_model.schedulingHorizon = timedelta(hours=4.5)

    test_market = Market()
    default_price = 1.2345
    test_market.defaultPrice = default_price
    test_market.priceModel = None
    test_market.intervalsToClear = 24
    test_market.intervalDuration = timedelta(hours=1)
    test_market.activationLeadTime = timedelta(days=2)
    test_market.priorRefinedMarket = None

    test_mtn = TransactiveNode()
    test_mtn.markets = [test_market]

    assert type(test_market.defaultPrice
                ) == float, 'A valid default price must be defined'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning:
        print("  The case encountered errors.")

    assert len(price_set) == 5, 'The number of horizon prices was unexpected'
    assert all([price_set[x].value == default_price for x in range(1, len(price_set))]), \
        'The default prices were not used'

    print("Method test_get_extended_prices() ran to completion.\n")