almost done
parent
2b9a3716c3
commit
72c2030381
|
@ -23,14 +23,7 @@ defmodule Farmbot.BotState do
|
|||
state
|
||||
end
|
||||
|
||||
def get_throttled do
|
||||
{output, 0} = System.cmd("vcgencmd", ["get_throttled"])
|
||||
{"throttled=0x0\n", 0}
|
||||
[_, throttled] = output
|
||||
|> String.strip
|
||||
|> String.split("=")
|
||||
throttled
|
||||
end
|
||||
|
||||
|
||||
def load(%{target: target, compat_version: compat_version, env: env, version: version}) do
|
||||
token = case Farmbot.Auth.get_token() do
|
||||
|
@ -47,17 +40,10 @@ defmodule Farmbot.BotState do
|
|||
informational_settings: %{
|
||||
controller_version: version,
|
||||
private_ip: nil,
|
||||
throttled: get_throttled,
|
||||
throttled: :blah, #get_throttled,
|
||||
target: target,
|
||||
compat_version: compat_version,
|
||||
environment: env
|
||||
},
|
||||
authorization: %{
|
||||
token: token,
|
||||
email: nil,
|
||||
pass: nil,
|
||||
server: nil,
|
||||
network: nil
|
||||
}
|
||||
}
|
||||
case SafeStorage.read(__MODULE__) do
|
||||
|
@ -87,137 +73,6 @@ defmodule Farmbot.BotState do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_call({:get_pin, pin_number}, _from, state) do
|
||||
{:reply, Map.get(state.pins, Integer.to_string(pin_number)), state}
|
||||
end
|
||||
|
||||
def handle_call(:get_current_pos, _from, state) do
|
||||
{:reply, state.location, state}
|
||||
end
|
||||
|
||||
def handle_call({:get_config, key}, _from, state)
|
||||
when is_atom(key) do
|
||||
{:reply, Map.get(state.configuration, key), state}
|
||||
end
|
||||
|
||||
def handle_call(:get_token, _from, state) do
|
||||
{:reply, state.authorization.token, state}
|
||||
end
|
||||
|
||||
# Allow the frontend to do stuff again.
|
||||
def handle_call({:remove_lock, string}, _from, state) do
|
||||
maybe_index = Enum.find_index(state.locks, fn(%{reason: str}) -> str == string end)
|
||||
cond do
|
||||
is_integer(maybe_index) ->
|
||||
{:reply, :ok, Map.put(state, :locks,
|
||||
List.delete_at(state.locks, maybe_index))}
|
||||
true ->
|
||||
{:reply, {:error, :no_index}, state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_call({:get_lock, string}, _from, state) do
|
||||
maybe_index = Enum.find_index(state.locks, fn(%{reason: str}) -> str == string end)
|
||||
{:reply, maybe_index, state}
|
||||
end
|
||||
|
||||
# I HAVE NO CLUE WHAT IM DOING
|
||||
def handle_cast({:scheduler,
|
||||
%Farmbot.Scheduler.State.Serializer{} = sch_state}, state)
|
||||
do
|
||||
{:noreply, %State{state | farm_scheduler: sch_state}}
|
||||
end
|
||||
|
||||
# Lock the frontend from doing stuff
|
||||
def handle_cast({:add_lock, string}, state) do
|
||||
maybe_index = Enum.find_index(state.locks, fn(%{reason: str}) -> str == string end)
|
||||
cond do
|
||||
is_integer(maybe_index) ->
|
||||
{:noreply, Map.put(state, :locks,
|
||||
List.replace_at(state.locks, maybe_index, %{reason: string}) )}
|
||||
is_nil(maybe_index) ->
|
||||
{:noreply, Map.put(state, :locks,
|
||||
state.locks ++ [%{reason: string}] )}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_cast({:update_info, key, value}, state) do
|
||||
new_info = Map.put(state.informational_settings, key, value)
|
||||
{:noreply, Map.put(state, :informational_settings, new_info)}
|
||||
end
|
||||
|
||||
def handle_cast({:set_pos, {x, y, z}}, state) do
|
||||
{:noreply, Map.put(state, :location, [x, y, z])}
|
||||
end
|
||||
|
||||
def handle_cast({:set_pin_value, {pin, value}}, state) do
|
||||
pin_state = state.pins
|
||||
new_pin_value =
|
||||
case Map.get(pin_state, Integer.to_string(pin)) do
|
||||
nil ->
|
||||
%{mode: -1, value: value}
|
||||
%{mode: mode, value: _} ->
|
||||
%{mode: mode, value: value}
|
||||
end
|
||||
# I REALLY don't want this to be here.
|
||||
spawn fn -> Farmbot.Logger.log("PIN #{pin} set: #{new_pin_value.value}", [], ["BotControl"]) end
|
||||
pin_state = Map.put(pin_state, Integer.to_string(pin), new_pin_value)
|
||||
{:noreply, Map.put(state, :pins, pin_state)}
|
||||
end
|
||||
|
||||
def handle_cast({:set_pin_mode, {pin, mode}}, state) do
|
||||
pin_state = state.pins
|
||||
new_pin_value =
|
||||
case Map.get(pin_state, Integer.to_string(pin)) do
|
||||
nil -> %{mode: mode, value: -1}
|
||||
%{mode: _, value: value} -> %{mode: mode, value: value}
|
||||
end
|
||||
pin_state = Map.put(pin_state, Integer.to_string(pin), new_pin_value)
|
||||
{:noreply, Map.put(state, :pins, pin_state)}
|
||||
end
|
||||
|
||||
def handle_cast({:set_param, {param_string, value} }, state) do
|
||||
new_params = Map.put(state.mcu_params, param_string, value)
|
||||
{:noreply, Map.put(state, :mcu_params, new_params)}
|
||||
end
|
||||
|
||||
def handle_cast({:creds, {email, pass, server}}, state) do
|
||||
auth = Map.merge(state.authorization,
|
||||
%{email: email, pass: pass, server: server, token: nil, network: nil})
|
||||
{:noreply, Map.put(state, :authorization, auth)}
|
||||
end
|
||||
|
||||
def handle_info({:connected, network, ip_addr}, state) do
|
||||
# GenServer.cast(Farmbot.BotState, {:update_info, :private_ip, address})
|
||||
new_info = Map.put(state.informational_settings, :private_ip, ip_addr)
|
||||
email = state.authorization.email
|
||||
pass = state.authorization.pass
|
||||
server = state.authorization.server
|
||||
|
||||
case Farmbot.Auth.login(email, pass, server) do
|
||||
{:ok, token} ->
|
||||
Logger.debug("Got Token!")
|
||||
auth = Map.merge(state.authorization,
|
||||
%{email: email, pass: pass, server: server, token: token,
|
||||
network: network})
|
||||
set_time
|
||||
Farmbot.node_reset(ip_addr)
|
||||
{:noreply,
|
||||
Map.put(state, :authorization, auth)
|
||||
|> Map.put(:informational_settings, new_info)
|
||||
}
|
||||
# If the bot is faster than your router (often) this can happen.
|
||||
{:error, "enetunreach"} ->
|
||||
Logger.warn("Something super weird happened.. Probably a race condition.")
|
||||
# Just crash ourselves and try again.
|
||||
handle_info({:connected, network, ip_addr}, state)
|
||||
error ->
|
||||
Logger.error("Something bad happened when logging in!: #{inspect error}")
|
||||
Farmbot.factory_reset
|
||||
{:noreply, state}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the current position of the bot. Returns [x,y,z]
|
||||
"""
|
||||
|
@ -401,4 +256,87 @@ defmodule Farmbot.BotState do
|
|||
check_time_set # wait until time is set
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# THESE NEED TO GO AWAY
|
||||
|
||||
|
||||
|
||||
|
||||
def handle_call({:get_config, key}, _from, state)
|
||||
when is_atom(key) do
|
||||
{:reply, Map.get(state.configuration, key), state}
|
||||
end
|
||||
|
||||
def handle_call(:get_token, _from, state) do
|
||||
{:reply, state.authorization.token, state}
|
||||
end
|
||||
|
||||
# Allow the frontend to do stuff again.
|
||||
def handle_call({:remove_lock, string}, _from, state) do
|
||||
maybe_index = Enum.find_index(state.locks, fn(%{reason: str}) -> str == string end)
|
||||
cond do
|
||||
is_integer(maybe_index) ->
|
||||
{:reply, :ok, Map.put(state, :locks,
|
||||
List.delete_at(state.locks, maybe_index))}
|
||||
true ->
|
||||
{:reply, {:error, :no_index}, state}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_call({:get_lock, string}, _from, state) do
|
||||
maybe_index = Enum.find_index(state.locks, fn(%{reason: str}) -> str == string end)
|
||||
{:reply, maybe_index, state}
|
||||
end
|
||||
|
||||
# Lock the frontend from doing stuff
|
||||
def handle_cast({:add_lock, string}, state) do
|
||||
maybe_index = Enum.find_index(state.locks, fn(%{reason: str}) -> str == string end)
|
||||
cond do
|
||||
is_integer(maybe_index) ->
|
||||
{:noreply, Map.put(state, :locks,
|
||||
List.replace_at(state.locks, maybe_index, %{reason: string}) )}
|
||||
is_nil(maybe_index) ->
|
||||
{:noreply, Map.put(state, :locks,
|
||||
state.locks ++ [%{reason: string}] )}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_cast({:update_info, key, value}, state) do
|
||||
new_info = Map.put(state.informational_settings, key, value)
|
||||
{:noreply, Map.put(state, :informational_settings, new_info)}
|
||||
end
|
||||
|
||||
|
||||
|
||||
def handle_info({:connected, network, ip_addr}, state) do
|
||||
# GenServer.cast(Farmbot.BotState, {:update_info, :private_ip, address})
|
||||
new_info = Map.put(state.informational_settings, :private_ip, ip_addr)
|
||||
email = state.authorization.email
|
||||
pass = state.authorization.pass
|
||||
server = state.authorization.server
|
||||
|
||||
case Farmbot.Auth.login(email, pass, server) do
|
||||
{:ok, token} ->
|
||||
Logger.debug("Got Token!")
|
||||
auth = Map.merge(state.authorization,
|
||||
%{email: email, pass: pass, server: server, token: token,
|
||||
network: network})
|
||||
set_time
|
||||
Farmbot.node_reset(ip_addr)
|
||||
{:noreply,
|
||||
Map.put(state, :authorization, auth)
|
||||
|> Map.put(:informational_settings, new_info)
|
||||
}
|
||||
# If the bot is faster than your router (often) this can happen.
|
||||
{:error, "enetunreach"} ->
|
||||
Logger.warn("Something super weird happened.. Probably a race condition.")
|
||||
# Just crash ourselves and try again.
|
||||
handle_info({:connected, network, ip_addr}, state)
|
||||
error ->
|
||||
Logger.error("Something bad happened when logging in!: #{inspect error}")
|
||||
Farmbot.factory_reset
|
||||
{:noreply, state}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -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.BotState.Network.State, as: Network
|
||||
alias Farmbot.Scheduler.State.Serializer, as: Scheduler
|
||||
|
||||
defmodule Farmbot.BotState.Monitor do
|
||||
|
@ -17,12 +18,14 @@ defmodule Farmbot.BotState.Monitor do
|
|||
hardware: Hardware.t,
|
||||
configuration: Configuration.t,
|
||||
authorization: Authorization.t,
|
||||
network: Network.t,
|
||||
scheduler: Scheduler.t
|
||||
}
|
||||
defstruct [
|
||||
hardware: %Hardware{},
|
||||
configuration: %Configuration{},
|
||||
authorization: %Authorization{},
|
||||
network: %Network{},
|
||||
scheduler: %Scheduler{}
|
||||
]
|
||||
end
|
||||
|
@ -66,6 +69,12 @@ defmodule Farmbot.BotState.Monitor do
|
|||
dispatch(mgr, new_state)
|
||||
end
|
||||
|
||||
# When we get a state update from Scheduler
|
||||
def handle_cast(%Network{} = new_things, {mgr, state}) do
|
||||
new_state = %State{state | network: new_things}
|
||||
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}
|
||||
|
@ -81,7 +90,7 @@ defmodule Farmbot.BotState.Monitor do
|
|||
do
|
||||
Farmbot.BotState.update_config("timezone", timezone)
|
||||
Farmbot.BotState.add_creds({email,password,server})
|
||||
NetMan.connect(:ethernet, Farmbot.BotState.Configuration)
|
||||
NetMan.connect(:ethernet, Farmbot.BotState.Network)
|
||||
dispatch(mgr,state)
|
||||
end
|
||||
|
||||
|
@ -94,7 +103,7 @@ defmodule Farmbot.BotState.Monitor do
|
|||
do
|
||||
Farmbot.BotState.update_config("timezone", timezone)
|
||||
Farmbot.BotState.add_creds({email,password,server})
|
||||
NetMan.connect({ssid, psk}, Farmbot.BotState.Configuration)
|
||||
NetMan.connect({ssid, psk}, Farmbot.BotState.Network)
|
||||
dispatch(mgr,state)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
defmodule Farmbot.BotState.Supervisor do
|
||||
use Supervisor
|
||||
require Logger
|
||||
def init(_args) do
|
||||
def init(initial_config)
|
||||
do
|
||||
children = [
|
||||
worker(GenEvent, [[name: BotStateEventManager]], [id: BotStateEventManager]),
|
||||
worker(Farmbot.BotState.Monitor, [BotStateEventManager], []),
|
||||
worker(Farmbot.BotState.Configuration, [initial_config], []),
|
||||
worker(Farmbot.BotState.Hardware, [[]], []),
|
||||
worker(Farmbot.BotState.Configuration, [[]], []),
|
||||
worker(Farmbot.BotState.Authorization, [[]], [])
|
||||
worker(Farmbot.BotState.Authorization, [[]], []),
|
||||
worker(Farmbot.BotState.Network, [[]], [])
|
||||
]
|
||||
opts = [strategy: :one_for_one, name: __MODULE__]
|
||||
supervise(children, opts)
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
defmodule Farmbot.BotState.Authorization do
|
||||
defmodule State do
|
||||
@type t :: %__MODULE__{
|
||||
token: map,
|
||||
email: String.t,
|
||||
pass: String.t,
|
||||
server: String.t,
|
||||
network: any
|
||||
token: map | nil,
|
||||
secret: nil | binary,
|
||||
server: nil,
|
||||
interim: nil | %{
|
||||
email: String.t,
|
||||
pass: String.t
|
||||
}
|
||||
}
|
||||
defstruct [
|
||||
token: nil,
|
||||
email: nil,
|
||||
pass: nil,
|
||||
secret: nil,
|
||||
server: nil,
|
||||
network: nil
|
||||
interim: %{
|
||||
email: nil,
|
||||
pass: nil
|
||||
}
|
||||
]
|
||||
|
||||
@spec broadcast(t) :: t
|
||||
|
@ -37,6 +41,31 @@ defmodule Farmbot.BotState.Authorization do
|
|||
dispatch :unhandled, state
|
||||
end
|
||||
|
||||
# def handle_cast(:connected, %State{} = state)
|
||||
# when state.interim |> is_nil or state.server |> is_nil
|
||||
# do
|
||||
# Logger.error("AUTH STATE IS MESSED UP")
|
||||
# end
|
||||
|
||||
# I CAN DO BETTER
|
||||
def handle_cast(:connected, %State{} = state) do
|
||||
# {:ok, pub_key} <- get_public_key(server),
|
||||
# {:ok, encryped} <- encrypt(email,pass,pub_key),
|
||||
# do: get_token_from_server(encryped, server)
|
||||
with {:ok, pub_key} <- Farmbot.Auth.get_public_key(state.server),
|
||||
{:ok, secret } <- Farmbot.Auth.encrypt(state.interim.email, state.interim.pass, pub_key),
|
||||
{:ok, token } <- Farmbot.Auth.get_token_from_server(secret, state.server),
|
||||
do: dispatch %State{state | interim: nil, token: token, secret: secret}
|
||||
end
|
||||
|
||||
def handle_cast({:creds, {email, pass, server}}, %State{} = state) do
|
||||
new_state = %State{state | interim: %{ email: email,
|
||||
pass: pass },
|
||||
token: nil,
|
||||
server: server}
|
||||
dispatch new_state
|
||||
end
|
||||
|
||||
def handle_cast(event, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CAST!: #{inspect event}", [__MODULE__])
|
||||
dispatch state
|
||||
|
|
|
@ -2,13 +2,37 @@ defmodule Farmbot.BotState.Configuration do
|
|||
defmodule State do
|
||||
@type t :: %__MODULE__{
|
||||
locks: list(String.t),
|
||||
configuration: map,
|
||||
informational_settings: map
|
||||
configuration: %{
|
||||
os_auto_update: boolean,
|
||||
fw_auto_update: boolean,
|
||||
timezone: String.t | nil,
|
||||
steps_per_mm: integer
|
||||
},
|
||||
informational_settings: %{
|
||||
controller_version: String.t,
|
||||
private_ip: nil | String.t,
|
||||
throttled: String.t,
|
||||
target: String.t,
|
||||
compat_version: integer,
|
||||
environment: :prod | :dev | :test
|
||||
}
|
||||
}
|
||||
defstruct [
|
||||
locks: [],
|
||||
configuration: %{},
|
||||
informational_settings: %{},
|
||||
configuration: %{
|
||||
os_auto_update: false,
|
||||
fw_auto_update: false,
|
||||
timezone: nil,
|
||||
steps_per_mm: 500
|
||||
},
|
||||
informational_settings: %{
|
||||
controller_version: "loading...",
|
||||
compat_version: -1,
|
||||
target: "loading...",
|
||||
environment: :loading,
|
||||
private_ip: nil,
|
||||
throttled: "loading..."
|
||||
},
|
||||
]
|
||||
|
||||
@spec broadcast(t) :: t
|
||||
|
@ -20,8 +44,21 @@ defmodule Farmbot.BotState.Configuration do
|
|||
|
||||
use GenServer
|
||||
require Logger
|
||||
def init(_args) do
|
||||
{:ok, State.broadcast(%State{})}
|
||||
def init(%{compat_version: compat_version,
|
||||
env: env,
|
||||
target: target,
|
||||
version: version})
|
||||
do
|
||||
initial_state = %State{
|
||||
informational_settings: %{
|
||||
controller_version: version,
|
||||
compat_version: compat_version,
|
||||
target: target,
|
||||
environment: env,
|
||||
throttled: get_throttled
|
||||
}}
|
||||
IO.inspect initial_state
|
||||
{:ok, State.broadcast(initial_state)}
|
||||
end
|
||||
|
||||
def start_link(args) do
|
||||
|
@ -35,25 +72,25 @@ defmodule Farmbot.BotState.Configuration do
|
|||
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}
|
||||
dispatch true, %State{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}
|
||||
dispatch true, %State{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}
|
||||
dispatch true, %State{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}
|
||||
dispatch true, %State{state | configuration: new_config}
|
||||
end
|
||||
|
||||
def handle_call({:update_config, key, _value}, _from, %State{} = state) do
|
||||
|
@ -80,4 +117,13 @@ defmodule Farmbot.BotState.Configuration do
|
|||
State.broadcast(state)
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
def get_throttled do
|
||||
{output, 0} = System.cmd("vcgencmd", ["get_throttled"])
|
||||
{"throttled=0x0\n", 0}
|
||||
[_, throttled] = output
|
||||
|> String.strip
|
||||
|> String.split("=")
|
||||
throttled
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,11 +41,55 @@ defmodule Farmbot.BotState.Hardware do
|
|||
GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
def handle_call({:get_pin, pin_number}, _from, %State{} = state) do
|
||||
dispatch Map.get(state.pins, Integer.to_string(pin_number)), state
|
||||
end
|
||||
|
||||
def handle_call(:get_current_pos, _from, %State{} = state) do
|
||||
dispatch state.location, 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({:set_pos, {x, y, z}}, %State{} = state) do
|
||||
dispatch %State{state | location: [x,y,z]}
|
||||
end
|
||||
|
||||
def handle_cast({:set_pin_value, {pin, value}}, %State{} = state) do
|
||||
pin_state = state.pins
|
||||
new_pin_value =
|
||||
case Map.get(pin_state, Integer.to_string(pin)) do
|
||||
nil ->
|
||||
%{mode: -1, value: value}
|
||||
%{mode: mode, value: _} ->
|
||||
%{mode: mode, value: value}
|
||||
end
|
||||
# I REALLY don't want this to be here.
|
||||
# spawn fn -> Farmbot.Logger.log("PIN #{pin} set: #{new_pin_value.value}", [], ["BotControl"]) end
|
||||
new_pin_state = Map.put(pin_state, Integer.to_string(pin), new_pin_value)
|
||||
dispatch %State{state | pins: new_pin_state}
|
||||
end
|
||||
|
||||
def handle_cast({:set_pin_mode, {pin, mode}}, %State{} = state) do
|
||||
pin_state = state.pins
|
||||
new_pin_value =
|
||||
case Map.get(pin_state, Integer.to_string(pin)) do
|
||||
nil -> %{mode: mode, value: -1}
|
||||
%{mode: _, value: value} -> %{mode: mode, value: value}
|
||||
end
|
||||
new_pin_state = Map.put(pin_state, Integer.to_string(pin), new_pin_value)
|
||||
dispatch %State{state | pins: new_pin_state}
|
||||
end
|
||||
|
||||
def handle_cast({:set_param, {param_string, value} }, %State{} = state) do
|
||||
new_params = Map.put(state.mcu_params, param_string, value)
|
||||
dispatch %State{state | mcu_params: new_params}
|
||||
end
|
||||
|
||||
# catch all.
|
||||
def handle_cast(event, %State{} = state) do
|
||||
Logger.warn("[#{__MODULE__}] UNHANDLED CAST!: #{inspect event}", [__MODULE__])
|
||||
dispatch state
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
defmodule Farmbot.BotState.Network do
|
||||
@moduledoc """
|
||||
I DONT KNOW WHAT IM DOING
|
||||
"""
|
||||
defmodule State do
|
||||
@moduledoc false
|
||||
|
||||
defstruct [
|
||||
connected?: false,
|
||||
connection: nil
|
||||
]
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
connected?: boolean,
|
||||
connection: :ethernet | {String.t, String.t}
|
||||
}
|
||||
|
||||
@spec broadcast(t) :: t
|
||||
def broadcast(%State{} = state) do
|
||||
GenServer.cast(Farmbot.BotState.Monitor, state)
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
use GenServer
|
||||
require Logger
|
||||
|
||||
def init(_args) do
|
||||
NetMan.put_pid(__MODULE__)
|
||||
{:ok, State.broadcast(%State{})}
|
||||
end
|
||||
|
||||
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({:connected, connection, ip_address}, %State{} = state) do
|
||||
# UPDATE CONFIGURATION WITH THE IP ADDRESS
|
||||
GenServer.cast(Farmbot.BotState.Authorization, :connected)
|
||||
dispatch %State{state | connected?: true, connection: connection}
|
||||
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
|
|
@ -15,7 +15,7 @@ defmodule Command.Tracker do
|
|||
|
||||
# When we get a successful message, reset the counter.
|
||||
def handle_cast(:done, _) do
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
{:noreply, 0}
|
||||
end
|
||||
|
||||
|
@ -26,7 +26,7 @@ defmodule Command.Tracker do
|
|||
# If the message is not successful, and count is less than three,
|
||||
# increase it.
|
||||
def handle_cast(issue, count) when count < 2 do
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
Farmbot.Logger.log("Problem writing command! #{inspect issue}", [:error_toast], [@tag])
|
||||
{:noreply, count + 1}
|
||||
end
|
||||
|
|
|
@ -110,9 +110,9 @@ defmodule Farmbot.RPC.Handler do
|
|||
@doc """
|
||||
Builds a json to send to the frontend
|
||||
"""
|
||||
@spec build_status :: binary
|
||||
def build_status do
|
||||
unserialized = GenEvent.call(BotStateEventManager, __MODULE__, :state)
|
||||
@spec build_status(Farmbot.BotState.Monitor.State.t) :: binary
|
||||
def build_status(unserialized) do
|
||||
# unserialized = GenEvent.call(BotStateEventManager, __MODULE__, :state)
|
||||
m = %Notification{
|
||||
id: nil,
|
||||
method: "status_update",
|
||||
|
@ -120,13 +120,13 @@ defmodule Farmbot.RPC.Handler do
|
|||
Poison.encode!(m)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Sends the status message over whatever transport.
|
||||
"""
|
||||
@spec send_status :: :ok | {:error, atom}
|
||||
def send_status do
|
||||
build_status |> @transport.emit
|
||||
end
|
||||
# @doc """
|
||||
# Sends the status message over whatever transport.
|
||||
# """
|
||||
# @spec send_status :: :ok | {:error, atom}
|
||||
# def send_status do
|
||||
# build_status |> @transport.emit
|
||||
# end
|
||||
|
||||
@doc """
|
||||
Takes the cached bot state, and then
|
||||
|
@ -156,6 +156,7 @@ defmodule Farmbot.RPC.Handler do
|
|||
|
||||
# Event from BotState.
|
||||
def handle_event({:dispatch, state}, _) do
|
||||
build_status(state) |> @transport.emit
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ defmodule Farmbot.RPC.Requests do
|
|||
# Read status
|
||||
def handle_request("read_status", _) do
|
||||
Logger.debug("Reporting Current Status")
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# FIXME
|
||||
end
|
||||
|
||||
def handle_request("check_updates", _) do
|
||||
|
@ -134,11 +134,11 @@ defmodule Farmbot.RPC.Requests do
|
|||
do
|
||||
{_, []} ->
|
||||
Farmbot.Logger.log("MCU params updated.", [:success_toast], ["RPCHANDLER"])
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
:ok
|
||||
{_, failed} ->
|
||||
Farmbot.Logger.log("MCU params failed: #{inspect failed}", [:error_toast], ["RPCHANDLER"])
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
@ -149,11 +149,11 @@ defmodule Farmbot.RPC.Requests do
|
|||
end) do
|
||||
{_, []} ->
|
||||
Farmbot.Logger.log("Bot Configs updated.", [:success_toast], ["RPCHANDLER"])
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
:ok
|
||||
{_, failed} ->
|
||||
Farmbot.Logger.log("Bot Configs failed: #{inspect failed}", [:error_toast], ["RPCHANDLER"])
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
@ -174,7 +174,7 @@ defmodule Farmbot.RPC.Requests do
|
|||
Farmbot.Sync.sync()
|
||||
regimen = Farmbot.Sync.get_regimen(id)
|
||||
Farmbot.Scheduler.add_regimen(regimen)
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
end
|
||||
|
||||
def handle_request("start_regimen", params) do
|
||||
|
|
|
@ -13,8 +13,6 @@ defmodule Serialized do
|
|||
configuration: %{},
|
||||
informational_settings: %{},
|
||||
|
||||
authorization: %{}, # DELETEME
|
||||
|
||||
# farm scheduler
|
||||
farm_scheduler: %Farmbot.Scheduler.State.Serializer{}
|
||||
]
|
||||
|
|
|
@ -3,8 +3,9 @@ defmodule Farmbot.RPC.Transport.Mqtt do
|
|||
require Logger
|
||||
|
||||
def init(_args) do
|
||||
Logger.debug("MQTT INIT")
|
||||
Process.flag(:trap_exit, true)
|
||||
{:ok, client} = Mqtt.Client.start_link(%{parent: __MODULE__})
|
||||
{:ok, client} = Mqtt.Client.start_link(%{parent: self()})
|
||||
case Farmbot.Auth.get_token do
|
||||
{:ok, token} ->
|
||||
login(token)
|
||||
|
@ -39,18 +40,20 @@ defmodule Farmbot.RPC.Transport.Mqtt do
|
|||
|
||||
def handle_info(:login, {client, token})
|
||||
when is_pid(client) do
|
||||
Mqtt.Client.connect(client, connect_options(token))
|
||||
Logger.debug("Trying to sign into MQTT")
|
||||
resp = Mqtt.Client.connect(client, connect_options(token))
|
||||
Logger.debug("FINDME: #{inspect resp}")
|
||||
{:noreply, {client, token}}
|
||||
end
|
||||
|
||||
def handle_info({:EXIT, pid, _reason}, {client, token})
|
||||
def handle_info({:EXIT, pid, reason}, {client, token})
|
||||
when pid == client do
|
||||
Logger.error("Hulaki died.")
|
||||
Logger.error("Hulaki died: #{inspect reason}")
|
||||
{:crashme, {client, token}}
|
||||
end
|
||||
|
||||
def handle_info({:EXIT, _pid, _reason}, {client, token}) do
|
||||
Logger.warn("something. died.")
|
||||
def handle_info({:EXIT, pid, reason}, {client, token}) do
|
||||
Logger.warn("something in mqtt.ex died: #{inspect pid}: #{inspect reason}")
|
||||
{:noreply, {client, token}}
|
||||
end
|
||||
|
||||
|
@ -101,16 +104,17 @@ defmodule Farmbot.RPC.Transport.Mqtt do
|
|||
mqtt_user = Map.get(token, "unencoded") |> Map.get("bot")
|
||||
mqtt_pass = Map.get(token, "encoded")
|
||||
[client_id: mqtt_user,
|
||||
username: mqtt_user,
|
||||
password: mqtt_pass,
|
||||
host: mqtt_host,
|
||||
port: 1883,
|
||||
timeout: 5000,
|
||||
keep_alive: 500,
|
||||
will_topic: "bot/#{bot(token)}/from_device",
|
||||
will_message: build_last_will_message,
|
||||
will_qos: 0,
|
||||
will_retain: 0]
|
||||
username: mqtt_user,
|
||||
password: mqtt_pass,
|
||||
host: mqtt_host, # mqtt.farmbot.io
|
||||
port: 1883,
|
||||
# port: 8883,
|
||||
timeout: 5000,
|
||||
keep_alive: 500,
|
||||
will_topic: "bot/#{bot(token)}/from_device",
|
||||
will_message: build_last_will_message,
|
||||
will_qos: 0,
|
||||
will_retain: 0]
|
||||
end
|
||||
|
||||
## ##
|
||||
|
@ -147,11 +151,6 @@ defmodule Farmbot.RPC.Transport.Mqtt do
|
|||
{:reply, :ok, {client, token}}
|
||||
end
|
||||
|
||||
def handle_call(thing, _from, {client, token}) do
|
||||
Logger.debug("Unhandled Thing #{inspect thing}")
|
||||
{:reply, :ok, {client, token}}
|
||||
end
|
||||
|
||||
### ###
|
||||
# THESE ARE ALL UNUSED CALLBACKS FROM THE MQTT_CLIENT #
|
||||
### ###
|
||||
|
@ -204,4 +203,9 @@ defmodule Farmbot.RPC.Transport.Mqtt do
|
|||
def handle_call({:subscribe, _message}, _from, {client, token}) do
|
||||
{:reply, :ok, {client, token}}
|
||||
end
|
||||
|
||||
def handle_call(thing, _from, {client, token}) do
|
||||
Logger.debug("Unhandled Thing #{inspect thing}")
|
||||
{:reply, :ok, {client, token}}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -163,7 +163,7 @@ defmodule Regimen.VM do
|
|||
msg = "Regimen: #{state.regimen.name} completed without errors!"
|
||||
Logger.debug(msg)
|
||||
Farmbot.Logger.log(msg, [:ticker, :success_toast], ["RegimenManager"])
|
||||
Farmbot.RPC.Handler.send_status
|
||||
# Farmbot.RPC.Handler.send_status
|
||||
end
|
||||
|
||||
# this gets called if the scheduler crashes.
|
||||
|
|
4
mix.exs
4
mix.exs
|
@ -88,10 +88,10 @@ defmodule Farmbot.Mixfile do
|
|||
{:hulaaki, github: "ConnorRigby/hulaaki"},
|
||||
{:mustache, "~> 0.0.2"},
|
||||
{:timex, "~> 3.0"},
|
||||
{:farmbot_auth, github: "Farmbot/farmbot_auth"},
|
||||
# {:farmbot_auth, github: "Farmbot/farmbot_auth"},
|
||||
{:farmbot_auth, path: "../farmbot_auth"},
|
||||
# {:farmbot_configurator, github: "Farmbot/farmbot_configurator"}
|
||||
{:farmbot_configurator, path: "../farmbot_configurator"}
|
||||
# {:farmbot_auth, path: "../farmbot_auth"}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue