from __future__ import annotations
from abc import abstractmethod, ABC
from dataclasses import dataclass
from typing import Dict, TYPE_CHECKING, Tuple
import immutables
from nrel.hive.model.energy import EnergyType
if TYPE_CHECKING:
from nrel.hive.util.units import Seconds, Ratio, Kilometers
from nrel.hive.util.typealiases import MechatronicsId
from nrel.hive.model.energy.charger import Charger
from nrel.hive.model.vehicle.vehicle import Vehicle
from nrel.hive.model.roadnetwork.route import Route
[docs]@dataclass(frozen=True)
class MechatronicsMixin:
mechatronics_id: MechatronicsId
[docs]class MechatronicsInterfaceABC(ABC):
"""
Interface for creating energy sources
"""
[docs] @classmethod
@abstractmethod
def from_dict(cls, d: Dict[str, str]) -> MechatronicsInterface:
"""
build from a dictionary
:param d: the dictionary to build from
:return: the built Mechatronics object
"""
[docs] @abstractmethod
def valid_charger(self, charger: Charger) -> bool:
"""
check to see if the mechatronics instance can use a certain charger
:param charger: the charger to check
:return: true/false
"""
[docs] @abstractmethod
def initial_energy(self, percent_full: Ratio) -> immutables.Map[EnergyType, float]:
"""
construct an initial energy state for a Vehicle
:param percent_full: the amount of energy in the vehicle
:return: the Vehicle.energy at startup
"""
[docs] @abstractmethod
def range_remaining_km(self, vehicle: Vehicle) -> Kilometers:
"""
how much range remains, in kilometers
:return:
"""
[docs] @abstractmethod
def calc_required_soc(self, required_range: Kilometers) -> Ratio:
"""
How much SOC needed to go required_range
"""
[docs] @abstractmethod
def fuel_source_soc(self, vehicle: Vehicle) -> Ratio:
"""
how much battery soc
:return:
"""
[docs] @abstractmethod
def is_empty(self, vehicle: Vehicle) -> bool:
"""
can the vehicle still move?
:return:
"""
[docs] @abstractmethod
def is_full(self, vehicle: Vehicle) -> bool:
"""
is the vehicle full of energy?
:return:
"""
[docs] @abstractmethod
def consume_energy(self, vehicle: Vehicle, route: Route) -> Vehicle:
"""
consume energy over a route
:param vehicle:
:param route:
:return: the vehicle after moving;
"""
[docs] @abstractmethod
def idle(self, vehicle: Vehicle, time_seconds: Seconds) -> Vehicle:
"""
idle for a set amount of time
:param vehicle:
:param time_seconds:
:return:
"""
[docs] @abstractmethod
def add_energy(
self, vehicle: Vehicle, charger: Charger, time_seconds: Seconds
) -> Tuple[Vehicle, Seconds]:
"""
add energy into the system
:param vehicle:
:param charger:
:param time_seconds:
:return: the updated vehicle, along with the time spent charging
"""
[docs]class MechatronicsInterface(MechatronicsMixin, MechatronicsInterfaceABC):
""""""