diff --git a/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex b/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex index 261ee9e5..39aef2b4 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex @@ -31,11 +31,6 @@ defmodule FarmbotCeleryScript.AST.Factory do ) end - def dump_info(%AST{} = ast) do - ast - |> add_body_node(new(:dump_info)) - end - def emergency_lock(%AST{} = ast) do ast |> add_body_node(new(:emergency_lock)) diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex index 40c3a744..eaa40171 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex @@ -279,12 +279,6 @@ defmodule FarmbotCeleryScript.Compiler do end end - def dump_info(_, _env) do - quote location: :keep do - FarmbotCeleryScript.SysCalls.dump_info() - end - end - defp print_compiled_code(compiled) do IO.puts("========") diff --git a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex index f7533663..5c9f0169 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex @@ -29,7 +29,6 @@ defmodule FarmbotCeleryScript.SysCalls do @callback check_update() :: ok_or_error @callback coordinate(x :: number, y :: number, z :: number) :: %{x: number(), y: number(), z: number()} | error - @callback dump_info() :: ok_or_error @callback emergency_lock() :: ok_or_error @callback emergency_unlock() :: ok_or_error @callback execute_script(package, args :: map()) :: ok_or_error @@ -172,10 +171,6 @@ defmodule FarmbotCeleryScript.SysCalls do coord_or_error(sys_calls, :coordinate, [x, y, z]) end - def dump_info(sys_calls \\ @sys_calls) do - ok_or_error(sys_calls, :dump_info, []) - end - def emergency_lock(sys_calls \\ @sys_calls) do ok_or_error(sys_calls, :emergency_lock, []) end diff --git a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex index e6d6b09e..ee903926 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex @@ -28,9 +28,6 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do @impl true def coordinate(x, y, z), do: error(:coordinate, [x, y, z]) - @impl true - def dump_info(), do: error(:dump_info, []) - @impl true def emergency_lock(), do: error(:emergency_lock, []) diff --git a/farmbot_celery_script/test/farmbot_celery_script/corpus/node_test.exs b/farmbot_celery_script/test/farmbot_celery_script/corpus/node_test.exs index ed412b77..5709cd3b 100644 --- a/farmbot_celery_script/test/farmbot_celery_script/corpus/node_test.exs +++ b/farmbot_celery_script/test/farmbot_celery_script/corpus/node_test.exs @@ -3,7 +3,7 @@ defmodule FarmbotCeleryScript.Corpus.NodeTest do alias FarmbotCeleryScript.Corpus test "inspect" do - assert "Sequence(version, locals) [calibrate, change_ownership, check_updates, dump_info, emergency_lock, emergency_unlock, execute, execute_script, factory_reset, find_home, flash_firmware, home, install_farmware, install_first_party_farmware, _if, move_absolute, move_relative, power_off, read_pin, read_status, reboot, remove_farmware, resource_update, send_message, set_servo_angle, set_user_env, sync, take_photo, toggle_pin, update_farmware, wait, write_pin, zero]" = + assert "Sequence(version, locals) [calibrate, change_ownership, check_updates, emergency_lock, emergency_unlock, execute, execute_script, factory_reset, find_home, flash_firmware, home, install_farmware, install_first_party_farmware, _if, move_absolute, move_relative, power_off, read_pin, read_status, reboot, remove_farmware, resource_update, send_message, set_servo_angle, set_user_env, sync, take_photo, toggle_pin, update_farmware, wait, write_pin, zero]" = inspect(Corpus.sequence()) end end diff --git a/farmbot_core/lib/farmbot_core/asset.ex b/farmbot_core/lib/farmbot_core/asset.ex index 079e6916..c289ce0a 100644 --- a/farmbot_core/lib/farmbot_core/asset.ex +++ b/farmbot_core/lib/farmbot_core/asset.ex @@ -9,7 +9,6 @@ defmodule FarmbotCore.Asset do Repo, Device, DeviceCert, - DiagnosticDump, FarmwareEnv, FirstPartyFarmware, FarmwareInstallation, @@ -54,6 +53,7 @@ defmodule FarmbotCore.Asset do if device = Repo.get_by(Device, id: id) do Repo.delete!(device) end + :ok end @@ -78,13 +78,14 @@ defmodule FarmbotCore.Asset do end def update_farm_event!(farm_event, params) do - farm_event = - farm_event |> - FarmEvent.changeset(params) + farm_event = + farm_event + |> FarmEvent.changeset(params) |> Repo.update!() if farm_event.executable_type == "Regimen" do regimen_instance = get_regimen_instance(farm_event) + if regimen_instance do regimen_instance |> Repo.preload([:farm_event, :regimen]) @@ -111,9 +112,11 @@ defmodule FarmbotCore.Asset do def get_farm_event_execution(%FarmEvent{} = farm_event, scheduled_at) do Repo.one( - from e in FarmEvent.Execution, - where: e.farm_event_local_id == ^farm_event.local_id - and e.scheduled_at == ^scheduled_at + from(e in FarmEvent.Execution, + where: + e.farm_event_local_id == ^farm_event.local_id and + e.scheduled_at == ^scheduled_at + ) ) end @@ -149,6 +152,7 @@ defmodule FarmbotCore.Asset do if fbos_config = Repo.get_by(FbosConfig, id: id) do Repo.delete!(fbos_config) end + :ok end @@ -177,6 +181,7 @@ defmodule FarmbotCore.Asset do if firmware_config = Repo.get_by(FirmwareConfig, id: id) do Repo.delete!(firmware_config) end + :ok end @@ -192,12 +197,19 @@ defmodule FarmbotCore.Asset do end def get_regimen_instance(%FarmEvent{} = farm_event) do - regimen = Repo.one(from r in Regimen, where: r.id == ^farm_event.executable_id) - regimen && Repo.one(from ri in RegimenInstance, where: ri.regimen_id == ^regimen.local_id and ri.farm_event_id == ^farm_event.local_id) + regimen = Repo.one(from(r in Regimen, where: r.id == ^farm_event.executable_id)) + + regimen && + Repo.one( + from(ri in RegimenInstance, + where: ri.regimen_id == ^regimen.local_id and ri.farm_event_id == ^farm_event.local_id + ) + ) end def new_regimen_instance!(%FarmEvent{} = farm_event, params \\ %{}) do - regimen = Repo.one!(from r in Regimen, where: r.id == ^farm_event.executable_id) + regimen = Repo.one!(from(r in Regimen, where: r.id == ^farm_event.executable_id)) + RegimenInstance.changeset(%RegimenInstance{}, params) |> Ecto.Changeset.put_assoc(:regimen, regimen) |> Ecto.Changeset.put_assoc(:farm_event, farm_event) @@ -207,7 +219,7 @@ defmodule FarmbotCore.Asset do def delete_regimen_instance!(%RegimenInstance{} = ri) do Repo.delete!(ri) end - + def add_execution_to_regimen_instance!(%RegimenInstance{} = ri, params \\ %{}) do %RegimenInstance.Execution{} |> RegimenInstance.Execution.changeset(params) @@ -217,9 +229,11 @@ defmodule FarmbotCore.Asset do def get_regimen_instance_execution(%RegimenInstance{} = ri, scheduled_at) do Repo.one( - from e in RegimenInstance.Execution, - where: e.regimen_instance_local_id == ^ri.local_id - and e.scheduled_at == ^scheduled_at + from(e in RegimenInstance.Execution, + where: + e.regimen_instance_local_id == ^ri.local_id and + e.scheduled_at == ^scheduled_at + ) ) end @@ -248,7 +262,7 @@ defmodule FarmbotCore.Asset do @doc "Returns all points matching Point.pointer_type" def get_all_points_by_type(type, order_by \\ "random") do - (from p in Point, where: p.pointer_type == ^type and is_nil(p.discarded_at)) + from(p in Point, where: p.pointer_type == ^type and is_nil(p.discarded_at)) |> Repo.all() |> sort_points(order_by) end @@ -257,7 +271,7 @@ defmodule FarmbotCore.Asset do points |> Enum.group_by(&group_points_by(&1, order_by)) |> Enum.sort(&group_sort(&1, &2, order_by)) - |> Enum.map(fn({_group_index, group}) -> Enum.sort(group, &sort_points(&1, &2, order_by)) end) + |> Enum.map(fn {_group_index, group} -> Enum.sort(group, &sort_points(&1, &2, order_by)) end) |> List.flatten() end @@ -272,7 +286,6 @@ defmodule FarmbotCore.Asset do def group_sort({lgroup, _}, {rgroup, _}, "yx_descending"), do: lgroup >= rgroup def group_sort(_, _, "random"), do: Enum.random([true, false]) - def sort_points(%{y: ly}, %{y: ry}, "xy_ascending"), do: ly <= ry def sort_points(%{y: ly}, %{y: ry}, "xy_descending"), do: ly >= ry def sort_points(%{x: lx}, %{x: rx}, "yx_ascending"), do: lx <= rx @@ -285,15 +298,15 @@ defmodule FarmbotCore.Asset do def get_point_group(params) do case Repo.get_by(PointGroup, params) do - nil -> + nil -> nil - %{sort_type: nil} = group -> - group + %{sort_type: nil} = group -> + group %{point_ids: unsorted, sort_type: sort_by} = point_group -> - sorted = - Repo.all(from p in Point, where: p.id in ^unsorted) + sorted = + Repo.all(from(p in Point, where: p.id in ^unsorted)) |> sort_points(sort_by) |> Enum.map(&Map.fetch!(&1, :id)) @@ -308,7 +321,7 @@ defmodule FarmbotCore.Asset do end def update_point_group!(point_group, params) do - updated = + updated = point_group |> PointGroup.changeset(params) |> Repo.update!() @@ -322,11 +335,11 @@ defmodule FarmbotCore.Asset do for asset <- farm_events ++ regimen_instances do # TODO(Connor) this might be worth creating a behaviour for if uses_point_group?(asset, point_group) do - Logger.debug "#{inspect(asset)} uses PointGroup: #{inspect(point_group)}. Reindexing it." + Logger.debug("#{inspect(asset)} uses PointGroup: #{inspect(point_group)}. Reindexing it.") FarmbotCore.AssetSupervisor.update_child(asset) end end - + updated end @@ -335,14 +348,16 @@ defmodule FarmbotCore.Asset do end def uses_point_group?(%FarmEvent{body: body}, %PointGroup{id: point_group_id}) do - any_body_node_uses_point_group?(body, point_group_id) end - def uses_point_group?(%Regimen{body: body, regimen_items: regimen_items}, %PointGroup{id: point_group_id}) do - any_body_node_uses_point_group?(body, point_group_id) || Enum.find(regimen_items, fn(%{sequence_id: sequence_id}) -> - any_body_node_uses_point_group?(get_sequence(sequence_id).body, point_group_id) - end) + def uses_point_group?(%Regimen{body: body, regimen_items: regimen_items}, %PointGroup{ + id: point_group_id + }) do + any_body_node_uses_point_group?(body, point_group_id) || + Enum.find(regimen_items, fn %{sequence_id: sequence_id} -> + any_body_node_uses_point_group?(get_sequence(sequence_id).body, point_group_id) + end) end def uses_point_group?(%RegimenInstance{farm_event: farm_event, regimen: regimen}, point_group) do @@ -350,11 +365,13 @@ defmodule FarmbotCore.Asset do end def any_body_node_uses_point_group?(body, point_group_id) do - Enum.find(body, fn + Enum.find(body, fn %{ kind: "execute", body: execute_body - } -> any_body_node_uses_point_group?(execute_body, point_group_id) + } -> + any_body_node_uses_point_group?(execute_body, point_group_id) + %{ args: %{ "data_value" => %{ @@ -364,7 +381,8 @@ defmodule FarmbotCore.Asset do "label" => "parent" }, kind: "parameter_application" - } -> true + } -> + true %{ args: %{ @@ -375,8 +393,11 @@ defmodule FarmbotCore.Asset do "label" => "parent" }, kind: "parameter_application" - } -> true - _ -> false + } -> + true + + _ -> + false end) end @@ -407,6 +428,7 @@ defmodule FarmbotCore.Asset do def new_public_key_from_home!() do public_key_path = Path.join([System.get_env("HOME"), ".ssh", "id_rsa.pub"]) public_key = File.read!(public_key_path) + %PublicKey{} |> PublicKey.changeset(%{public_key: public_key}) |> Repo.insert() @@ -417,7 +439,7 @@ defmodule FarmbotCore.Asset do |> PublicKey.changeset(%{public_key: public_key}) |> Repo.insert() end - + ## End PublicKey ## Begin Regimen @@ -435,18 +457,23 @@ defmodule FarmbotCore.Asset do end def delete_regimen!(regimen) do - regimen_instances = Repo.all(from ri in RegimenInstance, where: ri.regimen_id == ^regimen.local_id) + regimen_instances = + Repo.all(from(ri in RegimenInstance, where: ri.regimen_id == ^regimen.local_id)) + for ri <- regimen_instances do - IO.puts "deleting regimen instance: #{inspect(ri)}" + IO.puts("deleting regimen instance: #{inspect(ri)}") delete_regimen_instance!(ri) end + Repo.delete!(regimen) end @doc "Update an existing regimen" def update_regimen!(regimen, params) do - regimen_instances = Repo.all(from ri in RegimenInstance, where: ri.regimen_id == ^regimen.local_id) - |> Repo.preload([:farm_event, :regimen]) + regimen_instances = + Repo.all(from(ri in RegimenInstance, where: ri.regimen_id == ^regimen.local_id)) + |> Repo.preload([:farm_event, :regimen]) + for ri <- regimen_instances do ri |> RegimenInstance.changeset(%{updated_at: DateTime.utc_now()}) @@ -469,23 +496,31 @@ defmodule FarmbotCore.Asset do def update_sequence!(%Sequence{} = sequence, params \\ %{}) do sequence_id = sequence.id - farm_events = Repo.all(from f in FarmEvent, - where: f.executable_type == "Sequence" - and f.executable_id == ^sequence_id) - regimen_instances = RegimenInstance - |> Repo.all() - |> Repo.preload([:regimen, :farm_event]) - |> Enum.filter(fn - %{regimen: %{regimen_items: items}} -> - Enum.find(items, fn - %{sequence_id: ^sequence_id} -> true - %{sequence_id: _} -> true + farm_events = + Repo.all( + from(f in FarmEvent, + where: + f.executable_type == "Sequence" and + f.executable_id == ^sequence_id + ) + ) + + regimen_instances = + RegimenInstance + |> Repo.all() + |> Repo.preload([:regimen, :farm_event]) + |> Enum.filter(fn + %{regimen: %{regimen_items: items}} -> + Enum.find(items, fn + %{sequence_id: ^sequence_id} -> true + %{sequence_id: _} -> true + end) + + %{regimen: nil} -> + false end) - %{regimen: nil} -> false - end) - for asset <- farm_events ++ regimen_instances do FarmbotCore.AssetSupervisor.update_child(asset) end @@ -507,10 +542,11 @@ defmodule FarmbotCore.Asset do def get_farmware_manifest(package) do first_party_farmwares = Repo.all(from(fwi in FirstPartyFarmware, select: fwi.manifest)) regular_farmwares = Repo.all(from(fwi in FarmwareInstallation, select: fwi.manifest)) + Enum.find( - first_party_farmwares ++ regular_farmwares, - fn - %{package: pkg} -> pkg == package + first_party_farmwares ++ regular_farmwares, + fn + %{package: pkg} -> pkg == package _ -> false end ) @@ -519,10 +555,11 @@ defmodule FarmbotCore.Asset do def get_farmware_installation(package) do first_party_farmwares = Repo.all(from(fwi in FirstPartyFarmware)) regular_farmwares = Repo.all(from(fwi in FarmwareInstallation)) + Enum.find( - first_party_farmwares ++ regular_farmwares, - fn - %{manifest: %{package: pkg}} -> pkg == package + first_party_farmwares ++ regular_farmwares, + fn + %{manifest: %{package: pkg}} -> pkg == package _ -> false end ) @@ -530,12 +567,14 @@ defmodule FarmbotCore.Asset do def upsert_farmware_manifest_by_id(id, params) do fwi = Repo.get_by(FarmwareInstallation, id: id) || %FarmwareInstallation{} + FarmwareInstallation.changeset(fwi, params) |> Repo.insert_or_update() end def upsert_first_party_farmware_manifest_by_id(id, params) do fwi = Repo.get_by(FirstPartyFarmware, id: id) || %FirstPartyFarmware{} + FirstPartyFarmware.changeset(fwi, params) |> Repo.insert_or_update() end @@ -557,12 +596,14 @@ defmodule FarmbotCore.Asset do def new_farmware_env(params) do key = params["key"] || params[:key] - fwe = with key when is_binary(key) <- key, - [fwe | _] <- Repo.all(from fwe in FarmwareEnv, where: fwe.key == ^key) do - fwe - else - _ -> %FarmwareEnv{} - end + + fwe = + with key when is_binary(key) <- key, + [fwe | _] <- Repo.all(from(fwe in FarmwareEnv, where: fwe.key == ^key)) do + fwe + else + _ -> %FarmwareEnv{} + end FarmwareEnv.changeset(fwe, params) |> Repo.insert_or_update() @@ -596,7 +637,7 @@ defmodule FarmbotCore.Asset do Sensor.changeset(%Sensor{}, params) |> Repo.insert!() end - + def update_sensor!(sensor, params) do sensor |> Sensor.changeset(params) @@ -624,15 +665,6 @@ defmodule FarmbotCore.Asset do ## End SensorReading - ## Begin DiagnosticDump - - def new_diagnostic_dump(params) do - DiagnosticDump.changeset(%DiagnosticDump{}, params) - |> Repo.insert() - end - - ## End DiagnosticDump - ## Begin DeviceCert def new_device_cert(params) do diff --git a/farmbot_core/lib/farmbot_core/asset/command.ex b/farmbot_core/lib/farmbot_core/asset/command.ex index e007f477..994a9030 100644 --- a/farmbot_core/lib/farmbot_core/asset/command.ex +++ b/farmbot_core/lib/farmbot_core/asset/command.ex @@ -4,6 +4,7 @@ defmodule FarmbotCore.Asset.Command do """ require Logger alias FarmbotCore.{Asset, Asset.Repo} + alias FarmbotCore.Asset.{ Device, FarmEvent, @@ -44,31 +45,31 @@ defmodule FarmbotCore.Asset.Command do :ok end - def update(Device, _id, params) do + def update(Device, _id, params) do Asset.update_device!(params) :ok end - def update(FbosConfig, id, nil) do + def update(FbosConfig, id, nil) do Asset.delete_fbos_config!(id) :ok end - def update(FbosConfig, _id, params) do + def update(FbosConfig, _id, params) do Asset.update_fbos_config!(params) :ok end - def update(FirmwareConfig, id, nil) do + def update(FirmwareConfig, id, nil) do Asset.delete_firmware_config!(id) :ok end - - def update(FirmwareConfig, _id, params) do + + def update(FirmwareConfig, _id, params) do Asset.update_firmware_config!(params) :ok end - + # Deletion use case: # TODO(Connor) put checks for deleting Device, FbosConfig and FirmwareConfig @@ -96,12 +97,12 @@ defmodule FarmbotCore.Asset.Command do :ok end - def update(FarmwareEnv, id, params) do + def update(FarmwareEnv, id, params) do Asset.upsert_farmware_env_by_id(id, params) :ok end - - def update(FarmwareInstallation, id, params) do + + def update(FarmwareInstallation, id, params) do Asset.upsert_farmware_manifest_by_id(id, params) :ok end @@ -112,15 +113,17 @@ defmodule FarmbotCore.Asset.Command do def update(FarmEvent, id, params) do old = Asset.get_farm_event(id) - if old, - do: Asset.update_farm_event!(old, params), + + if old, + do: Asset.update_farm_event!(old, params), else: Asset.new_farm_event!(params) - + :ok end def update(PublicKey, id, params) do old = Asset.get_public_key(id) + if old, do: Asset.update_public_key!(old, params), else: Asset.new_public_key!(params) @@ -130,33 +133,37 @@ defmodule FarmbotCore.Asset.Command do def update(Regimen, id, params) do old = Asset.get_regimen(id) - if old, - do: Asset.update_regimen!(old, params), + + if old, + do: Asset.update_regimen!(old, params), else: Asset.new_regimen!(params) - + :ok end def update(Sensor, id, params) do old = Asset.get_sensor(id) - if old, - do: Asset.update_sensor!(old, params), + + if old, + do: Asset.update_sensor!(old, params), else: Asset.new_sensor!(params) - + :ok end def update(SensorReading, id, params) do old = Asset.get_sensor_reading(id) - if old, - do: Asset.update_sensor_reading!(old, params), + + if old, + do: Asset.update_sensor_reading!(old, params), else: Asset.new_sensor_reading!(params) - + :ok end def update(Sequence, id, params) do old = Asset.get_sequence(id) + if old, do: Asset.update_sequence!(old, params), else: Asset.new_sequence!(params) @@ -172,6 +179,7 @@ defmodule FarmbotCore.Asset.Command do def update(PointGroup, id, params) do old = Asset.get_point_group(id: id) + if old, do: Asset.update_point_group!(old, params), else: Asset.new_point_group!(params) @@ -181,8 +189,9 @@ defmodule FarmbotCore.Asset.Command do # Catch-all use case: def update(asset_kind, id, params) do - Logger.warn "AssetCommand needs implementation: #{asset_kind}" + Logger.warn("AssetCommand needs implementation: #{asset_kind}") mod = as_module!(asset_kind) + case Repo.get_by(mod, id: id) do nil -> struct!(mod) @@ -205,28 +214,27 @@ defmodule FarmbotCore.Asset.Command do mod.changeset(asset, params) end - defp as_module!("Device"), do: Asset.Device - defp as_module!("DiagnosticDump"), do: Asset.DiagnosticDump - defp as_module!("FarmEvent"), do: Asset.FarmEvent - defp as_module!("FarmwareEnv"), do: Asset.FarmwareEnv - defp as_module!("FirstPartyFarmware"), do: Asset.FirstPartyFarmware - defp as_module!("FarmwareInstallation"), do: Asset.FarmwareInstallation - defp as_module!("FbosConfig"), do: Asset.FbosConfig - defp as_module!("FirmwareConfig"), do: Asset.FirmwareConfig - defp as_module!("Peripheral"), do: Asset.Peripheral - defp as_module!("PinBinding"), do: Asset.PinBinding - defp as_module!("Point"), do: Asset.Point - defp as_module!("PointGroup"), do: Asset.PointGroup - defp as_module!("Regimen"), do: Asset.Regimen - defp as_module!("Sensor"), do: Asset.Sensor - defp as_module!("SensorReading"), do: Asset.SensorReading - defp as_module!("Sequence"), do: Asset.Sequence - defp as_module!("Tool"), do: Asset.Tool + defp as_module!("Device"), do: Asset.Device + defp as_module!("FarmEvent"), do: Asset.FarmEvent + defp as_module!("FarmwareEnv"), do: Asset.FarmwareEnv + defp as_module!("FirstPartyFarmware"), do: Asset.FirstPartyFarmware + defp as_module!("FarmwareInstallation"), do: Asset.FarmwareInstallation + defp as_module!("FbosConfig"), do: Asset.FbosConfig + defp as_module!("FirmwareConfig"), do: Asset.FirmwareConfig + defp as_module!("Peripheral"), do: Asset.Peripheral + defp as_module!("PinBinding"), do: Asset.PinBinding + defp as_module!("Point"), do: Asset.Point + defp as_module!("PointGroup"), do: Asset.PointGroup + defp as_module!("Regimen"), do: Asset.Regimen + defp as_module!("Sensor"), do: Asset.Sensor + defp as_module!("SensorReading"), do: Asset.SensorReading + defp as_module!("Sequence"), do: Asset.Sequence + defp as_module!("Tool"), do: Asset.Tool defp as_module!(module) when is_atom(module) do as_module!(List.last(Module.split(module))) end - + defp as_module!(kind) when is_binary(kind) do raise(""" Unknown kind: #{kind} diff --git a/farmbot_core/lib/farmbot_core/asset/diagnostic_dump.ex b/farmbot_core/lib/farmbot_core/asset/diagnostic_dump.ex deleted file mode 100644 index 8aa9c4ac..00000000 --- a/farmbot_core/lib/farmbot_core/asset/diagnostic_dump.ex +++ /dev/null @@ -1,58 +0,0 @@ -defmodule FarmbotCore.Asset.DiagnosticDump do - @moduledoc """ - Just the DiagDump REST resource, used by FarmBot staff to help users debug - remote device problems. - """ - use FarmbotCore.Asset.Schema, path: "/api/diagnostic_dumps" - - schema "diagnostic_dumps" do - field(:id, :id) - - has_one(:local_meta, FarmbotCore.Asset.Private.LocalMeta, - on_delete: :delete_all, - references: :local_id, - foreign_key: :asset_local_id - ) - - field(:ticket_identifier, :string) - field(:fbos_commit, :string) - field(:fbos_version, :string) - field(:firmware_commit, :string) - field(:firmware_state, :string) - field(:network_interface, :string) - field(:fbos_dmesg_dump, :string) - field(:monitor, :boolean, default: true) - timestamps() - end - - view diagnostic_dump do - %{ - id: diagnostic_dump.id, - ticket_identifier: diagnostic_dump.ticket_identifier, - fbos_commit: diagnostic_dump.fbos_commit, - fbos_version: diagnostic_dump.fbos_version, - firmware_commit: diagnostic_dump.firmware_commit, - firmware_state: diagnostic_dump.firmware_state, - network_interface: diagnostic_dump.network_interface, - fbos_dmesg_dump: diagnostic_dump.fbos_dmesg_dump - } - end - - def changeset(diagnostic_dump, params \\ %{}) do - diagnostic_dump - |> cast(params, [ - :id, - :ticket_identifier, - :fbos_commit, - :fbos_version, - :firmware_commit, - :firmware_state, - :network_interface, - :fbos_dmesg_dump, - :monitor, - :created_at, - :updated_at - ]) - |> validate_required([]) - end -end diff --git a/farmbot_core/lib/farmbot_core/asset/pin_binding.ex b/farmbot_core/lib/farmbot_core/asset/pin_binding.ex index e167a2d3..a655c3df 100644 --- a/farmbot_core/lib/farmbot_core/asset/pin_binding.ex +++ b/farmbot_core/lib/farmbot_core/asset/pin_binding.ex @@ -100,16 +100,15 @@ defimpl String.Chars, for: FarmbotCore.Asset.PinBinding do end defp special_action(button_number, action, pin_num) do - "Button #{button_number}: #{format_action(action)} (Pi #{pin_num})" + "Button #{button_number}: #{format_action(action)} (Pi #{pin_num})" end - defp format_action("dump_info"), do: "Dump Info" - defp format_action("emergency_lock"), do: "E-Stop" + defp format_action("emergency_lock"), do: "E-Stop" defp format_action("emergency_unlock"), do: "E-Unlock" defp format_action("power_off"), do: "Power Off" defp format_action("read_status"), do: "Read Status" defp format_action("reboot"), do: "Reboot" defp format_action("sync"), do: "Sync" - defp format_action("take_photo"), do: "Take Photo" + defp format_action("take_photo"), do: "Take Photo" defp format_action(_), do: nil end diff --git a/farmbot_core/lib/farmbot_core/asset/private/local_meta.ex b/farmbot_core/lib/farmbot_core/asset/private/local_meta.ex index bc23eb93..de3605f4 100644 --- a/farmbot_core/lib/farmbot_core/asset/private/local_meta.ex +++ b/farmbot_core/lib/farmbot_core/asset/private/local_meta.ex @@ -9,7 +9,6 @@ defmodule FarmbotCore.Asset.Private.LocalMeta do alias FarmbotCore.Asset.{ Repo, Device, - DiagnosticDump, DeviceCert, FarmEvent, FarmwareEnv, @@ -47,13 +46,6 @@ defmodule FarmbotCore.Asset.Private.LocalMeta do define_field: false ) - belongs_to(:diagnostic_dump, DiagnosticDump, - foreign_key: :asset_local_id, - type: :binary_id, - references: :local_id, - define_field: false - ) - belongs_to(:farm_event, FarmEvent, foreign_key: :asset_local_id, type: :binary_id, @@ -174,8 +166,7 @@ defmodule FarmbotCore.Asset.Private.LocalMeta do "firmware_configs", "fbos_configs", "farmware_installations", - "farmware_envs", - "diagnostic_dumps" + "farmware_envs" ]) |> unsafe_validate_unique([:table, :asset_local_id], Repo, message: "LocalMeta already exists." diff --git a/farmbot_core/lib/farmbot_core/asset/sync.ex b/farmbot_core/lib/farmbot_core/asset/sync.ex index 31e0e7f8..f065b3b1 100644 --- a/farmbot_core/lib/farmbot_core/asset/sync.ex +++ b/farmbot_core/lib/farmbot_core/asset/sync.ex @@ -41,7 +41,6 @@ defmodule FarmbotCore.Asset.Sync do embeds_many(:devices, Item) embeds_many(:firmware_configs, Item) embeds_many(:fbos_configs, Item) - embeds_many(:diagnostic_dumps, Item) embeds_many(:farm_events, Item) embeds_many(:farmware_envs, Item) embeds_many(:first_party_farmwares, Item) @@ -65,7 +64,6 @@ defmodule FarmbotCore.Asset.Sync do devices: Enum.map(sync.device, &Item.render/1), fbos_configs: Enum.map(sync.fbos_config, &Item.render/1), firmware_configs: Enum.map(sync.firmware_config, &Item.render/1), - diagnostic_dumps: Enum.map(sync.diagnostic_dumps, &Item.render/1), farm_events: Enum.map(sync.farm_events, &Item.render/1), farmware_envs: Enum.map(sync.farmware_envs, &Item.render/1), first_party_farmwares: Enum.map(sync.first_party_farmwares, &Item.render/1), @@ -90,7 +88,6 @@ defmodule FarmbotCore.Asset.Sync do |> cast_embed(:devices) |> cast_embed(:fbos_configs) |> cast_embed(:firmware_configs) - |> cast_embed(:diagnostic_dumps) |> cast_embed(:farm_events) |> cast_embed(:farmware_envs) |> cast_embed(:farmware_installations) diff --git a/farmbot_core/lib/farmbot_core/asset_helpers.ex b/farmbot_core/lib/farmbot_core/asset_helpers.ex index cd26acad..36a465a1 100644 --- a/farmbot_core/lib/farmbot_core/asset_helpers.ex +++ b/farmbot_core/lib/farmbot_core/asset_helpers.ex @@ -1,25 +1,26 @@ defmodule FarmbotCore.AssetHelpers do @moduledoc """ Helpers for the console at runtime. - + Example: iex()> use FarmbotCore.AssetHelpers iex()> Repo.all(Device) [%Device{}] """ - + @doc false defmacro __using__(_opts) do require Logger - Logger.warn "Don't use this in production please!" + Logger.warn("Don't use this in production please!") + quote do import Ecto.Query alias FarmbotCore.Asset + alias Asset.{ Repo, Device, DeviceCert, - DiagnosticDump, FarmwareEnv, FarmwareInstallation, FirstPartyFarmware, @@ -40,4 +41,4 @@ defmodule FarmbotCore.AssetHelpers do } end end -end \ No newline at end of file +end diff --git a/farmbot_core/lib/farmbot_core/asset_workers/pin_binding_worker.ex b/farmbot_core/lib/farmbot_core/asset_workers/pin_binding_worker.ex index 31260a89..4b22de57 100644 --- a/farmbot_core/lib/farmbot_core/asset_workers/pin_binding_worker.ex +++ b/farmbot_core/lib/farmbot_core/asset_workers/pin_binding_worker.ex @@ -3,12 +3,12 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do Worker for monitoring hardware GPIO. (not related to the mcu firmware.) Upon a button trigger, a `sequence`, or `special_action` will be executed by - the CeleryScript Runtime. + the CeleryScript Runtime. - This module also defines a behaviour that allows for abstracting and testing + This module also defines a behaviour that allows for abstracting and testing independent of GPIO hardware code. """ - + use GenServer require Logger require FarmbotCore.Logger @@ -75,6 +75,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do case Asset.get_sequence(pin_binding.sequence_id) do %Sequence{name: name} = seq -> FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing #{name}") + AST.decode(seq) |> execute(state) @@ -84,24 +85,24 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do end end - def handle_cast(:trigger, %{pin_binding: %{special_action: "dump_info"} = pin_binding} = state) do - FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Dump Info") - AST.Factory.new() - |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") - |> AST.Factory.dump_info() - |> execute(state) - end - - def handle_cast(:trigger, %{pin_binding: %{special_action: "emergency_lock"} = pin_binding} = state) do + def handle_cast( + :trigger, + %{pin_binding: %{special_action: "emergency_lock"} = pin_binding} = state + ) do FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Emergency Lock") + AST.Factory.new() |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") |> AST.Factory.emergency_lock() |> execute(state) - end + end - def handle_cast(:trigger, %{pin_binding: %{special_action: "emergency_unlock"} = pin_binding} = state) do + def handle_cast( + :trigger, + %{pin_binding: %{special_action: "emergency_unlock"} = pin_binding} = state + ) do FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Emergency Unlock") + AST.Factory.new() |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") |> AST.Factory.emergency_unlock() @@ -110,14 +111,19 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do def handle_cast(:trigger, %{pin_binding: %{special_action: "power_off"} = pin_binding} = state) do FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Power Off") + AST.Factory.new() |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") |> AST.Factory.power_off() |> execute(state) end - def handle_cast(:trigger, %{pin_binding: %{special_action: "read_status"} = pin_binding} = state) do + def handle_cast( + :trigger, + %{pin_binding: %{special_action: "read_status"} = pin_binding} = state + ) do FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Read Status") + AST.Factory.new() |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") |> AST.Factory.read_status() @@ -126,6 +132,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do def handle_cast(:trigger, %{pin_binding: %{special_action: "reboot"} = pin_binding} = state) do FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Reboot") + AST.Factory.new() |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") |> AST.Factory.reboot() @@ -134,6 +141,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do def handle_cast(:trigger, %{pin_binding: %{special_action: "sync"} = pin_binding} = state) do FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Sync") + AST.Factory.new() |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") |> AST.Factory.sync() @@ -142,6 +150,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do def handle_cast(:trigger, %{pin_binding: %{special_action: "take_photo"} = pin_binding} = state) do FarmbotCore.Logger.info(1, "#{pin_binding} triggered, executing Take Photo") + AST.Factory.new() |> AST.Factory.rpc_request("pin_binding.#{pin_binding.pin_num}") |> AST.Factory.take_photo() @@ -182,10 +191,13 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.PinBinding do defp execute(%AST{} = ast, state) do case FarmbotCeleryScript.execute(ast, make_ref()) do - :ok -> :ok + :ok -> + :ok + {:error, reason} -> - FarmbotCore.Logger.error 1, "error executing #{state.pin_binding}: #{reason}" + FarmbotCore.Logger.error(1, "error executing #{state.pin_binding}: #{reason}") end + {:noreply, state} end diff --git a/farmbot_ext/lib/farmbot_ext/api/dirty_worker/supervisor.ex b/farmbot_ext/lib/farmbot_ext/api/dirty_worker/supervisor.ex index a856b620..b1e78da0 100644 --- a/farmbot_ext/lib/farmbot_ext/api/dirty_worker/supervisor.ex +++ b/farmbot_ext/lib/farmbot_ext/api/dirty_worker/supervisor.ex @@ -1,7 +1,7 @@ defmodule FarmbotExt.API.DirtyWorker.Supervisor do @moduledoc """ - Responsible for supervising assets that will need to be - uploaded to the API via a `POST` or `PUT` request. + Responsible for supervising assets that will need to be + uploaded to the API via a `POST` or `PUT` request. """ use Supervisor @@ -10,7 +10,6 @@ defmodule FarmbotExt.API.DirtyWorker.Supervisor do alias FarmbotCore.Asset.{ Device, DeviceCert, - DiagnosticDump, FarmEvent, FarmwareEnv, FarmwareInstallation, @@ -39,7 +38,6 @@ defmodule FarmbotExt.API.DirtyWorker.Supervisor do {DirtyWorker, DeviceCert}, {DirtyWorker, FbosConfig}, {DirtyWorker, FirmwareConfig}, - {DirtyWorker, DiagnosticDump}, {DirtyWorker, FarmEvent}, {DirtyWorker, FarmwareEnv}, {DirtyWorker, FarmwareInstallation}, diff --git a/farmbot_ext/lib/farmbot_ext/api/eager_loader/supervisor.ex b/farmbot_ext/lib/farmbot_ext/api/eager_loader/supervisor.ex index f8221fea..cf7dd358 100644 --- a/farmbot_ext/lib/farmbot_ext/api/eager_loader/supervisor.ex +++ b/farmbot_ext/lib/farmbot_ext/api/eager_loader/supervisor.ex @@ -9,7 +9,6 @@ defmodule FarmbotExt.API.EagerLoader.Supervisor do alias FarmbotCore.Asset.{ Device, - DiagnosticDump, FarmEvent, FarmwareEnv, FirstPartyFarmware, @@ -42,7 +41,6 @@ defmodule FarmbotExt.API.EagerLoader.Supervisor do def init(_args) do children = [ {EagerLoader, Device}, - {EagerLoader, DiagnosticDump}, {EagerLoader, FarmEvent}, {EagerLoader, FarmwareEnv}, {EagerLoader, FirstPartyFarmware}, diff --git a/farmbot_os/.gitignore b/farmbot_os/.gitignore index 650cafa7..dca30926 100644 --- a/farmbot_os/.gitignore +++ b/farmbot_os/.gitignore @@ -18,4 +18,5 @@ erl_crash.dump *.sqlite3 auth_secret.exs log -*.csv \ No newline at end of file +*.csv +*.coverdata diff --git a/farmbot_os/lib/farmbot_os/sys_calls.ex b/farmbot_os/lib/farmbot_os/sys_calls.ex index fe911a09..2ca91c01 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls.ex @@ -18,7 +18,6 @@ defmodule FarmbotOS.SysCalls do alias FarmbotOS.SysCalls.{ ChangeOwnership, CheckUpdate, - DumpInfo, Farmware, FactoryReset, FlashFirmware, @@ -52,9 +51,6 @@ defmodule FarmbotOS.SysCalls do @impl true defdelegate change_ownership(email, secret, server), to: ChangeOwnership - @impl true - defdelegate dump_info(), to: DumpInfo - @impl true defdelegate check_update(), to: CheckUpdate diff --git a/farmbot_os/lib/farmbot_os/sys_calls/dump_info.ex b/farmbot_os/lib/farmbot_os/sys_calls/dump_info.ex deleted file mode 100644 index 9ea901c8..00000000 --- a/farmbot_os/lib/farmbot_os/sys_calls/dump_info.ex +++ /dev/null @@ -1,104 +0,0 @@ -defmodule FarmbotOS.SysCalls.DumpInfo do - @moduledoc false - - require FarmbotCore.Logger - require FarmbotTelemetry - - alias FarmbotCore.{ - Asset, - Asset.DiagnosticDump, - Asset.Private, - Config, - Project - } - - def dump_info do - FarmbotCore.Logger.busy(1, "Recording diagnostic dump.") - ifname = get_network_config() - dmesg = dmesg() - fbos_commit = Project.commit() - fbos_version = Project.version() - fw_version = fw_version() - fw_commit = Project.arduino_commit() - fw_hardware = extract_fw_hardware(fw_version) - fw_data = fw_state(fw_version, fw_hardware) - - params = %{ - network_interface: ifname, - firmware_hardware: fw_hardware, - firmware_commit: fw_commit, - fbos_commit: fbos_commit, - fbos_version: fbos_version, - fbos_dmesg_dump: dmesg, - firmware_state: FarmbotCore.JSON.encode!(fw_data) - } - - case Asset.new_diagnostic_dump(params) do - {:ok, diag} -> - _ = Private.mark_dirty!(diag, %{}) - FarmbotCore.Logger.success(1, "Diagnostic dump recorded.") - - FarmbotTelemetry.event(:diagnostic_dump, :record, nil, - diagnostic_dump: DiagnosticDump.render(diag) - ) - - :ok - - {:error, changeset} -> - FarmbotTelemetry.event(:diagnostic_dump, :record_error, nil, - error: inspect(changeset) - ) - - {:error, "error creating diagnostic dump: #{inspect(changeset)}"} - end - end - - defp get_network_config do - case Config.get_all_network_configs() do - [%{name: ifname} | _] -> ifname - _ -> nil - end - end - - defp dmesg do - {dmesg, _status} = System.cmd("dmesg", []) - dmesg - end - - defp fw_version do - case FarmbotFirmware.request({:software_version_read, []}) do - {:ok, {_, {:report_software_version, [version]}}} -> version - _ -> nil - end - end - - defp extract_fw_hardware(nil), do: nil - - defp extract_fw_hardware(str) do - case String.split(str, ".") do - [_, _, _, "R"] -> "arduino" - [_, _, _, "F"] -> "farmduino" - [_, _, _, "G"] -> "farmduino_k14" - [_, _, _, "H"] -> "farmduino_k15" - [_, _, _, "E"] -> "express_k10" - _ -> nil - end - end - - defp fw_state(version, hardware) do - pid = Process.whereis(FarmbotFirmware) - - if state = pid && :sys.get_state(pid) do - %{ - firmware_hardware: hardware, - firmware_version: version, - busy: state.status == :busy, - serial_port: state.transport_args[:device], - locked: state.status == :emergency_lock, - current_command: inspect(state.command_queue) - } - else - %{error: "Firmware process is not running. Could not collect info."} - end - end -end