Handler for Linux UEvents. Not wired up yet, but definately works.

pull/296/head
connor rigby 2017-04-21 08:48:22 -07:00
parent 420b5d8bfb
commit 7d260828c6
4 changed files with 135 additions and 2 deletions

View File

@ -0,0 +1,128 @@
defmodule Farmbot.System.UeventHandler do
@moduledoc """
Handles Events from Linux.
"""
use GenStage
use Farmbot.DebugLog
require Logger
@mountpath "/tmp/drive"
@target Mix.Project.config[:target]
@app Mix.Project.config[:app]
def start_link do
GenStage.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
# Starts a permanent subscription to the broadcaster
# which will automatically start requesting items.
{:consumer, :ok, subscribe_to: [Nerves.Runtime.Kernel.UEvent]}
end
def handle_events(events, _from, state) do
for event <- events do
handle_thing(event)
end
{:noreply, [], state}
end
defp handle_thing({:uevent, _, %{
action: "add", devname: devname, devtype: "partition", subsystem: "block"
}})
do
Logger.debug ">> Flash drive plugged in!!!"
:ok = mount_part(devname)
Logger.debug ">> Coppying logs!"
File.cp "#{Farmbot.System.FS.path()}/logs.txt", "#{@mountpath}/logs.txt"
:ok = maybe_flash_fw
:ok = unmount_part(devname)
:ok
end
defp handle_thing(_event) do
debug_log("Not Handling uevent.")
:ok
end
defp mount_part(devname) do
Logger.debug ">> Mounting flash drive storage!"
:ok = File.mkdir_p(@mountpath)
:ok = System.cmd("mount", ["-t", "vfat", "/dev/#{devname}", "#{@mountpath}"])
|> check_mount(devname)
:ok
end
defp unmount_part(devname) do
Logger.debug ">> Unmounting flash drive storage!"
:ok = System.cmd("umount", ["/dev/#{devname}"]) |> check_mount(devname)
end
defp check_mount({_, 0}, _devname), do: :ok
defp check_mount({err, _}, devname) do
Logger.error ">> Error mounting or unmounting #{devname}! #{inspect err}"
{:error, err}
end
defp maybe_flash_fw do
fw_file = "#{@mountpath}/firmware.hex"
os_file = "#{@mountpath}/#{@app}-#{@target}.fw"
debug_log "Checking for emergency flash files."
IO.inspect {fw_file, os_file}
case File.stat(fw_file) do
{:ok, _file} -> handle_arduino(fw_file)
_ -> debug_log "No fw file found."
end
case File.stat(os_file) do
{:ok, _file} -> handle_os(os_file)
_ -> debug_log "No os fw file found."
end
:ok
end
defp handle_os(file) do
Nerves.Firmware.upgrade_and_finalize(file)
Nerves.Firmware.reboot
end
defp handle_arduino(file) do
errrm = fn() ->
receive do
:done ->
:ok
{:error, reason} -> {:error, reason}
end
end
Logger.info ">> is installing a firmware update. "
<> " I may act weird for a moment", channels: [:toast]
pid = Process.whereis(Farmbot.Serial.Handler)
if pid do
GenServer.cast(Farmbot.Serial.Handler, {:update_fw, file, self()})
errrm.()
else
Logger.info "doing some magic..."
herp = Nerves.UART.enumerate()
|> Map.drop(["ttyS0","ttyAMA0"])
|> Map.keys
case herp do
[tty] ->
Logger.info "magic complete!"
Farmbot.Serial.Handler.flash_firmware(tty, file, self())
errrm.()
_ ->
Logger.warn "Please only have one serial device when updating firmware"
{:error, :could_not_detect_tty}
end
end
end
end

View File

@ -9,6 +9,7 @@ defmodule Logger.Backends.FarmbotLogger do
alias Farmbot.HTTP
use GenEvent
require Logger
use Farmbot.DebugLog
@save_path Application.get_env(:farmbot, :path) <> "/logs.txt"
# ten megs. i promise
@ -86,11 +87,13 @@ defmodule Logger.Backends.FarmbotLogger do
def handle_event(:flush, _state), do: {:ok, %{logs: [], posting: false}}
def handle_call(:post_success, state) do
debug_log "Logs uploaded!"
write_file(Enum.reverse(state.logs))
{:ok, :ok, %{state | posting: false, logs: []}}
end
def handle_call(:post_fail, state) do
debug_log "Logs failed to upload!"
{:ok, :ok, %{state | posting: false}}
end
@ -112,6 +115,7 @@ defmodule Logger.Backends.FarmbotLogger do
@spec write_file([log_message]) :: no_return
defp write_file(logs) do
debug_log("Writing log file!")
old = read_file()
new_file = Enum.reduce(logs, old, fn(log, acc) ->
if log.message != @filtered do

View File

@ -108,7 +108,8 @@ defmodule Farmbot.Mixfile do
[
{:nerves, "0.5.1"},
{:nerves_runtime, "~> 0.1.1"},
# {:nerves_runtime, "~> 0.1.1"},
{:nerves_runtime, github: "nerves-project/nerves_runtime", override: true},
{:nerves_hal, github: "LeToteTeam/nerves_hal"},
# Hardware stuff

View File

@ -45,7 +45,7 @@
"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_runtime": {:hex, :nerves_runtime, "0.1.1", "efa80e0dab93a53cb44dacdb6e2a326dfe4b54b94a0da6173c10f410e08fecb5", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, optional: false]}, {:gen_stage, "~> 0.4", [hex: :gen_stage, optional: false]}, {:nerves_uart, "~> 0.1.0", [hex: :nerves_uart, optional: true]}]},
"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_system_br": {:git, "https://github.com/tmecklem/nerves_system_br.git", "b4297e361bb8ecb3abb6abdd49e52faa6350af51", [branch: "master"]},
"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]}]},