more reimplementation.

This commit is contained in:
Connor Rigby 2017-11-05 16:18:44 -08:00
parent d6bdfd3433
commit fceef7ee74
13 changed files with 94 additions and 11 deletions

View file

@ -21,7 +21,8 @@ defmodule Farmbot.BotState do
controller_version: @version,
commit: @commit,
target: @target,
env: @env
env: @env,
sync_status: :sync_now,
},
user_env: %{},
process_info: %{}
@ -71,6 +72,7 @@ defmodule Farmbot.BotState do
defp do_handle([{key, diff} | rest], state) do
state = %{state | key => Map.merge(Map.get(state, key), diff)}
Logger.debug "Got #{key} => #{inspect diff} #{inspect state}"
do_handle(rest, state)
end
end

View file

@ -69,6 +69,10 @@ defmodule Farmbot.BotState.Transport.GenMQTT.Client do
|> Poison.decode!()
|> Farmbot.CeleryScript.AST.decode()
|> elem(1)
|> fn(ast) ->
Logger.debug "received #{inspect Farmbot.CeleryScript.AST.encode(ast) |> elem(1)}"
ast
end.()
|> Farmbot.CeleryScript.execute()
{:ok, state}
end
@ -101,8 +105,9 @@ defmodule Farmbot.BotState.Transport.GenMQTT.Client do
{:noreply, state}
end
def handle_cast({:emit, msg}, state) do
{:ok, encoded_ast} = AST.encode(msg)
def handle_cast({:emit, ast}, state) do
Logger.debug "Emitting #{inspect ast} | #{inspect AST.encode(ast) |> elem(1)}"
{:ok, encoded_ast} = AST.encode(ast)
json = Poison.encode!(encoded_ast)
GenMQTT.publish(self(), frontend_topic(state.device), json, 0, false)
{:noreply, state}

View file

@ -2,5 +2,6 @@ defmodule Farmbot.CeleryScript.AST.Arg do
@moduledoc "CeleryScript Argument."
@doc "Verify this arg."
@callback verify(any) :: {:ok, any} | {:error, term}
@callback decode(any) :: {:ok, any} | {:error, term}
@callback encode(any) :: {:ok, any} | {:error, term}
end

View file

@ -7,6 +7,11 @@ defmodule Farmbot.CeleryScript.AST.Arg.Axis do
def decode("z"), do: {:ok, :z}
def decode("all"), do: {:ok, :all}
def decode(:x), do: {:ok, :x}
def decode(:y), do: {:ok, :y}
def decode(:z), do: {:ok, :z}
def decode(:all), do: {:ok, :all}
def encode(:x), do: {:ok, "x"}
def encode(:y), do: {:ok, "y"}
def encode(:z), do: {:ok, "z"}

View file

@ -2,6 +2,9 @@ defmodule Farmbot.CeleryScript.AST.Arg.PinMode do
@moduledoc false
@behaviour Farmbot.CeleryScript.AST.Arg
def decode(val), do: {:ok, val}
def encode(val), do: {:ok, val}
def decode(0), do: {:ok, :digital}
def decode(1), do: {:ok, :analog}
def encode(:digital), do: {:ok, 0}
def encode(:analog), do: {:ok, 1}
end

View file

@ -2,4 +2,11 @@ defmodule Farmbot.CeleryScript.AST.Node.ReadPin do
@moduledoc false
use Farmbot.CeleryScript.AST.Node
allow_args [:pin_number, :label, :pin_mode]
def execute(%{pin_number: pin_num, pin_mode: mode}, _, env) do
case Farmbot.Firmware.read_pin(pin_num, mode) do
{:ok, _} -> {:ok, env}
{:error, reason} -> {:error, reason, env}
end
end
end

View file

@ -2,4 +2,5 @@ defmodule Farmbot.CeleryScript.AST.Node.Sync do
@moduledoc false
use Farmbot.CeleryScript.AST.Node
allow_args []
end

View file

@ -2,4 +2,8 @@ defmodule Farmbot.CeleryScript.AST.Node.TakePhoto do
@moduledoc false
use Farmbot.CeleryScript.AST.Node
allow_args []
def execute(_, _, env) do
Farmbot.CeleryScript.AST.Node.ExecuteScript.execute(%{label: "take-photo"}, [], env)
end
end

View file

@ -1,5 +1,14 @@
defmodule Farmbot.CeleryScript.AST.Node.TogglePin do
@moduledoc false
use Farmbot.CeleryScript.AST.Node
alias Farmbot.CeleryScript.AST.Node
allow_args [:pin_number]
def execute(%{pin_number: num}, _, env) do
case Farmbot.Firmware.read_pin(num, :digital) do
{:ok, 0} -> Node.WritePin.execute(%{pin_mode: :digital, pin_number: num, pin_value: 1}, [], env)
{:ok, 1} -> Node.WritePin.execute(%{pin_mode: :digital, pin_number: num, pin_value: 0}, [], env)
{:error, reason} -> {:error, reason, env}
end
end
end

View file

@ -2,4 +2,11 @@ defmodule Farmbot.CeleryScript.AST.Node.WritePin do
@moduledoc false
use Farmbot.CeleryScript.AST.Node
allow_args [:pin_number, :pin_value, :pin_mode]
def execute(%{pin_mode: mode, pin_value: value, pin_number: num}, [], env) do
case Farmbot.Firmware.write_pin(num, mode, value) do
:ok -> {:ok, env}
{:error, reason} -> {:error, reason, env}
end
end
end

View file

@ -10,9 +10,10 @@ defmodule Farmbot.CeleryScript do
def execute(ast, env \\ struct(Macro.Env))
def execute(%AST{kind: kind, body: body, args: args} = ast, env) do
Logger.debug "doing: #{inspect ast}"
maybe_log_comment(ast)
case kind.execute(args, body, env) do
{:ok, %Macro.Env{} = env} = res -> res
{:ok, %Macro.Env{} = _env} = res -> res
{:ok, %AST{} = ast} -> execute(ast, env)
{:error, reason, _env} when is_binary(reason) -> raise reason
{:error, reason, _env} -> raise inspect(reason)
@ -20,7 +21,7 @@ defmodule Farmbot.CeleryScript do
end
defp maybe_log_comment(%{comment: nil}), do: :ok
defp maybe_log_comment(%AST{comment: comment} = ast) do
defp maybe_log_comment(%AST{comment: comment} = _ast) do
Logger.info "[#{comment.kind}] - #{comment}"
end

View file

@ -73,7 +73,7 @@ defmodule Farmbot.Firmware do
## GenStage
defmodule State do
defstruct handler: nil, handler_mod: nil, idle: false
defstruct handler: nil, handler_mod: nil, idle: false, pins: %{}
end
def init([]) do
@ -112,8 +112,8 @@ defmodule Farmbot.Firmware do
defp handle_gcodes([code | rest], state, acc) do
case handle_gcode(code, state) do
{nil, state} -> handle_gcodes(rest, state, acc)
{key, diff, state} -> handle_gcodes(rest, state, [{key, diff} | acc])
{nil, new_state} -> handle_gcodes(rest, new_state, acc)
{key, diff, new_state} -> handle_gcodes(rest, new_state, [{key, diff} | acc])
end
end
@ -139,6 +139,27 @@ defmodule Farmbot.Firmware do
{nil, state}
end
defp handle_gcode({:report_pin_mode, pin, mode_atom}, state) do
Logger.debug "Got pin mode report: #{pin}: #{mode_atom}"
mode = if(mode_atom == :digital, do: 0, else: 1)
case state.pins[pin] do
%{mode: _, value: _} = pin_map ->
{:pins, %{pin => %{pin_map | mode: mode}}, %{state | pins: %{state.pins | pin => %{pin_map | mode: mode}}}}
nil ->
{:pins, %{pin => %{mode: mode, value: -1}}, %{state | pins: Map.put(state.pins, pin, %{mode: mode, value: -1})}}
end
end
defp handle_gcode({:report_pin_value, pin, value}, state) do
Logger.debug "Got pin value report: #{pin}: #{value} old: #{inspect state.pins[pin]}"
case state.pins[pin] do
%{mode: _, value: _} = pin_map ->
{:pins, %{pin => %{pin_map | value: value}}, %{state | pins: %{state.pins | pin => %{pin_map | value: value}}}}
nil ->
{:pins, %{pin => %{mode: nil, value: value}}, %{state | pins: Map.put(state.pins, pin, %{mode: nil, value: value})}}
end
end
defp handle_gcode(:idle, state) do
{:informational_settings, %{busy: false}, %{state | idle: true}}
end

View file

@ -87,6 +87,23 @@ defmodule Farmbot.Firmware.StubHandler do
{:reply, :ok, [], state}
end
def handle_call({:home, axis, _speed}, _from, state) do
state = %{state | pos: %{state.pos | axis => 0}}
case axis do
:x -> {:reply, :ok, [{:report_current_position, 0, state.pos.y, state.pos.z}], state}
:y -> {:reply, :ok, [{:report_current_position, state.pos.x, 0, state.pos.z}], state}
:z -> {:reply, :ok, [{:report_current_position, state.pos.x, state.pos.y, 0}], state}
end
end
def handle_call({:read_pin, pin, mode}, _from, state) do
{:reply, {:ok, 1}, [{:report_pin_mode, pin, mode}, {:report_pin_value, pin, 1}], state}
end
def handle_call({:write_pin, pin, mode, value}, _from, state) do
{:reply, :ok, [{:report_pin_mode, pin, mode}, {:report_pin_value, pin, value}], state}
end
def handle_call({:zero, axis, _speed}, _from, state) do
state = %{state | pos: %{state.pos | axis => 0}}
case axis do