From 0d4314b88053d3ade47f5eac90746c3512266574 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 22 Mar 2026 15:19:45 -0500 Subject: [PATCH] Fix object positioning to use object name instead of origin callsign Objects and items were being displayed at the origin station's location instead of their actual coordinates because the broadcast used the sender (origin callsign) as the identifier instead of object_name/item_name. For example, object CALGRY sent by VE6RWB-15 was appearing at VE6RWB-15's location instead of CALGRY's actual coordinates. Changes: - Modified broadcast_single_packet to use object_name for objects and item_name for items as the identifier instead of sender - Added tests verifying objects and items broadcast with correct identifier - Objects/items now display at their specified coordinates, not origin station Fixes the positioning bug where objects appeared at sender location. --- lib/aprsme/packet_consumer.ex | 11 +++- test/aprsme/packet_consumer_test.exs | 82 ++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/lib/aprsme/packet_consumer.ex b/lib/aprsme/packet_consumer.ex index 2cd09e4..28564d6 100644 --- a/lib/aprsme/packet_consumer.ex +++ b/lib/aprsme/packet_consumer.ex @@ -338,8 +338,17 @@ defmodule Aprsme.PacketConsumer do end defp broadcast_single_packet(packet_attrs, cluster_enabled) do + # For objects and items, use object_name/item_name as the identifier + # instead of sender (which is the origin station) + identifier = + cond do + packet_attrs[:object_name] -> packet_attrs[:object_name] + packet_attrs[:item_name] -> packet_attrs[:item_name] + true -> packet_attrs[:sender] + end + packet = %{ - sender: packet_attrs[:sender], + sender: identifier, latitude: packet_attrs[:lat], longitude: packet_attrs[:lon], received_at: packet_attrs[:received_at], diff --git a/test/aprsme/packet_consumer_test.exs b/test/aprsme/packet_consumer_test.exs index 630549b..d32895f 100644 --- a/test/aprsme/packet_consumer_test.exs +++ b/test/aprsme/packet_consumer_test.exs @@ -7,6 +7,88 @@ defmodule Aprsme.PacketConsumerTest do alias Aprsme.PacketConsumer alias Aprsme.StreamingPacketsPubSub + describe "object broadcast with correct identifier" do + test "broadcasts object packets using object_name instead of sender" do + # Subscribe to packets in test bounds + bounds = %{north: 52.0, south: 50.0, east: -113.0, west: -115.0} + StreamingPacketsPubSub.subscribe_to_bounds(self(), bounds) + + # Object packet - sender is VE6RWB-15, object name is CALGRY + events = [ + %{ + sender: "VE6RWB-15", + lat: 51.044733, + lon: -114.062019, + data_type: "object", + destination: "APRS", + path: "TCPIP*,qAC,T2ROMANIA", + object_name: "CALGRY", + information_field: ";CALGRY *111111z5102.68N/11403.72W-", + raw_packet: "VE6RWB-15>APRS,TCPIP*,qAC,T2ROMANIA:;CALGRY *111111z5102.68N/11403.72W-" + } + ] + + state = %{ + batch: [], + batch_length: 0, + batch_size: 1, + batch_timeout: 1000, + max_batch_size: 100, + timer: nil + } + + PacketConsumer.handle_events(events, nil, state) + # Wait for async broadcast task to complete + Process.sleep(50) + + # Should receive the packet via PubSub with object_name as sender + assert_receive {:streaming_packet, packet}, 1000 + assert packet.sender == "CALGRY", "Expected sender to be object name CALGRY, got #{packet.sender}" + assert packet.latitude == 51.044733 + assert packet.longitude == -114.062019 + end + + test "broadcasts item packets using item_name instead of sender" do + # Subscribe to packets in test bounds + bounds = %{north: 40.0, south: 30.0, east: -70.0, west: -80.0} + StreamingPacketsPubSub.subscribe_to_bounds(self(), bounds) + + # Item packet - sender is ITEMTEST, item name is MyItem + events = [ + %{ + sender: "ITEMTEST", + lat: 35.0, + lon: -75.0, + data_type: "item", + destination: "APRS", + path: "WIDE1-1", + item_name: "MyItem", + information_field: ")MyItem!3500.00N/07500.00W-Test item", + raw_packet: "ITEMTEST>APRS,WIDE1-1:)MyItem!3500.00N/07500.00W-Test item" + } + ] + + state = %{ + batch: [], + batch_length: 0, + batch_size: 1, + batch_timeout: 1000, + max_batch_size: 100, + timer: nil + } + + PacketConsumer.handle_events(events, nil, state) + # Wait for async broadcast task to complete + Process.sleep(50) + + # Should receive the packet via PubSub with item_name as sender + assert_receive {:streaming_packet, packet}, 1000 + assert packet.sender == "MyItem", "Expected sender to be item name MyItem, got #{packet.sender}" + assert packet.latitude == 35.0 + assert packet.longitude == -75.0 + end + end + describe "object name extraction" do test "extracts object name with hyphens from information_field" do events = [