Source code for nrel.hive.model.vehicle.mechatronics

from __future__ import annotations

from typing import Any, Callable, Dict, Optional

import yaml
from immutables import Map

from nrel.hive.model.vehicle.mechatronics.bev import BEV
from nrel.hive.model.vehicle.mechatronics.ice import ICE
from nrel.hive.model.vehicle.mechatronics.mechatronics_interface import MechatronicsInterface
from nrel.hive.model.vehicle.mechatronics.powercurve.powercurve import Powercurve
from nrel.hive.model.vehicle.mechatronics.powertrain.powertrain import Powertrain
from nrel.hive.util import fs
from nrel.hive.util.typealiases import MechatronicsId


[docs]def build_mechatronics_table( mechatronics_file: str, scenario_directory: str, custom_powertrain_constructor: Optional[Callable[[Dict[str, Any]], Powertrain]] = None, custom_powercurve_constructor: Optional[Callable[[Dict[str, Any]], Powercurve]] = None, ) -> Map[MechatronicsId, MechatronicsInterface]: """ constructs a dictionary containing all of the provided vehicle configurations where the key is the mechatronics ID and the contents are the appropriate mechatronics models with the desired attributes :param mechatronics_file: the mechatronics configuration yaml file :param scenario_directory: the directory with the required scenario files :return: a dictionary of the different vehicle configurations where the keys are the mechatronics IDs :raises Exception due to IOErrors, missing required parameters in the mechatronics yaml :raises Exception due to FileNotFoundErrors, missing the mechatronics, powertrain, or powercurve file(s) """ mechatronics: Dict[str, MechatronicsInterface] = {} with open(mechatronics_file) as f: config_dict = yaml.safe_load(f) for mechatronics_id in config_dict: # add the mechatronics id to the nested dictionary config_dict[mechatronics_id]["mechatronics_id"] = mechatronics_id try: mechatronics_type = config_dict[mechatronics_id]["mechatronics_type"] except KeyError: raise IOError(f"could not find mechatronics_type in {mechatronics_id}") if "powertrain_file" in config_dict[mechatronics_id]: powertrain_file = fs.construct_asset_path( config_dict[mechatronics_id]["powertrain_file"], scenario_directory, "powertrain", "powertrain", # resources.powertrain ) config_dict[mechatronics_id]["powertrain_file"] = powertrain_file if "powercurve_file" in config_dict[mechatronics_id]: powercurve_file = fs.construct_asset_path( config_dict[mechatronics_id]["powercurve_file"], scenario_directory, "powercurve", "powercurve", # resources.powercurve ) config_dict[mechatronics_id]["powercurve_file"] = powercurve_file if mechatronics_type == "bev": mechatronics[mechatronics_id] = BEV.from_dict( config_dict[mechatronics_id], custom_powertrain_constructor, custom_powercurve_constructor, ) elif mechatronics_type == "ice": mechatronics[mechatronics_id] = ICE.from_dict( config_dict[mechatronics_id], custom_powertrain_constructor ) else: raise ValueError( f"got unexpected mechatronics type {mechatronics_type}; try `bev` or `ice`" ) return Map(mechatronics)