예제 #1
0
파일: tesp_monitor.py 프로젝트: tpr1/tesp
 def on_closing(self):
   if messagebox.askokcancel('Quit', 'Do you want to close this window? This is likely to stop all simulations.'):
     self.root.quit()
     self.root.destroy()
     if self.bFNCSactive:
       fncs.finalize()
       self.bFNCSactive = False
예제 #2
0
 def Quit(self):
     """Shuts down this monitor, and also shuts down FNCS if active
 """
     self.root.quit()
     self.root.destroy()
     if self.bFNCSactive:
         fncs.finalize()
         self.bFNCSactive = False
예제 #3
0
 def kill_all(self):
     for proc in self.pids:
         print('trying to kill', proc.pid)
         proc.terminate()
     self.root.update()
     print('trying to finalize FNCS')
     fncs.finalize()
     print('FNCS finalized')
예제 #4
0
 def kill_all(self):
     """Shut down all FNCS federates in TESP, except for this monitor
 """
     for proc in self.pids:
         print('trying to kill', proc.pid)
         proc.terminate()
     self.root.update()
     print('trying to finalize FNCS')
     if self.bFNCSactive:
         fncs.finalize()
         self.bFNCSactive = False
     print('FNCS finalized')
예제 #5
0
    def on_closing(self):
        """Verify whether the user wants to stop TESP simulations before exiting the monitor

    This monitor is itself a FNCS federate, so it can not be shut down without shutting
    down all other FNCS federates in the TESP simulation.
    """
        if messagebox.askokcancel(
                'Quit',
                'Do you want to close this window? This is likely to stop all simulations.'
        ):
            self.root.quit()
            self.root.destroy()
            if self.bFNCSactive:
                fncs.finalize()
                self.bFNCSactive = False
예제 #6
0
def pypower_loop (casefile, rootname):
  """ Public function to start PYPOWER solutions under control of FNCS

  The time step, maximum time, and other data must be set up in a JSON file.
  This function will run the case under FNCS, manage the FNCS message traffic,
  and shutdown FNCS upon completion. Five files are written:

  - *rootname.csv*; intermediate solution results during simulation
  - *rootname_m_dict.json*; metadata for post-processing
  - *bus_rootname_metrics.json*; bus metrics for GridLAB-D connections, upon completion
  - *gen_rootname_metrics.json*; bulk system generator metrics, upon completion
  - *sys_rootname_metrics.json*; bulk system-level metrics, upon completion

  Args:
    casefile (str): the configuring JSON file name, without extension
    rootname (str): the root filename for metrics output, without extension
  """
#  if len(sys.argv) == 3:
#    rootname = sys.argv[1]
#    casefile = sys.argv[2]
#  else:
#    print ('usage: python fncsPYPOWER.py metrics_rootname casedata.json')
#    sys.exit()

  ppc = load_json_case (casefile)
  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=ppc['opf_dc'])
  ppopt_regular = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=ppc['pf_dc'])
  loads = np.loadtxt(ppc['CSVFile'], 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 topic in events:
      value = fncs.get_value(topic)
      if topic == 'UNRESPONSIVE_MW':
        unresp = load_scale * float(value)
        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(value)
        new_bid = True
      elif topic == 'RESPONSIVE_C2':
        resp_c2 = float(value) / load_scale
        new_bid = True
      elif topic == 'RESPONSIVE_C1':
        resp_c1 = float(value)
        new_bid = True
      elif topic == 'RESPONSIVE_DEG':
        resp_deg = int(value)
        new_bid = True
      else:
        gld_load = parse_mva (value) # 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] += 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 # the ERCOT version shows how to track scaled_resp separately for each FNCS bus
      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] / sqrt(3.0)  # VLN for GridLAB-D
    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, if necessary
    if ts >= tmax:
      print ('breaking out at',ts,flush=True)
      break
    ts = fncs.time_request(min(ts + dt, tmax))

  # ===================================
  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()

  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)))
예제 #7
0
    def update_plots(self, i):
        """This function is called by Matplotlib for each animation frame

    Each time called, collect FNCS messages until the next time to plot
    has been reached. Then update the plot quantities and return the
    Line2D objects that have been updated for plotting. Check for new
    data outside the plotted vertical range, which triggers a full
    re-draw of the axes. On the last frame, finalize FNCS.

    Args:
      i (int): the animation frame number
    """
        #    print ('.', end='')
        #    print ('frame', i, 'of', self.nsteps)
        bRedraw = False
        while self.time_granted < self.time_stop:  # time in seconds
            # find the time value and index into the time (X) array
            self.time_granted = fncs.time_request(self.time_stop)
            events = fncs.get_events()
            self.root.update()
            idx = int(self.time_granted / self.yaml_delta)
            if idx <= self.idxlast:
                continue
            self.idxlast = idx
            h = float(self.time_granted / 3600.0)
            self.hrs.append(h)

            # find the newest Y values
            v0 = 0.0
            v1 = 0.0
            v2auc = 0.0
            v2lmp = 0.0
            v3 = 0.0
            for topic in events:
                value = fncs.get_value(topic)
                if topic == 'power_A':
                    v1 = 3.0 * float(value.strip('+ degFkW')) / 1000.0
                elif topic == 'distribution_load':
                    v3 = helpers.parse_kw(value)
                    self.gld_load = v3
                elif topic == 'vpos7':
                    v0 = float(value.strip('+ degFkW')) / 133000.0
                elif topic == 'clear_price':
                    v2auc = float(value.strip('+ degFkW'))
                elif topic == 'LMP7':
                    v2lmp = float(value.strip('+ degFkW'))
                elif topic == 'SUBSTATION7':
                    v1 = float(value.strip('+ degFkW'))  # already in kW

            # expand the Y axis limits if necessary, keeping a 10% padding around the range
            if v0 < self.y0min or v0 > self.y0max:
                self.y0min, self.y0max = self.expand_limits(
                    v0, self.y0min, self.y0max)
                self.ax[0].set_ylim(self.y0min, self.y0max)
                bRedraw = True
            if v1 < self.y1min or v1 > self.y1max:
                self.y1min, self.y1max = self.expand_limits(
                    v1, self.y1min, self.y1max)
                self.ax[1].set_ylim(self.y1min, self.y1max)
                bRedraw = True
            if v2auc > v2lmp:
                v2max = v2auc
                v2min = v2lmp
            else:
                v2max = v2lmp
                v2min = v2auc
            if v2min < self.y2min or v2max > self.y2max:
                self.y2min, self.y2max = self.expand_limits(
                    v2min, self.y2min, self.y2max)
                self.y2min, self.y2max = self.expand_limits(
                    v2max, self.y2min, self.y2max)
                self.ax[2].set_ylim(self.y2min, self.y2max)
                bRedraw = True
            if v3 < self.y3min or v3 > self.y3max:
                self.y3min, self.y3max = self.expand_limits(
                    v3, self.y3min, self.y3max)
                self.ax[3].set_ylim(self.y3min, self.y3max)
                bRedraw = True

            # update the Y axis data to draw
            self.y0.append(v0)  # Vpu
            self.y1.append(v1)  # school kW
            self.y2auc.append(v2auc)  # price
            self.y2lmp.append(v2lmp)  # LMP
            self.y3fncs.append(
                v3)  # this feeder load from FNCS (could be zero if no update)
            self.y3gld.append(
                self.gld_load)  # most recent feeder load from FNCS
            self.ln0.set_data(self.hrs, self.y0)
            self.ln1.set_data(self.hrs, self.y1)
            self.ln2auc.set_data(self.hrs, self.y2auc)
            self.ln2lmp.set_data(self.hrs, self.y2lmp)
            self.ln3fncs.set_data(self.hrs, self.y3fncs)
            self.ln3gld.set_data(self.hrs, self.y3gld)

            if bRedraw:
                #        print ('redrawing axes')
                self.fig.canvas.draw()
            if i >= (self.nsteps - 1):
                print('finalizing FNCS')
                fncs.finalize()
                print('FNCS active to False')
                self.bFNCSactive = False

            return self.ln0, self.ln1, self.ln2auc, self.ln2lmp, self.ln3fncs, self.ln3gld,

        print('not finalizing FNCS')
        return self.ln0, self.ln1, self.ln2auc, self.ln2lmp, self.ln3fncs, self.ln3gld,  # in case we miss the last point
예제 #8
0
파일: fncsERCOT.py 프로젝트: pkritpra/tesp
            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

    # request the next time step, if necessary
    if ts >= tmax:
        print('breaking out at', ts, flush=True)
        break
    ts = fncs.time_request(min(ts + dt, tmax))

# ======================================================
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()
vp.close()
print('finalizing FNCS', flush=True)
fncs.finalize()
예제 #9
0
파일: tesp_monitor.py 프로젝트: tpr1/tesp
  def update_plots(self, i):
    print ('.', end='')
#    print ('frame', i, 'of', self.nsteps)
    bRedraw = False
    while self.time_granted < self.time_stop: # time in minutes
      self.time_granted = fncs.time_request(self.time_stop)
      events = fncs.get_events()
      self.root.update()
      idx = int (self.time_granted / self.yaml_delta)
      if idx <= self.idxlast:
        continue
      self.idxlast = idx

      v0 = 0.0
      v1 = 0.0
      v2 = 0.0
      v3 = 0.0

      for topic in events:
        value = fncs.get_value(topic)
        if topic == 'power_A':
          v1 = 3.0 * float (value.strip('+ degFkW')) / 1000.0
        elif topic == 'distribution_load':
          v3 = simple_auction.parse_kw (value)
        elif topic == 'vpos7':
          v0 = float (value.strip('+ degFkW')) / 133000.0
        elif topic == 'clear_price':
          v2 = float (value.strip('+ degFkW'))
        elif topic == 'LMP7':
          v2 = float (value.strip('+ degFkW'))
        elif topic == 'SUBSTATION7':
          v1 = float (value.strip('+ degFkW')) # already in kW

      retval = [self.ln0, self.ln1, self.ln2, self.ln3]

      h = float (self.time_granted / 60.0)
      self.hrs.append (h)
      if v0 < self.y0min or v0 > self.y0max:
        if v0 < self.y0min:
          self.y0min = v0
        if v0 > self.y0max:
          self.y0max = v0
        self.ax[0].set_ylim (self.y0min, self.y0max)
        bRedraw = True
      if v1 < self.y1min or v1 > self.y1max:
        if v1 < self.y1min:
          self.y1min = v1
        if v1 > self.y1max:
          self.y1max = v1
        self.ax[1].set_ylim (self.y1min, self.y1max)
        bRedraw = True
      if v2 < self.y2min or v2 > self.y2max:
        if v2 < self.y2min:
          self.y2min = v2
        if v2 > self.y2max:
          self.y2max = v2
        self.ax[2].set_ylim (self.y2min, self.y2max)
        bRedraw = True
      if v3 < self.y3min or v3 > self.y3max:
        if v3 < self.y3min:
          self.y3min = v3
        if v3 > self.y3max:
          self.y3max = v3
        self.ax[3].set_ylim (self.y3min, self.y3max)
        bRedraw = True

      self.y0.append (v0) # Vpu
      self.y1.append (v1) # school kW
      self.y2.append (v2) # price
      self.y3.append (v3) # feeder load
      self.ln0.set_data (self.hrs, self.y0)
      self.ln1.set_data (self.hrs, self.y1)
      self.ln2.set_data (self.hrs, self.y2)
      self.ln3.set_data (self.hrs, self.y3)

      if bRedraw:
        self.fig.canvas.draw()
      if i >= (self.nsteps - 1):
        fncs.finalize()
        self.bFNCSactive = False
      return retval
예제 #10
0
파일: tesp_monitor.py 프로젝트: tpr1/tesp
 def Quit(self):
   self.root.quit()
   self.root.destroy()
   if self.bFNCSactive:
     fncs.finalize()
     self.bFNCSactive = False
예제 #11
0
파일: precool.py 프로젝트: ikdmob/tesp
def precool_loop(nhours, metrics_root):
    time_stop = int(3600 * nhours)

    lp = open(metrics_root + "_agent_dict.json").read()
    dict = json.loads(lp)
    precool_meta = {
        'temperature_deviation_min': {
            'units': 'degF',
            'index': 0
        },
        'temperature_deviation_max': {
            'units': 'degF',
            'index': 1
        },
        'temperature_deviation_avg': {
            'units': 'degF',
            'index': 2
        }
    }
    StartTime = "2013-07-01 00:00:00 PST"
    precool_metrics = {'Metadata': precool_meta, 'StartTime': StartTime}

    dt = dict['dt']
    mean = dict['mean']
    stddev = dict['stddev']
    period = dict['period']
    k = dict['k_slope']

    print('run till', time_stop, 'period', period, 'step', dt, 'mean', mean,
          'stddev', stddev, 'k_slope', k)

    fncs.initialize()

    time_granted = 0
    price = 0.11  # mean

    # time_next = dt
    voltages = {}
    temperatures = {}
    setpoints = {}  # publish a new one only if changed
    lastchange = {}
    precooling_quiet = 4 * 3600
    precooling_off = 25 * 3600  # never turns off
    precooling_status = {}
    lockout_period = 360

    bSetDeadbands = True
    nPrecoolers = 0

    while time_granted < time_stop:
        time_granted = fncs.time_request(time_stop)  # time_next
        hour_of_day = 24.0 * ((float(time_granted) / 86400.0) % 1.0)
        events = fncs.get_events()
        for topic in events:
            value = fncs.get_value(topic)
            if topic == 'price':
                price = float(value)
            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 and heating setpoints 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
                fncs.publish(house + '_heating_setpoint', 60.0)

        # 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:
                value = row['night_set']
            # comfort metrics
            if house in temperatures:
                temp_dev = abs(temperatures[house] - value)
                if temp_dev < min_temp_dev:
                    min_temp_dev = temp_dev
                if temp_dev > max_temp_dev:
                    max_temp_dev = temp_dev
                sum_temp_dev += temp_dev
                count_temp_dev += 1
            # time-of-day price response
            tdelta = (price - mean) * row['deadband'] / k / stddev
            value += tdelta
            # overvoltage checks
            if time_granted >= precooling_quiet and not precooling_status[
                    house]:
                if house in voltages:
                    if voltages[house] > row['vthresh']:
                        precooling_status[house] = True
                        nPrecoolers += 1
            elif time_granted >= precooling_off:
                precooling_status[house] = False
            # overvoltage response
            if precooling_status[house]:
                value += row['toffset']
            if abs(value - setpoints[house]) > 0.1:
                if (time_granted - lastchange[house]) > lockout_period:
                    topic = house + '_cooling_setpoint'
                    fncs.publish(topic, value)
                    setpoints[house] = value
                    lastchange[house] = time_granted
                    print('setting', house, 'to', value, 'at', time_granted,
                          'precooling', precooling_status[house])

        if count_temp_dev < 1:
            count_temp_dev = 1
            min_temp_dev = 0.0
        precool_metrics[str(time_granted)] = [
            min_temp_dev, max_temp_dev, sum_temp_dev / count_temp_dev
        ]

        time_next = time_granted + dt

    print(nPrecoolers, 'houses participated in precooling')
    print('writing metrics', flush=True)
    mp = open("precool_" + metrics_root + "_metrics.json", "w")
    print(json.dumps(precool_metrics), file=mp)
    mp.close()
    print('done', flush=True)

    print('finalizing FNCS', 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)))
