2019-03-05 12:35:09 -07:00
|
|
|
defmodule FarmbotOS.SysCalls do
|
|
|
|
require FarmbotCore.Logger
|
|
|
|
|
|
|
|
alias FarmbotCeleryScript.AST
|
|
|
|
alias FarmbotFirmware
|
|
|
|
|
2019-03-19 14:59:22 -06:00
|
|
|
alias FarmbotOS.SysCalls.{SendMessage, ExecuteScript, FlashFirmware}
|
2019-03-05 12:35:09 -07:00
|
|
|
|
|
|
|
alias FarmbotCore.{Asset, Asset.Repo, Asset.Sync, BotState}
|
|
|
|
alias FarmbotExt.{API, API.Reconciler, API.SyncGroup}
|
|
|
|
alias Ecto.{Changeset, Multi}
|
|
|
|
|
|
|
|
@behaviour FarmbotCeleryScript.SysCalls
|
2019-02-20 12:57:45 -07:00
|
|
|
|
|
|
|
defdelegate send_message(level, message, channels), to: SendMessage
|
2019-03-14 11:29:23 -06:00
|
|
|
defdelegate execute_script(name, env), to: ExecuteScript
|
2019-03-19 14:59:22 -06:00
|
|
|
defdelegate flash_firmware(package), to: FlashFirmware
|
2019-02-20 12:57:45 -07:00
|
|
|
|
|
|
|
def read_status do
|
2019-03-27 08:33:32 -06:00
|
|
|
:ok = FarmbotExt.AMQP.BotStateNGChannel.force()
|
2019-02-20 12:57:45 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def set_user_env(key, value) do
|
2019-03-05 12:35:09 -07:00
|
|
|
FarmbotCore.BotState.set_user_env(key, value)
|
2019-02-20 12:57:45 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def get_current_x do
|
|
|
|
get_position(:x)
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_current_y do
|
|
|
|
get_position(:y)
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_current_z do
|
|
|
|
get_position(:z)
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_pin(pin_number, mode) do
|
2019-03-05 12:35:09 -07:00
|
|
|
case FarmbotFirmware.request({nil, {:pin_read, [p: pin_number, m: mode]}}) do
|
2019-03-04 14:32:56 -07:00
|
|
|
{:ok, {_, {:report_pin_value, [p: _, v: val]}}} ->
|
|
|
|
val
|
|
|
|
|
|
|
|
{:error, reason} ->
|
2019-04-08 15:48:17 -06:00
|
|
|
{:error, "Firmware error: #{inspect(reason)}"}
|
2019-03-04 14:32:56 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def write_pin(pin_number, mode, value) do
|
2019-03-05 12:35:09 -07:00
|
|
|
case FarmbotFirmware.command({:pin_write, [p: pin_number, v: value, m: mode]}) do
|
2019-04-08 15:48:17 -06:00
|
|
|
:ok ->
|
|
|
|
:ok
|
|
|
|
|
|
|
|
{:error, reason} ->
|
|
|
|
{:error, "Firmware error: #{inspect(reason)}"}
|
2019-03-04 14:32:56 -07:00
|
|
|
end
|
2019-02-20 12:57:45 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def point(kind, id) do
|
2019-03-05 12:35:09 -07:00
|
|
|
case Asset.get_point(id: id) do
|
2019-02-20 12:57:45 -07:00
|
|
|
nil -> {:error, "#{kind} not found"}
|
|
|
|
%{x: x, y: y, z: z} -> %{x: x, y: y, z: z}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defp get_position(axis) do
|
2019-04-09 15:43:41 -06:00
|
|
|
axis = assert_axis!(axis)
|
|
|
|
|
2019-03-05 12:35:09 -07:00
|
|
|
case FarmbotFirmware.request({nil, {:position_read, []}}) do
|
2019-03-04 14:32:56 -07:00
|
|
|
{:ok, {_, {:report_position, params}}} ->
|
2019-02-20 12:57:45 -07:00
|
|
|
Keyword.fetch!(params, axis)
|
|
|
|
|
2019-03-04 14:32:56 -07:00
|
|
|
{:error, reason} ->
|
2019-04-08 15:48:17 -06:00
|
|
|
{:error, "Firmware error: #{inspect(reason)}"}
|
2019-02-20 12:57:45 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def move_absolute(x, y, z, speed) do
|
|
|
|
params = [x: x / 1.0, y: y / 1.0, z: z / 1.0, s: speed / 1.0]
|
|
|
|
|
2019-03-05 12:35:09 -07:00
|
|
|
case FarmbotFirmware.command({nil, {:command_movement, params}}) do
|
2019-03-04 14:32:56 -07:00
|
|
|
:ok ->
|
|
|
|
:ok
|
|
|
|
|
|
|
|
{:error, reason} ->
|
2019-04-08 15:48:17 -06:00
|
|
|
{:error, "Firmware error: #{inspect(reason)}"}
|
2019-03-04 14:32:56 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def calibrate(axis) do
|
2019-04-09 15:43:41 -06:00
|
|
|
axis = assert_axis!(axis)
|
|
|
|
|
2019-03-05 12:35:09 -07:00
|
|
|
case FarmbotFirmware.command({:command_movement_calibrate, axis}) do
|
2019-03-04 14:32:56 -07:00
|
|
|
:ok ->
|
|
|
|
:ok
|
|
|
|
|
|
|
|
{:error, reason} ->
|
2019-04-09 15:43:41 -06:00
|
|
|
{:error, "Firmware error: #{inspect(reason)}"}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def find_home(axis) do
|
|
|
|
axis = assert_axis!(axis)
|
|
|
|
|
|
|
|
case FarmbotFirmware.command({:command_movement_find_home, axis}) do
|
|
|
|
:ok ->
|
|
|
|
:ok
|
|
|
|
|
|
|
|
{:error, reason} ->
|
|
|
|
{:error, "Firmware error: #{inspect(reason)}"}
|
2019-02-20 12:57:45 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-04-09 15:43:41 -06:00
|
|
|
defp assert_axis!(axis) when is_atom(axis),
|
|
|
|
do: axis
|
|
|
|
|
|
|
|
defp assert_axis!(axis) when axis in ~w(x y z),
|
|
|
|
do: String.to_existing_atom(axis)
|
|
|
|
|
|
|
|
defp assert_axis!(axis) do
|
|
|
|
# {:error, "unknown axis #{axis}"}
|
|
|
|
raise("unknown axis #{axis}")
|
|
|
|
end
|
|
|
|
|
|
|
|
def wait(ms) do
|
|
|
|
Process.sleep(ms)
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
|
|
|
|
def named_pin(kind, id) do
|
|
|
|
{:error, "unknown pin kind: #{kind} of id: #{id}"}
|
|
|
|
end
|
|
|
|
|
2019-02-20 12:57:45 -07:00
|
|
|
def get_sequence(id) do
|
2019-03-05 12:35:09 -07:00
|
|
|
case Asset.get_sequence(id: id) do
|
2019-02-20 12:57:45 -07:00
|
|
|
nil -> {:error, "sequence not found"}
|
|
|
|
%{} = sequence -> AST.decode(sequence)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def sync() do
|
2019-03-05 12:35:09 -07:00
|
|
|
FarmbotCore.Logger.busy(3, "Syncing")
|
2019-02-20 12:57:45 -07:00
|
|
|
sync_changeset = API.get_changeset(Sync)
|
|
|
|
sync = Changeset.apply_changes(sync_changeset)
|
|
|
|
multi = Multi.new()
|
|
|
|
|
2019-03-05 12:35:09 -07:00
|
|
|
:ok = BotState.set_sync_status("syncing")
|
2019-02-20 12:57:45 -07:00
|
|
|
|
2019-03-14 15:37:03 -06:00
|
|
|
with {:ok, multi} <- Reconciler.sync_group(multi, sync, SyncGroup.group_0()),
|
|
|
|
{:ok, multi} <- Reconciler.sync_group(multi, sync, SyncGroup.group_1()),
|
2019-02-20 12:57:45 -07:00
|
|
|
{:ok, multi} <- Reconciler.sync_group(multi, sync, SyncGroup.group_2()),
|
|
|
|
{:ok, multi} <- Reconciler.sync_group(multi, sync, SyncGroup.group_3()),
|
|
|
|
{:ok, multi} <- Reconciler.sync_group(multi, sync, SyncGroup.group_4()) do
|
|
|
|
Multi.insert(multi, :syncs, sync_changeset)
|
|
|
|
|> Repo.transaction()
|
|
|
|
|
2019-03-05 12:35:09 -07:00
|
|
|
FarmbotCore.Logger.success(3, "Synced")
|
|
|
|
:ok = BotState.set_sync_status("synced")
|
2019-02-20 12:57:45 -07:00
|
|
|
:ok
|
|
|
|
else
|
|
|
|
error ->
|
2019-03-05 12:35:09 -07:00
|
|
|
:ok = BotState.set_sync_status("sync_error")
|
2019-02-20 12:57:45 -07:00
|
|
|
{:error, inspect(error)}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|