Change if and read_pin to function the same as v7
this prevents the possibility of reading a sensor and it changing by the time an if statement is executedpull/974/head
parent
b42992c3c8
commit
8a816ba1f4
|
@ -267,23 +267,26 @@ defmodule FarmbotCeleryScript.Compiler do
|
|||
lhs =
|
||||
case lhs_ast do
|
||||
"x" ->
|
||||
quote [location: :keep], do: FarmbotCeleryScript.SysCalls.get_current_x()
|
||||
quote [location: :keep],
|
||||
do: FarmbotCeleryScript.SysCalls.get_cached_x()
|
||||
|
||||
"y" ->
|
||||
quote [location: :keep], do: FarmbotCeleryScript.SysCalls.get_current_y()
|
||||
quote [location: :keep],
|
||||
do: FarmbotCeleryScript.SysCalls.get_cached_y()
|
||||
|
||||
"z" ->
|
||||
quote [location: :keep], do: FarmbotCeleryScript.SysCalls.get_current_z()
|
||||
quote [location: :keep],
|
||||
do: FarmbotCeleryScript.SysCalls.get_cached_z()
|
||||
|
||||
"pin" <> pin ->
|
||||
quote [location: :keep],
|
||||
do: FarmbotCeleryScript.SysCalls.read_pin(unquote(String.to_integer(pin)), nil)
|
||||
do: FarmbotCeleryScript.SysCalls.read_cached_pin(unquote(String.to_integer(pin)))
|
||||
|
||||
# Named pin has two intents here
|
||||
# in this case we want to read the named pin.
|
||||
%AST{kind: :named_pin} = ast ->
|
||||
quote [location: :keep],
|
||||
do: FarmbotCeleryScript.SysCalls.read_pin(unquote(compile_ast(ast)), nil)
|
||||
do: FarmbotCeleryScript.SysCalls.read_cached_pin(unquote(compile_ast(ast)))
|
||||
|
||||
%AST{} = ast ->
|
||||
compile_ast(ast)
|
||||
|
|
|
@ -38,6 +38,11 @@ defmodule FarmbotCeleryScript.SysCalls do
|
|||
@callback get_current_x() :: number() | error()
|
||||
@callback get_current_y() :: number() | error()
|
||||
@callback get_current_z() :: number() | error()
|
||||
|
||||
@callback get_cached_x() :: number() | error()
|
||||
@callback get_cached_y() :: number() | error()
|
||||
@callback get_cached_z() :: number() | error()
|
||||
|
||||
@callback get_sequence(resource_id) :: FarmbotCeleryScript.AST.t() | error()
|
||||
@callback get_toolslot_for_tool(resource_id) ::
|
||||
%{x: number(), y: number(), z: number()} | error()
|
||||
|
@ -51,6 +56,7 @@ defmodule FarmbotCeleryScript.SysCalls do
|
|||
@callback point(point_type :: String.t(), resource_id) :: number() | error()
|
||||
@callback power_off() :: ok_or_error
|
||||
@callback read_pin(pin_num :: number(), pin_mode :: number()) :: number | error()
|
||||
@callback read_cached_pin(pin_num :: number()) :: number | error()
|
||||
@callback toggle_pin(pin_num :: number()) :: ok_or_error
|
||||
@callback read_status() :: ok_or_error
|
||||
@callback reboot() :: ok_or_error
|
||||
|
@ -184,6 +190,18 @@ defmodule FarmbotCeleryScript.SysCalls do
|
|||
number_or_error(sys_calls, :get_current_z, [])
|
||||
end
|
||||
|
||||
def get_cached_x(sys_calls \\ @sys_calls) do
|
||||
number_or_nil_or_error(sys_calls, :get_cached_x, [])
|
||||
end
|
||||
|
||||
def get_cached_y(sys_calls \\ @sys_calls) do
|
||||
number_or_nil_or_error(sys_calls, :get_cached_y, [])
|
||||
end
|
||||
|
||||
def get_cached_z(sys_calls \\ @sys_calls) do
|
||||
number_or_nil_or_error(sys_calls, :get_cached_z, [])
|
||||
end
|
||||
|
||||
def get_sequence(sys_calls \\ @sys_calls, sequence_id) do
|
||||
case sys_calls.get_sequence(sequence_id) do
|
||||
%AST{} = ast -> ast
|
||||
|
@ -236,6 +254,10 @@ defmodule FarmbotCeleryScript.SysCalls do
|
|||
number_or_error(sys_calls, :read_pin, [pin_num, pin_mode])
|
||||
end
|
||||
|
||||
def read_cached_pin(sys_calls \\ @sys_calls, pin_num) do
|
||||
number_or_nil_or_error(sys_calls, :read_cached_pin, [pin_num])
|
||||
end
|
||||
|
||||
def toggle_pin(sys_calls \\ @sys_calls, pun_num) do
|
||||
ok_or_error(sys_calls, :toggle_pin, [pun_num])
|
||||
end
|
||||
|
@ -298,6 +320,14 @@ defmodule FarmbotCeleryScript.SysCalls do
|
|||
end
|
||||
end
|
||||
|
||||
defp number_or_nil_or_error(sys_calls, fun, args) do
|
||||
case apply(sys_calls, fun, args) do
|
||||
result when is_number(result) -> result
|
||||
nil -> nil
|
||||
error -> or_error(sys_calls, fun, args, error)
|
||||
end
|
||||
end
|
||||
|
||||
defp coord_or_error(sys_calls, fun, args) do
|
||||
case apply(sys_calls, fun, args) do
|
||||
%{x: x, y: y, z: z} = coord when is_number(x) when is_number(y) when is_number(z) -> coord
|
||||
|
|
|
@ -64,6 +64,15 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do
|
|||
@impl true
|
||||
def get_current_z(), do: error(:get_current_z, [])
|
||||
|
||||
@impl true
|
||||
def get_cached_x(), do: error(:get_cached_x, [])
|
||||
|
||||
@impl true
|
||||
def get_cached_y(), do: error(:get_cached_y, [])
|
||||
|
||||
@impl true
|
||||
def get_cached_z(), do: error(:get_cached_z, [])
|
||||
|
||||
@impl true
|
||||
def get_sequence(resource_id), do: error(:get_sequence, [resource_id])
|
||||
|
||||
|
@ -94,6 +103,9 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do
|
|||
@impl true
|
||||
def read_pin(pin_num, pin_mode), do: error(:read_pin, [pin_num, pin_mode])
|
||||
|
||||
@impl true
|
||||
def read_cached_pin(pin_num), do: error(:read_cached_pin, [pin_num])
|
||||
|
||||
@impl true
|
||||
def toggle_pin(pin_num), do: error(:toggle_pin, [pin_num])
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ defmodule FarmbotOS.SysCalls do
|
|||
@impl true
|
||||
defdelegate read_pin(number, mode), to: PinControl
|
||||
|
||||
@impl true
|
||||
defdelegate read_cached_pin(number), to: PinControl
|
||||
|
||||
@impl true
|
||||
defdelegate write_pin(number, mode, value), to: PinControl
|
||||
|
||||
|
@ -171,6 +174,21 @@ defmodule FarmbotOS.SysCalls do
|
|||
get_position(:z)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def get_cached_x do
|
||||
get_cached_position(:x)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def get_cached_y do
|
||||
get_cached_position(:y)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def get_cached_z do
|
||||
get_cached_position(:z)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def zero(axis) do
|
||||
axis = assert_axis!(axis)
|
||||
|
@ -211,6 +229,16 @@ defmodule FarmbotOS.SysCalls do
|
|||
end
|
||||
end
|
||||
|
||||
def get_cached_position() do
|
||||
%{x: x, y: y, z: z} = FarmbotCore.BotState.fetch().location_data.position
|
||||
[x: x, y: y, z: z]
|
||||
end
|
||||
|
||||
def get_cached_position(axis) do
|
||||
axis = assert_axis!(axis)
|
||||
Keyword.fetch!(get_cached_position(), axis)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def move_absolute(x, y, z, speed) do
|
||||
do_move_absolute(x, y, z, speed, max_retries())
|
||||
|
|
|
@ -9,6 +9,14 @@ defmodule FarmbotOS.SysCalls.PinControl do
|
|||
|
||||
require FarmbotCore.Logger
|
||||
|
||||
def read_cached_pin(%_{pin: number}) do
|
||||
read_cached_pin(number)
|
||||
end
|
||||
|
||||
def read_cached_pin(pin_number) do
|
||||
FarmbotCore.BotState.fetch().pins()[pin_number][:value]
|
||||
end
|
||||
|
||||
def toggle_pin(pin_number) when is_number(pin_number) do
|
||||
peripheral = Asset.get_peripheral_by_pin(pin_number)
|
||||
|
||||
|
@ -198,19 +206,16 @@ defmodule FarmbotOS.SysCalls.PinControl do
|
|||
end
|
||||
|
||||
# Peripheral digital
|
||||
def write_pin(%Peripheral{pin: pin, label: label}, 0, 1) do
|
||||
FarmbotCore.Logger.info(2, "Turning the #{label} ON (digital)")
|
||||
def write_pin(%Peripheral{pin: pin, label: _label}, 0, 1) do
|
||||
do_write_pin(pin, 0, 1)
|
||||
end
|
||||
|
||||
def write_pin(%Peripheral{pin: pin, label: label}, 0, 0) do
|
||||
FarmbotCore.Logger.info(2, "Turning the #{label} OFF (digital)")
|
||||
def write_pin(%Peripheral{pin: pin, label: _label}, 0, 0) do
|
||||
do_write_pin(pin, 0, 0)
|
||||
end
|
||||
|
||||
# Peripheral analog
|
||||
def write_pin(%Peripheral{pin: pin, label: label}, 1, value) do
|
||||
FarmbotCore.Logger.info(2, "Setting the #{label} to #{value} (analog)")
|
||||
def write_pin(%Peripheral{pin: pin, label: _label}, 1, _value) do
|
||||
do_write_pin(pin, 0, 0)
|
||||
end
|
||||
|
||||
|
@ -248,17 +253,14 @@ defmodule FarmbotOS.SysCalls.PinControl do
|
|||
|
||||
# Generic pin digital
|
||||
def write_pin(pin, 0, 1) do
|
||||
FarmbotCore.Logger.info(2, "Turning pin #{pin} ON (digital)")
|
||||
do_write_pin(pin, 0, 1)
|
||||
end
|
||||
|
||||
def write_pin(pin, 0, 0) do
|
||||
FarmbotCore.Logger.info(2, "Turning pin #{pin} OFF (digital)")
|
||||
do_write_pin(pin, 0, 0)
|
||||
end
|
||||
|
||||
def write_pin(pin, 1, value) do
|
||||
FarmbotCore.Logger.info(2, "Setting pin #{pin} to #{value} (analog)")
|
||||
do_write_pin(pin, 1, value)
|
||||
end
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ defmodule FarmbotOS.SysCalls.SendMessage do
|
|||
|
||||
def render(templ) do
|
||||
with {:ok, pos} <- pos(),
|
||||
{:ok, pins} <- pins(Enum.to_list(0..69)),
|
||||
{:ok, pins} <- pins(),
|
||||
env <- Keyword.merge(pos, pins) do
|
||||
env = Map.new(env, fn {k, v} -> {to_string(k), to_string(v)} end)
|
||||
|
||||
|
@ -44,33 +44,22 @@ defmodule FarmbotOS.SysCalls.SendMessage do
|
|||
end
|
||||
|
||||
def pos do
|
||||
case FarmbotFirmware.request({:position_read, []}) do
|
||||
{:ok, {_, {:report_position, [x: x, y: y, z: z]}}} ->
|
||||
{:ok,
|
||||
[
|
||||
x: FarmbotCeleryScript.FormatUtil.format_float(x),
|
||||
y: FarmbotCeleryScript.FormatUtil.format_float(y),
|
||||
z: FarmbotCeleryScript.FormatUtil.format_float(z)
|
||||
]}
|
||||
[x: x, y: y, z: z] = FarmbotOS.SysCalls.get_cached_position()
|
||||
|
||||
{:error, reason} ->
|
||||
{:error, inspect(reason)}
|
||||
end
|
||||
{:ok,
|
||||
[
|
||||
x: FarmbotCeleryScript.FormatUtil.format_float(x),
|
||||
y: FarmbotCeleryScript.FormatUtil.format_float(y),
|
||||
z: FarmbotCeleryScript.FormatUtil.format_float(z)
|
||||
]}
|
||||
end
|
||||
|
||||
def pins(nums, acc \\ [])
|
||||
|
||||
def pins([p | rest], acc) do
|
||||
case FarmbotFirmware.request({:pin_read, [p: p]}) do
|
||||
{:ok, {_, {:report_pin_value, [p: ^p, v: v]}}} ->
|
||||
v = FarmbotCeleryScript.FormatUtil.format_float(v)
|
||||
acc = Keyword.put(acc, :"pin#{p}", v)
|
||||
pins(rest, acc)
|
||||
|
||||
er ->
|
||||
er
|
||||
end
|
||||
def pins() do
|
||||
{:ok,
|
||||
FarmbotCore.BotState.fetch().pins
|
||||
|> Map.new()
|
||||
|> Enum.map(fn {p, %{value: v}} ->
|
||||
{:"pin#{p}", FarmbotCeleryScript.FormatUtil.format_float(v)}
|
||||
end)}
|
||||
end
|
||||
|
||||
def pins([], acc), do: {:ok, acc}
|
||||
end
|
||||
|
|
|
@ -106,6 +106,21 @@ defmodule Farmbot.TestSupport.CeleryScript.TestSysCalls do
|
|||
call({:get_current_z, []})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def get_cached_x do
|
||||
call({:get_cached_x, []})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def get_cached_y do
|
||||
call({:get_cached_y, []})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def get_cached_z do
|
||||
call({:get_cached_z, []})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def write_pin(pin_number, mode, value) do
|
||||
call({:write_pin, [pin_number, mode, value]})
|
||||
|
@ -121,6 +136,11 @@ defmodule Farmbot.TestSupport.CeleryScript.TestSysCalls do
|
|||
call({:read_pin, [number, mode]})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def read_cached_pin(number) do
|
||||
call({:read_cached_pin, [number]})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def toggle_pin(number) do
|
||||
call({:toggle_pin, [number]})
|
||||
|
|
Loading…
Reference in New Issue