Beispiel #1
0
def thermal_setpoint_initilize(controller,houseID,NI,NJ):
	for i in range(NI):
		for j in range(NJ):
			value=np.random.uniform(74,76)
			fncs.publish('controller_'+houseID[i][j], value)
			setattr(controller,houseID[i][j], value)
	return
Beispiel #2
0
	def subscribeVal(self, fncs_sub_value_String,time_granted):

		# Update market and house information at this time step from subscribed key values:
		#print('day:', self.day, 'prev day:', self.prevday, flush=True)
		if "DSO" in fncs_sub_value_String:
			for k in range(len(self.controller['Dsystem'])):
				self.market['retail_price'] = fncs_sub_value_String['DSO'][self.market['name']][self.controller['houseName']]['retail_price']
				
				retail_price = self.market['retail_price']
				pistar = self.house[self.controller['Dsystem'][k]]['pistar']	
				systemmode = self.house[self.controller['Dsystem'][k]]['systemmode']
				
				print('time:', time_granted, 'retail price:', retail_price, 'pistar:', pistar, 'systemmode:', systemmode, flush=True)
				if retail_price > pistar: #retail_price > pistar
					#print('pi* is below retail_price: setting Cool OFF for the house', flush = True)
					systemmode = "OFF"
					self.fncs_publish['controller'][self.controller['name']]['state'] = "OFF"
					self.house[self.controller['Dsystem'][k]]['Ta'] = self.house[self.controller['Dsystem'][k]]['TaCaseOFF'] 
					self.house[self.controller['Dsystem'][k]]['Tm'] = self.house[self.controller['Dsystem'][k]]['TmCaseOFF'] 
				elif retail_price <= pistar:
					#print('pi* is above retail_price: setting Cool ON for the house', flush = True)
					systemmode = "COOL"
					self.fncs_publish['controller'][self.controller['name']]['state'] = "COOL"
					self.house[self.controller['Dsystem'][k]]['Ta'] = self.house[self.controller['Dsystem'][k]]['TaCaseON']
					self.house[self.controller['Dsystem'][k]]['Tm'] = self.house[self.controller['Dsystem'][k]]['TmCaseON']
				
				self.house[self.controller['Dsystem'][k]]['systemmode'] = systemmode
				print('setting pistar to:', pistar, flush = True)	
				print('sending systemmode: ',systemmode)
				publish_key = self.controller['Dsystem'][k] + '_system_mode'
				#print('publish_key:', publish_key, flush = True)
				fncs.publish(publish_key, systemmode)
Beispiel #3
0
 def onmessage(self, peer, sender, bus, topic, headers, message):
     d = {'topic': topic, 'headers': headers, 'message': message}
     # Forward message to FNCS
     if not fncs.is_initialized():
         raise RuntimeError("FNCS connection was terminated. Killing Bridge.")
     fncsmessage = str(message)
     topic = topic.replace('fncs/input/','')
     fncs.publish(topic, fncsmessage)
     _log.debug('Volttron->FNCS:\nTopic:%s\nMessage:%s\n'%(topic, message))
Beispiel #4
0
def monitor_powerflow(power_listz, power_maximum):
    for power_list in power_listz:
        for i in range(15):
            #print(power_list)
            if ((power_list[0] == node_index[i])
                    and (power_list[1] == phase_index[i])):

                if (power_list[2] > power_maximum):
                    for j in range(12):
                        fncs.publish('house_' + str(i + 1) + '_' + str(j + 1),
                                     ThermostatMode_action)
                else:
                    for j in range(12):
                        fncs.publish('house_' + str(i + 1) + '_' + str(j + 1),
                                     ThermostatMode_default)
    return 0
Beispiel #5
0
	def tradeResp(self):
		print(self.time_granted, self.request, flush=True)

		req_batt_num = self.msg['ID']
		m_batt_num = self.getBattNum(req_batt_num)
		keyname = m_batt_num + '_solar_power'

		if(keyname in self.solar_power):
			#Solar power is negative in GridLabD
			batt_out = self.msg['power'] + self.solar_power[keyname][-1]
			print('msg[\'power\']: ', str(self.msg['power']),flush=True)
			print('solar power:', self.solar_power[keyname][-1],flush=True)
			print('batt_out:', str(batt_out),flush=True)
		else:
			batt_out = 0

		fncs.publish(m_batt_num + '_batt_P_Out', str(batt_out))
		self.prev_batt_commands[m_batt_num] = batt_out
		print('fncs published:', m_batt_num + '_batt_P_Out', str(batt_out))
		self.server.send_pyobj('Trade Posted') 
Beispiel #6
0
def publish_Price(value):
    #print('checking before updation',fncs_publish['auction'][market['name']]['price_cap']['propertyValue'], flush = True)
    fncs_publish['auction'][market['name']]['market_id']['propertyValue'] = 1
    fncs_publish['auction'][market['name']]['std_dev']['propertyValue'] = 0.01
    fncs_publish['auction'][
        market['name']]['average_price']['propertyValue'] = 0.02078
    fncs_publish['auction'][market['name']]['clear_price'] = value
    fncs_publish['auction'][
        market['name']]['price_cap']['propertyValue'] = 3.78
    fncs_publish['auction'][market['name']]['period']['propertyValue'] = 300
    fncs_publish['auction'][
        market['name']]['initial_price']['propertyValue'] = 0.02078

    fncs_publishString = json.dumps(fncs_publish)
    fncs.agentPublish(fncs_publishString)
    fncs.publish('clear_price', value)
    # for i in range(15):
    # for j in range(12):
    # print('publishing WP: ', value,flush = True)
    # fncs.publish('clear_price'+'_'+'house_'+str(i+1)+'_'+str(j+1), value)
    return 0
