start to bundle arduino firmware with os
parent
735124eb86
commit
157770fa2e
|
@ -35,3 +35,4 @@ _images
|
|||
Makefile
|
||||
release-*
|
||||
dump.rdb
|
||||
#priv/firmware.hex
|
||||
|
|
35
blah.exs
35
blah.exs
|
@ -1,35 +0,0 @@
|
|||
defmodule F do
|
||||
require Logger
|
||||
@path "/tmp/logs.txt"
|
||||
|
||||
def blah(count) when count > 10000 do
|
||||
print()
|
||||
end
|
||||
|
||||
def blah(count \\ 0) do
|
||||
Logger.debug random_number()
|
||||
blah(count + 1)
|
||||
end
|
||||
|
||||
def print do
|
||||
f = case File.stat(@path) do
|
||||
{:ok, f} -> f
|
||||
_ ->
|
||||
seed()
|
||||
print()
|
||||
end
|
||||
if f.size > 52000, do: Logger.warn "File is too big!"
|
||||
blah = File.read! @path
|
||||
[rhead | _rest] = String.split(blah, "\r\n")
|
||||
Logger.debug "File size is: #{f.size}"
|
||||
Logger.debug "First line is: #{rhead}"
|
||||
end
|
||||
|
||||
def random_number do
|
||||
:rand.uniform(:os.system_time)
|
||||
end
|
||||
|
||||
def seed do
|
||||
for i <- 0..50, do: Logger.debug "Seeding: #{i}"
|
||||
end
|
||||
end
|
|
@ -14,7 +14,6 @@ defmodule Farmbot.BotState.Configuration do
|
|||
configuration: %{
|
||||
user_env: %{},
|
||||
os_auto_update: false,
|
||||
fw_auto_update: false,
|
||||
steps_per_mm_x: 10,
|
||||
steps_per_mm_y: 10,
|
||||
steps_per_mm_z: 50,
|
||||
|
@ -46,7 +45,6 @@ defmodule Farmbot.BotState.Configuration do
|
|||
configuration: %{
|
||||
user_env: map,
|
||||
os_auto_update: boolean,
|
||||
fw_auto_update: boolean,
|
||||
steps_per_mm_x: integer,
|
||||
steps_per_mm_y: integer,
|
||||
steps_per_mm_z: integer,
|
||||
|
@ -73,7 +71,6 @@ defmodule Farmbot.BotState.Configuration do
|
|||
}
|
||||
{:ok, user_env} = get_config("user_env")
|
||||
{:ok, os_a_u} = get_config("os_auto_update")
|
||||
{:ok, fw_a_u} = get_config("fw_auto_update")
|
||||
{:ok, spm_x} = get_config("steps_per_mm_x")
|
||||
{:ok, spm_y} = get_config("steps_per_mm_y")
|
||||
{:ok, spm_z} = get_config("steps_per_mm_z")
|
||||
|
@ -84,7 +81,6 @@ defmodule Farmbot.BotState.Configuration do
|
|||
%State{initial | configuration: %{
|
||||
user_env: user_env,
|
||||
os_auto_update: os_a_u,
|
||||
fw_auto_update: fw_a_u,
|
||||
steps_per_mm_x: spm_x,
|
||||
steps_per_mm_y: spm_y,
|
||||
steps_per_mm_z: spm_z,
|
||||
|
@ -110,19 +106,6 @@ defmodule Farmbot.BotState.Configuration do
|
|||
dispatch true, new_state
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "fw_auto_update", f_value},
|
||||
_from, %State{} = state) do
|
||||
value = cond do
|
||||
f_value == 1 -> true
|
||||
f_value == 0 -> false
|
||||
is_boolean(f_value) -> f_value
|
||||
end
|
||||
new_config = Map.put(state.configuration, :fw_auto_update, value)
|
||||
new_state = %State{state | configuration: new_config}
|
||||
put_config("fw_auto_update", value)
|
||||
dispatch true, new_state
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "steps_per_mm_x", val}, _, state) do
|
||||
config = state.configuration
|
||||
new_config = %{config | steps_per_mm_x: val}
|
||||
|
|
|
@ -202,6 +202,9 @@ defmodule Farmbot.CeleryScript.Command do
|
|||
@spec pairs_to_tuples([pair]) :: [tuple]
|
||||
def pairs_to_tuples(config_pairs) do
|
||||
Enum.map(config_pairs, fn(%Ast{} = thing) ->
|
||||
if thing.args.label == nil do
|
||||
Logger.error("FINDME: #{inspect config_pairs}")
|
||||
end
|
||||
{thing.args.label, thing.args.value}
|
||||
end)
|
||||
end
|
||||
|
@ -469,8 +472,8 @@ defmodule Farmbot.CeleryScript.Command do
|
|||
def check_updates(%{package: package}, []) do
|
||||
case package do
|
||||
"arduino_firmware" ->
|
||||
# TODO(Connor): Move this, and its contents somewhere else
|
||||
Farmbot.Updates.Handler.check_and_download_updates(:fw)
|
||||
Logger.warn "Arduino Firmware is now coupled to farmbot_os and can't " <>
|
||||
"updated individually."
|
||||
"farmbot_os" ->
|
||||
Farmbot.System.Updates.check_and_download_updates()
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ defmodule Farmbot.Configurator.Router do
|
|||
# this is so we can serve the bundle.js file.
|
||||
plug Plug.Static, at: "/", from: :farmbot
|
||||
plug Plug.Static, at: "/image", from: "/tmp/images", gzip: false
|
||||
plug Plug.Parsers, parsers: [:urlencoded, :multipart], length: 111409842
|
||||
|
||||
plug Plug.Parsers, parsers: [:urlencoded, :json],
|
||||
pass: ["text/*"],
|
||||
pass: ["*/*"],
|
||||
json_decoder: Poison
|
||||
plug :match
|
||||
plug :dispatch
|
||||
|
@ -21,9 +21,7 @@ defmodule Farmbot.Configurator.Router do
|
|||
|
||||
target = Mix.Project.config[:target]
|
||||
|
||||
if Mix.env == :dev do
|
||||
use Plug.Debugger, otp_app: :farmbot
|
||||
end
|
||||
if Mix.env == :dev, do: use Plug.Debugger, otp_app: :farmbot
|
||||
|
||||
get "/image/latest" do
|
||||
list_images = fn() ->
|
||||
|
@ -69,24 +67,23 @@ defmodule Farmbot.Configurator.Router do
|
|||
|
||||
post "/api/config" do
|
||||
Logger.info ">> router got config json"
|
||||
{:ok, body, _} = read_body(conn)
|
||||
rbody = Poison.decode!(body)
|
||||
# TODO THIS NEEDS SOME HARD CHECKING. PROBABLY IN THE CONFIG STORAGE MODULE
|
||||
ConfigStorage.replace_config_file(rbody)
|
||||
conn |> send_resp(200,body)
|
||||
{:ok, _body, conn} = read_body(conn)
|
||||
ConfigStorage.replace_config_file(conn.body_params)
|
||||
conn |> send_resp(200, "OK")
|
||||
end
|
||||
|
||||
post "/api/config/creds" do
|
||||
Logger.info ">> router got credentials"
|
||||
{:ok, body, _} = read_body(conn)
|
||||
%{"email" => email,"pass" => pass,"server" => server} = Poison.decode!(body)
|
||||
{:ok, _body, conn} = read_body(conn)
|
||||
|
||||
%{"email" => email,"pass" => pass,"server" => server} = conn.body_params
|
||||
Farmbot.Auth.interim(email, pass, server)
|
||||
conn |> send_resp(200, "ok")
|
||||
conn |> send_resp(200, "OK")
|
||||
end
|
||||
|
||||
post "/api/network/scan" do
|
||||
{:ok, body, _} = read_body(conn)
|
||||
%{"iface" => iface} = Poison.decode!(body)
|
||||
{:ok, _body, conn} = read_body(conn)
|
||||
%{"iface" => iface} = conn.body_params
|
||||
scan = NetMan.scan(iface)
|
||||
case scan do
|
||||
{:error, reason} -> conn |> send_resp(500, "could not scan: #{inspect reason}")
|
||||
|
@ -147,6 +144,28 @@ defmodule Farmbot.Configurator.Router do
|
|||
conn |> send_resp(200, json)
|
||||
end
|
||||
|
||||
post "/api/flash_firmware" do
|
||||
"#{:code.priv_dir(:farmbot)}/firmware.hex" |> handle_arduino(conn)
|
||||
end
|
||||
|
||||
get "/firmware/upload" do
|
||||
html = ~s"""
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Upload a FarmbotOS Firmware file (.fw) or a Arduino Firmware file (.hex)
|
||||
</p>
|
||||
<form action="/api/upload_firmware" method="post" enctype="multipart/form-data" accept="*">
|
||||
<input type="file" name="firmware" id="fileupload">
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
conn |> send_resp(200, html)
|
||||
end
|
||||
|
||||
plug Plug.Parsers, parsers: [:urlencoded, :multipart], length: 111409842
|
||||
post "/api/upload_firmware" do
|
||||
{:ok, _body, conn} = Plug.Conn.read_body(conn)
|
||||
upload = conn.body_params["firmware"]
|
||||
|
@ -163,13 +182,21 @@ defmodule Farmbot.Configurator.Router do
|
|||
end
|
||||
end
|
||||
|
||||
# anything that doesn't match a rest end point gets the index.
|
||||
match _, do: conn |> send_resp(404, "not found")
|
||||
|
||||
@spec make_html :: binary
|
||||
defp make_html do
|
||||
"#{:code.priv_dir(:farmbot)}/static/index.html" |> File.read!
|
||||
end
|
||||
|
||||
defp handle_arduino(file, conn) do
|
||||
errrm = fn(blerp) ->
|
||||
receive do
|
||||
:done ->
|
||||
blerp |> send_resp(200, "OK")
|
||||
{:error, reason} ->
|
||||
blerp |> send_resp(400, IO.inspect (reason))
|
||||
blerp |> send_resp(400, IO.inspect(reason))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -191,6 +218,7 @@ defmodule Farmbot.Configurator.Router do
|
|||
errrm.(conn)
|
||||
_ ->
|
||||
Logger.warn "Please only have one serial device when updating firmware"
|
||||
conn |> send_resp(200, "OK")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -209,30 +237,4 @@ defmodule Farmbot.Configurator.Router do
|
|||
else
|
||||
defp handle_os(_file, conn), do: conn |> send_resp(200, "OK")
|
||||
end
|
||||
|
||||
|
||||
get "/firmware/upload" do
|
||||
html = ~s"""
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Upload a FarmbotOS Firmware file (.fw) or a Arduino Firmware file (.hex)
|
||||
</p>
|
||||
<form action="/api/upload_firmware" method="post" enctype="multipart/form-data" accept="*">
|
||||
<input type="file" name="firmware" id="fileupload">
|
||||
<input type="submit" value="submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
conn |> send_resp(200, html)
|
||||
end
|
||||
|
||||
# anything that doesn't match a rest end point gets the index.
|
||||
match _, do: conn |> send_resp(404, "not found")
|
||||
|
||||
@spec make_html :: binary
|
||||
defp make_html do
|
||||
"#{:code.priv_dir(:farmbot)}/static/index.html" |> File.read!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -160,10 +160,14 @@ defmodule Farmbot.Serial.Gcode.Parser do
|
|||
def parse_param("21"), do: :movement_invert_endpoints_x
|
||||
def parse_param("22"), do: :movement_invert_endpoints_y
|
||||
def parse_param("23"), do: :movement_invert_endpoints_z
|
||||
def parse_param("25"), do: :movement_enable_endpoints_x
|
||||
def parse_param("26"), do: :movement_enable_endpoints_y
|
||||
def parse_param("27"), do: :movement_enable_endpoints_z
|
||||
def parse_param("31"), do: :movement_invert_motor_x
|
||||
def parse_param("32"), do: :movement_invert_motor_y
|
||||
def parse_param("33"), do: :movement_invert_motor_z
|
||||
def parse_param("36"), do: :moevment_secondary_motor_x
|
||||
def parse_param("37"), do: :movement_secondary_motor_invert_x
|
||||
def parse_param("41"), do: :movement_steps_acc_dec_x
|
||||
def parse_param("42"), do: :movement_steps_acc_dec_y
|
||||
def parse_param("43"), do: :movement_steps_acc_dec_z
|
||||
|
@ -217,7 +221,11 @@ defmodule Farmbot.Serial.Gcode.Parser do
|
|||
def parse_param(:movement_invert_motor_x), do: 31
|
||||
def parse_param(:movement_invert_motor_y), do: 32
|
||||
def parse_param(:movement_invert_motor_z), do: 33
|
||||
def parse_param(:movement_enable_endpoints_x), do: 25
|
||||
def parse_param(:movement_enable_endpoints_y), do: 26
|
||||
def parse_param(:movement_enable_endpoints_z), do: 27
|
||||
def parse_param(:moevment_secondary_motor_x), do: 36
|
||||
def parse_param(:movement_secondary_motor_invert_x), do: 37
|
||||
def parse_param(:movement_steps_acc_dec_x), do: 41
|
||||
def parse_param(:movement_steps_acc_dec_y), do: 42
|
||||
def parse_param(:movement_steps_acc_dec_z), do: 43
|
||||
|
@ -260,6 +268,10 @@ defmodule Farmbot.Serial.Gcode.Parser do
|
|||
def parse_param(param_string) when is_bitstring(param_string),
|
||||
do: param_string |> String.to_atom |> parse_param
|
||||
|
||||
def parse_param(_), do: nil
|
||||
def parse_param(uhh) do
|
||||
require Logger
|
||||
Logger.error("LOOK AT ME IM IMPORTANT: #{inspect uhh}")
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -127,6 +127,8 @@ defmodule Farmbot.Serial.Handler do
|
|||
state = %{tty: tty, nerves: nerves, queue: :queue.new(), current: nil}
|
||||
{:ok, state}
|
||||
else
|
||||
Logger.warn "Handshake failed!"
|
||||
deregister()
|
||||
# if we cant handshake, kill the previous Nerves
|
||||
GenServer.stop(nerves, :normal)
|
||||
:ignore
|
||||
|
@ -166,6 +168,7 @@ defmodule Farmbot.Serial.Handler do
|
|||
# Recieved happens before our actual response, just go to the next one
|
||||
# if it exists
|
||||
{:nerves_uart, ^tty, "R01" <> _} -> do_handshake(nerves, tty, handshake)
|
||||
{:nerves_uart, ^tty, "Command:" <> _} -> do_handshake(nerves, tty, handshake)
|
||||
|
||||
# This COULD be our handshake. Check it.
|
||||
{:nerves_uart, ^tty, str} ->
|
||||
|
@ -196,6 +199,13 @@ defmodule Farmbot.Serial.Handler do
|
|||
|
||||
@spec update_default(pid) :: :ok | no_return
|
||||
defp update_default(pid) do
|
||||
deregister()
|
||||
# Either way, register this pid as the new one.
|
||||
Process.register(pid, __MODULE__)
|
||||
end
|
||||
|
||||
@spec deregister :: no_return
|
||||
defp deregister do
|
||||
# lookup the old default pid
|
||||
old_pid = Process.whereis(__MODULE__)
|
||||
|
||||
|
@ -204,9 +214,6 @@ defmodule Farmbot.Serial.Handler do
|
|||
Logger.debug "Deregistering #{inspect old_pid} from default Serial Handler"
|
||||
Process.unregister(__MODULE__)
|
||||
end
|
||||
|
||||
# Either way, register this pid as the new one.
|
||||
Process.register(pid, __MODULE__)
|
||||
end
|
||||
|
||||
def handle_call(:get_state, _, state), do: {:reply, state, state}
|
||||
|
@ -371,12 +378,12 @@ defmodule Farmbot.Serial.Handler do
|
|||
end
|
||||
|
||||
defp handle_gcode({:unhandled_gcode, code}, state) do
|
||||
Logger.warn ">> got an unhandled gcode! #{code}"
|
||||
Logger.warn ">> got an misc gcode #{code}"
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
defp handle_gcode(parsed, state) do
|
||||
Logger.warn "Unhandled GCODE: #{inspect parsed}"
|
||||
Logger.warn "Unhandled message: #{inspect parsed}"
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
|
@ -395,11 +402,13 @@ defmodule Farmbot.Serial.Handler do
|
|||
"-Uflash:w:#{hex_file}:i"]
|
||||
|
||||
"avrdude" |> System.cmd(params) |> log(pid)
|
||||
handler = Process.whereis(__MODULE__)
|
||||
if handler, do: spawn fn() -> GenServer.stop(handler, :normal) end
|
||||
Farmbot.Serial.Supervisor.open_ttys(Farmbot.Serial.Supervisor, [tty])
|
||||
end
|
||||
|
||||
defp log({_, 0}, pid) do
|
||||
Logger.debug "FLASHED FIRMWARE!"
|
||||
Farmbot.CeleryScript.Command.reboot(%{}, [])
|
||||
send pid, :done
|
||||
end
|
||||
|
||||
|
|
|
@ -29,12 +29,10 @@ defmodule Farmbot.Serial.Supervisor do
|
|||
supervise(children, strategy: :one_for_all)
|
||||
end
|
||||
|
||||
@spec open_ttys(atom | pid) :: :ok | no_return
|
||||
def open_ttys(supervisor) do
|
||||
UART.enumerate()
|
||||
|> Map.drop(["ttyS0","ttyAMA0"])
|
||||
|> Map.keys
|
||||
|> try_open(supervisor)
|
||||
@spec open_ttys(atom | pid, [binary]) :: :ok | no_return
|
||||
def open_ttys(supervisor, ttys \\ nil) do
|
||||
blah = ttys || UART.enumerate() |> Map.drop(["ttyS0","ttyAMA0"]) |> Map.keys
|
||||
blah |> try_open(supervisor)
|
||||
end
|
||||
|
||||
@spec try_open([binary], atom | pid) :: :ok | no_return
|
||||
|
|
|
@ -1,158 +0,0 @@
|
|||
defmodule Farmbot.Updates.Handler do
|
||||
alias Farmbot.Auth
|
||||
alias Farmbot.BotState
|
||||
require Logger
|
||||
#TODO(connor): please refactor this into a target specific module.
|
||||
|
||||
@moduledoc """
|
||||
Bunch of stuff to do updates.
|
||||
"""
|
||||
|
||||
@type update_output
|
||||
:: {:update, String.t | nil}
|
||||
| {:error, String.t | atom}
|
||||
| :no_updates
|
||||
|
||||
@doc """
|
||||
Another shortcut for the shorcut
|
||||
"""
|
||||
@spec check_and_download_updates(:os | :fw)
|
||||
:: :ok | {:error, atom} | :no_updates
|
||||
def check_and_download_updates(something) do
|
||||
Logger.info ">> Is checking for updates: #{inspect something}"
|
||||
case check_updates(something) do
|
||||
{:error, reason} ->
|
||||
Logger.info """
|
||||
>> encountered an error checking for updates: #{inspect reason}.
|
||||
"""
|
||||
{:update, url} ->
|
||||
install_update(something, url)
|
||||
:no_updates ->
|
||||
Logger.info(">> is already on the latest operating system version.",
|
||||
channels: [:toast], type: :success)
|
||||
end
|
||||
end
|
||||
|
||||
@spec install_update(:fw, String.t) :: no_return
|
||||
defp install_update(:fw, url) do
|
||||
Logger.info ">> found a firmware update!"
|
||||
File.rm("/tmp/update.hex")
|
||||
file = Downloader.run(url, "/tmp/update.hex")
|
||||
Logger.info """
|
||||
>> is installing a firmware update. I may act weird for a moment
|
||||
""",
|
||||
channels: [:toast]
|
||||
if Farmbot.Serial.Handler.available? do
|
||||
GenServer.cast(Farmbot.Serial.Handler, {:update_fw, file, self()})
|
||||
receive do
|
||||
:done ->
|
||||
Logger.info ">> is done installing a firmware update!", type: :success,
|
||||
channels: [:toast]
|
||||
{:error, reason} ->
|
||||
Logger.error """
|
||||
>> encountered an error installing firmware update!: #{inspect reason}
|
||||
""",
|
||||
channels: [:toast]
|
||||
end
|
||||
else
|
||||
Logger.debug "doing some magic..."
|
||||
herp = Nerves.UART.enumerate()
|
||||
|> Map.drop(["ttyS0","ttyAMA0"])
|
||||
|> Map.keys
|
||||
case herp do
|
||||
[tty] ->
|
||||
Logger.debug "magic complete!"
|
||||
Farmbot.Serial.Handler.flash_firmware(tty, file, self())
|
||||
_ ->
|
||||
Logger.warn "Please only have one serial device when updating firmware"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@spec check_updates(any) :: no_return
|
||||
def check_updates(:fw) do
|
||||
with {:ok, token} <- Auth.get_token,
|
||||
do: check_updates(
|
||||
token.unencoded.fw_update_server,
|
||||
BotState.get_fw_version,
|
||||
".hex")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Uses Github Release api to check for an update.
|
||||
If there is an update on URL, it returns the asset with the given extension
|
||||
for said update.
|
||||
"""
|
||||
@spec check_updates(String.t, String.t, String.t) :: update_output
|
||||
def check_updates(url, current_version, extension) do
|
||||
resp = HTTPoison.get url, ["User-Agent": "FarmbotOLD"]
|
||||
with {:assets, new_version, assets} <- parse_resp(resp),
|
||||
true <- is_updates?(current_version, new_version),
|
||||
do: get_dl_url(assets, extension)
|
||||
end
|
||||
|
||||
@spec get_dl_url([any,...] | map, String.t)
|
||||
:: {:update, String.t} | {:error, atom}
|
||||
defp get_dl_url(assets, extension)
|
||||
when is_list(assets) do
|
||||
Enum.find_value(assets, {:error, :no_assets},
|
||||
fn asset ->
|
||||
url = get_dl_url(asset)
|
||||
if String.contains?(url, extension) do
|
||||
{:update, url}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp get_dl_url(asset) when is_map(asset) do
|
||||
Map.get(asset, "browser_download_url")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if two strings are the same lol
|
||||
"""
|
||||
@spec is_updates?(String.t, String.t) :: :no_updates | true
|
||||
def is_updates?(current, new) do
|
||||
if current == new do
|
||||
:no_updates
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
@doc """
|
||||
Parses the httpotion response.
|
||||
"""
|
||||
|
||||
@spec parse_resp(HTTPoison.Response.t)
|
||||
:: {:assets, Strint.t, String.t} | {:error, :bad_resp}
|
||||
def parse_resp(
|
||||
{:ok, %HTTPoison.Response{
|
||||
body: body,
|
||||
status_code: 200}})
|
||||
do
|
||||
json = Poison.decode!(body)
|
||||
"v" <> new_version = Map.get(json, "tag_name")
|
||||
assets = Map.get(json, "assets")
|
||||
{:assets, new_version, assets}
|
||||
end
|
||||
|
||||
def parse_resp(_), do: {:error, :bad_resp}
|
||||
|
||||
def do_update_check do
|
||||
Logger.info ">> is checking for updates."
|
||||
|
||||
# check configuration.
|
||||
case BotState.get_config(:os_auto_update) do
|
||||
true -> Farmbot.System.Updates.check_and_download_updates()
|
||||
_ -> Logger.warn ">> won't check for operating system updates."
|
||||
end
|
||||
|
||||
case BotState.get_config(:fw_auto_update) do
|
||||
true -> check_and_download_updates(:fw)
|
||||
_ -> Logger.warn ">> won't check for firmware updates."
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,7 +6,6 @@
|
|||
"configuration": {
|
||||
"user_env": {},
|
||||
"os_auto_update": false,
|
||||
"fw_auto_update": false,
|
||||
"first_party_farmware": true,
|
||||
"steps_per_mm_x": 5,
|
||||
"steps_per_mm_y": 5,
|
||||
|
@ -16,6 +15,7 @@
|
|||
"distance_mm_z": 800
|
||||
},
|
||||
"hardware": {
|
||||
"params": {}
|
||||
"params": {},
|
||||
"custom_firmware": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
},
|
||||
"ntp": true,
|
||||
"ssh": true
|
||||
"ssh": false
|
||||
},
|
||||
"authorization": {
|
||||
"server": "https://my.farmbot.io"
|
||||
|
@ -15,7 +15,6 @@
|
|||
"configuration": {
|
||||
"user_env": {},
|
||||
"os_auto_update": false,
|
||||
"fw_auto_update": false,
|
||||
"first_party_farmware": true,
|
||||
"steps_per_mm_x": 5,
|
||||
"steps_per_mm_y": 5,
|
||||
|
@ -25,6 +24,7 @@
|
|||
"distance_mm_z": 800
|
||||
},
|
||||
"hardware": {
|
||||
"params": {}
|
||||
"params": {},
|
||||
"custom_firmware": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
},
|
||||
"ntp": true,
|
||||
"ssh": true
|
||||
"ssh": false
|
||||
},
|
||||
"authorization": {
|
||||
"server": "https://my.farmbot.io"
|
||||
|
@ -15,7 +15,6 @@
|
|||
"configuration": {
|
||||
"user_env": {},
|
||||
"os_auto_update": false,
|
||||
"fw_auto_update": false,
|
||||
"first_party_farmware": true,
|
||||
"steps_per_mm_x": 5,
|
||||
"steps_per_mm_y": 5,
|
||||
|
@ -25,6 +24,7 @@
|
|||
"distance_mm_z": 800
|
||||
},
|
||||
"hardware": {
|
||||
"params": {}
|
||||
"params": {},
|
||||
"custom_firmware": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
}
|
||||
},
|
||||
"ntp": true,
|
||||
"ssh": true
|
||||
"ssh": false
|
||||
},
|
||||
"authorization": {
|
||||
"server": "https://my.farmbot.io"
|
||||
|
@ -22,7 +22,6 @@
|
|||
"configuration": {
|
||||
"user_env": {},
|
||||
"os_auto_update": false,
|
||||
"fw_auto_update": false,
|
||||
"first_party_farmware": true,
|
||||
"steps_per_mm_x": 5,
|
||||
"steps_per_mm_y": 5,
|
||||
|
@ -32,6 +31,7 @@
|
|||
"distance_mm_z": 800
|
||||
},
|
||||
"hardware": {
|
||||
"params": {}
|
||||
"params": {},
|
||||
"custom_firmware": false
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
|||
defmodule DisableSSH do
|
||||
def run(json) do
|
||||
network = json["network"]
|
||||
net_config =
|
||||
if network do
|
||||
# if we have a network config, make ssh key false
|
||||
Map.put(network, "ssh", false)
|
||||
else
|
||||
# if no network, just make it false.
|
||||
false
|
||||
end
|
||||
|
||||
%{json | "network" => net_config}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
defmodule RemoveArduinoFwUpdates do
|
||||
def run(json) do
|
||||
configuration = json["configuration"]
|
||||
configuration = Map.delete(configuration, "fw_auto_update")
|
||||
%{json | "configuration" => configuration}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
defmodule RemoveArduinoFwUpdates do
|
||||
def run(json) do
|
||||
hardware = json["hardware"]
|
||||
hardware = Map.put(hardware, "custom_firmware", false)
|
||||
%{json | "hardware" => hardware}
|
||||
end
|
||||
end
|
|
@ -49,10 +49,6 @@ defmodule Farmbot.BotStateTest do
|
|||
os_auto_update = Farmbot.BotState.get_config(:os_auto_update)
|
||||
assert(os_auto_update == false)
|
||||
|
||||
true = Farmbot.BotState.update_config("fw_auto_update", false)
|
||||
fw_auto_update = Farmbot.BotState.get_config(:fw_auto_update)
|
||||
assert(fw_auto_update == false)
|
||||
|
||||
true = Farmbot.BotState.update_config("steps_per_mm_x", 123)
|
||||
true = Farmbot.BotState.update_config("steps_per_mm_y", 456)
|
||||
true = Farmbot.BotState.update_config("steps_per_mm_z", 789)
|
||||
|
|
|
@ -6,10 +6,11 @@ import { observer } from "mobx-react";
|
|||
interface Props {
|
||||
mobx: MainState;
|
||||
}
|
||||
export function AdvancedSettings({mobx}: Props) {
|
||||
export function AdvancedSettings({ mobx }: Props) {
|
||||
let ssh = false;
|
||||
let ntp = false
|
||||
let ntp = false;
|
||||
let hasNetwork = mobx.configuration.network ? true : false;
|
||||
let customFW = false;
|
||||
|
||||
if (mobx.configuration.network) {
|
||||
ssh = mobx.configuration.network.ssh;
|
||||
|
@ -22,9 +23,20 @@ export function AdvancedSettings({mobx}: Props) {
|
|||
<label> Factory Reset Your Bot </label>
|
||||
<button type="button" onClick={() => {
|
||||
mobx.factoryReset();
|
||||
} }> Factory Reset your bot! </button>
|
||||
}}> Factory Reset your bot! </button>
|
||||
</fieldset>
|
||||
|
||||
{/* Allow the user to force custom firmware */}
|
||||
<div>
|
||||
<label> Use Custom Arduino Firmware </label>
|
||||
<input type="checkbox"
|
||||
defaultChecked={false}
|
||||
onChange={(event) => {
|
||||
customFW = event.currentTarget.checked;
|
||||
mobx.CustomFW(customFW);
|
||||
}} />
|
||||
</div>
|
||||
|
||||
{/* Allow the user to force network to be enabled */}
|
||||
<div>
|
||||
<label> Enable Network</label>
|
||||
|
@ -33,8 +45,7 @@ export function AdvancedSettings({mobx}: Props) {
|
|||
onChange={(event) => {
|
||||
mobx.toggleNetwork();
|
||||
hasNetwork = event.currentTarget.checked;
|
||||
}
|
||||
} />
|
||||
}} />
|
||||
</div>
|
||||
|
||||
{/* hide these settings if we dont have network */}
|
||||
|
@ -46,7 +57,7 @@ export function AdvancedSettings({mobx}: Props) {
|
|||
onChange={(event) => {
|
||||
let blah = event.currentTarget.checked;
|
||||
mobx.toggleSSH(blah);
|
||||
} } />
|
||||
}} />
|
||||
</fieldset>
|
||||
|
||||
{/* NTP */}
|
||||
|
@ -56,10 +67,12 @@ export function AdvancedSettings({mobx}: Props) {
|
|||
onChange={(event) => {
|
||||
let blah = event.currentTarget.checked;
|
||||
mobx.toggleNTP(blah);
|
||||
} } />
|
||||
}} />
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
}
|
|
@ -66,11 +66,11 @@ export interface DhcpConfigFileNetIface extends ConfigFileNetIface {
|
|||
default: "dhcp";
|
||||
}
|
||||
|
||||
/** Farmbot's Configuratrion
|
||||
/** Farmbot's Configuratrion
|
||||
* doing an HTTP get to "/api/config" will give the bots current config.
|
||||
*/
|
||||
export interface BotConfigFile {
|
||||
/** network false indicates that farmbot will already have network
|
||||
/** network false indicates that farmbot will already have network
|
||||
* when started.
|
||||
*/
|
||||
network: {
|
||||
|
@ -92,8 +92,6 @@ export interface BotConfigFile {
|
|||
configuration: {
|
||||
/** auto update the operating system */
|
||||
os_auto_update: boolean;
|
||||
/** auto update the arduino firmware */
|
||||
fw_auto_update: boolean;
|
||||
/** steps per milimeter for the arduino firmware */
|
||||
steps_per_mm: {
|
||||
x: number;
|
||||
|
@ -104,6 +102,7 @@ export interface BotConfigFile {
|
|||
/** hardware mcu stuff */
|
||||
hardware: {
|
||||
params: McuParams;
|
||||
custom_firmware: boolean;
|
||||
}
|
||||
}
|
||||
export type LogChannel = "toast";
|
||||
|
|
|
@ -49,12 +49,12 @@ export class Main extends React.Component<MainProps, FormState> {
|
|||
showCustomNetworkWidget: false,
|
||||
ssidSelection: {},
|
||||
customInterface: null,
|
||||
connecting: false
|
||||
connecting: false,
|
||||
};
|
||||
}
|
||||
|
||||
@action
|
||||
handleSubmit(event: React.SyntheticEvent<HTMLFormElement>) {
|
||||
async handleSubmit(event: React.SyntheticEvent<HTMLFormElement>) {
|
||||
event.preventDefault();
|
||||
let mainState = this.props.mobx;
|
||||
let fullFile = mainState.configuration;
|
||||
|
@ -65,8 +65,19 @@ export class Main extends React.Component<MainProps, FormState> {
|
|||
console.log("server: " + server);
|
||||
|
||||
if ((email && pass && server) && this.state.connecting != true) {
|
||||
// this.state.connecting = true;
|
||||
this.setState({ connecting: true });
|
||||
|
||||
// try to flash the arduino
|
||||
if (!fullFile.hardware.custom_firmware) {
|
||||
try {
|
||||
await mainState.flashFW();
|
||||
console.log("Firmware Flashed!!!");
|
||||
} catch (_error) {
|
||||
console.error("Firmware failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mainState.uploadCreds(email, pass, server)
|
||||
.then((thing) => {
|
||||
console.log("uploaded web app credentials!");
|
||||
|
@ -75,6 +86,7 @@ export class Main extends React.Component<MainProps, FormState> {
|
|||
.catch((thing) => {
|
||||
console.error("Error uploading web app credentials!")
|
||||
});
|
||||
|
||||
} else {
|
||||
console.error("Email, Password, or Server is incomplete or already connecting!")
|
||||
return;
|
||||
|
|
|
@ -62,10 +62,9 @@ export class MainState {
|
|||
},
|
||||
configuration: {
|
||||
os_auto_update: false,
|
||||
fw_auto_update: false,
|
||||
steps_per_mm: { x: 500, y: 500, z: 500 }
|
||||
},
|
||||
hardware: { params: {} }
|
||||
hardware: { params: {}, custom_firmware: false }
|
||||
};
|
||||
|
||||
@observable ssids: string[] = [];
|
||||
|
@ -142,6 +141,15 @@ export class MainState {
|
|||
}
|
||||
}
|
||||
|
||||
@action
|
||||
CustomFW(bool: boolean) {
|
||||
this.configuration.hardware.custom_firmware = bool;
|
||||
}
|
||||
|
||||
flashFW() {
|
||||
return Axios.post("/api/flash_firmware");
|
||||
}
|
||||
|
||||
enumerateInterfaces() {
|
||||
Axios.get("/api/network/interfaces")
|
||||
.then(this.enumerateInterfacesOK.bind(this))
|
||||
|
|
Loading…
Reference in New Issue