Add Lua helpers for updating and getting resources
parent
a242cce830
commit
209ded96cb
|
@ -11,12 +11,6 @@ standard library](https://www.lua.org/manual/5.2/).
|
||||||
```lua
|
```lua
|
||||||
-- Comments are ignored by the interpreter
|
-- Comments are ignored by the interpreter
|
||||||
|
|
||||||
-- help(function_name)
|
|
||||||
-- Returns docs for a function
|
|
||||||
|
|
||||||
print(help("send_message"));
|
|
||||||
print(help("get_position"));
|
|
||||||
|
|
||||||
-- get_position()
|
-- get_position()
|
||||||
-- Returns a table containing the current position data
|
-- Returns a table containing the current position data
|
||||||
|
|
||||||
|
@ -28,6 +22,8 @@ else
|
||||||
return false;
|
return false;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return get_position("y") <= 20;
|
||||||
|
|
||||||
-- get_pins()
|
-- get_pins()
|
||||||
-- Returns a table containing current pin data
|
-- Returns a table containing current pin data
|
||||||
|
|
||||||
|
@ -36,10 +32,106 @@ if pins[9] == 1.0 then
|
||||||
return true;
|
return true;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return get_pin(10) == 0;
|
||||||
|
|
||||||
-- send_message(type, message, channels)
|
-- send_message(type, message, channels)
|
||||||
-- Sends a message to farmbot's logger
|
-- Sends a message to farmbot's logger
|
||||||
|
|
||||||
send_message("info", "hello, world", ["toast"])
|
send_message("info", "hello, world", ["toast"]);
|
||||||
|
|
||||||
|
-- calibrate(axis)
|
||||||
|
-- calibrate an axis
|
||||||
|
|
||||||
|
calibrate("x");
|
||||||
|
calibrate("y");
|
||||||
|
calibrate("z");
|
||||||
|
|
||||||
|
-- emergency_lock()
|
||||||
|
-- emergency_unlock()
|
||||||
|
-- lock and unlock farmbot's firmware.
|
||||||
|
send_message("error", "locking the firmware!");
|
||||||
|
emergancy_lock();
|
||||||
|
emergency_unlock();
|
||||||
|
|
||||||
|
-- find_home(axis)
|
||||||
|
-- Find home on an axis.
|
||||||
|
|
||||||
|
find_home("x");
|
||||||
|
find_home("y");
|
||||||
|
find_home("z");
|
||||||
|
|
||||||
|
-- home(axis)
|
||||||
|
-- Go to home on an axis.
|
||||||
|
|
||||||
|
home("x");
|
||||||
|
home("y");
|
||||||
|
home("z");
|
||||||
|
|
||||||
|
-- coordinate(x, y, z)
|
||||||
|
-- create a vec3
|
||||||
|
move_to = coordinate(1.0, 0, 0);
|
||||||
|
|
||||||
|
-- move_absolute(x, y, z)
|
||||||
|
-- Move in a line to a position
|
||||||
|
move_absolute(1.0, 0, 0);
|
||||||
|
move_absolute(coordinate(1.0, 20, 30));
|
||||||
|
|
||||||
|
-- check_position(vec3, tolerance)
|
||||||
|
-- Check a position against Farmbot's current
|
||||||
|
-- position within a error threshold
|
||||||
|
|
||||||
|
move_absolute(1.0, 0, 0);
|
||||||
|
return check_position({x = 1.0, y = 0; z = 0}, 0.50);
|
||||||
|
|
||||||
|
move_absolute(20, 100, 100);
|
||||||
|
return check_position(coordinate(20, 100, 100), 1);
|
||||||
|
|
||||||
|
-- read_status(arg0)
|
||||||
|
-- Get a field on farmbot's current state
|
||||||
|
|
||||||
|
status = read_status();
|
||||||
|
return status.informational_settings.wifi_level >= 5;
|
||||||
|
|
||||||
|
return read_status("location_data", "raw_encoders") >= 1900;
|
||||||
|
|
||||||
|
-- version()
|
||||||
|
-- return Farmbot's current version
|
||||||
|
return version() == "8.1.2";
|
||||||
|
|
||||||
|
-- get_device(field)
|
||||||
|
-- return the device settings
|
||||||
|
|
||||||
|
return get_device().timezone == "America/los_angeles";
|
||||||
|
|
||||||
|
return get_device("name") == "Test Farmbot";
|
||||||
|
|
||||||
|
-- update_device(table)
|
||||||
|
-- update device settings
|
||||||
|
|
||||||
|
update_device({name = "Test Farmbot"});
|
||||||
|
|
||||||
|
-- get_fbos_config(field)
|
||||||
|
-- return the current fbos_config
|
||||||
|
|
||||||
|
return get_fbos_config("auto_sync");
|
||||||
|
return get_fbos_config().os_auto_update;
|
||||||
|
|
||||||
|
-- update_fbos_config(table)
|
||||||
|
-- update the current fbos_config
|
||||||
|
|
||||||
|
update_fbos_config({auto_sync = true, os_auto_update = false});
|
||||||
|
|
||||||
|
-- get_firmware_config(field)
|
||||||
|
-- return current firmware_config data
|
||||||
|
|
||||||
|
return get_firmware_config().encoder_enabled_x == 1.0;
|
||||||
|
|
||||||
|
return get_firmware_config("encoder_enabled_z");
|
||||||
|
|
||||||
|
-- update_firmware_config(table)
|
||||||
|
-- update current firmware_config data
|
||||||
|
|
||||||
|
update_firmware_config({encoder_enabled_z = 1.0});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Expression contract
|
## Expression contract
|
||||||
|
|
|
@ -187,11 +187,16 @@ defmodule FarmbotCeleryScript.Compiler do
|
||||||
|
|
||||||
quote location: :keep do
|
quote location: :keep do
|
||||||
comment_header = unquote(comment_header)
|
comment_header = unquote(comment_header)
|
||||||
|
assertion_type = unquote(assertion_type)
|
||||||
|
|
||||||
case FarmbotCeleryScript.SysCalls.eval_assertion(unquote(compile_ast(expression))) do
|
case FarmbotCeleryScript.SysCalls.eval_assertion(
|
||||||
|
unquote(comment),
|
||||||
|
unquote(compile_ast(expression))
|
||||||
|
) do
|
||||||
{:error, reason} ->
|
{:error, reason} ->
|
||||||
FarmbotCeleryScript.SysCalls.log_assertion(
|
FarmbotCeleryScript.SysCalls.log_assertion(
|
||||||
false,
|
false,
|
||||||
|
assertion_type,
|
||||||
"#{comment_header}failed to evaluate, aborting"
|
"#{comment_header}failed to evaluate, aborting"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -200,34 +205,43 @@ defmodule FarmbotCeleryScript.Compiler do
|
||||||
true ->
|
true ->
|
||||||
FarmbotCeleryScript.SysCalls.log_assertion(
|
FarmbotCeleryScript.SysCalls.log_assertion(
|
||||||
true,
|
true,
|
||||||
|
assertion_type,
|
||||||
"#{comment_header}passed, continuing execution"
|
"#{comment_header}passed, continuing execution"
|
||||||
)
|
)
|
||||||
|
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
false when unquote(assertion_type) == "continue" ->
|
false when assertion_type == "continue" ->
|
||||||
FarmbotCeleryScript.SysCalls.log_assertion(
|
FarmbotCeleryScript.SysCalls.log_assertion(
|
||||||
false,
|
false,
|
||||||
|
assertion_type,
|
||||||
"#{comment_header}failed, continuing execution"
|
"#{comment_header}failed, continuing execution"
|
||||||
)
|
)
|
||||||
|
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
false when unquote(assertion_type) == "abort" ->
|
false when assertion_type == "abort" ->
|
||||||
FarmbotCeleryScript.SysCalls.log_assertion(false, "#{comment_header}failed, aborting")
|
|
||||||
{:error, "Assertion failed (aborting)"}
|
|
||||||
|
|
||||||
false when unquote(assertion_type) == "recover" ->
|
|
||||||
FarmbotCeleryScript.SysCalls.log_assertion(
|
FarmbotCeleryScript.SysCalls.log_assertion(
|
||||||
false,
|
false,
|
||||||
|
assertion_type,
|
||||||
|
"#{comment_header}failed, aborting"
|
||||||
|
)
|
||||||
|
|
||||||
|
{:error, "Assertion failed (aborting)"}
|
||||||
|
|
||||||
|
false when assertion_type == "recover" ->
|
||||||
|
FarmbotCeleryScript.SysCalls.log_assertion(
|
||||||
|
false,
|
||||||
|
assertion_type,
|
||||||
"#{comment_header}failed, recovering and continuing"
|
"#{comment_header}failed, recovering and continuing"
|
||||||
)
|
)
|
||||||
|
|
||||||
unquote(compile_block(then_ast))
|
unquote(compile_block(then_ast))
|
||||||
|
|
||||||
false when unquote(assertion_type) == "abort_recover" ->
|
false when assertion_type == "abort_recover" ->
|
||||||
FarmbotCeleryScript.SysCalls.log_assertion(
|
FarmbotCeleryScript.SysCalls.log_assertion(
|
||||||
false,
|
false,
|
||||||
|
assertion_type,
|
||||||
"#{comment_header}failed, recovering and aborting"
|
"#{comment_header}failed, recovering and aborting"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -67,24 +67,25 @@ defmodule FarmbotCeleryScript.SysCalls do
|
||||||
@callback log(message :: String.t()) :: any()
|
@callback log(message :: String.t()) :: any()
|
||||||
@callback sequence_init_log(message :: String.t()) :: any()
|
@callback sequence_init_log(message :: String.t()) :: any()
|
||||||
@callback sequence_complete_log(message :: String.t()) :: any()
|
@callback sequence_complete_log(message :: String.t()) :: any()
|
||||||
@callback eval_assertion(expression :: String.t()) :: true | false | error()
|
@callback eval_assertion(comment :: String.t(), expression :: String.t()) ::
|
||||||
|
true | false | error()
|
||||||
|
|
||||||
def eval_assertion(sys_calls \\ @sys_calls, expression) when is_binary(expression) do
|
def eval_assertion(sys_calls \\ @sys_calls, comment, expression) when is_binary(expression) do
|
||||||
case sys_calls.eval_assertion(expression) do
|
case sys_calls.eval_assertion(comment, expression) do
|
||||||
true ->
|
true ->
|
||||||
true
|
true
|
||||||
|
|
||||||
false ->
|
false ->
|
||||||
false
|
false
|
||||||
|
|
||||||
{:error, reason} when is_binary(reason) ->
|
{:error, reason} = error when is_binary(reason) ->
|
||||||
or_error(sys_calls, :eval_assertion, [expression], reason)
|
or_error(sys_calls, :eval_assertion, [comment, expression], error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def log_assertion(sys_calls \\ @sys_calls, passed?, message) do
|
def log_assertion(sys_calls \\ @sys_calls, passed?, type, message) do
|
||||||
if function_exported?(sys_calls, :log_assertion, 2) do
|
if function_exported?(sys_calls, :log_assertion, 3) do
|
||||||
apply(sys_calls, :log_assertion, [passed?, message])
|
apply(sys_calls, :log_assertion, [passed?, type, message])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do
|
||||||
def zero(axis), do: error(:zero, [axis])
|
def zero(axis), do: error(:zero, [axis])
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def eval_assertion(expression), do: error(:eval_assertion, [expression])
|
def eval_assertion(comment, expression), do: error(:eval_assertion, [comment, expression])
|
||||||
|
|
||||||
defp error(fun, _args) do
|
defp error(fun, _args) do
|
||||||
msg = """
|
msg = """
|
||||||
|
|
|
@ -96,7 +96,10 @@ defmodule FarmbotExt.AMQP.LogChannel do
|
||||||
# ANSWER(Connor) - because the FE needed it.
|
# ANSWER(Connor) - because the FE needed it.
|
||||||
created_at: DateTime.from_naive!(log.inserted_at, "Etc/UTC") |> DateTime.to_unix(),
|
created_at: DateTime.from_naive!(log.inserted_at, "Etc/UTC") |> DateTime.to_unix(),
|
||||||
channels: log.meta[:channels] || log.meta["channels"] || [],
|
channels: log.meta[:channels] || log.meta["channels"] || [],
|
||||||
assertion_passed: log.meta[:assertion_passed],
|
meta: %{
|
||||||
|
assertion_passed: log.meta[:assertion_passed],
|
||||||
|
assertion_type: log.meta[:assertion_type]
|
||||||
|
},
|
||||||
message: log.message
|
message: log.message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
defmodule FarmbotOS.Lua do
|
defmodule FarmbotOS.Lua do
|
||||||
@type t() :: tuple()
|
@type t() :: tuple()
|
||||||
@type table() :: [{any, any}]
|
@type table() :: [{any, any}]
|
||||||
|
require FarmbotCore.Logger
|
||||||
|
|
||||||
alias FarmbotOS.Lua.Ext.{
|
alias FarmbotOS.Lua.Ext.{
|
||||||
|
Data,
|
||||||
Firmware,
|
Firmware,
|
||||||
Info
|
Info
|
||||||
}
|
}
|
||||||
|
|
||||||
def log_assertion(passed?, message) do
|
def log_assertion(passed?, type, message) do
|
||||||
# FarmbotCore.Logger.dispatch_log(__ENV__, :assertion, 2, message, [assertion_passed: passed?])
|
meta = [assertion_passed: passed?, assertion_type: type]
|
||||||
FarmbotCore.Logger.dispatch_log(__ENV__, :info, 2, message, assertion_passed: passed?)
|
FarmbotCore.Logger.dispatch_log(__ENV__, :assertion, 2, message, meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Evaluates some Lua code. The code should
|
Evaluates some Lua code. The code should
|
||||||
return a boolean value.
|
return a boolean value.
|
||||||
"""
|
"""
|
||||||
def eval_assertion(str) when is_binary(str) do
|
def eval_assertion(comment, str) when is_binary(str) do
|
||||||
init()
|
init()
|
||||||
|> eval(str)
|
|> eval(str)
|
||||||
|> case do
|
|> case do
|
||||||
|
@ -35,6 +38,17 @@ defmodule FarmbotOS.Lua do
|
||||||
{:error, "lua runtime error evaluating expression"}
|
{:error, "lua runtime error evaluating expression"}
|
||||||
|
|
||||||
{:error, {:badmatch, {:error, [{line, :luerl_parse, parse_error}], _}}} ->
|
{:error, {:badmatch, {:error, [{line, :luerl_parse, parse_error}], _}}} ->
|
||||||
|
FarmbotCore.Logger.error(
|
||||||
|
1,
|
||||||
|
"""
|
||||||
|
Failed to parse expression:
|
||||||
|
`#{comment}.lua:#{line}`
|
||||||
|
|
||||||
|
#{IO.iodata_to_binary(parse_error)}
|
||||||
|
""",
|
||||||
|
channels: [:toast]
|
||||||
|
)
|
||||||
|
|
||||||
{:error, "failed to parse expression (line:#{line}): #{IO.iodata_to_binary(parse_error)}"}
|
{:error, "failed to parse expression (line:#{line}): #{IO.iodata_to_binary(parse_error)}"}
|
||||||
|
|
||||||
error ->
|
error ->
|
||||||
|
@ -59,6 +73,14 @@ defmodule FarmbotOS.Lua do
|
||||||
|> set_table([:read_status], &Info.read_status/2)
|
|> set_table([:read_status], &Info.read_status/2)
|
||||||
|> set_table([:send_message], &Info.send_message/2)
|
|> set_table([:send_message], &Info.send_message/2)
|
||||||
|> set_table([:version], &Info.version/2)
|
|> set_table([:version], &Info.version/2)
|
||||||
|
|> set_table([:update_device], &Data.update_device/2)
|
||||||
|
|> set_table([:get_device], &Data.get_device/2)
|
||||||
|
|> set_table([:update_fbos_config], &Data.update_fbos_config/2)
|
||||||
|
|> set_table([:get_fbos_config], &Data.get_fbos_config/2)
|
||||||
|
|> set_table([:update_firmware_config], &Data.update_firmware_config/2)
|
||||||
|
|> set_table([:get_firmware_config], &Data.get_firmware_config/2)
|
||||||
|
|> set_table([:new_farmware_env], &Data.new_farmware_env/2)
|
||||||
|
|> set_table([:new_sensor_reading], &Data.new_sensor_reading/2)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec set_table(t(), Path.t(), any()) :: t()
|
@spec set_table(t(), Path.t(), any()) :: t()
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
defmodule FarmbotOS.Lua.Ext.Data do
|
||||||
|
@moduledoc """
|
||||||
|
Extensions for manipulating data from Lua
|
||||||
|
"""
|
||||||
|
import FarmbotOS.Lua.Util
|
||||||
|
|
||||||
|
alias FarmbotCore.{
|
||||||
|
Asset,
|
||||||
|
Asset.Device,
|
||||||
|
Asset.FbosConfig,
|
||||||
|
Asset.FirmwareConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
def update_device([table], lua) do
|
||||||
|
params = Map.new(table)
|
||||||
|
_ = Asset.update_device!(params)
|
||||||
|
{[true], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_device([field], lua) do
|
||||||
|
device = Asset.device() |> Device.render()
|
||||||
|
{[device[String.to_atom(field)]], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_device(_, lua) do
|
||||||
|
device = Asset.device() |> Device.render()
|
||||||
|
{[map_to_table(device)], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_fbos_config([table], lua) do
|
||||||
|
params = Map.new(table)
|
||||||
|
_ = Asset.update_fbos_config!(params)
|
||||||
|
{[true], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_fbos_config([field], lua) do
|
||||||
|
fbos_config = Asset.fbos_config() |> FbosConfig.render()
|
||||||
|
{[fbos_config[String.to_atom(field)]], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_fbos_config(_, lua) do
|
||||||
|
fbos_config = Asset.fbos_config() |> FbosConfig.render()
|
||||||
|
{[map_to_table(fbos_config)], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_firmware_config([table], lua) do
|
||||||
|
params = Map.new(table)
|
||||||
|
_ = Asset.update_firmware_config!(params)
|
||||||
|
{[true], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_firmware_config([field], lua) do
|
||||||
|
firmware_config = Asset.firmware_config() |> FirmwareConfig.render()
|
||||||
|
{[firmware_config[String.to_atom(field)]], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_firmware_config(_, lua) do
|
||||||
|
firmware_config = Asset.firmware_config() |> FirmwareConfig.render()
|
||||||
|
{[map_to_table(firmware_config)], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_farmware_env([table], lua) do
|
||||||
|
params = Map.new(table)
|
||||||
|
_ = Asset.new_farmware_env(params)
|
||||||
|
{[true], lua}
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_sensor_reading([table], lua) do
|
||||||
|
params = Map.new(table)
|
||||||
|
_ = Asset.new_sensor_reading!(params)
|
||||||
|
{[true], lua}
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,7 @@
|
||||||
defmodule FarmbotOS.Lua.Ext.Info do
|
defmodule FarmbotOS.Lua.Ext.Info do
|
||||||
|
@moduledoc """
|
||||||
|
Lua extensions for gathering information about Farmbot
|
||||||
|
"""
|
||||||
alias FarmbotCeleryScript.SysCalls
|
alias FarmbotCeleryScript.SysCalls
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -22,76 +25,24 @@ defmodule FarmbotOS.Lua.Ext.Info do
|
||||||
do_send_message(kind, message, channels, lua)
|
do_send_message(kind, message, channels, lua)
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_status(_, lua) do
|
@doc "Returns data about the bot's state"
|
||||||
bot_state = FarmbotCore.BotState.fetch()
|
def read_status([], lua) do
|
||||||
|
bot_state = FarmbotCore.BotState.fetch() |> FarmbotCore.BotStateNG.view()
|
||||||
|
|
||||||
configuration_table = [
|
{[map_to_table(bot_state)], lua}
|
||||||
{"arduino_debug_messages", bot_state.configuration.arduino_debug_messages},
|
end
|
||||||
{"auto_sync", bot_state.configuration.auto_sync},
|
|
||||||
{"beta_opt_in", bot_state.configuration.beta_opt_in},
|
|
||||||
{"disable_factory_reset", bot_state.configuration.disable_factory_reset},
|
|
||||||
{"firmware_hardware", bot_state.configuration.firmware_hardware},
|
|
||||||
{"firmware_input_log", bot_state.configuration.firmware_input_log},
|
|
||||||
{"firmware_output_log", bot_state.configuration.firmware_output_log},
|
|
||||||
{"network_not_found_timer", bot_state.configuration.network_not_found_timer},
|
|
||||||
{"os_auto_update", bot_state.configuration.os_auto_update},
|
|
||||||
{"sequence_body_log", bot_state.configuration.sequence_body_log},
|
|
||||||
{"sequence_complete_log", bot_state.configuration.sequence_complete_log},
|
|
||||||
{"sequence_init_log", bot_state.configuration.sequence_init_log}
|
|
||||||
]
|
|
||||||
|
|
||||||
informational_settings_table = [
|
def read_status(path, lua) do
|
||||||
{"busy", bot_state.informational_settings.busy},
|
bot_state = FarmbotCore.BotState.fetch() |> FarmbotCore.BotStateNG.view()
|
||||||
{"cache_bust", bot_state.informational_settings.cache_bust},
|
path = List.flatten(path) |> Enum.map(&String.to_atom(&1))
|
||||||
{"commit", bot_state.informational_settings.commit},
|
|
||||||
{"controller_version", bot_state.informational_settings.controller_version},
|
|
||||||
{"disk_usage", bot_state.informational_settings.disk_usage},
|
|
||||||
{"env", bot_state.informational_settings.env},
|
|
||||||
{"firmware_commit", bot_state.informational_settings.firmware_commit},
|
|
||||||
{"firmware_version", bot_state.informational_settings.firmware_version},
|
|
||||||
{"idle", bot_state.informational_settings.idle},
|
|
||||||
{"last_status", bot_state.informational_settings.last_status},
|
|
||||||
{"locked", bot_state.informational_settings.locked},
|
|
||||||
{"memory_usage", bot_state.informational_settings.memory_usage},
|
|
||||||
{"node_name", bot_state.informational_settings.node_name},
|
|
||||||
{"soc_temp", bot_state.informational_settings.soc_temp},
|
|
||||||
{"sync_status", bot_state.informational_settings.sync_status},
|
|
||||||
{"target", bot_state.informational_settings.target},
|
|
||||||
{"throttled", bot_state.informational_settings.throttled},
|
|
||||||
{"update_available", bot_state.informational_settings.update_available},
|
|
||||||
{"uptime", bot_state.informational_settings.uptime},
|
|
||||||
{"wifi_level", bot_state.informational_settings.wifi_level},
|
|
||||||
{"wifi_level_percent", bot_state.informational_settings.wifi_level_percent}
|
|
||||||
]
|
|
||||||
|
|
||||||
location_data_table = [
|
case get_in(bot_state, path) do
|
||||||
{"position",
|
%{} = map ->
|
||||||
[
|
{[map_to_table(map)], lua}
|
||||||
{"x", bot_state.location_data.position.x},
|
|
||||||
{"y", bot_state.location_data.position.y},
|
|
||||||
{"z", bot_state.location_data.position.z}
|
|
||||||
]},
|
|
||||||
{"raw_encoders",
|
|
||||||
[
|
|
||||||
{"x", bot_state.location_data.raw_encoders.x},
|
|
||||||
{"y", bot_state.location_data.raw_encoders.y},
|
|
||||||
{"z", bot_state.location_data.raw_encoders.z}
|
|
||||||
]},
|
|
||||||
{"scaled_encoders",
|
|
||||||
[
|
|
||||||
{"x", bot_state.location_data.scaled_encoders.x},
|
|
||||||
{"y", bot_state.location_data.scaled_encoders.y},
|
|
||||||
{"z", bot_state.location_data.scaled_encoders.z}
|
|
||||||
]}
|
|
||||||
]
|
|
||||||
|
|
||||||
final_table = [
|
other ->
|
||||||
{"configuration", configuration_table},
|
{[other], lua}
|
||||||
{"informational_settings", informational_settings_table},
|
end
|
||||||
{"location_data", location_data_table}
|
|
||||||
]
|
|
||||||
|
|
||||||
{[final_table, nil], lua}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Returns the current version of farmbot."
|
@doc "Returns the current version of farmbot."
|
||||||
|
@ -108,4 +59,14 @@ defmodule FarmbotOS.Lua.Ext.Info do
|
||||||
{[nil, reason], lua}
|
{[nil, reason], lua}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp map_to_table(map) do
|
||||||
|
Enum.map(map, fn
|
||||||
|
{key, %{} = value} ->
|
||||||
|
{to_string(key), map_to_table(value)}
|
||||||
|
|
||||||
|
{key, value} ->
|
||||||
|
{to_string(key), value}
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
defmodule FarmbotOS.Lua.Util do
|
||||||
|
@doc "Convert an Elixir map to a Lua table"
|
||||||
|
def map_to_table(map) do
|
||||||
|
Enum.map(map, fn
|
||||||
|
{key, %{} = value} ->
|
||||||
|
{to_string(key), map_to_table(value)}
|
||||||
|
|
||||||
|
{key, value} ->
|
||||||
|
{to_string(key), value}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
|
@ -61,8 +61,8 @@ defmodule FarmbotOS.SysCalls do
|
||||||
defdelegate set_pin_io_mode(pin, mode), to: SetPinIOMode
|
defdelegate set_pin_io_mode(pin, mode), to: SetPinIOMode
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
defdelegate eval_assertion(expression), to: Lua
|
defdelegate eval_assertion(comment, expression), to: Lua
|
||||||
defdelegate log_assertion(passed?, message), to: Lua
|
defdelegate log_assertion(passed?, type, message), to: Lua
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def log(message) do
|
def log(message) do
|
||||||
|
|
|
@ -242,8 +242,8 @@ defmodule Farmbot.TestSupport.CeleryScript.TestSysCalls do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def eval_assertion(expression) do
|
def eval_assertion(comment, expression) do
|
||||||
call({:eval_assertion, [expression]})
|
call({:eval_assertion, [comment, expression]})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp call(data) do
|
defp call(data) do
|
||||||
|
|
Loading…
Reference in New Issue