from ScEpTIC.emulator.energy.mcu_peripheral.options import MCUPeripheralPowerStateBehaviour from ScEpTIC.emulator.energy.voltage_drawner import VoltageDrawner from ScEpTIC.exceptions import ConfigurationException class MCUPeripheral(VoltageDrawner): """ Generic peripheral that attaches to the MCU """ def __init__(self): self.mcu = None self.power_state_behaviour = MCUPeripheralPowerStateBehaviour.ALWAYS_ON def set_power_state_behaviour(self, behaviour): """ Sets the power-state behaviour of the peripheral :param behaviour: a MCUPeripheralPowerStateBehaviour enum """ if not isinstance(behaviour, MCUPeripheralPowerStateBehaviour): raise ConfigurationException(f"{self.__class__.__name__}.set_power_state_behaviour() requires a MCUPeripheralPowerStateBehaviour but {behaviour.__class__.__name__} was given") self.power_state_behaviour = behaviour def attach_mcu(self, mcu): """ Attaches the mcu to the peripheral :param mcu: the MCU energy model """ # Smelly solution, but resolves the ciruclar import problem from ScEpTIC.emulator.energy.mcu import MCUEnergyModel if not isinstance(mcu, MCUEnergyModel): raise ConfigurationException(f"{self.__class__.__name__}.attach_mcu() requires a MCUEnergyModel but {mcu.__class__.__name__} was given") self.mcu = mcu def get_power_state_events(self): """ :return: a list of PowerState events that are occurring """ raise NotImplementedError(f"{self.__class__.__name__} must implement get_power_state_events()") def _follow_mcu_power_state(self): """ Checks the MCU power state and updates the peripheral power state accordingly """ raise NotImplementedError(f"{self.__class__.__name__} must implement check_mcu_power_state()") def get_drained_energy(self, t): """ Calculates the energy consumed by the component and follows MCU power state. :param t: elapsed time :return: the consumed energy """ if self.power_state_behaviour == MCUPeripheralPowerStateBehaviour.FOLLOW_MCU: self._follow_mcu_power_state() return self._get_drained_energy(t) def _get_drained_energy(self, t): """ Calculates the energy consumed by the component. :param t: elapsed time :return: the consumed energy """ raise NotImplementedError(f"{self.__class__.__name__} must implement _get_drained_energy()")