From 0f0f377e988003695270d910fb00dbfb6b9c92c4 Mon Sep 17 00:00:00 2001 From: dvdrw Date: Sat, 16 May 2026 14:42:37 +0200 Subject: [PATCH] feat: include self-reported tx_power in measurement calls --- lib/localiser/localisation/sensor/server.ex | 13 ++++---- lib/localiser/mqtt/router.ex | 33 +++++++++++++-------- lib/localiser/rssi_buffer.ex | 6 ++-- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/lib/localiser/localisation/sensor/server.ex b/lib/localiser/localisation/sensor/server.ex index b893161..618483e 100644 --- a/lib/localiser/localisation/sensor/server.ex +++ b/lib/localiser/localisation/sensor/server.ex @@ -21,9 +21,10 @@ defmodule Localiser.Localisation.Sensor.Server do {:via, Registry, {Localiser.Registry, {:sensor, sensor_id}}} end - # Returns %{sensor_id, floor_x, floor_y, distance} for a raw RSSI reading. - def measure(sensor_id, rssi) do - GenServer.call(via(sensor_id), {:measure, rssi}) + # Returns %{sensor_id, floor_x, floor_y, distance, rssi, tx_power} for a raw RSSI reading. + # tx_power is the beacon-advertised expected RSSI at 1 m (nil if not available). + def measure(sensor_id, rssi, tx_power \\ nil) do + GenServer.call(via(sensor_id), {:measure, rssi, tx_power}) end # Returns true if the sensor is currently collecting calibration samples. @@ -66,14 +67,16 @@ defmodule Localiser.Localisation.Sensor.Server do end @impl true - def handle_call({:measure, rssi}, _from, state) do + def handle_call({:measure, rssi, tx_power}, _from, state) do distance = rssi_to_distance(rssi, state.rssi_ref, state.path_loss_exp) measurement = %{ sensor_id: state.sensor_id, floor_x: state.floor_x, floor_y: state.floor_y, - distance: distance + distance: distance, + rssi: rssi, + tx_power: tx_power } {:reply, measurement, state} diff --git a/lib/localiser/mqtt/router.ex b/lib/localiser/mqtt/router.ex index eb1560b..a83d29e 100644 --- a/lib/localiser/mqtt/router.ex +++ b/lib/localiser/mqtt/router.ex @@ -51,20 +51,29 @@ defmodule Localiser.MQTT.Router do end defp handle_rssi(sensor_id, payload) do - with {:ok, %{"tag_id" => tag_id, "rssi" => rssi}} <- - Jason.decode(payload) do + case Jason.decode(payload) do + {:ok, %{"id" => tag_id, "rssi" => rssi} = decoded} -> + reading = %{ + sensor_id: sensor_id, + tag_id: tag_id, + rssi: rssi, + tx_power: Map.get(decoded, "tx_power"), + timestamp: DateTime.utc_now() + } + Localiser.MQTT.Telemetry.count_reading() + Localiser.RSSI.Buffer.push(reading) - reading = %{ - sensor_id: sensor_id, - tag_id: tag_id, - rssi: rssi, - timestamp: DateTime.utc_now() - } + {:ok, %{"tag_id" => tag_id, "rssi" => rssi}} -> + reading = %{ + sensor_id: sensor_id, + tag_id: tag_id, + rssi: rssi, + tx_power: nil, + timestamp: DateTime.utc_now() + } + Localiser.MQTT.Telemetry.count_reading() + Localiser.RSSI.Buffer.push(reading) - Localiser.MQTT.Telemetry.count_reading() - Localiser.RSSI.Buffer.push(reading) - - else {:error, reason} -> Logger.error("[MQTT.Router] Bad payload from #{sensor_id}: #{inspect(reason)}") Localiser.MQTT.Telemetry.count_error() diff --git a/lib/localiser/rssi_buffer.ex b/lib/localiser/rssi_buffer.ex index 1bb0b85..563de20 100644 --- a/lib/localiser/rssi_buffer.ex +++ b/lib/localiser/rssi_buffer.ex @@ -6,7 +6,7 @@ defmodule Localiser.RSSI.Buffer do @flush_interval_ms 500 - # reading :: %{sensor_id: String.t(), tag_id: String.t(), rssi: integer()} + # reading :: %{sensor_id: String.t(), tag_id: String.t(), rssi: integer(), tx_power: integer() | nil} def push(reading) do GenServer.cast(__MODULE__, {:push, reading}) end @@ -50,14 +50,14 @@ defmodule Localiser.RSSI.Buffer do # If the sensor is in calibration mode, feeds the reading to Sensor.Server instead # and returns [] so the sample is excluded from Tag.Filter measurements. # If the sensor server isn't running, returns []. - defp resolve_measurement(%{sensor_id: sensor_id, rssi: rssi}) do + defp resolve_measurement(%{sensor_id: sensor_id, rssi: rssi, tx_power: tx_power}) do case Registry.lookup(Localiser.Registry, {:sensor, sensor_id}) do [{_pid, _}] -> if SensorServer.calibrating?(sensor_id) do SensorServer.calibration_reading(sensor_id, rssi) [] else - [SensorServer.measure(sensor_id, rssi)] + [SensorServer.measure(sensor_id, rssi, tx_power)] end [] ->