Source code for citylearn.internal.units

"""Unit conversion helpers shared by runtime services."""

from __future__ import annotations

from typing import Optional


[docs] def seconds_to_hours(seconds_per_time_step: float) -> float: """Convert a control-step duration in seconds to hours.""" seconds = max(float(seconds_per_time_step), 0.0) return seconds / 3600.0
[docs] def power_kw_to_energy_kwh(power_kw: float, seconds_per_time_step: float) -> float: """Convert power in kW to control-step energy in kWh.""" return float(power_kw) * seconds_to_hours(seconds_per_time_step)
[docs] def energy_kwh_to_power_kw(energy_kwh: float, seconds_per_time_step: float) -> float: """Convert control-step energy in kWh to average power in kW.""" hours = max(seconds_to_hours(seconds_per_time_step), 1.0e-12) return float(energy_kwh) / hours
[docs] def normalized_power_action_to_energy_kwh( action: float, nominal_power_kw: float, seconds_per_time_step: float, ) -> float: """Convert a normalized power action to control-step energy in kWh.""" return power_kw_to_energy_kwh(float(action) * float(nominal_power_kw), seconds_per_time_step)
[docs] def normalized_capacity_action_to_energy_kwh( action: float, capacity_kwh: float, *, seconds_per_time_step: Optional[float] = None, scale_with_time: bool = False, ) -> float: """Convert a normalized capacity action to control-step energy in kWh.""" energy_kwh = float(action) * float(capacity_kwh) if not scale_with_time: return energy_kwh if seconds_per_time_step is None: raise ValueError("seconds_per_time_step must be provided when scale_with_time=True.") return energy_kwh * seconds_to_hours(seconds_per_time_step)
[docs] def to_dataset_resolution_energy(energy_kwh: float, time_step_ratio: Optional[float]) -> float: """Convert control-step energy to dataset-resolution energy when needed.""" ratio = 1.0 if time_step_ratio in (None, 0) else float(time_step_ratio) return float(energy_kwh) / ratio