Exemplo n.º 1
0
def test_update_vertices():
    # TEST_UPDATE_VERTICES() - test method update_vertices(), which for this base class of LocalAsset does
    # practically nothing and must be redefined by child classes that represent flesible assets.
    print('Running LocalAsset.test_update_vertices()')

    #   Create a test Market.
    test_market = Market()

    #   Create and store a TimeInterval.
    dt = datetime.now(
    )  # datetime that may be used for most datetime arguments
    time_interval = TimeInterval(dt, timedelta(hours=1), test_market, dt, dt)
    test_market.timeIntervals = [time_interval]

    #   Create a test LocalAsset.
    test_model = LocalAsset()

    #   Create and store a scheduled power IntervalValue in the active time interval.
    test_model.scheduledPowers = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ScheduledPower, 50)
    ]

    #   Create maximum and minimum powers.
    test_model.maximumPower = 200
    test_model.minimumPower = 0

    # TEST 1
    print('- Test 1: Basic operation')

    try:
        test_model.update_vertices(test_market)
        print('  - the method ran without errors')
    except RuntimeWarning as cause:
        print('  - the method encountered errors', cause)

    assert len(test_model.activeVertices
               ) == 1, 'There were an unexpected number of active vertices'

    # Success.
    print('Method test_update_vertices ran to completion.\n')
Exemplo n.º 2
0
def test_prod_cost_from_vertices():
    from code.local_asset_model import LocalAsset
    from code.market import Market

    # TEST_PROD_COST_FROM_VERTICES - tests function prod_cost_from_vertices()
    print('Running test_prod_cost_from_vertices()')
    pf = 'pass'

    # Create a test object
    test_object = LocalAsset

    # Create a test market
    test_market = Market()

    # Create several active vertices av
    av = [Vertex(0.02, 5, 0),
          Vertex(0.02, 7, 100),
          Vertex(0.025, 9.25, 200)]

    # Create a time interval
    dt = datetime.now()
    at = dt
    #   NOTE: Function Hours() corrects behavior of Matlab function hours().
    dur = timedelta(hours=1)
    mkt = test_market
    mct = dt
    st = dt
    ti = TimeInterval(at, dur, mkt, mct, st)

    # Create and store the activeVertices, which are IntervalValues
    test_object.activeVertices = [IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[0]),
                                  IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[1]),
                                  IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2])]

    # CASE: Various signed powers when there is more than one vertex
    test_powers = [-50, 0, 50, 150, 250]
    pc = []
    for p in test_powers:
        pc.append(prod_cost_from_vertices(test_object, ti, p))

    # pc(1) = 0: value is always 0 for power < 0
    # pc(2) = 5.0: assign cost from first vertex
    # pc(3) = 6.0: interpolate between vertices
    # pc(4) = 8.125: interpolate between vertices
    # pc(5) = 9.25: use last vertex cost if power > last vertex power

    # if ~all(pc == [0, 5.0, 6.0, 8.125, 9.25])
    expected = [0, 5.0, 6.0, 8.125, 9.25]
    if not all([pc[i] == expected[i] for i in range(len(pc))]):
        pf = 'fail'
        raise Exception('- the production cost was incorrectly calculated')
    else:
        print('- the production cost was correctly calculated')

    # CASE: One vertex (inelastic case, a constant)
    test_object.activeVertices = [
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[0])]

    # pc[i] = prod_cost_from_vertices(test_object, ti, test_powers[i])
    pc = []
    for p in test_powers:
        pc.append(prod_cost_from_vertices(test_object, ti, p))

    expected = [0.0, 5.0, 5.0, 5.0, 5.0]
    # if ~all(pc == [0.0, 5.0, 5.0, 5.0, 5.0])
    if not all([pc[i] == expected[i] for i in range(len(pc))]):
        pf = 'fail'
        raise Exception('- made an incorrect assignment when there is one vertex')
    else:
        print('- made a correct assignment when there is one vertex')

    # CASE: No active vertices (error case):
    test_object.activeVertices = []

    # print('off', 'all')
    try:
        pc = prod_cost_from_vertices(test_object, ti, test_powers[4])
        pf = 'fail'
        # print('on', 'all')
        raise Exception('- the function should have warned and continued when there were no active vertices')
    except:
        print('- the function returned gracefully when there were no active vertices')
        # print('on', 'all')

    #   Success
    print('- the test function ran to completion')
    print('Result: #s\n\n', pf)
Exemplo n.º 3
0
def test_prod_cost_from_formula():
    from code.local_asset_model import LocalAsset
    from code.market import Market

    print('Running test_prod_cost_from_formula()')
    pf = 'pass'

    #   Create a test object
    test_object = LocalAsset()

    #   Create a test market
    test_market = Market()

    #   Create and store the object's cost parameters
    test_object.costParameters = [4, 3, 2]

    #   Create and store three hourly TimeIntervals
    #   Modified to use the TimeInterval constructor.
    dt = datetime.now()
    at = dt
    dur = timedelta(hours=1)
    mkt = test_market
    mct = dt

    st = dt
    ti = [TimeInterval(at, dur, mkt, mct, st)]

    st = st + dur
    ti.append(TimeInterval(at, dur, mkt, mct, st))

    st = st + dur
    ti.append(TimeInterval(at, dur, mkt, mct, st))

    test_market.timeIntervals = ti

    # Create and store three corresponding scheduled powers
    iv = [IntervalValue(test_object, ti[0], test_market, MeasurementType.ScheduledPower, 100),
          IntervalValue(test_object, ti[1], test_market, MeasurementType.ScheduledPower, 200),
          IntervalValue(test_object, ti[2], test_market, MeasurementType.ScheduledPower, 300)]
    test_object.scheduledPowers = iv

    #   Run the test
    pc = [0] * 3
    for i in range(3):
        pc[i] = prod_cost_from_formula(test_object, ti[i])

    # pc(1) = 4 + 3 * 100 + 0.5 * 2 * 100^2 = 10304
    # pc(2) = 4 + 3 * 200 + 0.5 * 2 * 200^2 = 40604
    # pc(3) = 4 + 3 * 300 + 0.5 * 2 * 300^2 = 90904

    # if all(pc ~=[10304, 40604, 90904])
    expected = [10304, 40604, 90904]
    if all([pc[i] != expected[i] for i in range(len(pc))]):
        pf = 'fail'
        raise Exception('- production cost was incorrectly calculated')
    else:
        print('- production cost was correctly calculated')

    #   Success
    print('- the test ran to completion')
    print('Result: #s\n\n', pf)
Exemplo n.º 4
0
def test_production():
    from code.local_asset_model import LocalAsset
    from code.market import Market

    print('Running test_production()')
    pf = 'pass'

    #   Create a test object
    test_object = LocalAsset()

    #   Create a test market
    test_market = Market()

    #   Create several active vertices av
    av = [Vertex(0.0200, 5.00, 0.0),
          Vertex(0.0200, 7.00, 100.0),
          Vertex(0.0250, 9.25, 200.0)]

    # Create a time interval ti
    dt = datetime.now()
    at = dt
    #   NOTE: Function Hours() corrects the behavior of Matlab hours().
    dur = timedelta(hours=1)
    mkt = test_market
    mct = dt
    st = dt
    ti = TimeInterval(at, dur, mkt, mct, st)

    # Assign activeVertices, which are IntervalValues
    test_object.activeVertices = [
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[0]),
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[1]),
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2])]

    # CASE: Various marginal prices when there is more than one vertex
    test_prices = [-0.010, 0.000, 0.020, 0.0225, 0.030]

    p = [0] * len(test_prices)  # zeros(1, length(test_prices))
    for i in range(len(test_prices)):  # for i = 1:length(test_prices)
        p[i] = production(test_object, test_prices[i], ti)

    print('- the function ran without errors')

    # p(1) = 0: below first vertex
    # p(2) = 0: below first vertex
    # p(3) = 100: at first vertex, which has identical marginal price as second
    # p(4) = 150: interpolate between vertices
    # p(5) = 200: exceeds last vertex

    # if ~all(abs(p - [0, 0, 100, 150, 200]) < 0.001):
    expected = [0, 0, 100, 150, 200]
    if not all([p[i] - expected[i] < 0.001 for i in range(len(p))]):
        pf = 'fail'
        raise Exception('- the production cost was incorrectly calculated')
    else:
        print('- the production cost was correctly calculated')

    # CASE: One vertex (inelastic case, a constant)
    test_object.activeVertices = [IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2])]

    for i in range(5):
        p[i] = production(test_object, test_prices[i], ti)

    # if ~all(p == 200 * ones(1, length(p))):
    if not all(x == 200 for x in p):
        pf = 'fail'
        raise Exception('the vertex power should be assigned when there is one vertex')
    else:
        print('- the correct power was assigned when there is one vertex')

    # CASE: No active vertices (error case):
    test_object.activeVertices = []

    try:
        p = production(test_object, test_prices[4], ti)
        pf = 'fail'
        raise Exception('- an error should have occurred with no active vertices')
    except:
        print('- with no vertices, system returned with warnings, as expected')

    #   Success
    print('- the test function ran to completion')
    print('Result: #s\n\n', pf)
Exemplo n.º 5
0
def test_update_costs():
    print('Running AbstractModel.test_update_costs()')

    test_mtn = TransactiveNode()

    #   Create a test market test_mkt
    test_mkt = Market()

    #   Create a sample time interval ti
    dt = datetime.now()
    at = dt
    #   NOTE: Function Hours() corrects behavior of Matlab hours().
    dur = timedelta(hours=1)
    mkt = test_mkt
    mct = dt
    st = datetime.combine(date.today(), time()) + timedelta(hours=20)
    ti = TimeInterval(at, dur, mkt, mct, st)

    #   Save the time interval
    test_mkt.timeIntervals = [ti]

    #   Assign a marginal price in the time interval
    test_mkt.check_marginal_prices(test_mtn)

    #   Create a Neighbor test object and give it a default maximum power value
    # test_obj = Neighbor()
    #     test_obj.maximumPower = 100

    #   Create a corresponding Neighbor.
    test_mdl = Neighbor()

    #   Make sure that the model and object cross-reference one another
    # test_obj.model = test_mdl
    # test_mdl.object = test_obj

    test_mdl.scheduledPowers = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ScheduledPower,
                      100)
    ]
    test_mdl.activeVertices = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ActiveVertex,
                      Vertex(0.05, 0, 100))
    ]

    #   Run a test with a Neighbor object
    print('- running test with a Neighbor:')
    try:
        test_mdl.update_costs(test_mkt)
        print('  - the method encountered no errors')
    except RuntimeWarning:
        print('  - ERRORS ENCOUNTERED')

    assert len(test_mdl.productionCosts
               ) == 1, '  - the method did not store a production cost'
    assert len(
        test_mdl.dualCosts) == 1, '  - the method did not store a dual cost'
    assert test_mdl.totalProductionCost == sum([x.value for x in test_mdl.productionCosts]), \
            '  - the method did not store a total production cost'
    assert test_mdl.totalDualCost == sum([x.value for x in test_mdl.dualCosts]), \
            '  - the method did not store a total dual cost'

    # Run a test again with a LocalAsset.
    # test_obj = LocalAsset()
    test_mdl = LocalAsset()
    # test_obj.model = test_mdl
    # test_mdl.object = test_obj
    test_mdl.maximumPower = 100

    test_mdl.scheduledPowers = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ScheduledPower,
                      100)
    ]
    test_mdl.activeVertices = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ActiveVertex,
                      Vertex(0.05, 0, 100))
    ]

    print('- running test with a LocalAsset:')

    try:
        test_mdl.update_costs(test_mkt)
        print('  - the method encountered no errors')
    except RuntimeWarning:
        print('  - ERRORS ENCOUNTERED')

    assert len(test_mdl.productionCosts
               ) == 1, '  - the method did not store a production cost'
    assert len(
        test_mdl.dualCosts) == 1, '  - the method did not store a dual cost'
    assert test_mdl.totalProductionCost == sum([x.value for x in test_mdl.productionCosts]), \
            '  - the method did not store a total production cost'
    assert test_mdl.totalDualCost == sum([x.value for x in test_mdl.dualCosts]), \
            '  - the method did not store a total dual cost'

    # Success
    print('test_update_costs() ran to completion.\n')
