Exemplo n.º 1
0
 def stop(self):
     try:
         self.service.stop()
     except:
         pass
     try:
         self.broker.kill()
     except:
         pass
     try:
         self.engine.kill()
     except:
         pass
     try:
         self.dbase.stop()
     except:
         pass
     try:
         fncs.finalize()
     except:
         pass
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
def kill_all():
    if sys.platform == 'win32':
        fncs.finalize()
        subprocess.Popen('call kill5570.bat', shell=True)
    else:
        print('TODO: kill all processes')
Exemplo n.º 5
0
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()
Exemplo n.º 6
0
Arquivo: test.py Projeto: FNCS/fncs
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()
Exemplo n.º 7
0
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()
Exemplo n.º 8
0
	def mainLoop(self):
		if(self.RIAPS):
			self.context = zmq.Context(1)
			self.server = self.context.socket(zmq.REP)
			self.server.bind("tcp://*:5555")

			while self.time_granted < self.time_stop:
				events = fncs.get_events()
				for topic in events:
					value = fncs.get_value(topic)
					#Collect Most recent charge data
					if('batt_charge' in topic):
						self.batt_charges[topic] = float(value.split(" ")[0][1:])
					if('solar_power' in topic):
						if topic in self.solar_power:
							self.solar_power[topic].append(float(value.split(' ')[0]))
						else:
							self.solar_power[topic] = [float(value.split(' ')[0])]
					if('batt_power' in topic):
						if topic in self.batt_power:
							self.batt_power[topic].append(float(value.split(' ')[0]))
						else:
							self.batt_power[topic] = [float(value.split(' ')[0])]
				if('step' in events):
					self.request = ''
					while(self.request != 'step'):
						self.msg = self.server.recv_pyobj()
						self.request = self.msg['request']
						if (self.request == 'postTrade'):
							self.tradeResp()
						if (self.request == 'charge'):
							self.chargeResp()
					print(self.time_granted, self.request, flush=True)
					print("solar_power: ", self.solar_power)
					print("batt_power: ", self.batt_power)
					self.solar_power = {}
					self.batt_power = {}
					self.time_granted = fncs.time_request(self.time_stop)
					self.server.send_pyobj('Step Granted')
					
				else:
					self.time_granted = fncs.time_request(self.time_stop)
					print("Simulation Continue, new time_granted:", str(self.time_granted))

			self.server.close()
			self.context.term()
			print('zmq Closed', flush=True)

		else:
			while self.time_granted < self.time_stop:
				self.time_granted = fncs.time_request(self.time_stop)
				events = fncs.get_events()
				for topic in events:
					value = fncs.get_value(topic)
					#Collect Most recent charge data
					if('batt_charge' in topic):
						self.batt_charges[topic] = value
					if('solar_power' in topic):
						self.solar_power[topic] = value



		print('End of Simulation', flush=True)
		fncs.finalize()

		if sys.platform != 'win32':
			usage = resource.getrusage(resource.RUSAGE_SELF)
			RESOURCES = [
			('ru_utime', 'User time'),
			('ru_stime', 'System time'),
			('ru_maxrss', 'Max. Resident Set Size'),
			('ru_ixrss', 'Shared Memory Size'),
			('ru_idrss', 'Unshared Memory Size'),
			('ru_isrss', 'Stack Size'),
			('ru_inblock', 'Block inputs'),
			('ru_oublock', 'Block outputs')]
			print('Resource usage:')
			for name, desc in RESOURCES:
				print('  {:<25} ({:<10}) = {}'.format(desc, name, getattr(usage, name)))
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
    def publish_heartbeat(self):
        '''Send heartbeat message every HEARTBEAT_PERIOD seconds.

        HEARTBEAT_PERIOD is set and can be adjusted in the settings module.
        '''
        now = datetime.utcnow().isoformat(' ') + 'Z'
        nowdate = datetime.utcnow()
        print "publish_heartbeat", now
        timeDiff = nowdate - self.simStart
        valMap = defaultdict(dict)
        metaMap = defaultdict(dict)
        headers = {headers_mod.TIMESTAMP: now, headers_mod.DATE: now}
        #Tell FNCS we are at our next timestep
        if not fncs.is_initialized():
            raise RuntimeError("FNCS connection was terminated. Killing Bridge.")
        elif self.simtime > self.simlength:
            fncs.finalize()
            self.core.stop()
        elif timeDiff.seconds >= 1:
            self.simtime+=self.heartbeat_period*self.heartbeat_multiplier
            print "fncs.time_request(",self.simtime,") request"
            self.simtime = fncs.time_request(self.simtime)
            print "fncs.time_request() response", self.simtime
            #Grab Subscriptions from FNCS to publish to Volttron message bus
            subKeys = fncs.get_events()
            if len(subKeys) > 0:
                for x in subKeys:
                    valStr = fncs.get_value(x)
                    #parse message to split value and unit
                    valList = valStr.split(' ')
                    if len(valList) == 1:
                        val = valList[0]
                        valUnit = '';
                        try:
                            val = float(val)
                        except:
                            pass
                    elif len(valList) == 2:
                        val = valList[0]
                        valUnit = valList[1]
                        if 'int' in self.fncs_zpl['values'][x]['type']:
                            val = int(val)
                        elif 'double' in self.fncs_zpl['values'][x]['type']:
                            val = float(val)
                        elif 'complex' in self.fncs_zpl['values'][x]['type']:
                            raise RuntimeError("complex data type is currently not supported in Volttron.")
                        #TODO: come up with a better way to handle all types that can come in from fncs
                    else:
                        warnings.warn("FNCS message could not be parsed into value and unit. The message will be farwarded to Volttron message bus as is.")
                        val = valStr
                        valUnit = ''
                    fncsmessage = [val, {'units' : '{0}'.format(valUnit), 'tz' : 'UTC', 'type': '{0[type]}'.format(self.fncs_zpl['values'][x])}]
                    fncsTopic = common.FNCS_OUTPUT_PATH(path = 'devices/{0[topic]}'.format(self.fncs_zpl['values'][x])) #fncs/output/devices/topic
                    self.vip.pubsub.publish('pubsub', fncsTopic, headers, fncsmessage).get(timeout=5)
                    _log.debug('FNCS->Volttron:\nTopic:%s\n:Message:%s\n'%(fncsTopic, str(fncsmessage)))
                    device, point = self.fncs_zpl['values'][x]['topic'].rsplit('/', 1)
                    deviceAllTopic = common.FNCS_OUTPUT_PATH(path = 'devices/' + device + '/all')
                    valMap[deviceAllTopic][point] = val
                    metaMap[deviceAllTopic][point] = fncsmessage[1]
                for k in valMap.keys():
                    allMessage = [valMap[k], metaMap[k]]
                    self.vip.pubsub.publish('pubsub', k, headers, allMessage).get(timeout=5)
                    _log.debug('FNCS->Volttron:\nTopic:%s\n:Message:%s\n'%(k, str(allMessage)))
                    
                
        #Publish heartbeat message to voltron bus        
        self.vip.pubsub.publish(
            'pubsub', '{0[name]}/heartbeat'.format(self.fncs_zpl), headers, now).get(timeout=5)