fix: actually include sensor firmware version string in repo, /version response
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user