Exemplo n.º 1
0
    def setUpClass(self):
        # This method instantiates the fleet and executes a simple request to get the device response for evaluation

        # Create test fleet
        kwargs = {}
        kwargs['start_time'] = start_time
        kwargs['service_weight'] = 0.75
        kwargs['sim_step'] = delt
        grid_type = 1
        fleet = create_fleet(fleet_name, grid_type, **kwargs)
        if fleet is None:
            raise 'Could not create fleet with name ' + fleet_name

        cycle = 5  #24
        dt_day = [(start_time + delt * i) for i in range(cycle)]
        p_needed = [(100 * i) for i in range(cycle)]

        requests = [
            FleetRequest(ts=dt_day[i],
                         sim_step=delt,
                         start_time=start_time,
                         p=p_needed[i]) for i in range(cycle)
        ]
        fleet_responses = fleet.forecast(requests)
        self.responses = fleet_responses
Exemplo n.º 2
0
def main(ts, grid):

    # Instantiation of an object of the ElectricVehiclesFleet class
    fleet_test = ElectricVehiclesFleet(grid, ts)

    dt = 3600 * 1  # time step (in seconds)
    sim_step = timedelta(seconds=dt)
    seconds_of_simulation = 24 * 3600  # (in seconds)
    local_time = fleet_test.get_time_of_the_day(ts)
    t = np.arange(local_time, local_time + seconds_of_simulation,
                  dt)  # array of time in seconds

    # Power requested (kW): test
    fleet_test.is_autonomous = False
    fleet_test.is_P_priority = True

    # List of requests
    requests = []
    for i in range(len(t)):
        req = FleetRequest(ts + i * sim_step, sim_step, ts, None, 0.)
        requests.append(req)

    FORECAST = fleet_test.forecast(requests)

    eff_charging = np.zeros([
        len(t),
    ])
    eff_discharging = np.zeros([
        len(t),
    ])
    energy = np.zeros([
        len(t),
    ])
    capacity = np.zeros([
        len(t),
    ])
    min_power_service = np.zeros([
        len(t),
    ])
    max_power_service = np.zeros([
        len(t),
    ])
    min_power_togrid = np.zeros([
        len(t),
    ])
    max_power_togrid = np.zeros([
        len(t),
    ])
    for i in range(len(t)):
        eff_charging[i] = FORECAST[i].Eff_charge
        eff_discharging[i] = FORECAST[i].Eff_discharge
        energy[i] = FORECAST[i].E
        capacity[i] = FORECAST[i].C
        min_power_service[i] = FORECAST[i].P_service_min
        max_power_service[i] = FORECAST[i].P_service_max
        min_power_togrid[i] = FORECAST[i].P_togrid_min
        max_power_togrid[i] = FORECAST[i].P_togrid_max

    return (eff_charging, eff_discharging, energy, capacity, min_power_service,
            max_power_service, max_power_togrid, min_power_togrid)
Exemplo n.º 3
0
def integration_test():

    # Establish the test variables
    n = 24
    dt = 1
    SoC0 = 50
#    t = numpy.linspace(0, (n - 1), n)
#    EffMatrix = numpy.zeros((n, n))
    ts = datetime.utcnow()
#    print(n)

    Fleet = BatteryInverterFleet()
    Fleet.soc = SoC0  # initialize SoC
    Power = numpy.zeros(n)  # initialize Power
    Power = Fleet.max_power_charge
#    Power = Fleet.max_power_discharge
    # simulate the system with SoC0 and Power requests
    for T in numpy.arange(0, n):
        req = FleetRequest(ts,dt,Power[T],0.0)
        Fleet.process_request(req)
    
    SoCFin = Fleet.soc  # get final SoC
    [P2, Cost, Able] = Fleet.cost(SoCFin, SoC0, dt)  # retreeve how much power it would take to return to SoC0
    P2Charge = max(P2,0)
    P2Discharge = min(P2,0)
Exemplo n.º 4
0
def fleet_test():
    Fleet = BatteryInverterFleet()

    t = numpy.linspace(0, 24, 97)

    requests = []
    ts = datetime.utcnow()
    dt = 1/4 #hours
    for i in t:
        req = FleetRequest(ts,dt,float(10*numpy.sin(2*numpy.pi*i/24)),0.0)
        requests.append(req)

    # print the initial SoC
    print("SoC =", str(Fleet.soc))
    FORCAST = Fleet.forecast(requests) # generate a forecast 
    print("SoC =", str(Fleet.soc))
    # make sure that the forecast function does not change the SoC

    # print the forecasted achivable power schedule
    for i in range(97):
        rsp = FORCAST[i]
        print("P =", str(rsp.P_injected))

    # process the requests 
    for req in requests:
        Fleet.process_request(req.sim_step, req.P_req, req.Q_req)
        print("SoC =", str(Fleet.soc)) # show that process_request function updates the SoC
 def request(
         self,
         ts,
         sim_step,
         p,
         q=0.0):  # added input variables; what's the purpose of sim_step??
     fleet_request = FleetRequest(ts=ts, sim_step=sim_step, p=p, q=0.0)
     fleet_response = self.fleet.process_request(fleet_request)
     #print(fleet_response.P_service)
     return fleet_request, fleet_response
