diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ee17530..b3f2b2c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,13 @@ ## Unreleased * Added the ability to remote TX audio. * Added TX TUNE button +* Added the ability to remotely wake the radio from the connections listing. +* Reworked the connections screen to be a LiveView. * Added the ability to configure the UDP audio port from 60001 via OPEN890_UDP_PORT * Updated startup message to explain how to control the server host and port through OPEN890_HOST and OPEN890_PORT * Fixed PROC on/off state not correctly queried on startup * Further fixes to purple TF SET indicator (WIP) - ## 1.0.8.1 - 2023-11-20 * Fixed TF SET display * Added purple TF SET carrier indicator diff --git a/config/config.exs b/config/config.exs index b9d26726..9dcb8b18 100644 --- a/config/config.exs +++ b/config/config.exs @@ -28,8 +28,6 @@ config :logger, :console, config :phoenix, :json_library, Jason config :phoenix, :trim_on_html_eex_engine, false -config :open890, Open890.RadioConnectionRepo, database: :"db/radio_connections.dets" - config :esbuild, version: "0.14.0", default: [ diff --git a/config/runtime.exs b/config/runtime.exs index 812930f9..84d22e1f 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -23,6 +23,9 @@ if config_env() in [:dev, :prod] do config :open890, Open890.UDPAudioServer, port: udp_port Logger.info("Configured OPEN890_HOST: #{inspect(host)}, OPEN890_PORT: #{inspect(port)}, OPEN890_UDP_PORT: #{inspect(udp_port)}") + + config :open890, Open890.RadioConnectionRepo, database: :"db/radio_connections.dets" else config :open890, Open890.UDPAudioServer, port: 60001 + config :open890, Open890.RadioConnectionRepo, database: :"db/radio_connections_test.dets" end diff --git a/config/test.exs b/config/test.exs index dd5bbadc..fcd43379 100644 --- a/config/test.exs +++ b/config/test.exs @@ -14,5 +14,3 @@ config :open890, Open890Web.Endpoint, # Print only warnings and errors during test config :logger, level: :warn - -config :open890, Open890.RadioConnectionRepo, database: :"db/radio_connections_test.dets" diff --git a/lib/open890/application.ex b/lib/open890/application.ex index 09cd6359..1ba794ba 100644 --- a/lib/open890/application.ex +++ b/lib/open890/application.ex @@ -54,6 +54,7 @@ defmodule Open890.Application do |> Enum.filter(fn conn -> Map.get(conn, :auto_start, "false") == "true" end) + |> IO.inspect(label: "auto-start connections") |> Enum.each(fn conn -> Logger.info("Auto-starting connection id #{conn.id}, \"#{conn.name}\"") conn |> RadioConnection.start() diff --git a/lib/open890/connection_commands.ex b/lib/open890/connection_commands.ex index f62c9e79..6d326e76 100644 --- a/lib/open890/connection_commands.ex +++ b/lib/open890/connection_commands.ex @@ -8,6 +8,8 @@ defmodule Open890.ConnectionCommands do Logger.debug("*** GET INITIAL STATE ***") conn + |> power_on() + |> get_power_state() |> get_active_receiver() |> get_vfo_a_freq() |> get_vfo_b_freq() @@ -59,6 +61,24 @@ defmodule Open890.ConnectionCommands do |> get_proc_enabled() end + def power_on(conn), do: conn |> cmd("PS1") + def power_off(conn), do: conn |> cmd("PS0") + + def wake(%RadioConnection{mac_address: nil} = conn) do + Logger.info("Attempted to WOL connection without a MAC address") + conn + end + + def wake(%RadioConnection{mac_address: mac_address} = conn) do + Logger.info("Sending WOL packet to #{mac_address}") + WOL.send(mac_address) + conn + end + + def wake(conn) do + WOL.send(conn.mac_address) + end + def get_busy_led_state(conn), do: conn |> cmd("BY") def get_fine(conn), do: conn |> cmd("FS") @@ -165,13 +185,18 @@ defmodule Open890.ConnectionCommands do end def set_power_level(conn, value) do - value = value - |> to_string() - |> String.pad_leading(3, "0") + value = + value + |> to_string() + |> String.pad_leading(3, "0") conn |> cmd("PC#{value}") end + def get_power_state(conn) do + conn |> cmd("PS") + end + def get_power_level(conn) do conn |> cmd("PC") end diff --git a/lib/open890/extract.ex b/lib/open890/extract.ex index ec3e459f..9d0e3e72 100644 --- a/lib/open890/extract.ex +++ b/lib/open890/extract.ex @@ -368,6 +368,18 @@ defmodule Open890.Extract do end end + def power_state(str) when is_binary(str) do + str + |> trim_to_integer(["PS"]) + |> case do + 0 -> :off + 1 -> :on + 2 -> :source_off + 3 -> :on_activating + _ -> :on + end + end + def power_level(str) when is_binary(str) do str |> trim_to_integer(["PC"]) end diff --git a/lib/open890/radio_connection.ex b/lib/open890/radio_connection.ex index a149a87a..bff27ead 100644 --- a/lib/open890/radio_connection.ex +++ b/lib/open890/radio_connection.ex @@ -10,6 +10,7 @@ defmodule Open890.RadioConnection do name: nil, ip_address: nil, tcp_port: @default_tcp_port, + mac_address: nil, user_name: nil, password: nil, user_is_admin: false, @@ -24,7 +25,21 @@ defmodule Open890.RadioConnection do alias Open890.{CloudlogSupervisor, RadioConnectionSupervisor} alias Open890.RadioConnectionRepo, as: Repo - alias Open890.{RadioState, UserMarker} + alias Open890.{ConnectionCommands, RadioState, UserMarker} + + def mac_address(connection) do + connection |> Map.get(:mac_address, nil) + end + + def wake(%__MODULE__{mac_address: mac}) when is_binary(mac) do + Logger.info("Sending WOL packet to #{inspect mac}") + WOL.send(mac) + end + + def wake(_) do + Logger.info("No MAC address associated with connection, not sending WOL") + :ok + end def tcp_port(%__MODULE__{} = connection) do connection @@ -45,7 +60,7 @@ defmodule Open890.RadioConnection do def first, do: all() |> Enum.at(0) - def add_user_marker(%__MODULE__{id: id} = connection, %UserMarker{} = marker) do + def add_user_marker(%__MODULE__{id: _id} = _connection, %UserMarker{} = _marker) do # the problem here is that the old connection struct seemingly doesn't even # have a :user_markers key, despite it being in the struct. it's like it's completely # frozen in the previous state when coming from dets, keys and all @@ -55,11 +70,11 @@ defmodule Open890.RadioConnection do :ok end - def delete_user_marker(%__MODULE__{} = connection, user_marker_id) do + def delete_user_marker(%__MODULE__{} = _connection, _user_marker_id) do :ok end - def clear_user_markers(%__MODULE__{} = connection) do + def clear_user_markers(%__MODULE__{} = _connection) do # repo().update(%{connection | user_markers: []}) :ok end @@ -109,6 +124,7 @@ defmodule Open890.RadioConnection do name: params["name"], ip_address: params["ip_address"], tcp_port: params["tcp_port"], + mac_address: params["mac_address"], user_name: params["user_name"], password: params["password"], user_is_admin: params["user_is_admin"], @@ -246,6 +262,10 @@ defmodule Open890.RadioConnection do end end + def query_power_state(connection) do + connection |> cmd("PS") + end + def cmd(%__MODULE__{} = connection, command) when is_binary(command) do connection |> get_connection_pid() @@ -275,12 +295,20 @@ defmodule Open890.RadioConnection do end end + def power_off(%{id: _id} = conn) do + ConnectionCommands.power_off(conn) + end + def broadcast_freq_delta(%__MODULE__{id: id} = _connection, args) do Open890Web.Endpoint.broadcast("connection:#{id}", "freq_delta", args) end def broadcast_connection_state(%__MODULE__{id: id} = _connection, state) do - Open890Web.Endpoint.broadcast("connection:#{id}", "connection_state", state) + Open890Web.Endpoint.broadcast("connection:#{id}", "connection_state", %{id: id, state: state}) + end + + def broadcast_power_state(%__MODULE__{id: id} = _connection, power_state) do + Open890Web.Endpoint.broadcast("connection:#{id}", "power_state", %{id: id, state: power_state}) end def broadcast_band_scope(%__MODULE__{id: id}, band_scope_data) do diff --git a/lib/open890/radio_connection_repo.ex b/lib/open890/radio_connection_repo.ex index 77340db4..8c2677ee 100644 --- a/lib/open890/radio_connection_repo.ex +++ b/lib/open890/radio_connection_repo.ex @@ -111,6 +111,7 @@ defmodule Open890.RadioConnectionRepo do end def update(%RadioConnection{id: id} = conn) when not is_nil(id) do + conn |> IO.inspect(label: "ConnectionRepo.update, conn") table_name() |> :dets.insert({id, conn}) end diff --git a/lib/open890/radio_state.ex b/lib/open890/radio_state.ex index 4a721daf..4d081b8f 100644 --- a/lib/open890/radio_state.ex +++ b/lib/open890/radio_state.ex @@ -52,7 +52,7 @@ defmodule Open890.RadioState do comp_meter: 0, cw_delay: nil, cw_key_speed: nil, - data_speed: nil, + data_speed: 1, display_screen_id: 0, filter_high_freq: nil, filter_low_freq: nil, diff --git a/lib/open890/tcp_client.ex b/lib/open890/tcp_client.ex index 1efa04ef..ae3ec37b 100644 --- a/lib/open890/tcp_client.ex +++ b/lib/open890/tcp_client.ex @@ -2,6 +2,7 @@ defmodule Open890.TCPClient do use GenServer require Logger alias Open890.RTP + alias Open890.Extract import Bitwise, [:>>>, :&&&] @@ -276,9 +277,10 @@ defmodule Open890.TCPClient do {:stop, :shutdown, state} end - # power status respnose - def handle_msg("PS1", state) do - # TODO: Cancel the connection timer here + def handle_msg("PS" <> _level = msg, %{connection: connection} = state) do + power_state = Extract.power_state(msg) + RadioConnection.broadcast_power_state(connection, power_state) + state end @@ -293,10 +295,6 @@ defmodule Open890.TCPClient do # # filter scope LAN/high cycle respnose # def handle_msg("DD11", state), do: state - def handle_msg("PS0", state) do - {:noreply, state} - # {:stop, :normal, state} - end def handle_msg("BSD", %{connection: connection} = state) do RadioConnection.broadcast_band_scope_cleared(connection) diff --git a/lib/open890_web.ex b/lib/open890_web.ex index 431f46f0..6514c856 100644 --- a/lib/open890_web.ex +++ b/lib/open890_web.ex @@ -17,6 +17,8 @@ defmodule Open890Web do and import those modules here. """ + def static_paths, do: ~w(assets fonts images favicon.ico robots.txt) + def controller do quote do require Logger @@ -25,6 +27,8 @@ defmodule Open890Web do import Plug.Conn import Open890Web.Gettext alias Open890Web.Router.Helpers, as: Routes + + unquote(verified_routes()) end end @@ -109,6 +113,17 @@ defmodule Open890Web do alias Open890.RadioConnection import Phoenix.LiveView + + unquote(verified_routes()) + end + end + + def verified_routes do + quote do + use Phoenix.VerifiedRoutes, + endpoint: Open890Web.Endpoint, + router: Open890Web.Router, + statics: Open890Web.static_paths() end end diff --git a/lib/open890_web/components/slider.ex b/lib/open890_web/components/slider.ex index cede4a3c..8aafcc85 100644 --- a/lib/open890_web/components/slider.ex +++ b/lib/open890_web/components/slider.ex @@ -7,6 +7,7 @@ defmodule Open890Web.Components.Slider do attr :label, :string, required: true attr :max_value, :integer, required: false attr :padded_top_value, :integer, required: false + attr :padded_top, :boolean, default: false attr :value, :any, required: true attr :wheel, :string, required: false diff --git a/lib/open890_web/components/voip_buttons.ex b/lib/open890_web/components/voip_buttons.ex index 91e4115e..014383ed 100644 --- a/lib/open890_web/components/voip_buttons.ex +++ b/lib/open890_web/components/voip_buttons.ex @@ -6,11 +6,11 @@ defmodule Open890Web.Components.VoipButtons do def mic_button(assigns) do ~H""" <%= if @enabled do %> - + VOIP Mic: ON <% else %> - + VOIP Mic: OFF <% end %> diff --git a/lib/open890_web/controllers/radio_connection_controller.ex b/lib/open890_web/controllers/radio_connection_controller.ex index cbb9e422..4fb12aa5 100644 --- a/lib/open890_web/controllers/radio_connection_controller.ex +++ b/lib/open890_web/controllers/radio_connection_controller.ex @@ -2,22 +2,13 @@ defmodule Open890Web.RadioConnectionController do use Open890Web, :controller alias Open890.RadioConnection + alias Open890.ConnectionCommands plug :assign_bg_theme - def index(conn, _params) do - radio_connections = RadioConnection.all() - - conn - |> assign(:radio_connections, radio_connections) - |> render("index.html") - end - def new(conn, _params) do - radio_connection = %RadioConnection{} - conn - |> assign(:radio_connection, radio_connection) + |> assign(:radio_connection, %RadioConnection{}) |> render("new.html") end @@ -27,13 +18,13 @@ defmodule Open890Web.RadioConnectionController do |> case do {:ok, %RadioConnection{auto_start: true} = connection} -> Logger.info("Connection is auto_start, starting") - connection |> RadioConnection.start() + RadioConnection.start(connection) other -> Logger.info("Connection is not auto-start, create result: #{inspect(other)}") end - conn |> redirect(to: Routes.radio_connection_path(conn, :index)) + conn |> redirect(to: connections_path()) end def edit(conn, %{"id" => id} = _params) do @@ -46,7 +37,7 @@ defmodule Open890Web.RadioConnectionController do _ -> conn - |> redirect(to: Routes.radio_connection_path(conn, :index)) + |> redirect(to: connections_path()) end end @@ -59,7 +50,7 @@ defmodule Open890Web.RadioConnectionController do |> RadioConnection.update_connection(radio_params) |> case do :ok -> - conn |> redirect(to: Routes.radio_connection_path(conn, :index)) + conn |> redirect(to: connections_path()) {:error, reason} -> Logger.debug("Could not update connection: #{inspect(reason)}") @@ -68,80 +59,17 @@ defmodule Open890Web.RadioConnectionController do _ -> Logger.warn("Could not find connection: #{id}") - conn |> redirect(to: Routes.radio_connection_path(conn, :index)) + conn |> redirect(to: connections_path()) end end - def delete(conn, %{"id" => id} = _params) do - id - |> RadioConnection.find() - |> case do - {:ok, connection} -> - connection |> RadioConnection.delete_connection() + def wake(conn, %{"id" => id} = _params) do + case RadioConnection.find(id) do + {:ok, conn} -> + ConnectionCommands.wake(conn) _ -> - Logger.warn("Could not find connection id: #{inspect(id)}") - end - - conn - |> redirect(to: Routes.radio_connection_path(conn, :index)) - end - - def start(conn, %{"id" => id} = _params) do - result = id |> RadioConnection.start() - - conn = - result - |> case do - {:ok, _radio_connection} -> - Logger.debug("Successfully started connection: #{id}") - - conn - |> redirect(to: Routes.radio_connection_path(conn, :index)) - - {:error, reason} -> - Logger.debug("Could not start connection #{id}: #{inspect(reason)}") - - pretty_error = - case reason do - {:bad_return_value, result} -> - case result do - {:error, :ehostunreach} -> - "Host unreachable" - - {:error, :econnrefused} -> - "Connection refused" - - {:error, err} -> - "Other error: #{inspect(err)}" - - err -> - "Unknown error: #{inspect(err)}" - end - - other -> - Logger.warn("Unmatched error starting connection: #{inspect(other)}") - inspect(other) - end - - conn - |> put_flash(:error, "Error starting connection to radio: #{pretty_error}") - |> redirect(to: Routes.radio_connection_path(conn, :index)) - end - - conn - end - - def stop(conn, %{"id" => id} = _params) do - result = id |> RadioConnection.stop() - - result - |> case do - :ok -> - Logger.info("stopped connection id #{id}") - - {:error, reason} -> - Logger.warn("Unable to stop connection #{id}: #{inspect(reason)}") + Logger.warn("Could not find connection: #{inspect(id)}") end conn @@ -151,4 +79,8 @@ defmodule Open890Web.RadioConnectionController do defp assign_bg_theme(conn, _options) do conn |> assign(:bg_theme, "light") end + + defp connections_path do + ~p"/connections" + end end diff --git a/lib/open890_web/live/connections.ex b/lib/open890_web/live/connections.ex new file mode 100644 index 00000000..94beb24a --- /dev/null +++ b/lib/open890_web/live/connections.ex @@ -0,0 +1,189 @@ +defmodule Open890Web.Live.Connections do + require Logger + + use Open890Web, :live_view + + alias Phoenix.Socket.Broadcast + + alias Open890.RadioConnection + + def mount(_params, _session, socket) do + Logger.info("Connections live mounted") + + connections = RadioConnection.all() + + power_states = connections + |> Enum.reduce(%{}, fn conn, acc -> + Map.put(acc, conn.id, :unknown) + end) + + socket = socket |> assign(:power_states, power_states) + + connection_states = connections + |> Enum.reduce(%{}, fn conn, acc -> + + + state = case RadioConnection.process_exists?(conn) do + true -> + RadioConnection.query_power_state(conn) + :up + + false -> :stopped + end + + Map.put(acc, conn.id, state) + end) + + socket = socket + |> assign_theme() + |> assign(:connections, connections) + |> assign(:connection_states, connection_states) + + if connected?(socket) do + for c <- connections do + Logger.info("Subscribing to connection:#{c.id}") + Phoenix.PubSub.subscribe(Open890.PubSub, "connection:#{c.id}") + end + end + + {:ok, socket} + end + + def handle_event("start_connection" = event, %{"id" => id} = params, %{assigns: assigns} = socket) do + Logger.debug("**** ConnectionsLive: handle_event: #{event}, params: #{inspect params}") + + result = RadioConnection.start(id) + + socket = case result do + {:ok, _conn} -> + new_connection_states = assigns.connection_states |> Map.put(id, :up) + socket |> assign(:connection_states, new_connection_states) + _ -> + Logger.warn("Could not start connection: #{inspect result}") + socket + end + + {:noreply, socket} + end + + def handle_event("stop_connection" = event, %{"id" => id} = params, %{assigns: assigns} = socket) do + Logger.debug("ConnectionsLive: handle_event: #{event}, params: #{inspect params}") + + result = id |> RadioConnection.stop() + + socket = case result do + :ok -> + Logger.info("stopped connection id #{id}") + new_connection_states = assigns.connection_states |> Map.put(id, :stopped) + new_power_states = assigns.power_states |> Map.put(id, :unknown) + socket + |> assign(:connection_states, new_connection_states) + |> assign(:power_states, new_power_states) + + {:error, reason} -> + Logger.warn("Unable to stop connection #{id}: #{inspect(reason)}") + socket + end + + {:noreply, socket} + end + + def handle_event("delete_connection" = _event, %{"id" => id} = _params, %{assigns: assigns} = socket) do + case RadioConnection.find(id) do + {:ok, connection} -> + RadioConnection.stop(id) + RadioConnection.delete_connection(connection) + _ -> + Logger.warn("Could not find connection id: #{inspect id}") + end + + new_connections = assigns.connections + |> Enum.reject(fn x -> x.id == id end) + + socket = socket + |> assign(%{ + connections: new_connections, + power_states: Map.delete(assigns.power_states, id), + connection_states: Map.delete(assigns.connection_states, id) + }) + + {:noreply, socket} + end + + def handle_event("power_off" = _event, %{"id" => id} = _params, %{assigns: _assigns} = socket) do + case RadioConnection.find(id) do + {:ok, conn} -> + RadioConnection.power_off(conn) + + _ -> + Logger.warn("Could not find connection: #{inspect(id)}") + end + + {:noreply, socket} + end + + def handle_event("wake" = _event, %{"id" => id} = _params, %{assigns: _assigns} = socket) do + case RadioConnection.find(id) do + {:ok, conn} -> + RadioConnection.wake(conn) + + _ -> + Logger.warn("Could not find connection: #{inspect(id)}") + end + + {:noreply, socket} + end + + def handle_event(event, params, %{assigns: _assigns} = socket) do + Logger.debug("ConnectionsLive: default handle_event: #{event}, params: #{inspect params}") + {:noreply, socket} + end + + def handle_info(%Broadcast{event: "connection_state", payload: payload}, socket) do + new_connection_states = socket.assigns.connection_states + |> Map.put(payload.id, payload.state) + + socket = socket + |> assign(:connection_states, new_connection_states) + + {:noreply, socket} + end + + def handle_info(%Broadcast{event: "power_state", payload: %{id: connection_id, state: power_state} = _payload}, socket) do + new_power_states = socket.assigns.power_states |> Map.put(connection_id, power_state) + + socket = socket + |> assign(:power_states, new_power_states) + + {:noreply, socket} + end + + def handle_info(%Broadcast{event: event, payload: payload}, socket) do + Logger.debug("ConnectionsLive: unhandled broadcast event: #{event}, payload: #{inspect payload}") + {:noreply, socket} + end + + defp assign_theme(conn) do + conn |> assign(:bg_theme, "light") + end + + defp pretty_connection_state({type, _extra}) do + type + end + + defp pretty_connection_state(state) when is_atom(state) do + state + end + + defp pretty_connection_state(other) do + Logger.warn("*** Unknown connection state: #{inspect other}") + :unknown_other + end + + defp connection_up?(:up), do: true + defp connection_up?(_), do: false + + defp power_on?(:on), do: true + defp power_on?(_), do: false + +end diff --git a/lib/open890_web/live/connections.html.heex b/lib/open890_web/live/connections.html.heex new file mode 100644 index 00000000..4fc06f26 --- /dev/null +++ b/lib/open890_web/live/connections.html.heex @@ -0,0 +1,103 @@ +<%= if @connections == [] do %> +

