Split Morse.Server into Application and Server.
Rename Morse.Signaler to Worker.
This commit is contained in:
parent
375a58ef14
commit
3432ef75b2
5 changed files with 19 additions and 13 deletions
12
morse/lib/morse/application.ex
Normal file
12
morse/lib/morse/application.ex
Normal file
|
@ -0,0 +1,12 @@
|
|||
defmodule Morse.Application do
|
||||
use Application
|
||||
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
{Morse.Server, nil}
|
||||
]
|
||||
|
||||
opts = [strategy: :one_for_one, name: Morse.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
end
|
42
morse/lib/morse/server.ex
Normal file
42
morse/lib/morse/server.ex
Normal file
|
@ -0,0 +1,42 @@
|
|||
defmodule Morse.Server do
|
||||
use GenServer
|
||||
|
||||
def start_link(_) do
|
||||
GenServer.start_link(__MODULE__, {nil, 0}, name: __MODULE__)
|
||||
end
|
||||
|
||||
def start_morse do
|
||||
GenServer.call(__MODULE__, :start)
|
||||
end
|
||||
|
||||
def update_progress(progress) do
|
||||
GenServer.cast(__MODULE__, {:progress, progress})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(state) do
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
@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}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_cast({:progress, new_progress}, {pid, _progress}) do
|
||||
broadcast_progress(new_progress)
|
||||
{:noreply, {pid, new_progress}}
|
||||
end
|
||||
|
||||
defp broadcast_progress(progress) do
|
||||
UiWeb.Endpoint.broadcast("morse:progress", "update", %{value: progress})
|
||||
end
|
||||
end
|
77
morse/lib/morse/worker.ex
Normal file
77
morse/lib/morse/worker.ex
Normal file
|
@ -0,0 +1,77 @@
|
|||
defmodule Morse.Worker do
|
||||
alias Circuits.GPIO
|
||||
|
||||
@moduledoc """
|
||||
Functions to control the signal lamp connected with GPIO.
|
||||
"""
|
||||
|
||||
@sleep_short 200
|
||||
@sleep_delay 400
|
||||
@sleep_long 700
|
||||
@sleep_pause 1000
|
||||
@sleep_start 3000
|
||||
|
||||
@on 0
|
||||
@off 1
|
||||
|
||||
@doc """
|
||||
Signal the provided symbols using GPIO.
|
||||
Notifies the parent when the signalling is done.
|
||||
"""
|
||||
|
||||
def signal() do
|
||||
{:ok, gpio} = GPIO.open(relay_pin(), :output)
|
||||
GPIO.write(gpio, @off)
|
||||
Process.sleep(@sleep_start)
|
||||
update_progress(gpio, String.graphemes(secret_code()))
|
||||
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
|
||||
GPIO.write(gpio, @on)
|
||||
|
||||
case symbol do
|
||||
"." -> Process.sleep(@sleep_short)
|
||||
"-" -> Process.sleep(@sleep_long)
|
||||
end
|
||||
|
||||
GPIO.write(gpio, @off)
|
||||
|
||||
Process.sleep(@sleep_delay)
|
||||
signal_sentence(gpio, rest)
|
||||
end
|
||||
|
||||
defp signal_sentence(gpio, [" " | rest]) do
|
||||
Process.sleep(@sleep_pause)
|
||||
|
||||
update_progress(gpio, rest)
|
||||
end
|
||||
|
||||
defp signal_sentence(_gpio, [symbol | _rest]) do
|
||||
{:error, "Undefined symbol: " <> symbol}
|
||||
end
|
||||
|
||||
defp relay_pin() do
|
||||
Application.fetch_env!(:morse, :relay_pin)
|
||||
end
|
||||
|
||||
defp secret_code do
|
||||
Application.fetch_env!(:morse, :morse_message)
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue