Move pinbindings from config_storage to asset storage to store in API
parent
56954a3790
commit
fc43da88f3
|
@ -44,7 +44,7 @@ config :farmbot, :behaviour,
|
|||
authorization: Farmbot.Bootstrap.Authorization,
|
||||
firmware_handler: Farmbot.Firmware.StubHandler,
|
||||
http_adapter: Farmbot.HTTP.HTTPoisonAdapter,
|
||||
gpio_handler: Farmbot.System.GPIO.StubHandler,
|
||||
pin_binding_handler: Farmbot.PinBinding.StubHandler,
|
||||
json_parser: Farmbot.JSON.JasonParser
|
||||
|
||||
config :farmbot, :farmware,
|
||||
|
|
|
@ -57,7 +57,7 @@ config :farmbot, :behaviour,
|
|||
system_tasks: Farmbot.Target.SystemTasks,
|
||||
firmware_handler: Farmbot.Firmware.StubHandler,
|
||||
update_handler: Farmbot.Target.UpdateHandler,
|
||||
gpio_handler: Farmbot.Target.GPIO.AleHandler
|
||||
pin_binding_handler: Farmbot.Target.PinBinding.AleHandler
|
||||
|
||||
local_file = Path.join(System.user_home!(), ".ssh/id_rsa.pub")
|
||||
local_key = if File.exists?(local_file), do: [File.read!(local_file)], else: []
|
||||
|
|
|
@ -55,7 +55,7 @@ config :farmbot, :behaviour,
|
|||
system_tasks: Farmbot.Target.SystemTasks,
|
||||
firmware_handler: Farmbot.Firmware.StubHandler,
|
||||
update_handler: Farmbot.Target.UpdateHandler,
|
||||
gpio_handler: Farmbot.Target.GPIO.AleHandler
|
||||
pin_binding_handler: Farmbot.Target.PinBinding.AleHandler
|
||||
|
||||
config :shoehorn,
|
||||
init: [:nerves_runtime],
|
||||
|
|
|
@ -5,7 +5,9 @@ lib/farmbot/farmware/runtime.ex
|
|||
lib/farmbot/farmware/runtime_error.ex
|
||||
lib/farmbot/farmware/supervisor.ex
|
||||
lib/farmbot/repo/worker.ex
|
||||
lib/farmbot/system/gpio/gpio.ex
|
||||
lib/farmbot/pin_binding/handler.ex
|
||||
lib/farmbot/pin_binding/pin_binding.ex
|
||||
lib/farmbot/pin_binding/stub_handler.ex
|
||||
lib/farmbot/asset/farm_event.ex
|
||||
lib/farmbot/asset/regimen.ex
|
||||
lib/farmbot/jwt.ex
|
||||
|
|
|
@ -9,6 +9,7 @@ defmodule Farmbot.Asset do
|
|||
Device,
|
||||
FarmEvent,
|
||||
Peripheral,
|
||||
PinBinding,
|
||||
Point,
|
||||
Regimen,
|
||||
Sensor,
|
||||
|
@ -30,6 +31,10 @@ defmodule Farmbot.Asset do
|
|||
:ok
|
||||
end
|
||||
|
||||
def all_pin_bindings do
|
||||
Farmbot.Repo.all(PinBinding)
|
||||
end
|
||||
|
||||
@doc "Information about _this_ device."
|
||||
def device do
|
||||
Farmbot.Repo.one(Device)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
defmodule Farmbot.Asset.PinBinding do
|
||||
@moduledoc """
|
||||
When a pin binding is triggered a sequence fires.
|
||||
"""
|
||||
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
schema "pin_bindings" do
|
||||
field(:pin_num, :integer)
|
||||
field(:sequence_id, :integer)
|
||||
end
|
||||
|
||||
@required_fields [:id, :pin_num, :sequence_id]
|
||||
|
||||
def changeset(pin_binding, params \\ %{}) do
|
||||
pin_binding
|
||||
|> cast(params, @required_fields)
|
||||
|> validate_required(@required_fields)
|
||||
|> unique_constraint(:id)
|
||||
end
|
||||
end
|
|
@ -34,13 +34,11 @@ defmodule Farmbot.Bootstrap.AuthTask do
|
|||
auth_task = Application.get_env(:farmbot, :behaviour)[:authorization]
|
||||
{email, pass, server} = {fetch_email(), fetch_pass(), fetch_server()}
|
||||
# Logger.busy(3, "refreshing token: #{email} - #{server}")
|
||||
Farmbot.System.GPIO.Leds.led_status_err()
|
||||
case auth_task.authorize(email, pass, server) do
|
||||
{:ok, token} ->
|
||||
# Logger.success(3, "Successful authorization: #{email} - #{server}")
|
||||
update_config_value(:bool, "settings", "first_boot", false)
|
||||
update_config_value(:string, "authorization", "token", token)
|
||||
Farmbot.System.GPIO.Leds.led_status_ok()
|
||||
if get_config_value(:bool, "settings", "auto_sync") do
|
||||
# Force an auto sync
|
||||
Farmbot.Repo.sync(2)
|
||||
|
|
|
@ -14,7 +14,6 @@ defmodule Farmbot.Bootstrap.Authorization do
|
|||
@type token :: binary
|
||||
|
||||
use Farmbot.Logger
|
||||
alias Farmbot.System.GPIO.Leds
|
||||
alias Farmbot.System.ConfigStorage
|
||||
import ConfigStorage, only: [update_config_value: 4, get_config_value: 3]
|
||||
|
||||
|
@ -51,7 +50,6 @@ defmodule Farmbot.Bootstrap.Authorization do
|
|||
{:ok, resp} <- request_token(server, payload),
|
||||
{:ok, body} <- Poison.decode(resp),
|
||||
{:ok, map} <- Map.fetch(body, "token") do
|
||||
Leds.led_status_ok()
|
||||
last_reset_reason_file = Path.join(@data_path, "last_shutdown_reason")
|
||||
File.rm(last_reset_reason_file)
|
||||
Map.fetch(map, "encoded")
|
||||
|
@ -86,7 +84,6 @@ defmodule Farmbot.Bootstrap.Authorization do
|
|||
update_config_value(:bool, "settings", "first_boot", false)
|
||||
last_reset_reason_file = Path.join(@data_path, "last_shutdown_reason")
|
||||
File.rm(last_reset_reason_file)
|
||||
Leds.led_status_ok()
|
||||
Map.fetch(map, "encoded")
|
||||
else
|
||||
:error -> {:error, "unknown error."}
|
||||
|
|
|
@ -127,6 +127,7 @@ defmodule Farmbot.Bootstrap.Supervisor do
|
|||
supervisor(Farmbot.HTTP.Supervisor, []),
|
||||
worker(Farmbot.Bootstrap.SettingsSync, []),
|
||||
supervisor(Farmbot.Firmware.Supervisor, []),
|
||||
supervisor(Farmbot.PinBinding.Supervisor, []),
|
||||
supervisor(Farmbot.BotState.Supervisor, []),
|
||||
supervisor(Farmbot.BotState.Transport.Supervisor, []),
|
||||
supervisor(Farmbot.Repo.Supervisor, []),
|
||||
|
|
|
@ -161,7 +161,7 @@ defmodule Farmbot.BotState do
|
|||
info_settings = %{initial_state.informational_settings | node_name: node()}
|
||||
state = %{initial_state | informational_settings: info_settings}
|
||||
gen_stage_opts = [
|
||||
subscribe_to: [Firmware, ConfigStorage.Dispatcher, Farmbot.System.GPIO],
|
||||
subscribe_to: [Firmware, ConfigStorage.Dispatcher, Farmbot.PinBinding.Manager],
|
||||
dispatcher: GenStage.BroadcastDispatcher
|
||||
]
|
||||
{:producer_consumer, state, gen_stage_opts}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Node.RegisterGpio do
|
||||
@moduledoc false
|
||||
use Farmbot.CeleryScript.AST.Node
|
||||
allow_args [:sequence_id, :pin_number]
|
||||
use Farmbot.Logger
|
||||
alias Farmbot.Asset
|
||||
|
||||
def execute(%{sequence_id: id, pin_number: pin_num}, _, env) do
|
||||
env = mutate_env(env)
|
||||
case Asset.get_sequence_by_id(id) do
|
||||
nil -> {:error, "Could not find sequence by id: #{id}", env}
|
||||
seq ->
|
||||
Logger.busy 1, "Registering gpio: #{pin_num} to sequence: #{seq.name}"
|
||||
case Farmbot.System.GPIO.register_pin(pin_num, id) do
|
||||
:ok -> {:ok, env}
|
||||
{:error, reason} -> {:error, reason, env}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,14 +0,0 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Node.UnregisterGpio do
|
||||
@moduledoc false
|
||||
use Farmbot.CeleryScript.AST.Node
|
||||
allow_args [:pin_number]
|
||||
use Farmbot.Logger
|
||||
|
||||
def execute(%{pin_number: pin_num}, _, env) do
|
||||
env = mutate_env(env)
|
||||
case Farmbot.System.GPIO.unregister_pin(pin_num)do
|
||||
:ok -> {:ok, env}
|
||||
{:error, reason} -> {:error, reason, env}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -260,7 +260,6 @@ defmodule Farmbot.Firmware do
|
|||
:ok ->
|
||||
timer = start_timer(current, state.timeout_ms)
|
||||
if fun == :emergency_unlock do
|
||||
Farmbot.System.GPIO.Leds.led_status_ok()
|
||||
new_dispatch = [{:informational_settings, %{busy: false, locked: false}} | dispatch]
|
||||
{:noreply, new_dispatch, %{state | current: current, timer: timer}}
|
||||
else
|
||||
|
@ -503,7 +502,6 @@ defmodule Farmbot.Firmware do
|
|||
end
|
||||
|
||||
defp handle_gcode(:report_emergency_lock, state) do
|
||||
Farmbot.System.GPIO.Leds.led_status_err
|
||||
maybe_send_email()
|
||||
if state.current do
|
||||
do_reply(state, {:error, :emergency_lock})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
defmodule Farmbot.System.GPIO.Handler do
|
||||
@moduledoc "Behaviour for GPIO handlers to implement."
|
||||
defmodule Farmbot.PinBinding.Handler do
|
||||
@moduledoc "Behaviour for PinBinding handlers to implement."
|
||||
|
||||
@doc "Start the handler."
|
||||
@callback start_link :: GenServer.on_start
|
||||
@callback start_link :: GenServer.on_start()
|
||||
|
||||
@doc "Register a pin."
|
||||
@callback register_pin(integer) :: :ok | {:error, term}
|
|
@ -1,11 +1,11 @@
|
|||
defmodule Farmbot.System.GPIO do
|
||||
@moduledoc "Handles GPIO inputs."
|
||||
defmodule Farmbot.PinBinding.Manager do
|
||||
@moduledoc "Handles PinBinding inputs and outputs"
|
||||
use GenStage
|
||||
use Farmbot.Logger
|
||||
alias Farmbot.System.ConfigStorage
|
||||
alias ConfigStorage.GpioRegistry
|
||||
|
||||
@handler Application.get_env(:farmbot, :behaviour)[:gpio_handler]
|
||||
alias Farmbot.Asset
|
||||
alias Asset.PinBinding
|
||||
@handler Application.get_env(:farmbot, :behaviour)[:pin_binding_handler]
|
||||
@handler || Mix.raise("No pin binding handler.")
|
||||
|
||||
@doc "Register a pin number to execute sequence."
|
||||
def register_pin(pin_num, sequence_id) do
|
||||
|
@ -13,8 +13,8 @@ defmodule Farmbot.System.GPIO do
|
|||
end
|
||||
|
||||
@doc "Unregister a sequence."
|
||||
def unregister_pin(sequence_id) do
|
||||
GenStage.call(__MODULE__, {:unregister_pin, sequence_id})
|
||||
def unregister_pin(pin_num) do
|
||||
GenStage.call(__MODULE__, {:unregister_pin, pin_num})
|
||||
end
|
||||
|
||||
def confirm_asset_storage_up do
|
||||
|
@ -22,8 +22,8 @@ defmodule Farmbot.System.GPIO do
|
|||
end
|
||||
|
||||
@doc false
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [], name: __MODULE__)
|
||||
def start_link(args) do
|
||||
GenStage.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
defmodule State do
|
||||
|
@ -37,8 +37,7 @@ defmodule Farmbot.System.GPIO do
|
|||
def init([]) do
|
||||
case @handler.start_link() do
|
||||
{:ok, handler} ->
|
||||
all_gpios = ConfigStorage.all_gpios()
|
||||
state = initial_state(all_gpios, struct(State, handler: handler))
|
||||
state = initial_state([], struct(State, handler: handler))
|
||||
Process.send_after(self(), :update_fb_state_tree, 10)
|
||||
|
||||
{:producer_consumer, state,
|
||||
|
@ -52,7 +51,7 @@ defmodule Farmbot.System.GPIO do
|
|||
defp initial_state([], state), do: state
|
||||
|
||||
defp initial_state(
|
||||
[%GpioRegistry{pin: pin, sequence_id: sequence_id} | rest],
|
||||
[%PinBinding{pin_num: pin, sequence_id: sequence_id} | rest],
|
||||
state
|
||||
) do
|
||||
case @handler.register_pin(pin) do
|
||||
|
@ -96,12 +95,11 @@ defmodule Farmbot.System.GPIO do
|
|||
end
|
||||
|
||||
def handle_call({:register_pin, pin_num, sequence_id}, _from, state) do
|
||||
Logger.info 1, "Registering #{pin_num} to sequence by id: #{sequence_id}"
|
||||
case state.registered[pin_num] do
|
||||
nil ->
|
||||
case @handler.register_pin(pin_num) do
|
||||
:ok ->
|
||||
ConfigStorage.add_gpio_registry(pin_num, sequence_id)
|
||||
|
||||
new_state = %{
|
||||
state
|
||||
| registered: Map.put(state.registered, pin_num, sequence_id)
|
||||
|
@ -119,14 +117,15 @@ defmodule Farmbot.System.GPIO do
|
|||
end
|
||||
|
||||
def handle_call({:unregister_pin, pin_num}, _from, state) do
|
||||
|
||||
case state.registered[pin_num] do
|
||||
nil ->
|
||||
{:reply, {:error, :unregistered}, [], state}
|
||||
|
||||
sequence_id ->
|
||||
Logger.info 1, "Unregistering #{pin_num} from sequence by id: #{sequence_id}"
|
||||
case @handler.unregister_pin(pin_num) do
|
||||
:ok ->
|
||||
ConfigStorage.delete_gpio_registry(pin_num, sequence_id)
|
||||
|
||||
new_state = %{
|
||||
state
|
||||
|
@ -142,6 +141,8 @@ defmodule Farmbot.System.GPIO do
|
|||
end
|
||||
|
||||
def handle_call(:confirm_asset_storage_up, _, state) do
|
||||
all_bindings = Asset.all_pin_bindings()
|
||||
state = initial_state(all_bindings, state)
|
||||
{:reply, :ok, [], %{state | repo_up: true}}
|
||||
end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
defmodule Farmbot.System.GPIO.StubHandler do
|
||||
@moduledoc "Stub for handling GPIO."
|
||||
@behaviour Farmbot.System.GPIO.Handler
|
||||
defmodule Farmbot.PinBinding.StubHandler do
|
||||
@moduledoc "Stub for handling PinBinding."
|
||||
@behaviour Farmbot.PinBinding.Handler
|
||||
use GenStage
|
||||
|
||||
def test_fire(pin) do
|
||||
|
@ -16,7 +16,7 @@ defmodule Farmbot.System.GPIO.StubHandler do
|
|||
end
|
||||
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [], [name: __MODULE__])
|
||||
GenStage.start_link(__MODULE__, [], name: __MODULE__)
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
|
@ -37,9 +37,11 @@ defmodule Farmbot.System.GPIO.StubHandler do
|
|||
|
||||
def handle_call({:test_fire, pin}, _from, state) do
|
||||
case state[pin] do
|
||||
nil -> {:reply, :error, [], state}
|
||||
nil ->
|
||||
{:reply, :error, [], state}
|
||||
|
||||
:enabled ->
|
||||
send self(), {:do_test_fire, pin}
|
||||
send(self(), {:do_test_fire, pin})
|
||||
{:reply, :ok, [], state}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
defmodule Farmbot.PinBinding.Supervisor do
|
||||
@moduledoc false
|
||||
use Supervisor
|
||||
|
||||
def start_link() do
|
||||
Supervisor.start_link(__MODULE__, [], [name: __MODULE__])
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
children = [
|
||||
{Farmbot.PinBinding.Manager, []}
|
||||
]
|
||||
Supervisor.init(children, [strategy: :one_for_one])
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@ defmodule Farmbot.Repo.AfterSyncWorker do
|
|||
|
||||
def init([]) do
|
||||
Farmbot.Repo.Registry.subscribe()
|
||||
Farmbot.System.GPIO.confirm_asset_storage_up()
|
||||
Farmbot.PinBinding.Manager.confirm_asset_storage_up()
|
||||
{:ok, %{}}
|
||||
end
|
||||
|
||||
|
@ -26,6 +26,22 @@ defmodule Farmbot.Repo.AfterSyncWorker do
|
|||
{:noreply, state}
|
||||
end
|
||||
|
||||
def handle_info({Farmbot.Repo.Registry, :addition, Farmbot.Asset.PinBinding, %{pin_num: pin, sequence_id: sequence_id}}, state) do
|
||||
Farmbot.PinBinding.Manager.register_pin(pin, sequence_id)
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
def handle_info({Farmbot.Repo.Registry, :updated, Farmbot.Asset.PinBinding, %{pin_num: pin, sequence_id: sequence_id}}, state) do
|
||||
Farmbot.PinBinding.Manager.unregister_pin(pin)
|
||||
Farmbot.PinBinding.Manager.register_pin(pin, sequence_id)
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
def handle_info({Farmbot.Repo.Registry, :deletion, Farmbot.Asset.PinBinding, %{pin_num: pin, sequence_id: _sequence_id}}, state) do
|
||||
Farmbot.PinBinding.Manager.unregister_pin(pin)
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
def handle_info(_, state) do
|
||||
{:noreply, state}
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ defmodule Farmbot.Repo do
|
|||
Device,
|
||||
FarmEvent,
|
||||
Peripheral,
|
||||
PinBinding,
|
||||
Point,
|
||||
Regimen,
|
||||
Sensor,
|
||||
|
@ -69,6 +70,7 @@ defmodule Farmbot.Repo do
|
|||
results = Farmbot.Repo.all(Device) ++
|
||||
Farmbot.Repo.all(FarmEvent) ++
|
||||
Farmbot.Repo.all(Peripheral) ++
|
||||
Farmbot.Repo.all(PinBinding) ++
|
||||
Farmbot.Repo.all(Point) ++
|
||||
Farmbot.Repo.all(Regimen) ++
|
||||
Farmbot.Repo.all(Sensor) ++
|
||||
|
@ -86,6 +88,7 @@ defmodule Farmbot.Repo do
|
|||
Task.async(fn() -> {Device, HTTP.get!("/api/device.json") |> Map.fetch!(:body) |> Poison.decode!(as: struct(Device))} end),
|
||||
Task.async(fn() -> {FarmEvent, HTTP.get!("/api/farm_events.json") |> Map.fetch!(:body) |> Poison.decode!(as: [struct(FarmEvent)])} end),
|
||||
Task.async(fn() -> {Peripheral, HTTP.get!("/api/peripherals.json") |> Map.fetch!(:body) |> Poison.decode!(as: [struct(Peripheral)])} end),
|
||||
Task.async(fn() -> {PinBinding, HTTP.get!("/api/pin_bindings.json") |> Map.fetch!(:body) |> Poison.decode!(as: [struct(PinBinding)])} end),
|
||||
Task.async(fn() -> {Point, HTTP.get!("/api/points.json") |> Map.fetch!(:body) |> Poison.decode!(as: [struct(Point)])} end),
|
||||
Task.async(fn() -> {Regimen, HTTP.get!("/api/regimens.json") |> Map.fetch!(:body) |> Poison.decode!(as: [struct(Regimen)])} end),
|
||||
Task.async(fn() -> {Sensor, HTTP.get!("/api/sensors.json") |> Map.fetch!(:body) |> Poison.decode!(as: [struct(Sensor)])} end),
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
defmodule Farmbot.System.GPIO.Leds do
|
||||
@moduledoc false
|
||||
|
||||
use GenServer
|
||||
|
||||
@led_status_on Application.get_env(:farmbot, :gpio, :status_led_off) || true
|
||||
|
||||
def led_status_ok do
|
||||
GenServer.call(__MODULE__, :led_status_ok)
|
||||
end
|
||||
|
||||
def led_status_err do
|
||||
GenServer.call(__MODULE__, :led_status_err)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def start_link do
|
||||
GenServer.start_link(__MODULE__, [], [name: __MODULE__])
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
names = Application.get_env(:nerves_leds, :names) || []
|
||||
status_led_name = Keyword.get(names, :status)
|
||||
{:ok, %{status: status_led_name}}
|
||||
end
|
||||
|
||||
def handle_call(_, _from, %{status: nil} = state) do
|
||||
{:reply, :ok, state}
|
||||
end
|
||||
|
||||
def handle_call(:led_status_ok, _from, %{status: _} = state) do
|
||||
Nerves.Leds.set status: @led_status_on
|
||||
{:reply, :ok, state}
|
||||
end
|
||||
|
||||
def handle_call(:led_status_err, _from, %{status: _} = state) do
|
||||
Nerves.Leds.set status: :slowblink
|
||||
{:reply, :ok, state}
|
||||
end
|
||||
end
|
|
@ -18,7 +18,6 @@ defmodule Farmbot.System.Supervisor do
|
|||
supervisor(Farmbot.System.Init.Ecto, [[], []]),
|
||||
supervisor(Farmbot.System.ConfigStorage, []),
|
||||
worker(Farmbot.System.ConfigStorage.Dispatcher, []),
|
||||
worker(Farmbot.System.GPIO.Leds, []),
|
||||
]
|
||||
|
||||
init_mods =
|
||||
|
@ -27,7 +26,6 @@ defmodule Farmbot.System.Supervisor do
|
|||
|
||||
after_init_children = [
|
||||
supervisor(Farmbot.System.Updates, []),
|
||||
worker(Farmbot.System.GPIO, []),
|
||||
worker(Farmbot.EasterEggs, []),
|
||||
]
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ defmodule Farmbot.Target.Bootstrap.Configurator do
|
|||
Logger.info(3, "Building new configuration.")
|
||||
import Supervisor.Spec
|
||||
:ets.new(:session, [:named_table, :public, read_concurrency: true])
|
||||
Farmbot.System.GPIO.Leds.led_status_err()
|
||||
ConfigStorage.destroy_all_network_configs()
|
||||
children = [
|
||||
worker(Configurator.CaptivePortal, [], restart: :transient),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
defmodule Farmbot.Target.GPIO.AleHandler do
|
||||
@moduledoc "GPIO handler that uses Elixir.Ale"
|
||||
defmodule Farmbot.Target.PinBinding.AleHandler do
|
||||
@moduledoc "PinBinding handler that uses Elixir.Ale"
|
||||
|
||||
use GenStage
|
||||
alias ElixirALE.GPIO
|
||||
@behaviour Farmbot.System.GPIO.Handler
|
||||
@behaviour Farmbot.PinBinding.Handler
|
||||
|
||||
# GPIO Handler Callbacks
|
||||
# PinBinding.Handler Callbacks
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [], [name: __MODULE__])
|
||||
end
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
defmodule Farmbot.Repo.Migrations.CreatePinBindingsTable do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table("pin_bindings", primary_key: false) do
|
||||
add(:id, :integer)
|
||||
add(:pin_num, :integer)
|
||||
add(:sequence_id, :integer)
|
||||
end
|
||||
|
||||
create(unique_index("pin_bindings", [:id]))
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue