Files
py-dvt-ate/src/py_dvt_ate/data/models.py

84 lines
2.3 KiB
Python

"""Data models for test persistence.
This module defines dataclasses representing test runs, results, and measurements.
These models map to SQLite tables (for metadata) and Parquet files (for time-series).
"""
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
class TestStatus(Enum):
"""Test run status."""
PENDING = "pending"
RUNNING = "running"
PASSED = "passed"
FAILED = "failed"
ERROR = "error"
SKIPPED = "skipped"
@dataclass
class TestRun:
"""Test run metadata.
Maps to the test_runs SQLite table.
"""
id: str # UUID
test_name: str
started_at: datetime
status: TestStatus
config_json: str # JSON string of test configuration
description: str | None = None
completed_at: datetime | None = None
operator: str | None = None
notes: str | None = None
created_at: datetime = field(default_factory=datetime.now)
@dataclass(frozen=True)
class TestResult:
"""Immutable test result with limits.
Maps to the test_results SQLite table.
Represents a single scalar measurement with pass/fail limits.
"""
id: str # UUID
test_run_id: str # Foreign key to test_runs.id
parameter: str
value: float
unit: str
measured_at: datetime
lower_limit: float | None = None
upper_limit: float | None = None
@property
def passed(self) -> bool | None:
"""Evaluate pass/fail. None if no limits defined."""
if self.lower_limit is None and self.upper_limit is None:
return None
lower_ok = self.lower_limit is None or self.value >= self.lower_limit
upper_ok = self.upper_limit is None or self.value <= self.upper_limit
return lower_ok and upper_ok
@dataclass(frozen=True)
class Measurement:
"""Immutable measurement record for time-series data.
Maps to Parquet files for efficient storage and analysis.
Includes measurement conditions (temperature, voltage, current) at time of measurement.
"""
timestamp: float # Seconds since epoch (high precision)
parameter: str
value: float
unit: str
temperature: float = 0.0 # Chamber temperature at measurement
input_voltage: float = 0.0 # DUT input voltage at measurement
load_current: float = 0.0 # DUT load current at measurement