aprs.me/lib/aprs/packet.ex
2025-06-15 21:14:10 -05:00

90 lines
2.2 KiB
Elixir

defmodule Aprs.Packet do
@moduledoc false
use Aprs.Schema
import Ecto.Changeset
alias Aprs.DataExtended
schema "packets" do
field(:base_callsign, :string)
field(:data_type, :string)
field(:destination, :string)
field(:information_field, :string)
field(:path, :string)
field(:sender, :string)
field(:ssid, :string)
field(:received_at, :utc_datetime_usec)
field(:region, :string)
field(:lat, :float)
field(:lon, :float)
field(:has_position, :boolean, default: false)
embeds_one(:data_extended, DataExtended)
timestamps()
end
@doc false
def changeset(packet, attrs) do
# Convert atom data_type to string
attrs = normalize_data_type(attrs)
packet
|> cast(attrs, [
:base_callsign,
:data_type,
:destination,
:information_field,
:path,
:sender,
:ssid,
:received_at,
:region,
:lat,
:lon,
:has_position
])
|> validate_required([
:base_callsign,
:data_type,
:destination,
:information_field,
:path,
:sender,
:ssid,
:received_at
])
|> maybe_set_has_position()
end
defp maybe_set_has_position(changeset) do
if (get_field(changeset, :lat) && get_field(changeset, :lon)) ||
(get_change(changeset, :data_extended) &&
get_change(changeset, :data_extended).latitude &&
get_change(changeset, :data_extended).longitude) do
put_change(changeset, :has_position, true)
else
changeset
end
end
# Convert atom data_type to string for storage
defp normalize_data_type(%{data_type: data_type} = attrs) when is_atom(data_type) do
%{attrs | data_type: to_string(data_type)}
end
defp normalize_data_type(%{"data_type" => data_type} = attrs) when is_atom(data_type) do
%{attrs | "data_type" => to_string(data_type)}
end
# Handle :data_type key access format
defp normalize_data_type(attrs) when is_map(attrs) do
if Map.has_key?(attrs, :data_type) and is_atom(attrs.data_type) do
%{attrs | data_type: to_string(attrs.data_type)}
else
attrs
end
end
defp normalize_data_type(attrs), do: attrs
end