71 lines
2.0 KiB
Elixir
71 lines
2.0 KiB
Elixir
defmodule FarmbotCore.Asset.RegimenInstance do
|
|
use Ecto.Schema
|
|
import Ecto.Changeset
|
|
@primary_key {:local_id, :binary_id, autogenerate: true}
|
|
@timestamps_opts inserted_at: :created_at, type: :utc_datetime
|
|
|
|
alias FarmbotCore.Asset.{FarmEvent, Regimen, RegimenInstance.Execution}
|
|
|
|
schema "regimen_instances" do
|
|
belongs_to(:regimen, Regimen,
|
|
type: :binary_id,
|
|
references: :local_id,
|
|
on_replace: :delete
|
|
)
|
|
belongs_to(:farm_event, FarmEvent,
|
|
type: :binary_id,
|
|
references: :local_id,
|
|
on_replace: :delete
|
|
)
|
|
has_many(:executions, Execution,
|
|
on_delete: :delete_all,
|
|
on_replace: :delete)
|
|
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(regimen_instance, params \\ %{}) do
|
|
regimen_instance
|
|
|> cast(params, [:started_at, :next, :next_sequence_id, :monitor, :updated_at])
|
|
|> 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 FarmbotCore.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
|