Time for bed.
parent
7b6bb8eb52
commit
2b9a3716c3
|
@ -4,6 +4,12 @@ import_config "#{Mix.env}.exs"
|
|||
config :farmbot_auth,
|
||||
callbacks: [Farmbot.Sync, Farmbot.RPC.Transport.Mqtt]
|
||||
|
||||
config :farmbot_configurator,
|
||||
callback: Farmbot.BotState.Monitor
|
||||
|
||||
config :json_rpc,
|
||||
transport: Farmbot.RPC.Transport.Mqtt,
|
||||
handler: Farmbot.RPC.Handler
|
||||
transport: Farmbot.RPC.Transport.Mqtt,
|
||||
handler: Farmbot.RPC.Handler
|
||||
|
||||
config :uart,
|
||||
baud: 115200
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
use Mix.Config
|
||||
config :uart,
|
||||
baud: 115200
|
||||
|
||||
config :farmbot,
|
||||
state_path: "/tmp/state"
|
||||
|
|
|
@ -3,17 +3,17 @@ config :nerves, :firmware,
|
|||
rootfs_additions: "config/rootfs-additions-#{Mix.Project.config[:target]}",
|
||||
hardware: "config/rootfs-additions-#{Mix.Project.config[:target]}"
|
||||
|
||||
config :uart,
|
||||
baud: 115200
|
||||
|
||||
config :farmbot,
|
||||
state_path: "/state",
|
||||
state_path: "/state"
|
||||
|
||||
config :farmbot_networking,
|
||||
dnsmasq_path: "/root/dnsmasq.lease"
|
||||
|
||||
config :logger, :console,
|
||||
# format: "$metadata[$level] $levelpad$message\r\n",
|
||||
colors: [enabled: true ]
|
||||
config :Logger,
|
||||
|
||||
config :logger,
|
||||
handle_sasl_reports: true,
|
||||
handle_otp_reports: true
|
||||
|
||||
|
@ -28,9 +28,3 @@ config :iex,
|
|||
"%node",
|
||||
">",
|
||||
:reset ] |> IO.ANSI.format |> IO.chardata_to_string
|
||||
|
||||
config :blinky, led_list: [ :green ]
|
||||
config :nerves_leds, names: [ green: "led0" ]
|
||||
|
||||
config :farmbot_configurator,
|
||||
event_handler: Farmbot.BotState.EventManager
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
defmodule Farmbot.BotState.EventManager do
|
||||
@moduledoc """
|
||||
Handles stuff like logging in to web services and what not.
|
||||
"""
|
||||
use GenEvent
|
||||
require Logger
|
||||
|
||||
def handle_event({:login,
|
||||
%{"email" => email,
|
||||
"network" => "ethernet",
|
||||
"password" => password,
|
||||
"server" => server,
|
||||
"tz" => timezone}}, parent)
|
||||
do
|
||||
Farmbot.BotState.update_config("timezone", timezone)
|
||||
Farmbot.BotState.add_creds({email,password,server})
|
||||
NetMan.connect(:ethernet, Farmbot.BotState)
|
||||
{:ok, parent}
|
||||
end
|
||||
|
||||
def handle_event({:login,
|
||||
%{"email" => email,
|
||||
"network" => %{"psk" => psk, "ssid" => ssid},
|
||||
"password" => password,
|
||||
"server" => server,
|
||||
"tz" => timezone}}, parent)
|
||||
do
|
||||
Farmbot.BotState.update_config("timezone", timezone)
|
||||
Farmbot.BotState.add_creds({email,password,server})
|
||||
NetMan.connect({ssid, psk}, Farmbot.BotState)
|
||||
{:ok, parent}
|
||||
end
|
||||
|
||||
def handle_event(event, parent) do
|
||||
Logger.warn("unhandled botstate event #{inspect event}")
|
||||
{:ok, parent}
|
||||
end
|
||||
end
|
|
@ -1,8 +1,8 @@
|
|||
alias Farmbot.BotState.Hardware, as: Hardware
|
||||
alias Farmbot.BotState.Configuration, as: Configuration
|
||||
alias Farmbot.BotState.Authorization, as: Authorization
|
||||
alias Serialized, as: State # DELETE ME
|
||||
|
||||
alias Serialized, as: State
|
||||
defmodule Farmbot.BotState do
|
||||
require Logger
|
||||
@moduledoc """
|
||||
|
@ -95,39 +95,6 @@ defmodule Farmbot.BotState do
|
|||
{:reply, state.location, state}
|
||||
end
|
||||
|
||||
# This call should probably be a cast actually, and im sorry.
|
||||
# Returns true for configs that exist and are the correct typpe,
|
||||
# and false for anything else
|
||||
# TODO make sure these are properly typed.
|
||||
def handle_call({:update_config, "os_auto_update", value}, _from, state)
|
||||
when is_boolean(value) do
|
||||
new_config = Map.put(state.configuration, :os_auto_update, value)
|
||||
{:reply, true, Map.put(state, :configuration, new_config)}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "fw_auto_update", value}, _from, state)
|
||||
when is_boolean(value) do
|
||||
new_config = Map.put(state.configuration, :fw_auto_update, value)
|
||||
{:reply, true, Map.put(state, :configuration, new_config)}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "timezone", value}, _from, state)
|
||||
when is_bitstring(value) do
|
||||
new_config = Map.put(state.configuration, :timezone, value)
|
||||
{:reply, true, Map.put(state, :configuration, new_config)}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "steps_per_mm", value}, _from, state)
|
||||
when is_integer(value) do
|
||||
new_config = Map.put(state.configuration, :steps_per_mm, value)
|
||||
{:reply, true, Map.put(state, :configuration, new_config)}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, key, _value}, _from, state) do
|
||||
Logger.error("#{key} is not a valid config.")
|
||||
{:reply, false, state}
|
||||
end
|
||||
|
||||
def handle_call({:get_config, key}, _from, state)
|
||||
when is_atom(key) do
|
||||
{:reply, Map.get(state.configuration, key), state}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
alias Farmbot.BotState.Hardware.State, as: Hardware
|
||||
alias Farmbot.BotState.Configuration.State, as: Configuration
|
||||
alias Farmbot.BotState.Authorization.State, as: Authorization
|
||||
alias Farmbot.Scheduler.State.Serializer, as: Scheduler
|
||||
|
||||
defmodule Farmbot.BotState.Monitor do
|
||||
@moduledoc """
|
||||
|
@ -15,12 +16,14 @@ defmodule Farmbot.BotState.Monitor do
|
|||
@type t :: %__MODULE__{
|
||||
hardware: Hardware.t,
|
||||
configuration: Configuration.t,
|
||||
authorization: Authorization.t
|
||||
authorization: Authorization.t,
|
||||
scheduler: Scheduler.t
|
||||
}
|
||||
defstruct [
|
||||
hardware: %Hardware{},
|
||||
configuration: %Configuration{},
|
||||
authorization: %Authorization{}
|
||||
authorization: %Authorization{},
|
||||
scheduler: %Scheduler{}
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -63,6 +66,38 @@ defmodule Farmbot.BotState.Monitor do
|
|||
dispatch(mgr, new_state)
|
||||
end
|
||||
|
||||
# When we get a state update from Scheduler
|
||||
def handle_cast(%Scheduler{} = new_things, {mgr, state}) do
|
||||
new_state = %State{state | scheduler: new_things}
|
||||
dispatch(mgr, new_state)
|
||||
end
|
||||
|
||||
def handle_cast({:login,
|
||||
%{"email" => email,
|
||||
"network" => "ethernet",
|
||||
"password" => password,
|
||||
"server" => server,
|
||||
"tz" => timezone}}, {mgr, state})
|
||||
do
|
||||
Farmbot.BotState.update_config("timezone", timezone)
|
||||
Farmbot.BotState.add_creds({email,password,server})
|
||||
NetMan.connect(:ethernet, Farmbot.BotState.Configuration)
|
||||
dispatch(mgr,state)
|
||||
end
|
||||
|
||||
def handle_cast({:login,
|
||||
%{"email" => email,
|
||||
"network" => %{"psk" => psk, "ssid" => ssid},
|
||||
"password" => password,
|
||||
"server" => server,
|
||||
"tz" => timezone}}, {mgr, state})
|
||||
do
|
||||
Farmbot.BotState.update_config("timezone", timezone)
|
||||
Farmbot.BotState.add_creds({email,password,server})
|
||||
NetMan.connect({ssid, psk}, Farmbot.BotState.Configuration)
|
||||
dispatch(mgr,state)
|
||||
end
|
||||
|
||||
# If a handler dies, we try to restart it
|
||||
def handle_info({:gen_event_EXIT, handler, _reason}, {mgr, state}) do
|
||||
Logger.warn("HANDLER DIED: #{inspect handler} Goint to try to restart")
|
||||
|
|
|
@ -31,4 +31,24 @@ defmodule Farmbot.BotState.Authorization do
|
|||
def start_link(args) do
|
||||
GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
def handle_call(event, _from, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CALL!: #{inspect event}", [__MODULE__])
|
||||
dispatch :unhandled, state
|
||||
end
|
||||
|
||||
def handle_cast(event, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CAST!: #{inspect event}", [__MODULE__])
|
||||
dispatch state
|
||||
end
|
||||
|
||||
defp dispatch(reply, %State{} = state) do
|
||||
State.broadcast(state)
|
||||
{:reply, reply, state}
|
||||
end
|
||||
|
||||
defp dispatch(%State{} = state) do
|
||||
State.broadcast(state)
|
||||
{:noreply, state}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,4 +27,57 @@ defmodule Farmbot.BotState.Configuration do
|
|||
def start_link(args) do
|
||||
GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
# This call should probably be a cast actually, and im sorry.
|
||||
# Returns true for configs that exist and are the correct typpe,
|
||||
# and false for anything else
|
||||
# TODO make sure these are properly typed.
|
||||
def handle_call({:update_config, "os_auto_update", value}, _from, %State{} = state)
|
||||
when is_boolean(value) do
|
||||
new_config = Map.put(state.configuration, :os_auto_update, value)
|
||||
dispatch true, %State{configuration: new_config}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "fw_auto_update", value}, _from, %State{} = state)
|
||||
when is_boolean(value) do
|
||||
new_config = Map.put(state.configuration, :fw_auto_update, value)
|
||||
dispatch true, %State{configuration: new_config}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "timezone", value}, _from, %State{} = state)
|
||||
when is_bitstring(value) do
|
||||
new_config = Map.put(state.configuration, :timezone, value)
|
||||
dispatch true, %State{configuration: new_config}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, "steps_per_mm", value}, _from, %State{} = state)
|
||||
when is_integer(value) do
|
||||
new_config = Map.put(state.configuration, :steps_per_mm, value)
|
||||
dispatch true, %State{configuration: new_config}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, key, _value}, _from, %State{} = state) do
|
||||
Logger.error("#{key} is not a valid config.")
|
||||
dispatch false, state
|
||||
end
|
||||
|
||||
def handle_call(event, _from, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CALL!: #{inspect event}", [__MODULE__])
|
||||
dispatch :unhandled, state
|
||||
end
|
||||
|
||||
def handle_cast(event, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CAST!: #{inspect event}", [__MODULE__])
|
||||
dispatch state
|
||||
end
|
||||
|
||||
defp dispatch(reply, %State{} = state) do
|
||||
State.broadcast(state)
|
||||
{:reply, reply, state}
|
||||
end
|
||||
|
||||
defp dispatch(%State{} = state) do
|
||||
State.broadcast(state)
|
||||
{:noreply, state}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,4 +40,24 @@ defmodule Farmbot.BotState.Hardware do
|
|||
def start_link(args) do
|
||||
GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
def handle_call(event, _from, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CALL!: #{inspect event}", [__MODULE__])
|
||||
dispatch :unhandled, state
|
||||
end
|
||||
|
||||
def handle_cast(event, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CAST!: #{inspect event}", [__MODULE__])
|
||||
dispatch state
|
||||
end
|
||||
|
||||
defp dispatch(reply, %State{} = state) do
|
||||
State.broadcast(state)
|
||||
{:reply, reply, state}
|
||||
end
|
||||
|
||||
defp dispatch(%State{} = state) do
|
||||
State.broadcast(state)
|
||||
{:noreply, state}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -135,7 +135,7 @@ defmodule Farmbot.RPC.Handler do
|
|||
"""
|
||||
@spec serialize_state(Farmbot.BotState.Monitor.State.t) :: Serialized.t
|
||||
def serialize_state(%Farmbot.BotState.Monitor.State{
|
||||
hardware: hardware, configuration: configuration
|
||||
hardware: hardware, configuration: configuration, scheduler: scheduler
|
||||
}) do
|
||||
%Serialized{
|
||||
mcu_params: hardware.mcu_params,
|
||||
|
@ -148,7 +148,7 @@ defmodule Farmbot.RPC.Handler do
|
|||
informational_settings: configuration.informational_settings,
|
||||
|
||||
# farm scheduler
|
||||
farm_scheduler: %Farmbot.Scheduler.State.Serializer{}
|
||||
farm_scheduler: scheduler
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
defmodule Serialized do
|
||||
@moduledoc """
|
||||
MOVE THIS SOMEWHERE ELSE
|
||||
MOVE THIS SOMEWHERE ELSE
|
||||
"""
|
||||
defstruct [
|
||||
# Hardware
|
||||
|
|
|
@ -280,10 +280,13 @@ defmodule Farmbot.Scheduler do
|
|||
regimens: regimens}}
|
||||
end
|
||||
|
||||
@doc """
|
||||
I CAN'T THINK OF A BETTER WAY TO DO THIS IM SORRY
|
||||
"""
|
||||
@spec save_and_update(State.t) :: :ok
|
||||
def save_and_update(%State{} = state) do
|
||||
GenServer.cast(Farmbot.BotState,
|
||||
{:scheduler, State.Serializer.serialize(state)})
|
||||
GenServer.cast(Farmbot.BotState.Monitor,
|
||||
{State.Serializer.serialize(state)})
|
||||
SafeStorage.write(__MODULE__, :erlang.term_to_binary(state))
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule RPC.Supervisor do
|
|||
@transport Application.get_env(:json_rpc, :transport)
|
||||
@handler Application.get_env(:json_rpc, :handler)
|
||||
|
||||
def init(args) do
|
||||
def init(_args) do
|
||||
children = [
|
||||
worker(RPC.MessageManager, []),
|
||||
worker(RPC.MessageHandler, [], id: 1, name: RPC.MessageHandler ),
|
||||
|
|
16
mix.exs
16
mix.exs
|
@ -34,7 +34,7 @@ defmodule Farmbot.Mixfile do
|
|||
|
||||
def application do
|
||||
[mod: {Farmbot, [%{target: target(Mix.env), compat_version: @compat_version,
|
||||
version: @version, env: Mix.env}]},
|
||||
version: @version, env: Mix.env}]},
|
||||
applications: apps(Mix.env)]
|
||||
end
|
||||
|
||||
|
@ -51,7 +51,8 @@ defmodule Farmbot.Mixfile do
|
|||
:runtime_tools,
|
||||
:mustache,
|
||||
:timex,
|
||||
:farmbot_auth]
|
||||
:farmbot_auth,
|
||||
:farmbot_configurator]
|
||||
end
|
||||
|
||||
# on device
|
||||
|
@ -59,8 +60,7 @@ defmodule Farmbot.Mixfile do
|
|||
apps ++ platform_apps(target(:prod)) ++
|
||||
[
|
||||
:nerves,
|
||||
:nerves_firmware_http,
|
||||
:farmbot_configurator
|
||||
:nerves_firmware_http
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -89,6 +89,8 @@ defmodule Farmbot.Mixfile do
|
|||
{:mustache, "~> 0.0.2"},
|
||||
{:timex, "~> 3.0"},
|
||||
{:farmbot_auth, github: "Farmbot/farmbot_auth"},
|
||||
# {:farmbot_configurator, github: "Farmbot/farmbot_configurator"}
|
||||
{:farmbot_configurator, path: "../farmbot_configurator"}
|
||||
# {:farmbot_auth, path: "../farmbot_auth"}
|
||||
]
|
||||
end
|
||||
|
@ -97,9 +99,7 @@ defmodule Farmbot.Mixfile do
|
|||
deps ++ platform_deps(target(Mix.env)) ++ system(target(Mix.env)) ++
|
||||
[
|
||||
{:nerves, "~> 0.3.0"},
|
||||
{:nerves_firmware_http, github: "nerves-project/nerves_firmware_http"},
|
||||
# {:farmbot_configurator, github: "Farmbot/farmbot_configurator"}
|
||||
{:farmbot_configurator, path: "../farmbot_configurator"}
|
||||
{:nerves_firmware_http, github: "nerves-project/nerves_firmware_http"}
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -113,7 +113,7 @@ defmodule Farmbot.Mixfile do
|
|||
def deps(:dev) do
|
||||
deps ++ [
|
||||
# {:fake_nerves, github: "ConnorRigby/fake_nerves"},
|
||||
{:fake_nerves, path: "../fake_nerves"},
|
||||
{:fake_nerves, path: "../fake_nerves", override: true},
|
||||
{:credo, "~> 0.4"},
|
||||
{:dialyxir, "~> 0.4"}]
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue