cant figure out the ssl bug

pull/353/head
connor rigby 2017-05-26 14:44:17 -07:00
parent cf02cc35d2
commit be618d8f5f
17 changed files with 156 additions and 92 deletions

1
.gitignore vendored
View File

@ -40,3 +40,4 @@ dump.rdb
# this file isnt stored here but just in case.
fwup-key.priv
.env

View File

@ -22,6 +22,10 @@ config :farmbot,
path: "/state",
config_file_name: "default_config_rpi3.json"
config :logger, :console,
format: "\n$time $metadata[$level] $levelpad$message\n",
metadata: [:module]
# In production, we want a cron job for checking for updates.
config :quantum, cron: [ "5 1 * * *": {Farmbot.System.Updates, :do_update_check}]

View File

@ -5,10 +5,6 @@ via shell environment variables.
## Firmware Signing
We Produce signed releases in PROD environment. export `PRIV_KEY_FILE` to be the private key file.
## IO debugger
If you want more verbose logs you can export `DEBUG_LOG`. This will cause (a lot of) messages
to be displayed on the current tty.
## Mix Environment
you can set `MIX_ENV=prod` or `MIX_ENV=dev` (default) to change the environment
of the farmbot application.
@ -24,7 +20,7 @@ into a static website that gets served by `Plug`
Webpack is configured via a package called `ex_webpack`. Default behavior it to
watch the web source files for changes and recompile. This adds extra time to the
initial compile of the application and can be just generally annoying. to disable
this export `USE_WEBPACK=false`
this export `NO_WEBPACK=true`
## Configurator
The Configurator app is started by default on port `5000`.

View File

View File

@ -1 +0,0 @@
heyhey

View File

@ -44,19 +44,20 @@ defmodule Farmbot.CeleryScript.Command.DataUpdate do
end
@type number_or_wildcard :: non_neg_integer | binary # "*"
@type syncable :: Farmbot.Database.syncable
@type syncable :: Farmbot.Database.syncable | nil
@spec parse_syncable_str(binary) :: syncable
defp parse_syncable_str("regimens"), do: Regimen
defp parse_syncable_str("regimens"), do: Regimen
defp parse_syncable_str("peripherals"), do: Peripheral
defp parse_syncable_str("sequences"), do: Sequence
defp parse_syncable_str("sequences"), do: Sequence
defp parse_syncable_str("farm_events"), do: FarmEvent
defp parse_syncable_str("tools"), do: Tool
defp parse_syncable_str("points"), do: Point
defp parse_syncable_str("devices"), do: Device
defp parse_syncable_str("tools"), do: Tool
defp parse_syncable_str("points"), do: Point
defp parse_syncable_str("device"), do: Device
defp parse_syncable_str(str) do
debug_log "no such syncable: #{str}"
nil
end

View File

@ -59,12 +59,18 @@ defmodule Farmbot.Database do
@spec all_syncable_modules :: [syncable]
def all_syncable_modules, do: unquote(syncable_modules)
defp set_syncing(ctx, msg) do
:ok = Farmbot.BotState.set_sync_msg(ctx, msg)
:ok
end
@doc """
Sync up with the API.
"""
# TODO(Connor) this is slow.
@spec sync(Context.t) :: :ok | no_return
def sync(%Context{} = ctx) do
Farmbot.BotState.set_sync_msg(ctx, :syncing)
set_syncing(ctx, :syncing)
try do
for module_name <- all_syncable_modules() do
if get_awaiting(ctx, module_name) do
@ -82,12 +88,12 @@ defmodule Farmbot.Database do
end
end
Farmbot.BotState.set_sync_msg(ctx, :synced)
set_syncing(ctx, :synced)
:ok
rescue
e ->
Logger.info ">> Encountered error syncing, #{inspect e}", type: :error
Farmbot.BotState.set_sync_msg(ctx, :sync_error)
set_syncing(ctx, :sync_error)
end
end

View File

@ -36,7 +36,7 @@ defmodule Farmbot.HTTP do
def request(context, method, url, body \\ "", headers \\ [], opts \\ [])
def request(%Context{} = ctx, method, url, body, headers, opts) do
GenServer.call(ctx.http, {:request, method, url, body, headers, opts}, :infinity)
GenServer.call(ctx.http, {:request, method, url, body, headers, opts}, 30_000)
end
def request!(context, method, url, body \\ "", headers \\ [], opts \\ [])
@ -71,7 +71,10 @@ defmodule Farmbot.HTTP do
def post(context, url, body \\ "", headers \\ [], opts \\ [])
def post(%Context{} = ctx, url, body, headers, opts), do: request(ctx, :post, url, body, headers, opts)
def post(%Context{} = ctx, url, body, headers, opts) do
debug_log "doing http post: \n" <> body
request(ctx, :post, url, body, headers, opts)
end
@doc """
Downloads a file to the filesystem
@ -108,6 +111,7 @@ defmodule Farmbot.HTTP do
end
def init(ctx) do
Process.flag(:trap_exit, true)
state = %{
context: %{ctx | http: self()},
requests: %{}
@ -126,7 +130,7 @@ defmodule Farmbot.HTTP do
user_agent = {"User-Agent", "FarmbotOS/#{@version} (#{@target}) #{@target}"}
headers = [user_agent | headers]
try do
debug_log "Trying to create request"
debug_log "Trying to create request: #{inspect options}"
%AsyncResponse{id: ref} = HTTPoison.request!(method, url, body, headers, options)
empty_request = empty_request()
populated = if save_to_file do
@ -283,6 +287,11 @@ defmodule Farmbot.HTTP do
{:noreply, state}
end
end
def handle_info(e, state) do
require IEx
IEx.pry
{:noreply, state}
end
end
# defmodule Farmbot.HTTP do
# @moduledoc """

View File

@ -5,6 +5,7 @@ defmodule Farmbot.ImageWatcher do
use GenServer
require Logger
alias Farmbot.Context
use Farmbot.DebugLog
@images_path "/tmp/images"
@type state :: []
@ -22,6 +23,8 @@ defmodule Farmbot.ImageWatcher do
def force_upload(%Context{} = ctx), do: do_checkup(ctx)
def init(context) do
debug_log "Ensuring #{@images_path} exists."
File.mkdir_p! @images_path
# TODO(Connor) kill :fs if this app dies.
:fs_app.start(:normal, [])
:fs.subscribe()

View File

@ -8,20 +8,26 @@ defmodule Farmbot.Serial.Handler.OpenTTY do
@baud 115_200
defp ensure_supervisor(sup) when is_atom(sup) do
defp ensure_supervisor(sup, retries \\ 0)
defp ensure_supervisor(sup, retries) when retries > 25 do
:error
end
defp ensure_supervisor(sup, retries) when is_atom(sup) do
case Process.whereis(sup) do
pid when is_pid(pid) -> ensure_supervisor(pid)
_ -> ensure_supervisor(sup)
pid when is_pid(pid) -> ensure_supervisor(pid, retries + 1)
_ -> ensure_supervisor(sup, retries + 1)
end
end
defp ensure_supervisor(sup) when is_pid(sup) do
defp ensure_supervisor(sup, retries) when is_pid(sup) do
if Process.alive?(sup) do
debug_log "Serial has a supervisor."
:ok
else
debug_log "Waiting for serial to find a supervisor."
ensure_supervisor(sup)
ensure_supervisor(sup, retries + 1)
end
end

View File

@ -65,14 +65,19 @@ defmodule Farmbot.System.NervesCommon.FileSystem do
do: raise "error doing command(#{num}): #{inspect err}"
defp format_state_part do
state_path = unquote(state_path)
# Format partition
System.cmd("mkfs.#{unquote(fs_type)}", ["#{unquote(block_device)}", "-F"])
# Mount it as read/write
# NOTE(connor): is there a reason i did this in band?
System.cmd("mount", ["-t", unquote(fs_type), "-o", "rw",
unquote(block_device), unquote(state_path)])
unquote(block_device), state_path])
# Basically a flag that says the partition is formatted.
File.write!("#{unquote(state_path)}/.formatted", "DONT CAT ME\n")
File.mkdir_p! "#{state_path}/farmware"
File.mkdir_p! "#{state_path}/farmware/packages"
File.mkdir_p! "#{state_path}/farmware/repos"
:ok
end
end

