added covarage
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from app.core.antenna import AntennaPattern, gain
|
||||
from app.core.coverage import compute_coverage
|
||||
from app.core.vegetation import WORLDCOVER_P833, p833_coefficients_for_class
|
||||
from app.models.coverage import CoverageRequest
|
||||
from app.services import jobs
|
||||
|
||||
|
||||
def test_jobs_store_roundtrip() -> None:
|
||||
job_id = jobs.create_job("coverage", {"model": "fspl"})
|
||||
jobs.update_job(job_id, status="running")
|
||||
jobs.update_job(job_id, status="done", result={"ok": True})
|
||||
response = jobs.get_job(job_id)
|
||||
assert response is not None
|
||||
assert response.status == "done"
|
||||
assert response.result == {"ok": True}
|
||||
|
||||
|
||||
def test_coverage_fspl_geojson() -> None:
|
||||
request = CoverageRequest(
|
||||
tx={
|
||||
"lat": 59.935,
|
||||
"lon": 30.305,
|
||||
"height_agl": 30,
|
||||
"power_dbm": 40,
|
||||
"frequency_mhz": 433,
|
||||
},
|
||||
antenna={"pattern": "omni", "gain_dbi": 8},
|
||||
rx={"height_agl": 2, "sensitivity_dbm": -110, "gain_dbi": 2},
|
||||
model="fspl",
|
||||
radius_m=5000,
|
||||
azimuth_step_deg=90,
|
||||
range_step_m=500,
|
||||
include_vegetation=False,
|
||||
levels_dbm=[-90],
|
||||
format="geojson",
|
||||
)
|
||||
result = compute_coverage(request)
|
||||
assert result["type"] == "FeatureCollection"
|
||||
assert len(result["features"]) >= 1
|
||||
|
||||
|
||||
def test_worldcover_p833_mapping() -> None:
|
||||
coeffs = p833_coefficients_for_class("tree_cover")
|
||||
assert coeffs.gamma_db_per_m == WORLDCOVER_P833["tree_cover"].gamma_db_per_m
|
||||
|
||||
|
||||
def test_antenna_pattern_file(tmp_path: Path) -> None:
|
||||
pattern_file = tmp_path / "pattern.csv"
|
||||
pattern_file.write_text(
|
||||
"# azimuth, elevation, relative_gain\n"
|
||||
"0,0,0\n"
|
||||
"90,0,-3\n"
|
||||
"180,0,-20\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
pattern = AntennaPattern(pattern="file", gain_dbi=8, pattern_file=str(pattern_file))
|
||||
assert gain(pattern, 0, 0) == 8
|
||||
assert gain(pattern, 90, 0) == 5
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", ["itm", "p452", "p1812"])
|
||||
def test_propagation_models_return_positive_loss(model: str) -> None:
|
||||
from app.core.geo import GeoPoint
|
||||
from app.core.propagation import itm_loss, p452_loss, p1812_field
|
||||
|
||||
tx = GeoPoint(lat=59.935, lon=30.305)
|
||||
rx = GeoPoint(lat=59.945, lon=30.325)
|
||||
profile = [10.0, 12.0, 15.0, 13.0, 11.0]
|
||||
kwargs = {
|
||||
"tx_height_agl": 30.0,
|
||||
"rx_height_agl": 2.0,
|
||||
"freq_mhz": 433.0,
|
||||
"elevation_profile_m": profile,
|
||||
}
|
||||
if model == "itm":
|
||||
loss = itm_loss(tx, rx, **kwargs)
|
||||
elif model == "p452":
|
||||
loss = p452_loss(tx, rx, **kwargs)
|
||||
else:
|
||||
loss = p1812_field(tx, rx, environment="rural", **kwargs)
|
||||
assert loss > 0
|
||||
@@ -49,7 +49,7 @@ def test_link_budget_includes_vegetation_loss(monkeypatch) -> None:
|
||||
assert result.fresnel_violations_count >= 0
|
||||
assert isclose(
|
||||
result.total_loss_db,
|
||||
result.fspl_db + result.diffraction_db + 5.0,
|
||||
result.fspl_db + result.diffraction_db + result.vegetation_db + result.atmospheric_db,
|
||||
)
|
||||
|
||||
|
||||
@@ -94,7 +94,10 @@ def test_link_budget_includes_diffraction_loss(monkeypatch) -> None:
|
||||
result = link_service.link_budget(request)
|
||||
|
||||
assert result.diffraction_db > 0
|
||||
assert isclose(result.total_loss_db, result.fspl_db + result.diffraction_db)
|
||||
assert isclose(
|
||||
result.total_loss_db,
|
||||
result.fspl_db + result.diffraction_db + result.atmospheric_db,
|
||||
)
|
||||
assert result.fresnel_clear is False
|
||||
assert result.los_clear is False
|
||||
assert result.fresnel_quality == "blocked"
|
||||
|
||||
Reference in New Issue
Block a user