Enhance info page live updates with comprehensive packet data
Update PostgreSQL notify trigger to send ALL packet fields including: - Device information (model, vendor, contact, class) - Weather data fields for weather-enabled stations - SSID and base_callsign for proper SSID grouping - data_type for packet type identification Also added debug logging to verify live updates are working correctly. This ensures the info page displays complete, real-time information for all sections including position, device info, nearby stations, and raw packet data. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8c84706c6b
commit
29a811adf2
3 changed files with 128 additions and 2 deletions
|
|
@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Fixed
|
### Fixed
|
||||||
- PostgreSQL notify trigger now sends all required fields for info page updates
|
- PostgreSQL notify trigger now sends all required fields for info page updates
|
||||||
- Info page real-time updates now display all packet details correctly
|
- Info page real-time updates now display all packet details correctly
|
||||||
|
- Enhanced PostgreSQL notify to include complete packet data (device info, weather data, SSIDs, etc.)
|
||||||
|
|
||||||
## [0.2.0] - 2025-07-26
|
## [0.2.0] - 2025-07-26
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,13 +53,21 @@ defmodule AprsmeWeb.InfoLive.Show do
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:postgres_packet, packet}, socket) do
|
def handle_info({:postgres_packet, packet}, socket) do
|
||||||
# Since we're subscribed to callsign-specific topic, no need to filter
|
# Since we're subscribed to callsign-specific topic, no need to filter
|
||||||
|
# The packet from PostgreSQL notify already contains all fields
|
||||||
process_packet_update(packet, socket)
|
process_packet_update(packet, socket)
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_info(_message, socket), do: {:noreply, socket}
|
def handle_info(_message, socket), do: {:noreply, socket}
|
||||||
|
|
||||||
defp process_packet_update(_incoming_packet, socket) do
|
defp process_packet_update(incoming_packet, socket) do
|
||||||
# Refresh data when new packet arrives
|
# Log for debugging
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
Logger.debug(
|
||||||
|
"InfoLive received packet update for #{socket.assigns.callsign}: #{inspect(Map.get(incoming_packet, "raw_packet"))}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Refresh all data when new packet arrives
|
||||||
packet = get_latest_packet(socket.assigns.callsign)
|
packet = get_latest_packet(socket.assigns.callsign)
|
||||||
packet = if packet, do: SharedPacketHandler.enrich_with_device_info(packet)
|
packet = if packet, do: SharedPacketHandler.enrich_with_device_info(packet)
|
||||||
# Get locale from socket assigns
|
# Get locale from socket assigns
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
defmodule Aprsme.Repo.Migrations.AddMissingFieldsToPacketNotify do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
# Drop existing trigger and function
|
||||||
|
execute "DROP TRIGGER IF EXISTS packets_notify_insert ON packets;"
|
||||||
|
execute "DROP FUNCTION IF EXISTS notify_packets_insert();"
|
||||||
|
|
||||||
|
# Create updated function that includes ALL fields that might be needed
|
||||||
|
execute """
|
||||||
|
CREATE OR REPLACE FUNCTION notify_packets_insert() RETURNS trigger AS $$
|
||||||
|
DECLARE
|
||||||
|
payload TEXT;
|
||||||
|
BEGIN
|
||||||
|
-- Build a comprehensive payload with all packet fields
|
||||||
|
payload := json_build_object(
|
||||||
|
'id', NEW.id,
|
||||||
|
'sender', NEW.sender,
|
||||||
|
'ssid', NEW.ssid,
|
||||||
|
'base_callsign', NEW.base_callsign,
|
||||||
|
'lat', NEW.lat,
|
||||||
|
'lon', NEW.lon,
|
||||||
|
'altitude', NEW.altitude,
|
||||||
|
'course', NEW.course,
|
||||||
|
'speed', NEW.speed,
|
||||||
|
'symbol_table_id', NEW.symbol_table_id,
|
||||||
|
'symbol_code', NEW.symbol_code,
|
||||||
|
'device_identifier', NEW.device_identifier,
|
||||||
|
'device_model', NEW.device_model,
|
||||||
|
'device_vendor', NEW.device_vendor,
|
||||||
|
'device_contact', NEW.device_contact,
|
||||||
|
'device_class', NEW.device_class,
|
||||||
|
'path', NEW.path,
|
||||||
|
'data_type', NEW.data_type,
|
||||||
|
'received_at', NEW.received_at,
|
||||||
|
'comment', NEW.comment,
|
||||||
|
'raw_packet', NEW.raw_packet,
|
||||||
|
'phg_power', NEW.phg_power,
|
||||||
|
'phg_height', NEW.phg_height,
|
||||||
|
'phg_gain', NEW.phg_gain,
|
||||||
|
'phg_directivity', NEW.phg_directivity,
|
||||||
|
'temperature', NEW.temperature,
|
||||||
|
'humidity', NEW.humidity,
|
||||||
|
'pressure', NEW.pressure,
|
||||||
|
'wind_speed', NEW.wind_speed,
|
||||||
|
'wind_direction', NEW.wind_direction,
|
||||||
|
'wind_gust', NEW.wind_gust,
|
||||||
|
'rain_1h', NEW.rain_1h,
|
||||||
|
'rain_24h', NEW.rain_24h,
|
||||||
|
'rain_midnight', NEW.rain_midnight,
|
||||||
|
'luminosity', NEW.luminosity,
|
||||||
|
'snow_24h', NEW.snow_24h,
|
||||||
|
'has_weather', NEW.has_weather,
|
||||||
|
'inserted_at', NEW.inserted_at
|
||||||
|
)::text;
|
||||||
|
|
||||||
|
-- Notify on the aprs_packets channel
|
||||||
|
PERFORM pg_notify('aprs_packets', payload);
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Recreate trigger
|
||||||
|
execute """
|
||||||
|
CREATE TRIGGER packets_notify_insert
|
||||||
|
AFTER INSERT ON packets
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION notify_packets_insert();
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
# Drop updated trigger and function
|
||||||
|
execute "DROP TRIGGER IF EXISTS packets_notify_insert ON packets;"
|
||||||
|
execute "DROP FUNCTION IF EXISTS notify_packets_insert();"
|
||||||
|
|
||||||
|
# Restore previous version
|
||||||
|
execute """
|
||||||
|
CREATE OR REPLACE FUNCTION notify_packets_insert() RETURNS trigger AS $$
|
||||||
|
DECLARE
|
||||||
|
payload TEXT;
|
||||||
|
BEGIN
|
||||||
|
payload := json_build_object(
|
||||||
|
'id', NEW.id,
|
||||||
|
'sender', NEW.sender,
|
||||||
|
'lat', NEW.lat,
|
||||||
|
'lon', NEW.lon,
|
||||||
|
'altitude', NEW.altitude,
|
||||||
|
'course', NEW.course,
|
||||||
|
'speed', NEW.speed,
|
||||||
|
'symbol_table_id', NEW.symbol_table_id,
|
||||||
|
'symbol_code', NEW.symbol_code,
|
||||||
|
'device_identifier', NEW.device_identifier,
|
||||||
|
'path', NEW.path,
|
||||||
|
'received_at', NEW.received_at,
|
||||||
|
'comment', NEW.comment,
|
||||||
|
'raw_packet', NEW.raw_packet,
|
||||||
|
'phg_power', NEW.phg_power,
|
||||||
|
'phg_height', NEW.phg_height,
|
||||||
|
'phg_gain', NEW.phg_gain,
|
||||||
|
'phg_directivity', NEW.phg_directivity,
|
||||||
|
'inserted_at', NEW.inserted_at
|
||||||
|
)::text;
|
||||||
|
PERFORM pg_notify('aprs_packets', payload);
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
"""
|
||||||
|
|
||||||
|
execute """
|
||||||
|
CREATE TRIGGER packets_notify_insert
|
||||||
|
AFTER INSERT ON packets
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION notify_packets_insert();
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Add table
Reference in a new issue