from typing import Literal from pydantic import BaseModel, Field from app.models.antenna import AntennaPatternSpec from app.models.common import OutputFormat, RxPoint, TxPoint class CoverageRx(BaseModel): height_agl: float = Field(ge=0) sensitivity_dbm: float gain_dbi: float = 0 class CoverageTx(TxPoint): power_dbm: float frequency_mhz: float = Field(gt=0) class CoverageRequest(BaseModel): tx: CoverageTx antenna: AntennaPatternSpec rx: CoverageRx model: Literal["p1812", "itm", "fspl"] = "fspl" environment: Literal["urban", "suburban", "rural"] = "rural" radius_m: float = Field(gt=0) azimuth_step_deg: float = Field(default=1.0, gt=0, le=360) range_step_m: float = Field(default=30, gt=0) include_buildings: bool = True include_vegetation: bool = True levels_dbm: list[float] = Field(default_factory=lambda: [-90, -100, -110]) format: OutputFormat = "geojson" class LinkTx(TxPoint): power_dbm: float gain_dbi: float = 0 class LinkRx(RxPoint): gain_dbi: float = 0 sensitivity_dbm: float