class TestEV(TestCase): def setUp(self): basicBatt = create_autospec(Battery) self.ev = EV(0, 10, 25.0, 'PS-001', '0001', basicBatt) def test_charge_valid_rate(self): self.ev._battery.charge = Mock(return_value=16) rate = self.ev.charge(16, 240, 5) self.assertEqual(rate, 16) self.assertAlmostEqual(self.ev.energy_delivered, 0.32) self.ev._battery.charge.assert_called_once() def test_charge_over_max_rate(self): self.ev._battery.charge = Mock(return_value=32) rate = self.ev.charge(40, 240, 5) self.assertEqual(rate, 32) self.assertAlmostEqual(self.ev.energy_delivered, 0.64) self.ev._battery.charge.assert_called_once() def test_reset(self): self.ev._battery.reset = Mock() self.ev._battery.reset = Mock() self.ev.reset() self.assertEqual(self.ev.energy_delivered, 0) self.ev._battery.reset.assert_called_once()
def test_post_charging_update_early_departure_no_ev_in_queue( self, choice_mock): self.network.early_departure = True ev1 = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) # Plug ev1 into space PS-001 choice_mock.return_value = "PS-002" self.network.plugin(ev1) # Fully charge ev1 ev1._energy_delivered = 10 # Test that unplug is called during post_charging_update. self.network.unplug = Mock() self.network.post_charging_update() self.network.unplug.assert_not_called()
def test_unplug_station_exists_session_id_mismatch(self, choice_mock) -> None: ev = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) choice_mock.return_value = "PS-002" self.network.plugin(ev) self.network._EVSEs["PS-002"].unplug = Mock() self.network.unplug(ev.station_id, "Incorrect ID") # noinspection PyUnresolvedReferences self.network._EVSEs["PS-002"].unplug.assert_not_called()
def test_unplug_station_exists_session_id_matches_queue_empty( self, choice_mock) -> None: ev = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) choice_mock.return_value = "PS-002" self.network.plugin(ev) self.network._EVSEs["PS-002"].unplug = Mock() self.network.unplug(ev.station_id, ev.session_id) self.network._EVSEs["PS-002"].unplug.assert_called()
def test_plugin_ev_no_spot_available_evs_in_waiting_queue(self) -> None: ev1 = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) ev2 = EV(0, 10, 10, "", "Session-02", Battery(100, 0, 6.6)) # Mock available_evses to behavior like the network is full. self.network.available_evses = Mock(return_value=[]) # Add ev1 to the waiting queue self.network.waiting_queue[ev1.session_id] = ev1 self.network.waiting_queue.move_to_end(ev1.session_id) self.network.plugin(ev2) # EV should be added to waiting_queue self.assertEqual(len(self.network.waiting_queue), 2) # ev1 should be after ev2 in the queue _, first_in_queue = self.network.waiting_queue.popitem(last=False) _, second_in_queue = self.network.waiting_queue.popitem(last=False) self.assertIs(first_in_queue, ev1) self.assertIs(second_in_queue, ev2)
def test_plugin_ev_no_spot_available_empty_waiting_queue(self) -> None: ev = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) # Mock available_evses to behavior like the network is full. self.network.available_evses = Mock(return_value=[]) self.network.plugin(ev) # EV should be added to waiting_queue self.assertEqual(len(self.network.waiting_queue), 1) self.assertIn(ev.session_id, self.network.waiting_queue) self.assertIs(self.network.waiting_queue[ev.session_id], ev)
def test_post_charging_update_early_departure_ev_not_full( self, choice_mock): self.network.early_departure = True ev1 = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) ev2 = EV(0, 10, 10, "", "Session-02", Battery(100, 0, 6.6)) # Plug ev1 into space PS-001 choice_mock.return_value = "PS-002" self.network.plugin(ev1) # ev1 not fully charged ev1._energy_delivered = 5 # Add ev2 to the waiting queue self.network.waiting_queue[ev2.session_id] = ev2 self.network.waiting_queue.move_to_end(ev2.session_id) # Test that unplug is called during post_charging_update. self.network.unplug = Mock() self.network.post_charging_update() self.network.unplug.assert_not_called()
def test_unplug_station_exists_session_id_matches_ev_in_queue( self, choice_mock) -> None: ev1 = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) ev2 = EV(0, 10, 10, "", "Session-02", Battery(100, 0, 6.6)) # Plug ev1 into space PS-001 choice_mock.return_value = "PS-002" self.network.plugin(ev1) # Add ev2 to the waiting queue self.network.waiting_queue[ev2.session_id] = ev2 self.network.waiting_queue.move_to_end(ev2.session_id) # Mock the plugin method so we can assert it was called. self.network._EVSEs["PS-002"].plugin = Mock() # Unplug ev1 self.network.unplug(ev1.station_id, ev1.session_id) # ev2 should be plugged in after ev1 leaves self.network._EVSEs["PS-002"].plugin.assert_called_with(ev2) # swaps counter should be incremented self.assertEqual(self.network.swaps, 1)
def test_unplug_when_ev_in_waiting_queue(self): ev1 = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) # Add ev2 to the waiting queue self.network.waiting_queue[ev1.session_id] = ev1 self.network.waiting_queue.move_to_end(ev1.session_id) self.assertEqual(len(self.network.waiting_queue), 1) self.network.unplug(ev1.station_id, ev1.session_id) # ev1 should be removed from the waiting queue self.assertEqual(len(self.network.waiting_queue), 0) # never_charged counter should be incremented self.assertEqual(self.network.never_charged, 1)
def setUp(self): basicBatt = create_autospec(Battery) self.ev = EV(0, 10, 25.0, 'PS-001', '0001', basicBatt)
def setUp(self): basicBatt = create_autospec(Battery) self.ev = EV(0, 10, 25.0, "PS-001", "0001", basicBatt)
def test_plugin_ev_with_spot_available(self, choice_mock) -> None: ev = EV(0, 10, 10, "", "Session-01", Battery(100, 0, 6.6)) choice_mock.return_value = "PS-002" self.network.plugin(ev) self.assertEqual(ev.station_id, "PS-002") self.assertIs(self.network.get_ev("PS-002"), ev)
def _convert_ev_matrix( ev_matrix: np.ndarray, period: float, voltage: float, max_battery_power: float, max_len: int = None, battery_params: Optional[BatteryParams] = None, force_feasible: bool = False, ) -> List[EV]: """ Args: ev_matrix (np.ndarray[float]): Nx3 array where N is the number of EVs. Column 1 is the arrival time in hours since midnight, column 2 is the session duration in hours, and column 3 is the energy demand in kWh. (See generate_events() for other arguments) Returns: List[EV]: List of EVs with parameters taken from ev_matrix. """ period_per_hour = 60 / period evs = [] for row_idx, row in enumerate(ev_matrix): arrival, duration, energy_delivered = row if arrival < 0 or duration <= 0 or energy_delivered <= 0: print("Invalid session.") continue if max_len is not None and duration > max_len: duration = max_len if force_feasible: max_feasible = max_battery_power * duration energy_delivered = np.minimum(max_feasible, energy_delivered) departure = int((arrival + duration) * period_per_hour) arrival = int(arrival * period_per_hour) session_id = f"session_{row_idx}" # By default a new station is created for each EV. # Infinite space assumption. station_id = f"station_{row_idx}" battery_params_input: BatteryParams if battery_params is None: battery_params_input = {"type": Battery} else: battery_params_input = battery_params battery_kwargs = ( battery_params_input["kwargs"] if "kwargs" in battery_params_input else {} ) if "capacity_fn" in battery_params_input: cap_fn: CapFnCallable = battery_params_input["capacity_fn"] cap, init = cap_fn(energy_delivered, duration, voltage, period) else: cap = energy_delivered init = 0 battery_type = battery_params_input["type"] battery = battery_type(cap, init, max_battery_power, **battery_kwargs) evs.append( EV( arrival, departure, energy_delivered, station_id, session_id, battery, ) ) return evs