Add beacon keying field (on/off or FSK)
This commit is contained in:
parent
73112eb44b
commit
f5b5af171e
6 changed files with 65 additions and 2 deletions
|
|
@ -11,6 +11,10 @@ defmodule Microwaveprop.Beacons.Beacon do
|
||||||
|
|
||||||
alias Microwaveprop.Radio.Maidenhead
|
alias Microwaveprop.Radio.Maidenhead
|
||||||
|
|
||||||
|
@keyings ~w(on_off fsk)
|
||||||
|
|
||||||
|
def keyings, do: @keyings
|
||||||
|
|
||||||
@primary_key {:id, :binary_id, autogenerate: true}
|
@primary_key {:id, :binary_id, autogenerate: true}
|
||||||
@foreign_key_type :binary_id
|
@foreign_key_type :binary_id
|
||||||
schema "beacons" do
|
schema "beacons" do
|
||||||
|
|
@ -23,20 +27,32 @@ defmodule Microwaveprop.Beacons.Beacon do
|
||||||
field :height_ft, :float
|
field :height_ft, :float
|
||||||
field :on_the_air, :boolean, default: true
|
field :on_the_air, :boolean, default: true
|
||||||
field :approved, :boolean, default: false
|
field :approved, :boolean, default: false
|
||||||
|
field :keying, :string, default: "on_off"
|
||||||
field :user_id, :binary_id
|
field :user_id, :binary_id
|
||||||
|
|
||||||
timestamps(type: :utc_datetime)
|
timestamps(type: :utc_datetime)
|
||||||
end
|
end
|
||||||
|
|
||||||
@required_fields [:frequency_mhz, :callsign, :lat, :lon, :power_mw, :height_ft]
|
@required_fields [:frequency_mhz, :callsign, :lat, :lon, :power_mw, :height_ft, :keying]
|
||||||
|
|
||||||
def changeset(beacon, attrs) do
|
def changeset(beacon, attrs) do
|
||||||
beacon
|
beacon
|
||||||
|> cast(attrs, [:frequency_mhz, :callsign, :grid, :lat, :lon, :power_mw, :height_ft, :on_the_air])
|
|> cast(attrs, [
|
||||||
|
:frequency_mhz,
|
||||||
|
:callsign,
|
||||||
|
:grid,
|
||||||
|
:lat,
|
||||||
|
:lon,
|
||||||
|
:power_mw,
|
||||||
|
:height_ft,
|
||||||
|
:on_the_air,
|
||||||
|
:keying
|
||||||
|
])
|
||||||
|> update_change(:callsign, fn cs -> cs && String.upcase(String.trim(cs)) end)
|
|> update_change(:callsign, fn cs -> cs && String.upcase(String.trim(cs)) end)
|
||||||
|> maybe_fill_latlon()
|
|> maybe_fill_latlon()
|
||||||
|> maybe_fill_grid()
|
|> maybe_fill_grid()
|
||||||
|> validate_required(@required_fields)
|
|> validate_required(@required_fields)
|
||||||
|
|> validate_inclusion(:keying, @keyings)
|
||||||
|> validate_number(:frequency_mhz, greater_than: 0)
|
|> validate_number(:frequency_mhz, greater_than: 0)
|
||||||
|> validate_number(:power_mw, greater_than_or_equal_to: 0)
|
|> validate_number(:power_mw, greater_than_or_equal_to: 0)
|
||||||
|> validate_number(:height_ft, greater_than_or_equal_to: 0)
|
|> validate_number(:height_ft, greater_than_or_equal_to: 0)
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,13 @@ defmodule MicrowavepropWeb.BeaconLive.Form do
|
||||||
step="any"
|
step="any"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<.input
|
||||||
|
field={@form[:keying]}
|
||||||
|
type="select"
|
||||||
|
label="Keying"
|
||||||
|
options={[{"On/Off", "on_off"}, {"FSK", "fsk"}]}
|
||||||
|
required
|
||||||
|
/>
|
||||||
<.input field={@form[:on_the_air]} type="checkbox" label="On the air" />
|
<.input field={@form[:on_the_air]} type="checkbox" label="On the air" />
|
||||||
<footer>
|
<footer>
|
||||||
<.button phx-disable-with="Saving..." variant="primary">Save Beacon</.button>
|
<.button phx-disable-with="Saving..." variant="primary">Save Beacon</.button>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ defmodule MicrowavepropWeb.BeaconLive.Index do
|
||||||
<:col :let={{_id, beacon}} label="Lon">{beacon.lon}</:col>
|
<:col :let={{_id, beacon}} label="Lon">{beacon.lon}</:col>
|
||||||
<:col :let={{_id, beacon}} label="EIRP (mW)">{format_mw(beacon.power_mw)}</:col>
|
<:col :let={{_id, beacon}} label="EIRP (mW)">{format_mw(beacon.power_mw)}</:col>
|
||||||
<:col :let={{_id, beacon}} label="Height AGL (ft)">{beacon.height_ft}</:col>
|
<:col :let={{_id, beacon}} label="Height AGL (ft)">{beacon.height_ft}</:col>
|
||||||
|
<:col :let={{_id, beacon}} label="Keying">{keying_label(beacon.keying)}</:col>
|
||||||
<:col :let={{_id, beacon}} label="On air">
|
<:col :let={{_id, beacon}} label="On air">
|
||||||
<span class={["badge badge-sm", (beacon.on_the_air && "badge-success") || "badge-ghost"]}>
|
<span class={["badge badge-sm", (beacon.on_the_air && "badge-success") || "badge-ghost"]}>
|
||||||
{if beacon.on_the_air, do: "Yes", else: "No"}
|
{if beacon.on_the_air, do: "Yes", else: "No"}
|
||||||
|
|
@ -168,6 +169,10 @@ defmodule MicrowavepropWeb.BeaconLive.Index do
|
||||||
defp authenticated?(%{user: %{}}), do: true
|
defp authenticated?(%{user: %{}}), do: true
|
||||||
defp authenticated?(_), do: false
|
defp authenticated?(_), do: false
|
||||||
|
|
||||||
|
defp keying_label("on_off"), do: "On/Off"
|
||||||
|
defp keying_label("fsk"), do: "FSK"
|
||||||
|
defp keying_label(other), do: other
|
||||||
|
|
||||||
# Format a milliwatt power value without scientific notation.
|
# Format a milliwatt power value without scientific notation.
|
||||||
# Keeps up to 3 decimal places, drops trailing zeros.
|
# Keeps up to 3 decimal places, drops trailing zeros.
|
||||||
defp format_mw(nil), do: ""
|
defp format_mw(nil), do: ""
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
|
||||||
<:item title="Longitude">{@beacon.lon}</:item>
|
<:item title="Longitude">{@beacon.lon}</:item>
|
||||||
<:item title="TX power (EIRP) (mW)">{@beacon.power_mw}</:item>
|
<:item title="TX power (EIRP) (mW)">{@beacon.power_mw}</:item>
|
||||||
<:item title="Height above ground (ft)">{@beacon.height_ft}</:item>
|
<:item title="Height above ground (ft)">{@beacon.height_ft}</:item>
|
||||||
|
<:item title="Keying">{keying_label(@beacon.keying)}</:item>
|
||||||
<:item title="On the air">{if @beacon.on_the_air, do: "Yes", else: "No"}</:item>
|
<:item title="On the air">{if @beacon.on_the_air, do: "Yes", else: "No"}</:item>
|
||||||
</.list>
|
</.list>
|
||||||
</Layouts.app>
|
</Layouts.app>
|
||||||
|
|
@ -148,4 +149,8 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
|
||||||
|
|
||||||
defp admin?(%{user: %{is_admin: true}}), do: true
|
defp admin?(%{user: %{is_admin: true}}), do: true
|
||||||
defp admin?(_), do: false
|
defp admin?(_), do: false
|
||||||
|
|
||||||
|
defp keying_label("on_off"), do: "On/Off"
|
||||||
|
defp keying_label("fsk"), do: "FSK"
|
||||||
|
defp keying_label(other), do: other
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule Microwaveprop.Repo.Migrations.AddKeyingToBeacons do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:beacons) do
|
||||||
|
add :keying, :string, null: false, default: "on_off"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -135,6 +135,27 @@ defmodule Microwaveprop.BeaconsTest do
|
||||||
assert beacon.on_the_air == false
|
assert beacon.on_the_air == false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "defaults keying to on_off" do
|
||||||
|
user = user_fixture()
|
||||||
|
{:ok, beacon} = Beacons.create_beacon(user, valid_beacon_attrs())
|
||||||
|
assert beacon.keying == "on_off"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "accepts keying: fsk" do
|
||||||
|
user = user_fixture()
|
||||||
|
{:ok, beacon} = Beacons.create_beacon(user, valid_beacon_attrs(keying: "fsk"))
|
||||||
|
assert beacon.keying == "fsk"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "rejects an unknown keying" do
|
||||||
|
user = user_fixture()
|
||||||
|
|
||||||
|
assert {:error, changeset} =
|
||||||
|
Beacons.create_beacon(user, valid_beacon_attrs(keying: "cw"))
|
||||||
|
|
||||||
|
assert "is invalid" in errors_on(changeset).keying
|
||||||
|
end
|
||||||
|
|
||||||
test "upcases the callsign" do
|
test "upcases the callsign" do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
{:ok, beacon} = Beacons.create_beacon(user, valid_beacon_attrs(callsign: "w5hn"))
|
{:ok, beacon} = Beacons.create_beacon(user, valid_beacon_attrs(callsign: "w5hn"))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue