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
def handle_call(:start, _from, {pid, _progress} = state) do
cond do
pid == nil or not Process.alive?(pid) ->
pid = spawn(&Morse.Worker.signal/0)
{:reply, :ok, {pid, 0}}
true ->
{:reply, {:error, :already_started}, state}
if pid == nil or not Process.alive?(pid) do
pid = spawn(&Morse.Worker.signal/0)
{:reply, :ok, {pid, 0}}
else
{:reply, {:error, :already_started}, state}
end
end
@impl true
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}}
end
defp broadcast_progress(progress) do
GenServer.cast(Ui.SocketAPI, {:broadcast_progress, progress})
end
end

View file

@ -15,56 +15,51 @@ defmodule Morse.Worker do
@off 1
@doc """
Signal the provided symbols using GPIO.
Notifies the parent when the signalling is done.
Signal the provided morse symbols using the GPIO.
"""
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)
GPIO.write(gpio, @off)
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
# Update progress for clients, and signals the rest of the sentence.
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
defp signal_symbol(gpio, {'.', _index}, _length) do
GPIO.write(gpio, @on)
case symbol do
"." -> Process.sleep(@sleep_short)
"-" -> Process.sleep(@sleep_long)
end
Process.sleep(@sleep_short)
GPIO.write(gpio, @off)
Process.sleep(@sleep_delay)
signal_sentence(gpio, rest)
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)
update_progress(gpio, rest)
update_progress(index, length)
end
defp signal_sentence(_gpio, [symbol | _rest]) do
{:error, "Undefined symbol: " <> symbol}
defp signal_symbol(_gpio, {symbol, _index}, _length) do
{:error, "Undefined symbol: " <> <<symbol :: utf8>>}
end
defp update_progress(index, length) do
Morse.Server.update_progress(index / length * 100)
end
defp relay_pin() do
@ -73,5 +68,6 @@ defmodule Morse.Worker do
defp secret_code do
Application.fetch_env!(:morse, :morse_message)
|> String.to_charlist()
end
end