clean up status page
This commit is contained in:
parent
400e444eaa
commit
534bd8df8a
4 changed files with 112 additions and 26 deletions
|
|
@ -133,7 +133,8 @@ defmodule Aprsme.Is do
|
|||
login_id: Application.get_env(:aprsme, :aprsme_is_login_id, "W5ISP"),
|
||||
filter: Application.get_env(:aprsme, :aprsme_is_default_filter, "r/33/-96/100"),
|
||||
packet_stats: default_packet_stats(),
|
||||
stored_packet_count: Aprsme.Packets.get_total_packet_count()
|
||||
stored_packet_count: Aprsme.Packets.get_total_packet_count(),
|
||||
oldest_packet_timestamp: Aprsme.Packets.get_oldest_packet_timestamp()
|
||||
}
|
||||
|
||||
_pid ->
|
||||
|
|
@ -154,7 +155,8 @@ defmodule Aprsme.Is do
|
|||
login_id: Application.get_env(:aprsme, :aprsme_is_login_id, "W5ISP"),
|
||||
filter: Application.get_env(:aprsme, :aprsme_is_default_filter, "r/33/-96/100"),
|
||||
packet_stats: default_packet_stats(),
|
||||
stored_packet_count: Aprsme.Packets.get_total_packet_count()
|
||||
stored_packet_count: Aprsme.Packets.get_total_packet_count(),
|
||||
oldest_packet_timestamp: Aprsme.Packets.get_oldest_packet_timestamp()
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -259,7 +261,8 @@ defmodule Aprsme.Is do
|
|||
login_id: state.login_params.user_id,
|
||||
filter: state.login_params.filter,
|
||||
packet_stats: state.packet_stats,
|
||||
stored_packet_count: Aprsme.Packets.get_total_packet_count()
|
||||
stored_packet_count: Aprsme.Packets.get_total_packet_count(),
|
||||
oldest_packet_timestamp: Aprsme.Packets.get_oldest_packet_timestamp()
|
||||
}
|
||||
|
||||
{:reply, status, state}
|
||||
|
|
|
|||
|
|
@ -638,6 +638,18 @@ defmodule Aprsme.Packets do
|
|||
0
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the timestamp of the oldest stored packet in the database.
|
||||
Returns nil if no packets exist.
|
||||
"""
|
||||
@spec get_oldest_packet_timestamp() :: DateTime.t() | nil
|
||||
def get_oldest_packet_timestamp do
|
||||
Repo.one(
|
||||
from p in Packet,
|
||||
select: min(p.received_at)
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Configure packet retention policy.
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
assign(socket,
|
||||
page_title: "System Status",
|
||||
aprs_status: aprs_status,
|
||||
version: get_app_version(),
|
||||
current_time: DateTime.utc_now(),
|
||||
health_score: calculate_health_score(aprs_status),
|
||||
loading: false
|
||||
|
|
@ -83,23 +82,7 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
<span class="font-mono">{Calendar.strftime(@current_time, "%H:%M:%S UTC")}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Application Information -->
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4">{gettext("Application Information")}</h2>
|
||||
<div class="card bg-base-200">
|
||||
<div class="card-body">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="flex items-center">
|
||||
<span class="text-sm font-medium opacity-70 mr-2">{gettext("Version:")}</span>
|
||||
<span class="text-sm font-mono">{@version}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Overall Status Alert -->
|
||||
<!-- Overall Status Alert -->
|
||||
<%= if not @aprs_status.connected do %>
|
||||
<div class="alert alert-error mb-6">
|
||||
<svg
|
||||
|
|
@ -244,6 +227,29 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
<div class="flex items-center">
|
||||
<span class="text-sm font-medium opacity-70 mr-2">
|
||||
{gettext("Oldest Packet:")}
|
||||
</span>
|
||||
<span class="text-sm">
|
||||
<%= if @aprs_status[:oldest_packet_timestamp] do %>
|
||||
<span class="font-mono">
|
||||
{Calendar.strftime(
|
||||
@aprs_status.oldest_packet_timestamp,
|
||||
"%Y-%m-%d %H:%M:%S UTC"
|
||||
)}
|
||||
</span>
|
||||
<span class="opacity-70">
|
||||
({format_time_ago(@aprs_status.oldest_packet_timestamp)})
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="opacity-50">{gettext("No packets stored")}</span>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Health Score -->
|
||||
|
|
@ -320,14 +326,11 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
packets_per_second: 0,
|
||||
last_packet_at: nil
|
||||
},
|
||||
stored_packet_count: 0
|
||||
stored_packet_count: 0,
|
||||
oldest_packet_timestamp: nil
|
||||
}
|
||||
end
|
||||
|
||||
defp get_app_version do
|
||||
:aprsme |> Application.spec(:vsn) |> List.to_string()
|
||||
end
|
||||
|
||||
defp schedule_refresh do
|
||||
Process.send_after(self(), :refresh_status, @refresh_interval)
|
||||
end
|
||||
|
|
@ -373,6 +376,8 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
end
|
||||
end
|
||||
|
||||
def format_time_ago(nil), do: gettext("Never")
|
||||
|
||||
def format_time_ago(datetime) do
|
||||
diff_seconds = DateTime.diff(DateTime.utc_now(), datetime)
|
||||
|
||||
|
|
|
|||
66
test/aprsme/packets_oldest_test.exs
Normal file
66
test/aprsme/packets_oldest_test.exs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
defmodule Aprsme.PacketsOldestTest do
|
||||
use Aprsme.DataCase
|
||||
|
||||
alias Aprsme.Packets
|
||||
alias Aprsme.Repo
|
||||
|
||||
describe "get_oldest_packet_timestamp/0" do
|
||||
test "returns nil when no packets exist" do
|
||||
assert is_nil(Packets.get_oldest_packet_timestamp())
|
||||
end
|
||||
|
||||
test "returns the timestamp of the oldest packet" do
|
||||
# Create packets with different timestamps
|
||||
oldest_time = ~U[2023-01-01 00:00:00Z]
|
||||
middle_time = ~U[2023-06-15 12:30:00Z]
|
||||
newest_time = ~U[2023-12-31 23:59:59Z]
|
||||
|
||||
# Insert packets with different timestamps
|
||||
{:ok, _} = create_test_packet("OLD-1", oldest_time)
|
||||
{:ok, _} = create_test_packet("MID-1", middle_time)
|
||||
{:ok, _} = create_test_packet("NEW-1", newest_time)
|
||||
|
||||
# Should return the oldest timestamp
|
||||
assert Packets.get_oldest_packet_timestamp() == oldest_time
|
||||
end
|
||||
|
||||
test "handles packets with microsecond precision" do
|
||||
# Create a packet with microsecond precision
|
||||
timestamp_with_microseconds = ~U[2023-07-15 14:30:45.123456Z]
|
||||
{:ok, _} = create_test_packet("TEST-1", timestamp_with_microseconds)
|
||||
|
||||
result = Packets.get_oldest_packet_timestamp()
|
||||
# Database might truncate microseconds, so we check the timestamp is close
|
||||
assert DateTime.diff(result, timestamp_with_microseconds, :microsecond) < 1000
|
||||
end
|
||||
end
|
||||
|
||||
# Helper function to create a test packet with specific timestamp
|
||||
defp create_test_packet(callsign, received_at) do
|
||||
# Extract SSID from callsign (e.g., "TEST-1" -> ssid = "1")
|
||||
{base_callsign, ssid} =
|
||||
case String.split(callsign, "-", parts: 2) do
|
||||
[base] -> {base, "0"}
|
||||
[base, ssid_part] -> {base, ssid_part}
|
||||
end
|
||||
|
||||
packet_data = %{
|
||||
sender: callsign,
|
||||
base_callsign: base_callsign,
|
||||
ssid: ssid,
|
||||
destination: "APRS",
|
||||
data_type: "position",
|
||||
path: "WIDE1-1",
|
||||
information_field: "!3216.46N/09647.82W>Test packet",
|
||||
raw_packet: "#{callsign}>APRS,WIDE1-1:!3216.46N/09647.82W>Test packet",
|
||||
lat: 32.274333,
|
||||
lon: -96.797,
|
||||
has_position: true,
|
||||
received_at: received_at
|
||||
}
|
||||
|
||||
%Aprsme.Packet{}
|
||||
|> Aprsme.Packet.changeset(packet_data)
|
||||
|> Repo.insert()
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue