force state push on read_status, hardware tracker/arduino comms is broken

pull/269/head
connor rigby 2017-03-09 06:08:18 -08:00
parent 6eebaf3a20
commit ae09844da6
9 changed files with 83 additions and 24 deletions

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ Makefile.bac
_images _images
Makefile Makefile
release-* release-*
dump.rdb

View File

@ -80,7 +80,14 @@ defmodule Farmbot.BotState do
This is just a shortcut This is just a shortcut
""" """
@spec get_fw_version :: String.t @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 """ @doc """
Gets the current controller version Gets the current controller version

View File

@ -27,9 +27,9 @@ defmodule Farmbot.BotState.Configuration do
controller_version: "loading...", controller_version: "loading...",
compat_version: -1, compat_version: -1,
target: "loading...", target: "loading...",
private_ip: nil,
commit: "loading...", commit: "loading...",
sync_status: :sync_now sync_status: :sync_now,
firmware_version: "Arduino Disconnected!"
} }
] ]
@typedoc """ @typedoc """
@ -66,9 +66,9 @@ defmodule Farmbot.BotState.Configuration do
compat_version: args.compat_version, compat_version: args.compat_version,
locked: false, locked: false,
target: args.target, target: args.target,
private_ip: "loading...",
commit: args.commit, commit: args.commit,
sync_status: :sync_now sync_status: :sync_now,
firmware_version: "Arduino Disconnected!"
} }
} }
{:ok, user_env} = get_config("user_env") {:ok, user_env} = get_config("user_env")
@ -194,6 +194,10 @@ defmodule Farmbot.BotState.Configuration do
dispatch(state.informational_settings.controller_version, state) dispatch(state.informational_settings.controller_version, state)
end 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) def handle_call({:get_config, key}, _from, %State{} = state)
when is_atom(key) do when is_atom(key) do
dispatch Map.get(state.configuration, key), state dispatch Map.get(state.configuration, key), state

View File