View File

@ -67,11 +67,13 @@ defmodule Farmbot.Transport.GenMqtt do
{:noreply, [], state}
end
def handle_info(_e, state) do
# catch other messages if we don't have a token, or client or
# we just don't know how to handle this message.
{:noreply, [], state}
end
def handle_info(_, {nil, nil, _context} = state), do: {:noreply, [], state}
# def handle_info(_e, state) do
# # catch other messages if we don't have a token, or client or
# # we just don't know how to handle this message.
# {:noreply, [], state}
# end
@spec start_client(Context.t, Token.t) :: {:ok, pid}
defp start_client(%Context{} = context, %Token{} = token) do

View File

@ -59,7 +59,10 @@ defmodule Farmbot.Transport.GenMqtt.Client do
{:ok, {token, context}}
end
def on_disconnect(_), do: :shutdown
def on_disconnect(disconnect) do
require IEx
IEx.pry
end
def handle_cast({:status, %Ser{} = ser}, {%Token{} = token, %Context{} = con}) do
json = Poison.encode!(ser)
@ -79,11 +82,15 @@ defmodule Farmbot.Transport.GenMqtt.Client do
{:noreply, {token, context}}
end
def terminate(_,_), do: :ok
def terminate(a, state) do
require IEx
IEx.pry
end
@spec build_opts(Token.t) :: GenMQTT.option
defp build_opts(%Token{} = token) do
[name: __MODULE__,
[
# name: __MODULE__,
host: token.unencoded.mqtt,
timeout: 10_000,
reconnect_timeout: 10_000,

View File

@ -29,7 +29,7 @@ defmodule Farmbot.Transport.Supervisor do
end
defp default_transport(%Context{} = ctx) do
worker(Farmbot.Transport, [ctx, [name: Farmbot.Transport]])
worker(Farmbot.Transport, [ctx, [name: Farmbot.Transport]], restart: :permanent)
end
@doc """
@ -47,7 +47,7 @@ defmodule Farmbot.Transport.Supervisor do
worker(module, [context, []], restart: :permanent)
{module, opts} when is_atom(module) ->
debug_log "starting transport: #{module} with opts: #{inspect opts}"
worker(module, [context, [opts]], restart: :permanent)
worker(module, [context, opts], restart: :permanent)
end
end)
end

View File

@ -23,6 +23,9 @@ defmodule Mix.Tasks.Farmbot.Upload do
http_opts = [relaxed: true, autoredirect: true]
opts = []
:ok = do_ping_bot(ip_address)
{:ok, file} = :file.read_file('#{file_name}')
file = :binary.bin_to_list(file)
url = 'http://#{ip_address}/api/upload_firmware'
@ -39,6 +42,27 @@ defmodule Mix.Tasks.Farmbot.Upload do
|> response
end
defp do_ping_bot(ip_address) do
url = 'http://#{ip_address}/api/ping'
headers = []
:httpc.request(:get, {url, headers}, [], []) |> ping_response
end
defp ping_response({:ok, {{_, 200, _}, _, _}}) do
Mix.shell.info "Connected to bot!"
:ok
end
defp ping_response({:ok, {{_, status_code, _}, _, error}}) do
Mix.shell.info "\nCould not connect to bot! #{status_code} #{inspect error}"
{:error, status_code, error}
end
defp ping_response({:error, error}) do
Mix.shell.info "\nCould not connect to bot! #{inspect error}"
{:error, error}
end
defp start_httpc() do
Application.ensure_started(:inets)
Application.ensure_started(:ssl)

View File

@ -235,7 +235,8 @@ defmodule Farmbot.Mixfile do
# {:nerves_firmware, "~> 0.3"},
# {:nerves_firmware, path: "../nerves_firmware", override: true},
{:nerves_firmware, github: "nerves-project/nerves_firmware", tag: "0f558ad2402cbd5b36bd7a8a10bc2b53167de14e", override: true},
{:nerves_firmware, github: "nerves-project/nerves_firmware", override: true},
# {:nerves_firmware, github: "nerves-project/nerves_firmware", tag: "0f558ad2402cbd5b36bd7a8a10bc2b53167de14e", override: true},
{:nerves_ssdp_server, "~> 0.2.1"},
],

114
mix.lock
View File

@ -1,71 +1,71 @@
%{"amnesia": {:git, "https://github.com/meh/amnesia.git", "9094607fe61dc65a77ba71ae75a994847eb1dba5", []},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
"calendar": {:hex, :calendar, "0.17.1", "5c7dfffde2b68011c2d6832ff1a15496292de965a3b57b3fad32405f1176f024", [:mix], [{:tzdata, "~> 0.5.8 or ~> 0.1.201603", [hex: :tzdata, optional: false]}]},
"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []},
"combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], []},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []},
"cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, optional: false]}]},
"cowboy": {:hex, :cowboy, "1.1.0", "d9637f0fe7f0727efc8d703a9cfc2cf9e67fd11c6f7a22d35be687e44441d734", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.2.0", [hex: :ranch, optional: false]}]},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
"credo": {:hex, :credo, "0.6.0-rc1", "3db898270ba651aa7d8dc8d844f2827e0111526a01474ab088c7f7f677e83778", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]},
"dialyxir": {:hex, :dialyxir, "0.4.3", "a4daeebd0107de10d3bbae2ccb6b8905e69544db1ed5fe9148ad27cd4cb2c0cd", [:mix], []},
"distillery": {:hex, :distillery, "1.3.1", "211231af29ea55c79143d601a2caaf5936cc7b99e73bef25d78a0ff7f321b7fe", [:mix], []},
"earmark": {:hex, :earmark, "1.0.3", "89bdbaf2aca8bbb5c97d8b3b55c5dd0cff517ecc78d417e87f1d0982e514557b", [:mix], []},
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [:mix], []},
"ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]},
"ex_json_schema": {:hex, :ex_json_schema, "0.5.3", "f2db8eb71ca7a836607d67021d1b9c24f192dd5d1ec6b6b1c89bc934fec3bf5e", [:mix], []},
"ex_rollbar": {:hex, :ex_rollbar, "0.1.1", "65e4c37e631a3884a9458ce4973b9e00d2ff6765a24bb33af589eba464b19131", [:mix], [{:poison, "~> 3.0", [hex: :poison, optional: false]}]},
"ex_syslogger": {:hex, :ex_syslogger, "1.3.3", "914be2c8d759d60d853790815e6cf853e4cea9e24922c01b488c172ba0b7e105", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, optional: true]}, {:syslog, "~> 1.0.2", [hex: :syslog, optional: false]}]},
"ex_webpack": {:hex, :ex_webpack, "0.1.1", "d9deca1f9adfa1fa99ee2630f79756d741f17d4865bc808cd44577304fd053e3", [:mix], []},
"exactor": {:hex, :exactor, "2.2.3", "a6972f43bb6160afeb73e1d8ab45ba604cd0ac8b5244c557093f6e92ce582786", [:mix], []},
"excoveralls": {:hex, :excoveralls, "0.6.3", "894bf9254890a4aac1d1165da08145a72700ff42d8cb6ce8195a584cb2a4b374", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]},
"exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"calendar": {:hex, :calendar, "0.17.1", "5c7dfffde2b68011c2d6832ff1a15496292de965a3b57b3fad32405f1176f024", [:mix], [{:tzdata, "~> 0.5.8 or ~> 0.1.201603", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], [], "hexpm"},
"combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], [], "hexpm"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"cowboy": {:hex, :cowboy, "1.1.0", "d9637f0fe7f0727efc8d703a9cfc2cf9e67fd11c6f7a22d35be687e44441d734", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.2.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
"credo": {:hex, :credo, "0.6.0-rc1", "3db898270ba651aa7d8dc8d844f2827e0111526a01474ab088c7f7f677e83778", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"},
"dialyxir": {:hex, :dialyxir, "0.4.3", "a4daeebd0107de10d3bbae2ccb6b8905e69544db1ed5fe9148ad27cd4cb2c0cd", [:mix], [], "hexpm"},
"distillery": {:hex, :distillery, "1.3.1", "211231af29ea55c79143d601a2caaf5936cc7b99e73bef25d78a0ff7f321b7fe", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.0.3", "89bdbaf2aca8bbb5c97d8b3b55c5dd0cff517ecc78d417e87f1d0982e514557b", [:mix], [], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
"ex_json_schema": {:hex, :ex_json_schema, "0.5.3", "f2db8eb71ca7a836607d67021d1b9c24f192dd5d1ec6b6b1c89bc934fec3bf5e", [:mix], [], "hexpm"},
"ex_rollbar": {:hex, :ex_rollbar, "0.1.1", "65e4c37e631a3884a9458ce4973b9e00d2ff6765a24bb33af589eba464b19131", [:mix], [{:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"ex_syslogger": {:hex, :ex_syslogger, "1.3.3", "914be2c8d759d60d853790815e6cf853e4cea9e24922c01b488c172ba0b7e105", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.0.2", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm"},
"ex_webpack": {:hex, :ex_webpack, "0.1.1", "d9deca1f9adfa1fa99ee2630f79756d741f17d4865bc808cd44577304fd053e3", [:mix], [], "hexpm"},
"exactor": {:hex, :exactor, "2.2.3", "a6972f43bb6160afeb73e1d8ab45ba604cd0ac8b5244c557093f6e92ce582786", [:mix], [], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.6.3", "894bf9254890a4aac1d1165da08145a72700ff42d8cb6ce8195a584cb2a4b374", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
"exquisite": {:hex, :exquisite, "0.1.7", "4106503e976f409246731b168cd76eb54262bd04f4facc5cba82c2f53982aaf0", [:mix], []},
"exvcr": {:hex, :exvcr, "0.8.7", "e76f33b10dfefbcf32afa6d6867140566d0d54797e352b47485eed0241dd7edf", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, optional: false]}, {:exjsx, "~> 3.2", [hex: :exjsx, optional: false]}, {:httpoison, "~> 0.8", [hex: :httpoison, optional: true]}, {:httpotion, "~> 3.0", [hex: :httpotion, optional: true]}, {:ibrowse, "~> 4.2.2", [hex: :ibrowse, optional: true]}, {:meck, "~> 0.8.3", [hex: :meck, optional: false]}]},
"faker": {:hex, :faker, "0.7.0", "2c42deeac7be717173c78c77fb3edc749fb5d5e460e33d01fe592ae99acc2f0d", [:mix], []},
"exvcr": {:hex, :exvcr, "0.8.7", "e76f33b10dfefbcf32afa6d6867140566d0d54797e352b47485eed0241dd7edf", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 3.2", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.8", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.0", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.2.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8.3", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"faker": {:hex, :faker, "0.7.0", "2c42deeac7be717173c78c77fb3edc749fb5d5e460e33d01fe592ae99acc2f0d", [:mix], [], "hexpm"},
"farmbot_simulator": {:git, "https://github.com/farmbot-labs/farmbot_simulator.git", "ee072d54e756d8548b687e85651e055f222d21fb", []},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
"gen_mqtt": {:hex, :gen_mqtt, "0.3.1", "6ce6af7c2bcb125d5b4125c67c5ab1f29bcec2638236509bcc6abf510a6661ed", [:mix], [{:vmq_commons, "1.0.0", [hex: :vmq_commons, optional: false]}]},
"gen_stage": {:hex, :gen_stage, "0.11.0", "943bdfa85c75fa624e0a36a9d135baad20a523be040178f5a215444b45c66ea4", [:mix], []},
"gettext": {:hex, :gettext, "0.13.0", "daafbddc5cda12738bb93b01d84105fe75b916a302f1c50ab9fb066b95ec9db4", [:mix], []},
"hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"},
"gen_mqtt": {:hex, :gen_mqtt, "0.3.1", "6ce6af7c2bcb125d5b4125c67c5ab1f29bcec2638236509bcc6abf510a6661ed", [:mix], [{:vmq_commons, "1.0.0", [hex: :vmq_commons, repo: "hexpm", optional: false]}], "hexpm"},
"gen_stage": {:hex, :gen_stage, "0.11.0", "943bdfa85c75fa624e0a36a9d135baad20a523be040178f5a215444b45c66ea4", [:mix], [], "hexpm"},
"gettext": {:hex, :gettext, "0.13.0", "daafbddc5cda12738bb93b01d84105fe75b916a302f1c50ab9fb066b95ec9db4", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "4.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"httpoison": {:git, "https://github.com/edgurgel/httpoison.git", "d7633d7dc286aaac41970c7f2dd8d6f12da8f05d", []},
"ibrowse": {:hex, :ibrowse, "4.2.2", "b32b5bafcc77b7277eff030ed32e1acc3f610c64e9f6aea19822abcadf681b4b", [:rebar3], []},
"idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []},
"meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], []},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"mock": {:hex, :mock, "0.2.1", "bfdba786903e77f9c18772dee472d020ceb8ef000783e737725a4c8f54ad28ec", [:mix], [{:meck, "~> 0.8.2", [hex: :meck, optional: false]}]},
"mustache": {:hex, :mustache, "0.0.2", "870fbef411c47d17df06a57b8b3f69e26eb110cba0177c34e273db5d94369d9b", [:mix], []},
"nerves": {:hex, :nerves, "0.5.1", "a55d73752e8f271c7aca5fbe47747f07d0e7760b5e858e7f8da17ab06287f49c", [:mix], [{:distillery, "~> 1.0", [hex: :distillery, optional: false]}]},
"nerves_firmware": {:git, "https://github.com/nerves-project/nerves_firmware.git", "0f558ad2402cbd5b36bd7a8a10bc2b53167de14e", [tag: "0f558ad2402cbd5b36bd7a8a10bc2b53167de14e"]},
"idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], [], "hexpm"},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"},
"meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], [], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"mock": {:hex, :mock, "0.2.1", "bfdba786903e77f9c18772dee472d020ceb8ef000783e737725a4c8f54ad28ec", [:mix], [{:meck, "~> 0.8.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"mustache": {:hex, :mustache, "0.0.2", "870fbef411c47d17df06a57b8b3f69e26eb110cba0177c34e273db5d94369d9b", [:mix], [], "hexpm"},
"nerves": {:hex, :nerves, "0.5.1", "a55d73752e8f271c7aca5fbe47747f07d0e7760b5e858e7f8da17ab06287f49c", [:mix], [{:distillery, "~> 1.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_firmware": {:git, "https://github.com/nerves-project/nerves_firmware.git", "421d343a987b6b324e1e2919c24ba4e8e90e34df", []},
"nerves_firmware_http": {:hex, :nerves_firmware_http, "0.3.1", "e6ed2f8aa216df424a18ee56b6160b2aa7df9c3783406c93a61d92efd94acfac", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, optional: false]}, {:nerves_firmware, "~> 0.3", [hex: :nerves_firmware, optional: false]}]},
"nerves_hal": {:git, "https://github.com/LeToteTeam/nerves_hal.git", "249139e985017fdf0c5839eefc59788f575c48dd", []},
"nerves_interim_wifi": {:git, "https://github.com/nerves-project/nerves_interim_wifi.git", "42a70b8773adbbf2918e68262b47241c6fb61947", []},
"nerves_lib": {:git, "https://github.com/nerves-project/nerves_lib.git", "aac351cb3e621831a317f2d2a078257161efa551", []},
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.0", "a8e7662cd56fb4fe9060c891d35c43bbbff692ee6fd2d5efd538717da0cd96b8", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, optional: false]}]},
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.0", "a8e7662cd56fb4fe9060c891d35c43bbbff692ee6fd2d5efd538717da0cd96b8", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_runtime": {:git, "https://github.com/nerves-project/nerves_runtime.git", "d5fe649b4ce5c5ac7a7ab89083ecaee0d9214b94", []},
"nerves_ssdp_server": {:hex, :nerves_ssdp_server, "0.2.1", "2d010552023fc1a724e8cb5c92479a58552976e6f805b6dbf09babd31f923b8f", [:mix], []},
"nerves_ssdp_server": {:hex, :nerves_ssdp_server, "0.2.1", "2d010552023fc1a724e8cb5c92479a58552976e6f805b6dbf09babd31f923b8f", [:mix], [], "hexpm"},
"nerves_system_br": {:hex, :nerves_system_br, "0.9.4", "5096a9dfec49d4663ccb94c4a4fe45885303fbf31108f7e9400369bdec94b5e7", [:mix], []},
"nerves_toolchain_arm_unknown_linux_gnueabihf": {:hex, :nerves_toolchain_arm_unknown_linux_gnueabihf, "0.10.0", "18200c6cc3fcda1cbe263b7f7d50ff05db495b881ade9436cd1667b3e8e62429", [:mix], [{:nerves, "~> 0.4", [hex: :nerves, optional: false]}, {:nerves_toolchain_ctng, "~> 0.9", [hex: :nerves_toolchain_ctng, optional: false]}]},
"nerves_toolchain_arm_unknown_linux_gnueabihf": {:hex, :nerves_toolchain_arm_unknown_linux_gnueabihf, "0.10.0", "18200c6cc3fcda1cbe263b7f7d50ff05db495b881ade9436cd1667b3e8e62429", [:mix], [{:nerves, "~> 0.4", [hex: :nerves, repo: "hexpm", optional: false]}, {:nerves_toolchain_ctng, "~> 0.9", [hex: :nerves_toolchain_ctng, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_toolchain_armv6_rpi_linux_gnueabi": {:hex, :nerves_toolchain_armv6_rpi_linux_gnueabi, "0.10.0", "a730667fb22710270d3e9fdab8ce7230381c424f65b0381feb693829bc460f80", [:mix], [{:nerves, "~> 0.4", [hex: :nerves, optional: false]}, {:nerves_toolchain_ctng, "~> 0.9", [hex: :nerves_toolchain_ctng, optional: false]}]},
"nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "0.9.0", "825b2b5bbacc3ad20c8513baafd44978616d5b451e6e052cdb727be81e7cdcac", [:mix], []},
"nerves_uart": {:hex, :nerves_uart, "0.1.2", "4310dbb1721a5a007b8e5c416cf81754415bde6b7e2c9aa65a059886b85e637c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, optional: false]}]},
"nerves_wpa_supplicant": {:hex, :nerves_wpa_supplicant, "0.3.0", "dfda748df2662e1e9e95df6662c3a512d371ef23359b2c090b9c8c884b236a3d", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, optional: false]}]},
"plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
"quantum": {:hex, :quantum, "1.8.1", "37c9ad0307cf47bd578507ce1ddda98746199b281e8afe91cbe44c21d56af983", [:mix], [{:calendar, "~> 0.16", [hex: :calendar, optional: false]}]},
"ranch": {:hex, :ranch, "1.2.1", "a6fb992c10f2187b46ffd17ce398ddf8a54f691b81768f9ef5f461ea7e28c762", [:make], []},
"redix": {:hex, :redix, "0.5.1", "2bf874a186cc759791b8defdd0bfaa752784716bd48241f6aa972a20e7f95745", [:mix], [{:connection, "~> 1.0", [hex: :connection, optional: false]}]},
"nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "0.9.0", "825b2b5bbacc3ad20c8513baafd44978616d5b451e6e052cdb727be81e7cdcac", [:mix], [], "hexpm"},
"nerves_uart": {:hex, :nerves_uart, "0.1.2", "4310dbb1721a5a007b8e5c416cf81754415bde6b7e2c9aa65a059886b85e637c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_wpa_supplicant": {:hex, :nerves_wpa_supplicant, "0.3.0", "dfda748df2662e1e9e95df6662c3a512d371ef23359b2c090b9c8c884b236a3d", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"quantum": {:hex, :quantum, "1.8.1", "37c9ad0307cf47bd578507ce1ddda98746199b281e8afe91cbe44c21d56af983", [:mix], [{:calendar, "~> 0.16", [hex: :calendar, repo: "hexpm", optional: false]}], "hexpm"},
"ranch": {:hex, :ranch, "1.2.1", "a6fb992c10f2187b46ffd17ce398ddf8a54f691b81768f9ef5f461ea7e28c762", [:make], [], "hexpm"},
"redix": {:hex, :redix, "0.5.1", "2bf874a186cc759791b8defdd0bfaa752784716bd48241f6aa972a20e7f95745", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
"rollbax": {:hex, :rollbax, "0.8.2", "204a47a83fe32745def19ea0307b297395c00315fb85f30dfda04d5009b5ecb9", [:mix], [{:hackney, "~> 1.1", [hex: :hackney, optional: false]}, {:poison, "~> 1.4 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]},
"rsa": {:hex, :rsa, "0.0.1", "a63069f88ce342ffdf8448b7cdef4b39ba7dee3c1510644a39385c7e63ba246f", [:mix], []},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []},
"syslog": {:hex, :syslog, "1.0.2", "9cf72c0986675a170c03b210e49700845a0f7b61e96d302a3ba0df82963daf60", [:rebar], []},
"rsa": {:hex, :rsa, "0.0.1", "a63069f88ce342ffdf8448b7cdef4b39ba7dee3c1510644a39385c7e63ba246f", [:mix], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"syslog": {:hex, :syslog, "1.0.2", "9cf72c0986675a170c03b210e49700845a0f7b61e96d302a3ba0df82963daf60", [:rebar], [], "hexpm"},
"system_registry": {:hex, :system_registry, "0.1.2", "b6dba36c575786f1848e18a1155a2b6bd82f607f0ae9dc88185d6b7dc3fcdf60", [:mix], []},
"timex": {:hex, :timex, "3.1.7", "71f9c32e13ff4860e86a314303757cc02b3ead5db6e977579a2935225ce9a666", [:mix], [{:combine, "~> 0.7", [hex: :combine, optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, optional: false]}]},
"tzdata": {:hex, :tzdata, "0.1.201605", "0c4184819b9d6adedcc02107b68321c45d8e853def7a32629b7961b9f2e95f33", [:mix], []},
"vmq_commons": {:hex, :vmq_commons, "1.0.0", "5f5005c12db33f92f40e818a3617fb148972d59adcf99298c9d3808ef3582e34", [:rebar3], []},
"websocket_client": {:hex, :websocket_client, "1.2.1", "a965ce0be5583c90347400bceca66629e4debd5feb9bd516107e2924bdf39dad", [:rebar3], []},
"wobserver": {:hex, :wobserver, "0.1.7", "377b9a2903728b62e4e89d4e200ec17d60669ccdd3ed72b23a2ab3a2c079694d", [:mix], [{:cowboy, "~> 1.1", [hex: :cowboy, optional: false]}, {:httpoison, "~> 0.11", [hex: :httpoison, optional: false]}, {:plug, "~> 1.3", [hex: :plug, optional: false]}, {:poison, "~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}, {:websocket_client, "~> 1.2", [hex: :websocket_client, optional: false]}]}}
"timex": {:hex, :timex, "3.1.7", "71f9c32e13ff4860e86a314303757cc02b3ead5db6e977579a2935225ce9a666", [:mix], [{:combine, "~> 0.7", [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.1.201605", "0c4184819b9d6adedcc02107b68321c45d8e853def7a32629b7961b9f2e95f33", [:mix], [], "hexpm"},
"vmq_commons": {:hex, :vmq_commons, "1.0.0", "5f5005c12db33f92f40e818a3617fb148972d59adcf99298c9d3808ef3582e34", [:rebar3], [], "hexpm"},
"websocket_client": {:hex, :websocket_client, "1.2.1", "a965ce0be5583c90347400bceca66629e4debd5feb9bd516107e2924bdf39dad", [:rebar3], [], "hexpm"},
"wobserver": {:hex, :wobserver, "0.1.7", "377b9a2903728b62e4e89d4e200ec17d60669ccdd3ed72b23a2ab3a2c079694d", [:mix], [{:cowboy, "~> 1.1", [hex: :cowboy, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.11", [hex: :httpoison, repo: "hexpm", optional: false]}, {:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}, {:websocket_client, "~> 1.2", [hex: :websocket_client, repo: "hexpm", optional: false]}], "hexpm"}}