feat(beacons): plot-path link seeds TX chain to match beacon EIRP
The "Plot path to beacon" action now includes `tx_power_dbm` and `src_gain_dbi` in the /path query string so the path calculator's TX side emits the same EIRP as the beacon out of the box. The beacon schema stores `power_mw` as EIRP already (per Beacons.RangeEstimate), so we take 10·log10(power_mw), split against a default 30 dBi dish, and clamp the TX power to a 0 dBm floor so very-low-EIRP beacons produce a sane gain/power split instead of -10 dBm outputs. Examples: 10 W EIRP (40 dBm) → 30 dBi dish + 10 dBm TX 100 W EIRP (50 dBm) → 30 dBi dish + 20 dBm TX 100 mW EIRP (20 dBm) → 20 dBi + 0 dBm (clamped)
This commit is contained in:
parent
fbec454917
commit
5dea91d43f
2 changed files with 50 additions and 1 deletions
|
|
@ -285,11 +285,41 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
|
||||||
"dst_height_ft" => to_string(beacon.height_ft)
|
"dst_height_ft" => to_string(beacon.height_ft)
|
||||||
}
|
}
|
||||||
|
|
||||||
params = maybe_put(base, "band", BandResolver.resolve_as_string(beacon.frequency_mhz))
|
{tx_power_dbm, src_gain_dbi} = baseline_tx_for_eirp(beacon.power_mw)
|
||||||
|
|
||||||
|
params =
|
||||||
|
base
|
||||||
|
|> maybe_put("band", BandResolver.resolve_as_string(beacon.frequency_mhz))
|
||||||
|
|> maybe_put("tx_power_dbm", tx_power_dbm)
|
||||||
|
|> maybe_put("src_gain_dbi", src_gain_dbi)
|
||||||
|
|
||||||
"/path?" <> URI.encode_query(params)
|
"/path?" <> URI.encode_query(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Splits the beacon's EIRP (the beacon schema's `power_mw` field is
|
||||||
|
# already an EIRP value, per Beacons.RangeEstimate) into a
|
||||||
|
# tx_power_dbm + src_gain_dbi pair so the path calculator's TX chain
|
||||||
|
# emits the same EIRP as the beacon. We default the antenna gain to
|
||||||
|
# 30 dBi (typical 2-3 ft microwave dish) and derive the TX power from
|
||||||
|
# there, clamping to a 0 dBm / 1 mW minimum so very-low-EIRP beacons
|
||||||
|
# produce sane baseline values instead of -10 dBm absurdities.
|
||||||
|
defp baseline_tx_for_eirp(nil), do: {nil, nil}
|
||||||
|
defp baseline_tx_for_eirp(power_mw) when power_mw <= 0, do: {nil, nil}
|
||||||
|
|
||||||
|
defp baseline_tx_for_eirp(power_mw) do
|
||||||
|
eirp_dbm = 10.0 * :math.log10(power_mw)
|
||||||
|
default_gain = 30.0
|
||||||
|
min_tx_dbm = 0.0
|
||||||
|
|
||||||
|
tx_dbm = max(min_tx_dbm, eirp_dbm - default_gain)
|
||||||
|
gain_dbi = eirp_dbm - tx_dbm
|
||||||
|
|
||||||
|
{format_dbm(tx_dbm), format_dbi(gain_dbi)}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp format_dbm(v), do: v |> Float.round(1) |> to_string()
|
||||||
|
defp format_dbi(v), do: v |> Float.round(1) |> to_string()
|
||||||
|
|
||||||
defp precise_grid(%Beacon{lat: lat, lon: lon}) when is_number(lat) and is_number(lon) do
|
defp precise_grid(%Beacon{lat: lat, lon: lon}) when is_number(lat) and is_number(lon) do
|
||||||
Maidenhead.from_latlon(lat, lon, 8)
|
Maidenhead.from_latlon(lat, lon, 8)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,25 @@ defmodule MicrowavepropWeb.BeaconLiveTest do
|
||||||
{:ok, _view, html} = live(conn, ~p"/beacons/#{beacon}")
|
{:ok, _view, html} = live(conn, ~p"/beacons/#{beacon}")
|
||||||
assert html =~ "Pending approval"
|
assert html =~ "Pending approval"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "plot-path-to-beacon link pre-populates tx_power + gain to match beacon EIRP",
|
||||||
|
%{conn: conn} do
|
||||||
|
# power_mw: 10_000 → EIRP 40 dBm → default-gain 30 dBi → tx 10 dBm
|
||||||
|
beacon = approved_beacon_fixture(user_fixture(), power_mw: 10_000.0)
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/beacons/#{beacon}")
|
||||||
|
|
||||||
|
assert html =~ "tx_power_dbm=10.0"
|
||||||
|
assert html =~ "src_gain_dbi=30.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "low-EIRP beacon clamps tx_power to 0 dBm floor and lowers gain", %{conn: conn} do
|
||||||
|
# power_mw: 100 → EIRP 20 dBm → tx 0 dBm (clamped), gain 20 dBi
|
||||||
|
beacon = approved_beacon_fixture(user_fixture(), power_mw: 100.0, callsign: "W5LOW")
|
||||||
|
{:ok, _view, html} = live(conn, ~p"/beacons/#{beacon}")
|
||||||
|
|
||||||
|
assert html =~ "tx_power_dbm=0.0"
|
||||||
|
assert html =~ "src_gain_dbi=20.0"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Form" do
|
describe "Form" do
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue