feat: wait for enrolled sensors to announce, factory reset them on deletion
This commit is contained in:
@@ -55,6 +55,8 @@ defmodule Localiser.Domain.Sensors do
|
||||
end
|
||||
|
||||
def delete_sensor(%Sensor{} = sensor) do
|
||||
topic = "localiser/sensor/#{sensor.sensor_id}/cmd"
|
||||
Localiser.MQTT.Connection.publish(topic, Jason.encode!(%{command: "factory_reset"}))
|
||||
Repo.delete(sensor)
|
||||
end
|
||||
|
||||
@@ -89,14 +91,45 @@ defmodule Localiser.Domain.Sensors do
|
||||
|
||||
# Sensor lifecycle / enrollment helpers
|
||||
|
||||
@enrollment_timeout_ms Application.compile_env(:localiser, :enrollment_timeout_ms, 10_000)
|
||||
|
||||
# Called by the phone app to indicate a sensor is about to come online.
|
||||
# Creates an unconfirmed sensor record and starts a timeout Task.
|
||||
def expect_sensor(sensor_id) do
|
||||
result =
|
||||
%Sensor{}
|
||||
|> Sensor.changeset(%{sensor_id: sensor_id, confirmed: false})
|
||||
|> Repo.insert(
|
||||
on_conflict: [set: [confirmed: false, updated_at: DateTime.utc_now()]],
|
||||
conflict_target: :sensor_id,
|
||||
returning: true
|
||||
)
|
||||
|
||||
case result do
|
||||
{:ok, sensor} ->
|
||||
Phoenix.PubSub.broadcast(Localiser.PubSub, "sensors", {:sensor_expected, sensor})
|
||||
Task.start(fn ->
|
||||
Process.sleep(@enrollment_timeout_ms)
|
||||
fresh = Repo.get_by(Sensor, sensor_id: sensor_id)
|
||||
if fresh && !fresh.confirmed do
|
||||
Phoenix.PubSub.broadcast(Localiser.PubSub, "sensors", {:sensor_enrollment_timeout, sensor_id})
|
||||
end
|
||||
end)
|
||||
{:ok, sensor}
|
||||
|
||||
error ->
|
||||
error
|
||||
end
|
||||
end
|
||||
|
||||
# Called when an ESP board self-announces on MQTT. Inserts a new unplaced sensor
|
||||
# record, or bumps updated_at if the sensor_id already exists.
|
||||
# record, or marks it confirmed if the sensor_id already exists.
|
||||
def upsert_announced(sensor_id) do
|
||||
result =
|
||||
%Sensor{}
|
||||
|> Sensor.changeset(%{sensor_id: sensor_id})
|
||||
|> Sensor.changeset(%{sensor_id: sensor_id, confirmed: true})
|
||||
|> Repo.insert(
|
||||
on_conflict: [set: [updated_at: DateTime.utc_now()]],
|
||||
on_conflict: [set: [confirmed: true, updated_at: DateTime.utc_now()]],
|
||||
conflict_target: :sensor_id,
|
||||
returning: true
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user