Short-circuit RangeEstimate below 5.76 GHz to stop browser lockup
For a 1 W / 432 MHz beacon, RangeEstimate.estimate/1 was returning ~126 k cells because free-space loss dominates over atmospheric loss at low UHF, letting the rx_dbm filter pass almost the whole bbox. Jason-encoding that payload into the map's data-cells attribute was locking up browsers on the beacon detail page for low-band beacons even though the coverage toggle is already disabled for them. Return an empty estimate below the same 5760 MHz threshold the UI already enforces.
This commit is contained in:
parent
dc7bb5e110
commit
d5480ba676
2 changed files with 50 additions and 0 deletions
|
|
@ -35,6 +35,15 @@ defmodule Microwaveprop.Beacons.RangeEstimate do
|
|||
# HRRR grid step (degrees).
|
||||
@grid_step 0.125
|
||||
|
||||
# Below this frequency free-space loss dominates over atmospheric
|
||||
# loss, so `rx_dbm` exceeds the detection floor across tens of
|
||||
# thousands of km². On a 1 W / 432 MHz beacon the estimate produced
|
||||
# ~126k cells — Jason-encoding that into the map's data attribute
|
||||
# locked up browsers in prod. Return an empty estimate below the
|
||||
# threshold so the coverage toggle (also gated at 5760 MHz in the
|
||||
# LiveView) never has a payload to render.
|
||||
@min_supported_mhz 5760
|
||||
|
||||
@doc """
|
||||
Convert a power in milliwatts to dBm. Returns `-999.9` for non-positive input.
|
||||
"""
|
||||
|
|
@ -60,6 +69,10 @@ defmodule Microwaveprop.Beacons.RangeEstimate do
|
|||
detection floor.
|
||||
"""
|
||||
@spec estimate(struct()) :: map()
|
||||
def estimate(%{frequency_mhz: freq_mhz} = beacon) when freq_mhz < @min_supported_mhz do
|
||||
empty_estimate(beacon)
|
||||
end
|
||||
|
||||
def estimate(beacon) do
|
||||
band_mhz = nearest_band_mhz(beacon.frequency_mhz)
|
||||
band_config = BandConfig.get(band_mhz)
|
||||
|
|
@ -123,6 +136,25 @@ defmodule Microwaveprop.Beacons.RangeEstimate do
|
|||
}
|
||||
end
|
||||
|
||||
defp empty_estimate(beacon) do
|
||||
band_mhz = nearest_band_mhz(beacon.frequency_mhz)
|
||||
band_config = BandConfig.get(band_mhz)
|
||||
|
||||
%{
|
||||
beacon_id: beacon.id,
|
||||
band_mhz: band_mhz,
|
||||
band_label: band_config && band_config.label,
|
||||
center_score: 50,
|
||||
valid_time: nil,
|
||||
eirp_dbm: Float.round(mw_to_dbm(beacon.power_mw || 0.0), 1),
|
||||
atm_per_km: 0.0,
|
||||
grid_step: @grid_step,
|
||||
max_range_km: 0.0,
|
||||
cells: [],
|
||||
tiers: @tiers
|
||||
}
|
||||
end
|
||||
|
||||
# --- path loss ------------------------------------------------------------
|
||||
|
||||
defp received_dbm(_eirp, _f, _atm, +0.0, _score), do: 999.0
|
||||
|
|
|
|||
|
|
@ -112,5 +112,23 @@ defmodule Microwaveprop.Beacons.RangeEstimateTest do
|
|||
assert lon_mod < 0.01
|
||||
end
|
||||
end
|
||||
|
||||
test "short-circuits with empty cells for beacons below 5.76 GHz" do
|
||||
# 432 MHz with 1 W at unrestricted range would generate >100k cells
|
||||
# because atmospheric loss is negligible — encoding that payload
|
||||
# into the map's data attribute was locking up browsers in prod.
|
||||
result = RangeEstimate.estimate(beacon(frequency_mhz: 432.38, power_mw: 1000.0))
|
||||
assert result.cells == []
|
||||
assert result.max_range_km == 0.0
|
||||
# Still reports the nearest configured band for display purposes.
|
||||
assert is_integer(result.band_mhz)
|
||||
end
|
||||
|
||||
test "short-circuits at exactly 5760 MHz threshold" do
|
||||
above = RangeEstimate.estimate(beacon(frequency_mhz: 5760.0, power_mw: 1000.0))
|
||||
below = RangeEstimate.estimate(beacon(frequency_mhz: 5759.9, power_mw: 1000.0))
|
||||
assert above.cells != []
|
||||
assert below.cells == []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue