Configuration¶
diveplan.core.config¶
Dive configuration — physical constants, planning parameters, gas limits.
Validation philosophy: reject physically impossible values (negative pressure, zero density) but impose no operational upper bounds — diveplan is an experimentation platform.
Default config loading — priority chain (highest to lowest)¶
DIVEPLAN_CONFIG_FILE env var — path to a JSON config file
./diveplan.config.json — project-level config in CWD
~/.diveplan/config.json — user-level config in home directory
factory defaults — built-in defaults
Set DIVEPLAN_NO_FILE_CONFIG=1 to skip steps 1-3 and always use factory defaults. Useful for CI, testing, or any environment where predictable defaults are required.
Invalid files at any level are skipped with a warning and the next level is tried.
Usage¶
# read and mutate the global config
from diveplan.core.config import DiveConfig
DiveConfig.current().physics.water_density = 1.0
DiveConfig.current().physics.surface_pressure_mbar = 800
DiveConfig.current().physics.gravity = 9.7
DiveConfig.current().planning.ascent_rate = 9.0
DiveConfig.current().planning.last_stop_m = 6.0
DiveConfig.current().planning.sample_rate_s = 2
DiveConfig.current().gas.max_ppo2_bar = 1.4
DiveConfig.current().gas.deco_ppo2_bar = 1.6
DiveConfig.current().gas.min_ppo2_bar = 0.18
DiveConfig.current().gas.max_ppn2_bar = 3.2
DiveConfig.current().gas.max_end_m = 30.0
DiveConfig.current().gas.sac_bottom = 20.0
DiveConfig.current().gas.sac_deco = 15.0
DiveConfig.current().gas.gas_switch_minutes = 1.0
DiveConfig.current().gas.gas_switch_at_stops_only = True
# permanent global replacement
custom = DiveConfig()
custom.gas.max_ppo2_bar = 1.2
custom.planning.ascent_rate = 8.0
DiveConfig.set_default(custom)
# scoped override — stack-based, supports nesting
altitude = DiveConfig()
altitude.physics.surface_pressure_mbar = 800
altitude.physics.water_density = 1.0
with altitude:
DiveConfig.current().physics.surface_pressure_mbar # 800
DiveConfig.current().physics.surface_pressure_mbar # restored
# JSON round-trip
DiveConfig.current().to_json(path="my_config.json")
cfg = DiveConfig.from_json(path="my_config.json")
DiveConfig.set_default(cfg)
- class diveplan.core.config.DiveConfig(**data)[source]¶
Bases:
BaseModelRoot configuration object.
DiveConfig itself is frozen — sub-configs are swapped at construction time or via scoped overrides. Mutations happen inside sub-configs:
DiveConfig.current().gas.max_ppo2_bar = 2.0 # ✅ sub-config mutation DiveConfig.current().gas = GasConfig(…) # ❌ frozen, not allowed
See module docstring for the full default loading priority chain.
- Parameters:
data (
Any)physics (_PhysicsConfig)
planning (_DivePlanningConfig)
gas (_GasConfig)
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- classmethod current()[source]¶
Return the active config — top of the (context-local) stack, or startup default.
- Return type:
- classmethod set_default(config)[source]¶
Permanently replace the global default config.
- Parameters:
config (
DiveConfig)- Return type:
- classmethod reset_default()[source]¶
Restore factory defaults and clear the stack — useful in tests.
- Return type: