fix a couple DB stuffs, start work on farmware runtimne
parent
09a3d69771
commit
cf02cc35d2
|
@ -144,6 +144,12 @@ defmodule Farmbot.BotState do
|
|||
GenServer.call(context.configuration, {:update_config, "user_env", map})
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the user environment.
|
||||
"""
|
||||
@spec get_user_env(context) :: map
|
||||
def get_user_env(%Context{} = ctx), do: get_config(ctx, :user_env)
|
||||
|
||||
@doc """
|
||||
Locks the bot
|
||||
"""
|
||||
|
|
|
@ -5,7 +5,16 @@ defmodule Farmbot.CeleryScript.Command.DataUpdate do
|
|||
|
||||
alias Farmbot.CeleryScript.Command
|
||||
alias Farmbot.Database
|
||||
require Logger
|
||||
alias Database.Syncable.{
|
||||
Device,
|
||||
FarmEvent,
|
||||
Peripheral,
|
||||
Point,
|
||||
Regimen,
|
||||
Sequence,
|
||||
Tool
|
||||
}
|
||||
use Farmbot.DebugLog
|
||||
@behaviour Command
|
||||
|
||||
@typedoc """
|
||||
|
@ -24,8 +33,12 @@ defmodule Farmbot.CeleryScript.Command.DataUpdate do
|
|||
verb = parse_verb_str(verb)
|
||||
Enum.each(pairs, fn(%{args: %{label: s, value: nowc}}) ->
|
||||
syncable = s |> parse_syncable_str()
|
||||
value = nowc |> parse_val_str()
|
||||
:ok = Database.set_awaiting(context, syncable, verb, value)
|
||||
if syncable do
|
||||
value = nowc |> parse_val_str()
|
||||
:ok = Database.set_awaiting(context, syncable, verb, value)
|
||||
else
|
||||
:ok
|
||||
end
|
||||
end)
|
||||
context
|
||||
end
|
||||
|
@ -34,10 +47,19 @@ defmodule Farmbot.CeleryScript.Command.DataUpdate do
|
|||
@type syncable :: Farmbot.Database.syncable
|
||||
|
||||
@spec parse_syncable_str(binary) :: syncable
|
||||
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("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(str) do
|
||||
Module.concat([Farmbot.Database.Syncable, Macro.camelize(str)])
|
||||
debug_log "no such syncable: #{str}"
|
||||
end
|
||||
|
||||
|
||||
@spec parse_val_str(binary) :: number_or_wildcard
|
||||
defp parse_val_str("*"), do: "*"
|
||||
defp parse_val_str(int) when is_integer(int), do: int
|
||||
|
|
|
@ -43,17 +43,6 @@ defmodule Farmbot.Database do
|
|||
@typedoc false
|
||||
@type syncable_object :: map
|
||||
|
||||
@typedoc """
|
||||
State of the DB
|
||||
"""
|
||||
@type state :: %{
|
||||
by_kind_and_id: %{ required({syncable, db_id}) => ref_id },
|
||||
awaiting: %{ required(syncable) => boolean },
|
||||
by_kind: %{ required(syncable) => [ref_id] },
|
||||
refs: %{ required(ref_id) => resource_map },
|
||||
all: [ref_id],
|
||||
}
|
||||
|
||||
# This pulls all the module names by their filename.
|
||||
syncable_modules =
|
||||
"lib/farmbot/database/syncable/"
|
||||
|
@ -78,13 +67,20 @@ defmodule Farmbot.Database do
|
|||
Farmbot.BotState.set_sync_msg(ctx, :syncing)
|
||||
try do
|
||||
for module_name <- all_syncable_modules() do
|
||||
# see: `syncable.ex`. This is some macro magic.
|
||||
debug_log "#{module_name} Sync begin."
|
||||
:ok = module_name.fetch(ctx, {__MODULE__,
|
||||
:commit_records, [ctx, module_name]})
|
||||
if get_awaiting(ctx, module_name) do
|
||||
# see: `syncable.ex`. This is some macro magic.
|
||||
debug_log "#{module_name} Sync begin."
|
||||
:ok = module_name.fetch(ctx, {__MODULE__,
|
||||
:commit_records, [ctx, module_name]})
|
||||
|
||||
debug_log "#{module_name} Sync finish."
|
||||
:ok = unset_awaiting(ctx, module_name)
|
||||
:ok
|
||||
else
|
||||
debug_log "#{module_name} already up to date."
|
||||
:ok
|
||||
end
|
||||
|
||||
debug_log "#{module_name} Sync finish."
|
||||
:ok
|
||||
end
|
||||
Farmbot.BotState.set_sync_msg(ctx, :synced)
|
||||
:ok
|
||||
|
@ -164,6 +160,38 @@ defmodule Farmbot.Database do
|
|||
|
||||
## GenServer
|
||||
|
||||
defmodule State do
|
||||
@moduledoc false
|
||||
alias Farmbot.Database.DB
|
||||
|
||||
defimpl Inspect, for: __MODULE__ do
|
||||
def inspect(thing, _) do
|
||||
"#DatabaseState<#{inspect thing.all}>"
|
||||
end
|
||||
end
|
||||
|
||||
defstruct [
|
||||
:by_kind_and_id,
|
||||
:awaiting,
|
||||
:by_kind,
|
||||
:refs,
|
||||
:all
|
||||
]
|
||||
|
||||
@type t :: %{
|
||||
by_kind_and_id: %{ required({DB.syncable, DB.db_id}) => DB.ref_id },
|
||||
awaiting: %{ required(DB.syncable) => boolean },
|
||||
by_kind: %{ required(DB.syncable) => [DB.ref_id] },
|
||||
refs: %{ required(DB.ref_id) => DB.resource_map },
|
||||
all: [DB.ref_id],
|
||||
}
|
||||
end
|
||||
|
||||
@typedoc """
|
||||
State of the DB
|
||||
"""
|
||||
@type state :: State.t
|
||||
|
||||
@doc """
|
||||
Start the Database
|
||||
"""
|
||||
|
@ -176,7 +204,7 @@ defmodule Farmbot.Database do
|
|||
initial_refs = %{}
|
||||
initial_all = []
|
||||
|
||||
state = %{
|
||||
state = %State{
|
||||
by_kind_and_id: initial_by_kind_and_id,
|
||||
awaiting: initial_awaiting,
|
||||
by_kind: initial_by_kind,
|
||||
|
|
|
@ -3,13 +3,28 @@ defmodule Farmbot.Farmware.Runtime do
|
|||
Executes a farmware
|
||||
"""
|
||||
use Farmbot.DebugLog
|
||||
alias Farmbot.{Farmware, Context}
|
||||
alias Farmbot.{Farmware, Context, BotState, Auth}
|
||||
alias Farmware.RuntimeError, as: FarmwareRuntimeError
|
||||
|
||||
@doc """
|
||||
Executes a Farmware inside a safe sandbox
|
||||
"""
|
||||
def execute(%Context{} = _ctx, %Farmware{} = _fw) do
|
||||
raise FarmwareRuntimeError, "Farmware Runtime todo!"
|
||||
def execute(%Context{} = ctx, %Farmware{} = fw) do
|
||||
debug_log "Starting execution of #{inspect fw}"
|
||||
env = environment(ctx)
|
||||
|
||||
end
|
||||
|
||||
defp environment(%Context{} = ctx) do
|
||||
envs = BotState.get_user_env(ctx)
|
||||
{:ok, %Farmbot.Token{} = tkn} = Auth.get_token(ctx.auth)
|
||||
envs = Map.put(envs, "API_TOKEN", tkn)
|
||||
Enum.map(envs, fn({key, val}) ->
|
||||
{to_erl_safe(key), to_erl_safe(val)}
|
||||
end)
|
||||
end
|
||||
|
||||
defp to_erl_safe(%Farmbot.Token{encoded: enc}), do: to_erl_safe(enc)
|
||||
defp to_erl_safe(binary) when is_binary(binary), do: to_charlist(binary)
|
||||
defp to_erl_safe(map) when is_map(map), do: map |> Poison.encode! |> to_erl_safe()
|
||||
end
|
||||
|
|
|
@ -8,7 +8,8 @@ defmodule Module.concat([Farmbot,System,"host"]) do
|
|||
def factory_reset(reason) do
|
||||
files = path() |> File.ls!()
|
||||
Farmbot.System.FS.transaction fn() ->
|
||||
File.rm_rf files
|
||||
File.rm_rf! "#{path()}"
|
||||
File.mkdir_p! "#{path()}"
|
||||
File.write("#{path()}/factory_reset_reason", reason)
|
||||
end, true
|
||||
System.halt(0)
|
||||
|
|
|
@ -49,6 +49,9 @@ defmodule Farmbot.Transport.GenMqtt.Client do
|
|||
|> Poison.decode!
|
||||
|> Ast.parse
|
||||
|> Command.do_command(context)
|
||||
catch
|
||||
:exit, thing ->
|
||||
debug_log "caught a stray exit: #{inspect thing}"
|
||||
rescue
|
||||
e ->
|
||||
Logger.error ">> Saved mqtt client from cs death: #{inspect e}"
|
||||
|
|
|
@ -36,14 +36,13 @@ defmodule Logger.Backends.FarmbotLogger do
|
|||
"""
|
||||
@type logger_level
|
||||
:: :info
|
||||
| :debug
|
||||
| :warn
|
||||
| :error
|
||||
|
||||
@typedoc """
|
||||
One day this will me more
|
||||
"""
|
||||
@type channel :: :toast
|
||||
@type channel :: :toast | :email
|
||||
|
||||
@type log_message
|
||||
:: %{message: String.t,
|
||||
|
@ -109,7 +108,7 @@ defmodule Logger.Backends.FarmbotLogger do
|
|||
@spec do_post(Context.t, [log_message]) :: no_return
|
||||
defp do_post(%Context{} = ctx, logs) do
|
||||
try do
|
||||
HTTP.post(ctx, "/api/logs", Poison.encode!(logs))
|
||||
{:ok, %{status_code: 200}} = HTTP.post(ctx, "/api/logs", Poison.encode!(logs))
|
||||
GenEvent.call(Elixir.Logger, __MODULE__, :post_success)
|
||||
rescue
|
||||
_ -> GenEvent.call(Elixir.Logger, __MODULE__, :post_fail)
|
||||
|
@ -218,6 +217,10 @@ defmodule Logger.Backends.FarmbotLogger do
|
|||
end
|
||||
|
||||
@spec build_log(String.t, number, rpc_log_type, [channel]) :: log_message
|
||||
defp build_log(message, created_at, :debug, channels) do
|
||||
build_log(message, created_at, :info, channels)
|
||||
end
|
||||
|
||||
defp build_log(message, created_at, type, channels) do
|
||||
%{message: message,
|
||||
created_at: created_at,
|
||||
|
|
Loading…
Reference in New Issue