def __init__(self,year,num_season,seasonobj): ''' Arguments: * year * : integer * season * : integer * seasonobj * : an instance of class season, where features of season are defined Season object can be obtained as follows: import season seasonObj = season.season() Then seasonObj defines by default seasons like this: Winter = 0 Spring = 1 Summer = 2 Fall = 3 Example: req = Season_req(2012,2,seasonObj) print req.longname ''' self.year = year self.season = num_season ti_ref,self.longname = seasonobj.get_season_dates(num_season) delta_years=year - seasonobj._reference_year t = TimeInterval() t.start_time = ti_ref.start_time + relativedelta(years=delta_years) t.end_time = ti_ref.end_time + relativedelta(years=delta_years) self.time_interval = t self.string = str(year) + " " + self.longname[:3]
def __init__(self,year): self.year=year t = TimeInterval() t.start_time = datetime.datetime(year ,1,1) t.end_time = datetime.datetime(year+1,1,1) self.time_interval =t self.string = str(year)
def main(mode): if not (0 <= mode <= 2): return print('''Available modes: 0: initialise the refresh token based on the username and password 1: initialise the data (add every marker) 2: daemon mode (watch new topics)''') with open(CONFIG_PATH, encoding='UTF-8') as f: config = yaml.safe_load(f) zds = ZesteDeSavoir(config['client_id'], config['client_secret'], REFRESH_TOKEN_PATH, TimeInterval(0)) osm_ti = TimeInterval(0) if mode == 0: zds._refresh_token_from_logins(input('Username: '******'id']: m for m in markers if m is not None} utils.save_markers(MARKERS_PATH, markers) utils.git_send_markers(MARKERS_PATH) if mode == 2: markers = {m['id']: m for m in utils.retrieve_markers(MARKERS_PATH)} while True: has_changed = False topics = list(zds.topics(True)) topics.reverse() for topic in topics: msg = list(zds.messages(topic['id']))[-1] change, msg = utils.on_new_message(msg, config, markers, zds, osm_ti) if change: has_changed = True if msg is not None: zds.send_message(topic['id'], msg) if has_changed: utils.save_markers(MARKERS_PATH, markers) utils.git_send_markers(MARKERS_PATH) time.sleep(config['interval'])
def __init__(self,year,month): self.year=year self.month=month self.string = "%d%02d" % (self.year, self.month) t = TimeInterval() t.start_time = datetime.datetime(self.year, self.month,1) t.end_time = t.start_time + relativedelta(months = 1) self.time_interval = t
def __init__(self,year,month,day): self.year = year self.month = month self.day = day t = TimeInterval() t.start_time = datetime.datetime(self.year,self.month,self.day,0) t.end_time = t.start_time + datetime.timedelta(days=1) self.time_interval = t self.string = t.start_time.strftime("%Y%m%d")
def __init__(self,year,month,day): self.year = year self.month = month self.day = day centertime = datetime.datetime(self.year,self.month,self.day,12) t = TimeInterval() t.start_time = centertime - datetime.timedelta(days=3.5) t.end_time = centertime + datetime.timedelta(days=3.5) self.time_interval = t self.string = centertime.strftime("%Y%m%d") self.isoweekday = centertime.isoweekday()
def __init__(self,decad): self.decad = decad q,r=divmod(decad, 10) assert r in [0,1] t = TimeInterval() self.startyear = decad self.end__year = self.startyear+9 t.start_time = datetime.datetime(self.startyear ,1,1,0,0,0) t.end_time = datetime.datetime(self.end__year+1,1,1,0,0,0) self.time_interval = t
def test_single_unstable_and_successfull_build(): datetime_of_unstable_build = datetime(2020, 1, 1, 0, 30) datetime_of_successfull_build = datetime(2020, 1, 1, 14, 30) build_dto_unsuccessfull = BuildDto(123, STATUS_UNSTABLE, datetime_of_unstable_build) build_dto_successfull = BuildDto(124, STATUS_SUCCESS, datetime_of_successfull_build) expected_fail_time = TimeInterval(datetime_of_unstable_build, datetime_of_successfull_build) result = build_service.get_list_of_fail_times_from_builds([build_dto_unsuccessfull, build_dto_successfull]) assert result != None assert len(result) == 1 assert expected_fail_time.get_start() == result[0].get_start() assert expected_fail_time.get_end() == result[0].get_end()
def test_single_unstable_build(): datetime_of_build = datetime(2020, 1, 1, 0, 30) next_day = datetime.combine(datetime_of_build.date() + timedelta(days=1), datetime.min.time()) build_service.get_datetime_today = mock.MagicMock(return_value=next_day) expected_fail_time = TimeInterval(datetime_of_build, next_day) build_dto = BuildDto(123, STATUS_UNSTABLE, datetime_of_build) result = build_service.get_list_of_fail_times_from_builds([build_dto]) assert result != None assert len(result) == 1 assert expected_fail_time.get_start() == result[0].get_start() assert expected_fail_time.get_end() == result[0].get_end()
def test_view_marginal_prices(): print('Running Market.test_view_marginal_prices()') pf = 'pass' # Establish a test market test_mkt = Market # Create and store three TimeIntervals dt = datetime at = dt dur = timedelta(hours=1) mkt = test_mkt mct = dt ti = [] # TimeInterval.empty st = dt ti[0] = TimeInterval(at, dur, mkt, mct, st) st = st + dur ti[1] = TimeInterval(at, dur, mkt, mct, st) st = st + dur ti[2] = TimeInterval(at, dur, mkt, mct, st) test_mkt.timeIntervals = ti ## Test using a Market object print('- using a Market object') iv = [] # IntervalValue.empty # Create and store three marginal price values iv[0] = IntervalValue(test_mkt, ti[2], test_mkt, MeasurementType.MarginalPrice, 3) iv[1] = IntervalValue(test_mkt, ti[0], test_mkt, MeasurementType.MarginalPrice, 1) iv[2] = IntervalValue(test_mkt, ti[1], test_mkt, MeasurementType.MarginalPrice, 2) test_mkt.marginalPrices = iv try: test_mkt.view_marginal_prices() print(' - function ran without errors') except: raise (' - function encountered errors and stopped') # Success print('- the test ran to completion') print('Result: #s\n\n', pf)
def computeTimeWindow(freqString,currentDate): if (freqString == 'daily'): req = requestors.Daily_req(currentDate.year,currentDate.month,currentDate.day) if (freqString == 'weekly'): req = requestors.Weekly_req(currentDate.year, currentDate.month,currentDate.day) if (freqString == 'monthly'): req = requestors.Monthly_req(currentDate.year, currentDate.month) if (freqString == 'yearly'): req = requestors.Yearly_req(currentDate.year) return TimeInterval.fromdatetimes(req.time_interval.start_time, req.time_interval.end_time)
def intervals(self): intervals = [] intervals_names = self.rules['IntervalRules'][self.day].split(',') for interval_name in intervals_names: hours = self.rules['Intervals'][interval_name].split('-') intervals.append(TimeInterval(*hours)) return intervals
def test_while_in_market_lead(): print(' Running test_while_in_market_lead().') print(' CASE 1: One neighbor. Its direction is not assigned.') test_neighbor = Neighbor() test_neighbor.transactive = False test_neighbor.upOrDown = Direction.unknown test_neighbor.name = 'Test_Neighbor' test_market = Auction() test_market.marketState = MarketState.MarketLead dt = datetime.now() test_interval = TimeInterval(dt, timedelta(hours=1), test_market, dt, dt) test_market.timeIntervals = [test_interval] test_agent = TransactiveNode() test_agent.markets = [test_market] test_agent.neighbors = [test_neighbor] assert test_market.marketState == MarketState.MarketLead try: test_market.while_in_market_lead(test_agent) print(' - The method ran without errors') except RuntimeWarning: print(' - ERRORS ENCOUNTERED') assert test_market.marketState == MarketState.MarketLead, \ 'The market should not have changed from the market lead state' assert test_neighbor.upOrDown == Direction.downstream, \ 'The undefined direction should have been assigned downstream' assert len(test_neighbor.scheduledPowers) == 0, \ 'One scheduled power should have been scheduled by the test neighbor' print(' CASE 2: An upstream neighbor is added.') upstream_neighbor = Neighbor() upstream_neighbor.upOrDown = Direction.upstream test_agent.neighbors.append(upstream_neighbor) assert len(test_agent.neighbors) == 2, 'There should be two neighbors' try: test_market.while_in_market_lead(test_agent) print(' - The method ran without errors') except RuntimeWarning: print(' - ERRORS ENCOUNTERED') print(' test_while_in_market_lead() ran to completion.\n')
def __init__(self,year,month,day, deltastr): self.year = year self.month = month self.day = day centertime = datetime.datetime(self.year,self.month,self.day,12) delta = relativedelta(10) exec 'delta= relativedelta(' + deltastr + ')' self.time_interval = TimeInterval.fromdatetimes(centertime-delta/2, centertime+delta/2) self.string = centertime.strftime("%Y%m%d") self.deltastr = deltastr
def set_opening_intervals(self, opening_intervals): if not opening_intervals: raise ValueError('The day must have at least one opening interval.') self.opening_intervals = [] for opening_interval in opening_intervals: if not isinstance(opening_interval, (list, tuple)): raise ValueError('Interval must be a list.') if len(opening_interval) != 2: raise ValueError('Each interval must be an array containing opening and closing times.') self.opening_intervals.append(TimeInterval.fromString(opening_interval[0], opening_interval[1])) sorted(self.opening_intervals, key=lambda interval: interval.getStart())
def check_intervals(self): # Check or create the set of instantiated TimeIntervals in this Market # Create the array "steps" of time intervals that should be active. # steps = datetime(mkt.marketClearingTime): Hours(mkt.marketClearingInterval): datetime + Hours(mkt.futureHorizon) # steps = steps(steps > datetime - Hours(mkt.marketClearingInterval)) steps = [] cur_time = Timer.get_cur_time() end_time = cur_time + self.futureHorizon self.update_market_clearing_time(cur_time) step_time = self.marketClearingTime while step_time < end_time: if step_time > cur_time - self.marketClearingInterval: steps.append(step_time) step_time = step_time + self.marketClearingInterval # Keep only time intervals >= steps[0] if len(steps) > 0: self.timeIntervals = [ti for ti in self.timeIntervals if ti.startTime >= steps[0]] # Index through the needed TimeIntervals based on their start times. for i in range(len(steps)): # This is a test to semarketClearingTimee whether the interval exists. # Case 0: a new interval must be created # Case 1: There is one match, the TimeInterval exists # Otherwise: Duplicates exists and should be deleted. tis = [x for x in self.timeIntervals if x.startTime == steps[i]] tis_len = len(tis) # No match was found. Create a new TimeInterval. if tis_len == 0: # Create a new TimeInterval activation_time = steps[i] - self.futureHorizon duration = self.intervalDuration market_clearing_time = steps[i] st = steps[i] # startTime ti = TimeInterval(activation_time, duration, self, market_clearing_time, st) self.timeIntervals.append(ti) # The TimeInterval already exists. elif tis_len == 1: # Find the TimeInterval and check its market state assignment. tis[0].assign_state(self) # ti.assign_state(mkt) # Duplicate time intervals exist. Remove all but one. else: self.timeIntervals = [x for x in self.timeIntervals if x.startTime != steps[i]] self.timeIntervals.append(tis[0]) tis[0].assign_state(self)
def set_opening_intervals(self, opening_intervals): if not opening_intervals: raise ValueError( 'The day must have at least one opening interval.') self.opening_intervals = [] for opening_interval in opening_intervals: if not isinstance(opening_interval, (list, tuple)): raise ValueError('Interval must be a list.') if len(opening_interval) != 2: raise ValueError( 'Each interval must be an array containing opening and closing times.' ) self.opening_intervals.append( TimeInterval.fromString(opening_interval[0], opening_interval[1])) sorted(self.opening_intervals, key=lambda interval: interval.getStart())
def get_season_dates(self,season_num): """ Given season number, return the range of season dates (start and end) and the name of season. """ assert season_num < self.numbers_season start_date=self.SEASON_LIST[season_num] if (season_num + 1) == self.numbers_season: end_date = self.SEASON_LIST[0] + relativedelta(years = 1) else: end_date= self.SEASON_LIST[season_num+1] TI = TimeInterval.fromdatetimes(start_date, end_date) season_name = self.SEASON_LIST_NAME[season_num] return TI,season_name
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 __init__(self,datelist): ''' TimeList object is created by providing a list of datetime objects (At least 2). ''' nTimes = len(datelist) assert nTimes > 1 self.Timelist = datelist self.Timelist.sort() self.nTimes = nTimes self.timeinterval = TimeInterval.fromdatetimes(self.Timelist[0], self.Timelist[-1]) self.inputdir = None self.searchstring = None self.filelist = None self.filtervar = None self.inputFrequency= self.__searchFrequency()
def __generaltimeselector(self,requestor): SELECTION=[] weights =[] if self.inputFrequency == "daily": for it, t in enumerate(self.Timelist): if requestor.time_interval.contains(t): SELECTION.append(it) weights.append(1.) if self.inputFrequency in ['weekly','monthly','yearly']: for it, t in enumerate(self.Timelist): t1 = computeTimeWindow(self.inputFrequency,t); t2 = TimeInterval.fromdatetimes(requestor.time_interval.start_time, requestor.time_interval.end_time) weight = t1.overlapTime(t2) if (weight > 0. ) : SELECTION.append(it) weights.append(weight) return SELECTION , np.array(weights)
def get_list_of_fail_times_from_builds(build_dto_list): fail_time_list = [] previous_build_successfull = True for build_dto in build_dto_list: if build_dto.get_status() != "SUCCESS": if previous_build_successfull: time_interval = TimeInterval(build_dto.get_datetime()) fail_time_list.append(time_interval) previous_build_successfull = False else: previous_build_successfull = True fail_time_list_length = len(fail_time_list) if fail_time_list_length > 0: last_unstable_entry = fail_time_list[fail_time_list_length - 1] last_unstable_entry.set_end(build_dto.get_datetime()) _end_last_interval_if_unset(fail_time_list) return fail_time_list
def test_unstable_failure_and_successfull_alternating_builds(): datetime_of_unstable_build = datetime(2020, 1, 1, 0, 30) datetime_of_successfull_build = datetime(2020, 1, 1, 14, 30) datetime_of_failed_build = datetime(2020, 1, 1, 15, 00) next_day = datetime.combine(datetime_of_unstable_build.date() + timedelta(days=1), datetime.min.time()) build_service.get_datetime_today = mock.MagicMock(return_value=next_day) build_dto_unsuccessfull1 = BuildDto(123, STATUS_UNSTABLE, datetime_of_unstable_build) build_dto_successfull = BuildDto(124, STATUS_SUCCESS, datetime_of_successfull_build) build_dto_unsuccessfull2 = BuildDto(125, STATUS_FAILURE, datetime_of_failed_build) result = build_service.get_list_of_fail_times_from_builds([build_dto_unsuccessfull1, build_dto_successfull, build_dto_unsuccessfull2]) expected_fail_time1 = TimeInterval(datetime_of_unstable_build, datetime_of_successfull_build) expected_fail_time2 = TimeInterval(datetime_of_failed_build, next_day) assert result != None assert len(result) == 2 assert expected_fail_time1.get_start() == result[0].get_start() assert expected_fail_time1.get_end() == result[0].get_end() assert expected_fail_time2.get_start() == result[1].get_start() assert expected_fail_time2.get_end() == result[1].get_end()
def test_while_in_negotiation(): print(' Running test_while_in_negotiation().') print(' CASE: Normal function. Asset should schedule, and market becomes converged') test_asset = LocalAsset() default_power = 4.321 test_asset.defaultPower = default_power test_market = Auction() test_market.converged = False test_market.marketState = MarketState.Negotiation dt = datetime.now() test_interval = TimeInterval(dt, timedelta(hours=1), test_market, dt, dt) test_market.timeIntervals = [test_interval] test_agent = TransactiveNode() test_agent.markets = [test_market] test_agent.localAssets = [test_asset] assert test_market.converged is False, 'The test market should start out not converged' assert test_market.marketState == MarketState.Negotiation try: test_market.while_in_negotiation(test_agent) print(' - The method ran without errors') except RuntimeWarning: print(' - ERRORS ENCOUNTERED') assert test_market.converged is True, 'The market should be converged' assert test_market.marketState == MarketState.Negotiation, \ 'The market should not have changed from the negotiation state' assert len(test_asset.scheduledPowers) == 1, 'Precisely one scheduled power should have been assigned' print(' test_while_in_negotiation() ran to completion.\n') pass
def test_view_net_curve(): print('Running Market.test_view_net_curve()') pf = 'pass' # Establish a test market test_mkt = Market() # Create and store one TimeInterval dt = datetime(2018, 1, 1, 12, 0, 0) at = dt dur = timedelta(hours=1) mkt = test_mkt mct = dt st = dt ti = [TimeInterval(at, dur, mkt, mct, st)] test_mkt.timeIntervals = ti ## Test using a Market object print('- using a Market object') # Create and store three active vertices v = [Vertex(0.01, 0, -1), Vertex(0.02, 0, 1), Vertex(0.03, 0, 1)] iv = [ IntervalValue(test_mkt, ti[0], test_mkt, MeasurementType.ActiveVertex, v[2]), IntervalValue(test_mkt, ti[0], test_mkt, MeasurementType.ActiveVertex, v[0]), IntervalValue(test_mkt, ti[0], test_mkt, MeasurementType.ActiveVertex, v[1]) ] test_mkt.activeVertices = [iv] test_mkt.view_net_curve(0) print(' - function ran without errors') # Success print('- the test ran to completion') print('Result: #s\n\n', pf)
def test_update_dc_threshold(): print('Running BulkSupplier_dc.test_update_dc_threshold()') pf = 'pass' ## Basic configuration for tests: # Create a test object and initialize demand-realted properties test_obj = BulkSupplier_dc() test_obj.demandMonth = datetime.now().month # month(datetime) test_obj.demandThreshold = 1000 # Create a test market test_mkt = Market() # Create and store two time intervals dt = datetime.now() at = dt dur = timedelta(hours=1) # Hours(1) mkt = test_mkt mct = dt st = dt ti = [TimeInterval(at, dur, mkt, mct, st)] st = st + dur ti.append(TimeInterval(at, dur, mkt, mct, st)) test_mkt.timeIntervals = ti ## Test case when there is no MeterPoint object test_obj.demandThreshold = 1000 test_obj.demandMonth = datetime.now().month # month(datetime) test_obj.meterPoints = [] # MeterPoint.empty # Create and store a couple scheduled powers # iv(1) = IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900) # iv(2) = IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) ] test_obj.scheduledPowers = iv try: test_obj.update_dc_threshold(test_mkt) print('- the method ran without errors') except: pf = 'fail' print('- the method encountered errors when called') if test_obj.demandThreshold != 1000: pf = 'fail' print('- the method inferred the wrong demand threshold value') else: print('- the method properly kept the old demand threshold value with no meter') iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 1100), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) ] test_obj.scheduledPowers = iv try: test_obj.update_dc_threshold(test_mkt) print('- the method ran without errors when there is no meter') except: pf = 'fail' print('- the method encountered errors when there is no meter') if test_obj.demandThreshold != 1100: pf = 'fail' print('- the method did not update the inferred demand threshold value') else: print('- the method properly updated the demand threshold value with no meter') ## Test with an appropriate MeterPoint meter # Create and store a MeterPoint test object test_mtr = MeterPoint() test_mtr.measurementType = MeasurementType.AverageDemandkW test_mtr.currentMeasurement = 900 test_obj.meterPoints = [test_mtr] # Reconfigure the test object for this test: iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) ] test_obj.scheduledPowers = iv test_obj.demandThreshold = 1000 test_obj.demandMonth = datetime.now().month # Run the test. Confirm it runs. try: test_obj.update_dc_threshold(test_mkt) print('- the method ran without errors when there is a meter') except: pf = 'fail' print('- the method encountered errors when there is a meter') # Check that the old threshold is correctly retained. if test_obj.demandThreshold != 1000: pf = 'fail' print('- the method failed to keep the correct demand threshold value when there is a meter') else: print('- the method properly kept the old demand threshold value when there is a meter') # Reconfigure the test object with a lower current threshold iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) ] test_obj.scheduledPowers = iv test_obj.demandThreshold = 800 # Run the test. test_obj.update_dc_threshold(test_mkt) # Check that a new, higher demand threshold was set. if test_obj.demandThreshold != 900: pf = 'fail' print(['- the method failed to update the demand threshold value when there is a meter']) else: print('- the method properly updated the demand threshold value when there is a meter') ## Test rollover to new month # Configure the test object test_obj.demandMonth = dt + relativedelta.relativedelta(months=-1) # month(datetime - days(31)) # prior month test_obj.demandThreshold = 1000 test_obj.scheduledPowers[0].value = 900 test_obj.scheduledPowers[1].value = 900 test_obj.meterPoints = [] # MeterPoint.empty # Run the test test_obj.update_dc_threshold(test_mkt) # See if the demand threshold was reset at the new month. if test_obj.demandThreshold != 0.8 * 1000: pf = 'fail' print('- the method did not reduce the threshold properly in a new month') else: print('- the method reduced the threshold properly in a new month') # Success print('- the test ran to completion') print('Result: #s\n\n', pf)
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)
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)
def select(self,requestor): ''' Method for time aggregation indexes, weights = select(requestor) Returned values: - a list of indexes (integers) indicating to access selected times (or files) - a numpy array of weights ''' if isinstance(requestor,requestors.Daily_req): # hourly values are treated as instantaneous values, not time averages assert self.inputFrequency in ["hourly","daily"] # it does not matter how many hours SELECTION=[] weights = [] for it,t in enumerate(self.Timelist): if requestor.time_interval.contains(t): SELECTION.append(it) weights.append(1.) return SELECTION , np.array(weights) if isinstance(requestor, requestors.Monthly_req): SELECTION=[] weights = [] if self.inputFrequency == 'daily': for it, t in enumerate(self.Timelist): if (t.year==requestor.year) & (t.month==requestor.month): SELECTION.append(it) weights.append(1.) if self.inputFrequency == 'weekly': for it,t in enumerate(self.Timelist): t1 = computeTimeWindow("weekly",t); t2 = TimeInterval.fromdatetimes(requestor.time_interval.start_time, requestor.time_interval.end_time) weight = t1.overlapTime(t2); if (weight > 0. ) : SELECTION.append(it) weights.append(weight) if self.inputFrequency == 'monthly': #print "Not time aggregation" for it,t in enumerate(self.Timelist): if requestor.time_interval.contains(t): SELECTION.append(it) weights.append(1.) return SELECTION , np.array(weights) if isinstance(requestor, requestors.Weekly_req): assert self.inputFrequency != "monthly" assert self.inputFrequency != "weekly" SELECTION=[] weights =[] if self.inputFrequency == "daily": for it,t in enumerate(self.Timelist): if requestor.time_interval.contains(t): SELECTION.append(it) weights.append(1.) return SELECTION , np.array(weights) if isinstance(requestor, requestors.Interval_req): return self.__generaltimeselector(requestor) if isinstance(requestor, requestors.Season_req): return self.__generaltimeselector(requestor) if isinstance(requestor, requestors.Yearly_req): return self.__generaltimeselector(requestor) if isinstance(requestor, requestors.Decadal_req): return self.__generaltimeselector(requestor) if isinstance(requestor, requestors.Generic_req): return self.__generaltimeselector(requestor) if isinstance(requestor, requestors.Clim_day): assert self.inputFrequency == 'daily' SELECTION=[] weights =[] for it,t in enumerate(self.Timelist): if (t.month == requestor.month) & (t.day == requestor.day): SELECTION.append(it) weights.append(1.) return SELECTION , np.array(weights) if isinstance(requestor,requestors.Clim_month): SELECTION = [] weights = [] YEARLIST=self.getYearlist() for year_req in YEARLIST: req = requestors.Monthly_req(year_req.year, requestor.month) s,w = self.select(req) SELECTION.extend(s) weights.extend(w) return SELECTION , np.array(weights) if isinstance(requestor,requestors.Clim_season): SELECTION = [] weights = [] YEARLIST=self.getYearlist() for year_req in YEARLIST: req = requestors.Season_req(year_req.year, requestor.season,seasonobj) s,w = self.select(req) SELECTION.extend(s) weights.extend(w) return SELECTION , np.array(weights)
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_are_different2(): from transactive_record import TransactiveRecord print('Running test_production()') pf = 'pass' # Create a time interval ti dt = datetime.now() at = dt dur = timedelta(hours=1) mkt = None mct = dt st = dt ti = TimeInterval(at, dur, mkt, mct, st) transactive_records = [ TransactiveRecord(ti, 0, 0.5, 100), TransactiveRecord(ti, 0, 0.5, 105), TransactiveRecord(ti, 1, 0.022, -0.0), TransactiveRecord(ti, 2, 0.022, 16400), TransactiveRecord(ti, 2, 0.023, 16400) ] # CASE 0: SIGNAL SETS DIFFER IN NUMBERS OF RECORDS print('Case 0: Signals have different record counts.') prepped_records = [transactive_records[0]] sent_records = [transactive_records[0], transactive_records[1]] threshold = 0.02 response = False try: response = are_different2(prepped_records, sent_records, threshold) print(' The method ran without errors') except Exception as ex: pf = 'fail' print(ex.message) if not response: pf = 'fail' print(' The method said the signals are the same which is wrong') else: print(' The method correctly said the signals differ') # CASE 1: No flexibility. One signal each. Powers of Records 0 match. print( 'Case 1: No flexibility. One signal each. Powers of Records 0 match.') prepped_records = [transactive_records[0]] sent_records = [transactive_records[0]] threshold = 0.02 try: response = are_different2(prepped_records, sent_records, threshold) print(' The method ran without errors') except: pf = 'fail' print(' The method encountered errors and stopped') if response: pf = 'fail' print(' The method said the signals were different which is wrong') else: print(' The method correctly said the signals were the same') # CASE 2 - No flexibiltiy. One signal each. Powers of Records 0 do not # match. print( 'Case 2: No flexibility. One signal each. Powers of Records 0 do NOT match.' ) prepped_records = [transactive_records[0]] sent_records = [transactive_records[1]] threshold = 0.02 try: response = are_different2(prepped_records, sent_records, threshold) print(' The method ran without errors') except: pf = 'fail' print(' The method encountered errors and stopped') if not response: pf = 'fail' print(' The method said the signals were the same which is wrong') else: print(' The method correctly said the signals differ') # CASE 3 - (Hung's case) Flexibility, but identical signals. #NOTE: Hung had found a case where powers had become zero, causing logic #problems. Code has been revised to avoid this possiblity. print('Case 3: Flexibility. Signals are identical') prepped_records = [transactive_records[2], transactive_records[3]] sent_records = [transactive_records[2], transactive_records[3]] threshold = 0.02 try: response = are_different2(prepped_records, sent_records, threshold) print(' The method ran without errors') except: pf = 'fail' print(' The method encountered errors and stopped') if response: pf = 'fail' print(' The method said the signals differ which is wrong') else: print(' The method correctly said the signals are the same') # CASE 4 - Flexibility, but different signals. print('Case 4: Flexibility. Signals are different') prepped_records = [transactive_records[2], transactive_records[3]] sent_records = [ transactive_records[2], transactive_records[3], transactive_records[4] ] threshold = 0.02 try: response = are_different2(prepped_records, sent_records, threshold) print(' The method ran without errors') except: pf = 'fail' print(' The method encountered errors and stopped') if not response: pf = 'fail' print(' The method said the signals are the same which is wrong') else: print(' The method correctly said the signals differ') # Success print('- the test ran to completion') print('Result: {}\n\n'.format(pf))
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)
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_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_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_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)
def test_schedule_power(cls): print('Running test_schedule_power()') pf = 'pass' # Create a test Market object. test_mkt = Market() # Create and store a couple TimeInterval objects at a known date and # time. dt = datetime(2017, 11, 1, 12, 0, 0) # Wednesday Nov. 1, 2017 at noon at = dt dur = timedelta(hours=1) mkt = test_mkt mct = dt st = dt test_intervals = [TimeInterval(at, dur, mkt, mct, st)] st = st + dur # 1p on the same day test_intervals.append(TimeInterval(at, dur, mkt, mct, st)) test_mkt.timeIntervals = test_intervals # Create a test TemperatureForecastModel object and give it some # temperature values in the test TimeIntervals. # test_forecast = TemperatureForecastModel # # The information type should be specified so the test object will # # correctly identivy it. # test_forecast.informationType = 'temperature' # # test_forecast.update_information(test_mkt) # test_forecast.predictedValues(1) = IntervalValue(test_forecast, test_intervals(1), test_mkt, 'Temperature', 20) # Heating regime # test_forecast.predictedValues(2) = IntervalValue(test_forecast, test_intervals(2), test_mkt, 'Temperature', 100) # Cooling regime # test_obj.informationServiceModels = {test_forecast} # Create a OpenLoopRichlandLoadPredictor test object. test_forecast = TemperatureForecastModel() test_forecast.informationType = 'temperature' test_forecast.predictedValues = [ IntervalValue(test_forecast, test_intervals[0], test_mkt, MeasurementType.Temperature, 20), # Heating regime IntervalValue(test_forecast, test_intervals[1], test_mkt, MeasurementType.Temperature, 100) # Cooling regime ] test_obj = OpenLoopRichlandLoadPredictor(test_forecast) # Manually evaluate from the lookup table and the above categorical inputs # DOW = Wed. ==> Intercept1 = 146119 Intercept2 = 18836 Intercept3 = -124095 Factor1 = -1375 Factor2 = 1048 Temperature1 = 20 Temperature2 = 100 LOAD = [ -(Intercept1 + Intercept2 + Factor1 * Temperature1), -(Intercept1 + Intercept3 + Factor2 * Temperature2) ] try: test_obj.schedule_power(test_mkt) print('- the method ran without errors') except: pf = 'fail' _log.warning('- the method had errors when called') #if any(abs([test_obj.scheduledPowers(1: 2).value] - [LOAD])) > 5 if any([ abs(test_obj.scheduledPowers[i].value - LOAD[i]) > 5 for i in range(len(test_obj.scheduledPowers)) ]): pf = 'fail' _log.warning('- the calculated powers were not as expected') else: print('- the calculated powers were as expected') # Success print('- the test ran to completion') print('Result: #s\n\n', pf)
def test_prod_cost_from_vertices(): from local_asset_model import LocalAssetModel # 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 = LocalAssetModel # 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)
def test_update_dc_threshold(): print('Running BulkSupplier_dc.test_update_dc_threshold()') # Basic configuration for tests: # Create a test object and initialize demand-related properties test_obj = BulkSupplier_dc() test_obj.demandMonth = datetime.now().month # month(datetime) test_obj.demandThreshold = 1000 # Create a test market test_mkt = Market() # Create and store two time intervals dt = datetime.now() at = dt dur = timedelta(hours=1) # Hours(1) mkt = test_mkt mct = dt st = dt ti = [TimeInterval(at, dur, mkt, mct, st)] st = st + dur ti.append(TimeInterval(at, dur, mkt, mct, st)) test_mkt.timeIntervals = ti # Test case when there is no MeterPoint object test_obj.demandThreshold = 1000 test_obj.demandMonth = datetime.now().month # month(datetime) test_obj.meterPoints = [] # MeterPoint.empty # Create and store a couple scheduled powers # iv(1) = IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900) # iv(2) = IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) ] test_obj.scheduledPowers = iv try: test_obj.update_dc_threshold(test_mkt) print('- the method ran without errors') except RuntimeWarning: print('- the method encountered errors when called') assert test_obj.demandThreshold == 1000, '- the method inferred the wrong demand threshold value' iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 1100), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) ] test_obj.scheduledPowers = iv try: test_obj.update_dc_threshold(test_mkt) print('- the method ran without errors when there is no meter') except RuntimeWarning: print('- the method encountered errors when there is no meter') assert test_obj.demandThreshold == 1100, '- the method did not update the inferred demand threshold value' # Test with an appropriate MeterPoint meter # Create and store a MeterPoint test object test_mtr = MeterPoint() test_mtr.measurementType = MeasurementType.AverageDemandkW test_mtr.currentMeasurement = 900 test_obj.meterPoints = [test_mtr] # Reconfigure the test object for this test: iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900) ] test_obj.scheduledPowers = iv test_obj.demandThreshold = 1000 test_obj.demandMonth = datetime.now().month # Run the test. Confirm it runs. try: test_obj.update_dc_threshold(test_mkt) print('- the method ran without errors when there is a meter') except RuntimeWarning: print('- the method encountered errors when there is a meter') # Check that the old threshold is correctly retained. assert test_obj.demandThreshold == 1000, \ '- the method failed to keep the correct demand threshold value when there is a meter' # Reconfigure the test object with a lower current threshold iv = [ IntervalValue(test_obj, ti[0], test_mkt, MeasurementType.ScheduledPower, 900), IntervalValue(test_obj, ti[1], test_mkt, MeasurementType.ScheduledPower, 900)] test_obj.scheduledPowers = iv test_obj.demandThreshold = 800 # Run the test. test_obj.update_dc_threshold(test_mkt) # Check that a new, higher demand threshold was set. assert test_obj.demandThreshold == 900, \ '- the method failed to update the demand threshold value when there is a meter' # Test rollover to new month # Configure the test object last_month = dt.month - 1 if last_month == 0: last_month = 12 test_obj.demandMonth = last_month # month(datetime - days(31)) # prior month test_obj.demandThreshold = 1000 test_obj.scheduledPowers[0].value = 900 test_obj.scheduledPowers[1].value = 900 test_obj.meterPoints = [] # MeterPoint.empty test_obj.demandThresholdCoef = 0.8 # Run the test try: test_obj.update_dc_threshold(test_mkt) print(' - The method ran without errors') except RuntimeWarning: print(' - ERRORS ENCOUNTERED') # See if the demand threshold was reset at the new month. assert test_obj.demandThreshold == test_obj.demandThresholdCoef * 1000, \ '- the method did not reduce the threshold properly in a new month' # Success print('test_update_dc_threshold() ran to completion.\n')
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)
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)
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)