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

View file

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

View file

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