Beispiel #7
0
def house_control(houseID,value):
	if value==(-1):
		T=85
		fncs.publish(houseID+'_cooling_setpoint', T)
		#turn off
	elif value==0:
		T=72
		fncs.publish(houseID+'_cooling_setpoint', T)
		 #restore
	elif value==1:
		T=65
		fncs.publish(houseID+'_cooling_setpoint', T)
		 #turn on
	return
Beispiel #8
0
def turn_off(i,j):
	fncs.publish('house_'+str(i)+'_'+str(j)+'_status', -1)
	return
Beispiel #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']
    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()
Beispiel #10
0
def restore(i,j):
	fncs.publish('house_'+str(i)+'_'+str(j)+'_status', 0)
	return
Beispiel #11
0
        elif row[1] == 1:
            refload = parse_kw(value)
            aucObj.set_refload(refload)
        elif row[1] == 2:
            row[0].set_air_temp(value)
        elif row[1] == 3:
            row[0].set_voltage(value)
        elif row[1] == 4:
            row[0].set_hvac_load(value)
        elif row[1] == 5:
            row[0].set_hvac_state(value)

    # set the time-of-day schedule
    for key, obj in hvacObjs.items():
        if obj.change_basepoint(hour_of_day):
            fncs.publish(obj.name + '/cooling_setpoint', obj.basepoint)
    if bSetDefaults:
        for key, obj in hvacObjs.items():
            fncs.publish(obj.name + '/bill_mode', 'HOURLY')
            fncs.publish(obj.name + '/monthly_fee', 0.0)
            fncs.publish(obj.name + '/thermostat_deadband', obj.deadband)
        bSetDefaults = False

    if time_granted >= tnext_bid:
        print('**', tnext_clear)
        aucObj.clear_bids()
        time_key = str(int(tnext_clear))
        controller_metrics[time_key] = {}
        for key, obj in hvacObjs.items():
            bid = obj.formulate_bid()  # bid is [price, quantity, on_state]
            if bWantMarket:
Beispiel #12
0
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()
Beispiel #13
0
                },
                'period': {
                    'propertyType': 'double',
                    'propertyUnit': 'none',
                    'propertyValue': -1.0
                },
                'initial_price': {
                    'propertyType': 'double',
                    'propertyUnit': 'none',
                    'propertyValue': 0.0
                }
            }
        }
    }
    fncs_publish['auction'][market['name']]['clear_price'] = 0.002
    fncs.publish('clear_price', 0.002)
    ts = 0
    tnext = 0
    tnextBill = 300
    dtBill = 300  #2592000
    MonthlyBill = 20
    fncs.initialize()
    iter = 1

    #	ts = -dt
    #	while ts <= tmax:
    #		ts += dt
    p = 0.0167
    a = 0.004
    c = -1
    while ts <= tmax:
Beispiel #14
0
    def sync(self, t1):    
        
        # Update controller t1 information
        self.controller['t1'] = t1
        
        # Inputs from market object:
        marketId = self.market['market_id']
        clear_price = self.market['clear_price']
        avgP = self.market['average_price']
        stdP = self.market['std_dev']
        
        # Inputs from controller:
        ramp_low = self.controller['ramp_low']
        ramp_high = self.controller['ramp_high']
        range_low = self.controller['range_low']
        range_high = self.controller['range_high']
        lastmkt_id = self.controller['lastmkt_id']
        deadband = self.controller['deadband']
        setpoint0 = self.controller['setpoint0']
        last_setpoint = self.controller['last_setpoint']
        minT = self.controller['minT']
        maxT = self.controller['maxT']
        bid_delay = self.controller['bid_delay']
        next_run = self.controller['next_run']
        direction = self.controller['direction']
        
        # Inputs from house object:
        demand = self.house['controlled_load_all']
        monitor = self.house['currTemp']
        powerstate = self.house['powerstate']

        # determine what we have to do in this sync step
        update_setpoints = False
        update_bid = False
        if marketId != lastmkt_id:
            print ('sync: market changed, need to update the setpoints', t1, next_run, marketId, lastmkt_id)
            update_setpoints = True
        elif t1 >= next_run - bid_delay and self.controller_bid['rebid'] == 0: # temporarily disable rebids
            print ('sync: t1 within bidding window, need to publish bid and state', t1, next_run - bid_delay)
            update_bid = True
        else:
#            print ('  returning', next_run)
            return next_run

        print ('  processing', demand, powerstate, monitor, last_setpoint, deadband, direction, clear_price, avgP, stdP)

   # Check t1 to determine if the sync part is needed to be processed or not
   #     if t1 == next_run and marketId == lastmkt_id :
   #         print ('  return because t1 == next_run and marketId == lastmkt_id')
   #         return sys.maxsize    
   #     if  t1 < next_run and marketId == lastmkt_id :
   #         if t1 <= next_run - bid_delay :
   #             if self.controller['use_predictive_bidding'] == 1 and ((self.controller['control_mode'] == 'CN_RAMP' and setpoint0 != last_setpoint) or (self.controller['control_mode'] == 'CN_DOUBLE_RAMP' and (self.controller['heating_setpoint0']  != self.controller['last_heating_setpoint'] or self.controller['cooling_setpoint0']  != self.controller['last_cooling_setpoint']))):
   # Base set point setpoint0 is changed, and therefore sync is needed:
   #                 print (' pass because setpoint0 changed')
   #                 pass
   #             elif self.controller['use_override'] == 'ON' and t1 == next_run - bid_delay :
   # At the exact time that controller is operating, therefore sync is needed:
   #                 print ('  pass because times match exactly')
   #                 pass
   #             else:
   #                 if self.house['last_pState'] == powerstate:
   # If house state not changed, then do not go through sync part:
   #                     print ('  return because house state did not change')
   #                     return next_run
   #         else:
   #             print ('  return because t1 > next_run - bid_delay')
   #             return next_run
        
        # If market get updated, then update the set point                
        deadband_shift = 0
        # Set deadband shift if user predictive bidding is true
        if self.controller['use_predictive_bidding'] == 1:
            deadband_shift = 0.5 * deadband
        
        #  
        if self.controller['control_mode'] == 'CN_RAMP':
            if update_setpoints == True: 
                
                # Update controller last market id and bid id
                self.controller['lastmkt_id'] = marketId
                self.controller['lastbid_id'] = -1
                self.controller_bid['rebid'] = 0 
                
                # Calculate shift direction
                shift_direction = 0
                if self.controller['use_predictive_bidding'] == 1:
                    if (self.controller['dir'] > 0 and clear_price < self.controller['last_p']) or (self.controller['dir'] < 0 and clear_price > self.controller['last_p']):
                        shift_direction = -1
                    elif (self.controller['dir'] > 0 and clear_price >= self.controller['last_p']) or (self.controller['dir'] < 0 and clear_price <= self.controller['last_p']):
                        shift_direction = 1
                    else:
                        shift_direction = 0
                        
                # Calculate updated set_temp
                if abs(stdP) < 0.0001:
                    set_temp = setpoint0
                elif clear_price < avgP and range_low != 0:
                    set_temp = setpoint0 + (clear_price - avgP) * abs(range_low) / (ramp_low * stdP) + deadband_shift*shift_direction
                elif clear_price > avgP and range_high != 0:
                    set_temp = setpoint0 + (clear_price - avgP) * abs(range_high) / (ramp_high * stdP) + deadband_shift*shift_direction
                else:
                    set_temp = setpoint0 + deadband_shift*shift_direction
                
                # override
#                 if self.controller['use_override'] == 'ON' and self.house['re_override'] != 'none':
#                     if clear_price <= self.controller['last_p']:
#                         self.fncs_publish['controller'][self.controller['name']]['override_prop'] = 'ON'
#                     else:
#                         self.fncs_publish['controller'][self.controller['name']]['override_prop'] = 'OFF'
                
                # Check if set_temp is out of limit
                if set_temp > maxT:
                    set_temp = maxT
                elif set_temp < minT:
                    set_temp = minT
                # Update house set point and the cleared price
                if t1 != 0:
                    print('  changing', self.house['lastsetpoint0'], 'to', set_temp, 'at', clear_price)
                    self.house['setpoint0'] = set_temp - self.house['lastsetpoint0'] 
                    fncs.publish('cooling_setpoint', set_temp)
                    fncs.publish('bill_mode', 'HOURLY')
                    fncs.publish('price', clear_price)
                    self.house['lastsetpoint0'] = set_temp
            else:
                # Change of house setpoint only changes when market changes
                self.house['setpoint0'] = 0;
                
            # Calculate bidding price
            # Bidding price when monitored load temperature is at the min and max limit of the controller
            bid_price = -1
            no_bid = 0
            if self.controller['dir'] > 0:
                if self.controller['use_predictive_bidding'] == 1:
                    if powerstate == 'OFF' and monitor > (maxT - deadband_shift):
                        bid_price = self.market['price_cap']
                    elif powerstate != 'OFF' and monitor < (minT + deadband_shift):
                        bid_price = 0
                        no_bid = 1
                    elif powerstate != 'OFF' and monitor > maxT:
                        bid_price = self.market['price_cap']
                    elif powerstate == 'OFF' and monitor < minT:
                        bid_price = 0
                        no_bid = 1
                else:
                    if monitor > maxT:
                        bid_price = self.market['price_cap']
                    elif monitor < minT:
                        bid_price = 0
                        no_bid = 1
            elif self.controller['dir'] < 0:
                if self.controller['use_predictive_bidding'] == 1:
                    if powerstate == 'OFF' and monitor < (minT + deadband_shift):
                        bid_price = self.market['price_cap']
                    elif powerstate != 'OFF' and monitor > (maxT - deadband_shift):
                        bid_price = 0
                        no_bid = 1
                    elif powerstate != 'OFF' and monitor < minT:
                        bid_price = self.market['price_cap']
                    elif powerstate == 'OFF' and monitor > maxT:
                        bid_price = 0
                        no_bid = 1
                else:
                    if monitor < minT:
                        bid_price = self.market['price_cap']
                    elif monitor > maxT:
                        bid_price = 0
                        no_bid = 1
            elif self.controller['dir'] == 0:
                if self.controller['use_predictive_bidding'] == 1:
                    if not(direction):
                        warnings.warn('the variable direction did not get set correctly')
                    elif ((monitor > maxT + deadband_shift) or  (powerstate != 'OFF' and monitor > minT - deadband_shift)) and direction > 0:
                        bid_price = self.market['price_cap']
                    elif ((monitor < minT - deadband_shift) or  (powerstate != 'OFF' and monitor < maxT + deadband_shift)) and direction < 0:
                        bid_price = self.market['price_cap']
                    elif powerstate == 'OFF' and monitor > maxT:
                        bid_price = 0
                        no_bid = 1
                else:
                    if monitor < minT:
                        bid_price = self.market['price_cap']
                    elif monitor > maxT:
                        bid_price = 0
                        no_bid = 1
                    else:
                        bid_price = avgP
            
            # Bidding price when the monitored load temperature is within the controller temp limit
            if monitor > setpoint0:
                k_T = ramp_high
                T_lim = range_high
            elif monitor < setpoint0:
                k_T = ramp_low
                T_lim = range_low
            else:
                k_T = 0
                T_lim = 0
            
            bid_offset = 0.0001
            if bid_price < 0 and monitor != setpoint0:
                if abs(stdP) < bid_offset:
                    bid_price = avgP
                else:
                    bid_price = avgP + (monitor - setpoint0)*(k_T * stdP) / abs(T_lim)   
            elif monitor == setpoint0:
                bid_price = avgP
            
            # Update the outputs
            if demand > 0 and no_bid != 1:
                # Update bid price and quantity
                self.controller['last_p'] = bid_price
                self.controller['last_q'] = demand
#                 self.controller['bid_id'] += 1
                # Check market unit with controller default unit kW
                if (self.market['market_unit']).lower() != "kW":
                    if (self.market['market_unit']).lower() == "w":
                        self.controller['last_q'] = self.controller['last_q']*1000
                    elif (self.market['market_unit']).lower() == "mw":
                        self.controller['last_q'] = self.controller['last_q']/1000
                # Update  parameters
                self.controller_bid['market_id'] = self.controller['lastmkt_id']
                self.controller_bid['bid_price'] = self.controller['last_p']
                self.controller_bid['bid_quantity'] = self.controller['last_q']
               
                # Set controller_bid state
                self.controller_bid['state'] = powerstate
                    
            else:
                # Update bid price and quantity
                self.controller['last_p'] = 0
                self.controller['last_q'] = 0
                # Update controller_bid parameters
                self.controller_bid['market_id'] = 0
                self.controller_bid['bid_price'] = 0
                self.controller_bid['bid_quantity'] = 0
        
        # If the controller is double_ramp type
        elif self.controller['control_mode'] == 'CN_DOUBLE_RAMP':
            midpoint = 0.0
            if self.controller['cool_minT'] - self.controller['heat_maxT'] < deadband:
                if self.controller_bid['resolve_mode'] == 'DEADBAND':
                    midpoint = (self.controller['heat_maxT'] + self.controller['cool_minT']) / 2
                    if (midpoint - deadband/2) < self.controller['heating_setpoint0'] or (midpoint + deadband/2) < self.controller['cooling_setpoint0']:
                        warnings.warn('The midpoint between the max heating setpoint and the min cooling setpoint must be half a deadband away from each base setpoint')
                        return -1
                    else:
                        self.controller['heat_maxT'] = midpoint - deadband/2
                        self.controller['cool_minT'] = midpoint + deadband/2
                elif self.controller_bid['resolve_mode'] == 'SLIDING':
                    if self.controller['heat_maxT'] > self.controller['cooling_setpoint0'] - deadband:
                        warnings.warn('The max heating setpoint must be a full deadband less than the cooling_base_setpoint')
                        return -1
                
                    if self.controller['cool_minT'] < self.controller['heating_setpoint0'] + deadband:
                        warnings.warn('The min cooling setpoint must be a full deadband greater than the heating_base_setpoint')
                        return -1
                    
                    if self.controller['last_mode'] == 'OFF' or self.controller['last_mode'] == 'COOL':
                        self.controller['heat_maxT'] = self.controller['cool_minT'] - deadband
                    elif self.controller['last_mode'] == 'HEAT':
                        self.controller['cool_minT'] = self.controller['heat_maxT'] + deadband
                else:
                    warnings.warn('Unrecognized resolve_mode when double_ramp overlap resolution is needed')
                    return -1
                
            if update_setpoints == True:
                
                # Update controller last market id and bid id
                self.controller['lastmkt_id'] = marketId
                self.controller['lastbid_id'] = -1
                self.controller_bid['rebid'] = 0 
                
                # Calculate shift direction
                shift_direction = 0
                if self.controller['use_predictive_bidding'] == 1:
                    if (self.controller['thermostat_mode'] == 'COOL' and clear_price < self.controller['last_p']) or (self.controller['thermostat_mode'] == 'HEAT' and clear_price > self.controller['last_p']):
                        shift_direction = -1
                    elif (self.controller['thermostat_mode'] == 'COOL' and clear_price >= self.controller['last_p']) or (self.controller['thermostat_mode'] == 'HEAT' and clear_price <= self.controller['last_p']):
                        shift_direction = 1
                    else:
                        shift_direction = 0
                        
                # Calculate updated set_temp
                if abs(stdP) < 0.0001:
                    set_temp_cooling = self.controller['cooling_setpoint0']
                    set_temp_heating = self.controller['heating_setpoint0']
                elif clear_price > avgP:
                    set_temp_cooling = self.controller['cooling_setpoint0'] + (clear_price - avgP) * abs(self.controller['cool_range_high']) / (self.controller['cool_ramp_high'] * stdP) + deadband_shift*shift_direction
                    set_temp_heating = self.controller['heating_setpoint0'] + (clear_price - avgP) * abs(self.controller['heat_range_low']) / (self.controller['heat_ramp_low'] * stdP) + deadband_shift*shift_direction
                elif clear_price < avgP:
                    set_temp_cooling = self.controller['cooling_setpoint0'] + (clear_price - avgP) * abs(self.controller['cool_range_low']) / (self.controller['cool_ramp_low'] * stdP) + deadband_shift*shift_direction
                    set_temp_heating = self.controller['heating_setpoint0'] + (clear_price - avgP) * abs(self.controller['heat_range_high']) / (self.controller['heat_ramp_high'] * stdP) + deadband_shift*shift_direction
                else:
                    set_temp_cooling = self.controller['cooling_setpoint0'] + deadband_shift*shift_direction
                    set_temp_heating = self.controller['heating_setpoint0'] + deadband_shift*shift_direction
                    
                # Check if set_temp is out of limit
                if set_temp_cooling > self.controller['cool_maxT']:
                    set_temp_cooling = self.controller['cool_maxT']
                elif set_temp_cooling < self.controller['cool_minT']:
                    set_temp_cooling = self.controller['cool_minT']
                if set_temp_heating > self.controller['heat_maxT']:
                    set_temp_heating = self.controller['heat_maxT']
                elif set_temp_heating < self.controller['heat_minT']:
                    set_temp_heating = self.controller['heat_minT']
                    
                # Update house set point - output delta setpoint0
                if t1 != 0:
                    self.house['cooling_setpoint0'] = set_temp_cooling - self.house['lastcooling_setpoint0']
                    self.house['lastcooling_setpoint0'] = set_temp_cooling
                    self.house['heating_setpoint0'] = set_temp_heating - self.house['lastheating_setpoint0']
                    self.house['lastheating_setpoint0'] = set_temp_heating
#               fncs.publish('cooling_setpoint', set_temp_cooling)
#               fncs.publish('heating_setpoint', set_temp_heating)
            else:
                self.house['cooling_setpoint0'] = 0
                self.house['heating_setpoint0'] = 0
            
            # Calculate bidding price
            # Bidding price when monitored load temperature is at the min and max limit of the controller
            last_p = last_q = 0.0
            # We have to cool:
            if monitor > self.controller['cool_maxT'] and (self.house['thermostat_state'] == 'UNKNOWN' or self.house['thermostat_state'] == 'OFF'
                                                           or self.house['thermostat_state'] == 'COOL'):
                last_p = self.market['price_cap']
                last_q = self.house['cooling_demand']
            # We have to heat:
            elif monitor < self.controller['heat_minT'] and (self.house['thermostat_state'] == 'UNKNOWN' or self.house['thermostat_state'] == 'OFF'
                                                           or self.house['thermostat_state'] == 'HEAT'):
                last_p = self.market['price_cap']
                last_q = self.house['heating_demand']    
            # We are floating in between heating and cooling
            elif monitor > self.controller['heat_maxT'] and monitor < self.controller['cool_minT']:
                last_p = last_q = 0.0
            # We might heat, if the price is right
            elif monitor <= self.controller['heat_maxT'] and monitor >= self.controller['heat_minT'] and (self.house['thermostat_state'] == 'UNKNOWN' or self.house['thermostat_state'] == 'OFF'
                                                           or self.house['thermostat_state'] == 'HEAT'):
                ramp = self.controller['heat_ramp_high'] if monitor > self.controller['heating_setpoint0'] else self.controller['heat_ramp_low']
                range = self.controller['heat_range_high'] if monitor > self.controller['heating_setpoint0'] else self.controller['heat_range_low']
                if monitor != self.controller['heating_setpoint0']:
                    if abs(stdP) < 0.0001:
                        last_p = avgP
                    else:
                        last_p = avgP + (monitor - self.controller['heating_setpoint0'])*(ramp * stdP) / abs(range)
                last_q = self.house['heating_demand']  
            # We might cool, if the price is right
            elif monitor <= self.controller['cool_maxT'] and monitor >= self.controller['cool_minT'] and (self.house['thermostat_state'] == 'UNKNOWN' or self.house['thermostat_state'] == 'OFF'
                                                           or self.house['thermostat_state'] == 'COOL'):
                ramp = self.controller['cool_ramp_high'] if monitor > self.controller['cooling_setpoint0'] else self.controller['cool_ramp_low']
                range = self.controller['cool_range_high'] if monitor > self.controller['cooling_setpoint0'] else self.controller['cool_range_low']
                if monitor != self.controller['cooling_setpoint0']:
                    if abs(stdP) < 0.0001:
                        last_p = avgP
                    else:
                        last_p = avgP + (monitor - self.controller['cooling_setpoint0'])*(ramp * stdP) / abs(range)
                last_q = self.house['cooling_demand']  
            
            if last_p > self.market['price_cap']:
                last_p = self.market['price_cap']
            if last_p < -self.market['price_cap']:
                last_p = -self.market['price_cap']
            
            # Update the outputs
            # Update bid price and quantity
            self.controller['last_p'] = bid_price
            self.controller['last_q'] = demand
            self.controller['bid_id'] += 1
            
            # Check market unit with controller default unit kW
            if (self.market['market_unit']).lower() != "kW":
                if (self.market['market_unit']).lower() == "w":
                    self.controller['last_q'] = self.controller['last_q']*1000
                elif (self.market['market_unit']).lower() == "mw":
                    self.controller['last_q'] = self.controller['last_q']/1000
                    
            # Update  parameters
            self.controller_bid['market_id'] = self.controller['lastmkt_id']
            self.controller_bid['bid_price'] = last_p
            self.controller_bid['bid_quantity'] = last_q
           
            if last_q > 0.001:
                # Set controller_bid state
                self.controller_bid['state'] = powerstate
            else:
                if self.house['last_pState'] !=  powerstate:
                    # Set controller_bid state
                    self.controller_bid['state'] = powerstate
         
        # Update house last power state
        self.house['last_pState'] = powerstate
        
        # Issue a bid, if appropriate
        if update_bid == True and self.controller_bid['bid_quantity'] > 0 and self.controller_bid['rebid'] == 0: #temporarily disable rebids
            self.fncs_publish['controller'][self.controller['name']]['market_id']['propertyValue'] = self.controller_bid['market_id']
            self.fncs_publish['controller'][self.controller['name']]['bid_id']['propertyValue'] = self.controller['name'] # bid_id is unique for each controller unchanged
            self.fncs_publish['controller'][self.controller['name']]['price']['propertyValue'] = self.controller_bid['bid_price']
            self.fncs_publish['controller'][self.controller['name']]['quantity']['propertyValue'] = self.controller_bid['bid_quantity']
            self.fncs_publish['controller'][self.controller['name']]['bid_accepted']['propertyValue'] = 1 if no_bid == 0 else 0
            self.fncs_publish['controller'][self.controller['name']]['state']['propertyValue'] = self.controller_bid['state']
            self.fncs_publish['controller'][self.controller['name']]['rebid']['propertyValue'] = self.controller_bid['rebid'] 
            self.fncs_publish['controller'][self.controller['name']]['bid_name'] = self.controller['name']
           
            fncs_publishString = json.dumps(self.fncs_publish)
            fncs.agentPublish(fncs_publishString)

            print ('*** Published Bid at', t1, next_run - bid_delay, self.controller_bid['bid_price'], self.controller_bid['bid_quantity'], self.controller_bid['state'], self.controller_bid['rebid'])

            self.controller_bid['rebid'] = 1
        
        # Return sync time t2
        return sys.maxsize
            loadforecast_RP(hour, day, FileName)

    #print ('ts3: ',ts, flush = True)
    if (len(load) != 0):
        #print ('ts3: ',ts, flush = True)
        for i in range(len(load)):
            #print('ts3:', ts, 'load[i][0]:', load[i][0], flush=True)
            if (ts >= load[i][0]):
                #print ('ts4: ',ts, flush = True)
                if (ts == load[i][0]):
                    print('Publishing loadforecast to AMES: ',
                          str(load[i][0]),
                          str(load[i][1]),
                          load[i][2],
                          flush=True)
                    fncs.publish(str(load[i][1]), load[i][2])
            else:
                break
    if (ts < (timeSim + deltaT)):
        ts = fncs.time_request(timeSim + deltaT)
    else:
        #print('time_granted2:', ts, flush = True)
        timeSim = timeSim + deltaT
        ts = fncs.time_request(timeSim + deltaT)

    #print('Day:', day, 'Hour:', hour, flush=True)
    prev_day = day
    prev_hour = hour

fncs.finalize()
Beispiel #16
0
def publish_WholesalePrice(value):
    fncs.publish('WholesalePrice', value)
    return 0
Beispiel #17
0
        bline.append(base_line)
        hour = int(len(bline) / hour_factor)
        minute = (len(bline) - hour * hour_factor) / (minute_factor)
        print('hour: ', hour, ' minutes: ', minute)
        print('base_line: ', base_line)
        print('distribution load: ', distribution_load)
        print('base_line - distribution_load:', power_error)
        dload.append(distribution_load)
        #clear price
        clear_price = market_clearing(power_error, total_hvac, list_pistar,
                                      list_power_level)
        print('************************************************')
        print('************************************************')
        if sub_time >= 10:
            sub_time = 0
            fncs.publish('clear_price', clear_price)
            print('clear_price for next 5 mins:', clear_price)
            #clprice.append(clear_price)
            clprice.extend([clear_price for i in range(10)])
        time_granted = fncs.time_request(timeSim + deltaT)

        #announce price every 5 mins
        #sub_time=0
        #print('*******DLOAD**************')
        #print(dload)
        #print('*******BLINE**************')
        #print(bline)

print('*******DLOAD**************')
print(dload)
print('*******BLINE**************')
Beispiel #18
0
 Ploss = Pgen - Pload
 print(ts, res['success'], bus[:, 2].sum())
 print(ts,
       res['success'],
       bus[:, 2].sum(),
       bus[6, 2],
       bus[6, 7],
       bus[6, 13],
       bus[6, 14],
       gen[0, 1],
       gen[1, 1],
       gen[2, 1],
       gen[3, 1],
       sep=',',
       file=op)
 fncs.publish('LMP_B7', 0.001 * bus[6, 13])
 fncs.publish('three_phase_voltage_B7',
              1000.0 * bus[6, 7] * bus[6, 9])
 print('publishing LMP=', 0.001 * bus[6, 13], 'vpos=',
       1000.0 * bus[6, 7] * bus[6, 9])
 # 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]
     ]
Beispiel #19
0
def turn_on(i, j):
    #turn on hvac by reducing the temprature setpoints
    New_T_setpoint = 60
    fncs.publish(houseID[i][j] + '/cooling_setpoint', New_T_setpoint)

    return
Beispiel #20
0
fncs.initialize()

print('# time key value till', time_stop, flush=True)
alpha = 0.4
factor = 0.1

while time_granted < time_stop:
    print('Resident market time ', time_granted, flush=True)
    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 == 'MonthlyBill':
            alpha = alpha + float(value) * factor
            fncs.publish('Preference', alpha)
    # if time_granted >= time_next:
    # fncs.publish('Preference', alpha)
    # time_next += deltaT
    # if time_next > time_stop:
    # print ('breaking out at',time_next,flush=True)
    # break
    time_next = time_next + deltaT
    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()
# value = value + 0.001
Beispiel #21
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()
Beispiel #22
0
def turn_on(i,j):
	#turn on hvac by reducing the temprature setpoints
	fncs.publish('house_'+str(i)+'_'+str(j)+'_status', 1)
	return
Beispiel #23
0
 signalValues=()
 signals_l = list(RtlabApi.GetSignalsDescription())
 #find only V signal values of interest
 for sig_name in signalNames:
     for item in signals_l:
         if sig_name in item:
             signalValues=signalValues+(item[6],)
 i=0
 for voltage in voltages_topic:
     Voltage_real=signalValues[2*i]
     Voltage_imag=signalValues[2*i+1]
     if Voltage_imag<0:
         Voltage_str=str(Voltage_real) + str(Voltage_imag) + "j"
     else:
         Voltage_str=str(Voltage_real) + "+" + str(Voltage_imag) + "j"
     fncs.publish(voltage,Voltage_str)
     i+=1
 #Get P&Q values
 P_val=()
 for P in load_p_topic:
     P_val=P_val+(round((float(fncs.get_value(P))/10000),2),)
 
 print P_val
 Q_val=()
 for Q in load_q_topic:
     Q_val=Q_val+(round((float(fncs.get_value(Q))/10000),2),)
 print Q_val
 # Get control to send parameters
 RtlabApi.GetParameterControl(1)
 # Send control signals after getting control
 timetest=time.time()
Beispiel #24
0
def restore(i, j):
    #assign default setting, i.e. 72
    New_T_setpoint = 72
    fncs.publish(houseID[i][j] + '/cooling_setpoint', New_T_setpoint)
    return
Beispiel #25
0
    def sync(self, timeSim):    
        
        # Update controller t1 information
        self.controller['t1'] = timeSim
        
        # Inputs from market object:
        marketId = self.market['market_id']
        clear_price = self.market['clear_price']
        avgP = self.market['average_price']
        stdP = self.market['std_dev']
        
        # Inputs from controller:
        
        # Inputs from house object:
        demand = self.house['controlled_load_all']
        monitor = self.house['currTemp']
        powerstate = self.house['powerstate']
        thermostatcontrol = self.house['thermostatcontrol']
        systemmode = self.house['systemmode']
        lastmkt_id = self.controller['lastmkt_id']
        
        air_temperature = self.house['currTemp']
        Tbliss = self.house['Tbliss']
        theta = self.house['theta']
        d = self.house['d']
        P = self.house['P']

        print ("  sync:", demand, powerstate, clear_price, flush=True)
        
        
        if  self.controller['t1'] < self.controller['next_run'] and marketId == lastmkt_id :
            if self.controller['t1'] <= self.controller['next_run'] - bid_delay :
                if self.controller['use_predictive_bidding'] == 1 and ((self.controller['control_mode'] == 'CN_RAMP' and setpoint0 != last_setpoint) or (self.controller['control_mode'] == 'CN_DOUBLE_RAMP' and (self.controller['heating_setpoint0']  != self.controller['last_heating_setpoint'] or self.controller['cooling_setpoint0']  != self.controller['last_cooling_setpoint']))):
                    # Base set point setpoint0 is changed, and therefore sync is needed:
                    pass
                elif self.controller['use_override'] == 'ON' and self.controller['t1'] == self.controller['next_run']- bid_delay :
                    # At the exact time that controller is operating, therefore sync is needed:
                    pass
                else:
                    if self.house['last_pState'] == powerstate:
                        # If house state not changed, then do not go through sync part:
                        return self.controller['next_run']
            else:
                return self.controller['next_run']
        
        # Update house last power state
        self.house['last_pState'] = powerstate
        
        print('checking theta', theta, flush=True)
        print('air_temperature', air_temperature, flush=True)
        print('clear_price', clear_price, flush=True)
        pi = theta * air_temperature
        print('pi*:', pi, theta * air_temperature, flush=True)
        if air_temperature >= Tbliss + d:
            print('air_temperature exceeded Tmax: setting Cool ON for the house', flush=True)
            systemmode = "COOL"
        elif Tbliss - d >= air_temperature:
            print('air_temperature is below Tmin: setting Cool OFF for the house', flush = True)
            systemmode = "OFF"
        elif clear_price > theta * air_temperature:
            print('pi* is below clear_price: setting Cool OFF for the house', flush = True)
            systemmode = "OFF"
        else: 
            print('pi* is above clear_price: setting Cool ON for the house', flush = True)
            systemmode = "COOL"
        fncs.publish('system_mode', systemmode)
        print('publishing set values', flush = True)
        fncs_publishString = json.dumps(self.fncs_publish)
        fncs.agentPublish(fncs_publishString)
        # Return sync time t2
        return sys.maxsize
Beispiel #26
0
Datei: test.py Projekt: 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()
Beispiel #27
0
def turn_off(i, j):
    #turn on havac by increasing the temperature set points
    New_T_setpoint = 100
    fncs.publish(houseID[i][j] + '/cooling_setpoint', New_T_setpoint)
    return
Beispiel #28
0
# requires the zpl/yaml file
fncs.initialize()
print('*****FNCS HAS INITIALIZED******')
print("# time      key       value", file=op)

while time_granted < time_stop:
    time_granted = fncs.time_request(time_stop)
    events = fncs.get_events()
    SubKeys = []
    SubKeyVals = []
    for key in events:
        print(time_granted,
              key.decode(),
              fncs.get_value(key).decode(),
              file=op)
        Temp = str(key.decode())
        SubKeys.append(Temp)
        Temp = str(fncs.get_value(key).decode())
        SubKeyVals.append(Temp)
    keys, key_val = fncs_parser.synch(SubKeys, SubKeyVals)

    for i in range(len(keys)):
        print(str(keys[i]))
        print(str(key_val[i]))
        fncs.publish(str(keys[i]), str(key_val[i]))
    time.sleep(5)

fncs.finalize()
op.close()
print('*****FNCS HAS ENDED******')
Beispiel #29
0
        else:
            pair = topic.split('#')
            houseName = pair[0]
            if pair[1] == 'V1':
                voltages[houseName] = parse_fncs_magnitude(value)
            elif pair[1] == 'Tair':
                temperatures[houseName] = parse_fncs_magnitude(value)

    if bSetDeadbands:
        bSetDeadbands = False
        print('setting thermostat deadbands at', time_granted)
        # set all of the house deadbands and initial setpoints
        for house, row in dict['houses'].items():
            topic = house + '_thermostat_deadband'
            value = row['deadband']
            fncs.publish(topic, value)
            setpoints[house] = 0.0
            lastchange[house] = -lockout_period
            precooling_status[house] = False

    # update all of the house setpoints
    count_temp_dev = 0
    sum_temp_dev = 0.0
    min_temp_dev = 10000.0
    max_temp_dev = 0.0
    for house, row in dict['houses'].items():
        # time-scheduled setpoints
        if hour_of_day >= row['day_start_hour'] and hour_of_day <= row[
                'day_end_hour']:
            value = row['day_set']
        else:
Beispiel #30
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)
Beispiel #31
0
	distribution_load=[]
	while ts <= tmax:
#		print ("looping", ts, tnext, tmax, flush=True)
		if ts >= tnext:
			tnext += dt
			if tnext > tmax:
				# print ('breaking out at',tnext,flush=True)
				break
		ts = fncs.time_request(tnext)
		events = fncs.get_events()
		for key in events:
			topic = key.decode()
			value = float(fncs.get_value(key).decode())
			if topic == 'rt_price':
				price=value
				for i in range (15):
					for j in range(12):
						New_T_setpoint=house_control(i,j,price,controller)
						fncs.publish('controller_'+houseID[i][j], New_T_setpoint) #publish new set point to hous i j in gridlab
						#setattr(controller,houseID[i][j],New_T_setpoint) # set new setpoint to controller dictionary
			if topic=='distribution_load':
				distribution_load.append(value)
				#print (distribution_load)
                      
	print ('finalizing FNCS', flush=True)
	logfile('distribution_load.txt',distribution_load)
	fncs.finalize()