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
Makefile
release-*
dump.rdb

View File

@ -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

View File

@ -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

View File

@ -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: []}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)