예제 #12
0
파일: auction.py 프로젝트: thuang/tesp
def auction_loop (configfile, metrics_root, flag='WithMarket'):
    bWantMarket = True
    if flag == 'NoMarket':
        bWantMarket = False
        print ('Disabled the market', flush=True)
    time_stop = int (48 * 3600) # simulation time in seconds
    StartTime = '2013-07-01 00:00:00 -0800'
    time_fmt = '%Y-%m-%d %H:%M:%S %z'
    dt_now = datetime.strptime (StartTime, time_fmt)

    # ====== load the JSON dictionary; create the corresponding objects =========

    lp = open (configfile).read()
    dict = json.loads(lp)

    market_key = list(dict['markets'].keys())[0]  # TODO: only using the first market
    market_row = dict['markets'][market_key]
    unit = market_row['unit']

    auction_meta = {'clearing_price':{'units':'USD','index':0},'clearing_type':{'units':'[0..5]=[Null,Fail,Price,Exact,Seller,Buyer]','index':1}}
    controller_meta = {'bid_price':{'units':'USD','index':0},'bid_quantity':{'units':unit,'index':1}}
    auction_metrics = {'Metadata':auction_meta,'StartTime':StartTime}
    controller_metrics = {'Metadata':controller_meta,'StartTime':StartTime}

    aucObj = simple_auction.simple_auction (market_row, market_key)

    dt = float(dict['dt'])
    period = aucObj.period

    topicMap = {} # to dispatch incoming FNCS messages; 0..5 for LMP, Feeder load, airtemp, mtr volts, hvac load, hvac state
    topicMap['LMP'] = [aucObj, 0]
    topicMap['refload'] = [aucObj, 1]

    hvacObjs = {}
    hvac_keys = list(dict['controllers'].keys())
    for key in hvac_keys:
      row = dict['controllers'][key]
      hvacObjs[key] = simple_auction.hvac (row, key, aucObj)
      ctl = hvacObjs[key]
      topicMap[key + '#Tair'] = [ctl, 2]
      topicMap[key + '#V1'] = [ctl, 3]
      topicMap[key + '#Load'] = [ctl, 4]
      topicMap[key + '#On'] = [ctl, 5]

    # ==================== Time step looping under FNCS ===========================

    fncs.initialize()
    aucObj.initAuction()
    LMP = aucObj.mean
    refload = 0.0
    bSetDefaults = True

    tnext_bid = period - 2 * dt  #3 * dt  # controllers calculate their final bids
    tnext_agg = period - 2 * dt  # auction calculates and publishes aggregate bid
    tnext_opf = period - 1 * dt  # PYPOWER executes OPF and publishes LMP (no action here)
    tnext_clear = period         # clear the market with LMP
    tnext_adjust = period        # + dt   # controllers adjust setpoints based on their bid and clearing

    time_granted = 0
    time_last = 0
    while (time_granted < time_stop):
        time_granted = fncs.time_request(time_stop)
        time_delta = time_granted - time_last
        time_last = time_granted
        hour_of_day = 24.0 * ((float(time_granted) / 86400.0) % 1.0)
# TODO - getting an overflow error when killing process - investigate whether that happens if simulation runs to completion
#        print (dt_now, time_delta, timedelta (seconds=time_delta))
        dt_now = dt_now + timedelta (seconds=time_delta)
        day_of_week = dt_now.weekday()
        hour_of_day = dt_now.hour
        print ('  ', time_last, time_granted, time_stop, time_delta, hour_of_day, day_of_week, flush=True)

        # update the data from FNCS messages
        events = fncs.get_events()
        for key in events:
            topic = key.decode()
            value = fncs.get_value(key).decode()
            row = topicMap[topic]
            if row[1] == 0:
                LMP = simple_auction.parse_fncs_magnitude (value)
                aucObj.set_lmp (LMP)
            elif row[1] == 1:
                refload = simple_auction.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, day_of_week):
                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)
                fncs.publish (obj.name + '/heating_setpoint', 60.0)
            bSetDefaults = False

        if time_granted >= tnext_bid:
            print ('**', tnext_clear, flush=True)
            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:
                    aucObj.collect_bid (bid)
                controller_metrics[time_key][obj.name] = [bid[0], bid[1]]
            tnext_bid += period

        if time_granted >= tnext_agg:
            aucObj.aggregate_bids()
            fncs.publish ('unresponsive_mw', aucObj.agg_unresp)
            fncs.publish ('responsive_max_mw', aucObj.agg_resp_max)
            fncs.publish ('responsive_c2', aucObj.agg_c2)
            fncs.publish ('responsive_c1', aucObj.agg_c1)
            fncs.publish ('responsive_deg', aucObj.agg_deg)
            tnext_agg += period

        if time_granted >= tnext_clear:
            if bWantMarket:
                aucObj.clear_market()
                fncs.publish ('clear_price', aucObj.clearing_price)
                for key, obj in hvacObjs.items():
                    obj.inform_bid (aucObj.clearing_price)
            time_key = str (int (tnext_clear))
            auction_metrics [time_key] = {aucObj.name:[aucObj.clearing_price, aucObj.clearing_type]}
            tnext_clear += period

        if time_granted >= tnext_adjust:
            if bWantMarket:
                for key, obj in hvacObjs.items():
                    fncs.publish (obj.name + '/price', aucObj.clearing_price)
                    if obj.bid_accepted ():
                        fncs.publish (obj.name + '/cooling_setpoint', obj.setpoint)
            tnext_adjust += period

    # ==================== Finalize the metrics output ===========================

    print ('writing metrics', flush=True)
    auction_op = open ('auction_' + metrics_root + '_metrics.json', 'w')
    controller_op = open ('controller_' + metrics_root + '_metrics.json', 'w')
    print (json.dumps(auction_metrics), file=auction_op)
    print (json.dumps(controller_metrics), file=controller_op)
    auction_op.close()
    controller_op.close()

    print ('finalizing FNCS', flush=True)
    fncs.finalize()
예제 #13
0
    def update_plots(self, i):
        """This function is called by Matplotlib for each animation frame

        Each time called, collect FNCS messages until the next time to plot
        has been reached. Then update the plot quantities and return the
        Line2D objects that have been updated for plotting. Check for new
        data outside the plotted vertical range, which triggers a full
        re-draw of the axes. On the last frame, finalize FNCS.

        Args:
          i (int): the animation frame number
        """
        print('.', end='')
        #    print ('frame', i, 'of', self.nsteps)
        bRedraw = False
        while self.time_granted < self.time_stop:  # time in minutes
            self.time_granted = fncs.time_request(self.time_stop)
            events = fncs.get_events()
            self.root.update()
            idx = int(self.time_granted / self.yaml_delta)
            if idx <= self.idxlast:
                continue
            self.idxlast = idx

            v0 = 0.0
            v1 = 0.0
            v2 = 0.0
            v3 = 0.0

            # for topic in events:
            #   value = fncs.get_value(topic)
            #   # if topic == 'vpos8':
            #   #   v1 = float (value.strip('+ degFkW')) / 199185.0
            #   if topic == 'vpos1':
            #     v1 = float(value.strip('+ degFkW')) / 199185.0
            #   elif topic == 'distribution_load8':
            #     v3 = helpers.parse_kw (value)
            #   elif topic == 'vpos8':
            #     v0 = float (value.strip('+ degFkW')) / 199185.0
            #   # elif topic == 'clear_price':
            #   #   v2 = float (value.strip('+ degFkW'))
            #   elif topic == 'LMP8':
            #     v2 = float (value.strip('+ degFkW'))
            #   # elif topic == 'SUBSTATION7':
            #   #   v1 = float (value.strip('+ degFkW')) # already in kW

            for topic in events:
                value = fncs.get_value(topic)
                if topic == self.topicDict[self.plot0.title.get()]:
                    v0 = self.CalculateValue(topic, value, self.plot0)
                elif topic == self.topicDict[self.plot1.title.get()]:
                    v1 = self.CalculateValue(topic, value, self.plot1)
                elif topic == self.topicDict[self.plot2.title.get()]:
                    v2 = self.CalculateValue(topic, value, self.plot2)
                elif topic == self.topicDict[self.plot3.title.get()]:
                    v3 = self.CalculateValue(topic, value, self.plot3)

            retval = [
                self.plot0.ln, self.plot1.ln, self.plot2.ln, self.plot3.ln
            ]

            h = float(self.time_granted / 3600.0)
            self.plot0.hrs.append(h)
            self.plot1.hrs.append(h)
            self.plot2.hrs.append(h)
            self.plot3.hrs.append(h)
            self.plot0.y.append(v0)  # Vpu
            self.plot1.y.append(v1)  # school kW
            self.plot2.y.append(v2)  # price
            self.plot3.y.append(v3)  # feeder load
            self.plot0.ln.set_data(self.plot0.hrs, self.plot0.y)
            self.plot1.ln.set_data(self.plot1.hrs, self.plot1.y)
            self.plot2.ln.set_data(self.plot2.hrs, self.plot2.y)
            self.plot3.ln.set_data(self.plot3.hrs, self.plot3.y)
            if len(self.plot0.y) == 2:
                diff = abs(self.plot0.y[0] - self.plot0.y[1])
                if diff == 0:
                    self.plot0.ymin = self.plot0.y[0] - 0.00001
                    self.plot0.ymax = self.plot0.y[0] + 0.00001
                else:
                    self.plot0.ymin = min(self.plot0.y) - 0.00001 * diff
                    self.plot0.ymax = max(self.plot0.y) + 0.00001 * diff
                if self.plot0.ymin < 0:
                    self.plot0.ymin = 0
                self.plot0.ax.set_ylim(self.plot0.ymin, self.plot0.ymax)
                self.plot0.fig.canvas.draw()
                diff = abs(self.plot1.y[0] - self.plot1.y[1])
                if diff == 0:
                    self.plot1.ymin = self.plot1.y[0] - 0.00001
                    self.plot1.ymax = self.plot1.y[0] + 0.00001
                else:
                    self.plot1.ymin = min(self.plot1.y) - 0.00001 * diff
                    self.plot1.ymax = max(self.plot1.y) + 0.00001 * diff
                if self.plot1.ymin < 0:
                    self.plot1.ymin = 0
                self.plot1.ax.set_ylim(self.plot1.ymin, self.plot1.ymax)
                self.plot1.fig.canvas.draw()
                diff = abs(self.plot2.y[0] - self.plot2.y[1])
                if diff == 0:
                    self.plot2.ymin = self.plot2.y[0] - 0.00001
                    self.plot2.ymax = self.plot2.y[0] + 0.00001
                else:
                    self.plot2.ymin = min(self.plot2.y) - 0.00001 * diff
                    self.plot2.ymax = max(self.plot2.y) + 0.00001 * diff
                if self.plot2.ymin < 0:
                    self.plot2.ymin = 0
                self.plot2.ax.set_ylim(self.plot2.ymin, self.plot2.ymax)
                self.plot2.fig.canvas.draw()
                diff = abs(self.plot3.y[0] - self.plot3.y[1])
                if diff == 0:
                    self.plot3.ymin = self.plot3.y[0] - 0.00001
                    self.plot3.ymax = self.plot3.y[0] + 0.00001
                else:
                    self.plot3.ymin = min(self.plot3.y) - 0.00001 * diff
                    self.plot3.ymax = max(self.plot3.y) + 0.00001 * diff
                if self.plot3.ymin < 0:
                    self.plot3.ymin = 0
                self.plot3.ax.set_ylim(self.plot3.ymin, self.plot3.ymax)
                self.plot3.fig.canvas.draw()
            else:
                if v0 < self.plot0.ymin or v0 > self.plot0.ymax:
                    if v0 < self.plot0.ymin:
                        self.plot0.ymin = v0
                    if v0 > self.plot0.ymax:
                        self.plot0.ymax = v0
                    self.plot0.ax.set_ylim(self.plot0.ymin, self.plot0.ymax)
                    self.plot0.fig.canvas.draw()
                if v1 < self.plot1.ymin or v1 > self.plot1.ymax:
                    if v1 < self.plot1.ymin:
                        self.plot1.ymin = v1
                    if v1 > self.plot1.ymax:
                        self.plot1.ymax = v1
                    self.plot1.ax.set_ylim(self.plot1.ymin, self.plot1.ymax)
                    self.plot1.fig.canvas.draw()
                if v2 < self.plot2.ymin or v2 > self.plot2.ymax:
                    if v2 < self.plot2.ymin:
                        self.plot2.ymin = v2
                    if v2 > self.plot2.ymax:
                        self.plot2.ymax = v2
                    self.plot2.ax.set_ylim(self.plot2.ymin, self.plot2.ymax)
                    self.plot2.fig.canvas.draw()
                if v3 < self.plot3.ymin or v3 > self.plot3.ymax:
                    if v3 < self.plot3.ymin:
                        self.plot3.ymin = v3
                    if v3 > self.plot3.ymax:
                        self.plot3.ymax = v3
                    self.plot3.ax.set_ylim(self.plot3.ymin, self.plot3.ymax)
                    self.plot3.fig.canvas.draw()

            # if bRedraw:
            #   self.plot0.fig.canvas.draw()
            #   self.plot1.fig.canvas.draw()
            #   self.plot2.fig.canvas.draw()
            #   self.plot3.fig.canvas.draw()
            if i >= (self.nsteps - 1):
                fncs.finalize()
                self.bFNCSactive = False
            return retval
예제 #14
0
    def update_plots(self, i):
        print('.', end='')
        #    print ('frame', i, 'of', self.nsteps)
        bRedraw = False
        while self.time_granted < self.time_stop:  # time in minutes
            self.time_granted = fncs.time_request(self.time_stop)
            events = fncs.get_events()
            self.root.update()
            idx = int(self.time_granted / self.yaml_delta)
            if idx <= self.idxlast:
                continue
            self.idxlast = idx

            v0 = 0.0
            v1 = 0.0
            v2 = 0.0
            v3 = 0.0

            # for topic in events:
            #   value = fncs.get_value(topic)
            #   # if topic == 'vpos8':
            #   #   v1 = float (value.strip('+ degFkW')) / 199185.0
            #   if topic == 'vpos1':
            #     v1 = float(value.strip('+ degFkW')) / 199185.0
            #   elif topic == 'distribution_load8':
            #     v3 = simple_auction.parse_kw (value)
            #   elif topic == 'vpos8':
            #     v0 = float (value.strip('+ degFkW')) / 199185.0
            #   # elif topic == 'clear_price':
            #   #   v2 = float (value.strip('+ degFkW'))
            #   elif topic == 'LMP8':
            #     v2 = float (value.strip('+ degFkW'))
            #   # elif topic == 'SUBSTATION7':
            #   #   v1 = float (value.strip('+ degFkW')) # already in kW

            for topic in events:
                value = fncs.get_value(topic)
                if topic == self.topicDict[self.plot0.title.get()]:
                    v0 = self.CalculateValue(topic, value, self.plot0)
                elif topic == self.topicDict[self.plot1.title.get()]:
                    v1 = self.CalculateValue(topic, value, self.plot1)
                elif topic == self.topicDict[self.plot2.title.get()]:
                    v2 = self.CalculateValue(topic, value, self.plot2)
                elif topic == self.topicDict[self.plot3.title.get()]:
                    v3 = self.CalculateValue(topic, value, self.plot3)

            retval = [self.plot0.ln, self.plot1.ln, self.plot2.ln, self.plot3.ln]

            h = float(self.time_granted / 3600.0)
            self.plot0.hrs.append(h)
            self.plot1.hrs.append(h)
            self.plot2.hrs.append(h)
            self.plot3.hrs.append(h)
            self.plot0.y.append(v0)  # Vpu
            self.plot1.y.append(v1)  # school kW
            self.plot2.y.append(v2)  # price
            self.plot3.y.append(v3)  # feeder load
            self.plot0.ln.set_data(self.plot0.hrs, self.plot0.y)
            self.plot1.ln.set_data(self.plot1.hrs, self.plot1.y)
            self.plot2.ln.set_data(self.plot2.hrs, self.plot2.y)
            self.plot3.ln.set_data(self.plot3.hrs, self.plot3.y)
            if len(self.plot0.y) == 2:
                diff = abs(self.plot0.y[0] - self.plot0.y[1])
                if diff == 0:
                    self.plot0.ymin = self.plot0.y[0] - 0.00001
                    self.plot0.ymax = self.plot0.y[0] + 0.00001
                else:
                    self.plot0.ymin = min(self.plot0.y) - 0.00001 * diff
                    self.plot0.ymax = max(self.plot0.y) + 0.00001 * diff
                if self.plot0.ymin < 0:
                    self.plot0.ymin = 0
                self.plot0.ax.set_ylim(self.plot0.ymin, self.plot0.ymax)
                self.plot0.fig.canvas.draw()
                diff = abs(self.plot1.y[0] - self.plot1.y[1])
                if diff == 0:
                    self.plot1.ymin = self.plot1.y[0] - 0.00001
                    self.plot1.ymax = self.plot1.y[0] + 0.00001
                else:
                    self.plot1.ymin = min(self.plot1.y) - 0.00001 * diff
                    self.plot1.ymax = max(self.plot1.y) + 0.00001 * diff
                if self.plot1.ymin < 0:
                    self.plot1.ymin = 0
                self.plot1.ax.set_ylim(self.plot1.ymin, self.plot1.ymax)
                self.plot1.fig.canvas.draw()
                diff = abs(self.plot2.y[0] - self.plot2.y[1])
                if diff == 0:
                    self.plot2.ymin = self.plot2.y[0] - 0.00001
                    self.plot2.ymax = self.plot2.y[0] + 0.00001
                else:
                    self.plot2.ymin = min(self.plot2.y) - 0.00001 * diff
                    self.plot2.ymax = max(self.plot2.y) + 0.00001 * diff
                if self.plot2.ymin < 0:
                    self.plot2.ymin = 0
                self.plot2.ax.set_ylim(self.plot2.ymin, self.plot2.ymax)
                self.plot2.fig.canvas.draw()
                diff = abs(self.plot3.y[0] - self.plot3.y[1])
                if diff == 0:
                    self.plot3.ymin = self.plot3.y[0] - 0.00001
                    self.plot3.ymax = self.plot3.y[0] + 0.00001
                else:
                    self.plot3.ymin = min(self.plot3.y) - 0.00001 * diff
                    self.plot3.ymax = max(self.plot3.y) + 0.00001 * diff
                if self.plot3.ymin < 0:
                    self.plot3.ymin = 0
                self.plot3.ax.set_ylim(self.plot3.ymin, self.plot3.ymax)
                self.plot3.fig.canvas.draw()
            else:
                if v0 < self.plot0.ymin or v0 > self.plot0.ymax:
                    if v0 < self.plot0.ymin:
                        self.plot0.ymin = v0
                    if v0 > self.plot0.ymax:
                        self.plot0.ymax = v0
                    self.plot0.ax.set_ylim(self.plot0.ymin, self.plot0.ymax)
                    self.plot0.fig.canvas.draw()
                if v1 < self.plot1.ymin or v1 > self.plot1.ymax:
                    if v1 < self.plot1.ymin:
                        self.plot1.ymin = v1
                    if v1 > self.plot1.ymax:
                        self.plot1.ymax = v1
                    self.plot1.ax.set_ylim(self.plot1.ymin, self.plot1.ymax)
                    self.plot1.fig.canvas.draw()
                if v2 < self.plot2.ymin or v2 > self.plot2.ymax:
                    if v2 < self.plot2.ymin:
                        self.plot2.ymin = v2
                    if v2 > self.plot2.ymax:
                        self.plot2.ymax = v2
                    self.plot2.ax.set_ylim(self.plot2.ymin, self.plot2.ymax)
                    self.plot2.fig.canvas.draw()
                if v3 < self.plot3.ymin or v3 > self.plot3.ymax:
                    if v3 < self.plot3.ymin:
                        self.plot3.ymin = v3
                    if v3 > self.plot3.ymax:
                        self.plot3.ymax = v3
                    self.plot3.ax.set_ylim(self.plot3.ymin, self.plot3.ymax)
                    self.plot3.fig.canvas.draw()

            # if bRedraw:
            #   self.plot0.fig.canvas.draw()
            #   self.plot1.fig.canvas.draw()
            #   self.plot2.fig.canvas.draw()
            #   self.plot3.fig.canvas.draw()
            if i >= (self.nsteps - 1):
                fncs.finalize()
                self.bFNCSactive = False
            return retval
예제 #15
0
    def launch_all(self):
        print('launching all simulators')
        self.pids = []
        for row in self.commands:
            procargs = row['args']
            procenv = os.environ.copy()
            for var in row['env']:
                procenv[var[0]] = var[1]
            logfd = None
            if 'log' in row:
                logfd = open(row['log'], 'w')
#      print ('*******************************************************')
#      print (procargs, procenv)
            proc = subprocess.Popen(procargs, env=procenv, stdout=logfd)
            self.pids.append(proc)

#    print ('*******************************************************')
        print('launched', len(self.pids), 'simulators')  # , self.pids)

        self.root.update()
        #    print ('root update')

        fncs.initialize()
        print('FNCS initialized')
        time_granted = 0
        nsteps = int(self.time_stop / self.yaml_delta)
        #    plt.xlim(0.0, self.hour_stop)

        hrs = np.linspace(0.0, self.hour_stop, nsteps + 1)
        print('time_stop, hour_stop and nsteps =', self.time_stop,
              self.hour_stop, nsteps)
        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 < self.time_stop:
            time_granted = fncs.time_request(self.time_stop)
            events = fncs.get_events()
            idx = int(time_granted / self.yaml_delta)
            if idx <= idxlast:
                continue
            idxlast = idx
            bWantX0 = True  # pu volts
            bWantX1 = True  # school load
            bWantX2 = True  # prices
            bWantX3 = True  # total feeder load
            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
                    self.ax[1].plot(hrs[1:idx], x1[1:idx], color='red')
                    bWantX1 = False
                elif bWantX3 and tok == 'distribution_load':
                    val = simple_auction.parse_kw(fncs.get_value(key).decode())
                    x3[idx] = val
                    self.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
                    self.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
                    self.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
                    self.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
                    self.ax[1].plot(hrs[1:idx], x1[1:idx], color='red')
                    bWantX1 = False


#      print (time_granted, key.decode(), fncs.get_value(key).decode())
            self.root.update()
            self.fig.canvas.draw()
        fncs.finalize()