From 640647ec5c60f6f591e2c4a3c2938d72f331742f Mon Sep 17 00:00:00 2001 From: Kai Chappell Date: Tue, 2 Dec 2025 22:49:30 +0000 Subject: [PATCH] Add configuration Pydantic models --- src/py_dvt_ate/app/config.py | 119 +++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/py_dvt_ate/app/config.py diff --git a/src/py_dvt_ate/app/config.py b/src/py_dvt_ate/app/config.py new file mode 100644 index 0000000..007a21f --- /dev/null +++ b/src/py_dvt_ate/app/config.py @@ -0,0 +1,119 @@ +"""Configuration models for py_dvt_ate. + +This module defines Pydantic models for all configuration sections. +Configuration can be loaded from YAML files and validated at runtime. +""" + +from typing import Literal + +from pydantic import BaseModel, Field + + +class SimulatorConfig(BaseModel): + """Configuration for simulator instrument backend.""" + + host: str = "localhost" + thermal_chamber_port: int = 5001 + power_supply_port: int = 5002 + multimeter_port: int = 5003 + + +class PyVISAConfig(BaseModel): + """Configuration for PyVISA instrument backend.""" + + thermal_chamber: str | None = None + power_supply: str | None = None + multimeter: str | None = None + + +class InstrumentsConfig(BaseModel): + """Instrument backend configuration.""" + + backend: Literal["simulator", "pyvisa"] = "simulator" + simulator: SimulatorConfig = Field(default_factory=SimulatorConfig) + pyvisa: PyVISAConfig = Field(default_factory=PyVISAConfig) + + +class ThermalConfig(BaseModel): + """Thermal physics parameters.""" + + chamber_time_constant_s: float = 30.0 + case_time_constant_s: float = 5.0 + theta_jc: float = 15.0 # °C/W (junction to case) + theta_ca: float = 5.0 # °C/W (case to ambient) + + +class ChamberConfig(BaseModel): + """Thermal chamber behaviour parameters.""" + + ramp_rate_c_per_min: float = 10.0 + stability_window_c: float = 0.5 + stability_time_s: float = 30.0 + + +class PhysicsConfig(BaseModel): + """Physics simulation parameters.""" + + update_rate_hz: float = 100.0 + thermal: ThermalConfig = Field(default_factory=ThermalConfig) + chamber: ChamberConfig = Field(default_factory=ChamberConfig) + + +class DUTParameters(BaseModel): + """DUT model parameters.""" + + nominal_output_voltage: float = 3.3 + tempco_ppm_per_c: float = 50.0 + quiescent_current_ua: float = 50.0 + quiescent_current_tempco: float = 0.003 + dropout_voltage: float = 0.3 + + +class DUTConfig(BaseModel): + """DUT model configuration.""" + + model: str = "ldo" + parameters: DUTParameters = Field(default_factory=DUTParameters) + + +class DataConfig(BaseModel): + """Data storage paths.""" + + database_path: str = "./data/py_dvt_ate.db" + measurements_dir: str = "./data/measurements" + reports_dir: str = "./data/reports" + + +class LoggingConfig(BaseModel): + """Logging configuration.""" + + level: str = "INFO" + file: str = "./data/logs/py_dvt_ate.log" + format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + + +class DashboardConfig(BaseModel): + """Dashboard (Streamlit) configuration.""" + + enabled: bool = True + port: int = 8501 + + +class APIConfig(BaseModel): + """API server configuration (Phase 2).""" + + enabled: bool = False + host: str = "0.0.0.0" + port: int = 8000 + + +class AppConfig(BaseModel): + """Root configuration model.""" + + instruments: InstrumentsConfig = Field(default_factory=InstrumentsConfig) + physics: PhysicsConfig = Field(default_factory=PhysicsConfig) + dut: DUTConfig = Field(default_factory=DUTConfig) + data: DataConfig = Field(default_factory=DataConfig) + logging: LoggingConfig = Field(default_factory=LoggingConfig) + dashboard: DashboardConfig = Field(default_factory=DashboardConfig) + api: APIConfig = Field(default_factory=APIConfig)