def start(self, sender, **kwargs): self.vip.pubsub.subscribe(peer = 'pubsub', prefix = 'fncs/input/', #prefix = '', callback = self.onmessage).get(timeout=5) #Register with FNCS cfg = "name = {0[name]}\ntime_delta = {0[time_delta]}\nbroker = {0[broker]}\n".format(self.fncs_zpl) if 'values' in self.fncs_zpl.keys(): cfg += "values" for x in self.fncs_zpl['values'].keys(): cfg += "\n {0}\n topic = {1[topic]}\n defualt = {1[default]}\n type = {1[type]}\n list = {1[list]}".format(x,self.fncs_zpl['values'][x]) fncs.initialize(cfg) if not fncs.is_initialized(): raise RuntimeError("FNCS connection failed!") self.publish_heartbeat() print(self.heartbeat_period) self.core.periodic(self.heartbeat_period, self.publish_heartbeat)
def __init__(self, time): self.time_stop = int(time) self.time_granted = 0 if os.getenv('RIAPS')=='True': self.RIAPS = True print("RIAPS: %s" %(self.RIAPS==True)) else: self.RIAPS = False print("RIAPS: %s" %(self.RIAPS==True)) fncs.initialize() self.batt_charges = {} self.solar_power = {} self.batt_power = {} self.prev_batt_commands = {} self.mainLoop()
import string import sys import fncs time_stop = int(sys.argv[1]) time_granted = 0 time_next = 1 # requires the yaml file fncs.initialize() print('# time key value till', time_stop, flush=True) while time_granted < time_stop: time_granted = fncs.time_request(time_stop) # time_next # print('**', time_granted) events = fncs.get_events() for key in events: topic = key.decode() print(time_granted, key, topic, fncs.get_value(key), flush=True) value = fncs.get_value(key).decode() if topic == 'sw_status': fncs.publish('sw_status', value) time_next = time_granted + 1 print('finalizing FNCS', flush=True) fncs.finalize() print('done', flush=True)
def start_bridge(self): """Register with the fncs_broker and return. Function arguments: broker_location -- Type: string. Description: The ip location and port for the fncs_broker. It must not be an empty string. Default: 'tcp://localhost:5570'. Function returns: None. Function exceptions: RuntimeError() ValueError() """ global is_initialized # First connect with goos via the GridAPPSD interface self._gridappsd = GridAPPSD(self.simulation_id, id=2, base_simulation_status_topic=BASE_SIMULATION_STATUS_TOPIC) self._gridappsd_listener = GridAPPSDListener(self, self._gridappsd) self._gridappsd.subscribe(self.simulation_input_topic, callback=self._gridappsd_listener) self._gridappsd.send_simulation_status("STARTING", "Starting Bridge for simulation id: {}".format(self.simulation_id)) configuration_zpl = '' try: message_str = 'Registering with FNCS broker ' + str(self.simulation_id) + ' and broker ' + self.fncs_broker_location self._gridappsd.send_simulation_status("STARTED", message_str) message_str = 'connected to goss {}'.format(self._gridappsd.connected) self._gridappsd.send_simulation_status("STARTED", message_str) if not self.simulation_id or type(self.simulation_id) != str: raise ValueError( 'simulation_id must be a nonempty string.\n' + 'simulation_id = {0}'.format(self.simulation_id)) if not self.fncs_broker_location or type(self.fncs_broker_location) != str: raise ValueError( 'broker_location must be a nonempty string.\n' + 'broker_location = {0}'.format(self.fncs_broker_location)) fncs_configuration = { 'name': 'FNCS_GOSS_Bridge_' + self.simulation_id, 'time_delta': '1s', 'broker': self.fncs_broker_location, 'values': { self.simulation_id: { 'topic': self.simulation_id + '/fncs_output', 'default': '{}', 'type': 'JSON', 'list': 'false' } } } configuration_zpl = ('name = {0}\n'.format(fncs_configuration['name']) + 'time_delta = {0}\n'.format(fncs_configuration['time_delta']) + 'broker = {0}\nvalues'.format(fncs_configuration['broker'])) for x in fncs_configuration['values'].keys(): configuration_zpl += '\n {0}'.format(x) configuration_zpl += '\n topic = {0}'.format( fncs_configuration['values'][x]['topic']) configuration_zpl += '\n default = {0}'.format( fncs_configuration['values'][x]['default']) configuration_zpl += '\n type = {0}'.format( fncs_configuration['values'][x]['type']) configuration_zpl += '\n list = {0}'.format( fncs_configuration['values'][x]['list']) fncs.initialize(configuration_zpl) is_initialized = fncs.is_initialized() if is_initialized: message_str = 'Registered with fncs ' + str(is_initialized) self._gridappsd.send_simulation_status("RUNNING", message_str) except Exception as e: message_str = 'Error while registering with fncs broker ' + str(e) self._gridappsd.send_simulation_status('ERROR', message_str, 'ERROR') if fncs.is_initialized(): fncs.die() if not fncs.is_initialized(): message_str = 'fncs.initialize(configuration_zpl) failed!\n' + 'configuration_zpl = {0}'.format( configuration_zpl) self._gridappsd.send_simulation_status('ERROR', message_str, 'ERROR') if fncs.is_initialized(): fncs.die() raise RuntimeError( 'fncs.initialize(configuration_zpl) failed!\n' + 'configuration_zpl = {0}'.format(configuration_zpl))
def launch_all(): print('launching all simulators') if sys.platform == 'win32': subprocess.Popen('call run30.bat', shell=True) else: subprocess.Popen( '(export FNCS_BROKER="tcp://*:5570" && exec fncs_broker 36 &> broker.log &)', shell=True) subprocess.Popen( '(export FNCS_CONFIG_FILE=eplus.yaml && exec EnergyPlus -w ../energyplus/USA_AZ_Tucson.Intl.AP.722740_TMY3.epw -d output -r ../energyplus/SchoolDualController.idf &> eplus.log &)', shell=True) subprocess.Popen( '(export FNCS_CONFIG_FILE=eplus_json.yaml && exec eplus_json 2d 5m School_DualController eplus_TE_Challenge_metrics.json &> eplus_json.log &)', shell=True) subprocess.Popen('(exec ./launch_TE_Challenge_agents.sh &)', shell=True) subprocess.Popen( '(export FNCS_CONFIG_FILE=pypower30.yaml && export FNCS_FATAL=NO && export FNCS_LOG_STDOUT=yes && exec python fncsPYPOWER.py TE_Challenge &> pypower.log &)', shell=True) print('launched all simulators') root.update() os.environ['FNCS_CONFIG_FILE'] = 'tesp.yaml' os.environ['FNCS_FATAL'] = 'NO' print('config file =', os.environ['FNCS_CONFIG_FILE']) fncs.initialize() time_granted = 0 time_stop = 2 * 24 * 60 yaml_delta = 5 nsteps = int(time_stop / yaml_delta) hrs = np.linspace(0.0, 48.0, nsteps + 1) idxlast = -1 x0 = np.empty(nsteps + 1) x1 = np.zeros(nsteps + 1) x2 = np.zeros(nsteps + 1) x3 = np.zeros(nsteps + 1) while time_granted < time_stop: time_granted = fncs.time_request(time_stop) events = fncs.get_events() idx = int(time_granted / yaml_delta) if idx <= idxlast: continue idxlast = idx bWantX0 = True bWantX1 = True bWantX2 = True bWantX3 = True for key in events: tok = key.decode() if bWantX1 and tok == 'power_A': val = 3.0 * float( fncs.get_value(key).decode().strip('+ degFkW')) / 1000.0 x1[idx] = val ax[1].plot(hrs[1:idx], x1[1:idx], color='red') bWantX1 = False elif bWantX3 and tok == 'house_air_temperature': val = float(fncs.get_value(key).decode().strip('+ degFkW')) x3[idx] = val ax[3].plot(hrs[1:idx], x3[1:idx], color='magenta') bWantX3 = False elif bWantX0 and tok == 'vpos7': val = float( fncs.get_value(key).decode().strip('+ degFkW')) / 133000.0 x0[idx] = val ax[0].plot(hrs[1:idx], x0[1:idx], color='green') bWantX0 = False elif bWantX2 and tok == 'clear_price': val = float(fncs.get_value(key).decode().strip('+ degFkW')) x2[idx] = val ax[2].plot(hrs[1:idx], x2[1:idx], color='blue') bWantX2 = False elif bWantX2 and tok == 'LMP7': val = float(fncs.get_value(key).decode().strip('+ degFkW')) x2[idx] = val ax[2].plot(hrs[1:idx], x2[1:idx], color='blue') bWantX2 = False elif bWantX1 and tok == 'SUBSTATION7': val = float(fncs.get_value(key).decode().strip( '+ degFkW')) # already in kW x1[idx] = val ax[1].plot(hrs[1:idx], x1[1:idx], color='red') bWantX1 = False # print (time_granted, key.decode(), fncs.get_value(key).decode()) root.update() fig.canvas.draw() fncs.finalize()
def launch_all(): print('launching all simulators') if sys.platform == 'win32': subprocess.Popen ('call run30.bat', shell=True) else: subprocess.Popen ('(export simNum=36 && ./runVisualTE30ChallengeDocker.sh &)', shell=True) print('launched all simulators') root.update() os.environ['FNCS_CONFIG_FILE'] = 'tespTE30.yaml' os.environ['FNCS_FATAL'] = 'NO' print('config file =', os.environ['FNCS_CONFIG_FILE']) fncs.initialize() time_granted = 0 time_stop = 2 * 24 * 60 yaml_delta = 5 nsteps = int (time_stop / yaml_delta) hrs=np.linspace(0.0, 48.0, nsteps+1) idxlast = -1 x0 = np.empty(nsteps+1) x1 = np.zeros(nsteps+1) x2 = np.zeros(nsteps+1) x3 = np.zeros(nsteps+1) while time_granted < time_stop: time_granted = fncs.time_request(time_stop) events = fncs.get_events() idx = int (time_granted / yaml_delta) if idx <= idxlast: continue idxlast = idx bWantX0 = True bWantX1 = True bWantX2 = True bWantX3 = True for key in events: tok = key.decode() if bWantX1 and tok == 'power_A': val = 3.0 * float (fncs.get_value(key).decode().strip('+ degFkW')) / 1000.0 x1[idx] = val ax[1].plot(hrs[1:idx],x1[1:idx],color='red') bWantX1 = False elif bWantX3 and tok == 'house_air_temperature': val = float (fncs.get_value(key).decode().strip('+ degFkW')) x3[idx] = val ax[3].plot(hrs[1:idx],x3[1:idx],color='magenta') bWantX3 = False elif bWantX0 and tok == 'vpos7': val = float (fncs.get_value(key).decode().strip('+ degFkW')) / 133000.0 x0[idx] = val ax[0].plot(hrs[1:idx],x0[1:idx],color='green') bWantX0 = False elif bWantX2 and tok == 'clear_price': val = float (fncs.get_value(key).decode().strip('+ degFkW')) x2[idx] = val ax[2].plot(hrs[1:idx],x2[1:idx],color='blue') bWantX2 = False elif bWantX2 and tok == 'LMP7': val = float (fncs.get_value(key).decode().strip('+ degFkW')) x2[idx] = val ax[2].plot(hrs[1:idx],x2[1:idx],color='blue') bWantX2 = False elif bWantX1 and tok == 'SUBSTATION7': val = float (fncs.get_value(key).decode().strip('+ degFkW')) # already in kW x1[idx] = val ax[1].plot(hrs[1:idx],x1[1:idx],color='red') bWantX1 = False # print (time_granted, key.decode(), fncs.get_value(key).decode()) root.update() fig.canvas.draw() fncs.finalize()
def _register_with_fncs_broker(broker_location='tcp://localhost:5570'): """Register with the fncs_broker and return. Function arguments: broker_location -- Type: string. Description: The ip location and port for the fncs_broker. It must not be an empty string. Default: 'tcp://localhost:5570'. Function returns: None. Function exceptions: RuntimeError() ValueError() """ global is_initialized configuration_zpl = '' try: message_str = 'Registering with FNCS broker ' + str( simulation_id) + ' and broker ' + broker_location _send_simulation_status('STARTED', message_str, 'INFO') message_str = 'still connected to goss 1 ' + str( goss_connection.is_connected()) _send_simulation_status('STARTED', message_str, 'INFO') if simulation_id == None or simulation_id == '' or type( simulation_id) != str: raise ValueError('simulation_id must be a nonempty string.\n' + 'simulation_id = {0}'.format(simulation_id)) if (broker_location == None or broker_location == '' or type(broker_location) != str): raise ValueError('broker_location must be a nonempty string.\n' + 'broker_location = {0}'.format(broker_location)) fncs_configuration = { 'name': 'FNCS_GOSS_Bridge_' + simulation_id, 'time_delta': '1s', 'broker': broker_location, 'values': { simulation_id: { 'topic': simulation_id + '/fncs_output', 'default': '{}', 'type': 'JSON', 'list': 'false' } } } configuration_zpl = ( 'name = {0}\n'.format(fncs_configuration['name']) + 'time_delta = {0}\n'.format(fncs_configuration['time_delta']) + 'broker = {0}\nvalues'.format(fncs_configuration['broker'])) for x in fncs_configuration['values'].keys(): configuration_zpl += '\n {0}'.format(x) configuration_zpl += '\n topic = {0}'.format( fncs_configuration['values'][x]['topic']) configuration_zpl += '\n default = {0}'.format( fncs_configuration['values'][x]['default']) configuration_zpl += '\n type = {0}'.format( fncs_configuration['values'][x]['type']) configuration_zpl += '\n list = {0}'.format( fncs_configuration['values'][x]['list']) fncs.initialize(configuration_zpl) is_initialized = fncs.is_initialized() if is_initialized: message_str = 'Registered with fncs ' + str(is_initialized) _send_simulation_status('RUNNING', message_str, 'INFO') except Exception as e: message_str = 'Error while registering with fncs broker ' + str(e) _send_simulation_status('ERROR', message_str, 'ERROR') if fncs.is_initialized(): fncs.die() if not fncs.is_initialized(): message_str = 'fncs.initialize(configuration_zpl) failed!\n' + 'configuration_zpl = {0}'.format( configuration_zpl) _send_simulation_status('ERROR', message_str, 'ERROR') if fncs.is_initialized(): fncs.die() raise RuntimeError('fncs.initialize(configuration_zpl) failed!\n' + 'configuration_zpl = {0}'.format(configuration_zpl))
import random import string import fncs name = "randome_name_" + "".join( [random.choice(string.digits) for i in xrange(8)] ) config = """name = %s time_delta = 1s""" % name # generate some time steps time_steps = sorted(random.sample([i for i in xrange(100)], 10)) print time_steps fncs.initialize(config) for time in time_steps: current_time = fncs.time_request(time) print "current time is", current_time fncs.publish("some_key", "some_value") fncs.finalize()
def main_loop(): if len(sys.argv) == 2: rootname = sys.argv[1] else: print('usage: python fncsPYPOWER.py rootname') sys.exit() ppc = ppcasefile() StartTime = ppc['StartTime'] tmax = int(ppc['Tmax']) period = int(ppc['Period']) dt = int(ppc['dt']) make_dictionary(ppc, rootname) bus_mp = open("bus_" + rootname + "_metrics.json", "w") gen_mp = open("gen_" + rootname + "_metrics.json", "w") sys_mp = open("sys_" + rootname + "_metrics.json", "w") bus_meta = { 'LMP_P': { 'units': 'USD/kwh', 'index': 0 }, 'LMP_Q': { 'units': 'USD/kvarh', 'index': 1 }, 'PD': { 'units': 'MW', 'index': 2 }, 'QD': { 'units': 'MVAR', 'index': 3 }, 'Vang': { 'units': 'deg', 'index': 4 }, 'Vmag': { 'units': 'pu', 'index': 5 }, 'Vmax': { 'units': 'pu', 'index': 6 }, 'Vmin': { 'units': 'pu', 'index': 7 } } gen_meta = { 'Pgen': { 'units': 'MW', 'index': 0 }, 'Qgen': { 'units': 'MVAR', 'index': 1 }, 'LMP_P': { 'units': 'USD/kwh', 'index': 2 } } sys_meta = { 'Ploss': { 'units': 'MW', 'index': 0 }, 'Converged': { 'units': 'true/false', 'index': 1 } } bus_metrics = {'Metadata': bus_meta, 'StartTime': StartTime} gen_metrics = {'Metadata': gen_meta, 'StartTime': StartTime} sys_metrics = {'Metadata': sys_meta, 'StartTime': StartTime} gencost = ppc['gencost'] fncsBus = ppc['FNCS'] ppopt = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=1) loads = np.loadtxt('NonGLDLoad.txt', delimiter=',') for row in ppc['UnitsOut']: print('unit ', row[0], 'off from', row[1], 'to', row[2], flush=True) for row in ppc['BranchesOut']: print('branch', row[0], 'out from', row[1], 'to', row[2], flush=True) nloads = loads.shape[0] ts = 0 tnext_opf = -dt op = open(rootname + '.csv', 'w') print( 't[s],Converged,Pload,P7 (csv), GLD Unresp, P7 (opf), Resp (opf), GLD Pub, BID?, P7 Min, V7,LMP_P7,LMP_Q7,Pgen1,Pgen2,Pgen3,Pgen4,Pdisp, gencost2, gencost1, gencost0', file=op, flush=True) # print ('t[s], ppc-Pd5, ppc-Pd9, ppc-Pd7, bus-Pd7, ppc-Pg1, gen-Pg1, ppc-Pg2, gen-Pg2, ppc-Pg3, gen-Pg3, ppc-Pg4, gen-Pg4, ppc-Pg5, gen-Pg5, ppc-Cost2, gencost-Cost2, ppc-Cost1, gencost-Cost1, ppc-Cost0, gencost-Cost0', file=op, flush=True) fncs.initialize() # transactive load components csv_load = 0 scaled_unresp = 0 scaled_resp = 0 resp_c0 = 0 resp_c1 = 0 resp_c2 = 0 resp_max = 0 gld_load = 0 # this is the actual # ================================== # Laurentiu Marinovici - 2017-12-14 actual_load = 0 new_bid = False # saveInd = 0 # saveDataDict = {} # =================================== while ts <= tmax: if ts >= tnext_opf: # expecting to solve opf one dt before the market clearing period ends, so GridLAB-D has time to use it idx = int((ts + dt) / period) % nloads bus = ppc['bus'] print( '<<<<< ts = {}, ppc-Pd5 = {}, bus-Pd5 = {}, ppc-Pd7 = {}, bus-Pd7 = {}, ppc-Pd9 = {}, bus-Pd9 = {} >>>>>>>' .format(ts, ppc["bus"][4, 2], bus[4, 2], ppc["bus"][6, 2], bus[6, 2], ppc["bus"][8, 2], bus[8, 2])) gen = ppc['gen'] branch = ppc['branch'] gencost = ppc['gencost'] csv_load = loads[idx, 0] bus[4, 2] = loads[idx, 1] bus[8, 2] = loads[idx, 2] print( '<<<<< ts = {}, ppc-Pd5 = {}, bus-Pd5 = {}, ppc-Pd7 = {}, bus-Pd7 = {}, ppc-Pd9 = {}, bus-Pd9 = {} >>>>>>>' .format(ts, ppc["bus"][4, 2], bus[4, 2], ppc["bus"][6, 2], bus[6, 2], ppc["bus"][8, 2], bus[8, 2])) # process the generator and branch outages for row in ppc['UnitsOut']: if ts >= row[1] and ts <= row[2]: gen[row[0], 7] = 0 else: gen[row[0], 7] = 1 for row in ppc['BranchesOut']: if ts >= row[1] and ts <= row[2]: branch[row[0], 10] = 0 else: branch[row[0], 10] = 1 bus[6, 2] = csv_load # ================================= # Laurentiu Marinovici - 2017-12-14 # bus[6,2] = csv_load + actual_load # ================================= for row in ppc['FNCS']: scaled_unresp = float(row[2]) * float(row[3]) newidx = int(row[0]) - 1 bus[newidx, 2] += scaled_unresp print( '<<<<< ts = {}, ppc-Pd5 = {}, bus-Pd5 = {}, ppc-Pd7 = {}, bus-Pd7 = {}, ppc-Pd9 = {}, bus-Pd9 = {} >>>>>>>' .format(ts, ppc["bus"][4, 2], bus[4, 2], ppc["bus"][6, 2], bus[6, 2], ppc["bus"][8, 2], bus[8, 2])) gen[4][9] = -resp_max * float(fncsBus[0][2]) gencost[4][3] = 3 gencost[4][4] = resp_c2 gencost[4][5] = resp_c1 gencost[4][6] = resp_c0 # ================================= # Laurentiu Marinovici - 2017-12-14 # print('Before running OPF:') # print('Disp load/neg gen: Pg = ', gen[4][1], ', Pmax = ', gen[4][8], ', Pmin = ', gen[4][9], ', status = ', gen[4][7]) # print('Disp load/neg gen cost coefficients: ', gencost[4][4], ', ', gencost[4][5], ', ', gencost[4][6]) # gen[4, 7] = 1 # turn on dispatchable load #ppc['gen'] = gen #ppc['bus'] = bus #ppc['branch'] = branch #ppc['gencost'] = gencost # print (ts, ppc["bus"][4, 2], ppc["bus"][8, 2], ppc["bus"][6, 2], bus[6, 2], ppc["gen"][0, 1], gen[0, 1], ppc["gen"][1, 1], gen[1, 1], ppc["gen"][2, 1], gen[2, 1], ppc["gen"][3, 1], gen[3, 1], ppc["gen"][4, 1], gen[4, 1], ppc["gencost"][4, 4], gencost[4, 4], ppc["gencost"][4, 5], gencost[4, 5], ppc["gencost"][4, 6], gencost[4, 6], sep=',', file=op, flush=True) # ===================================================================================================================== res = pp.runopf(ppc, ppopt) # ================================= # Laurentiu Marinovici - 2017-12-21 # mpcKey = 'mpc' + str(saveInd) # resKey = 'res' + str(saveInd) # saveDataDict[mpcKey] = copy.deepcopy(ppc) # saveDataDict[resKey] = copy.deepcopy(res) # saveInd += 1 # ================================= bus = res['bus'] gen = res['gen'] Pload = bus[:, 2].sum() Pgen = gen[:, 1].sum() Ploss = Pgen - Pload scaled_resp = -1.0 * gen[4, 1] # CSV file output print(ts, res['success'], '{:.3f}'.format(bus[:, 2].sum()), '{:.3f}'.format(csv_load), '{:.3f}'.format(scaled_unresp), '{:.3f}'.format(bus[6, 2]), '{:.3f}'.format(scaled_resp), '{:.3f}'.format(actual_load), new_bid, '{:.3f}'.format(gen[4, 9]), '{:.3f}'.format(bus[6, 7]), '{:.3f}'.format(bus[6, 13]), '{:.3f}'.format(bus[6, 14]), '{:.2f}'.format(gen[0, 1]), '{:.2f}'.format(gen[1, 1]), '{:.2f}'.format(gen[2, 1]), '{:.2f}'.format(gen[3, 1]), '{:.2f}'.format(res['gen'][4, 1]), '{:.6f}'.format(ppc['gencost'][4, 4]), '{:.4f}'.format(ppc['gencost'][4, 5]), '{:.4f}'.format(ppc['gencost'][4, 6]), sep=',', file=op, flush=True) fncs.publish('LMP_B7', 0.001 * bus[6, 13]) fncs.publish('three_phase_voltage_B7', 1000.0 * bus[6, 7] * bus[6, 9]) print('**OPF', ts, csv_load, scaled_unresp, gen[4][9], scaled_resp, bus[6, 2], 'LMP', 0.001 * bus[6, 13]) # update the metrics sys_metrics[str(ts)] = {rootname: [Ploss, res['success']]} bus_metrics[str(ts)] = {} for i in range(fncsBus.shape[0]): busnum = int(fncsBus[i, 0]) busidx = busnum - 1 row = bus[busidx].tolist() bus_metrics[str(ts)][str(busnum)] = [ row[13] * 0.001, row[14] * 0.001, row[2], row[3], row[8], row[7], row[11], row[12] ] gen_metrics[str(ts)] = {} for i in range(gen.shape[0]): row = gen[i].tolist() busidx = int(row[0] - 1) gen_metrics[str(ts)][str(i + 1)] = [ row[1], row[2], float(bus[busidx, 13]) * 0.001 ] tnext_opf += period if tnext_opf > tmax: print('breaking out at', tnext_opf, flush=True) break # apart from the OPF, keep loads updated ts = fncs.time_request(ts + dt) events = fncs.get_events() new_bid = False for key in events: topic = key.decode() # ================================== # Laurentiu Marinovici - 2017-12-14l # print('The event is: ........ ', key) # print('The topic is: ........ ', topic) # print('The value is: ........ ', fncs.get_value(key).decode()) # ============================================================= if topic == 'UNRESPONSIVE_KW': unresp_load = 0.001 * float(fncs.get_value(key).decode()) fncsBus[0][ 3] = unresp_load # poke unresponsive estimate into the bus load slot new_bid = True elif topic == 'RESPONSIVE_MAX_KW': resp_max = 0.001 * float(fncs.get_value(key).decode()) # in MW new_bid = True elif topic == 'RESPONSIVE_M': # resp_c2 = 1000.0 * 0.5 * float(fncs.get_value(key).decode()) resp_c2 = -1e6 * float(fncs.get_value(key).decode()) new_bid = True elif topic == 'RESPONSIVE_B': # resp_c1 = 1000.0 * float(fncs.get_value(key).decode()) resp_c1 = 1e3 * float(fncs.get_value(key).decode()) new_bid = True # ============================================ # Laurentiu Marinovici elif topic == 'RESPONSIVE_BB': resp_c0 = -float(fncs.get_value(key).decode()) new_bid = True # ============================================ elif topic == 'UNRESPONSIVE_PRICE': # not actually used unresp_price = float(fncs.get_value(key).decode()) new_bid = True else: gld_load = parse_mva(fncs.get_value(key).decode( )) # actual value, may not match unresp + resp load # ================================== # Laurentiu Marinovici - 2017-12-14 # print('GLD real = ', float(gld_load[0]), '; GLD imag = ', float(gld_load[1])) # print('Amp factor = ', float(fncsBus[0][2])) # ================================================================== actual_load = float(gld_load[0]) * float(fncsBus[0][2]) print(' Time = ', ts, '; actual load real = ', actual_load) if new_bid == True: print('**Bid', ts, unresp_load, resp_max, resp_c2, resp_c1, resp_c0) # Laurentiu Marinovici - 2017-12-21 # spio.savemat('matFile.mat', saveDataDict) # =================================== print('writing metrics', flush=True) print(json.dumps(bus_metrics), file=bus_mp, flush=True) print(json.dumps(gen_metrics), file=gen_mp, flush=True) print(json.dumps(sys_metrics), file=sys_mp, flush=True) print('closing files', flush=True) bus_mp.close() gen_mp.close() sys_mp.close() op.close() print('finalizing FNCS', flush=True) fncs.finalize()
def _registerWithFncsBroker(simId, brokerLocation='tcp://localhost:5570'): '''Register with the fncs_broker and return. Function arguments: simulationId -- Type: string. Description: The simulation id. It must not be an empty string. Default: None. brokerLocation -- Type: string. Description: The ip location and port for the fncs_broker. It must not be an empty string. Default: 'tcp://localhost:5570'. Function returns: None. Function exceptions: RuntimeError() ValueError() ''' global simulationId global isInitialized simulationId = simId try: logger.info('Registering with FNCS broker ' + str(simulationId) + ' and broker ' + brokerLocation) logger.debug('still connected to goss 1 ' + str(gossConnection.is_connected())) if simulationId == None or simulationId == '' or type( simulationId) != str: raise ValueError('simulationId must be a nonempty string.\n' + 'simulationId = {0}'.format(simulationId)) if (brokerLocation == None or brokerLocation == '' or type(brokerLocation) != str): raise ValueError('brokerLocation must be a nonempty string.\n' + 'brokerLocation = {0}'.format(brokerLocation)) fncsConfiguration = { 'name': 'FNCS_GOSS_Bridge_' + simulationId, 'time_delta': '1s', 'broker': brokerLocation, 'values': { simulationId: { 'topic': simulationId + '/fncs_output', 'default': '{}', 'type': 'JSON', 'list': 'false' } } } configurationZpl = ( 'name = {0}\n'.format(fncsConfiguration['name']) + 'time_delta = {0}\n'.format(fncsConfiguration['time_delta']) + 'broker = {0}\nvalues'.format(fncsConfiguration['broker'])) for x in fncsConfiguration['values'].keys(): configurationZpl += '\n {0}'.format(x) configurationZpl += '\n topic = {0}'.format( fncsConfiguration['values'][x]['topic']) configurationZpl += '\n default = {0}'.format( fncsConfiguration['values'][x]['default']) configurationZpl += '\n type = {0}'.format( fncsConfiguration['values'][x]['type']) configurationZpl += '\n list = {0}'.format( fncsConfiguration['values'][x]['list']) fncs.initialize(configurationZpl) isInitialized = fncs.is_initialized() logger.info('Registered with fncs ' + str(isInitialized)) except Exception as e: logger.error('Error while registering with fncs broker ' + str(e)) if not fncs.is_initialized(): raise RuntimeError('fncs.initialize(configurationZpl) failed!\n' + 'configurationZpl = {0}'.format(configurationZpl))
def main_loop(): if len(sys.argv) == 2: rootname = sys.argv[1] else: print('usage: python fncsPYPOWER.py rootname') sys.exit() ppc = ppcasefile() StartTime = ppc['StartTime'] tmax = int(ppc['Tmax']) period = int(ppc['Period']) dt = int(ppc['dt']) make_dictionary(ppc, rootname) bus_mp = open("bus_" + rootname + "_metrics.json", "w") gen_mp = open("gen_" + rootname + "_metrics.json", "w") sys_mp = open("sys_" + rootname + "_metrics.json", "w") bus_meta = { 'LMP_P': { 'units': 'USD/kwh', 'index': 0 }, 'LMP_Q': { 'units': 'USD/kvarh', 'index': 1 }, 'PD': { 'units': 'MW', 'index': 2 }, 'QD': { 'units': 'MVAR', 'index': 3 }, 'Vang': { 'units': 'deg', 'index': 4 }, 'Vmag': { 'units': 'pu', 'index': 5 }, 'Vmax': { 'units': 'pu', 'index': 6 }, 'Vmin': { 'units': 'pu', 'index': 7 } } gen_meta = { 'Pgen': { 'units': 'MW', 'index': 0 }, 'Qgen': { 'units': 'MVAR', 'index': 1 }, 'LMP_P': { 'units': 'USD/kwh', 'index': 2 } } sys_meta = { 'Ploss': { 'units': 'MW', 'index': 0 }, 'Converged': { 'units': 'true/false', 'index': 1 } } bus_metrics = {'Metadata': bus_meta, 'StartTime': StartTime} gen_metrics = {'Metadata': gen_meta, 'StartTime': StartTime} sys_metrics = {'Metadata': sys_meta, 'StartTime': StartTime} gencost = ppc['gencost'] fncsBus = ppc['FNCS'] gen = ppc['gen'] ppopt_market = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=1) ppopt_regular = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=1) loads = np.loadtxt('NonGLDLoad.txt', delimiter=',') for row in ppc['UnitsOut']: print('unit ', row[0], 'off from', row[1], 'to', row[2], flush=True) for row in ppc['BranchesOut']: print('branch', row[0], 'out from', row[1], 'to', row[2], flush=True) nloads = loads.shape[0] ts = 0 tnext_opf = -dt # initializing for metrics collection tnext_metrics = 0 loss_accum = 0 conv_accum = True n_accum = 0 bus_accum = {} gen_accum = {} for i in range(fncsBus.shape[0]): busnum = int(fncsBus[i, 0]) bus_accum[str(busnum)] = [0, 0, 0, 0, 0, 0, 0, 99999.0] for i in range(gen.shape[0]): gen_accum[str(i + 1)] = [0, 0, 0] op = open(rootname + '.csv', 'w') print( 't[s],Converged,Pload,P7 (csv),Unresp (opf),P7 (rpf),Resp (opf),GLD Pub,BID?,P7 Min,V7,LMP_P7,LMP_Q7,Pgen1,Pgen2,Pgen3,Pgen4,Pdisp,Deg,c2,c1', file=op, flush=True) fncs.initialize() # transactive load components csv_load = 0 # from the file unresp = 0 # unresponsive load estimate from the auction agent resp = 0 # will be the responsive load as dispatched by OPF resp_deg = 0 # RESPONSIVE_DEG from FNCS resp_c1 = 0 # RESPONSIVE_C1 from FNCS resp_c2 = 0 # RESPONSIVE_C2 from FNCS resp_max = 0 # RESPONSIVE_MAX_MW from FNCS feeder_load = 0 # amplified feeder MW while ts <= tmax: # start by getting the latest inputs from GridLAB-D and the auction events = fncs.get_events() new_bid = False load_scale = float(fncsBus[0][2]) for key in events: topic = key.decode() if topic == 'UNRESPONSIVE_MW': unresp = load_scale * float(fncs.get_value(key).decode()) fncsBus[0][ 3] = unresp # to poke unresponsive estimate into the bus load slot new_bid = True elif topic == 'RESPONSIVE_MAX_MW': resp_max = load_scale * float(fncs.get_value(key).decode()) new_bid = True elif topic == 'RESPONSIVE_C2': resp_c2 = float(fncs.get_value(key).decode()) / load_scale new_bid = True elif topic == 'RESPONSIVE_C1': resp_c1 = float(fncs.get_value(key).decode()) new_bid = True elif topic == 'RESPONSIVE_DEG': resp_deg = int(fncs.get_value(key).decode()) new_bid = True else: gld_load = parse_mva(fncs.get_value(key).decode( )) # actual value, may not match unresp + resp load feeder_load = float(gld_load[0]) * load_scale if new_bid == True: dummy = 2 # print('**Bid', ts, unresp, resp_max, resp_deg, resp_c2, resp_c1) # update the case for bids, outages and CSV loads idx = int((ts + dt) / period) % nloads bus = ppc['bus'] gen = ppc['gen'] branch = ppc['branch'] gencost = ppc['gencost'] csv_load = loads[idx, 0] bus[4, 2] = loads[idx, 1] bus[8, 2] = loads[idx, 2] # process the generator and branch outages for row in ppc['UnitsOut']: if ts >= row[1] and ts <= row[2]: gen[row[0], 7] = 0 else: gen[row[0], 7] = 1 for row in ppc['BranchesOut']: if ts >= row[1] and ts <= row[2]: branch[row[0], 10] = 0 else: branch[row[0], 10] = 1 if resp_deg == 2: gencost[4][3] = 3 gencost[4][4] = -resp_c2 gencost[4][5] = resp_c1 elif resp_deg == 1: gencost[4][3] = 2 gencost[4][4] = resp_c1 gencost[4][5] = 0.0 else: gencost[4][3] = 1 gencost[4][4] = 999.0 gencost[4][5] = 0.0 gencost[4][6] = 0.0 if ts >= tnext_opf: # expecting to solve opf one dt before the market clearing period ends, so GridLAB-D has time to use it # for OPF, the FNCS bus load is CSV + Unresponsive estimate, with Responsive separately dispatchable bus = ppc['bus'] gen = ppc['gen'] bus[6, 2] = csv_load for row in ppc['FNCS']: unresp = float(row[3]) newidx = int(row[0]) - 1 if unresp >= feeder_load: bus[newidx, 2] += unresp else: bus[newidx, 2] += unresp # feeder_load gen[4][9] = -resp_max res = pp.runopf(ppc, ppopt_market) if res['success'] == False: conv_accum = False opf_bus = deepcopy(res['bus']) opf_gen = deepcopy(res['gen']) lmp = opf_bus[6, 13] resp = -1.0 * opf_gen[4, 1] fncs.publish('LMP_B7', 0.001 * lmp) # publishing $/kwh print(' OPF', ts, csv_load, '{:.3f}'.format(unresp), '{:.3f}'.format(resp), '{:.3f}'.format(feeder_load), '{:.3f}'.format(opf_bus[6, 2]), '{:.3f}'.format(opf_gen[0, 1]), '{:.3f}'.format(opf_gen[1, 1]), '{:.3f}'.format(opf_gen[2, 1]), '{:.3f}'.format(opf_gen[3, 1]), '{:.3f}'.format(opf_gen[4, 1]), '{:.3f}'.format(lmp)) # if unit 2 (the normal swing bus) is dispatched at max, change the swing bus to 9 if opf_gen[1, 1] >= 191.0: ppc['bus'][1, 1] = 2 ppc['bus'][8, 1] = 3 print(' SWING Bus 9') else: ppc['bus'][1, 1] = 3 ppc['bus'][8, 1] = 1 print(' SWING Bus 2') tnext_opf += period # always update the electrical quantities with a regular power flow bus = ppc['bus'] gen = ppc['gen'] bus[6, 13] = lmp gen[0, 1] = opf_gen[0, 1] gen[1, 1] = opf_gen[1, 1] gen[2, 1] = opf_gen[2, 1] gen[3, 1] = opf_gen[3, 1] # during regular power flow, we use the actual CSV + feeder load, ignore dispatchable load and use actual bus[6, 2] = csv_load + feeder_load gen[4, 1] = 0 # opf_gen[4, 1] gen[4, 9] = 0 rpf = pp.runpf(ppc, ppopt_regular) if rpf[0]['success'] == False: conv_accum = False bus = rpf[0]['bus'] gen = rpf[0]['gen'] Pload = bus[:, 2].sum() Pgen = gen[:, 1].sum() Ploss = Pgen - Pload # update the metrics n_accum += 1 loss_accum += Ploss for i in range(fncsBus.shape[0]): busnum = int(fncsBus[i, 0]) busidx = busnum - 1 row = bus[busidx].tolist() # LMP_P, LMP_Q, PD, QD, Vang, Vmag, Vmax, Vmin: row[11] and row[12] are Vmax and Vmin constraints PD = row[ 2] + resp # TODO, if more than one FNCS bus, track scaled_resp separately Vpu = row[7] bus_accum[str(busnum)][0] += row[13] * 0.001 bus_accum[str(busnum)][1] += row[14] * 0.001 bus_accum[str(busnum)][2] += PD bus_accum[str(busnum)][3] += row[3] bus_accum[str(busnum)][4] += row[8] bus_accum[str(busnum)][5] += Vpu if Vpu > bus_accum[str(busnum)][6]: bus_accum[str(busnum)][6] = Vpu if Vpu < bus_accum[str(busnum)][7]: bus_accum[str(busnum)][7] = Vpu for i in range(gen.shape[0]): row = gen[i].tolist() busidx = int(row[0] - 1) # Pgen, Qgen, LMP_P (includes the responsive load as dispatched by OPF) gen_accum[str(i + 1)][0] += row[1] gen_accum[str(i + 1)][1] += row[2] gen_accum[str(i + 1)][2] += float(opf_bus[busidx, 13]) * 0.001 # write the metrics if ts >= tnext_metrics: sys_metrics[str(ts)] = { rootname: [loss_accum / n_accum, conv_accum] } bus_metrics[str(ts)] = {} for i in range(fncsBus.shape[0]): busnum = int(fncsBus[i, 0]) busidx = busnum - 1 row = bus[busidx].tolist() met = bus_accum[str(busnum)] bus_metrics[str(ts)][str(busnum)] = [ met[0] / n_accum, met[1] / n_accum, met[2] / n_accum, met[3] / n_accum, met[4] / n_accum, met[5] / n_accum, met[6], met[7] ] bus_accum[str(busnum)] = [0, 0, 0, 0, 0, 0, 0, 99999.0] gen_metrics[str(ts)] = {} for i in range(gen.shape[0]): met = gen_accum[str(i + 1)] gen_metrics[str(ts)][str(i + 1)] = [ met[0] / n_accum, met[1] / n_accum, met[2] / n_accum ] gen_accum[str(i + 1)] = [0, 0, 0] tnext_metrics += period n_accum = 0 loss_accum = 0 conv_accum = True volts = 1000.0 * bus[6, 7] * bus[6, 9] fncs.publish('three_phase_voltage_B7', volts) # CSV file output print( ts, res['success'], '{:.3f}'.format(Pload), # Pload '{:.3f}'.format(csv_load), # P7 (csv) '{:.3f}'.format(unresp), # GLD Unresp '{:.3f}'.format(bus[6, 2]), # P7 (rpf) '{:.3f}'.format(resp), # Resp (opf) '{:.3f}'.format(feeder_load), # GLD Pub new_bid, '{:.3f}'.format(gen[4, 9]), # P7 Min '{:.3f}'.format(bus[6, 7]), # V7 '{:.3f}'.format(bus[6, 13]), # LMP_P7 '{:.3f}'.format(bus[6, 14]), # LMP_Q7 '{:.2f}'.format(gen[0, 1]), # Pgen1 '{:.2f}'.format(gen[1, 1]), # Pgen2 '{:.2f}'.format(gen[2, 1]), # Pgen3 '{:.2f}'.format(gen[3, 1]), # Pgen4 '{:.2f}'.format(res['gen'][4, 1]), # Pdisp '{:.4f}'.format(resp_deg), # degree '{:.8f}'.format(ppc['gencost'][4, 4]), # c2 '{:.8f}'.format(ppc['gencost'][4, 5]), # c1 sep=',', file=op, flush=True) # request the next time step ts = fncs.time_request(ts + dt) if ts > tmax: print('breaking out at', ts, flush=True) break # spio.savemat('matFile.mat', saveDataDict) # =================================== print('writing metrics', flush=True) print(json.dumps(sys_metrics), file=sys_mp, flush=True) print(json.dumps(bus_metrics), file=bus_mp, flush=True) print(json.dumps(gen_metrics), file=gen_mp, flush=True) print('closing files', flush=True) bus_mp.close() gen_mp.close() sys_mp.close() op.close() print('finalizing FNCS', flush=True) fncs.finalize()
list=false bus_725_phB_Q topic = bus_7XX_phX/bus_725_phB_Q list=false bus_727_phC_Q topic = bus_7XX_phX/bus_727_phC_Q list=false""" voltages_topic = ["bus_701_phA_V","bus_701_phB_V","bus_701_phC_V","bus_712_phC_V","bus_713_phC_V","bus_714_phA_V","bus_714_phB_V","bus_718_phA_V","bus_720_phC_V","bus_722_phB_V","bus_722_phC_V","bus_724_phB_V","bus_725_phB_V","bus_727_phC_V"] load_p_topic = ["bus_701_phA_P","bus_701_phB_P","bus_701_phC_P","bus_712_phC_P","bus_713_phC_P","bus_714_phA_P","bus_714_phB_P","bus_718_phA_P","bus_720_phC_P","bus_722_phB_P","bus_722_phC_P","bus_724_phB_P","bus_725_phB_P","bus_727_phC_P"] load_q_topic = ["bus_701_phA_Q","bus_701_phB_Q","bus_701_phC_Q","bus_712_phC_Q","bus_713_phC_Q","bus_714_phA_Q","bus_714_phB_Q","bus_718_phA_Q","bus_720_phC_Q","bus_722_phB_Q","bus_722_phC_Q","bus_724_phB_Q","bus_725_phB_Q","bus_727_phC_Q"] parameterNames_P=('ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load1/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load2/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L712/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L713/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load1/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L718/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L720/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load1/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L724/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L725/Single-Phase Static Load13/GLD_pNom/Value','ssn_IEEE_37bus/sm_computation/L727/Single-Phase Static Load13/GLD_pNom/Value') parameterNames_Q=('ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load1/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load2/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L712/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L713/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load1/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L718/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L720/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load1/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L724/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L725/Single-Phase Static Load13/GLD_qNom/Value','ssn_IEEE_37bus/sm_computation/L727/Single-Phase Static Load13/GLD_qNom/Value') signalNames=('ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load1/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load1/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load2/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L701/Single-Phase Static Load2/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L712/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L712/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L713/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L713/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load1/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L714/Single-Phase Static Load1/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L718/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L718/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L720/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L720/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load1/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L722/Single-Phase Static Load1/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L724/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L724/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L725/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L725/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)','ssn_IEEE_37bus/sm_computation/L727/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(1)','ssn_IEEE_37bus/sm_computation/L727/Single-Phase Static Load13/Magnitude-Angle to Complex/port1(2)') #Initializing FNCS fncs.initialize(config) print "FNCS initialized.....\n" + str(RtlabApi.GetModelState()[0]) # This the logic that controls the execution, acquisition and controls realTimeMode=realTimeModeList['Hardware Synchronized'] timeFactor=1.0 PauseTime=1.0 multiplier=1 if realTimeMode==1: PauseTime= PauseTime*multiplier # We are going to pause and resume for five different steps and at each time we need to acquire, and send control back to the model. loop = 0 RtlabApi.GetSystemControl() RtlabApi.SetPauseTime(PauseTime-0.00) RtlabApi.SetStopTime(25*PauseTime-0.00) (modelState, realTimeMode) = RtlabApi.GetModelState() if modelState == RtlabApi.MODEL_PAUSED:
def run(self): time_granted = 0 fncs.initialize() time_stop = self.conf.time_stop time_pace = self.conf.time_pace while time_granted < time_stop: time1 = time.perf_counter() time_prev = time_granted time_granted = fncs.time_request(time_stop) time_advance = datetime.timedelta(seconds=(time_granted - time_prev)) self.time = self.time + time_advance events = fncs.get_events() for topic in events: value = fncs.get_value(topic) print((time_granted, topic, value)) key = topic.decode('utf-8') resp = value.decode('utf-8') result = None drop = None with self.lock: if key in self.logSpec: drop = self.logSpec[key].unit elif key in self.subs: drop = self.subs[key][0].unit else: pass resp = drop.sub('', resp) if drop != None else resp try: result = float(resp) except: try: c_resp = resp[0:-1] + 'j' if resp[ -1] == 'i' else resp result = complex(c_resp) except: try: result = str(resp) except: pass obj, attr = key.split('.') self.results[key] = (obj, attr, result, time_granted) if key in self.subs: for sub in self.subs[key]: sub.client.sendClient(sub.obj, sub.attr, result, time_granted) if key in self.logSpec: self.dbase.log(self.time, self.logSpec[key], resp) with self.lock: for pub in self.pubs: topic = pub.topic.encode('utf-8') value = pub.value.encode('utf-8') print((time_granted, topic, value)) fncs.publish(topic, value) if pub.topic in self.logSpec: self.dbase.log(self.time, self.logSpec[pub.topic], pub.value) self.pubs = [] self.dbase.flush() time2 = time.perf_counter() delta = time2 - time1 sleep = time_pace - delta if sleep > 0: time.sleep(sleep)