Spaces:
Sleeping
Sleeping
# SOC is normalized so that minimal_depth_of_discharge = 0 and maximal_depth_of_discharge = 1. | |
# please set capacity_Ah = nominal_capacity_Ah * (max_dod - min_dod) | |
# | |
# TODO efficiency multiplier is not currently used, where best to put it? | |
class BatteryModel: | |
def __init__(self, capacity_Ah, time_interval_h): | |
self.capacity_Ah = capacity_Ah | |
self.efficiency = 0.9 # [dimensionless] | |
self.voltage_V = 600 | |
self.charge_kW = 50 | |
self.discharge_kW = 60 | |
self.time_interval_h = time_interval_h | |
# the only non-constant member variable! | |
# ratio of self.current_capacity_kWh and self.maximal_capacity_kWh | |
self.soc = 0.0 | |
def maximal_capacity_kWh(self): | |
return self.capacity_Ah * self.voltage_V / 1000 | |
def current_capacity_kWh(self): | |
return self.soc * self.maximal_capacity_kWh | |
def satisfy_demand(self, demand_kW): | |
assert 0 <= self.soc <= 1 | |
assert demand_kW >= 0 | |
# rate limited: | |
possible_discharge_in_timestep_kWh = self.discharge_kW * self.time_interval_h | |
# limited by current capacity: | |
possible_discharge_in_timestep_kWh = min((possible_discharge_in_timestep_kWh, self.current_capacity_kWh)) | |
# limited by need: | |
discharge_in_timestep_kWh = min((possible_discharge_in_timestep_kWh, demand_kW * self.time_interval_h)) | |
consumption_from_bess_kW = discharge_in_timestep_kWh / self.time_interval_h | |
unsatisfied_demand_kW = demand_kW - consumption_from_bess_kW | |
cap_of_battery_kWh = self.current_capacity_kWh - discharge_in_timestep_kWh | |
soc = cap_of_battery_kWh / self.maximal_capacity_kWh | |
assert 0 <= soc <= self.soc <= 1 | |
self.soc = soc | |
return unsatisfied_demand_kW | |
def charge(self, charge_kW): | |
assert 0 <= self.soc <= 1 | |
assert charge_kW >= 0 | |
# rate limited: | |
possible_charge_in_timestep_kWh = self.charge_kW * self.time_interval_h | |
# limited by current capacity: | |
possible_charge_in_timestep_kWh = min((possible_charge_in_timestep_kWh, self.maximal_capacity_kWh - self.current_capacity_kWh)) | |
# limited by supply: | |
charge_in_timestep_kWh = min((possible_charge_in_timestep_kWh, charge_kW * self.time_interval_h)) | |
actual_charge_kW = charge_in_timestep_kWh / self.time_interval_h | |
unused_charge_kW = charge_kW - actual_charge_kW | |
cap_of_battery_kWh = self.current_capacity_kWh + charge_in_timestep_kWh | |
soc = cap_of_battery_kWh / self.maximal_capacity_kWh | |
assert 0 <= self.soc <= soc <= 1 | |
self.soc = soc | |
return unused_charge_kW | |