Exemplo n.º 6
0
def test_calculate_reserve_margin():
    # TEST_LAM_CALCULATE_RESERVE_MARGIN() - a LocalAsset ("LAM") class
    # method NOTE: Reserve margins are introduced but not fully integrated into
    # code in early template versions.
    # CASES:
    # 1. uses hard maximum if no active vertices exist
    # 2. vertices exist
    # 2.1 uses maximum vertex power if it is less than hard power constraint
    # 2.2 uses hard constraint if it is less than maximum vertex power
    # 2.3 upper flex power is greater than scheduled power assigns correct
    # positive reserve margin
    # 2.4 upperflex power less than scheduled power assigns zero value to
    # reserve margin.
    print('Running LocalAsset.test_calculate_reserve_margin()')

    # Establish test market
    test_mkt = Market()

    # Establish test market with an active time interval
    # Note: modified 1/29/18 due to new TimeInterval constructor
    dt = datetime.now()
    at = dt
    # NOTE: def Hours() corrects behavior of Matlab hours().
    dur = timedelta(hours=1)
    mkt = test_mkt
    mct = dt
    # st = datetime(date)
    st = datetime.combine(date.today(), time())

    ti = TimeInterval(at, dur, mkt, mct, st)

    # Store time interval
    test_mkt.timeIntervals = [ti]

    # Establish test object that is a LocalAsset.
    test_model = LocalAsset()
    test_model.scheduledPowers = [
        IntervalValue(test_model, ti, test_mkt, MeasurementType.ScheduledPower,
                      0.0)
    ]
    test_model.maximumPower = 100

    # Run the first test case.
    print("  Case 1:")
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    print(test_model.reserveMargins[0].value)

    assert len(test_model.reserveMargins
               ) == 1, 'An unexpected number of results were stored'

    assert test_model.reserveMargins[0].value == test_model.maximumPower, \
                                                                'The method did not use the available maximum power'

    # create some vertices and store them
    iv = [
        IntervalValue(test_model, ti, test_mkt, MeasurementType.Vertex,
                      Vertex(0, 0, -10)),
        IntervalValue(test_model, ti, test_mkt, MeasurementType.Vertex,
                      Vertex(0, 0, 10))
    ]
    test_model.activeVertices = iv

    print("  Case 2: test with maximum power greater than maximum vertex")
    test_model.maximumPower = 100
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert test_model.reserveMargins[
        0].value == 10, 'The method should have used vertex for comparison'

    print("  Case 3: test with maximum power less than maximum vertex")
    test_model.maximumPower = 5
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert test_model.reserveMargins[
        0].value == 5, 'The method should have used maximum power for comparison'

    print("  Case 4: test with scheduled power greater than maximum vertex")
    test_model.scheduledPowers[0].value = 20
    test_model.maximumPower = 500
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)
    print(test_model.reserveMargins[0].value)
    assert test_model.reserveMargins[
        0].value == 0, 'The method should have assigned zero for a neg. result'

    # Success.
    print('Method test_calculate_reserve_margin() ran to completion.\n')
