start to bundle arduino firmware with os

pull/273/head
connor rigby 2017-03-13 15:50:01 -07:00
parent 735124eb86
commit 157770fa2e
22 changed files with 2692 additions and 298 deletions

1
.gitignore vendored
View File

@ -35,3 +35,4 @@ _images
Makefile
release-*
dump.rdb
#priv/firmware.hex

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

2522
priv/firmware.hex 100644

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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