fix(coverage): production show-page crash and stale device on PubSub refresh
- show.html.heex: `@coverage.device_id and ...` raised BadBooleanError in production because device_id is a UUID string, not a boolean. Use is_nil/1 checks instead. - show.ex: handle_info/2 was reloading the coverage without preloading :device, so the device row vanished from the UI on every status broadcast. Preload :device alongside the reload. - coverage_worker: thread the precomputed tx_height through the pixel loop instead of re-deriving `coverage.height_agl_m + ...` per pixel with inconsistent nil-safety vs. compute_pixels/6.
This commit is contained in:
parent
3273312f6a
commit
ef4a4c99b5
3 changed files with 15 additions and 20 deletions
|
|
@ -140,18 +140,11 @@ defmodule Towerops.Workers.CoverageWorker do
|
|||
fn r ->
|
||||
row_lat = max_lat - (r + 0.5) * cell_lat
|
||||
|
||||
tx = {{lat, lon}, tx_z, tx_height}
|
||||
|
||||
for c <- 0..(ncols - 1) do
|
||||
pixel_lon = min_lon + (c + 0.5) * cell_lon
|
||||
|
||||
compute_pixel(
|
||||
coverage,
|
||||
antenna,
|
||||
{lat, lon},
|
||||
tx_z,
|
||||
{row_lat, pixel_lon},
|
||||
grid,
|
||||
eirp
|
||||
)
|
||||
compute_pixel(coverage, antenna, tx, {row_lat, pixel_lon}, grid, eirp)
|
||||
end
|
||||
end,
|
||||
ordered: true,
|
||||
|
|
@ -173,7 +166,7 @@ defmodule Towerops.Workers.CoverageWorker do
|
|||
}}
|
||||
end
|
||||
|
||||
defp compute_pixel(coverage, antenna, tx_latlon, tx_z, rx_latlon, grid, eirp) do
|
||||
defp compute_pixel(coverage, antenna, {tx_latlon, _tx_z, _tx_height} = tx, rx_latlon, grid, eirp) do
|
||||
distance_m = Profile.great_circle_distance_m(tx_latlon, rx_latlon)
|
||||
|
||||
cond do
|
||||
|
|
@ -184,15 +177,14 @@ defmodule Towerops.Workers.CoverageWorker do
|
|||
:nan
|
||||
|
||||
true ->
|
||||
do_compute_pixel(coverage, antenna, tx_latlon, tx_z, rx_latlon, grid, eirp, distance_m)
|
||||
do_compute_pixel(coverage, antenna, tx, rx_latlon, grid, eirp, distance_m)
|
||||
end
|
||||
end
|
||||
|
||||
defp do_compute_pixel(
|
||||
coverage,
|
||||
antenna,
|
||||
{tx_lat, tx_lon} = tx_latlon,
|
||||
tx_z,
|
||||
{{tx_lat, tx_lon} = tx_latlon, tx_z, tx_height},
|
||||
{rx_lat, rx_lon} = rx_latlon,
|
||||
grid,
|
||||
eirp,
|
||||
|
|
@ -202,10 +194,10 @@ defmodule Towerops.Workers.CoverageWorker do
|
|||
samples = max(3, min(@profile_samples, ceil(distance_m / coverage.cell_size_m) + 2))
|
||||
profile = Profile.sample(grid, tx_latlon, rx_latlon, samples)
|
||||
|
||||
# Replace TX endpoint with the absolute Z (so diffraction sees the correct
|
||||
# antenna height). The receiver height is added inside Propagation.
|
||||
# Replace TX endpoint with the ground elevation under the antenna (so the
|
||||
# path loss model sees the correct antenna height above terrain).
|
||||
[_old_first | rest] = profile
|
||||
profile = [tx_z - (coverage.height_agl_m + (coverage.height_above_rooftop_m || 0.0)) | rest]
|
||||
profile = [tx_z - tx_height | rest]
|
||||
|
||||
# 2. Antenna pattern attenuation at this bearing/elevation.
|
||||
bearing_offset = bearing_offset_deg(tx_lat, tx_lon, rx_lat, rx_lon, coverage.azimuth_deg)
|
||||
|
|
@ -218,7 +210,7 @@ defmodule Towerops.Workers.CoverageWorker do
|
|||
distance_m,
|
||||
coverage.frequency_mhz * 1.0,
|
||||
profile,
|
||||
coverage.height_agl_m + (coverage.height_above_rooftop_m || 0.0),
|
||||
tx_height,
|
||||
coverage.receiver_height_m || 3.0
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ defmodule ToweropsWeb.CoverageLive.Show do
|
|||
@impl true
|
||||
def handle_info({:coverage_status, _status, _extra}, socket) do
|
||||
coverage =
|
||||
Coverages.get_coverage!(socket.assigns.organization.id, socket.assigns.coverage.id)
|
||||
socket.assigns.organization.id
|
||||
|> Coverages.get_coverage!(socket.assigns.coverage.id)
|
||||
|> Towerops.Repo.preload(:device)
|
||||
|
||||
eirp =
|
||||
Coverage.eirp_dbm(
|
||||
|
|
|
|||
|
|
@ -199,7 +199,8 @@
|
|||
/>
|
||||
<.param_row
|
||||
:if={
|
||||
@coverage.device_id and Ecto.assoc_loaded?(@coverage.device) and @coverage.device
|
||||
not is_nil(@coverage.device_id) and Ecto.assoc_loaded?(@coverage.device) and
|
||||
not is_nil(@coverage.device)
|
||||
}
|
||||
label={t("Device")}
|
||||
value={@coverage.device.name || @coverage.device.ip_address}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue