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_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)