commit
fd00163255
|
@ -1,4 +1,10 @@
|
|||
# Changelog
|
||||
# 6.4.9
|
||||
* Add feature to save logs to sdcard for debugging.
|
||||
* Fix bug causing long running Farmwares to fail.
|
||||
* Make sure to clear eeprom before flashing Arduino firmware.
|
||||
* Update Linux system layer.
|
||||
|
||||
# 6.4.8
|
||||
* Make sure not to crash if a wifi network is malformed.
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ The "brains" of the FarmBot Project
|
|||
# :floppy_disk: LATEST OS IMAGE DOWNLOADS
|
||||
<!-- DON'T CHANGE THE TEXT ABOVE. It is used in documentation links. -->
|
||||
|
||||
:star: **[RPi 3 (Ships with FarmBot.io kits)](https://github.com/FarmBot/farmbot_os/releases/download/v6.4.7/farmbot-rpi3-6.4.7.img)**
|
||||
:star: **[RPi 3 (Ships with FarmBot.io kits)](https://github.com/FarmBot/farmbot_os/releases/download/v6.4.8/farmbot-rpi3-6.4.8.img)**
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
|
|
@ -6,11 +6,19 @@ env = Mix.env()
|
|||
|
||||
config :logger, [
|
||||
utc_log: true,
|
||||
# handle_otp_reports: true,
|
||||
# handle_sasl_reports: true,
|
||||
backends: [RingLogger]
|
||||
handle_otp_reports: true,
|
||||
handle_sasl_reports: true,
|
||||
backends: [:console]
|
||||
]
|
||||
|
||||
# Randomly picked 300 megabytes.
|
||||
# 3964928 bytes == ~4 megabytes in sqlite3
|
||||
# 9266 logs = ~4 megabytes
|
||||
# 4 logs * 75 = 300 megabytes
|
||||
# 9266 logs * 75 = 694950 logs
|
||||
# This will trim 175000 logs (25%) every time it gets to the max logs.
|
||||
config :logger_backend_ecto, max_logs: 700000
|
||||
|
||||
# Stop lager redirecting :error_logger messages
|
||||
config :lager, :error_logger_redirect, false
|
||||
|
||||
|
|
|
@ -29,14 +29,16 @@ config :farmbot, ecto_repos: [Farmbot.Repo, Farmbot.System.ConfigStorage]
|
|||
config :farmbot, Farmbot.Repo,
|
||||
adapter: Sqlite.Ecto2,
|
||||
loggers: [],
|
||||
database: "tmp/#{Farmbot.Repo}_dev.sqlite3",
|
||||
pool_size: 1
|
||||
database: "tmp/#{Farmbot.Repo}_dev.sqlite3"
|
||||
|
||||
config :farmbot, Farmbot.System.ConfigStorage,
|
||||
adapter: Sqlite.Ecto2,
|
||||
loggers: [],
|
||||
database: "tmp/#{Farmbot.System.ConfigStorage}_dev.sqlite3",
|
||||
pool_size: 1
|
||||
database: "tmp/#{Farmbot.System.ConfigStorage}_dev.sqlite3"
|
||||
|
||||
config :logger_backend_ecto, LoggerBackendEcto.Repo,
|
||||
adapter: Sqlite.Ecto2,
|
||||
database: "tmp/logs.sqlite3"
|
||||
|
||||
config :farmbot, :farmware, first_part_farmware_manifest_url: nil
|
||||
config :farmbot, default_server: "https://staging.farm.bot"
|
||||
|
|
|
@ -29,20 +29,21 @@ config :farmbot, :behaviour,
|
|||
system_tasks: Farmbot.Test.SystemTasks,
|
||||
update_handler: FarmbotTestSupport.TestUpdateHandler
|
||||
|
||||
|
||||
config :farmbot, Farmbot.Repo, [
|
||||
adapter: Sqlite.Ecto2,
|
||||
database: "test_tmp/farmbot_repo_test",
|
||||
priv: "priv/repo",
|
||||
pool_size: 2,
|
||||
loggers: []
|
||||
]
|
||||
|
||||
config :farmbot, Farmbot.System.ConfigStorage, [
|
||||
adapter: Sqlite.Ecto2,
|
||||
database: "test_tmp/farmbot_config_storage_test",
|
||||
pool_size: 2,
|
||||
loggers: []
|
||||
]
|
||||
|
||||
config :logger_backend_ecto, LoggerBackendEcto.Repo,
|
||||
adapter: Sqlite.Ecto2,
|
||||
database: "test_tmp/debug_logs.sqlite3"
|
||||
|
||||
config :farmbot, ecto_repos: [Farmbot.Repo, Farmbot.System.ConfigStorage]
|
||||
|
|
|
@ -16,6 +16,10 @@ config :farmbot, Farmbot.System.ConfigStorage,
|
|||
loggers: [],
|
||||
database: "/root/config-#{Mix.env()}.sqlite3"
|
||||
|
||||
config :logger_backend_ecto, LoggerBackendEcto.Repo,
|
||||
adapter: Sqlite.Ecto2,
|
||||
database: "/root/debug_logs.sqlite3"
|
||||
|
||||
config :farmbot, ecto_repos: [Farmbot.Repo, Farmbot.System.ConfigStorage]
|
||||
|
||||
# Configure your our init system.
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
use Mix.Config
|
||||
|
||||
config :logger, [
|
||||
utc_log: true,
|
||||
handle_otp_reports: true,
|
||||
handle_sasl_reports: true,
|
||||
backends: [RingLogger]
|
||||
]
|
||||
|
||||
config :farmbot, data_path: "/root"
|
||||
|
||||
# Disable tzdata autoupdates because it tries to dl the update file
|
||||
|
@ -23,6 +16,10 @@ config :farmbot, Farmbot.System.ConfigStorage,
|
|||
loggers: [],
|
||||
database: "/root/config-#{Mix.env()}.sqlite3"
|
||||
|
||||
config :logger_backend_ecto, LoggerBackendEcto.Repo,
|
||||
adapter: Sqlite.Ecto2,
|
||||
database: "/root/debug_logs.sqlite3"
|
||||
|
||||
config :farmbot, ecto_repos: [Farmbot.Repo, Farmbot.System.ConfigStorage]
|
||||
|
||||
# Configure your our init system.
|
||||
|
|
|
@ -25,7 +25,7 @@ defmodule Farmbot do
|
|||
end
|
||||
|
||||
def init([]) do
|
||||
RingLogger.attach()
|
||||
# RingLogger.attach()
|
||||
children = [
|
||||
{Farmbot.Logger.Supervisor, []},
|
||||
{Farmbot.System.Supervisor, []},
|
||||
|
@ -38,13 +38,8 @@ defmodule Farmbot do
|
|||
end
|
||||
|
||||
def prep_stop(_state) do
|
||||
formatted = Farmbot.Logger.format_logs()
|
||||
|
||||
formatted
|
||||
|> Enum.join("\n")
|
||||
|> Farmbot.System.stop()
|
||||
|
||||
formatted
|
||||
# logs = LoggerBackendEcto.all_logs()
|
||||
Logger.remove_backend(LoggerBackendEcto)
|
||||
end
|
||||
|
||||
def stop(_data) do
|
||||
|
|
|
@ -268,19 +268,13 @@ defmodule Farmbot.BotState.Transport.AMQP do
|
|||
{:noreply, [], state}
|
||||
else
|
||||
case Poison.decode(payload) do
|
||||
{:ok, %{"body" => nil}} ->
|
||||
# If the settings were reset remotely, just set migrated to true,
|
||||
# which will cause FBOS to download the defaults and apply them.
|
||||
pl = %{"api_migrated" => true} |> Poison.encode!()
|
||||
Farmbot.HTTP.put!("/api/fbos_config", pl)
|
||||
Farmbot.Bootstrap.SettingsSync.run()
|
||||
{:noreply, [], state}
|
||||
{:ok, %{"body" => config}} ->
|
||||
{:ok, %{"body" => %{"api_migrated" => true} = config}} ->
|
||||
# Logger.info 1, "Got fbos config from amqp: #{inspect config}"
|
||||
old = state.state_cache.configuration
|
||||
updated = Farmbot.Bootstrap.SettingsSync.apply_fbos_map(old, config)
|
||||
push_bot_state(state.chan, state.bot, %{state.state_cache | configuration: updated})
|
||||
{:noreply, [], state}
|
||||
_ -> {:noreply, [], state}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,8 +57,20 @@ defmodule Farmbot.BotState.Transport.HTTP do
|
|||
public_key = body |> JOSE.JWK.from_pem
|
||||
# FIXME(Connor) The router should probably
|
||||
# be put in an externally supervised module..
|
||||
opts = [port: @port, acceptors: 2, dispatch: [cowboy_dispatch()]]
|
||||
case Plug.Adapters.Cowboy2.http Router, [], opts do
|
||||
protocol_options = [
|
||||
idle_timeout: :infinity,
|
||||
shutdown_timeout: :infinity,
|
||||
inactivity_timeout: :infinity,
|
||||
shutdown_timeout: :infinity,
|
||||
request_timeout: :infinity
|
||||
]
|
||||
opts = [
|
||||
port: @port,
|
||||
acceptors: 2,
|
||||
dispatch: [cowboy_dispatch()],
|
||||
protocol_options: protocol_options
|
||||
]
|
||||
case Plug.Adapters.Cowboy2.http(Router, [], opts) do
|
||||
{:ok, web} ->
|
||||
state = %{web: web, bot_state: nil, sockets: [], public_key: public_key}
|
||||
Process.link(state.web)
|
||||
|
|
|
@ -113,15 +113,21 @@ defmodule Farmbot.Firmware.UartHandler.Update do
|
|||
|
||||
# Farmduino
|
||||
defp do_flash("F", uart, tty) do
|
||||
avrdude("#{:code.priv_dir(:farmbot)}/eeprom_clear.ino.hex", uart, tty)
|
||||
Process.sleep(1000)
|
||||
avrdude("#{:code.priv_dir(:farmbot)}/farmduino.hex", uart, tty)
|
||||
end
|
||||
|
||||
defp do_flash("G", uart, tty) do
|
||||
avrdude("#{:code.priv_dir(:farmbot)}/eeprom_clear.ino.hex", uart, tty)
|
||||
Process.sleep(1000)
|
||||
avrdude("#{:code.priv_dir(:farmbot)}/farmduino_k14.hex", uart, tty)
|
||||
end
|
||||
|
||||
# Anything else. (should always be "R")
|
||||
defp do_flash(_, uart, tty) do
|
||||
avrdude("#{:code.priv_dir(:farmbot)}/eeprom_clear.ino.hex", uart, tty)
|
||||
Process.sleep(1000)
|
||||
avrdude("#{:code.priv_dir(:farmbot)}/arduino_firmware.hex", uart, tty)
|
||||
end
|
||||
|
||||
|
@ -141,17 +147,18 @@ defmodule Farmbot.Firmware.UartHandler.Update do
|
|||
|
||||
def avrdude(fw_file, uart, tty) do
|
||||
close(uart)
|
||||
Logger.busy 3, "Starting avrdude."
|
||||
Logger.busy 3, "Starting avrdude: #{fw_file}"
|
||||
args = ~w"-q -q -patmega2560 -cwiring -P#{tty} -b#{@uart_speed} -D -V -Uflash:w:#{fw_file}:i"
|
||||
opts = [stderr_to_stdout: true, into: IO.stream(:stdio, :line)]
|
||||
res = System.cmd("avrdude", args, opts)
|
||||
Process.sleep(1500) # wait to allow file descriptors to be closed.
|
||||
case res do
|
||||
{_, 0} ->
|
||||
Logger.success 1, "Firmware flashed!"
|
||||
Logger.success 1, "Firmware flashed! #{fw_file}"
|
||||
:ok
|
||||
{_, err_code} ->
|
||||
Logger.error 1, "Failed to flash Firmware! #{err_code}"
|
||||
Logger.error 1, "Failed to flash Firmware! #{fw_file} #{err_code}"
|
||||
Farmbot.Firmware.Utils.replace_firmware_handler(Farmbot.Firmware.StubHandler)
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
|
|
@ -138,7 +138,14 @@ defmodule Farmbot.Logger do
|
|||
file: env.file,
|
||||
line: env.line,
|
||||
module: env.module])
|
||||
logger_meta = [function: fun, file: env.file, line: env.line, module: env.module, time: time]
|
||||
logger_meta = [
|
||||
application: :farmbot,
|
||||
function: fun,
|
||||
file: env.file,
|
||||
line: env.line,
|
||||
module: env.module,
|
||||
time: time
|
||||
]
|
||||
logger_level = if level in [:info, :debug, :warn, :error], do: level, else: :info
|
||||
Elixir.Logger.bare_log(logger_level, log, logger_meta)
|
||||
{:noreply, [log], state}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
defmodule Farmbot.Logger.NetLogger do
|
||||
@moduledoc false
|
||||
use GenStage
|
||||
use Farmbot.Logger
|
||||
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [], name: __MODULE__)
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
send self(), :try_connect
|
||||
{:consumer, %{client: nil}, subscribe_to: [Farmbot.Logger]}
|
||||
end
|
||||
|
||||
def handle_events(_e, _from, %{client: nil} = state) do
|
||||
{:noreply, [], state}
|
||||
end
|
||||
|
||||
def handle_events(events, _from, %{client: client} = state) do
|
||||
for e <- events do
|
||||
log = %NetLogger.Log{message: e.message, time: e.time, level: e.level, verbosity: e.verbosity}
|
||||
try do
|
||||
NetLogger.UDP.Client.log(client, log)
|
||||
:ok
|
||||
rescue
|
||||
_ -> :ok
|
||||
end
|
||||
end
|
||||
{:noreply, [], state}
|
||||
end
|
||||
|
||||
def handle_info(:try_connect, %{client: nil} = state) do
|
||||
case NetLogger.UDP.Client.start_link([]) do
|
||||
{:ok, client} ->
|
||||
{:noreply, [], %{state | client: client}}
|
||||
{:error, _} ->
|
||||
Process.send_after(self(), :try_connect, 30_000)
|
||||
{:noreply, [], state}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -75,7 +75,6 @@ defmodule Farmbot.System.Init.Ecto do
|
|||
migrated = migrator.(repo, migrations_path, :up, opts)
|
||||
pid && repo.stop(pid)
|
||||
Mix.Ecto.restart_apps_if_migrated(apps, migrated)
|
||||
Logger.remove_backend Logger.Backends.Console
|
||||
Process.sleep(500)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule Farmbot.System.Init.FSCheckup do
|
|||
@moduledoc false
|
||||
use Supervisor
|
||||
use Farmbot.Logger
|
||||
|
||||
|
||||
@behaviour Farmbot.System.Init
|
||||
@data_path Application.get_env(:farmbot, :data_path)
|
||||
@data_path || Mix.raise("Unconfigured data path.")
|
||||
|
@ -46,6 +46,7 @@ defmodule Farmbot.System.Init.FSCheckup do
|
|||
Logger.busy(3, "Deleting: #{fw}")
|
||||
File.rm_rf(fw)
|
||||
end
|
||||
Elixir.Logger.add_backend(LoggerBackendEcto)
|
||||
:ok
|
||||
|
||||
err ->
|
||||
|
|
|
@ -26,9 +26,6 @@ defmodule Farmbot.System do
|
|||
"""
|
||||
@type unparsed_reason :: any
|
||||
|
||||
@doc "Called when the Application stops."
|
||||
@callback stop(String.t) :: any
|
||||
|
||||
@doc """
|
||||
Should remove all persistant data. this includes:
|
||||
* network config
|
||||
|
@ -42,10 +39,6 @@ defmodule Farmbot.System do
|
|||
@doc "Shuts down the machine."
|
||||
@callback shutdown(reason) :: no_return
|
||||
|
||||
def stop(data) do
|
||||
@system_tasks.stop(data)
|
||||
end
|
||||
|
||||
@doc "Remove all configuration data, and reboot."
|
||||
@spec factory_reset(unparsed_reason) :: no_return
|
||||
def factory_reset(reason) do
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
defmodule Logger.Backends.Farmbot do
|
||||
@moduledoc false
|
||||
|
||||
def init(_opts) do
|
||||
{:ok, %{}}
|
||||
end
|
||||
|
||||
def handle_event({_level, gl, {Logger, _, _, _}}, state) when node(gl) != node() do
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_event({level, _gl, {Logger, unformated_message, ts, metadata}}, state) do
|
||||
{{year, month, day}, {hour, minute, second, _millisecond}} = ts
|
||||
t =
|
||||
%DateTime{
|
||||
year: year,
|
||||
month: month,
|
||||
day: day,
|
||||
hour: hour,
|
||||
minute: minute,
|
||||
calendar: Calendar.ISO,
|
||||
microsecond: {0, 0},
|
||||
second: second,
|
||||
std_offset: 0,
|
||||
time_zone: "Etc/UTC",
|
||||
utc_offset: 0,
|
||||
zone_abbr: "UTC"
|
||||
}
|
||||
|> DateTime.to_unix()
|
||||
|
||||
module = metadata[:module]
|
||||
function = metadata[:function] || "no_function"
|
||||
verbosity = 3
|
||||
file = metadata[:file]
|
||||
line = metadata[:line]
|
||||
log = struct(Farmbot.Log,
|
||||
[
|
||||
time: t,
|
||||
level: level,
|
||||
verbosity: verbosity,
|
||||
message: format_message(unformated_message),
|
||||
meta: [], function: function,
|
||||
file: file, line: line,
|
||||
module: module
|
||||
]
|
||||
)
|
||||
Farmbot.Logger.dispatch_log(log)
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_event(:flush, state) do
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_info(_, state) do
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
defp format_message(msg) when is_binary(msg) or is_atom(msg) do
|
||||
msg
|
||||
end
|
||||
|
||||
defp format_message(msg) do
|
||||
msg |> to_string
|
||||
rescue
|
||||
_ -> inspect msg
|
||||
end
|
||||
end
|
7
mix.exs
7
mix.exs
|
@ -114,8 +114,7 @@ defmodule Farmbot.Mixfile do
|
|||
{:cors_plug, "~> 1.5"},
|
||||
{:rsa, "~> 0.0.1"},
|
||||
{:joken, "~> 1.5"},
|
||||
{:ecto, "~> 2.2.2"},
|
||||
{:sqlite_ecto2, "~> 2.2.1"},
|
||||
{:sqlite_ecto2, "~> 2.2.4"},
|
||||
{:uuid, "~> 1.1"},
|
||||
{:socket, "~> 0.3.13"},
|
||||
{:amqp, "~> 1.0"},
|
||||
|
@ -123,7 +122,7 @@ defmodule Farmbot.Mixfile do
|
|||
{:ring_logger, "~> 0.4.1"},
|
||||
{:bbmustache, "~> 1.5"},
|
||||
{:apex, "~> 1.2"},
|
||||
{:net_logger, "~> 0.1"}
|
||||
{:logger_backend_ecto, "~> 1.1"}
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -155,7 +154,7 @@ defmodule Farmbot.Mixfile do
|
|||
end
|
||||
|
||||
defp system("rpi3"),
|
||||
do: [{:nerves_system_farmbot_rpi3, "1.2.1-farmbot.2", runtime: false}]
|
||||
do: [{:nerves_system_farmbot_rpi3, "1.3.0-farmbot.2", runtime: false}]
|
||||
|
||||
defp package do
|
||||
[
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
"dialyxir": {:hex, :dialyxir, "1.0.0-rc.3", "774306f84973fc3f1e2e8743eeaa5f5d29b117f3916e5de74c075c02f1b8ef55", [:mix], [], "hexpm"},
|
||||
"distillery": {:hex, :distillery, "1.5.3", "b2f4fc34ec71ab4f1202a796f9290e068883b042319aa8c9aa45377ecac8597a", [:mix], [], "hexpm"},
|
||||
"earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"},
|
||||
"ecto": {:hex, :ecto, "2.2.8", "a4463c0928b970f2cee722cd29aaac154e866a15882c5737e0038bbfcf03ec2c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.4.2", "332c649d08c18bc1ecc73b1befc68c647136de4f340b548844efc796405743bf", [:mix], [], "hexpm"},
|
||||
"esqlite": {:hex, :esqlite, "0.2.3", "1a8b60877fdd3d50a8a84b342db04032c0231cc27ecff4ddd0d934485d4c0cd5", [:rebar3], [], "hexpm"},
|
||||
"esqlite": {:hex, :esqlite, "0.2.4", "3a8a352c190afe2d6b828b252a6fbff65b5cc1124647f38b15bdab3bf6fd4b3e", [:rebar3], [], "hexpm"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"excoveralls": {:hex, :excoveralls, "0.9.1", "14fd20fac51ab98d8e79615814cc9811888d2d7b28e85aa90ff2e30dcf3191d6", [:mix], [{:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
@ -32,18 +32,19 @@
|
|||
"httpoison": {:hex, :httpoison, "1.2.0", "2702ed3da5fd7a8130fc34b11965c8cfa21ade2f232c00b42d96d4967c39a3a3", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jason": {:hex, :jason, "1.1.0", "9634bca30f2f7468dde3e704d5865319b1eb88e4a8cded5c995baf0aa957524f", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"jason": {:hex, :jason, "1.1.1", "d3ccb840dfb06f2f90a6d335b536dd074db748b3e7f5b11ab61d239506585eb2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"joken": {:hex, :joken, "1.5.0", "42a0953e80bd933fc98a0874e156771f78bf0e92abe6c3a9c22feb6da28efb0b", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"jose": {:hex, :jose, "1.8.4", "7946d1e5c03a76ac9ef42a6e6a20001d35987afd68c2107bcd8f01a84e75aa73", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"},
|
||||
"lager": {:hex, :lager, "3.5.1", "63897a61af646c59bb928fee9756ce8bdd02d5a1a2f3551d4a5e38386c2cc071", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"lager_logger": {:hex, :lager_logger, "1.0.5", "2b58be52fe1e0fb82656180fc54e45618aa2dc619090b00e6d3fb4707c6a1fe5", [:mix], [{:lager, ">= 2.1.0", [hex: :lager, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"logger_backend_ecto": {:hex, :logger_backend_ecto, "1.1.0", "d43b128f1d12598a9b0ad0906a01e3b861c9db19744797d6a8ee15b4e3abee52", [:mix], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:sqlite_ecto2, "~> 2.2.4", [hex: :sqlite_ecto2, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"meck": {:hex, :meck, "0.8.10", "455aaef8403be46752272206613e7a15467c014d40994b22fb54cde4d1ff7075", [:rebar3], [], "hexpm"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||
"mime": {:hex, :mime, "1.3.0", "5e8d45a39e95c650900d03f897fbf99ae04f60ab1daa4a34c7a20a5151b7a5fe", [:mix], [], "hexpm"},
|
||||
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
|
||||
"mock": {:hex, :mock, "0.3.1", "994f00150f79a0ea50dc9d86134cd9ebd0d177ad60bd04d1e46336cdfdb98ff9", [:mix], [{:meck, "~> 0.8.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves": {:hex, :nerves, "1.1.0", "acc8af6d508793aa68be3aeefda7be4e01c2bc4cfcb729e335d60212d2cfcf12", [:mix], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"nerves": {:hex, :nerves, "1.1.1", "2fc347fc796c9d0557a68f0da81c3e59c108800dae7f18ed468d7a7e6854c663", [:mix], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"nerves_leds": {:hex, :nerves_leds, "0.8.0", "193692767dca1a201b09113d242648493b9be0087bab83ebee99c3b0a254f5e1", [:mix], [], "hexpm"},
|
||||
"nerves_uart": {:hex, :nerves_uart, "1.2.0", "195424116b925cd3bf9d666be036c2a80655e6ca0f8d447e277667a60005c50e", [:mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"net_logger": {:hex, :net_logger, "0.1.0", "59be302c09cf70dab164810c923ccb9a976eda7270e5a32b93ba8aeb850de1d6", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:uuid, "~> 1.1", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
@ -60,8 +61,8 @@
|
|||
"rsa": {:hex, :rsa, "0.0.1", "a63069f88ce342ffdf8448b7cdef4b39ba7dee3c1510644a39385c7e63ba246f", [:mix], [], "hexpm"},
|
||||
"sbroker": {:hex, :sbroker, "1.0.0", "28ff1b5e58887c5098539f236307b36fe1d3edaa2acff9d6a3d17c2dcafebbd0", [:rebar3], [], "hexpm"},
|
||||
"socket": {:hex, :socket, "0.3.13", "98a2ab20ce17f95fb512c5cadddba32b57273e0d2dba2d2e5f976c5969d0c632", [:mix], [], "hexpm"},
|
||||
"sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.2", "7a3e5c0521e1cb6e30a4907ba4d952b97db9b2ab5d1a4806ceeb66a10b23ba65", [:mix], [{:connection, "~> 1.0.3", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.3.2 or ~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlitex": {:hex, :sqlitex, "1.3.3", "3aac5fd702be346f71d9de6e01702c9954484cd0971aa443490bb3bde045d919", [:mix], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.4", "e192c243750511efc1369d74c15d65a014e176e4aba9f67ca7852e9826b2cba4", [:mix], [{:connection, "~> 1.0.3", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.3.2 or ~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlitex": {:hex, :sqlitex, "1.4.2", "b18f2b53cefbc9cca0bd17d51386f9caa7cf341144cb314e5cd9fd2a1f9b0845", [:mix], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.4", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
|
||||
"timex": {:hex, :timex, "3.3.0", "e0695aa0ddb37d460d93a2db34d332c2c95a40c27edf22fbfea22eb8910a9c8d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"tzdata": {:hex, :tzdata, "0.5.16", "13424d3afc76c68ff607f2df966c0ab4f3258859bbe3c979c9ed1606135e7352", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
"dhcp_server": {:hex, :dhcp_server, "0.4.0", "3af7e9488517ff4d9eba8541085b65f7435b175bcf66ccfa9786882bdca43247", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network, "~> 0.3", [hex: :nerves_network, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"distillery": {:hex, :distillery, "1.5.3", "b2f4fc34ec71ab4f1202a796f9290e068883b042319aa8c9aa45377ecac8597a", [:mix], [], "hexpm"},
|
||||
"dns": {:hex, :dns, "2.1.0", "4777fe07ae3060c1d5d75024f05c26d7e11fa701d48a6edb9fc305d24cd12c8c", [:mix], [{:socket, "~> 0.3.13", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"ecto": {:hex, :ecto, "2.2.8", "a4463c0928b970f2cee722cd29aaac154e866a15882c5737e0038bbfcf03ec2c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"elixir_ale": {:hex, :elixir_ale, "1.0.2", "f2b7cadf3d1e2adc67201ef4e725e18f3ee5ff37b80ccb7f1bb812f0f765356d", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.4.2", "332c649d08c18bc1ecc73b1befc68c647136de4f340b548844efc796405743bf", [:mix], [], "hexpm"},
|
||||
"esqlite": {:hex, :esqlite, "0.2.3", "1a8b60877fdd3d50a8a84b342db04032c0231cc27ecff4ddd0d934485d4c0cd5", [:rebar3], [], "hexpm"},
|
||||
"esqlite": {:hex, :esqlite, "0.2.4", "3a8a352c190afe2d6b828b252a6fbff65b5cc1124647f38b15bdab3bf6fd4b3e", [:rebar3], [], "hexpm"},
|
||||
"fs": {:hex, :fs, "3.4.0", "6d18575c250b415b3cad559e6f97a4c822516c7bc2c10bfbb2493a8f230f5132", [:rebar3], [], "hexpm"},
|
||||
"gen_stage": {:hex, :gen_stage, "0.14.0", "65ae78509f85b59d360690ce3378d5096c3130a0694bab95b0c4ae66f3008fad", [:mix], [], "hexpm"},
|
||||
"gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"},
|
||||
|
@ -32,11 +32,12 @@
|
|||
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"},
|
||||
"lager": {:hex, :lager, "3.5.1", "63897a61af646c59bb928fee9756ce8bdd02d5a1a2f3551d4a5e38386c2cc071", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"lager_logger": {:hex, :lager_logger, "1.0.5", "2b58be52fe1e0fb82656180fc54e45618aa2dc619090b00e6d3fb4707c6a1fe5", [:mix], [{:lager, ">= 2.1.0", [hex: :lager, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"logger_backend_ecto": {:hex, :logger_backend_ecto, "1.1.0", "d43b128f1d12598a9b0ad0906a01e3b861c9db19744797d6a8ee15b4e3abee52", [:mix], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:sqlite_ecto2, "~> 2.2.4", [hex: :sqlite_ecto2, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"mdns": {:hex, :mdns, "1.0.1", "c0e490f7c90ee6b546284c942ebb1c239375fb5f788e765d22ea8ff848cfe842", [:mix], [{:dns, "~> 2.0", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||
"mime": {:hex, :mime, "1.3.0", "5e8d45a39e95c650900d03f897fbf99ae04f60ab1daa4a34c7a20a5151b7a5fe", [:mix], [], "hexpm"},
|
||||
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
|
||||
"nerves": {:hex, :nerves, "1.1.0", "acc8af6d508793aa68be3aeefda7be4e01c2bc4cfcb729e335d60212d2cfcf12", [:mix], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"nerves": {:hex, :nerves, "1.1.1", "2fc347fc796c9d0557a68f0da81c3e59c108800dae7f18ed468d7a7e6854c663", [:mix], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"nerves_firmware": {:hex, :nerves_firmware, "0.4.0", "ac2fed915a7ca4bb69f567d9b742d77cffc3a6a56420ce65e870c8c34119b935", [:mix], [], "hexpm"},
|
||||
"nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.3.2", "2cdf126b5b264ec11c31f58b7f9933445eb065348a0b33c6762f08b1f46e87a9", [:mix], [{:nerves_runtime, "~> 0.4", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_init_gadget": {:hex, :nerves_init_gadget, "0.4.0", "b850850956070bdbb0780e8beba87dc7a801644e5735ce7d7b0cae40224a9e9f", [:mix], [{:mdns, "~> 1.0", [hex: :mdns, repo: "hexpm", optional: false]}, {:nerves_firmware_ssh, "~> 0.2", [hex: :nerves_firmware_ssh, repo: "hexpm", optional: false]}, {:nerves_network, "~> 0.3", [hex: :nerves_network, repo: "hexpm", optional: false]}, {:nerves_runtime, "~> 0.3", [hex: :nerves_runtime, repo: "hexpm", optional: false]}, {:ring_logger, "~> 0.4", [hex: :ring_logger, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
@ -44,11 +45,11 @@
|
|||
"nerves_network": {:hex, :nerves_network, "0.3.6", "c95779283ace071e9d12882d6a80e31edc8c476012adc61aba2ff6c306ef97b3", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.0", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.3.0", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.4", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.4", "200b1a84bc1a7fdeaf3a1e0e2d4e9b33e240b034e73f39372768d43f8690bae0", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_runtime": {:hex, :nerves_runtime, "0.6.1", "0af96a0de0ec85bdbda349aa3bdbe999ce2236640bb21b2c8ca29a03388863b8", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.5", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_system_br": {:hex, :nerves_system_br, "1.3.2", "e8d617095ebc015f45065965a951d62805bdea2535a774189a705f8385e9d756", [:mix], [], "hexpm"},
|
||||
"nerves_system_farmbot_rpi3": {:hex, :nerves_system_farmbot_rpi3, "1.2.1-farmbot.2", "4e5c6f8794eb9dc1515c1fa4fb59f2fa3e44682d5938d2ae654a784dae274735", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.3.2", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_arm_unknown_linux_gnueabihf, "1.0.0", [hex: :nerves_toolchain_arm_unknown_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_system_br": {:hex, :nerves_system_br, "1.4.1", "58a85d4dd85c84c7d1b535f9295aae64283638a9d9f49b8279f22ef1673eef42", [:mix], [], "hexpm"},
|
||||
"nerves_system_farmbot_rpi3": {:hex, :nerves_system_farmbot_rpi3, "1.3.0-farmbot.2", "d8440383466a858c1e993ea27e47f1fd0281624853a59b554718ba0b86a06c52", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_system_br, "1.4.1", [hex: :nerves_system_br, repo: "hexpm", optional: false]}, {:nerves_system_linter, "~> 0.3.0", [hex: :nerves_system_linter, repo: "hexpm", optional: false]}, {:nerves_toolchain_arm_unknown_linux_gnueabihf, "1.1.0", [hex: :nerves_toolchain_arm_unknown_linux_gnueabihf, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_system_linter": {:hex, :nerves_system_linter, "0.3.0", "84e0f63c8ac196b16b77608bbe7df66dcf352845c4e4fb394bffd2b572025413", [:mix], [], "hexpm"},
|
||||
"nerves_toolchain_arm_unknown_linux_gnueabihf": {:hex, :nerves_toolchain_arm_unknown_linux_gnueabihf, "1.0.0", "39da5b503b977a594c9e386ca16a50c433b333797bc30ac941fd402ce1832274", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.4", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "1.4.0", "ec844dd286a5281223e023edb1359c8763fef79a3af9daac45397713cff1cb88", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_toolchain_arm_unknown_linux_gnueabihf": {:hex, :nerves_toolchain_arm_unknown_linux_gnueabihf, "1.1.0", "ca466a656f8653346a8551a35743f7c41046f3d53e945723e970cb4a7811e617", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 1.5.0", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "1.5.0", "34b8f5664858ff6ce09730b26221441398acd1fa361b8c6d744d9ec18238c16b", [:mix], [{:nerves, "~> 1.0", [hex: :nerves, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_uart": {:hex, :nerves_uart, "1.2.0", "195424116b925cd3bf9d666be036c2a80655e6ca0f8d447e277667a60005c50e", [:mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"nerves_wpa_supplicant": {:git, "https://github.com/nerves-project/nerves_wpa_supplicant.git", "2b3bb056a1594bff16b44d37876e8d599349dcb5", []},
|
||||
"net_logger": {:hex, :net_logger, "0.1.0", "59be302c09cf70dab164810c923ccb9a976eda7270e5a32b93ba8aeb850de1d6", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:uuid, "~> 1.1", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
@ -66,8 +67,8 @@
|
|||
"sbroker": {:hex, :sbroker, "1.0.0", "28ff1b5e58887c5098539f236307b36fe1d3edaa2acff9d6a3d17c2dcafebbd0", [:rebar3], [], "hexpm"},
|
||||
"shoehorn": {:hex, :shoehorn, "0.3.1", "e4f1db8f25e3e6ccba4ab787a45a3c6968c0cc483d8e55425385becdd101387e", [:mix], [{:distillery, "~> 1.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"socket": {:hex, :socket, "0.3.13", "98a2ab20ce17f95fb512c5cadddba32b57273e0d2dba2d2e5f976c5969d0c632", [:mix], [], "hexpm"},
|
||||
"sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.2", "7a3e5c0521e1cb6e30a4907ba4d952b97db9b2ab5d1a4806ceeb66a10b23ba65", [:mix], [{:connection, "~> 1.0.3", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.3.2 or ~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlitex": {:hex, :sqlitex, "1.3.3", "3aac5fd702be346f71d9de6e01702c9954484cd0971aa443490bb3bde045d919", [:mix], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.3", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.4", "e192c243750511efc1369d74c15d65a014e176e4aba9f67ca7852e9826b2cba4", [:mix], [{:connection, "~> 1.0.3", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.3.2 or ~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlitex": {:hex, :sqlitex, "1.4.2", "b18f2b53cefbc9cca0bd17d51386f9caa7cf341144cb314e5cd9fd2a1f9b0845", [:mix], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.4", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
|
||||
"system_registry": {:hex, :system_registry, "0.8.0", "09240347628b001433d18279a2759ef7237ba7361239890d8c599cca9a2fbbc2", [:mix], [], "hexpm"},
|
||||
"timex": {:hex, :timex, "3.3.0", "e0695aa0ddb37d460d93a2db34d332c2c95a40c27edf22fbfea22eb8910a9c8d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
|
|
@ -17,6 +17,4 @@ defmodule Farmbot.Host.SystemTasks do
|
|||
def shutdown(_reason) do
|
||||
:init.stop()
|
||||
end
|
||||
|
||||
def stop(_), do: :ok
|
||||
end
|
||||
|
|
|
@ -38,6 +38,25 @@ defmodule Farmbot.Target.Bootstrap.Configurator.Router do
|
|||
end
|
||||
end
|
||||
|
||||
get "/view_logs" do
|
||||
all_logs = LoggerBackendEcto.all_logs()
|
||||
render_page(conn, "view_logs", [logs: all_logs])
|
||||
end
|
||||
|
||||
get "/logs" do
|
||||
file = Path.join(@data_path, "debug_logs.sqlite3")
|
||||
case File.read(file) do
|
||||
{:ok, data} ->
|
||||
md5 = data |> :erlang.md5() |> Base.encode16()
|
||||
conn
|
||||
|> put_resp_content_type("application/octet-stream")
|
||||
|> put_resp_header("Content-Disposition", "inline; filename=\"#{@version}-#{md5}-logs.sqlite3\"")
|
||||
|> send_resp(200, data)
|
||||
{:error, posix} ->
|
||||
send_resp(conn, 404, "Error downloading file: #{posix}")
|
||||
end
|
||||
end
|
||||
|
||||
get "/setup", do: redir(conn, "/")
|
||||
|
||||
#NETWORKCONFIG
|
||||
|
|
|
@ -2,8 +2,6 @@ defmodule Farmbot.Target.SystemTasks do
|
|||
@moduledoc "Target implementation for System Tasks."
|
||||
|
||||
@behaviour Farmbot.System
|
||||
@block_device "/dev/sda1"
|
||||
@mount_point "/tmp/log_dev"
|
||||
|
||||
def factory_reset(reason) do
|
||||
reboot(reason)
|
||||
|
@ -16,23 +14,4 @@ defmodule Farmbot.Target.SystemTasks do
|
|||
def shutdown(_reason) do
|
||||
Nerves.Runtime.poweroff()
|
||||
end
|
||||
|
||||
def stop(data) do
|
||||
System.cmd("umount", [@mount_point])
|
||||
if File.exists?(@block_device) do
|
||||
IO.puts "Found Block device #{@block_device}"
|
||||
File.mkdir_p!(@mount_point)
|
||||
case System.cmd("mount", [@block_device, @mount_point]) do
|
||||
{_, 0} ->
|
||||
dir = Path.join([@mount_point, "logs", DateTime.utc_now() |> DateTime.to_unix() |> to_string])
|
||||
path = Path.join([dir, "logs.txt"])
|
||||
File.mkdir_p!(dir)
|
||||
File.write!(path, data, [:sync])
|
||||
System.cmd("umount", [@mount_point])
|
||||
:ok
|
||||
{reason, code} ->
|
||||
IO.puts "Could not mount device #{code}: #{inspect reason}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,16 +4,30 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title> Configure your Farmbot Version <%= version %> </title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
|
||||
<script>
|
||||
let count = 0;
|
||||
function secret(event) {
|
||||
count++;
|
||||
if(count >= 10) {
|
||||
document.getElementById("hidden-logs").hidden = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Configure your FarmBot Version <%= version %></h1>
|
||||
<h1 onclick="secret()"> Configure your FarmBot Version <%= version %></h1>
|
||||
|
||||
<div class="widget">
|
||||
<div class="widget-header">
|
||||
<h5>Start</h5>
|
||||
</div>
|
||||
|
||||
<div class="widget-content">
|
||||
|
||||
<p> <a hidden=true id='hidden-logs' href="/view_logs">Download all logs</a> </p>
|
||||
|
||||
<%= if last_reset_reason do %>
|
||||
<h5> Farmbot unexpectedly shut down </h5> <p>
|
||||
Last shutdown reason: <%= last_reset_reason %>
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title> Log Viewer </title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
|
||||
<style>
|
||||
.collapsible {
|
||||
background-color: #777;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
padding: 18px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.active, .collapsible:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
.colapsablecontent {
|
||||
padding: 0 18px;
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1> Log Viewer </h1>
|
||||
<div class="widget">
|
||||
<div class="widget-header">
|
||||
<h5>Log Viewer</h5>
|
||||
</div>
|
||||
<div class="widget-content">
|
||||
|
||||
<h3> <bold> WARNING </bold> </h3>
|
||||
<p>
|
||||
Be cautious when sharing this log dump. It will contain potentially
|
||||
sensitive information about your bot.
|
||||
</p>
|
||||
<p> <a href="/logs">Download all logs</a> </p>
|
||||
|
||||
<%= for log <- logs do %>
|
||||
<button class="collapsible"> <%= String.slice(log.message, 0..30) %> </button>
|
||||
<div class="colapsablecontent">
|
||||
<%= log.message %>
|
||||
</div>
|
||||
<%= end %>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var coll = document.getElementsByClassName("collapsible");
|
||||
var i;
|
||||
|
||||
for (i = 0; i < coll.length; i++) {
|
||||
coll[i].addEventListener("click", function() {
|
||||
this.classList.toggle("active");
|
||||
var content = this.nextElementSibling;
|
||||
if (content.style.display === "block") {
|
||||
content.style.display = "none";
|
||||
} else {
|
||||
content.style.display = "block";
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -9,4 +9,4 @@ if [ -z $2 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
avrdude -v -patmega2560 -cwiring -P$2 -b115200 -D -V -Uflash:w:./priv/$1.hex:i
|
||||
avrdude -v -p atmega2560 -c wiring -P$2 -b 115200 -D -V -Uflash:w:./priv/$1.hex:i
|
||||
|
|
|
@ -12,13 +12,8 @@ fi
|
|||
FW_TYPE=$1
|
||||
TTY=$2
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
if $DIR/flash_fw.sh clear_eeprom $TTY; then
|
||||
if $DIR/flash_fw.sh blink $TTY; then
|
||||
if $DIR/flash_fw.sh eeprom_clear.ino $TTY; then
|
||||
$DIR/flash_fw.sh $FW_TYPE $TTY
|
||||
else
|
||||
echo "Failed to flash blink!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Failed to clear eeprom!"
|
||||
exit 1
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Node.MoveAbsoluteTest do
|
||||
alias Farmbot.CeleryScript.AST.Node.{Coordinate, MoveAbsolute}
|
||||
|
||||
use FarmbotTestSupport.AST.NodeTestCase, async: false
|
||||
|
||||
test "mutates env", %{env: env} do
|
||||
args = %{
|
||||
location: nothing(),
|
||||
speed: 100,
|
||||
offset: nothing()
|
||||
}
|
||||
{:ok, env} = MoveAbsolute.execute(args, [], env)
|
||||
assert_cs_env_mutation(MoveAbsolute, env)
|
||||
end
|
||||
|
||||
test "moves to a location with no offset", %{env: env} do
|
||||
nothing = nothing()
|
||||
{:ok, coordinate, env} = Coordinate.execute(%{x: 100, y: 123, z: -123}, [], env)
|
||||
args = %{
|
||||
location: coordinate,
|
||||
speed: 100,
|
||||
offset: nothing
|
||||
}
|
||||
MoveAbsolute.execute(args, [], env) |> assert_cs_success()
|
||||
%{x: res_x, y: res_y, z: res_z} = Farmbot.BotState.get_current_pos()
|
||||
assert res_x == coordinate.args.x
|
||||
assert res_y == coordinate.args.y
|
||||
assert res_z == coordinate.args.z
|
||||
end
|
||||
|
||||
test "moves to a location with an offset", %{env: env} do
|
||||
{:ok, location, env} = Coordinate.execute(%{x: 0, y: 0, z: 0}, [], env)
|
||||
{:ok, offset, env} = Coordinate.execute(%{x: 100, y: 123, z: -123}, [], env)
|
||||
args = %{
|
||||
location: location,
|
||||
speed: 100,
|
||||
offset: offset
|
||||
}
|
||||
MoveAbsolute.execute(args, [], env) |> assert_cs_success()
|
||||
%{x: res_x, y: res_y, z: res_z} = Farmbot.BotState.get_current_pos()
|
||||
assert res_x == offset.args.x
|
||||
assert res_y == offset.args.y
|
||||
assert res_z == offset.args.z
|
||||
end
|
||||
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Node.MoveRelativeTest do
|
||||
alias Farmbot.CeleryScript.AST.Node.{MoveRelative, MoveAbsolute, Coordinate}
|
||||
|
||||
use FarmbotTestSupport.AST.NodeTestCase, async: false
|
||||
|
||||
test "mutates env", %{env: env} do
|
||||
{:ok, env} = MoveRelative.execute(%{x: 0, y: 0, z: 0, speed: 100}, [], env)
|
||||
assert_cs_env_mutation(MoveAbsolute, env)
|
||||
end
|
||||
|
||||
test "moves relatively from a location to another location", %{env: env} do
|
||||
{:ok, coordinate, env} = Coordinate.execute(%{x: 0, y: 0, z: 0}, [], env)
|
||||
{:ok, env} = MoveAbsolute.execute(%{location: coordinate, offset: nothing(), speed: 100}, [], env)
|
||||
MoveRelative.execute(%{x: 100, y: 150, z: 155, speed: 100}, [], env) |> assert_cs_success()
|
||||
assert match?(%{x: 100, y: 150, z: 155}, Farmbot.BotState.get_current_pos())
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue