historical data selection
This commit is contained in:
parent
a4547f4b75
commit
8446303399
1 changed files with 58 additions and 23 deletions
|
|
@ -211,13 +211,29 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("update_trail_duration", %{"target" => %{"value" => duration}}, socket) do
|
def handle_event("update_trail_duration", %{"trail_duration" => duration}, socket) do
|
||||||
{:noreply, assign(socket, trail_duration: duration)}
|
# Convert duration string to hours and calculate new threshold
|
||||||
|
hours = String.to_integer(duration)
|
||||||
|
new_threshold = DateTime.add(DateTime.utc_now(), -hours * 3600, :second)
|
||||||
|
|
||||||
|
socket = assign(socket, trail_duration: duration, packet_age_threshold: new_threshold)
|
||||||
|
|
||||||
|
# Trigger cleanup to remove packets that are now outside the new duration
|
||||||
|
send(self(), :cleanup_old_packets)
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("update_historical_hours", %{"target" => %{"value" => hours}}, socket) do
|
def handle_event("update_historical_hours", %{"historical_hours" => hours}, socket) do
|
||||||
{:noreply, assign(socket, historical_hours: hours)}
|
socket = assign(socket, historical_hours: hours)
|
||||||
|
|
||||||
|
# Trigger a reload of historical packets with the new time range
|
||||||
|
if socket.assigns.map_ready do
|
||||||
|
send(self(), :reload_historical_packets)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|
@ -312,6 +328,8 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
|
|
||||||
def handle_info(:cleanup_old_packets, socket), do: handle_cleanup_old_packets(socket)
|
def handle_info(:cleanup_old_packets, socket), do: handle_cleanup_old_packets(socket)
|
||||||
|
|
||||||
|
def handle_info(:reload_historical_packets, socket), do: handle_reload_historical_packets(socket)
|
||||||
|
|
||||||
def handle_info({:postgres_packet, packet}, socket), do: handle_info_postgres_packet(packet, socket)
|
def handle_info({:postgres_packet, packet}, socket), do: handle_info_postgres_packet(packet, socket)
|
||||||
|
|
||||||
def handle_info(%Phoenix.Socket.Broadcast{topic: "aprs_messages", event: "packet", payload: packet}, socket),
|
def handle_info(%Phoenix.Socket.Broadcast{topic: "aprs_messages", event: "packet", payload: packet}, socket),
|
||||||
|
|
@ -631,9 +649,9 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
</svg>
|
</svg>
|
||||||
<span>Trail Duration</span>
|
<span>Trail Duration</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="relative">
|
<form phx-change="update_trail_duration" class="relative">
|
||||||
<select
|
<select
|
||||||
phx-change="update_trail_duration"
|
name="trail_duration"
|
||||||
class="w-full px-4 py-3 border border-slate-300 rounded-xl shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm bg-white appearance-none transition-all duration-200 hover:border-slate-400"
|
class="w-full px-4 py-3 border border-slate-300 rounded-xl shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm bg-white appearance-none transition-all duration-200 hover:border-slate-400"
|
||||||
>
|
>
|
||||||
<option value="1" selected={@trail_duration == "1"}>1 Hour</option>
|
<option value="1" selected={@trail_duration == "1"}>1 Hour</option>
|
||||||
|
|
@ -658,7 +676,7 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
<p class="text-xs text-slate-500 flex items-center space-x-1">
|
<p class="text-xs text-slate-500 flex items-center space-x-1">
|
||||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
|
|
@ -685,9 +703,9 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
</svg>
|
</svg>
|
||||||
<span>Historical Data</span>
|
<span>Historical Data</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="relative">
|
<form phx-change="update_historical_hours" class="relative">
|
||||||
<select
|
<select
|
||||||
phx-change="update_historical_hours"
|
name="historical_hours"
|
||||||
class="w-full px-4 py-3 border border-slate-300 rounded-xl shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm bg-white appearance-none transition-all duration-200 hover:border-slate-400"
|
class="w-full px-4 py-3 border border-slate-300 rounded-xl shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm bg-white appearance-none transition-all duration-200 hover:border-slate-400"
|
||||||
>
|
>
|
||||||
<option value="1" selected={@historical_hours == "1"}>1 Hour</option>
|
<option value="1" selected={@historical_hours == "1"}>1 Hour</option>
|
||||||
|
|
@ -711,7 +729,7 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
<p class="text-xs text-slate-500 flex items-center space-x-1">
|
<p class="text-xs text-slate-500 flex items-center space-x-1">
|
||||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
|
|
@ -734,12 +752,14 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
# Schedule next cleanup
|
# Schedule next cleanup
|
||||||
Process.send_after(self(), :cleanup_old_packets, 60_000)
|
Process.send_after(self(), :cleanup_old_packets, 60_000)
|
||||||
|
|
||||||
one_hour_ago = DateTime.add(DateTime.utc_now(), -3600, :second)
|
# Use the current packet_age_threshold instead of hardcoded one hour
|
||||||
|
threshold = socket.assigns.packet_age_threshold
|
||||||
|
|
||||||
# Remove expired packets from visible_packets
|
# Remove expired packets from visible_packets
|
||||||
expired_keys =
|
expired_keys =
|
||||||
socket.assigns.visible_packets
|
socket.assigns.visible_packets
|
||||||
|> Enum.filter(fn {_key, packet} ->
|
|> Enum.filter(fn {_key, packet} ->
|
||||||
not packet_within_time_threshold?(packet, one_hour_ago)
|
not packet_within_time_threshold?(packet, threshold)
|
||||||
end)
|
end)
|
||||||
|> Enum.map(fn {key, _} -> key end)
|
|> Enum.map(fn {key, _} -> key end)
|
||||||
|
|
||||||
|
|
@ -758,6 +778,23 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
{:noreply, assign(socket, visible_packets: updated_visible_packets)}
|
{:noreply, assign(socket, visible_packets: updated_visible_packets)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp handle_reload_historical_packets(socket) do
|
||||||
|
if socket.assigns.map_ready and socket.assigns.map_bounds do
|
||||||
|
# Clear existing historical packets
|
||||||
|
socket = assign(socket, historical_packets: %{})
|
||||||
|
|
||||||
|
# Clear all markers on the client
|
||||||
|
socket = push_event(socket, "clear_all_markers", %{})
|
||||||
|
|
||||||
|
# Load historical packets with new time range
|
||||||
|
socket = load_historical_packets_for_bounds(socket, socket.assigns.map_bounds)
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
else
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Check if a packet is within the time threshold (not too old)
|
# Check if a packet is within the time threshold (not too old)
|
||||||
@spec packet_within_time_threshold?(map(), DateTime.t()) :: boolean()
|
@spec packet_within_time_threshold?(map(), DateTime.t()) :: boolean()
|
||||||
defp packet_within_time_threshold?(packet, threshold) do
|
defp packet_within_time_threshold?(packet, threshold) do
|
||||||
|
|
@ -781,7 +818,9 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
if socket.assigns.map_ready do
|
if socket.assigns.map_ready do
|
||||||
# Get time range for historical data
|
# Get time range for historical data
|
||||||
now = DateTime.utc_now()
|
now = DateTime.utc_now()
|
||||||
one_hour_ago = DateTime.add(now, -60 * 60, :second)
|
# Use the user's selected historical hours setting
|
||||||
|
historical_hours = String.to_integer(socket.assigns.historical_hours)
|
||||||
|
start_time = DateTime.add(now, -historical_hours * 3600, :second)
|
||||||
|
|
||||||
# Convert map bounds to the format expected by the database query
|
# Convert map bounds to the format expected by the database query
|
||||||
bounds = [
|
bounds = [
|
||||||
|
|
@ -792,7 +831,7 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
]
|
]
|
||||||
|
|
||||||
# Fetch historical packets with position data within the current map bounds
|
# Fetch historical packets with position data within the current map bounds
|
||||||
historical_packets = fetch_historical_packets(bounds, one_hour_ago, now)
|
historical_packets = fetch_historical_packets(bounds, start_time, now)
|
||||||
|
|
||||||
if Enum.empty?(historical_packets) do
|
if Enum.empty?(historical_packets) do
|
||||||
# No historical packets found - silently continue
|
# No historical packets found - silently continue
|
||||||
|
|
@ -927,13 +966,7 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
# Fetch historical packets from the database
|
# Fetch historical packets from the database
|
||||||
@spec fetch_historical_packets(list(), DateTime.t(), DateTime.t()) :: [struct()]
|
@spec fetch_historical_packets(list(), DateTime.t(), DateTime.t()) :: [struct()]
|
||||||
defp fetch_historical_packets(bounds, start_time, end_time) do
|
defp fetch_historical_packets(bounds, start_time, end_time) do
|
||||||
# Force start_time to be at most 1 hour ago
|
effective_start_time = start_time
|
||||||
one_hour_ago = DateTime.add(DateTime.utc_now(), -3600, :second)
|
|
||||||
|
|
||||||
effective_start_time =
|
|
||||||
if DateTime.before?(start_time, one_hour_ago),
|
|
||||||
do: one_hour_ago,
|
|
||||||
else: start_time
|
|
||||||
|
|
||||||
# Use the Packets context to retrieve historical packets
|
# Use the Packets context to retrieve historical packets
|
||||||
packets_params = %{
|
packets_params = %{
|
||||||
|
|
@ -957,7 +990,9 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
defp load_historical_packets_for_bounds(socket, map_bounds) do
|
defp load_historical_packets_for_bounds(socket, map_bounds) do
|
||||||
# Get time range for historical data
|
# Get time range for historical data
|
||||||
now = DateTime.utc_now()
|
now = DateTime.utc_now()
|
||||||
one_hour_ago = DateTime.add(now, -60 * 60, :second)
|
# Use the user's selected historical hours setting
|
||||||
|
historical_hours = String.to_integer(socket.assigns.historical_hours)
|
||||||
|
start_time = DateTime.add(now, -historical_hours * 3600, :second)
|
||||||
|
|
||||||
# Convert map bounds to the format expected by the database query
|
# Convert map bounds to the format expected by the database query
|
||||||
bounds = [
|
bounds = [
|
||||||
|
|
@ -968,7 +1003,7 @@ defmodule AprsWeb.MapLive.Index do
|
||||||
]
|
]
|
||||||
|
|
||||||
# Fetch historical packets with position data within the current map bounds
|
# Fetch historical packets with position data within the current map bounds
|
||||||
historical_packets = fetch_historical_packets(bounds, one_hour_ago, now)
|
historical_packets = fetch_historical_packets(bounds, start_time, now)
|
||||||
|
|
||||||
if Enum.empty?(historical_packets) do
|
if Enum.empty?(historical_packets) do
|
||||||
# No historical packets found
|
# No historical packets found
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue