fix: actually include sensor firmware version string in repo, /version response

This commit is contained in:
2026-05-21 18:29:22 +02:00
parent c9b65c7013
commit 7b02a37abe
5 changed files with 57 additions and 11 deletions
+2 -1
View File
@@ -8,6 +8,7 @@ defmodule Localiser.Domain.Schema.Sensor do
schema "sensors" do schema "sensors" do
field :sensor_id, :string field :sensor_id, :string
field :confirmed, :boolean, default: false field :confirmed, :boolean, default: false
field :firmware_version, :string
field :x, :float field :x, :float
field :y, :float field :y, :float
field :floor_x, :float, virtual: true field :floor_x, :float, virtual: true
@@ -22,7 +23,7 @@ defmodule Localiser.Domain.Schema.Sensor do
@doc false @doc false
def changeset(sensor, attrs) do def changeset(sensor, attrs) do
sensor sensor
|> cast(attrs, [:sensor_id, :confirmed, :room_id, :x, :y]) |> cast(attrs, [:sensor_id, :confirmed, :firmware_version, :room_id, :x, :y])
|> validate_required([:sensor_id]) |> validate_required([:sensor_id])
|> unique_constraint(:sensor_id) |> unique_constraint(:sensor_id)
|> assoc_constraint(:room) |> assoc_constraint(:room)
+35 -5
View File
@@ -59,9 +59,29 @@ defmodule Localiser.Domain.Sensors do
{:ok, sensor} {:ok, sensor}
end end
@version_timeout_ms 5_000
def get_version(%Sensor{} = sensor) do def get_version(%Sensor{} = sensor) do
Localiser.MQTT.Connection.publish(cmd_topic(sensor), Jason.encode!(%{action: "version"})) :ok = Phoenix.PubSub.subscribe(Localiser.PubSub, "sensors")
{:ok, sensor}
case Localiser.MQTT.Connection.publish(cmd_topic(sensor), Jason.encode!(%{action: "version"})) do
:ok ->
result =
receive do
{:sensor_announced, %Sensor{sensor_id: sid, firmware_version: v}}
when sid == sensor.sensor_id and not is_nil(v) ->
{:ok, v}
after
@version_timeout_ms -> {:error, :timeout}
end
Phoenix.PubSub.unsubscribe(Localiser.PubSub, "sensors")
result
error ->
Phoenix.PubSub.unsubscribe(Localiser.PubSub, "sensors")
error
end
end end
def send_ota_update(%Sensor{} = sensor, url, version) do def send_ota_update(%Sensor{} = sensor, url, version) do
@@ -169,12 +189,22 @@ defmodule Localiser.Domain.Sensors do
# Called when an ESP board self-announces on MQTT. Inserts a new unplaced sensor # Called when an ESP board self-announces on MQTT. Inserts a new unplaced sensor
# record, or marks it confirmed if the sensor_id already exists. # record, or marks it confirmed if the sensor_id already exists.
def upsert_announced(sensor_id) do def upsert_announced(sensor_id, firmware_version \\ nil) do
attrs = %{sensor_id: sensor_id, confirmed: true}
attrs = if firmware_version, do: Map.put(attrs, :firmware_version, firmware_version), else: attrs
on_conflict =
if firmware_version do
[set: [confirmed: true, firmware_version: firmware_version, updated_at: DateTime.utc_now()]]
else
[set: [confirmed: true, updated_at: DateTime.utc_now()]]
end
result = result =
%Sensor{} %Sensor{}
|> Sensor.changeset(%{sensor_id: sensor_id, confirmed: true}) |> Sensor.changeset(attrs)
|> Repo.insert( |> Repo.insert(
on_conflict: [set: [confirmed: true, updated_at: DateTime.utc_now()]], on_conflict: on_conflict,
conflict_target: :sensor_id, conflict_target: :sensor_id,
returning: true returning: true
) )
+9 -3
View File
@@ -30,7 +30,7 @@ defmodule Localiser.MQTT.Router do
handle_rssi(sensor_id, payload) handle_rssi(sensor_id, payload)
{:announce, sensor_id} -> {:announce, sensor_id} ->
handle_announce(sensor_id) handle_announce(sensor_id, payload)
{:error, :invalid_topic} -> {:error, :invalid_topic} ->
Logger.debug("[MQTT.Router] Received message with invalid topic: #{topic}") Logger.debug("[MQTT.Router] Received message with invalid topic: #{topic}")
@@ -70,8 +70,14 @@ defmodule Localiser.MQTT.Router do
end end
end end
defp handle_announce(sensor_id) do defp handle_announce(sensor_id, payload) do
case Sensors.upsert_announced(sensor_id) do version =
case Jason.decode(payload) do
{:ok, %{"version" => v}} when is_binary(v) -> v
_ -> nil
end
case Sensors.upsert_announced(sensor_id, version) do
{:ok, _sensor} -> {:ok, _sensor} ->
Logger.info("[MQTT.Router] Sensor announced: #{sensor_id}") Logger.info("[MQTT.Router] Sensor announced: #{sensor_id}")
@@ -241,8 +241,8 @@ defmodule Localiser.Web.Controllers.SensorController do
def get_version(conn, %{"id" => id}) do def get_version(conn, %{"id" => id}) do
sensor = Sensors.get_sensor!(id) sensor = Sensors.get_sensor!(id)
{:ok, _} = Sensors.get_version(sensor) {:ok, version} = Sensors.get_version(sensor)
json(conn, %{status: "ok"}) json(conn, %{status: "ok", version: version})
end end
def reconfigure(conn, %{"id" => id} = params) do def reconfigure(conn, %{"id" => id} = params) do
@@ -0,0 +1,9 @@
defmodule Localiser.Repo.Migrations.AddFirmwareVersionToSensors do
use Ecto.Migration
def change do
alter table(:sensors) do
add :firmware_version, :string
end
end
end