Source code for evnrg.simulation.simulation

from typing import NamedTuple
import uuid

import pandas as pd
import numpy as np

# Scenario information
from evnrg.common.scenario import Scenario
from .eligibility import EligibilityRules
from .fleet import Fleet
# Storage
from evnrg.storage import (
    StorageInfo,
    DataResource,
    DataHandler
)
# Objects
from evnrg.common.evse import EVSE, EVSEType
from evnrg.common.bank import Bank, QueueMode
from evnrg.common.status import Status

# The loop
from .loop import simulation_loop

__all__ = [
    'SimulationResult',
    'run_simulation'
]

[docs]class SimulationResult(NamedTuple): deferred: pd.DataFrame fuel_use: pd.DataFrame occupancy: pd.DataFrame demand: pd.DataFrame battery: pd.DataFrame uid: str = uuid.uuid4().hex errors: list = []
[docs]def run_simulation(sc: Scenario, storage_info: StorageInfo): """Runs a simulation with a given scenario by downloading data, running the simulation, and uploading results. Args: sc (Scenario): The scenario structure to use. Returns: A `SimulationResult` with all the relevant energy data. """ # First pull down the data storage = DataHandler(storage_info) df = storage.read_data(sc.obj_path) rows = len(df.index) interval_len = df.reset_index()['index'][:2].diff()[1].seconds / 60.0 # Basic rules creation for now mask_df = pd.DataFrame( np.zeros(df.values.shape, dtype=np.uint8), index=df.index ) for mask_rule in sc.home_mask_rules: if mask_rule.get('type') == 'time': begin = mask_rule.get('begin', '23:55') end = mask_rule.get('end', '00:00') mask_df.loc[df.between_time(begin, end).index] = int(Status.HOME_ELIGIBLE) rules = EligibilityRules( away_threshold=round(sc.away_threshold_min/interval_len), home_threshold=round(sc.home_threshold_min/interval_len), mask=mask_df.values.astype(np.uint8) ) # Create the fleet fleet = Fleet(df, sc.powertrains, sc.distribution, rules) # Get the banks up away_banks = [] for bank_info in sc.away_banks: evse_list = [] for evse_type in bank_info.get('evse'): evse_list.append(EVSE(evse_type)) demand_a = np.zeros(rows, dtype=np.float32) occupancy_a = np.zeros(rows, dtype=np.uint8) bank = Bank( max_power=bank_info.get('max_power', 0.), capacity=bank_info.get('capacity', 0.), evse=evse_list, queue_probability=bank_info.get('probability', .2), queue_mode=bank_info.get('queue', QueueMode.DEFAULT), demand_profile=demand_a, occupancy_profile=occupancy_a, dynamic_size=True ) away_banks.append(bank) num_banks = 0 home_banks = [] for bank_info in sc.home_banks: evse_list = [] for evse_type in bank_info.get('evse'): evse_list.append(EVSE(evse_type)) bank = Bank( max_power=bank_info.get('max_power', 0.), capacity=bank_info.get('capacity', 0.), evse=evse_list, queue_probability=bank_info.get('probability', 1.), queue_mode=bank_info.get('queue', QueueMode.DEFAULT), demand_profile=np.zeros(rows, dtype=np.float32), occupancy_profile=np.zeros(rows, dtype=np.uint8), dynamic_size=False ) home_banks.append(bank) num_banks += 1 out_vehicles, out_banks = simulation_loop( fleet.vehicles, home_banks, away_banks, rules, interval_len, rows ) vehicle_ids = df.columns.values.tolist() fuel_df = pd.DataFrame(index=df.index) demand_df = pd.DataFrame(index=df.index) occupancy_df = pd.DataFrame(index=df.index) deferred_df = pd.DataFrame(index=df.index) battery_df = pd.DataFrame(index=df.index) for vehicle in out_vehicles: vid = vehicle_ids[vehicle.fleet_id] fuel_df[vid] = vehicle.fuel_burned_a deferred_df[vid] = vehicle.deferred_a battery_df[vid] = vehicle.battery_a bank_i = 0 for bank in out_banks: bank_col = 'bank_{}'.format(bank_i) demand_df[bank_col] = bank.demand_profile occupancy_df[bank_col] = (bank.occupancy_profile / bank.size) * 100.0 bank_i += 1 obj_base = 'results/' + sc.dataset_id + 'simulations/' + sc.run_id + '/' for fr, nm in zip([fuel_df, demand_df, battery_df, occupancy_df, deferred_df], ['fuel', 'demand', 'battery', 'occupancy', 'deferred']): storage.upload_data( df=fr, obj_path=obj_base + nm, formats='parquet records csv', ) return SimulationResult( uid=sc.run_id, deferred=deferred_df, fuel_use=fuel_df, occupancy=occupancy_df, demand=demand_df, battery=battery_df, errors=[] ) storage.cleanup() return SimulationResult(errors=['Some error occurred.'])