Exemplo n.º 7
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")
Exemplo n.º 8
0
def test_update_production_costs():
    # TEST_UPDATE_PRODUCTION_COSTS() - test method update_production_costs() that calculates production costs from
    # active vertices and scheduled powers.
    # NOTE: This test is virtually identical to the Neighbor test of the same name.
    print('Running LocalAsset.test_update_production_costs()')

    #   Create a test Market.
    test_market = Market()

    #   Create and store a TimeInterval.
    dt = datetime.now(
    )  # datetime that may be used for most datetime arguments
    time_interval = TimeInterval(dt, timedelta(hours=1), test_market, dt, dt)
    test_market.timeIntervals = [time_interval]

    #   Create a test LocalAsset.
    test_model = LocalAsset()

    #   Create and store a scheduled power IntervalValue in the active time interval.
    test_model.scheduledPowers = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ScheduledPower, 50)
    ]

    #   Create and store some active vertices IntervalValues in the active time interval.
    vertices = [Vertex(0.1, 1000, 0), Vertex(0.2, 1015, 100)]
    interval_values = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ActiveVertex, vertices[0]),
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ActiveVertex, vertices[1])
    ]
    test_model.activeVertices = interval_values

    # TEST 1
    print('- Test 1: First calculation of a production cost')

    try:
        test_model.update_production_costs(test_market)
        print('  - the method ran without errors')
    except RuntimeWarning as cause:
        print('  - the method encountered errors', cause)

    assert len(test_model.productionCosts
               ) == 1, 'The wrong number of production costs was created'

    production_cost = test_model.productionCosts[0].value
    assert production_cost == 1007.5, 'An unexpected production cost value was found'

    # TEST 2
    print('- Test 2: Reassignment of an existing production cost')

    #   Configure the test by modifying the scheduled power value.
    test_model.scheduledPowers[0].value = 150

    try:
        test_model.update_production_costs(test_market)
        print('  - the method ran without errors')
    except RuntimeWarning as cause:
        print('  - the method encountered errors', cause)

    assert len(test_model.productionCosts
               ) == 1, 'The wrong number of productions was created'

    production_cost = test_model.productionCosts[0].value

    assert production_cost == 1015, 'An unexpected dual cost value was found'

    # Success.
    print('Method test_update_production_costs() ran to completion.\n')
Exemplo n.º 9
0
def test_update_dual_costs():
    # TEST_UPDATE_DUAL_COSTS() - test method update_dual_costs() that creates or revises the dual costs in active time
    # intervals using active vertices, scheduled powers, and marginal prices.
    # NOTE: This test is virtually identical to the Neighbor test of the same name.
    print('Running LocalAsset.test_update_dual_costs()')

    #   Create a test Market object.
    test_market = Market()

    #   Create and store a TimeInterval object.
    dt = datetime.now(
    )  # datetime that may be used for most datetime arguments
    time_interval = TimeInterval(dt, timedelta(hours=1), test_market, dt, dt)
    test_market.timeIntervals = [time_interval]

    #   Create and store a marginal price IntervalValue object.
    test_market.marginalPrices = [
        IntervalValue(test_market, time_interval, test_market,
                      MeasurementType.MarginalPrice, 0.1)
    ]

    #   Create a test LocalAsset.
    test_model = LocalAsset()

    #   Create and store a scheduled power IntervalValue in the active time interval.
    test_model.scheduledPowers = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ScheduledPower, 100)
    ]

    #   Create and store a production cost IntervalValue in the active time interval.
    test_model.productionCosts = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ProductionCost, 1000)
    ]

    # TEST 1
    print('- Test 1: First calculation of a dual cost')

    try:
        test_model.update_dual_costs(test_market)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert len(test_model.dualCosts
               ) == 1, 'The wrong number of dual cost values was created'

    dual_cost = test_model.dualCosts[0].value

    assert dual_cost == (1000 -
                         100 * 0.1), 'An unexpected dual cost value was found'

    # TEST 2
    print('- Test 2: Reassignment of an existing dual cost')

    #   Configure the test by modifying the marginal price value.
    test_market.marginalPrices[0].value = 0.2

    try:
        test_model.update_dual_costs(test_market)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert len(test_model.dualCosts
               ) == 1, 'The wrong number of dual cost values was created'

    dual_cost = test_model.dualCosts[0].value

    assert dual_cost == (1000 -
                         100 * 0.2), 'An unexpected dual cost value was found'

    # Success.
    print('Method test_update_dual_costs() ran to completion.\n')