Render empty state

+<% else %> +
+
+
+
+

Radio Connections

+
+
+ <.link href={~p"/connections/new"} class="ui basic tiny icon button right floated"> + + Add new connection + +
+
+
+ + + + + + + + + + + + <%= for connection <- @connections do %> + + + + + + + + + + + + <% end %> + +
NameConnectionRadio PowerUIActions
+

<%= connection.name %>

+ + <%= connection_to_uri(connection) %> + +
+ <%= @connection_states |> Map.get(connection.id, :unknown) |> pretty_connection_state() %> + + <%= @power_states |> Map.get(connection.id, :unknown) %> + + <%= if @power_states |> Map.get(connection.id, :unknown) |> power_on?() do %> + <.link href={~p"/connections/#{connection.id}?panel=true&panelTab=txrx"} class="">Radio + | + <.link href={~p"/connections/#{connection.id}/bandscope"} class="">Bandscope + | + <.link href={~p"/connections/#{connection.id}/audioscope"} class="">Audioscope + | + <.link href={~p"/connections/#{connection.id}/meter"} class="">Meters + <% end %> + + <%= if @power_states |> Map.get(connection.id) != :on do %> + + <% end %> + + <%= if @connection_states |> Map.get(connection.id) |> connection_up?() do %> + + + + <% else %> + <.link id={"edit-button-#{connection.id}"} class="ui tiny button" href={~p"/connections/#{connection.id}/edit"}>Edit + + + + + + <% end %> +
+
+
+
+ +<% end %> \ No newline at end of file diff --git a/lib/open890_web/live/radio.ex b/lib/open890_web/live/radio.ex index 00165a0d..49e586f8 100644 --- a/lib/open890_web/live/radio.ex +++ b/lib/open890_web/live/radio.ex @@ -162,10 +162,10 @@ defmodule Open890Web.Live.Radio do end # Connection state messages - def handle_info(%Broadcast{event: "connection_state", payload: payload}, socket) do + def handle_info(%Broadcast{event: "connection_state", payload: %{id: _id, state: connection_state}} = payload, socket) do Logger.debug("Bandscope LV: RX connection_state: #{inspect(payload)}") - {:noreply, assign(socket, :connection_state, payload)} + {:noreply, assign(socket, :connection_state, connection_state)} end def handle_info(%Broadcast{event: "freq_delta", payload: payload}, socket) do @@ -179,6 +179,11 @@ defmodule Open890Web.Live.Radio do {:noreply, socket} end + def handle_info(%Broadcast{event: "power_state", payload: payload}, socket) do + # ignore power state broadcasts for now + {:noreply, socket} + end + def handle_info(%Broadcast{} = bc, socket) do Logger.warn("Unknown broadcast: #{inspect(bc)}") diff --git a/lib/open890_web/live/radio.html.heex b/lib/open890_web/live/radio.html.heex index e6835920..ce05eee3 100644 --- a/lib/open890_web/live/radio.html.heex +++ b/lib/open890_web/live/radio.html.heex @@ -122,22 +122,18 @@
<%= if connection_startable?(@connection_state) do %> -
-
- - - <%= format_connection_state(@connection_state) %> - -
+
+ + + <%= format_connection_state(@connection_state) %> +
<% else %> -
-
- - - <%= format_connection_state(@connection_state) %> - -
+
+ + + <%= format_connection_state(@connection_state) %> +
<% end %> @@ -158,37 +154,31 @@
<%= if @connection_state == :up && @radio_state.voip_enabled do %> -
-
- - VOIP Audio: Streaming   - - -
+
+ + VOIP Audio: Streaming   + +
<% else %> -
- <%= if @connection_state == :up do %> -
- VOIP Audio: Stopped -
- <% else %> -
- VOIP Audio: Stopped -
- <% end %> -
+ <%= if @connection_state == :up do %> +
+ VOIP Audio: Stopped +
+ <% else %> +
+ VOIP Audio: Stopped +
+ <% end %> <% end %>
<% else %> <%= if @connection_state == :up do %> -
-
- -   - VOIP Audio: Not available -
+
+ +   + VOIP Audio: Not available
<% end %> <% end %> diff --git a/lib/open890_web/router.ex b/lib/open890_web/router.ex index c4ad252b..630b0d6b 100644 --- a/lib/open890_web/router.ex +++ b/lib/open890_web/router.ex @@ -24,10 +24,9 @@ defmodule Open890Web.Router do get "/", PageController, :index - resources "/connections", RadioConnectionController, except: [:show] + live "/connections", Live.Connections, :index - post "/connections/:id/start", RadioConnectionController, :start - post "/connections/:id/stop", RadioConnectionController, :stop + resources "/connections", RadioConnectionController, except: [:index, :show] live "/connections/:id", Live.Radio, :show live "/connections/:id/bandscope", Live.Bandscope, :show diff --git a/lib/open890_web/templates/radio_connection/_form.html.eex b/lib/open890_web/templates/radio_connection/_form.html.eex index 88e9f146..0a790f94 100644 --- a/lib/open890_web/templates/radio_connection/_form.html.eex +++ b/lib/open890_web/templates/radio_connection/_form.html.eex @@ -1,35 +1,48 @@ -
+
<%= label @f, :name, "Connection Name", class: "" %>
<%= text_input @f, :name, value: @radio_connection.name, required: true %>
-
-
+
+
<%= label @f, :ip_address, "IP Address" %>
<%= text_input @f, :ip_address, value: @radio_connection.ip_address, required: true %>
-
+
<%= label @f, :tcp_port, "TCP Port" %>
<%= text_input @f, :tcp_port, value: RadioConnection.tcp_port(@radio_connection), required: true %>
+ +
+ + +
+ <%= text_input @f, :mac_address, value: RadioConnection.mac_address(@radio_connection), pattern: "^([0-9A-Fa-f]{2}[:\\-]){5}([0-9A-Fa-f]{2})$", maxlength: 17, placeholder: "XX-XX-XX-XX-XX" %> +
+
-
+
<%= label @f, :user_name, "KNS User" %>
<%= text_input @f, :user_name, value: @radio_connection.user_name, required: true %>
-
+
<%= label @f, :user_pass, "KNS Password" %>
<%= password_input @f, :password, value: @radio_connection.password, required: true %> diff --git a/lib/open890_web/templates/radio_connection/edit.html.eex b/lib/open890_web/templates/radio_connection/edit.html.eex index ea63adca..1226920a 100644 --- a/lib/open890_web/templates/radio_connection/edit.html.eex +++ b/lib/open890_web/templates/radio_connection/edit.html.eex @@ -8,7 +8,7 @@
<%= form_for @conn, Routes.radio_connection_path(@conn, :update, @radio_connection), [as: :radio_connection, method: :put, class: "ui form"], fn f -> %> <%= render "_form.html", f: f, radio_connection: @radio_connection %> - <%= link "Cancel", to: Routes.radio_connection_path(@conn, :index), class: "ui large left floated button" %> + <%= link "Cancel", to: ~p"/connections", class: "ui large left floated button" %> <%= submit "Update", class: "ui large primary button right floated" %> <% end %>
diff --git a/lib/open890_web/templates/radio_connection/index.html.eex b/lib/open890_web/templates/radio_connection/index.html.eex deleted file mode 100644 index bc210adf..00000000 --- a/lib/open890_web/templates/radio_connection/index.html.eex +++ /dev/null @@ -1,71 +0,0 @@ -<%= if @radio_connections == [] do %> - <%= render "_empty_state.html", conn: @conn %> -<% else %> -
-
-
-
-

Radio Connections

-
- -
-
- - - - - - - - - - - - <%= for connection <- @radio_connections do %> - - - - - - - - - - - - <% end %> - -
NameStatusUIDetails
-

<%= connection.name %>

-
- <%= if RadioConnection.process_exists?(connection) do %> -
Running
- <% else %> -
Stopped
- <% end %> -
- <%= link("Radio", to: Routes.radio_path(@conn, :show, connection, %{panel: true, panelTab: "txrx"}), data_tooltip: "Full radio UI", class: "ui tiny button") %> - <%= link("Bandscope", to: Routes.bandscope_path(@conn, :show, connection), data_tooltip: "Bandscope & minimal controls", class: "ui tiny button") %> - <%= link("Audioscope", to: Routes.audio_scope_path(@conn, :show, connection), data_tooltip: "Audio/filter scope", class: "ui tiny button") %> - <%= link("Meters", to: Routes.meter_path(@conn, :show, connection), data_tooltip: "Meters", class: "ui tiny button") %> - - <%= connection_to_uri(connection) %> - - <%= if RadioConnection.process_exists?(connection) do %> - <%= button("Stop", to: Routes.radio_connection_path(@conn, :stop, connection), class: "ui primary button") %> - <% else %> - <%= button("Delete", to: Routes.radio_connection_path(@conn, :delete, connection), method: :delete, data: [confirm: "Delete this connection?"], class: "ui button") %> - <%= link("Edit", to: Routes.radio_connection_path(@conn, :edit, connection), class: "ui button") %> - <%= button("Start", to: Routes.radio_connection_path(@conn, :start, connection), class: "ui primary button") %> - <% end %> - -
-
- -
-<% end %> diff --git a/lib/open890_web/templates/radio_connection/new.html.eex b/lib/open890_web/templates/radio_connection/new.html.eex index f8e5001b..97ebe6f1 100644 --- a/lib/open890_web/templates/radio_connection/new.html.eex +++ b/lib/open890_web/templates/radio_connection/new.html.eex @@ -8,7 +8,7 @@
<%= form_for @conn, Routes.radio_connection_path(@conn, :create), [as: :radio_connection, class: "ui form"], fn f -> %> <%= render "_form.html", f: f, radio_connection: @radio_connection %> - <%= link "Cancel", to: Routes.radio_connection_path(@conn, :index), class: "ui large left floated button" %> + <%= link "Cancel", to: ~p"/connections", class: "ui large left floated button" %> <%= submit "Create", class: "ui large right floated primary button" %> <% end %>
diff --git a/mix.exs b/mix.exs index 1cd7d534..be96048e 100644 --- a/mix.exs +++ b/mix.exs @@ -10,6 +10,9 @@ defmodule Open890.MixProject do version: version(), elixir: "~> 1.14", elixirc_paths: elixirc_paths(Mix.env()), + elixirc_options: [ + warnings_as_errors: false, + ], compilers: [:gettext] ++ Mix.compilers(), start_permanent: Mix.env() == :prod, aliases: aliases(), @@ -66,7 +69,8 @@ defmodule Open890.MixProject do {:telemetry_metrics, "~> 0.6"}, {:telemetry_poller, "~> 0.5"}, {:toml, "~> 0.6.2"}, - {:uniq, "~> 0.5"} + {:uniq, "~> 0.5"}, + {:wakeonlan, "~> 0.1.0"} ] end diff --git a/mix.lock b/mix.lock index 64f54526..fd3e6125 100644 --- a/mix.lock +++ b/mix.lock @@ -33,6 +33,7 @@ "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"}, + "socket": {:hex, :socket, "0.3.13", "98a2ab20ce17f95fb512c5cadddba32b57273e0d2dba2d2e5f976c5969d0c632", [:mix], [], "hexpm", "f82ea9833ef49dde272e6568ab8aac657a636acb4cf44a7de8a935acb8957c2e"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"}, "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"}, @@ -41,6 +42,7 @@ "tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, "uniq": {:hex, :uniq, "0.5.3", "d9d54dac49fa4bb4b7fff0dd050281a8ded507813396de0507196347ecf53be1", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "6961e04cb62227f9f5fae3d8e26eede990826b885ba6e2f33973222cc856f2fb"}, + "wakeonlan": {:hex, :wakeonlan, "0.1.0", "4e74fbb30cb309979240ced01e0f9fd217d4f05f6e08a0eb84aa32dfee4a2e93", [:mix], [{:socket, "~> 0.3", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm", "20909cc7ac5119ad7af75dbdc1e442af00b5084d707f900d3eb8d7b9fa81676c"}, "websock": {:hex, :websock, "0.5.2", "b3c08511d8d79ed2c2f589ff430bd1fe799bb389686dafce86d28801783d8351", [:mix], [], "hexpm", "925f5de22fca6813dfa980fb62fd542ec43a2d1a1f83d2caec907483fe66ff05"}, "websock_adapter": {:hex, :websock_adapter, "0.5.3", "4908718e42e4a548fc20e00e70848620a92f11f7a6add8cf0886c4232267498d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "cbe5b814c1f86b6ea002b52dd99f345aeecf1a1a6964e209d208fb404d930d3d"}, }