parent
7cde2b2390
commit
cf5077e2a9
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -141,11 +141,9 @@ defmodule Farmbot.Asset do
|
|||
fwe =
|
||||
if params["key"] || params[:key] do
|
||||
Repo.get_by(FarmwareEnv, key: params["key"] || params[:key])
|
||||
else
|
||||
%FarmwareEnv{}
|
||||
end
|
||||
|
||||
FarmwareEnv.changeset(fwe, params)
|
||||
FarmwareEnv.changeset(fwe || %FarmwareEnv{}, params)
|
||||
|> Repo.insert_or_update()
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
defimpl Farmbot.AssetWorker, for: Farmbot.Asset.Device do
|
||||
alias Farmbot.Asset.Device
|
||||
use GenServer
|
||||
import Farmbot.Config, only: [update_config_value: 4]
|
||||
|
||||
def preload(%Device{}), do: []
|
||||
|
||||
|
@ -14,7 +13,6 @@ defimpl Farmbot.AssetWorker, for: Farmbot.Asset.Device do
|
|||
end
|
||||
|
||||
def handle_info(:timeout, %Device{} = device) do
|
||||
update_config_value(:string, "settings", "timezone", device.timezone)
|
||||
{:noreply, device}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ defimpl Farmbot.AssetWorker, for: Farmbot.Asset.FbosConfig do
|
|||
require Logger
|
||||
|
||||
alias Farmbot.Asset.FbosConfig
|
||||
import Farmbot.Config, only: [update_config_value: 4]
|
||||
alias Farmbot.BotState
|
||||
|
||||
def preload(%FbosConfig{}), do: []
|
||||
|
||||
|
@ -16,37 +16,18 @@ defimpl Farmbot.AssetWorker, for: Farmbot.Asset.FbosConfig do
|
|||
end
|
||||
|
||||
def handle_info(:timeout, %FbosConfig{} = fbos_config) do
|
||||
bool("arduino_debug_messages", fbos_config.arduino_debug_messages)
|
||||
bool("auto_sync", fbos_config.auto_sync)
|
||||
bool("beta_opt_in", fbos_config.beta_opt_in)
|
||||
bool("disable_factory_reset", fbos_config.disable_factory_reset)
|
||||
string("firmware_hardware", fbos_config.firmware_hardware)
|
||||
bool("firmware_input_log", fbos_config.firmware_input_log)
|
||||
bool("firmware_output_log", fbos_config.firmware_output_log)
|
||||
float("network_not_found_timer", fbos_config.network_not_found_timer)
|
||||
bool("os_auto_update", fbos_config.os_auto_update)
|
||||
bool("sequence_body_log", fbos_config.sequence_body_log)
|
||||
bool("sequence_complete_log", fbos_config.sequence_complete_log)
|
||||
bool("sequence_init_log", fbos_config.sequence_init_log)
|
||||
:ok = BotState.set_config_value(:arduino_debug_messages, fbos_config.arduino_debug_messages)
|
||||
:ok = BotState.set_config_value(:auto_sync, fbos_config.auto_sync)
|
||||
:ok = BotState.set_config_value(:beta_opt_in, fbos_config.beta_opt_in)
|
||||
:ok = BotState.set_config_value(:disable_factory_reset, fbos_config.disable_factory_reset)
|
||||
:ok = BotState.set_config_value(:firmware_hardware, fbos_config.firmware_hardware)
|
||||
:ok = BotState.set_config_value(:firmware_input_log, fbos_config.firmware_input_log)
|
||||
:ok = BotState.set_config_value(:firmware_output_log, fbos_config.firmware_output_log)
|
||||
:ok = BotState.set_config_value(:network_not_found_timer, fbos_config.network_not_found_timer)
|
||||
:ok = BotState.set_config_value(:os_auto_update, fbos_config.os_auto_update)
|
||||
:ok = BotState.set_config_value(:sequence_body_log, fbos_config.sequence_body_log)
|
||||
:ok = BotState.set_config_value(:sequence_complete_log, fbos_config.sequence_complete_log)
|
||||
:ok = BotState.set_config_value(:sequence_init_log, fbos_config.sequence_init_log)
|
||||
{:noreply, fbos_config}
|
||||
end
|
||||
|
||||
defp bool(key, val) do
|
||||
update_config_value(:bool, "settings", key, val)
|
||||
:ok = Farmbot.BotState.set_config_value(key, val)
|
||||
end
|
||||
|
||||
defp string(key, val) do
|
||||
update_config_value(:string, "settings", key, val)
|
||||
:ok = Farmbot.BotState.set_config_value(key, val)
|
||||
end
|
||||
|
||||
defp float(_key, nil) do
|
||||
:ok
|
||||
end
|
||||
|
||||
defp float(key, val) do
|
||||
update_config_value(:float, "settings", key, val / 1)
|
||||
:ok = Farmbot.BotState.set_config_value(key, val)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,6 +58,16 @@ defmodule Farmbot.BotState do
|
|||
GenServer.call(bot_state_server, {:set_firmware_locked, false})
|
||||
end
|
||||
|
||||
@doc "Sets informational_settings.firmware_version"
|
||||
def set_firmware_version(bot_state_server \\ __MODULE__, version) do
|
||||
GenServer.call(bot_state_server, {:set_firmware_version, version})
|
||||
end
|
||||
|
||||
@doc "Sets informational_settings.busy"
|
||||
def set_firmware_busy(bot_state_server \\ __MODULE__, busy) do
|
||||
GenServer.call(bot_state_server, {:set_firmware_busy, busy})
|
||||
end
|
||||
|
||||
@doc "Sets informational_settings.status"
|
||||
def set_sync_status(bot_state_server \\ __MODULE__, s)
|
||||
when s in ["syncing", "synced", "error"] do
|
||||
|
@ -212,6 +222,26 @@ defmodule Farmbot.BotState do
|
|||
{:reply, reply, state}
|
||||
end
|
||||
|
||||
def handle_call({:set_firmware_version, version}, _from, state) do
|
||||
change = %{informational_settings: %{firmware_version: version}}
|
||||
|
||||
{reply, state} =
|
||||
BotStateNG.changeset(state.tree, change)
|
||||
|> dispatch_and_apply(state)
|
||||
|
||||
{:reply, reply, state}
|
||||
end
|
||||
|
||||
def handle_call({:set_firmware_busy, busy}, _from, state) do
|
||||
change = %{informational_settings: %{busy: busy}}
|
||||
|
||||
{reply, state} =
|
||||
BotStateNG.changeset(state.tree, change)
|
||||
|> dispatch_and_apply(state)
|
||||
|
||||
{:reply, reply, state}
|
||||
end
|
||||
|
||||
def handle_call({:set_sync_status, status}, _from, state) do
|
||||
change = %{informational_settings: %{sync_status: status}}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ defmodule Farmbot.Config.MigrationHelpers do
|
|||
|
||||
alias Farmbot.Config
|
||||
alias Config.{Repo, Config, StringValue, BoolValue, FloatValue}
|
||||
import Ecto.Query
|
||||
|
||||
@auth_group_id 1
|
||||
@hw_param_group_id 2
|
||||
|
@ -20,6 +21,16 @@ defmodule Farmbot.Config.MigrationHelpers do
|
|||
|> create_config(@settings_group_id, key)
|
||||
end
|
||||
|
||||
def delete_settings_config(key, type) when type in [:string, :float, :bool] do
|
||||
IO.puts "deleting #{key} #{type}"
|
||||
conf = Repo.one!(from c in Config, where: c.group_id == @settings_group_id and c.key == ^key)
|
||||
val_id = Map.fetch!(conf, :"#{type}_value_id")
|
||||
val = Repo.one!(from t in type_to_mod(type), where: t.id == ^val_id)
|
||||
Repo.delete!(conf)
|
||||
Repo.delete!(val)
|
||||
:ok
|
||||
end
|
||||
|
||||
def create_hw_param(key) when is_binary(key) do
|
||||
create_value(FloatValue, nil) |> create_config(@hw_param_group_id, key)
|
||||
end
|
||||
|
|
|
@ -37,14 +37,18 @@ defmodule Farmbot.Core.FirmwareSideEffects do
|
|||
:ok = Farmbot.BotState.set_pin_value(pin, value)
|
||||
end
|
||||
|
||||
def handle_software_version([_version]) do
|
||||
:noop
|
||||
def handle_software_version([version]) do
|
||||
:ok = Farmbot.BotState.set_firmware_version(version)
|
||||
end
|
||||
|
||||
def handle_end_stops(_) do
|
||||
:noop
|
||||
end
|
||||
|
||||
def handle_busy(busy) do
|
||||
:ok = Farmbot.BotState.set_firmware_busy(busy)
|
||||
end
|
||||
|
||||
def handle_emergency_lock() do
|
||||
_ = FirmwareEstopTimer.start_timer()
|
||||
:ok = Farmbot.BotState.set_firmware_locked()
|
||||
|
|
|
@ -6,40 +6,14 @@ defmodule Farmbot.Core.FirmwareSupervisor do
|
|||
Supervisor.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
def reinitialize do
|
||||
_ = Supervisor.terminate_child(Farmbot.Core, __MODULE__)
|
||||
Supervisor.restart_child(Farmbot.Core, __MODULE__)
|
||||
end
|
||||
|
||||
def stub do
|
||||
Asset.fbos_config()
|
||||
|> Asset.FbosConfig.changeset(%{firmware_path: "stub"})
|
||||
|> Asset.Repo.insert_or_update()
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
fbos_config = Asset.fbos_config()
|
||||
|
||||
children =
|
||||
firmware_children(fbos_config) ++
|
||||
[
|
||||
Farmbot.Core.FirmwareEstopTimer
|
||||
]
|
||||
children = [
|
||||
Farmbot.Core.FirmwareEstopTimer
|
||||
]
|
||||
|
||||
Supervisor.init(children, strategy: :one_for_all)
|
||||
end
|
||||
|
||||
def firmware_children(%Asset.FbosConfig{firmware_hardware: nil}), do: []
|
||||
|
||||
def firmware_children(%Asset.FbosConfig{firmware_path: "stub"}) do
|
||||
[
|
||||
{Farmbot.Firmware,
|
||||
transport: Farmbot.Firmware.StubTransport, side_effects: Farmbot.Core.FirmwareSideEffects}
|
||||
]
|
||||
end
|
||||
|
||||
def firmware_children(%Asset.FbosConfig{firmware_path: nil}), do: []
|
||||
|
||||
def firmware_children(%Asset.FbosConfig{} = fbos_config) do
|
||||
[
|
||||
{Farmbot.Firmware,
|
||||
|
|
|
@ -11,8 +11,7 @@ defmodule Farmbot.TimeUtils do
|
|||
# returns midnight of today
|
||||
@spec build_epoch(DateTime.t) :: DateTime.t
|
||||
def build_epoch(time) do
|
||||
import Farmbot.Config, only: [get_config_value: 3]
|
||||
tz = get_config_value(:string, "settings", "timezone")
|
||||
tz = Farmbot.Asset.fbos_config().timezone
|
||||
n = Timex.Timezone.convert(time, tz)
|
||||
Timex.shift(n, hours: -n.hour, seconds: -n.second, minutes: -n.minute)
|
||||
end
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,34 @@
|
|||
defmodule Farmbot.Config.Repo.Migrations.MigrateSettings do
|
||||
use Ecto.Migration
|
||||
import Farmbot.Config.MigrationHelpers
|
||||
|
||||
def change do
|
||||
delete_settings_config("auto_sync", :bool)
|
||||
delete_settings_config("firmware_needs_migration", :bool)
|
||||
delete_settings_config("email_on_estop", :bool)
|
||||
delete_settings_config("disable_factory_reset", :bool)
|
||||
delete_settings_config("ignore_fbos_config", :bool)
|
||||
delete_settings_config("os_update_server_overwrite", :string)
|
||||
delete_settings_config("network_not_found_timer", :float)
|
||||
delete_settings_config("timezone", :string)
|
||||
delete_settings_config("first_party_farmware_url", :string)
|
||||
delete_settings_config("sync_timeout_ms", :float)
|
||||
delete_settings_config("ignore_external_logs", :bool)
|
||||
delete_settings_config("needs_http_sync", :bool)
|
||||
delete_settings_config("currently_on_beta", :bool)
|
||||
delete_settings_config("arduino_debug_messages", :bool)
|
||||
delete_settings_config("firmware_output_log", :bool)
|
||||
delete_settings_config("firmware_input_log", :bool)
|
||||
delete_settings_config("beta_opt_in", :bool)
|
||||
delete_settings_config("log_amqp_connected", :bool)
|
||||
delete_settings_config("current_repo", :string)
|
||||
delete_settings_config("user_env", :string)
|
||||
delete_settings_config("sequence_complete_log", :bool)
|
||||
delete_settings_config("sequence_init_log", :bool)
|
||||
delete_settings_config("sequence_body_log", :bool)
|
||||
delete_settings_config("ignore_fw_config", :bool)
|
||||
delete_settings_config("api_migrated", :bool)
|
||||
delete_settings_config("firmware_needs_first_sync", :bool)
|
||||
delete_settings_config("first_boot", :bool)
|
||||
end
|
||||
end
|
Binary file not shown.
Binary file not shown.
|
@ -11,7 +11,6 @@ defmodule Farmbot.AMQP.AutoSyncTransport do
|
|||
|
||||
require Logger
|
||||
require Farmbot.Logger
|
||||
import Farmbot.Config, only: [get_config_value: 3]
|
||||
|
||||
alias Farmbot.{
|
||||
API.EagerLoader,
|
||||
|
@ -98,7 +97,7 @@ defmodule Farmbot.AMQP.AutoSyncTransport do
|
|||
end
|
||||
|
||||
def handle_asset(asset_kind, label, id, params, state) do
|
||||
auto_sync? = get_config_value(:bool, "settings", "auto_sync")
|
||||
auto_sync? = Farmbot.Asset.fbos_config().auto_sync
|
||||
|
||||
cond do
|
||||
# TODO(Connor) no way to cache a deletion yet
|
||||
|
@ -109,7 +108,6 @@ defmodule Farmbot.AMQP.AutoSyncTransport do
|
|||
Repo.get_by!(Device, id: id)
|
||||
|> Device.changeset(params)
|
||||
|> Repo.update!()
|
||||
|> Farmbot.Bootstrap.APITask.device_to_config_storage()
|
||||
|
||||
:ok
|
||||
|
||||
|
@ -117,7 +115,6 @@ defmodule Farmbot.AMQP.AutoSyncTransport do
|
|||
Repo.get_by!(FbosConfig, id: id)
|
||||
|> FbosConfig.changeset(params)
|
||||
|> Repo.update!()
|
||||
|> Farmbot.Bootstrap.APITask.fbos_config_to_config_storage()
|
||||
|
||||
:ok
|
||||
|
||||
|
@ -153,7 +150,7 @@ defmodule Farmbot.AMQP.AutoSyncTransport do
|
|||
end
|
||||
end
|
||||
|
||||
device = state.bot
|
||||
device = state.jwt.bot
|
||||
json = JSON.encode!(%{args: %{label: label}, kind: "rpc_ok"})
|
||||
:ok = Basic.publish(state.chan, @exchange, "bot.#{device}.from_device", json)
|
||||
{:noreply, state}
|
||||
|
|
|
@ -12,8 +12,6 @@ defmodule Farmbot.AMQP.CeleryScriptTransport do
|
|||
|
||||
alias Farmbot.AMQP.ConnectionWorker
|
||||
|
||||
import Farmbot.Config, only: [get_config_value: 3, update_config_value: 4]
|
||||
|
||||
@exchange "amq.topic"
|
||||
|
||||
defstruct [:conn, :chan, :jwt]
|
||||
|
@ -61,11 +59,7 @@ defmodule Farmbot.AMQP.CeleryScriptTransport do
|
|||
|
||||
# Confirmation sent by the broker after registering this process as a consumer
|
||||
def handle_info({:basic_consume_ok, _}, state) do
|
||||
if get_config_value(:bool, "settings", "log_amqp_connected") do
|
||||
Farmbot.Logger.success(1, "Farmbot is up and running!")
|
||||
update_config_value(:bool, "settings", "log_amqp_connected", false)
|
||||
end
|
||||
|
||||
Farmbot.Logger.success(1, "Farmbot is up and running!")
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
|
@ -101,7 +95,8 @@ defmodule Farmbot.AMQP.CeleryScriptTransport do
|
|||
|
||||
if results_ast.kind == :rpc_error do
|
||||
[%{args: %{message: message}}] = results_ast.body
|
||||
Logger.error(message)
|
||||
msg = ["CeleryScript Error\n", message, "\n", inspect(json)]
|
||||
Logger.error(msg)
|
||||
end
|
||||
|
||||
AMQP.Basic.publish(state.chan, @exchange, "bot.#{state.jwt.bot}.from_device", reply)
|
||||
|
|
|
@ -10,7 +10,6 @@ defmodule Farmbot.Bootstrap do
|
|||
end
|
||||
|
||||
def init([]) do
|
||||
update_config_value(:bool, "settings", "log_amqp_connected", true)
|
||||
{:ok, nil, 0}
|
||||
end
|
||||
|
||||
|
@ -45,14 +44,15 @@ defmodule Farmbot.Bootstrap do
|
|||
# TODO(Connor) - drop password and save secret here somehow.
|
||||
def try_auth(email, server, password, _secret) do
|
||||
Logger.debug("using password to auth")
|
||||
# require IEx; IEx.pry
|
||||
|
||||
with {:ok, tkn} <- Authorization.authorize_with_password(email, password, server),
|
||||
_ <- update_config_value(:string, "authorization", "token", tkn),
|
||||
{:ok, pid} <- Supervisor.start_child(Farmbot.Ext, Farmbot.Bootstrap.Supervisor) do
|
||||
{:noreply, pid}
|
||||
else
|
||||
_ -> {:noreply, nil, 5000}
|
||||
er ->
|
||||
Logger.error("password auth failed: #{inspect(er)} ")
|
||||
{:noreply, nil, 5000}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,16 +8,12 @@ defmodule Farmbot.Bootstrap.APITask do
|
|||
alias Ecto.{Changeset, Multi}
|
||||
|
||||
require Farmbot.Logger
|
||||
import Farmbot.Config, only: [get_config_value: 3, update_config_value: 4]
|
||||
alias Farmbot.API
|
||||
alias API.{Reconciler, SyncGroup, EagerLoader}
|
||||
|
||||
alias Farmbot.Asset.{
|
||||
Repo,
|
||||
Sync,
|
||||
Device,
|
||||
FbosConfig
|
||||
# FirmwareConfig
|
||||
Sync
|
||||
}
|
||||
|
||||
def child_spec(_) do
|
||||
|
@ -38,16 +34,16 @@ defmodule Farmbot.Bootstrap.APITask do
|
|||
multi = Multi.new()
|
||||
|
||||
with {:ok, multi} <- Reconciler.sync_group(multi, sync, SyncGroup.group_0()),
|
||||
{:ok, r} <- Repo.transaction(multi) do
|
||||
[%{id: device_id}] = sync.devices
|
||||
[%{id: fbos_config_id}] = sync.fbos_configs
|
||||
# [%{id: firmware_config_id}] = sync.firmware_configs
|
||||
:ok = device_to_config_storage(r[{:devices, device_id}])
|
||||
:ok = fbos_config_to_config_storage(r[{:fbos_configs, fbos_config_id}])
|
||||
# :ok = firmware_config_to_config_storage(r[{:firmware_configs, firmware_config_id}])
|
||||
{:ok, _} <- Repo.transaction(multi) do
|
||||
auto_sync_change =
|
||||
Enum.find_value(multi.operations, fn {{key, _id}, {:changeset, change, []}} ->
|
||||
key == :fbos_configs && Changeset.get_change(change, :auto_sync)
|
||||
end)
|
||||
|
||||
Farmbot.Logger.success(3, "Successfully synced bootup resources.")
|
||||
|
||||
:ok = maybe_auto_sync(sync_changeset, get_config_value(:bool, "settings", "auto_sync"))
|
||||
:ok =
|
||||
maybe_auto_sync(sync_changeset, auto_sync_change || Farmbot.Asset.fbos_config().auto_sync)
|
||||
end
|
||||
|
||||
:ignore
|
||||
|
@ -82,42 +78,4 @@ defmodule Farmbot.Bootstrap.APITask do
|
|||
Farmbot.Logger.success(3, "preloaded sync ok")
|
||||
:ok
|
||||
end
|
||||
|
||||
def device_to_config_storage(nil), do: :ok
|
||||
|
||||
def device_to_config_storage(%Device{timezone: tz} = _device) do
|
||||
update_config_value(:string, "settings", "timezone", tz)
|
||||
:ok
|
||||
end
|
||||
|
||||
def fbos_config_to_config_storage(nil), do: :ok
|
||||
|
||||
def fbos_config_to_config_storage(%FbosConfig{} = config) do
|
||||
update_config_value(
|
||||
:bool,
|
||||
"settings",
|
||||
"arduino_debug_messages",
|
||||
config.arduino_debug_messages
|
||||
)
|
||||
|
||||
update_config_value(:bool, "settings", "auto_sync", config.auto_sync)
|
||||
update_config_value(:bool, "settings", "beta_opt_in", config.beta_opt_in)
|
||||
update_config_value(:bool, "settings", "disable_factory_reset", config.disable_factory_reset)
|
||||
update_config_value(:string, "settings", "firmware_hardware", config.firmware_hardware)
|
||||
update_config_value(:bool, "settings", "firmware_input_log", config.firmware_input_log)
|
||||
update_config_value(:bool, "settings", "firmware_output_log", config.firmware_output_log)
|
||||
|
||||
update_config_value(
|
||||
:float,
|
||||
"settings",
|
||||
"network_not_found_timer",
|
||||
config.network_not_found_timer && config.network_not_found_timer / 1
|
||||
)
|
||||
|
||||
update_config_value(:bool, "settings", "os_auto_update", config.os_auto_update)
|
||||
update_config_value(:bool, "settings", "sequence_body_log", config.sequence_body_log)
|
||||
update_config_value(:bool, "settings", "sequence_complete_log", config.sequence_complete_log)
|
||||
update_config_value(:bool, "settings", "sequence_init_log", config.sequence_init_log)
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
|
Binary file not shown.
|
@ -282,6 +282,7 @@ defmodule Farmbot.Firmware do
|
|||
|
||||
# report_idle => goto(_, :idle)
|
||||
def handle_report({:report_idle, []}, %{status: _} = state) do
|
||||
side_effects(state, :handle_busy, [false])
|
||||
{:noreply, goto(%{state | caller_pid: nil, current: nil}, :idle), 0}
|
||||
end
|
||||
|
||||
|
@ -293,6 +294,7 @@ defmodule Farmbot.Firmware do
|
|||
def handle_report({:report_success, []} = code, state) do
|
||||
if state.caller_pid, do: send(state.caller_pid, {state.tag, code})
|
||||
new_state = %{state | current: nil, caller_pid: nil}
|
||||
side_effects(state, :handle_busy, [false])
|
||||
|
||||
if new_state.status == :emergency_lock do
|
||||
{:noreply, goto(new_state, :idle), 0}
|
||||
|
@ -303,16 +305,19 @@ defmodule Farmbot.Firmware do
|
|||
|
||||
def handle_report({:report_busy, []} = code, state) do
|
||||
if state.caller_pid, do: send(state.caller_pid, {state.tag, code})
|
||||
side_effects(state, :handle_busy, [true])
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
def handle_report({:report_error, []} = code, %{status: :configuration} = state) do
|
||||
if state.caller_pid, do: send(state.caller_pid, {state.tag, code})
|
||||
side_effects(state, :handle_busy, [false])
|
||||
{:stop, {:error, state.current}, state}
|
||||
end
|
||||
|
||||
def handle_report({:report_error, []} = code, state) do
|
||||
if state.caller_pid, do: send(state.caller_pid, {state.tag, code})
|
||||
side_effects(state, :handle_busy, [false])
|
||||
{:noreply, %{state | caller_pid: nil, current: nil}, 0}
|
||||
end
|
||||
|
||||
|
@ -351,6 +356,7 @@ defmodule Farmbot.Firmware do
|
|||
|
||||
# report_no_config => goto(_, :no_config)
|
||||
def handle_report({:report_no_config, []}, %{status: _} = state) do
|
||||
Logger.debug("REPORT_NO_CONFIG")
|
||||
tag = state.tag || "0"
|
||||
loaded_params = side_effects(state, :load_params, []) || []
|
||||
|
||||
|
@ -368,15 +374,18 @@ defmodule Farmbot.Firmware do
|
|||
|
||||
to_process =
|
||||
if loaded_params[:movement_home_at_boot_x] == 1,
|
||||
do: to_process ++ [{:command_movement_find_home, [:x]}]
|
||||
do: to_process ++ [{:command_movement_find_home, [:x]}],
|
||||
else: to_process
|
||||
|
||||
to_process =
|
||||
if loaded_params[:movement_home_at_boot_y] == 1,
|
||||
do: to_process ++ [{:command_movement_find_home, [:y]}]
|
||||
do: to_process ++ [{:command_movement_find_home, [:y]}],
|
||||
else: to_process
|
||||
|
||||
to_process =
|
||||
if loaded_params[:movement_home_at_boot_z] == 1,
|
||||
do: to_process ++ [{:command_movement_find_home, [:z]}]
|
||||
do: to_process ++ [{:command_movement_find_home, [:z]}],
|
||||
else: to_process
|
||||
|
||||
{:noreply, goto(%{state | tag: tag, configuration_queue: to_process}, :configuration), 0}
|
||||
end
|
||||
|
|
|
@ -17,6 +17,7 @@ defmodule Farmbot.Firmware.SideEffects do
|
|||
@callback handle_emergency_unlock() :: any()
|
||||
@callback handle_pin_value(p: integer(), v: integer()) :: any()
|
||||
@callback handle_software_version([String.t()]) :: any()
|
||||
@callback handle_busy(boolean()) :: any()
|
||||
|
||||
@type axis_state :: :stop | :idle | :begin | :crawl | :decelerate | :accelerate
|
||||
@callback handle_axis_state([{axis(), axis_state}]) :: any()
|
||||
|
|
|
@ -118,6 +118,8 @@ defmodule Farmbot.Firmware.StubSideEffects do
|
|||
|
||||
def handle_software_version(_), do: :noop
|
||||
|
||||
def handle_busy(_), do: :noop
|
||||
|
||||
def handle_input_gcode(_), do: :noop
|
||||
|
||||
def handle_output_gcode(_), do: :noop
|
||||
|
|
|
@ -28,11 +28,11 @@ defmodule Farmbot.Firmware.UARTTransport do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_info({:nerves_uart, _, {:error, reason}}, state) do
|
||||
def handle_info({:circuits_uart, _, {:error, reason}}, state) do
|
||||
{:stop, {:uart_error, reason}, state}
|
||||
end
|
||||
|
||||
def handle_info({:nerves_uart, _, data}, state) when is_binary(data) do
|
||||
def handle_info({:circuits_uart, _, data}, state) when is_binary(data) do
|
||||
code = GCODE.decode(String.trim(data))
|
||||
state.handle_gcode.(code)
|
||||
{:noreply, state}
|
||||
|
|
|
@ -46,6 +46,8 @@ config :farmbot, Farmbot.Platform.Supervisor,
|
|||
]
|
||||
|
||||
import_config("lagger.exs")
|
||||
config :logger, backends: [:console]
|
||||
config :logger, :console, metadata: [:changeset, :module]
|
||||
|
||||
if Mix.Project.config()[:target] == "host" do
|
||||
if File.exists?("config/host/#{Mix.env()}.exs") do
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use Mix.Config
|
||||
|
||||
data_path = Path.join(["/", "tmp", "farmbot"])
|
||||
File.mkdir_p(data_path)
|
||||
|
||||
config :farmbot_ext,
|
||||
data_path: data_path
|
||||
|
@ -24,19 +25,16 @@ config :farmbot_core, Farmbot.Asset.Repo,
|
|||
loggers: [],
|
||||
database: Path.join(data_path, "asset-#{Mix.env()}.sqlite3")
|
||||
|
||||
config :farmbot,
|
||||
ecto_repos: [Farmbot.Config.Repo, Farmbot.Logger.Repo, Farmbot.Asset.Repo],
|
||||
platform_children: [
|
||||
{Farmbot.Host.Configurator, []}
|
||||
config :farmbot, Farmbot.System.Init.Supervisor,
|
||||
init_children: [
|
||||
Farmbot.TTYDetector,
|
||||
Farmbot.Host.Configurator
|
||||
]
|
||||
|
||||
config :farmbot, :behaviour, system_tasks: Farmbot.Host.SystemTasks
|
||||
|
||||
config :farmbot,
|
||||
ecto_repos: [Farmbot.Config.Repo, Farmbot.Logger.Repo, Farmbot.Asset.Repo]
|
||||
|
||||
config :farmbot, Farmbot.System.NervesHub,
|
||||
farmbot_nerves_hub_handler: Farmbot.Host.NervesHubHandler
|
||||
|
||||
config :farmbot_core, :behaviour,
|
||||
leds_handler: Farmbot.Leds.StubHandler,
|
||||
pin_binding_handler: Farmbot.PinBinding.StubHandler,
|
||||
celery_script_io_layer: Farmbot.OS.IOLayer,
|
||||
firmware_handler: Farmbot.Firmware.UartHandler
|
||||
|
|
|
@ -44,10 +44,8 @@ defmodule Farmbot.System do
|
|||
# credo:disable-for-next-line
|
||||
require IEx; IEx.pry()
|
||||
end
|
||||
alias Farmbot.Config
|
||||
import Config, only: [get_config_value: 3]
|
||||
if Process.whereis Farmbot.Core do
|
||||
if get_config_value(:bool, "settings", "disable_factory_reset") do
|
||||
if Farmbot.Asset.fbos_config().disable_factory_reset do
|
||||
reboot(reason)
|
||||
else
|
||||
do_reset(reason)
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
defmodule Farmbot.TTYDetector do
|
||||
use GenServer
|
||||
require Logger
|
||||
alias Circuits.UART
|
||||
|
||||
import Farmbot.Config, only: [get_config_value: 3]
|
||||
|
||||
@expected_names ["ttyACM0"]
|
||||
@error_ms 5000
|
||||
|
||||
def start_link(args) do
|
||||
GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
{:ok, %{device: nil, needs_flash: false, open: false}, 0}
|
||||
end
|
||||
|
||||
def handle_info(:timeout, %{device: nil} = state) do
|
||||
case get_config_value(:string, "settings", "firmware_hardware") do
|
||||
nil -> {:noreply, state, @error_ms}
|
||||
_hw ->
|
||||
available = UART.enumerate() |> Map.to_list()
|
||||
{:noreply, state, {:continue, available}}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_info(:timeout, %{device: device, needs_flash: true} = state) do
|
||||
dir = Application.app_dir(:farmbot_core, ["priv"])
|
||||
case get_config_value(:string, "settings", "firmware_hardware") do
|
||||
"arduino" -> flash_fw(Path.join(dir, "arduino_firmware.hex"), state)
|
||||
"farmduino" -> flash_fw(Path.join(dir, "farmduino.hex"), state)
|
||||
"farmduino_k14" -> flash_fw(Path.join(dir, "farmduino_k14.hex"), state)
|
||||
nil -> {:noreply, state, @error_ms}
|
||||
other ->
|
||||
Logger.error "Unknown arduino firmware #{other}"
|
||||
{:stop, {:unknown_firmware, other}, state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_info(:timeout, %{device: device, needs_flash: false, open: false} = state) do
|
||||
opts = [
|
||||
device: device,
|
||||
transport: Farmbot.Firmware.UARTTransport,
|
||||
side_effects: Farmbot.Core.FirmwareSideEffects
|
||||
]
|
||||
case Farmbot.Firmware.start_link(opts) do
|
||||
{:ok, pid} ->
|
||||
Process.monitor(pid)
|
||||
{:noreply, %{state | open: true}}
|
||||
error ->
|
||||
{:stop, error, state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_info({:DOWN, _ref, :process, _pid, reason}, state) do
|
||||
{:stop, reason, state}
|
||||
end
|
||||
|
||||
def handle_continue([{name, _} | rest], %{device: nil} = state)
|
||||
when name in @expected_names do
|
||||
{:noreply, %{state | device: name}, 0}
|
||||
end
|
||||
|
||||
def handle_continue([_ | rest], %{device: nil} = state) do
|
||||
{:noreply, state, {:continue, rest}}
|
||||
end
|
||||
|
||||
def handle_continue([], %{device: nil} = state) do
|
||||
{:noreply, state, @error_ms}
|
||||
end
|
||||
|
||||
defp flash_fw(fw_file, state) do
|
||||
args = ~w"-q -q -patmega2560 -cwiring -P#{dev(state.device)} -b115200 -D -V -Uflash:w:#{fw_file}:i"
|
||||
opts = [stderr_to_stdout: true, into: IO.stream(:stdio, :line)]
|
||||
res = System.cmd("avrdude", args, opts)
|
||||
case res do
|
||||
{_, 0} -> {:noreply, %{state | needs_flash: false}, 0}
|
||||
_ ->
|
||||
Logger.error("firmware flash failed")
|
||||
{:noreply, state, @error_ms}
|
||||
end
|
||||
end
|
||||
|
||||
defp dev("/dev/" <> _ = device), do: IO.inspect(device, label: "DEVICE")
|
||||
defp dev("tty" <> _ = dev), do: IO.inspect(Path.join("/dev", dev), label: "DEVICE")
|
||||
end
|
|
@ -3,7 +3,7 @@ defmodule Farmbot.Host.Configurator do
|
|||
use Supervisor
|
||||
|
||||
import Farmbot.Config,
|
||||
only: [update_config_value: 4, get_config_value: 3]
|
||||
only: [update_config_value: 4]
|
||||
|
||||
@doc false
|
||||
def start_link(args) do
|
||||
|
@ -26,16 +26,7 @@ defmodule Farmbot.Host.Configurator do
|
|||
pass = System.get_env("FARMBOT_PASSWORD") || raise error("password")
|
||||
server = System.get_env("FARMBOT_SERVER") || raise error("server")
|
||||
update_config_value(:string, "authorization", "email", email)
|
||||
|
||||
# if there is no firmware hardware, default ot farmduino
|
||||
unless get_config_value(:string, "settings", "firmware_hardware") do
|
||||
update_config_value(:string, "settings", "firmware_hardware", "farmduino")
|
||||
end
|
||||
|
||||
if get_config_value(:bool, "settings", "first_boot") do
|
||||
update_config_value(:string, "authorization", "password", pass)
|
||||
end
|
||||
|
||||
update_config_value(:string, "authorization", "password", pass)
|
||||
update_config_value(:string, "authorization", "server", server)
|
||||
update_config_value(:string, "authorization", "token", nil)
|
||||
:ignore
|
||||
|
|
|
@ -11,7 +11,7 @@ defmodule Farmbot.System.NervesHubClient do
|
|||
@behaviour Farmbot.System.NervesHub
|
||||
|
||||
@current_version Farmbot.Project.version()
|
||||
@data_path Application.get_env(:farmbot, :data_path)
|
||||
@data_path Farmbot.OS.FileSystem.data_path()
|
||||
@data_path || Mix.raise("Please configure data_path in application env")
|
||||
|
||||
import Farmbot.Config, only: [get_config_value: 3]
|
||||
|
@ -196,7 +196,7 @@ defmodule Farmbot.System.NervesHubClient do
|
|||
Farmbot.BotState.set_update_available(true)
|
||||
end
|
||||
|
||||
case get_config_value(:bool, "settings", "os_auto_update") do
|
||||
case Farmbot.Asset.fbos_config(:os_auto_update) do
|
||||
true ->
|
||||
Logger.success(1, "Applying OTA update")
|
||||
{:reply, :apply, {:apply, url}}
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
defmodule Farmbot.Target.Network.DnsTask do
|
||||
require Farmbot.Logger
|
||||
use GenServer
|
||||
import Farmbot.Target.Network, only: [test_dns: 0]
|
||||
import Farmbot.Config, only: [get_config_value: 3]
|
||||
@default_timeout_ms 45_000
|
||||
|
||||
def start_link(args) do
|
||||
GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
# Block and reset if after 10 tries
|
||||
# resolution doesn't work.
|
||||
block_check(true)
|
||||
{:ok, nil, @default_timeout_ms}
|
||||
end
|
||||
|
||||
def handle_info(:timeout, state) do
|
||||
# Block and don't reset if after 10 tries
|
||||
# resolution doesn't work.
|
||||
block_check()
|
||||
{:noreply, state, @default_timeout_ms}
|
||||
end
|
||||
|
||||
defp block_check(last_result, reset \\ false, tries \\ 10)
|
||||
|
||||
defp block_check(last_result, false, 0) do
|
||||
server = get_config_value(:string, "authorization", "server")
|
||||
Farmbot.Logger.error(1, "Could not resolve #{server} after 10 tries.")
|
||||
end
|
||||
|
||||
defp block_check(_last_result, true, 0) do
|
||||
server = get_config_value(:string, "authorization", "server")
|
||||
Farmbot.Logger.error(1, "Tried 10 times to resolve DNS requests.")
|
||||
|
||||
msg = """
|
||||
FarmBot is unable to make DNS requests to #{server} after
|
||||
10 tries. It is possible your network has a firewall blocking this
|
||||
url, or your FarmBot is configured incorrectly.
|
||||
"""
|
||||
|
||||
Farmbot.System.factory_reset(msg)
|
||||
:error
|
||||
end
|
||||
|
||||
defp block_check(last_result, reset, tries) do
|
||||
server = get_config_value(:string, "authorization", "server")
|
||||
|
||||
case test_dns() do
|
||||
{:ok, _} ->
|
||||
:ok
|
||||
|
||||
{:error, :nxdomain} ->
|
||||
Process.sleep(10_000)
|
||||
Farmbot.Logger.error(1, "Trying to resolve #{server} #{tries - 1} more times.")
|
||||
block_check(reset, tries - 1)
|
||||
|
||||
err ->
|
||||
Farmbot.Logger.error(1, "Failed to resolve #{server}: #{inspect(err)}")
|
||||
block_check(reset, tries)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,4 +9,4 @@ if [ -z $2 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
avrdude -v -p atmega2560 -c wiring -P$2 -b 115200 -D -V -Uflash:w:./priv/$1.hex:i
|
||||
avrdude -v -p atmega2560 -c wiring -P$2 -b 115200 -D -V -Uflash:w:./farmbot_core/priv/$1.hex:i
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
AVAILABLE=$(ls priv/*.hex | grep -v "eeprom_clear" | tr '\n' ' ')
|
||||
AVAILABLE=$(ls ./farmbot_core/priv/*.hex | grep -v "eeprom_clear" | tr '\n' ' ')
|
||||
if [ -z $1 ]; then
|
||||
echo "usage: scripts/reset_fw.sh [$AVAILABLE] /dev/ttyACM0"
|
||||
exit 1
|
||||
|
|
Loading…
Reference in New Issue