💥
This commit is contained in:
parent
15d1b36474
commit
191903ac59
|
@ -228,7 +228,7 @@ defmodule Farmbot.BotState do
|
|||
{
|
||||
:producer_consumer,
|
||||
struct(__MODULE__, configuration: Map.delete(settings, "user_env"), user_env: user_env),
|
||||
subscribe_to: [Farmbot.Firmware, Farmbot.System.ConfigStorage.Dispatcher],
|
||||
subscribe_to: [Farmbot.Firmware, Farmbot.System.ConfigStorage.Dispatcher, Farmbot.System.GPIO],
|
||||
dispatcher: GenStage.BroadcastDispatcher
|
||||
}
|
||||
end
|
||||
|
|
|
@ -31,7 +31,7 @@ defmodule Farmbot.System.GPIO do
|
|||
def handle_events(pin_triggers, _from, state) do
|
||||
t = Enum.uniq(pin_triggers)
|
||||
IO.puts "Got triggers: #{inspect t}"
|
||||
for {pin, _} <- t do
|
||||
for {:pin_trigger, pin} <- t do
|
||||
sequence_id = state.registered[pin]
|
||||
if sequence_id do
|
||||
Logger.busy 1, "Starting Sequence: #{sequence_id} from pin: #{pin}"
|
||||
|
|
|
@ -1,4 +1,42 @@
|
|||
defmodule Farmbot.System.GPIO.StubHandler do
|
||||
@moduledoc "Stub for handling GPIO."
|
||||
@behaviour Farmbot.System.GPIO.Handler
|
||||
use GenStage
|
||||
|
||||
def test_fire(pin) do
|
||||
GenStage.call(__MODULE__, {:test_fire, pin})
|
||||
end
|
||||
|
||||
def register_pin(num) do
|
||||
GenStage.call(__MODULE__, {:register_pin, num})
|
||||
end
|
||||
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [], [name: __MODULE__])
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
{:producer, %{}, [dispatcher: GenStage.BroadcastDispatcher]}
|
||||
end
|
||||
|
||||
def handle_demand(_amnt, state) do
|
||||
{:noreply, [], state}
|
||||
end
|
||||
|
||||
def handle_call({:register_pin, num}, _from, state) do
|
||||
{:reply, :ok, [], Map.put(state, num, :enabled)}
|
||||
end
|
||||
|
||||
def handle_call({:test_fire, pin}, _from, state) do
|
||||
case state[pin] do
|
||||
nil -> {:reply, :error, [], state}
|
||||
:enabled ->
|
||||
send self(), {:do_test_fire, pin}
|
||||
{:reply, :ok, [], state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_info({:do_test_fire, pin}, state) do
|
||||
{:noreply, [{:pin_trigger, pin}], state}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,8 @@ defmodule Farmbot.System.Supervisor do
|
|||
|> Enum.map(fn child -> fb_init(child, [[], [name: child]]) end)
|
||||
|
||||
after_init_children = [
|
||||
supervisor(Farmbot.System.Updates, [])
|
||||
supervisor(Farmbot.System.Updates, []),
|
||||
worker(Farmbot.System.GPIO, [])
|
||||
]
|
||||
|
||||
supervise(before_init_children ++ init_mods ++ after_init_children, strategy: :one_for_all)
|
||||
|
|
|
@ -23,11 +23,11 @@ defmodule Farmbot.Target.GPIO.AleHandler do
|
|||
|
||||
defmodule PinState do
|
||||
@moduledoc false
|
||||
defstruct [:pin, :state, :signal]
|
||||
defstruct [:pin, :state, :signal, :timer]
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
{:producer, struct(State, [pins: %{}]), dispatcher: GenStage.BroadcastDispatcher}
|
||||
{:producer, struct(State, [pins: %{}]), [dispatcher: GenStage.BroadcastDispatcher]}
|
||||
end
|
||||
|
||||
def handle_demand(_amnt, state) do
|
||||
|
@ -36,22 +36,40 @@ defmodule Farmbot.Target.GPIO.AleHandler do
|
|||
|
||||
def handle_call({:register_pin, num}, _from, state) do
|
||||
with {:ok, pin} <- GPIO.start_link(num, :input),
|
||||
:ok <- GPIO.set_int(pin, :both) do
|
||||
{:reply, :ok, [], %{state | pins: Map.put(state.pins, num, struct(PinState, [pin: pin, state: nil, signal: :falling]))}}
|
||||
:ok <- GPIO.set_int(pin, :rising) do
|
||||
{:reply, :ok, [], %{state | pins: Map.put(state.pins, num, struct(PinState, [pin: pin, state: nil, signal: :rising]))}}
|
||||
else
|
||||
{:error, _} = err-> {:reply, err, [], state}
|
||||
err -> {:reply, {:error, err}, [], state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_info({:gpio_interrupt, pin, :rising}, state) do
|
||||
IO.puts "got rising signal. Dispatching: #{pin}"
|
||||
pin_state = state.pins[pin]
|
||||
if pin_state.timer do
|
||||
new_state = %{state | pins: %{state.pins | pin => %{pin_state | state: :rising}}}
|
||||
{:noreply, [], new_state}
|
||||
else
|
||||
timer = Process.send_after(self(), {:gpio_timer, pin}, 5000)
|
||||
new_state = %{state | pins: %{state.pins | pin => %{pin_state | timer: timer, state: :rising}}}
|
||||
{:noreply, [{:pin_trigger, pin}], new_state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_info({:gpio_interrupt, pin, signal}, state) do
|
||||
pin_state = state.pins[pin]
|
||||
new_state = %{state | pins: %{state.pins | pin => %{pin_state | state: signal}}}
|
||||
if (pin_state.state != signal) && (pin_state.signal == signal) do
|
||||
IO.puts "#{pin_state.state} => #{new_state.pins[pin].state}"
|
||||
{:noreply, [{pin, pin_state}], new_state}
|
||||
{:noreply, [], new_state}
|
||||
end
|
||||
|
||||
def handle_info({:gpio_timer, pin}, state) do
|
||||
pin_state = state.pins[pin]
|
||||
if pin_state do
|
||||
new_pin_state = %{pin_state | timer: nil}
|
||||
{:noreply, [], %{state | pins: %{state.pins | pin => new_pin_state}}}
|
||||
else
|
||||
{:noreply, [], new_state}
|
||||
{:noreply, [], state}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue