diff --git a/.gitignore b/.gitignore index 3528a223..e904e182 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ Makefile.bac _images Makefile release-* +dump.rdb diff --git a/lib/bot_state/bot_state.ex b/lib/bot_state/bot_state.ex index 8e3dcc7f..6d475653 100644 --- a/lib/bot_state/bot_state.ex +++ b/lib/bot_state/bot_state.ex @@ -80,7 +80,14 @@ defmodule Farmbot.BotState do This is just a shortcut """ @spec get_fw_version :: String.t - def get_fw_version, do: get_param(:param_version) + def get_fw_version, do: GenServer.call(Configuration, :get_fw_version) + + @doc """ + Set the version + """ + @spec set_fw_version(binary) :: no_return + def set_fw_version(v), + do: GenServer.cast(Configuration, {:update_info, :firmware_version, v}) @doc """ Gets the current controller version diff --git a/lib/bot_state/trackers/configuration_tracker.ex b/lib/bot_state/trackers/configuration_tracker.ex index 3bc68c85..8f0407d6 100644 --- a/lib/bot_state/trackers/configuration_tracker.ex +++ b/lib/bot_state/trackers/configuration_tracker.ex @@ -27,9 +27,9 @@ defmodule Farmbot.BotState.Configuration do controller_version: "loading...", compat_version: -1, target: "loading...", - private_ip: nil, commit: "loading...", - sync_status: :sync_now + sync_status: :sync_now, + firmware_version: "Arduino Disconnected!" } ] @typedoc """ @@ -66,9 +66,9 @@ defmodule Farmbot.BotState.Configuration do compat_version: args.compat_version, locked: false, target: args.target, - private_ip: "loading...", commit: args.commit, - sync_status: :sync_now + sync_status: :sync_now, + firmware_version: "Arduino Disconnected!" } } {:ok, user_env} = get_config("user_env") @@ -194,6 +194,10 @@ defmodule Farmbot.BotState.Configuration do dispatch(state.informational_settings.controller_version, state) end + def handle_call(:get_fw_version, _from, state) do + dispatch(state.informational_settings.firmware_version, state) + end + def handle_call({:get_config, key}, _from, %State{} = state) when is_atom(key) do dispatch Map.get(state.configuration, key), state diff --git a/lib/bot_state/trackers/hardware_tracker.ex b/lib/bot_state/trackers/hardware_tracker.ex index 8ac2614c..b8f29bcb 100644 --- a/lib/bot_state/trackers/hardware_tracker.ex +++ b/lib/bot_state/trackers/hardware_tracker.ex @@ -13,14 +13,14 @@ defmodule Farmbot.BotState.Hardware do location: [-1,-1,-1], end_stops: {-1,-1,-1,-1,-1,-1}, mcu_params: %{}, - pins: %{} + pins: %{}, ] @type t :: %__MODULE__.State{ location: location, end_stops: end_stops, mcu_params: mcu_params, - pins: pins + pins: pins, } @type location :: [number, ...] @@ -44,7 +44,6 @@ defmodule Farmbot.BotState.Hardware do Logger.error(">> Error setting Hardware Params: #{inspect reason}") end end - {:ok, initial_state} end @@ -53,17 +52,15 @@ defmodule Farmbot.BotState.Hardware do """ @spec set_initial_params(State.t) :: {:ok, :no_params} | :ok | {:error, term} def set_initial_params(%State{} = state) do + # BUG(Connor): The first param is rather unstable for some reason. + # Try to send a fake packet just to make sure we have a good + # Connection to the Firmware + + Farmbot.CeleryScript.Command.read_param(%{label: "param_version"}, []) + Farmbot.Serial.Gcode.Handler.block_send "F83" if Enum.empty?(state.mcu_params) do {:ok, :no_params} else - # BUG(Connor): The first param is rather unstable for some reason. - # Try to send a fake packet just to make sure we have a good - # Connection to the Firmware - - # Its magic - Farmbot.CeleryScript.Command.read_param(%{label: "param_version"}, []) - - # iterate over mcu_params and read each one config_pairs = Enum.map(state.mcu_params, fn({param, val}) -> %Farmbot.CeleryScript.Ast{kind: "pair", args: %{label: param, value: val}, body: []} diff --git a/lib/celery_script/command.ex b/lib/celery_script/command.ex index 62507384..06d379d3 100644 --- a/lib/celery_script/command.ex +++ b/lib/celery_script/command.ex @@ -173,6 +173,8 @@ defmodule Farmbot.CeleryScript.Command do # MUCH IF SORRY ABOUT THAT @spec config_update(%{package: package}, [pair]) :: no_return def config_update(%{package: "arduino_firmware"}, config_pairs) do + # side effects sup + GHan.block_send "F83" blah = pairs_to_tuples(config_pairs) for {param_str, val} <- blah do param_int = GParser.parse_param(param_str) @@ -487,8 +489,9 @@ defmodule Farmbot.CeleryScript.Command do @spec read_param(%{label: String.t}, []) :: no_return def read_param(%{label: param_str}, []) do param_int = GParser.parse_param(param_str) + IO.puts "reading param" if param_int do - GHan.block_send("F21 P#{param_int}") + GHan.block_send("F21 P#{param_int}", 1000) else Logger.error ">> got unknown param: #{param_str}" end diff --git a/lib/celery_script/commands/read_status.ex b/lib/celery_script/commands/read_status.ex index 71ea76ff..39f1f4f9 100644 --- a/lib/celery_script/commands/read_status.ex +++ b/lib/celery_script/commands/read_status.ex @@ -13,6 +13,6 @@ defmodule Farmbot.CeleryScript.Command.ReadStatus do """ @spec run(%{}, []) :: no_return def run(%{}, []) do - Farmbot.BotState.Monitor.get_state + Farmbot.Transport.force_state_push() end end diff --git a/lib/serial/gcode/handler.ex b/lib/serial/gcode/handler.ex index 375a2ddb..36b68890 100644 --- a/lib/serial/gcode/handler.ex +++ b/lib/serial/gcode/handler.ex @@ -106,6 +106,12 @@ defmodule Farmbot.Serial.Gcode.Handler do {:noreply, state} end + def handle_cast({:report_software_version, version}, state) do + parsed_version = parse_version(version) + BotState.set_fw_version(parsed_version) + {:noreply, state} + end + def handle_cast(:dont_handle_me, state), do: {:noreply, state} def handle_cast(event, state) do @@ -123,15 +129,27 @@ defmodule Farmbot.Serial.Gcode.Handler do |> Farmbot.BotState.get_config() end + @spec parse_version(binary) :: binary + defp parse_version(version) do + [derp | _] = String.split(version, " Q0") + derp + end + @doc """ Sends a message and blocks until it completes, or times out. The default timeout is ten seconds. """ @spec block_send(binary, integer) :: {:error, :no_serial} | atom - def block_send(str, timeout \\ 10_000) do + def block_send(str, timeout \\ 10_000) + def block_send(str, timeout) do + if str == "F83" do + IO.puts "UHHHH" + BotState.set_fw_version("WAITING FOR ARDUINO") + end + if Farmbot.Serial.Handler.available? do - GenServer.cast(Farmbot.Serial.Gcode.Handler,{:send, str, self()}) - __MODULE__.block(timeout) # is there a reason why i did this? + GenServer.cast(Farmbot.Serial.Gcode.Handler, {:send, str, self()}) + block(timeout) else {:error, :no_serial} end diff --git a/lib/transport/transport.ex b/lib/transport/transport.ex index e40ed310..1530a866 100644 --- a/lib/transport/transport.ex +++ b/lib/transport/transport.ex @@ -38,6 +38,12 @@ defmodule Farmbot.Transport do def handle_call(:get_state, _from, state), do: {:reply, state, [], state} + def handle_call(:force_state_push, _from, state) do + reset_count() + GenStage.async_notify(__MODULE__, {:status, state}) + {:reply, state, [], state} + end + def handle_events(events, _from, state) do for event <- events do Logger.info "#{__MODULE__} got event: #{inspect event} " @@ -87,7 +93,7 @@ defmodule Farmbot.Transport do inc_count() {:noreply, [], old_state} else - dec_count() # HACK(Connor) Dialyzer hack + # dec_count() # HACK(Connor) Dialyzer hack reset_count() GenStage.async_notify(__MODULE__, {:status, new_state}) {:noreply, [], new_state} @@ -96,10 +102,27 @@ defmodule Farmbot.Transport do def handle_info(_event, state), do: {:noreply, [], state} + @doc """ + Emit a message over all transports + """ @spec emit(any) :: no_return - @spec log(any) :: no_return - @spec get_state :: State.t def emit(message), do: GenStage.cast(__MODULE__, {:emit, message}) + + @doc """ + Log a log message over all transports + """ + @spec log(any) :: no_return def log(message), do: GenStage.cast(__MODULE__, {:log, message}) + + @doc """ + Get the state + """ + @spec get_state :: State.t def get_state, do: GenServer.call(__MODULE__, :get_state) + + @doc """ + Force a state push + """ + @spec force_state_push :: State.t + def force_state_push, do: GenServer.call(__MODULE__, :force_state_push) end diff --git a/test/bot_state/bot_state_test.exs b/test/bot_state/bot_state_test.exs index 2b4f39a0..587e5d5f 100644 --- a/test/bot_state/bot_state_test.exs +++ b/test/bot_state/bot_state_test.exs @@ -82,6 +82,12 @@ defmodule Farmbot.BotStateTest do assert get_hardware_part(:mcu_params) == Farmbot.BotState.get_all_mcu_params end + test "sets firmware version" do + Farmbot.BotState.set_fw_version("uhhhhh") + Process.sleep(100) + assert Farmbot.BotState.get_fw_version == "uhhhhh" + end + test "sets some farmware env vars" do r = Farmbot.BotState.set_user_env(%{"SUPER_COOL_VAR" => 123}) assert(r == true)