Exemplo n.º 6
0
def integration_test(Fleet):
    # Establish the test variables
    n = 24
    del_t = timedelta(hours=1.0)
    #dt = del_t.total_seconds()
    SoC0 = copy.copy(numpy.mean(Fleet.soc))
    #t = numpy.linspace(0, (n - 1), n)
    EffMatrix = numpy.zeros((n, n))
    ts = datetime.utcnow()
    print(n)

    for i in numpy.arange(0, n):
        print(i)
        if i == 1:
            print(i)
        for j in numpy.arange(0, n):
            if i != j:
                #Fleet = BatteryInverterFleet('config_ERM.ini')
                #Fleet.soc = SoC0  # initialize SoC
                Power = numpy.zeros(n)  # initialize Power
                Power[i] = Fleet.max_power_charge * Fleet.num_of_devices
                Power[j] = Fleet.max_power_discharge * Fleet.num_of_devices
                # simulate the system with SoC0 and Power requests
                requests = []
                for T in numpy.arange(0, n):
                    req = FleetRequest(ts, del_t, Power[T], 0.0)
                    requests.append(req)

                responses = Fleet.forecast(requests)

                for T in numpy.arange(0, n):
                    Power[T] = responses[T].P_service

                SoCFin = responses[n - 1].soc  # get final SoC
                [P2, Cost, Able] = Fleet.cost(
                    SoCFin, SoC0, del_t
                )  # calculate how much power it would take to return to SoC0

                P2Charge = max(P2, 0)
                P2Discharge = min(P2, 0)
                if (Power[i] + P2Charge) != 0:
                    EffMatrix[i, j] = -(Power[j] + P2Discharge) / (
                        Power[i] + P2Charge
                    )  # calculate efficiency      DISCHARGE_ENERGY / CHARGE_ENERGY
                else:
                    EffMatrix[i, j] = 0
                if Able == 0:
                    EffMatrix[i, j] = 0

    print(EffMatrix)
    with open('EffMatrix.csv', 'w') as csvfile:
        writer = csv.writer(csvfile, delimiter=",")
        writer.writerows(EffMatrix)
 def create_base_request(self,
                         ts = datetime(2017, 1, 1, 00, 0, 00, 000000),
                         hrs = 24,
                         sim_step = timedelta(hours = 1)):
     """
     Method to create a list of requests with P_req = None to call the forecast method
     of the fleet and obtain the API variables that are used
     by the energy market service class
     """
     requests = []
     for i in range(hrs):
         req = FleetRequest(ts+i*sim_step, sim_step, ts, None, 0.)
         requests.append(req)        
     return requests
Exemplo n.º 8
0
    def setUpClass(self):
        #This method instantiates the fleet and executes a simple request to get the device response for evaluation

        # Create test fleet
        kwargs = {}
        kwargs['start_time'] = start_time
        kwargs['service_weight'] = 0.75
        kwargs['sim_step'] = delt
        grid_type = 1
        fleet = create_fleet(fleet_name, grid_type, **kwargs)
        if fleet is None:
            raise 'Could not create fleet with name ' + fleet_name

        fleet_request = FleetRequest(cur_time, delt, start_time, Prequest,
                                     Qrequest)
        fleet_response = fleet.process_request(fleet_request)
        self.response = fleet_response
Exemplo n.º 9
0
    def request_loop(self, start_time, sim_step):
        responses = []

        #inittime = parser.parse("2018-10-12 00:00:00")
        #delt = timedelta(seconds=2 / 60)
        delt = sim_step
        cur_time = start_time
        end_time = cur_time + timedelta(seconds=149)
        while cur_time < end_time:
            fleet_request = FleetRequest(cur_time, delt, start_time)
            fleet_response = self.fleet_device.process_request(fleet_request)
           # fleet_response = self.fleet_device.frequency_watt(fleet_request)

            responses.append(fleet_response)
            cur_time += delt
            print("{}".format(cur_time))

        return responses
Exemplo n.º 10
0
def main(ts, grid):
    
    # Instantiation of an object of the ElectricVehiclesFleet class
    fleet_test = ElectricVehiclesFleet(grid, ts)

    dt = 1                                   # time step (in seconds)
    sim_step = timedelta(seconds = dt)
    seconds_of_simulation = 149             # (in seconds)
    local_time = fleet_test.get_time_of_the_day(ts)
    t = np.arange(local_time,local_time+seconds_of_simulation,dt) # array of time in seconds 

    # Power requested (kW): test
    power_request = np.empty(len(t), dtype=object)
    fleet_test.is_autonomous = True
    fleet_test.is_P_priority = False

    # List of requests
    requests = []
    for i in range(len(t)):
        req = FleetRequest(ts+i*sim_step, sim_step, ts, power_request[i], 0.)
        requests.append(req)
    
    # power and frequency empty lists
    p = []
    f = []
    e_in = []
    i = 0
    SOC_time = np.zeros([fleet_test.N_SubFleets, len(t)])
    for req in requests:
        r = fleet_test.process_request(req)
        p.append(r.P_service)
        f.append(grid.get_frequency(req.ts_req, 0, req.start_time))
        e_in.append(r.Eff_charge)  
        print('t = %s' %str(req.ts_req))
        print('service power is = %f MW at f = %f Hz' %(p[i]/1e3, f[i]))

        SOC_time[:,i] = fleet_test.SOC
        i+=1
        
    p = np.array(p)
    f = np.array(f)  
    e_in = np.array(e_in)      
        
    return t-t[0], f, p/1000, e_in
Exemplo n.º 11
0
    def setUpClass(self):
        # This method instantiates the fleet and executes a simple request to get the device response for evaluation

        # Create test fleet
        from grid_info_artificial_inertia import GridInfo
        grid = GridInfo('Grid_Info_data_artificial_inertia.csv')
        grid_type = 2
        kwargs = {}
        kwargs['start_time'] = start_time
        kwargs['service_weight'] = 0.75
        kwargs['sim_step'] = delt
        kwargs['autonomous'] = 'autonomous'

        cur_time = start_time + timedelta(seconds=75)
        fleet = create_fleet(fleet_name, grid_type, **kwargs)
        if fleet is None:
            raise 'Could not create fleet with name ' + fleet_name

        fleet_request = FleetRequest(cur_time, delt, start_time, Prequest,
                                     Qrequest)
        fleet_response = fleet.process_request(fleet_request)
        self.response = fleet_response
        self.f = grid.get_frequency(cur_time, 0, start_time)
Exemplo n.º 12
0
def integration_test():

    # Establish the test variables
    n = 24
    dt = 1
    SoC0 = 50
#    t = numpy.linspace(0, (n - 1), n)
    EffMatrix = numpy.zeros((n, n))
    ts = datetime.utcnow()
    print(n)

    for i in numpy.arange(0, n):
        for j in numpy.arange(0, n):
            if i != j:
                Fleet = BatteryInverterFleet()
                Fleet.soc = SoC0  # initialize SoC
                Power = numpy.zeros(n)  # initialize Power
                Power[i] = Fleet.max_power_charge
                Power[j] = Fleet.max_power_discharge
                # simulate the system with SoC0 and Power requests
                for T in numpy.arange(0, n):
                    req = FleetRequest(ts,dt,Power[T],0.0)
                    Fleet.process_request(req.sim_step, req.P_req, req.Q_req)
                
                SoCFin = Fleet.soc  # get final SoC
                [P2, Cost, Able] = Fleet.cost(SoCFin, SoC0, dt)  # retreeve how much power it would take to return to SoC0
                P2Charge = max(P2,0)
                P2Discharge = min(P2,0)
                EffMatrix[i, j] = -(Power[j] +P2Discharge)/ (
                            Power[i] + P2Charge)  # calculate efficiency      DISCHARGE_ENERGY / CHARGE_ENERGY
                if P2<0:
                    print('err')
                if Able == 0:
                    EffMatrix[i, j] = 0

    print(EffMatrix)
Exemplo n.º 13
0
def fleet_test1(fleet):
    p_data = loadmat(join(base_path, 'pdata.mat'), squeeze_me=True)

    # Power request
    p_req = p_data['PF']

    # Create fleet request
    fleet.is_autonomous = False
    fleet.FW21_Enabled = False
    fleet.is_P_priority = True
    ts = datetime.utcnow()
    dt = timedelta(seconds=1)
    fleet_request = [
        FleetRequest(ts=(ts + i * dt), sim_step=dt, start_time=ts, p=v, q=0.)
        for i, v in enumerate(p_req)
    ]

    # Process the request
    P_togrid, Q_togrid, soc, P_service,  P_base, P_service_max, P_service_min, ts = [], [], [], [], [], [], [], []

    for fr in fleet_request:
        fleet_response = fleet.process_request(fr)
        P_togrid.append(fleet_response.P_togrid)
        Q_togrid.append(fleet_response.Q_togrid)
        P_service.append(fleet_response.P_service)
        soc.append(fleet_response.E)
        P_base.append(fleet_response.P_base)
        P_service_max.append(fleet_response.P_service_max)
        P_service_min.append(fleet_response.P_service_min)
        ts.append(fleet_response.ts)

    # Generate the impact metrics file
    fleet.output_metrics('impact_metrics_%s' %
                         str(datetime.utcnow().strftime('%d_%b_%Y_%H_%M_%S')))

    # Plot the results
    fig1, y1 = subplots(figsize=(20, 12))
    y1.plot(ts, p_req, label='p_req')
    y1.plot(ts, P_service, label='P_service', alpha=0.5)
    y1.plot(ts, P_base, label='P_base')
    y1.set_ylabel('P(kW)')
    y1.set_xlabel('DateTime (mm-dd H:M:S)')
    y1.legend()
    grid()
    show()
    fig1.savefig(join(
        base_path, "FC_result_ALL_P_%s.png" %
        str(datetime.utcnow().strftime('%d_%b_%Y_%H_%M_%S'))),
                 bbox_inches='tight')

    kwargs = {
        'P_request': (p_req, 'kW'),
        'P_togrid': (P_togrid, 'kW'),
        'P_service': (P_service, 'kW'),
        'P_base': (P_base, 'kW'),
        'SoC': (soc, '%'),
        'P_service_max': (P_service_max, 'kW'),
        'P_service_min': (P_service_min, 'kW')
    }
    fleet.static_plots(**kwargs)

    fig1, y1 = subplots(figsize=(20, 12))
    p1, = y1.plot(ts, p_req, label='P_request')
    p2, = y1.plot(ts, P_togrid, label='P_togrid')
    p2a, = y1.plot(ts, P_service, label='P_service')
    y1.set_ylabel('P(kW)')
    y2 = y1.twinx()
    p3, = y2.plot(ts, array(soc) * 1e2, label='SoC', color='g')
    y2.set_ylabel('SoC(%)')
    plots = [p1, p2, p2a, p3]
    y1.set_xlabel('DateTime (mm-dd H:M:S)')
    y1.legend(plots, [l.get_label() for l in plots])
    grid()
    show()
    fig1.savefig(join(
        base_path, "FC_result_All_Ps_%s.png" %
        str(datetime.utcnow().strftime('%d_%b_%Y_%H_%M_%S'))),
                 bbox_inches='tight')
Exemplo n.º 14
0
def fleet_test2(fleet):

    # Create fleet request
    fleet.is_autonomous = True
    fleet.FW21_Enabled = True
    fleet.is_P_priority = False
    ts = datetime.utcnow()
    dt = timedelta(seconds=1)
    fleet_request = [
        FleetRequest(ts=(ts + i * dt),
                     sim_step=dt,
                     start_time=ts,
                     p=None,
                     q=None) for i in range(149)
    ]

    # Process the request
    P_togrid, Q_togrid, soc, P_service,  P_base, P_service_max, P_service_min, ts, f = \
        [], [], [], [], [], [], [], [], []

    for fr in fleet_request:
        fleet_response = fleet.process_request(fr)
        f.append(grid_dat.get_frequency(fr.ts_req, 0, fr.start_time))
        P_togrid.append(fleet_response.P_togrid)
        Q_togrid.append(fleet_response.Q_togrid)
        P_service.append(fleet_response.P_service)
        soc.append(fleet_response.E)
        P_base.append(fleet_response.P_base)
        P_service_max.append(fleet_response.P_service_max)
        P_service_min.append(fleet_response.P_service_min)
        ts.append(fleet_response.ts)
        print("P_togrid Rx", P_togrid[len(P_togrid) - 1])
        print("P_service Rx", P_service[len(P_service) - 1])

    # Generate the impact metrics file
    fleet.output_metrics('impact_metrics_%s' %
                         str(datetime.utcnow().strftime('%d_%b_%Y_%H_%M_%S')))

    # Plot the results
    fig1, y1 = subplots(figsize=(20, 12))
    p1, = y1.plot(f, label='Frequency', color='g')
    y1.set_ylabel('Hz')
    y2 = y1.twinx()
    p2, = y2.plot(array(P_togrid) / 240, label='P_togrid')
    y2.set_ylabel('Power Consumption (p.u.)')
    plots = [p1, p2]
    y1.set_xlabel('Time (s)')
    y1.legend(plots, [l.get_label() for l in plots])
    grid()
    show()
    fig1.savefig(join(
        base_path, "FC_result_P_grid_%s.png" %
        str(datetime.utcnow().strftime('%d_%b_%Y_%H_%M_%S'))),
                 bbox_inches='tight')

    fig2, y2 = subplots(figsize=(20, 12))
    y2.scatter(f, array(P_togrid) / 240, label='P_togrid')
    y2.set_ylabel('Power Consumption(p.u.)')
    y2.set_xlabel('Hz')
    grid()
    show()
    fig2.savefig(join(
        base_path, "FC_result_P_service_%s.png" %
        str(datetime.utcnow().strftime('%d_%b_%Y_%H_%M_%S'))),
                 bbox_inches='tight')
    def request_loop(self, start_time, service_name, fleet_name="PVInverterFleet"):
        cycle = 24
        ndx_start = 0
        ndx_end = ndx_start + cycle
        #device_ts = 
                # normalizes drive cycle and scales to fleet service capacity
        self.drive_cycle.load_forecast_mw *= self.fleet.assigned_service_kW()/max(self.drive_cycle.load_forecast_mw)
        
        # Find the "annual" peak (largest peak in our drive cycle really) and the desired new peak...
        #self.annual_peak = max(self.drive_cycle.load_forecast_mw)
        self.annual_peak = max(self.drive_cycle.load_forecast_mw)
        self.mw_target = self.annual_peak * (1 - self.f_reduction)
        requests = []
        responses = []
#        while ndx_end < len(self.drive_cycle.dt):   # Loop over days...
        while ndx_end <= len(self.drive_cycle.dt):   # Loop over days...
            dt_day = self.drive_cycle.dt[ndx_start:ndx_end]
            dt_day.reset_index(drop=True, inplace=True)
            mw_day = self.drive_cycle.load_forecast_mw[ndx_start:ndx_end]
            mw_day.reset_index(drop=True, inplace=True)
            p_needed = [max(0, mw_day[i] - self.mw_target) for i in range(cycle)]
            
            for index, item in enumerate(p_needed):
                if item == 0:
                    p_needed[index] = None
            
            ndx_start += 24
            ndx_end += 24

            # No need to work on days without high peaks
            #if max(mw_day) <= self.mw_target:
            for i in range(24):
                for j in range(int(3600/self.sim_step.seconds)):
                    fleet_request = FleetRequest(ts=dt_day[i]+j*self.sim_step, sim_step=self.sim_step, start_time=start_time, p=p_needed[i])
                    fleet_response = self.fleet.process_request(fleet_request)
            # store requests and responses
                    requests.append(fleet_request)
                    responses.append(fleet_response)
                    print(responses[-1].P_service)
            '''
            else:
                # Get a 24-hour forecast from fleet
                forecast_requests = [FleetRequest(ts=dt_day[i], sim_step=self.sim_step, p=p_needed[i]) for i in range(cycle)]
                forecast_response = self.fleet.forecast(forecast_requests)
                
                # See if the forecast can meet the desired load
                deficit = [forecast_response[i].P_service - p_needed[i] for i in range(24)]
                insufficient = [deficit[i] < 0 for i in range(cycle)]
                if any(insufficient):
                    # TODO:  NEED TO LOOP BACK AND REBUILD requests until we have a 24-hour request we know can be met
                    pass
                
                # Now we know what the fleet can do, so ask it to do it
                for i in range(24):
                    fleet_request = FleetRequest(ts=dt_day[i], sim_step=self.sim_step, start_time=start_time, p=forecast_response[i].P_service)
                    fleet_response = self.fleet.process_request(fleet_request)
                    # TODO:  store performance stats

                    requests.append(fleet_request)
                    responses.append(fleet_response)
                    print(responses[-1].P_service)
            '''        
        request_list_1h = []
        for r in requests:
            if r.P_req is not None:
                request_list_1h.append((r.ts_req, r.P_req / 1000))
            else:
                request_list_1h.append((r.ts_req, r.P_req))
        request_df_1h = pd.DataFrame(request_list_1h, columns=['Date_Time', 'Request'])
        
        if 'battery' in fleet_name.lower():
            # Include battery SoC in response list for plotting purposes
            response_list_1h = [(r.ts, r.P_service / 1000, r.P_togrid, r.P_base, r.soc) for r in responses]
            response_df_1h = pd.DataFrame(response_list_1h, columns=['Date_Time', 'Response', 'P_togrid', 'P_base', 'SoC'])
        else:
            
            response_list_1h = [(r.ts, np.nan if r.P_service is None else r.P_service / 1000, r.P_togrid, r.P_base) for r in responses]
            response_df_1h = pd.DataFrame(response_list_1h, columns=['Date_Time', 'Response', 'P_togrid','P_base'])

        # This merges/aligns the requests and responses dataframes based on their time stamp 
        # into a single dataframe
        df_1h = pd.merge(
            left=request_df_1h,
            right=response_df_1h,
            how='left',
            left_on='Date_Time',
            right_on='Date_Time')

        df_1h['P_togrid'] = df_1h['P_togrid'] / 1000
        df_1h['P_base'] = df_1h['P_base'] / 1000

        # Plot entire analysis period results and save plot to file
        # We want the plot to cover the entire df_1h dataframe
        plot_dir = join(dirname(dirname(dirname(abspath(__file__)))), 'integration_test', service_name)
        ensure_ddir(plot_dir)
        plot_filename = 'SimResults_PeakManagement_' + fleet_name + '_' + datetime.now().strftime('%Y%m%dT%H%M')  + '.png'
        plt.figure(1)
        plt.figure(figsize=(15, 8))
        plt.subplot(311)
        if not(all(pd.isnull(df_1h['Request']))):
            plt.plot(df_1h.Date_Time, df_1h.Request, label='P_Request', linestyle = '-')
        if not(all(pd.isnull(df_1h['Response']))):
            plt.plot(df_1h.Date_Time, df_1h.Response, label='P_Response', linestyle = '--')
        plt.ylabel('Power (MW)')
        plt.legend()
        
        plt.subplot(312)
        if not(all(pd.isnull(df_1h['P_base']))):
            plt.plot(df_1h.Date_Time, df_1h.P_base + df_1h.Request, label='P_base + P_Request', linestyle = '-')       
        if not(all(pd.isnull(df_1h['P_togrid']))):
            plt.plot(df_1h.Date_Time, df_1h.P_togrid, label='P_togrid', linestyle = '--')
        if not(all(pd.isnull(df_1h['P_base']))):
            plt.plot(df_1h.Date_Time, df_1h.P_base, label='P_base', linestyle = '-.')
        plt.ylabel('Power (MW)')
        plt.legend()
        
        if 'battery' is not fleet_name.lower():
            plt.xlabel('Time')
        
        if 'battery' in fleet_name.lower():
            if not(all(pd.isnull(df_1h['SoC']))):
                plt.subplot(313)
                plt.plot(df_1h.Date_Time, df_1h.SoC, label='SoC', linestyle = '-')
                plt.ylabel('SoC (%)')
                plt.xlabel('Time')
        plt.savefig(join(plot_dir, plot_filename), bbox_inches='tight')
        plt.close()
        
        # compute and report metrics to csv
        perf_metrics = pd.DataFrame(columns=['Service_efficacy'])
        temp_df_1h = df_1h.dropna()
        perf_metrics['Service_efficacy'] = pd.Series(min(1,abs(temp_df_1h.Response).sum()/abs(temp_df_1h.Request).sum()))
        metrics_filename = 'Performance_PeakManagement_' + fleet_name + '_' + datetime.now().strftime('%Y%m%dT%H%M')  + '.csv'
        perf_metrics.to_csv(join(plot_dir, metrics_filename) )
        
        # report results to csv
        results_filename = 'Results_PeakManagement_' + fleet_name + '_' + datetime.now().strftime('%Y%m%dT%H%M')  + '.csv'
        df_1h.to_csv(join(plot_dir, results_filename) )
Exemplo n.º 16
0
def fleet_test(Fleet,Grid):
    mat = spio.loadmat('ERM_model_validation.mat', squeeze_me=True)
    t = mat['TT']
    P = Fleet.num_of_devices* mat['PP']*Fleet.p_rated
 
   

    n = 300#len(t)
    Pach = numpy.zeros((n))
    Qach = numpy.zeros((n))
    f = numpy.zeros((n,2))
    v = numpy.zeros((n,2))
    
    requests = []
    ts = datetime.utcnow()
    dt = timedelta(hours=0.000277777778) #hours
    for i in range(n):
        req = FleetRequest(ts=(ts+i*dt),sim_step=dt,p=P[i],q=None)
        requests.append(req)
        
    idd = 0
    
       
    
    Fleet.is_autonomous=False
    Fleet.VV11_Enabled=False
    Fleet.FW21_Enabled=False
    Fleet.is_P_priority=False
        
    for idd, req in enumerate(requests):
        res=Fleet.process_request(req)
        Pach[idd] = res.P_togrid
        Qach[idd] = res.Q_togrid
        ts=res.ts
        f[idd,0] = Grid.get_frequency(ts,0)
        f[idd,1] = Grid.get_frequency(ts,1)
        v[idd,0] = Grid.get_voltage(ts,0)
        v[idd,1] = Grid.get_voltage(ts,1)
        print('iteration # ',idd,' of total number of iteration ',n,' (',100*idd/n,'% complete)')
        
#        if numpy.mod(idd,10000) == 0:
            #print('iteration # ',idd,' of total number of iteration ',n,' (',100*idd/n,'% complete)')
            
#        idd+=1
#    res=Fleet.forecast(req)
#    for req in requests:
#        res=Fleet.forecast(req)
#        print(res.P_togrid_max)
#        Pach[i] = res.P_togrid_max
#        Qach[i] = res.Q_togrid_max
#        f[i,0] = Grid.get_frequency(ts+i*dt,0)
#        f[i,1] = Grid.get_frequency(ts+i*dt,1)
#        v[i,0] = Grid.get_voltage(ts+i*dt,0)
#        v[i,1] = Grid.get_voltage(ts+i*dt,1)
#        
#        if numpy.mod(i,10000) == 0:
#            print(str(100*i/n) + ' %')

    Pach[i] = res.P_togrid
    Qach[i] = res.Q_togrid
    f[i,0] = Grid.get_frequency(ts+i*dt,0)
    f[i,1] = Grid.get_frequency(ts+i*dt,1)
    v[i,0] = Grid.get_voltage(ts+i*dt,0)
    v[i,1] = Grid.get_voltage(ts+i*dt,1)
    
    plt.figure(1)
    plt.subplot(211)
    plt.plot(t[0:n], P[0:n], label='Power Requested')
    plt.plot(t[0:n], Pach, label='Power Achieved by Fleet')
    plt.xlabel('Time (hours)')
    plt.ylabel('Real Power (kW)')
    plt.legend(loc='lower right')
    plt.subplot(212)
    plt.plot(t[0:n],60.036*numpy.ones(n))
    plt.plot(t[0:n],59.964*numpy.ones(n))
    plt.plot(t[0:n],f[0:n,0], label='Grid Frequency')
    #plt.plot(t[0:n],100*S[0:n], label='Recorded SoC')
    plt.xlabel('Time (hours)')
    plt.ylabel('frequency (Hz)')
    #plt.legend(loc='lower right')

    plt.figure(2)
    plt.subplot(211)
    plt.plot(t[0:n], Qach, label='Reactive Power Achieved by Fleet')
    plt.ylabel('Reactive Power (kvar)')
    plt.legend(loc='lower right')
    plt.subplot(212)
    plt.plot(t[0:n],240*(1-.03)*numpy.ones(n))
    plt.plot(t[0:n],240*(1-.001)*numpy.ones(n))
    plt.plot(t[0:n],240*(1+.001)*numpy.ones(n))
    plt.plot(t[0:n],240*(1+.03)*numpy.ones(n))
    plt.plot(t[0:n], v[0:n,0], label='Voltage at location 1')
    plt.plot(t[0:n], v[0:n,1], label='Voltage at location 2')
    plt.xlabel('Time (hours)')
    plt.ylabel('Voltage (V)')
    plt.legend(loc='lower right')
    plt.show()
Exemplo n.º 17
0
    def request_loop(self,
                     sensitivity_P=0.0001,
                     sensitivity_Q=0.0005,
                     start_time=parser.parse("2017-08-01 16:00:00"),
                     end_time=parser.parse("2017-08-01 17:00:00")):
        # Sensitivity_P, Sensitivity_Q are values depending on feeder characteristics
        # We can use dummy value to conduct test
        #sensitivity_P = 0.001
        #sensitivity_Q = 0.005
        assigned_service_kW = self._fleet.assigned_service_kW()
        assigned_service_kVar = self._fleet.assigned_service_kW()

        cur_time = start_time
        #end_time = endtime

        delt = self.sim_step
        volt = self.drive_cycle["voltage"]
        time = self.drive_cycle["time"]
        List_Time = list(time.values)
        dts = maya.parse(start_time).datetime() - maya.parse(
            List_Time[0]).datetime()
        dts = (dts).total_seconds()
        Vupper = self.Vupper
        Vlower = self.Vlower
        responses = []
        requests = []
        while cur_time < end_time:
            # normal operation

            for n in range(len(list(time.values))):

                dta = maya.parse(List_Time[n]).datetime()
                dtb = maya.parse(cur_time).datetime() - timedelta(seconds=dts)
                if dta == dtb:
                    index = n

        # index  = list(time.values).index(cur_time)
            cur_voltage = volt.values[index]
            #cur_voltage = 1.055
            if cur_voltage >= self.Vlower and cur_voltage <= self.Vupper:
                Prequest = 0
                Qrequest = 0
            else:
                if cur_voltage > Vupper:
                    dV = Vupper - cur_voltage
                    Qrequest = -dV / sensitivity_Q  # need Q absorption
                    if Qrequest < -1 * assigned_service_kVar:
                        Qrequest = -1 * assigned_service_kVar
                    Prequest = -dV / sensitivity_P  # need P curtailment
                    if Prequest < -1 * assigned_service_kW:
                        Prequest = -1 * assigned_service_kW
                elif cur_voltage < Vlower:
                    dV = Vlower - cur_voltage
                    Qrequest = dV / sensitivity_Q  # need Q injection
                    if Qrequest < assigned_service_kVar:
                        Qrequest = -1 * assigned_service_kVar
                    Prequest = dV / sensitivity_P  # need P injection
                    if Prequest < assigned_service_kW:
                        Prequest = -assigned_service_kW

            fleet_request = FleetRequest(ts=cur_time,
                                         sim_step=delt,
                                         p=Prequest,
                                         q=Qrequest)
            fleet_response = self.fleet.process_request(fleet_request)
            responses.append(fleet_response)
            requests.append(fleet_request)
            cur_time += delt
            print("{}".format(cur_time))

        Qach = numpy.zeros((len(responses)))
        Pach = numpy.zeros((len(responses)))
        #            Time[idd]=res.ts

        ts_request = [r.ts for r in responses]
        Pach = [r.P_togrid for r in responses]
        Qach = [r.Q_togrid for r in responses]
        Pservice = [r.P_service for r in responses]
        Qservice = [r.Q_service for r in responses]

        Preq = [r.P_req for r in requests]
        Qreq = [r.Q_req for r in requests]

        fig = plt.figure(1)
        plt.subplot(211)
        plt.plot(ts_request, Preq, label='Req.')
        plt.plot(ts_request, Pach, label='Achieved')
        plt.plot(ts_request, Pservice, label='Service')
        plt.xlabel('Time')
        plt.ylabel('kW')
        plt.title('Fleet Active Power')
        plt.legend(loc='lower right')

        plt.subplot(212)
        plt.plot(ts_request, Qreq, label='Req.')
        plt.plot(ts_request, Qach, label='Achieved')
        plt.plot(ts_request, Qservice, label='Service')
        #plt.plot(t[0:n],100*S[0:n], label='Recorded SoC')
        plt.xlabel('Time')
        plt.ylabel('kVar')
        plt.title('Fleet Reactive Power')
        plt.legend(loc='lower right')

        data_folder = os.path.dirname(sys.modules['__main__'].__file__)
        plot_filename = datetime.now().strftime(
            '%Y%m%d'
        ) + '_VoltageRegulation_FleetResponse_' + self.fleet.__class__.__name__ + '.png'
        File_Path_fig = join(data_folder, 'integration_test',
                             'voltage_regulation', plot_filename)

        plt.savefig(File_Path_fig, bbox_inches='tight')
        #        File_Path_fig = os.path.join(self.base_path , 'VR_Fleet_Response.png')
        #        fig.savefig(File_Path_fig)
        #plt.legend(loc='lower right')
        plt.close
        ServiceEefficacy = []
        ValueProvided = []
        ValueEfficacy = []

        CSV_FileName = datetime.now().strftime(
            '%Y%m%d'
        ) + '_Voltage_Regulation_' + self.fleet.__class__.__name__ + '.csv'

        data_folder = os.path.dirname(sys.modules['__main__'].__file__)
        File_Path_CSV = join(data_folder, 'integration_test',
                             'Voltage_Regulation', CSV_FileName)
        self.write_csv(File_Path_CSV, 'Time', 'service efficacy (%)',
                       'value provided ($)', 'value efficacy (%)')

        for idd in range(len(Pach)):
            service_efficacy, value_provided, value_efficacy = self.calculation(
                Prequest=Preq[idd],
                Qrequest=Qreq[idd],
                P0=Pach[idd],
                Q0=Qach[idd],
                price_P=1,
                price_Q=1)

            ServiceEefficacy.append(service_efficacy)
            ValueProvided.append(value_provided)
            ValueEfficacy.append(value_efficacy)

            self.write_csv(File_Path_CSV, ts_request[idd], service_efficacy,
                           value_provided, value_efficacy)

        fig, axs = plt.subplots(3, 1)
        axs[0].plot(ts_request, ServiceEefficacy)
        axs[0].set_title('ServiceEefficacy')
        #axs[0].set_xlabel('distance (m)')
        axs[0].set_ylabel('%')
        fig.suptitle('Service Metrics', fontsize=16)

        axs[1].plot(ts_request, ValueProvided)
        #axs[1].set_xlabel('time (s)')
        axs[1].set_title('ValueProvided')
        axs[1].set_ylabel('$')

        axs[2].plot(ts_request, ValueEfficacy)
        #axs[1].set_xlabel('time (s)')
        axs[2].set_title('ValueEfficacy')
        axs[2].set_ylabel('%')
        plot_filename = datetime.now().strftime(
            '%Y%m%d') + '_VoltageRegulation_ServiceMetrics' + '.png'

        File_Path_fig = join(data_folder, 'integration_test',
                             'voltage_regulation', plot_filename)
        plt.savefig(File_Path_fig, bbox_inches='tight')

        plt.show()

        return [requests, responses]
Exemplo n.º 18
0
def fleet_test(Fleet):

    mat = spio.loadmat('ERM_model_validation.mat', squeeze_me=True)
    t = mat['TT']
    P = -Fleet.num_of_devices * mat['PP']
    S = mat['SS']

    n = len(S)  #len(t)

    t = t[numpy.arange(1000, n - 1000, 45)]
    P = P[numpy.arange(1000, n - 1000, 45)] * 0
    S = S[numpy.arange(1000, n - 1000, 45)]

    n = len(t)
    print(n)
    Pach = numpy.zeros((n))
    Qach = numpy.zeros((n))
    f = numpy.zeros((n, 2))
    v = numpy.zeros((n, 2))
    SOC = numpy.zeros((n, Fleet.num_of_devices))
    #V = numpy.zeros(n)

    requests = []
    ts = datetime.utcnow()
    dt = timedelta(hours=(0.000277777778 * 45 / 3))  #hours
    for i in range(n):
        req = FleetRequest(ts=(ts + i * dt), sim_step=dt, p=P[i], q=None)
        requests.append(req)
    """ # print the initial SoC
    print("SoC =", str(Fleet.soc))
    FORCAST = Fleet.forecast(requests) # generate a forecast 
    print("SoC =", str(Fleet.soc))
    # make sure that the forecast function does not change the SoC
    """
    # print the forecasted achivable power schedule
    """ for i in range(n):
        rsp = FORCAST[i]
        P[i] = rsp.P_service """

    # process the requests
    i = 0
    for req in requests[:n]:
        Fleet.process_request(req)
        Pach[i] = sum(Fleet.P_service)
        Qach[i] = sum(Fleet.Q_service)
        f[i, 0] = Grid.get_frequency(ts + i * dt, 0)
        f[i, 1] = Grid.get_frequency(ts + i * dt, 1)
        v[i, 0] = Grid.get_voltage(ts + i * dt, 0)
        v[i, 1] = Grid.get_voltage(ts + i * dt, 1)
        """ if v[i] < 100:
            print(str(100*i/n) + ' %') """
        if numpy.mod(i, numpy.floor(n / 20)) == 0:
            print(str(100 * i / n) + ' %')
        for j in range(Fleet.num_of_devices):
            SOC[i, j] = Fleet.soc[
                j]  # show that process_request function updates the SoC
        #V[i] = Fleet.vbat
        i = i + 1

    plt.figure(1)
    plt.subplot(211)
    plt.plot(t[0:n], P[0:n], label='Power Requested')
    plt.plot(t[0:n], Pach, label='Power Achieved by Fleet')
    plt.xlabel('Time (hours)')
    plt.ylabel('Real Power (kW)')
    plt.legend(loc='lower right')
    plt.subplot(212)
    plt.plot(t[0:n], f[0:n, 0], label='Grid Frequency')
    #plt.plot(t[0:n],100*S[0:n], label='Recorded SoC')
    plt.xlabel('Time (hours)')
    plt.ylabel('frequency (Hz)')
    #plt.legend(loc='lower right')

    plt.figure(2)
    plt.subplot(211)
    plt.plot(t[0:n], Qach, label='Reactive Power Achieved by Fleet')
    plt.ylabel('Reactive Power (kvar)')
    plt.legend(loc='lower right')
    plt.subplot(212)
    plt.plot(t[0:n], v[0:n, 0], label='Voltage at location 1')
    plt.plot(t[0:n], v[0:n, 1], label='Voltage at location 2')
    plt.xlabel('Time (hours)')
    plt.ylabel('Voltage (V)')
    plt.legend(loc='lower right')
    plt.show()
Exemplo n.º 19
0
from fleet_config import FleetConfig


if __name__ == '__main__':
    haf = HomeAcFleet()

    # Init simulation time frame
    start_time = datetime.utcnow()
    end_time = datetime.utcnow() + timedelta(hours=3)

    # Create requests for each hour in simulation time frame
    cur_time = start_time
    sim_time_step = timedelta(hours=1)
    fleet_requests = []
    while cur_time < end_time:
        req = FleetRequest(ts=cur_time, sim_step=sim_time_step, p=1000, q=1000)
        fleet_requests.append(req)
        cur_time += sim_time_step

    # Use case 1
    res = haf.process_request(fleet_requests[0])
    print(res)

    # Use case 2
    forecast = haf.forecast(fleet_requests)
    print(forecast)

    # Use case 3
    fleet_config = FleetConfig(is_P_priority=True, is_autonomous=False, autonomous_threshold=0.1)
    haf.change_config(fleet_config)
Exemplo n.º 20
0
fleet_test.is_P_priority = True

dt = 5*60                                    # time step (in seconds)
sim_step = timedelta(seconds = dt)
seconds_of_simulation = 24*3600              # (in seconds)
local_time = fleet_test.get_time_of_the_day(ts)
t = np.arange(local_time,local_time+seconds_of_simulation,dt) # array of time in seconds 

# Power requested (kW): test
power_request = 50000*(1 + np.sin(2*np.pi*(t/seconds_of_simulation)))
# power_request = np.zeros([len(t), ])

# List of requests
requests = []
for i in range(len(t)):
    req = FleetRequest(ts+i*sim_step, sim_step, ts, power_request[i], 0.)
    requests.append(req)
   
print("SOC init = ", fleet_test.SOC)
# Measure cpu time
cpu_time = time.clock() 
FORECAST = fleet_test.forecast(requests)
cpu_time = (time.clock() - cpu_time)/len(t)
# check that the state of charge do not change when calling the forecast method
print("SOC check = ", fleet_test.SOC)
print("CPU time per time step = %f [sec]" %cpu_time)

power_service = []
max_power_service = []
power_response = []
energy_stored = np.zeros([len(t),])
 def request(self, ts, sim_step, start_time, p, q=0.0):
     fleet_request = FleetRequest(ts=ts, sim_step=sim_step,
                                  start_time=start_time, p=p, q=0.0)
     fleet_response = self.fleet.process_request(fleet_request)
     return fleet_request, fleet_response
