farmbot_os/farmbot_core/lib/farmbot_core/asset_workers/device_worker.ex

90 lines
2.5 KiB
Elixir

defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.Device do
alias FarmbotCore.{Asset, Asset.Device}
alias FarmbotCeleryScript.AST
use GenServer
require FarmbotCore.Logger
def tracks_changes?(%Device{}), do: true
def preload(%Device{}), do: []
def start_link(%Device{} = device, _args) do
GenServer.start_link(__MODULE__, %Device{} = device)
end
def init(%Device{} = device) do
send(self(), :check_factory_reset)
{:ok, %Device{} = device, 0}
end
def handle_info(:timeout, %Device{} = device) do
{:noreply, device}
end
def handle_info(:check_factory_reset, %Device{needs_reset: true} = state) do
ast =
AST.Factory.new()
|> AST.Factory.rpc_request("RESET_DEVICE_NOW")
|> AST.Factory.factory_reset("farmbot_os")
:ok = FarmbotCeleryScript.execute(ast, make_ref())
{:noreply, state}
end
def handle_info(:check_factory_reset, state) do
{:noreply, state}
end
def handle_info({:step_complete, _ref, _}, state) do
{:noreply, state}
end
def handle_cast({:new_data, new_device}, old_device) do
_ = log_changes(new_device, old_device)
send(self(), :check_factory_reset)
{:noreply, new_device}
end
def log_changes(new_device, old_device) do
interesting_params = [
:ota_hour,
:mounted_tool_id
]
new_interesting_device = Map.take(new_device, interesting_params) |> MapSet.new()
old_interesting_device = Map.take(old_device, interesting_params) |> MapSet.new()
difference = MapSet.difference(new_interesting_device, old_interesting_device)
Enum.each(difference, fn
{:ota_hour, nil} ->
FarmbotCore.Logger.success(1, "Farmbot will apply updates as soon as possible")
{:ota_hour, hour} ->
FarmbotCore.Logger.success(1, "Farmbot will apply updates during the hour of #{hour}:00")
{:mounted_tool_id, nil} ->
if old_device.mounted_tool_id do
if tool = Asset.get_tool(id: old_device.mounted_tool_id) do
FarmbotCore.Logger.info(2, "Farmbot dismounted #{tool.name}")
else
FarmbotCore.Logger.info(2, "Farmbot dismounted unknown tool")
end
else
# no previously mounted tool
:ok
end
{:mounted_tool_id, id} ->
if tool = Asset.get_tool(id: id) do
FarmbotCore.Logger.info(2, "Farmbot mounted #{tool.name}")
else
FarmbotCore.Logger.info(2, "Farmbot mounted unknown tool")
end
{_key, _value} ->
:noop
end)
end
end