def test_update_vertices():
    # TEST_UPDATE_VERTICES() - test method update_vertices(), which for this
    # base class of LocalAssetModel does practically nothing and must be
    # redefined by child classes that represent flesible assets.
    print('Running LocalAssetModel.test_update_vertices()')
    pf = 'pass'

    #   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 a test LocalAssetModel object.
    test_model = LocalAssetModel()

    #   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 a LocalAsset object and its maximum and minimum powers.
    test_object = LocalAsset()
    test_object.maximumPower = 200
    test_object.minimumPower = 0

    #   Have the LocalAsset model and object cross reference one another.
    test_object.model = test_model
    test_model.object = test_object

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

    test_model.update_vertices(test_market)
    print('  - the method ran without errors')

    if len(test_model.activeVertices) != 1:
        pf = 'fail'
        print('  - there is an unexpected number of active vertices')
    else:
        print('  - the expected number of active vertices was found')

    # Success.
    print('- the test ran to completion')
    print('\nResult: #s\n\n', pf)
def test_calculate_reserve_margin():
    # TEST_LAM_CALCULATE_RESERVE_MARGIN() - a LocalAssetModel ("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 LocalAssetModel.test_calculate_reserve_margin()')

    pf = 'pass'

    # 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 a test object that is a LocalAsset with assigned maximum power
    test_object = LocalAsset()
    test_object.maximumPower = 100

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

    # Allow object and model to cross-reference one another.
    test_object.model = test_model
    test_model.object = test_object

    # Run the first test case.
    test_model.calculate_reserve_margin(test_mkt)
    print('- method ran without errors')

    if len(test_model.reserveMargins) != 1:
        raise Exception('- an unexpected number of results were stored')
    else:
        print('- one reserve margin was stored, as expected')

    if test_model.reserveMargins[0].value != test_object.maximumPower:
        pf = 'fail'
        raise Exception('- the method did not use the available maximum power')
    else:
        print('- the method used maximum power value, as expected')

    # 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

    # run test with maximum power greater than maximum vertex
    test_object.maximumPower = 100
    test_model.calculate_reserve_margin(test_mkt)

    if test_model.reserveMargins[0].value != 10:
        pf = 'fail'
        raise Exception('- the method should have used vertex for comparison')
    else:
        print('- the method correctly chose to use the vertex power')

    # run test with maximum power less than maximum vertex
    test_object.maximumPower = 5
    test_model.calculate_reserve_margin(test_mkt)

    if test_model.reserveMargins[0].value != 5:
        pf = 'fail'
        raise Exception('- method should have used maximum power for comparison')
    else:
        print('- the method properly chose to use the maximum power')

    # run test with scheduled power greater than maximum vertex
    test_model.scheduledPowers[0].value = 20
    test_object.maximumPower = 500
    test_model.calculate_reserve_margin(test_mkt)

    if test_model.reserveMargins[0].value != 0:
        pf = 'fail'
        raise Exception('- method should have assigned zero for a neg. result')
    else:
        print('- the method properly assigned 0 for a negative result')

    # Success.
    print('- the test ran to completion')
    print('\nResult: #s\n\n', pf)
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 NeighborModel test of the
    # same name.
    print('Running LocalAssetModel.test_update_dual_costs()')
    pf = 'pass'

    #   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 LocalAssetModel object.
    test_model = LocalAssetModel()

    #   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 object 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')

    test_model.update_dual_costs(test_market)
    print('  - the method ran without errors')

    if len(test_model.dualCosts) != 1:
        pf = 'fail'
        print('  - the wrong number of dual cost values was created')
    else:
        print('  - the right number of dual cost values was created')

    dual_cost = test_model.dualCosts[0].value

    if dual_cost != (1000 - 100 * 0.1):
        pf = 'fail'
        print('  - an unexpected dual cost value was found')
    else:
        print('  - the expected 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

    test_model.update_dual_costs(test_market)
    print('  - the method ran without errors')

    if len(test_model.dualCosts) != 1:
        pf = 'fail'
        print('  - the wrong number of dual cost values was created')
    else:
        print('  - the right number of dual cost values was created')

    dual_cost = test_model.dualCosts[0].value

    if dual_cost != (1000 - 100 * 0.2):
        pf = 'fail'
        print('  - an unexpected dual cost value was found')
    else:
        print('  - the expected dual cost value was found')

    # Success.
    print('- the test ran to completion')
    print('\nResult: #s\n\n', pf)
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 NeighborModel test of the
    # same name.
    print('Running LocalAssetModel.test_update_production_costs()')
    pf = 'pass'

    #   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 a test LocalAssetModel object.
    test_model = LocalAssetModel()

    #   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 IntervalValue objects 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')

    test_model.update_production_costs(test_market)
    print('  - the method ran without errors')

    if len(test_model.productionCosts) != 1:
        pf = 'fail'
        print('  - the wrong number of production costs was created')
    else:
        print('  - the right number of production cost values was created')

    production_cost = test_model.productionCosts[0].value

    if float(production_cost) != float(1007.5):
        pf = 'fail'
        print('  - an unexpected production cost value was found')
    else:
        print('  - the expected 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

    test_model.update_production_costs(test_market)
    print('  - the method ran without errors')

    if len(test_model.productionCosts) != 1:
        pf = 'fail'
        print('  - the wrong number of productions was created')
    else:
        print('  - the right number of production cost values was created')

    production_cost = test_model.productionCosts[0].value

    if float(production_cost) != float(1015):
        pf = 'fail'
        print('  - an unexpected dual cost value was found')
    else:
        print('  - the expected dual cost value was found')

    # Success.
    print('- the test ran to completion')
    print('\nResult: #s\n\n', pf)
def test_schedule_engagement():
    # TEST_SCHEDULE_ENGAGEMENT() - tests a LocalAssetModel method called
    # schedule_engagment()

    print('Running LocalAssetModel.test_schedule_engagement()')

    pf = 'pass'

    #   Establish test market
    test_mkt = Market()

    #   Establish test market with two distinct active time intervals
    # Note: This changed 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.combine(date.today(), time())  # datetime(date)

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

    st = ti[0].startTime + dur
    ti.append(TimeInterval(at, dur, mkt, mct, st))

    #   store time intervals
    test_mkt.timeIntervals = ti

    #   Establish test object that is a LocalAssetModel
    test_object = LocalAssetModel()

    #   Run the first test case.
    test_object.schedule_engagement(test_mkt)

    #   Were the right number of engagement schedule values created?
    if len(test_object.engagementSchedule) != 2:
        pf = 'fail'
        raise Exception('- the method did not store the engagement schedule')
    else:
        print('- the method stored the right number of results')

    # Where the correct scheduled engagement values stored?
    if len([x.value for x in test_object.engagementSchedule if x.value != 1]) > 0:
        pf = 'fail'
        raise Exception('- the stored engagement schedule was not as expected')
    else:
        print('- the result values were as expected')

    # Create and store another active time interval.
    st = ti[1].startTime + dur
    ti.append(TimeInterval(at, dur, mkt, mct, st))

    #   Re-store time intervals
    test_mkt.timeIntervals = ti

    #   Run next test case.
    test_object.schedule_engagement(test_mkt)

    #   Was the new time interval used?
    if len(test_object.engagementSchedule) != 3:
        pf = 'fail'
        raise Exception('- the method apparently failed to create a new engagement')
    else:
        print('- the method created and stored new values')

    # Were the existing time interval values reassigned properly?
    # if any([test_object.engagementSchedule.value] != true * ones(1, 3)):
    if any([x.value != 1 for x in test_object.engagementSchedule]):
        pf = 'fail'
        raise Exception('- the existing list was not augmented as expected')

    # Success.
    print('- the test ran to completion')
    print('\nResult: #s\n\n', pf)
def test_schedule_power():
    # TEST_SCHEDULE_POWER() - tests a LocalAssetModel method called
    # schedule_power().

    print('Running LocalAssetModel.test_schedule_power()')

    pf = 'pass'

    #   Establish test market
    test_mkt = Market

    #   Establish test market with two distinct active time intervals
    # Note: This changed 1/29/19 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.combine(date.today(), time())  # datetime(date)

    ti = [TimeInterval(at, dur, mkt, mct, st)]
    st = ti[0].startTime + dur
    ti.append(TimeInterval(at, dur, mkt, mct, st))

    #   Store time intervals
    test_mkt.timeIntervals = ti

    #   Establish test object that is a LocalAssetModel with a default power
    #   property.
    test_object = LocalAssetModel()
    test_object.defaultPower = 3.14159

    #   Run the first test case.
    test_object.schedule_power(test_mkt)

    #   Were the right number of schduled power values created?
    if len(test_object.scheduledPowers) != 2:
        pf = 'fail'
        raise Exception('- the method did not store the right number of results')
    else:
        print('- the method stored the right number of results')

    # Where the correct scheduled power valules stored?
    # if any([test_object.scheduledPowers.value] != test_object.defaultPower * ones(1, 2))
    if any([x.value != test_object.defaultPower for x in test_object.scheduledPowers]):
        pf = 'fail'
        raise Exception('- the stored scheduled powers were not as expected')
    else:
        print('- the result value was as expected')

    # Change the default power.
    test_object.defaultPower = 6

    #   Create and store another active time interval.
    st = ti[1].startTime + dur
    ti.append(TimeInterval(at, dur, mkt, mct, st))

    #   Re-store time intervals
    test_mkt.timeIntervals = ti

    #   Run next test case.
    test_object.schedule_power(test_mkt)

    #   Was the new time interval used?
    if len(test_object.scheduledPowers) != 3:
        pf = 'fail'
        raise Exception('- the method failed to create a new scheduled power')

    # Were the existing time intervals reassigned properly?
    # if any([test_object.scheduledPowers.value] != test_object.defaultPower * ones(1, 3))
    if any([x.value != test_object.defaultPower for x in test_object.scheduledPowers]):
        pf = 'fail'
        raise Exception('- existing scheduled powers were not reassigned properly')

    # Success.
    print('- the test ran to completion')
    print('\nResult: #s\n\n', pf)
Esempio n. 7
0
def test_schedule():
    print('Running AbstractModel.test_schedule()')
    pf = 'pass'

    #   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
    # NOTE: Function Hours() corrects behavior of Matlab hours().
    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()

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

    #   Create a corresponding NeighborModel
    test_mdl = NeighborModel()

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

    #   Run a test with a NeighborModel object
    print('- running test with a NeighborModel:')

    test_mdl.schedule(test_mkt)
    print('  - the method encountered no errors')

    if len(test_mdl.scheduledPowers) != 1:
        pf = 'fail'
        raise '  - the method did not store a scheduled power'
    else:
        print('  - the method calculated and stored a scheduled power')

    if len(test_mdl.reserveMargins) != 1:
        pf = 'fail'
        raise '  - the method did not store a reserve margin'
    else:
        print('  - the method stored a reserve margin')

    if len(test_mdl.activeVertices) != 1:
        pf = 'fail'
        raise '  - the method did not store an active vertex'
    else:
        print('  - the method stored an active vertex')

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

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

    test_mdl.schedule(test_mkt)
    print('  - the method encountered no errors')

    if len(test_mdl.scheduledPowers) != 1:
        pf = 'fail'
        raise '  - the method did not store a scheduled power'
    else:
        print('  - the method calculated and stored a scheduled power')

    if len(test_mdl.reserveMargins) != 1:
        pf = 'fail'
        raise '  - the method did not store a reserve margin'
    else:
        print('  - the method stored a reserve margin')

    if len(test_mdl.activeVertices) != 1:
        pf = 'fail'
        raise '  - the method did not store an active vertex'
    else:
        print('  - the method stored an active vertex')

    # Success
    print('- the test ran to completion')
    print('Result: %s', pf)
def test_engagement_cost():
    print('Running LocalAssetModel.test_engagement_cost()')
    pf = 'pass'

    #   Create a test LocalAssetModel object.
    test_model = LocalAssetModel()

    #   Assign engagement costs for [dissengagement, hold, engagement]
    test_model.engagementCost = [1, 2, 3]

    ## TEST 1
    print('- Test 1: Normal transition input arguments [-1,0,1]')

    transition = 0  # false - false  # a hold transition, unchanged

    cost = test_model.engagement_cost(transition)
    print('  - the method ran without errors')

    if cost != 2:
        pf = 'fail'
        print('  - the method miscalculated the cost of a hold')
    else:
        print('  - the method correctly calculated the cost of a hold')

    transition = -1  # false - true  # an disengagement transition

    cost = test_model.engagement_cost(transition)

    if cost != 1:
        pf = 'fail'
        print('  - the method miscalculated the cost of a disengagement')
    else:
        print('  - the method correctly calculated the cost of a disengagement')

    transition = 1  # true - false  # an disengagement transition

    cost = test_model.engagement_cost(transition)

    if cost != 3:
        pf = 'fail'
        print('  - the method miscalculated the cost of an engagement')
    else:
        print('  - the method correctly calculated the cost of an engagement')

    ## TEST 2
    print('- Test 2: Unexpected, dissallowed input argument')

    transition = 7  # a disallowed transition

    cost = test_model.engagement_cost(transition)
    print('  - method warned and returned gracefully')

    if cost != 0:
        pf = 'fail'
        print('  - the method assigned a cost value other than zero')
    else:
        print('  - the method correctly assigned zero to the cost')

    # Success.
    print('- the test ran to completion')
    print('\nResult: #s\n\n', pf)
Esempio n. 9
0
def test_update_costs():
    print('Running AbstractModel.test_update_costs()')

    pf = 'pass'

    #   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()

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

    #   Create a corresponding NeighborModel
    test_mdl = NeighborModel()

    #   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 NeighborModel object
    print('- running test with a NeighborModel:')
    try:
        test_mdl.update_costs(test_mkt)
        print('  - the method encountered no errors')
    except:
        pf = 'fail'
        raise '  - the method did not run without errors'

    if len(test_mdl.productionCosts) != 1:
        pf = 'fail'
        raise '  - the method did not store a production cost'
    else:
        print('  - the method calculated and stored a production cost')

    if len(test_mdl.dualCosts) != 1:
        pf = 'fail'
        raise '  - the method did not store a dual cost'
    else:
        print('  - the method stored a dual cost')

    if test_mdl.totalProductionCost != sum(
        [x.value for x in test_mdl.productionCosts]):
        pf = 'fail'
        raise '  - the method did not store a total production cost'
    else:
        print('  - the method stored an total production cost')

    if test_mdl.totalDualCost != sum([x.value for x in test_mdl.dualCosts]):
        pf = 'fail'
        raise '  - the method did not store a total dual cost'
    else:
        print('  - the method stored an total dual cost')

    # Run a test again with a LocalAssetModel object
    test_obj = LocalAsset()
    #     test_obj.maximumPower = 100
    test_mdl = LocalAssetModel()
    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))
    ]

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

    try:
        test_mdl.update_costs(test_mkt)
        print('  - the method encountered no errors')
    except:
        pf = 'fail'
        raise '  - the method did not run without errors'

    if len(test_mdl.productionCosts) != 1:
        pf = 'fail'
        raise '  - the method did not store a production cost'
    else:
        print('  - the method calculated and stored a production cost')

    if len(test_mdl.dualCosts) != 1:
        pf = 'fail'
        raise '  - the method did not store a dual cost'
    else:
        print('  - the method stored a dual cost')

    if test_mdl.totalProductionCost != sum(
        [x.value for x in test_mdl.productionCosts]):
        pf = 'fail'
        raise '  - the method did not store a total production cost'
    else:
        print('  - the method stored an total production cost')

    if test_mdl.totalDualCost != sum([x.value for x in test_mdl.dualCosts]):
        pf = 'fail'
        raise '  - the method did not store a total dual cost'
    else:
        print('  - the method stored an total dual cost')

    # Success
    print('- the test ran to completion')
    print('Result: %s', pf)
Esempio n. 10
0
def test_prod_cost_from_formula():
    from local_asset_model import LocalAssetModel
    from market import Market

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

    #   Create a test object
    test_object = LocalAssetModel()

    #   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)
Esempio n. 11
0
def test_production():
    from local_asset_model import LocalAssetModel
    from market import Market

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

    #   Create a test object
    test_object = LocalAssetModel()

    #   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)
Esempio n. 12
0
def test_sum_vertices():
    print('Running Market.test_sum_vertices()')
    pf = 'pass'

    # Create a test myTransactiveNode object.
    test_node = myTransactiveNode()

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

    # List the test market with the test_node.
    test_node.markets = test_market

    # Create and store a time interval to work with.
    dt = datetime.now()
    at = dt
    dur = timedelta(hours=1)
    mkt = test_market
    mct = dt
    st = dt
    time_interval = TimeInterval(at, dur, mkt, mct, st)
    test_market.timeIntervals = [time_interval]

    # Create test LocalAsset and LocalAssetModel objects
    test_asset = LocalAsset()
    test_asset_model = LocalAssetModel()

    # Add the test_asset to the test node list.
    test_node.localAssets = [test_asset]

    # Have the test asset and its model cross reference one another.
    test_asset.model = test_asset_model
    test_asset_model.object = test_asset

    # Create and store an active Vertex or two for the test asset
    test_vertex = [Vertex(0.2, 0, -110), Vertex(0.2, 0, -90)]
    interval_values = [
        IntervalValue(test_node, time_interval, test_market,
                      MeasurementType.ActiveVertex, test_vertex[0]),
        IntervalValue(test_node, time_interval, test_market,
                      MeasurementType.ActiveVertex, test_vertex[1])
    ]
    test_asset_model.activeVertices = [interval_values[0], interval_values[1]
                                       ]  # interval_value(1:2)

    # Create test Neighbor and NeighborModel objects.
    test_neighbor = Neighbor()
    test_neighbor_model = NeighborModel()

    # Add the test neighbor to the test node list.
    test_node.neighbors = [test_neighbor]

    # Have the test neighbor and its model cross reference one another.
    test_neighbor.model = test_neighbor_model
    test_neighbor.model.object = test_neighbor

    # Create and store an active Vertex or two for the test neighbor
    test_vertex.append(Vertex(0.1, 0, 0))
    test_vertex.append(Vertex(0.3, 0, 200))
    interval_values.append(
        IntervalValue(test_node, time_interval, test_market,
                      MeasurementType.ActiveVertex, test_vertex[2]))
    interval_values.append(
        IntervalValue(test_node, time_interval, test_market,
                      MeasurementType.ActiveVertex, test_vertex[3]))
    test_neighbor_model.activeVertices = [
        interval_values[2], interval_values[3]
    ]

    ## Case 1
    print('- Case 1: Basic case with interleaved vertices')

    # Run the test.
    try:
        vertices = test_market.sum_vertices(test_node, time_interval)
        print('  - the method ran without errors')
    except:
        pf = 'fail'
        print('  - the method had errors when called and stopped')

    if len(vertices) != 4:
        pf = 'fail'
        print('  - an unexpected number of vertices was returned')
    else:
        print('  - the expected number of vertices was returned')

    powers = [x.power for x in vertices]

    # if any(~ismember(single(powers), single([-110.0000, -10.0000, 10.0000, 110.0000])))
    if len([
            x for x in powers
            if round(x, 4) not in [-110.0000, -10.0000, 10.0000, 110.0000]
    ]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex powers were as expected')

    marginal_prices = [round(x.marginalPrice, 4) for x in vertices]

    # if any(~ismember(single(marginal_prices), single([0.1000, 0.2000, 0.3000])))
    if len([
            x for x in marginal_prices
            if round(x, 4) not in [0.1000, 0.2000, 0.3000]
    ]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex marginal prices were as expected')

    ## CASE 2: NEIGHBOR MODEL TO BE EXCLUDED
    # This case is needed when a demand or supply curve must be created for a
    # transactive Neighbor object. The active vertices of the target Neighbor
    # must be excluded, leaving a residual supply or demand curve against which
    # the Neighbor may plan.
    print('- Case 2: Exclude test Neighbor model')

    # Run the test.
    try:
        # [vertices] = test_market.sum_vertices(test_node, time_interval, test_neighbor_model)
        vertices = test_market.sum_vertices(test_node, time_interval,
                                            test_neighbor_model)
        print('  - the method ran without errors')
    except:
        pf = 'fail'
        print('  - the method encountered errors and stopped')

    if len(vertices) != 2:
        pf = 'fail'
        print('  - an unexpected number of vertices was returned')
    else:
        print('  - the expected number of vertices was returned')

    powers = [round(x.power, 4) for x in vertices]

    # if any(~ismember(single(powers), single([-110.0000, -90.0000])))
    if len([x for x in powers if x not in [-110.0000, -90.0000]]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex powers were as expected')

    marginal_prices = [x.marginalPrice for x in vertices]

    # if any(~ismember(single(marginal_prices), single([0.2000])))
    if len([x for x in marginal_prices if round(x, 4) not in [0.2000]]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex marginal prices were as expected')

    ## CASE 3: CONSTANT SHOULD NOT CREATE NEW NET VERTEX
    print('- Case 3: Include a constant vertex. No net vertex should be added')

    # Change the test asset to NOT have any flexibility. A constant should
    # not introduce a net vertex at a constant's marginal price. Marginal
    # price is NOT meaningful for an inelastic device.
    test_asset_model.activeVertices = [interval_values[0]]

    # Run the test.
    try:
        # [vertices] = test_market.sum_vertices(test_node, time_interval)
        vertices = test_market.sum_vertices(test_node, time_interval)
        print('  - the method ran without errors')
    except:
        pf = 'fail'
        print('  - the method encountered errors and stopped')

    #%[180907DJH: THIS TEST IS CORRECTED. THE NEIGHBOR HAS TWO VERTICES. ADDING
    #AN ASSET WITH ONE VERTEX (NO FLEXIBILITY) SHOULD NOT CHANGE THE NUMBER OF
    #ACTIVE VERTICES, SO THE CORRECTED TEST CONFIRMS TWO VERTICES. THE CODE HAS
    #BEEN CORRECTED ACCORDINGLY.]
    if len(vertices) != 2:
        pf = 'fail'
        print('  - an unexpected number of vertices was returned')
    else:
        print('  - the expected number of vertices was returned')

    powers = [x.power for x in vertices]

    # if any(~ismember(single(powers), single([-110.0000, 90])))
    if len([x for x in powers if round(x, 4) not in [-110.0000, 90]]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex powers were as expected')

    marginal_prices = [x.marginalPrice for x in vertices]

    # if any(~ismember(single(marginal_prices), single([0.1000, 0.3000, Inf])))
    if len([
            x for x in marginal_prices if round(x, 4) not in
        [0.1000, 0.3000, float("inf")]
    ]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex marginal prices were as expected')

    # CASE 4: More than two vertices at any marginal price
    print('- Case 4: More than two vertices at same marginal price')

    # Move the two active vertices of the test asset to be at the same
    # marginal price as one of the neighbor active vertices.
    test_vertex = [Vertex(0.1, 0, -110), Vertex(0.1, 0, -90)]
    interval_values = [
        IntervalValue(test_node, time_interval, test_market,
                      MeasurementType.ActiveVertex, test_vertex[0]),
        IntervalValue(test_node, time_interval, test_market,
                      MeasurementType.ActiveVertex, test_vertex[1])
    ]
    test_asset_model.activeVertices = [interval_values[0], interval_values[1]
                                       ]  # interval_value(1:2)

    # Run the test.
    try:
        vertices = test_market.sum_vertices(test_node, time_interval)
        print('  - the method ran without errors')
    except:
        pf = 'fail'
        print('  - the method encountered errors and stopped')

    if len(vertices) != 3:
        pf = 'fail'
        print('  - an unexpected number of vertices was returned')
    else:
        print('  - the expected number of vertices was returned')

    powers = [x.power for x in vertices]

    # if any(~ismember(single(powers), single([-110.0000, -90.0000, 110.0000])))
    if len([
            x for x in powers
            if round(x, 4) not in [-110.0000, -90.0000, 110.0000]
    ]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex powers were as expected')

    marginal_prices = [x.marginalPrice for x in vertices]

    # if any(~ismember(single(marginal_prices), single([0.1000, 0.3000])))
    if len([x for x in marginal_prices if round(x, 4) not in [0.1000, 0.3000]
            ]) > 0:
        pf = 'fail'
        print('  - the vertex powers were not as expected')
    else:
        print('  - the vertex marginal prices were as expected')

    # Success
    print('- the test ran to completion')
    print('Result: #s\n\n', pf)
Esempio n. 13
0
def test_schedule():
    print('Running Market.test_schedule()')
    print('WARNING: This test may be affected by NeighborModel.schedule()')
    print('WARNING: This test may be affected by NeighborModel.schedule()')
    pf = 'pass'

    # Establish a myTransactiveNode object
    mtn = myTransactiveNode()

    # Establish a test market
    test_mkt = Market()

    # Create and store one TimeInterval
    dt = datetime(2018, 1, 1, 12, 0, 0)  # Noon Jan 1, 2018
    at = dt
    dur = timedelta(hours=1)
    mkt = test_mkt
    mct = dt
    st = dt
    ti = TimeInterval(at, dur, mkt, mct, st)

    test_mkt.timeIntervals = [ti]

    # Create and store a marginal price in the active interval.
    test_mkt.marginalPrices = [
        IntervalValue(test_mkt, ti, test_mkt, MeasurementType.MarginalPrice,
                      0.01)
    ]

    print('- configuring a test Neighbor and its NeighborModel')
    # Create a test object that is a Neighbor
    test_obj1 = Neighbor()
    test_obj1.maximumPower = 100

    # Create the corresponding model that is a NeighborModel
    test_mdl1 = NeighborModel()
    test_mdl1.defaultPower = 10

    test_obj1.model = test_mdl1
    test_mdl1.object = test_obj1

    mtn.neighbors = [test_obj1]

    print('- configuring a test LocalAsset and its LocalAssetModel')
    # Create a test object that is a Local Asset
    test_obj2 = LocalAsset
    test_obj2.maximumPower = 100

    # Create the corresponding model that is a LocalAssetModel
    test_mdl2 = LocalAssetModel()
    test_mdl2.defaultPower = 10

    test_obj2.model = test_mdl2
    test_mdl2.object = test_obj2

    mtn.localAssets = [test_obj2]

    try:
        test_mkt.schedule(mtn)
        print('- method ran without errors')
    except:
        raise ('- method did not run due to errors')

    if len(test_mdl1.scheduledPowers) != 1:
        raise (
            '- the wrong numbers of scheduled powers were stored for the Neighbor'
        )
    else:
        print(
            '- the right number of scheduled powers were stored for the Neighbor'
        )

    if len(test_mdl2.scheduledPowers) != 1:
        raise (
            '- the wrong numbers of scheduled powers were stored for the LocalAsset'
        )
    else:
        print(
            '- the right number of scheduled powers were stored for the LocalAsset'
        )

    # Success
    print('- the test ran to completion')
    print('Result: #s\n\n', pf)