@ -13,14 +13,14 @@ defmodule Farmbot.BotState.Hardware do
location: [-1,-1,-1], location: [-1,-1,-1],
end_stops: {-1,-1,-1,-1,-1,-1}, end_stops: {-1,-1,-1,-1,-1,-1},
mcu_params: %{}, mcu_params: %{},
pins: %{} pins: %{},
] ]
@type t :: %__MODULE__.State{ @type t :: %__MODULE__.State{
location: location, location: location,
end_stops: end_stops, end_stops: end_stops,
mcu_params: mcu_params, mcu_params: mcu_params,
pins: pins pins: pins,
} }
@type location :: [number, ...] @type location :: [number, ...]
@ -44,7 +44,6 @@ defmodule Farmbot.BotState.Hardware do
Logger.error(">> Error setting Hardware Params: #{inspect reason}") Logger.error(">> Error setting Hardware Params: #{inspect reason}")
end end
end end
{:ok, initial_state} {:ok, initial_state}
end end
@ -53,17 +52,15 @@ defmodule Farmbot.BotState.Hardware do
""" """
@spec set_initial_params(State.t) :: {:ok, :no_params} | :ok | {:error, term} @spec set_initial_params(State.t) :: {:ok, :no_params} | :ok | {:error, term}
def set_initial_params(%State{} = state) do 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 if Enum.empty?(state.mcu_params) do
{:ok, :no_params} {:ok, :no_params}
else 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}) -> config_pairs = Enum.map(state.mcu_params, fn({param, val}) ->
%Farmbot.CeleryScript.Ast{kind: "pair", %Farmbot.CeleryScript.Ast{kind: "pair",
args: %{label: param, value: val}, body: []} args: %{label: param, value: val}, body: []}

View File

@ -173,6 +173,8 @@ defmodule Farmbot.CeleryScript.Command do
# MUCH IF SORRY ABOUT THAT # MUCH IF SORRY ABOUT THAT
@spec config_update(%{package: package}, [pair]) :: no_return @spec config_update(%{package: package}, [pair]) :: no_return
def config_update(%{package: "arduino_firmware"}, config_pairs) do def config_update(%{package: "arduino_firmware"}, config_pairs) do
# side effects sup
GHan.block_send "F83"
blah = pairs_to_tuples(config_pairs) blah = pairs_to_tuples(config_pairs)
for {param_str, val} <- blah do for {param_str, val} <- blah do
param_int = GParser.parse_param(param_str) param_int = GParser.parse_param(param_str)
@ -487,8 +489,9 @@ defmodule Farmbot.CeleryScript.Command do
@spec read_param(%{label: String.t}, []) :: no_return @spec read_param(%{label: String.t}, []) :: no_return
def read_param(%{label: param_str}, []) do def read_param(%{label: param_str}, []) do
param_int = GParser.parse_param(param_str) param_int = GParser.parse_param(param_str)
IO.puts "reading param"
if param_int do if param_int do
GHan.block_send("F21 P#{param_int}") GHan.block_send("F21 P#{param_int}", 1000)
else else
Logger.error ">> got unknown param: #{param_str}" Logger.error ">> got unknown param: #{param_str}"
end end

View File

@ -13,6 +13,6 @@ defmodule Farmbot.CeleryScript.Command.ReadStatus do
""" """
@spec run(%{}, []) :: no_return @spec run(%{}, []) :: no_return
def run(%{}, []) do def run(%{}, []) do
Farmbot.BotState.Monitor.get_state Farmbot.Transport.force_state_push()
end end
end end

View File

@ -106,6 +106,12 @@ defmodule Farmbot.Serial.Gcode.Handler do
{:noreply, state} {:noreply, state}
end 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(:dont_handle_me, state), do: {:noreply, state}
def handle_cast(event, state) do def handle_cast(event, state) do
@ -123,15 +129,27 @@ defmodule Farmbot.Serial.Gcode.Handler do
|> Farmbot.BotState.get_config() |> Farmbot.BotState.get_config()
end end
@spec parse_version(binary) :: binary
defp parse_version(version) do
[derp | _] = String.split(version, " Q0")
derp
end
@doc """ @doc """
Sends a message and blocks until it completes, or times out. Sends a message and blocks until it completes, or times out.
The default timeout is ten seconds. The default timeout is ten seconds.
""" """
@spec block_send(binary, integer) :: {:error, :no_serial} | atom @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 if Farmbot.Serial.Handler.available? do
GenServer.cast(Farmbot.Serial.Gcode.Handler,{:send, str, self()}) GenServer.cast(Farmbot.Serial.Gcode.Handler, {:send, str, self()})
__MODULE__.block(timeout) # is there a reason why i did this? block(timeout)
else else
{:error, :no_serial} {:error, :no_serial}
end end

View File

@ -38,6 +38,12 @@ defmodule Farmbot.Transport do
def handle_call(:get_state, _from, state), do: {:reply, state, [], state} 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 def handle_events(events, _from, state) do
for event <- events do for event <- events do
Logger.info "#{__MODULE__} got event: #{inspect event} " Logger.info "#{__MODULE__} got event: #{inspect event} "
@ -87,7 +93,7 @@ defmodule Farmbot.Transport do
inc_count() inc_count()
{:noreply, [], old_state} {:noreply, [], old_state}
else else
dec_count() # HACK(Connor) Dialyzer hack # dec_count() # HACK(Connor) Dialyzer hack
reset_count() reset_count()
GenStage.async_notify(__MODULE__, {:status, new_state}) GenStage.async_notify(__MODULE__, {:status, new_state})
{:noreply, [], new_state} {:noreply, [], new_state}
@ -96,10 +102,27 @@ defmodule Farmbot.Transport do
def handle_info(_event, state), do: {:noreply, [], state} def handle_info(_event, state), do: {:noreply, [], state}
@doc """
Emit a message over all transports
"""
@spec emit(any) :: no_return @spec emit(any) :: no_return
@spec log(any) :: no_return
@spec get_state :: State.t
def emit(message), do: GenStage.cast(__MODULE__, {:emit, message}) 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}) 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) 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 end

View File

@ -82,6 +82,12 @@ defmodule Farmbot.BotStateTest do
assert get_hardware_part(:mcu_params) == Farmbot.BotState.get_all_mcu_params assert get_hardware_part(:mcu_params) == Farmbot.BotState.get_all_mcu_params
end 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 test "sets some farmware env vars" do
r = Farmbot.BotState.set_user_env(%{"SUPER_COOL_VAR" => 123}) r = Farmbot.BotState.set_user_env(%{"SUPER_COOL_VAR" => 123})
assert(r == true) assert(r == true)