farmbot_os/farmbot_core/lib/farmbot_core/asset/persistent_regimen.ex

58 lines
1.8 KiB
Elixir

defmodule Farmbot.Asset.PersistentRegimen do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:local_id, :binary_id, autogenerate: true}
@timestamps_opts inserted_at: :created_at, type: :utc_datetime
schema "persistent_regimens" do
belongs_to(:regimen, Farmbot.Asset.Regimen, references: :local_id, type: :binary_id)
belongs_to(:farm_event, Farmbot.Asset.FarmEvent, references: :local_id, type: :binary_id)
field(:epoch, :utc_datetime)
field(:started_at, :utc_datetime)
field(:next, :utc_datetime)
# Can't use references here.
field(:next_sequence_id, :id)
field(:monitor, :boolean, default: true)
timestamps()
end
def changeset(persistent_regimen, params \\ %{}) do
persistent_regimen
|> cast(params, [:started_at, :next, :next_sequence_id, :monitor])
|> put_epoch()
|> cast_assoc(:regimen)
|> cast_assoc(:farm_event)
end
defp put_epoch(%{valid?: true} = changeset) do
started_at = get_field(changeset, :started_at) || DateTime.utc_now()
if get_field(changeset, :epoch) do
changeset
else
case build_epoch(started_at) do
{:ok, epoch} -> put_change(changeset, :epoch, epoch)
:error -> add_error(changeset, :epoch, "Missing timezone")
end
end
end
defp put_epoch(changeset), do: changeset
# returns midnight of today
@spec build_epoch(DateTime.t()) :: DateTime.t()
def build_epoch(%DateTime{} = datetime) do
case Farmbot.Asset.device().timezone do
nil ->
:error
tz ->
%DateTime{} = n = Timex.Timezone.convert(datetime, tz)
opts = [hours: -n.hour, seconds: -n.second, minutes: -n.minute]
localized_epoch = Timex.shift(n, opts)
epoch = Timex.Timezone.convert(localized_epoch, datetime.time_zone)
{:ok, epoch}
end
end
end