Implement GenServer and Application for morse module.

This commit is contained in:
Pim Kunis 2019-07-24 23:56:42 +02:00
parent ef38b81dd6
commit 0c989c06d0
4 changed files with 61 additions and 33 deletions

37
morse/lib/morse_server.ex Normal file
View file

@ -0,0 +1,37 @@
defmodule MorseServer do
use GenServer
use Application
@impl true
def start(_type, _args) do
start_link()
end
def start_link do
GenServer.start_link(__MODULE__, :off, name: __MODULE__)
end
def start_morse do
GenServer.call(__MODULE__, :start)
end
@impl true
def init(state) do
{:ok, state}
end
@impl true
def handle_call(:start, _from, :on) do
{:reply, {:error, :already_started}, :on}
end
def handle_call(:start, _from, :off) do
spawn(MorseSignaler, :signal, [self()])
{:reply, :ok, :on}
end
@impl true
def handle_cast(:done, :on) do
{:noreply, :off}
end
end

View file

@ -1,4 +1,4 @@
defmodule Morse do defmodule MorseSignaler do
alias Circuits.GPIO alias Circuits.GPIO
@moduledoc """ @moduledoc """
@ -16,18 +16,17 @@ defmodule Morse do
@doc """ @doc """
Signal the provided symbols using GPIO. Signal the provided symbols using GPIO.
Also setup the GPIO. Notifies the parent when the signalling is done.
""" """
def signal do def signal(server_pid) do
signal(Application.fetch_env!(:morse, :morse_message)) # {:ok, gpio} = GPIO.open(relay_pin(), :output)
end # GPIO.write(gpio, @off)
def signal(symbols) do
{:ok, gpio} = GPIO.open(relay_pin(), :output)
GPIO.write(gpio, @off)
Process.sleep(@sleep_start) Process.sleep(@sleep_start)
signal_sentence(gpio, String.graphemes(symbols)) # signal_sentence(gpio, String.graphemes(secret_code()))
GenServer.cast(server_pid, :done)
:ok
end end
# Signal a whole sentence of symbols with GPIO. # Signal a whole sentence of symbols with GPIO.
@ -64,4 +63,8 @@ defmodule Morse do
defp relay_pin() do defp relay_pin() do
Application.fetch_env!(:morse, :relay_pin) Application.fetch_env!(:morse, :relay_pin)
end end
defp secret_code do
signal(Application.fetch_env!(:morse, :morse_message))
end
end end

View file

@ -15,7 +15,8 @@ defmodule Morse.MixProject do
def application do def application do
[ [
extra_applications: [:logger], extra_applications: [:logger],
env: [morse_message: "...---...", relay_pin: 17] env: [morse_message: "...---...", relay_pin: 17],
mod: {MorseServer, []}
] ]
end end

View file

@ -2,37 +2,24 @@ defmodule UiWeb.PageController do
use UiWeb, :controller use UiWeb, :controller
def index(conn, _params) do def index(conn, _params) do
conn conn |> send_resp(201, "")
|> send_resp(201, "")
end end
def instructions(conn, _params) do def instructions(conn, _params) do
conn conn |> render(:instructions)
|> render(:instructions)
end end
def morse(conn, _params) do def morse(conn, _params) do
conn conn |> render(:morse)
|> render(:morse)
end end
def start(conn, _params) do def start(conn, _params) do
now = System.system_time(:second) response =
case MorseServer.start_morse() do
case get_start_time() do :ok -> "Started."
start_time when start_time + 35 <= now -> {:error, :already_started} -> "The process is still in progress..."
System.put_env("MORSE_START_TIME", Integer.to_string(now))
Morse.signal()
text(conn, "Done.")
_ ->
text(conn, "It is still in progress...")
end
end end
defp get_start_time() do conn |> text(response)
case System.get_env("MORSE_START_TIME") do
nil -> 0
start_time -> String.to_integer(start_time)
end
end end
end end