Use Enum to loop over morse symbols.

Reset the progress bar when signalling starts.
This commit is contained in:
Pim Kunis 2019-08-17 16:44:31 +02:00
parent ada5099c1e
commit 4fcba648fe
2 changed files with 37 additions and 47 deletions

View file

@ -20,23 +20,17 @@ defmodule Morse.Server do
@impl true @impl true
def handle_call(:start, _from, {pid, _progress} = state) do def handle_call(:start, _from, {pid, _progress} = state) do
cond do if pid == nil or not Process.alive?(pid) do
pid == nil or not Process.alive?(pid) -> pid = spawn(&Morse.Worker.signal/0)
pid = spawn(&Morse.Worker.signal/0) {:reply, :ok, {pid, 0}}
{:reply, :ok, {pid, 0}} else
{:reply, {:error, :already_started}, state}
true ->
{:reply, {:error, :already_started}, state}
end end
end end
@impl true @impl true
def handle_cast({:progress, new_progress}, {pid, _progress}) do def handle_cast({:progress, new_progress}, {pid, _progress}) do
broadcast_progress(new_progress) GenServer.cast(Ui.SocketAPI, {:broadcast_progress, new_progress})
{:noreply, {pid, new_progress}} {:noreply, {pid, new_progress}}
end end
defp broadcast_progress(progress) do
GenServer.cast(Ui.SocketAPI, {:broadcast_progress, progress})
end
end end

View file

@ -15,56 +15,51 @@ defmodule Morse.Worker do
@off 1 @off 1
@doc """ @doc """
Signal the provided symbols using GPIO. Signal the provided morse symbols using the GPIO.
Notifies the parent when the signalling is done.
""" """
def signal() do def signal do
code = secret_code()
code_length = length(code)
update_progress(0, code_length)
{:ok, gpio} = GPIO.open(relay_pin(), :output) {:ok, gpio} = GPIO.open(relay_pin(), :output)
GPIO.write(gpio, @off) GPIO.write(gpio, @off)
Process.sleep(@sleep_start) Process.sleep(@sleep_start)
update_progress(gpio, String.graphemes(secret_code()))
code
|> Enum.with_index()
|> Enum.each(&signal_symbol(gpio, &1, code_length))
update_progress(100, 100)
end end
# Update progress for clients, and signals the rest of the sentence. defp signal_symbol(gpio, {'.', _index}, _length) do
defp update_progress(gpio, symbols) do
100 - length(symbols) / String.length(secret_code()) * 100
|> Morse.Server.update_progress()
if symbols != [] do
signal_sentence(gpio, symbols)
end
end
# Signal a whole sentence of symbols with GPIO.
defp signal_sentence(gpio, []) do
GPIO.write(gpio, @off)
GPIO.close(gpio)
update_progress(gpio, [])
:ok
end
defp signal_sentence(gpio, [symbol | rest]) when symbol in [".", "-"] do
GPIO.write(gpio, @on) GPIO.write(gpio, @on)
Process.sleep(@sleep_short)
case symbol do
"." -> Process.sleep(@sleep_short)
"-" -> Process.sleep(@sleep_long)
end
GPIO.write(gpio, @off) GPIO.write(gpio, @off)
Process.sleep(@sleep_delay) Process.sleep(@sleep_delay)
signal_sentence(gpio, rest)
end end
defp signal_sentence(gpio, [" " | rest]) do defp signal_symbol(gpio, {'-', _index}, _length) do
GPIO.write(gpio, @on)
Process.sleep(@sleep_long)
GPIO.write(gpio, @off)
Process.sleep(@sleep_delay)
end
defp signal_symbol(_gpio, {' ', index}, length) do
Process.sleep(@sleep_pause) Process.sleep(@sleep_pause)
update_progress(index, length)
update_progress(gpio, rest)
end end
defp signal_sentence(_gpio, [symbol | _rest]) do defp signal_symbol(_gpio, {symbol, _index}, _length) do
{:error, "Undefined symbol: " <> symbol} {:error, "Undefined symbol: " <> <<symbol :: utf8>>}
end
defp update_progress(index, length) do
Morse.Server.update_progress(index / length * 100)
end end
defp relay_pin() do defp relay_pin() do
@ -73,5 +68,6 @@ defmodule Morse.Worker do
defp secret_code do defp secret_code do
Application.fetch_env!(:morse, :morse_message) Application.fetch_env!(:morse, :morse_message)
|> String.to_charlist()
end end
end end