Exemplo n.º 22
0
def main():
    
    #Test case: Run a forecast for the day of July 26th
    #Configure the simulation to be run. Need to set the number of timesteps, start time, and the length of the timestep (in minutes)
    Steps = 24 #num steps in simulation, if greater than 1 assuming a forecast is being requested
    Timestep = 1 / 60. #minutes, NOTE, MUST BE A DIVISOR OF 60. Acceptable numbers are: 0.1, 0.2, 0.5, 1,2,3,4,5,6,10,12,15,20,30, 60, etc.
    allowable_timesteps = [1 / 60.,0.1, 0.2, 0.5, 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60]
    if Timestep not in allowable_timesteps:
        print("Timestep must be a divisor of 60")
        return
    starttime = 206*24 # 0-8759, hour of the year to start simulation
    if Steps > 1:
        forecast = 1
    else:
        forecast = 0
    Q_request = 0 # reactive power request, water heater can't provide reactive power
    Timestep = datetime.timedelta(minutes=Timestep)
    startday = (starttime // 24) + 1
    monthindex = [[1,31],[2,59],[3,90],[4,120],[5,151],[6,181],[7,212],[8,243],[9,273],[10,304],[11,334],[12,365]] #doesn't account for leap years
    for m in monthindex:
        if startday <= m[1]:
            startmonth = m[0]
            break
    
    if startmonth > 1:
        startday -= monthindex[(m[0]-2)][1]

    starthour = starttime % 24
    
    StartTime = datetime.datetime(2018,startmonth,startday,starthour)         
    grid = GridInfo('Grid_Info_Data_2.csv')
    ########################################################################
    #generate load request signal and regulation
#    NOTE: code is set up to deal with capacity separately from regulation, the only interface is in the capacity signal there is a single timestep
#    where regulation is called, the entire code switches into regulation mode for that single timestep (which is much longer than a regulation timestep)
#    when the calculations are complete, it returns conditions to be used for subsequent capacity timesteps
    P_request = []
    FleetResponse = [0]
    
    for step in range(Steps):
        capacity_needed = 1e6
#        capacity_needed = 1e6 + 2e5*random.random()#Watts needed, >0 is capacity add, <0 is capacity shed
#        Fleet_size_represented = capacity_needed/4500 # approximately how many WH would be needed to be able to provide this capacity
#        magnitude_load_add_shed = capacity_needed/Fleet_size_represented #def magnitude of request for load add/shed
        if step % 12 == 0 or step % 12 == 1 or step % 12 == 2: # this is my aribtrary but not random way of creating load add/shed events. should be replaced with a more realistic signal at some point
            if step > 1:
                s = -capacity_needed 
            else:
#                service = ['none',0]
                s = 0
        elif step % 7 == 0 or step % 7 == 1:
            s = capacity_needed 
        else:
            s = 0

        P_request.append(s)

############################################################################
#        Call fleet
    
    #creating service request object
    ServiceRequest = FleetRequest(StartTime, Timestep, P_request, Q_request)

    # initializing fleet
    fleet = WaterHeaterFleet(grid,StartTime,Timestep)
    
    #calling fleet
    FleetResponse = fleet.process_request(ServiceRequest)
    
    #Gather data to plot and look at the results
    #for y in range FleetResponse[0].AvailableCapacityAdd:
        
    #for x in range(len(FleetResponse)):
    #    for y in range FleetResponse[0].AvailableCapacityAdd:
############################################################################
    #Plotting load add/shed responses

    for n in range(len(FleetResponse.IsAvailableAdd)):
        plt.figure(n+1)
        plt.clf()
        plt.plot(FleetResponse.IsAvailableAdd[n],'r*-',label = 'AvailAdd')
        plt.plot(FleetResponse.IsAvailableShed[n],'bs-',label = 'AvailShed')
        plt.ylabel('Availability')
        plt.xlabel('step')
        plt.title('Water Heater {} Availability'.format(n+1))
        plt.legend()
        plt.ylim([-1,2])
    plt.show()
    
    for n in range(len(FleetResponse.IsAvailableAdd)):
        plt.figure(n+1)
        plt.clf()
        plt.plot(FleetResponse.Tset[n],'r*-',label = 'Tset')
        plt.plot(FleetResponse.Ttank[n],'bs-',label = 'Ttank')
        plt.ylabel('Temperature (F)')
        plt.xlabel('step')
        plt.title('Water Heater {} Setpoint and tank temperature'.format(n+1))
        plt.legend()
        plt.ylim([100,160])
    plt.show()
    
    for n in range(len(FleetResponse.IsAvailableAdd)):
        plt.figure(n+1)
        plt.clf()
        plt.plot(FleetResponse.IsAvailableAdd[n],'r*-',label = 'AvailAdd')
        plt.plot(FleetResponse.IsAvailableShed[n],'bs-',label = 'AvailShed')
        plt.ylabel('Availability')
        plt.xlabel('step')
        plt.title('Water Heater {} Availability'.format(n+1))
        plt.legend()
        plt.ylim([-1,2])
    plt.show()
Exemplo n.º 23
0
def fleet_test(Fleet,fig,writer):
    
    mat = spio.loadmat('ERM_model_validation.mat', squeeze_me=True)
    t = mat['TT']
    P = -Fleet.num_of_devices* mat['PP']
    S = mat['SS']
    
    n = len(S)#len(t)

    t = t[numpy.arange(1000,n-1000,45)]
    P = P[numpy.arange(1000,n-1000,45)]
    S = S[numpy.arange(1000,n-1000,45)]


    n = len(t)
    print(n)
    Pach = numpy.zeros((n))
    Qach = numpy.zeros((n))
    f = numpy.zeros((n,2))
    v = numpy.zeros((n,2))
    SOC = numpy.zeros((n,Fleet.num_of_devices))
    #V = numpy.zeros(n)

    requests = []
    ts = datetime.utcnow()
    dt = timedelta(hours=(0.000277777778*45/3)) #hours
    for i in range(n):
        req = FleetRequest(ts=(ts+i*dt),sim_step=dt,p=P[i],q=None)
        requests.append(req)

    """ # print the initial SoC
    print("SoC =", str(Fleet.soc))
    FORCAST = Fleet.forecast(requests) # generate a forecast 
    print("SoC =", str(Fleet.soc))
    # make sure that the forecast function does not change the SoC
    """
    # print the forecasted achivable power schedule
    """ for i in range(n):
        rsp = FORCAST[i]
        P[i] = rsp.P_service """

    # process the requests 
    i = 0
    for req in requests[:n-10]:
        writer.grab_frame()
        Fleet.process_request(req)
        Pach[i] = sum(Fleet.P_service)
        Qach[i] = sum(Fleet.Q_service)
        """ f[i,0] = Grid.get_frequency(ts+i*dt,0)
        f[i,1] = Grid.get_frequency(ts+i*dt,1)
        v[i,0] = Grid.get_voltage(ts+i*dt,0)
        v[i,1] = Grid.get_voltage(ts+i*dt,1) """

        """ if v[i] < 100:
            print(str(100*i/n) + ' %') """
        if numpy.mod(i,numpy.floor(n/20)) == 0:
            print(str(100*i/n) + ' %')
        for j in range(Fleet.num_of_devices):
            SOC[i,j] = Fleet.soc[j] # show that process_request function updates the SoC
        #V[i] = Fleet.vbat
        i = i + 1
        fig.set_figheight(5)
        yield t, Pach, P, f, v, SOC, S*100, i

    """ plt.figure(1)