2019-03-05 10:14:01 -07:00
|
|
|
defmodule FarmbotCeleryScript.SysCalls do
|
2019-02-20 12:57:45 -07:00
|
|
|
@moduledoc """
|
|
|
|
Behaviour for abstracting CeleryScript functionality.
|
|
|
|
"""
|
2019-03-05 10:14:01 -07:00
|
|
|
alias FarmbotCeleryScript.{AST, RuntimeError}
|
2019-02-20 12:57:45 -07:00
|
|
|
|
|
|
|
@sys_call_implementation Application.get_env(:farmbot_celery_script, __MODULE__)[:sys_calls]
|
|
|
|
@sys_call_implementation ||
|
|
|
|
Mix.raise("""
|
2019-03-05 10:14:01 -07:00
|
|
|
config :farmbot_celery_script, FarmbotCeleryScript.SysCalls, [
|
2019-02-20 12:57:45 -07:00
|
|
|
sys_calls: SomeModuleThatImplementsTheBehaviour
|
|
|
|
]
|
|
|
|
""")
|
|
|
|
|
|
|
|
@type error :: {:error, String.t()}
|
|
|
|
|
|
|
|
@type resource_id :: integer()
|
|
|
|
|
|
|
|
@type point_type :: String.t()
|
|
|
|
@type named_pin_type :: String.t()
|
|
|
|
|
|
|
|
@type axis_position :: float()
|
|
|
|
@type axis :: String.t()
|
|
|
|
@type axis_speed :: integer()
|
|
|
|
@type coordinate :: %{x: axis_position, y: axis_position, z: axis_position}
|
|
|
|
|
2019-04-15 16:36:39 -06:00
|
|
|
@type pin_number :: {:boxled, 3 | 4} | integer
|
2019-02-20 12:57:45 -07:00
|
|
|
@type pin_mode :: 0 | 1 | nil
|
|
|
|
@type pin_value :: integer
|
|
|
|
|
|
|
|
@type milliseconds :: integer
|
|
|
|
|
|
|
|
@type message_level :: String.t()
|
|
|
|
@type message_channel :: String.t()
|
2019-03-19 14:59:22 -06:00
|
|
|
@type package :: String.t()
|
2019-02-20 12:57:45 -07:00
|
|
|
|
|
|
|
@callback point(point_type, resource_id) :: coordinate | error
|
|
|
|
@callback move_absolute(x :: axis_position, y :: axis_position, z :: axis_position, axis_speed) ::
|
|
|
|
:ok | error
|
2019-04-09 15:43:41 -06:00
|
|
|
@callback find_home(axis) :: :ok | error
|
2019-02-20 12:57:45 -07:00
|
|
|
|
2019-03-04 14:32:56 -07:00
|
|
|
@callback calibrate(axis) :: :ok | error
|
|
|
|
|
2019-02-20 12:57:45 -07:00
|
|
|
@callback get_current_x() :: axis_position | error
|
|
|
|
@callback get_current_y() :: axis_position | error
|
|
|
|
@callback get_current_z() :: axis_position | error
|
|
|
|
|
|
|
|
@callback write_pin(pin_number, pin_mode, pin_value) :: :ok | error
|
|
|
|
@callback read_pin(pin_number, pin_mode) :: :ok | error
|
|
|
|
@callback named_pin(named_pin_type, resource_id) :: pin_number | error
|
|
|
|
|
|
|
|
@callback wait(milliseconds) :: any()
|
|
|
|
|
|
|
|
@callback send_message(message_level, String.t(), [message_channel]) :: :ok | error
|
|
|
|
|
|
|
|
@callback get_sequence(resource_id) :: map() | error
|
|
|
|
@callback execute_script(String.t(), map()) :: :ok | error
|
|
|
|
|
|
|
|
@callback read_status() :: map()
|
|
|
|
|
2019-03-14 11:29:23 -06:00
|
|
|
@callback set_user_env(String.t(), String.t()) :: :ok | error
|
2019-02-20 12:57:45 -07:00
|
|
|
|
|
|
|
@callback sync() :: :ok | error
|
2019-04-15 16:36:39 -06:00
|
|
|
@callback resource_update(String.t(), number(), map) :: :ok | error
|
|
|
|
|
|
|
|
@callback power_off() :: :ok | error
|
|
|
|
@callback reboot() :: :ok | error
|
|
|
|
@callback factory_reset() :: :ok | error
|
|
|
|
@callback change_ownership(String.t(), binary()) :: :ok | error
|
|
|
|
@callback dump_info() :: :ok | error
|
2019-02-20 12:57:45 -07:00
|
|
|
|
2019-03-19 14:59:22 -06:00
|
|
|
@callback flash_firmware(package) :: :ok | error
|
2019-04-15 16:36:39 -06:00
|
|
|
@callback firmware_reboot() :: :ok | error
|
|
|
|
|
2019-04-17 11:52:44 -06:00
|
|
|
@callback emergency_lock() :: :ok | error
|
|
|
|
@callback emergency_unlock() :: :ok | error
|
|
|
|
|
2019-04-17 12:19:28 -06:00
|
|
|
@callback check_update() :: :ok | error
|
|
|
|
|
|
|
|
def check_update(module \\ @sys_call_implementation) do
|
|
|
|
_ = module.check_update()
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
2019-04-17 11:52:44 -06:00
|
|
|
def emergency_lock(module \\ @sys_call_implementation) do
|
|
|
|
_ = module.emergency_lock()
|
2019-04-17 12:19:28 -06:00
|
|
|
:ok
|
2019-04-17 11:52:44 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def emergency_unlock(module \\ @sys_call_implementation) do
|
|
|
|
_ = module.emergency_unlock()
|
2019-04-17 12:19:28 -06:00
|
|
|
:ok
|
2019-04-17 11:52:44 -06:00
|
|
|
end
|
|
|
|
|
2019-04-15 16:36:39 -06:00
|
|
|
def power_off(module \\ @sys_call_implementation) do
|
|
|
|
_ = module.factory_reset()
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
def reboot(module \\ @sys_call_implementation) do
|
|
|
|
_ = module.reboot()
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
def factory_reset(module \\ @sys_call_implementation) do
|
|
|
|
_ = module.factory_reset()
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
def change_ownership(module \\ @sys_call_implementation, email, secret) do
|
|
|
|
_ = module.change_ownership(email, secret)
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
def dump_info(module \\ @sys_call_implementation) do
|
|
|
|
case module.dump_info() do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
2019-03-19 14:59:22 -06:00
|
|
|
|
|
|
|
def flash_firmware(module \\ @sys_call_implementation, package) do
|
|
|
|
case module.flash_firmware(package) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-04-15 16:36:39 -06:00
|
|
|
def firmware_reboot(module \\ @sys_call_implementation) do
|
|
|
|
case module.firmware_reboot() do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-20 12:57:45 -07:00
|
|
|
def point(module \\ @sys_call_implementation, type, id) do
|
|
|
|
case module.point(type, id) do
|
|
|
|
%{x: x, y: y, z: z} -> coordinate(x, y, z)
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def move_absolute(module \\ @sys_call_implementation, x, y, z, speed) do
|
|
|
|
case module.move_absolute(x, y, z, speed) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-04 14:32:56 -07:00
|
|
|
def calibrate(module \\ @sys_call_implementation, axis) do
|
|
|
|
case module.calibrate(axis) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-20 12:57:45 -07:00
|
|
|
def get_current_x(module \\ @sys_call_implementation) do
|
|
|
|
case module.get_current_x() do
|
|
|
|
position when is_number(position) -> position
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_current_y(module \\ @sys_call_implementation) do
|
|
|
|
case module.get_current_y() do
|
|
|
|
position when is_number(position) -> position
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_current_z(module \\ @sys_call_implementation) do
|
|
|
|
case module.get_current_z() do
|
|
|
|
position when is_number(position) -> position
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def write_pin(module \\ @sys_call_implementation, pin_number, pin_mode, pin_value) do
|
|
|
|
case module.write_pin(pin_number, pin_mode, pin_value) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_pin(module \\ @sys_call_implementation, pin_number, pin_mode) do
|
|
|
|
case module.read_pin(pin_number, pin_mode) do
|
|
|
|
value when is_number(value) -> value
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def named_pin(module \\ @sys_call_implementation, type, id) do
|
|
|
|
case module.named_pin(type, id) do
|
|
|
|
{:boxled, boxledid} when boxledid in [3, 4] -> {:boxled, boxledid}
|
|
|
|
number when is_integer(number) -> number
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def wait(module \\ @sys_call_implementation, milliseconds) do
|
|
|
|
_ = module.wait(milliseconds)
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_message(module \\ @sys_call_implementation, level, message, channels) do
|
|
|
|
case module.send_message(level, message, channels) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-04-09 15:43:41 -06:00
|
|
|
def find_home(module \\ @sys_call_implementation, axis) do
|
|
|
|
case module.find_home(axis) do
|
2019-02-20 12:57:45 -07:00
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_sequence(module \\ @sys_call_implementation, id) do
|
|
|
|
case module.get_sequence(id) do
|
|
|
|
%{kind: _, args: _} = probably_sequence ->
|
|
|
|
AST.decode(probably_sequence)
|
|
|
|
|
|
|
|
{:error, reason} when is_binary(reason) ->
|
|
|
|
error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute_script(module \\ @sys_call_implementation, name, args) do
|
|
|
|
case module.execute_script(name, args) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_status(module \\ @sys_call_implementation) do
|
|
|
|
_ = module.read_status
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_user_env(module \\ @sys_call_implementation, key, val) do
|
|
|
|
case module.set_user_env(key, val) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def sync(module \\ @sys_call_implementation) do
|
|
|
|
case module.sync() do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-04-15 16:36:39 -06:00
|
|
|
def resource_update(module \\ @sys_call_implementation, kind, id, params) do
|
|
|
|
case module.resource_update(kind, id, params) do
|
|
|
|
:ok -> :ok
|
|
|
|
{:error, reason} when is_binary(reason) -> error(reason)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-20 12:57:45 -07:00
|
|
|
def nothing, do: nil
|
|
|
|
|
|
|
|
def coordinate(x, y, z) do
|
|
|
|
%{x: x, y: y, z: z}
|
|
|
|
end
|
|
|
|
|
|
|
|
def error(message) when is_binary(message) do
|
|
|
|
raise RuntimeError, message: message
|
|
|
|
end
|
|
|
|
end
|