models package

Submodules

Module contents

Domain models for the electric port simulator.

Exposes Port, Boat, BoatState, Charger, ChargerState, Trip, TripPoint, PV, BESS, BESSControlStrategy.

class models.BESS(name: str, capacity: float, max_charge_power: float, max_discharge_power: float, efficiency: float = 0.9, soc_min: float = 0.1, soc_max: float = 0.9, initial_soc: float = 0.5, control_strategy: BESSControlStrategy = BESSControlStrategy.DEFAULT, current_soc: float = 0.5, current_power: float = 0.0)[source]

Bases: object

Battery energy storage system with SOC limits and round-trip efficiency.

name

BESS identifier.

Type:

str

capacity

Total energy capacity (kWh).

Type:

float

max_charge_power

Maximum charge power (kW).

Type:

float

max_discharge_power

Maximum discharge power (kW).

Type:

float

efficiency

Round-trip efficiency in (0, 1]; default 0.90.

Type:

float

soc_min

Minimum SOC in [0, 1]; default 0.10.

Type:

float

soc_max

Maximum SOC in [0, 1]; default 0.90.

Type:

float

initial_soc

Initial SOC; default 0.50.

Type:

float

control_strategy

Control strategy enum.

Type:

models.bess.BESSControlStrategy

current_soc

Current SOC (updated by charge/discharge).

Type:

float

current_power

Current power (kW); positive = charging, negative = discharging.

Type:

float

capacity: float
charge(power: float, timestep_seconds: float) float[source]

Charge for the given power and timestep; SOC is capped at soc_max.

Parameters:
  • power – Requested charging power (kW), must be positive.

  • timestep_seconds – Timestep duration (s).

Returns:

Actual power charged (kW); may be less than requested if SOC limit reached.

control_strategy: BESSControlStrategy = 'default'
current_power: float = 0.0
current_soc: float = 0.5
discharge(power: float, timestep_seconds: float) float[source]

Discharge for the given power and timestep; SOC is floored at soc_min.

Parameters:
  • power – Requested discharge power (kW), must be positive.

  • timestep_seconds – Timestep duration (s).

Returns:

Actual power discharged (kW); may be less than requested if SOC limit reached.

efficiency: float = 0.9
get_available_charge_capacity() float[source]

Capacity (kWh) available for charging (from current_soc to soc_max, accounting for efficiency).

get_available_energy() float[source]

Energy (kWh) that can still be discharged (from current_soc down to soc_min, after efficiency).

get_energy_stored() float[source]

Current energy stored in the battery (kWh).

get_max_charge_power_available(timestep_seconds: float) float[source]

Maximum charge power (kW) in this timestep (min of max_charge_power and capacity-limited power).

get_max_discharge_power_available(timestep_seconds: float) float[source]

Maximum discharge power (kW) in this timestep (min of max_discharge_power and energy-limited power).

idle() None[source]

Set current_power to 0 (no charge or discharge).

initial_soc: float = 0.5
max_charge_power: float
max_discharge_power: float
name: str
soc_max: float = 0.9
soc_min: float = 0.1
class models.BESSControlStrategy(value)[source]

Bases: Enum

BESS control strategy; DEFAULT = charge from PV surplus, discharge when needed.

DEFAULT = 'default'
class models.Boat(motor_power: int, weight: float, length: float, battery_capacity: float, range_speed: float, soc: float = 1.0, name: str = '')[source]

Bases: object

Electric boat at the port.

motor_power

Motor power (kW).

Type:

int

weight

Weight (kg).

Type:

float

length

Length (m).

Type:

float

battery_capacity

Battery capacity (kWh).

Type:

float

range_speed

Range speed (knots).

Type:

float

soc

State of charge in [0, 1]; default 1.0 (full).

Type:

float

name

Identifier; auto-generated as Boat_N if empty.

Type:

str

_state

Internal state (BoatState); use .state property.

Type:

models.boat.BoatState

battery_capacity: float
property k: float

motor_power / range_speed^3 (used in trip energy estimates).

Type:

Return k-factor for cube law

length: float
motor_power: int
name: str = ''
range_speed: float
soc: float = 1.0
property state: BoatState

Current boat state.

weight: float
class models.BoatState(value)[source]

Bases: Enum

Boat state: idle, charging, or sailing.

CHARGING = 'charging'
IDLE = 'idle'
SAILING = 'sailing'
class models.Charger(max_power: int, efficiency: float = 0.95, power: float = 0.0, name: str = '')[source]

Bases: object

Charging station at the port.

max_power

Maximum output power (kW).

Type:

int

efficiency

Charging efficiency in (0, 1]; default 0.95.

Type:

float

power

Current output power (kW).

Type:

float

name

Identifier; auto-generated as Charger_N if empty.

Type:

str

_state

Internal state; use .state property.

Type:

models.charger.ChargerState

connected_boat

Name of connected boat, or None.

Type:

str | None

connected_boat: str | None = None
property effective_power: float

Power delivered to the battery after efficiency (kW).

efficiency: float = 0.95
max_power: int
name: str = ''
power: float = 0.0
property state: ChargerState

Current charger state.

class models.ChargerState(value)[source]

Bases: Enum

Charger state: idle or charging.

CHARGING = 'charging'
IDLE = 'idle'
class models.PV(name: str, capacity: float, tilt: float = 30.0, azimuth: float = 180.0, latitude: float = 0.0, longitude: float = 0.0, current_production: float = 0.0)[source]

Bases: object

PV system with fixed tilt/azimuth; production from GHI/DNI/DHI and cell temperature.

name

System name.

Type:

str

capacity

DC capacity at STC (kW).

Type:

float

tilt

Panel tilt (degrees); default 30.

Type:

float

azimuth

Panel azimuth (degrees); default 180.

Type:

float

latitude

Site latitude.

Type:

float

longitude

Site longitude.

Type:

float

current_production

Last computed production (kW).

Type:

float

azimuth: float = 180.0
calculate_production(ghi: float, dni: float, dhi: float, temperature: float, timestamp, wind_speed: float = 1.0) float[source]

Compute DC power (kW) at timestamp using POA irradiance, Sandia cell temperature, PVWatts DC.

Parameters:
  • ghi – Global horizontal irradiance (W/m²).

  • dni – Direct normal irradiance (W/m²).

  • dhi – Diffuse horizontal irradiance (W/m²).

  • temperature – Air temperature (°C).

  • timestamp – Time for solar position.

  • wind_speed – Wind speed (m/s) for cell temperature; default 1.0.

Returns:

DC power in kW; 0 if sun below horizon. Also sets current_production.

capacity: float
current_production: float = 0.0
latitude: float = 0.0
longitude: float = 0.0
name: str
tilt: float = 30.0
class models.Port(name: str, contracted_power: int, lat: float, lon: float, boats: List[Boat] = <factory>, chargers: List[Charger] = <factory>, pv_systems: List[PV] = <factory>, bess_systems: List[BESS] = <factory>, tariff_path: str | None = None)[source]

Bases: object

Electric recreational port with boats, chargers, PV, BESS, and optional tariff.

name

Port name.

Type:

str

contracted_power

Contracted power limit (kW).

Type:

int

lat

Latitude.

Type:

float

lon

Longitude.

Type:

float

boats

List of boats.

Type:

List[Boat]

chargers

List of chargers.

Type:

List[Charger]

pv_systems

List of PV systems.

Type:

List[PV]

bess_systems

List of BESS systems.

Type:

List[BESS]

tariff_path

Optional path to tariff JSON; if None, default_tariff.json is tried.

Type:

str | None

add_bess(bess: BESS) None[source]

Append a BESS to the port’s bess_systems list.

add_boat(boat: Boat) None[source]

Append a boat to the port’s boat list.

add_charger(charger: Charger) None[source]

Append a charger to the port’s charger list.

add_pv(pv: PV) None[source]

Append a PV system to the port’s pv_systems list.

bess_systems: List[BESS]
boats: List[Boat]
chargers: List[Charger]
contracted_power: int
get_tariff_price(timestamp: datetime) float[source]

Return electricity price per kWh for the given timestamp (15-minute resolution).

Parameters:

timestamp – Time to look up.

Returns:

Price per kWh, or 0.0 if no tariff or slot not found.

lat: float
lon: float
name: str
pv_systems: List[PV]
property tariff: Dict | None

Loaded tariff data (from tariff_path); None if no tariff loaded.

tariff_path: str | None = None
class models.Trip(csv_path: str)[source]

Bases: object

Boat trip with waypoints loaded from CSV.

route_name

Route name (from CSV filename stem).

points

List of TripPoint waypoints.

duration

Total trip duration in seconds.

estimate_energy_required(boat_k_factor: float) float[source]

Estimate total energy (kWh) for the full trip using cube-law power per segment.

Parameters:

boat_k_factor – Boat k-factor (motor_power / range_speed^3).

Returns:

Total energy in kWh.

get_energy_between(start_elapsed_seconds: float, end_elapsed_seconds: float, boat_k_factor: float) float[source]

Energy (kWh) consumed in [start_elapsed, end_elapsed] using same segment integration as estimate_energy_required.

Parameters:
  • start_elapsed_seconds – Window start (s from trip start).

  • end_elapsed_seconds – Window end (s from trip start).

  • boat_k_factor – Boat k-factor (motor_power / range_speed^3).

Returns:

Energy in kWh for the window.

get_point_at_elapsed_time(elapsed_seconds: float) TripPoint | None[source]

Return the waypoint closest to the given elapsed time from trip start.

Parameters:

elapsed_seconds – Seconds since trip start.

Returns:

Closest TripPoint, or None if elapsed_seconds exceeds trip duration.

class models.TripPoint(timestamp: datetime, point_type: str, speed: float, heading: float, latitude: float, longitude: float)[source]

Bases: object

One waypoint in a trip route.

timestamp

Time at this point.

Type:

datetime.datetime

point_type

Type label (e.g. Static, Dock, Terrestrial, Interpolated).

Type:

str

speed

Speed in knots.

Type:

float

heading

Heading in degrees.

Type:

float

latitude

Latitude.

Type:

float

longitude

Longitude.

Type:

float

heading: float
latitude: float
longitude: float
point_type: str
speed: float
timestamp: datetime