feat: include self-reported tx_power in measurement calls
This commit is contained in:
@@ -21,9 +21,10 @@ defmodule Localiser.Localisation.Sensor.Server do
|
|||||||
{:via, Registry, {Localiser.Registry, {:sensor, sensor_id}}}
|
{:via, Registry, {Localiser.Registry, {:sensor, sensor_id}}}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns %{sensor_id, floor_x, floor_y, distance} for a raw RSSI reading.
|
# Returns %{sensor_id, floor_x, floor_y, distance, rssi, tx_power} for a raw RSSI reading.
|
||||||
def measure(sensor_id, rssi) do
|
# tx_power is the beacon-advertised expected RSSI at 1 m (nil if not available).
|
||||||
GenServer.call(via(sensor_id), {:measure, rssi})
|
def measure(sensor_id, rssi, tx_power \\ nil) do
|
||||||
|
GenServer.call(via(sensor_id), {:measure, rssi, tx_power})
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if the sensor is currently collecting calibration samples.
|
# Returns true if the sensor is currently collecting calibration samples.
|
||||||
@@ -66,14 +67,16 @@ defmodule Localiser.Localisation.Sensor.Server do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@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)
|
distance = rssi_to_distance(rssi, state.rssi_ref, state.path_loss_exp)
|
||||||
|
|
||||||
measurement = %{
|
measurement = %{
|
||||||
sensor_id: state.sensor_id,
|
sensor_id: state.sensor_id,
|
||||||
floor_x: state.floor_x,
|
floor_x: state.floor_x,
|
||||||
floor_y: state.floor_y,
|
floor_y: state.floor_y,
|
||||||
distance: distance
|
distance: distance,
|
||||||
|
rssi: rssi,
|
||||||
|
tx_power: tx_power
|
||||||
}
|
}
|
||||||
|
|
||||||
{:reply, measurement, state}
|
{:reply, measurement, state}
|
||||||
|
|||||||
@@ -51,20 +51,29 @@ defmodule Localiser.MQTT.Router do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp handle_rssi(sensor_id, payload) do
|
defp handle_rssi(sensor_id, payload) do
|
||||||
with {:ok, %{"tag_id" => tag_id, "rssi" => rssi}} <-
|
case Jason.decode(payload) do
|
||||||
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 = %{
|
{:ok, %{"tag_id" => tag_id, "rssi" => rssi}} ->
|
||||||
sensor_id: sensor_id,
|
reading = %{
|
||||||
tag_id: tag_id,
|
sensor_id: sensor_id,
|
||||||
rssi: rssi,
|
tag_id: tag_id,
|
||||||
timestamp: DateTime.utc_now()
|
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} ->
|
{:error, reason} ->
|
||||||
Logger.error("[MQTT.Router] Bad payload from #{sensor_id}: #{inspect(reason)}")
|
Logger.error("[MQTT.Router] Bad payload from #{sensor_id}: #{inspect(reason)}")
|
||||||
Localiser.MQTT.Telemetry.count_error()
|
Localiser.MQTT.Telemetry.count_error()
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ defmodule Localiser.RSSI.Buffer do
|
|||||||
|
|
||||||
@flush_interval_ms 500
|
@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
|
def push(reading) do
|
||||||
GenServer.cast(__MODULE__, {:push, reading})
|
GenServer.cast(__MODULE__, {:push, reading})
|
||||||
end
|
end
|
||||||
@@ -50,14 +50,14 @@ defmodule Localiser.RSSI.Buffer do
|
|||||||
# If the sensor is in calibration mode, feeds the reading to Sensor.Server instead
|
# 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.
|
# and returns [] so the sample is excluded from Tag.Filter measurements.
|
||||||
# If the sensor server isn't running, returns [].
|
# 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
|
case Registry.lookup(Localiser.Registry, {:sensor, sensor_id}) do
|
||||||
[{_pid, _}] ->
|
[{_pid, _}] ->
|
||||||
if SensorServer.calibrating?(sensor_id) do
|
if SensorServer.calibrating?(sensor_id) do
|
||||||
SensorServer.calibration_reading(sensor_id, rssi)
|
SensorServer.calibration_reading(sensor_id, rssi)
|
||||||
[]
|
[]
|
||||||
else
|
else
|
||||||
[SensorServer.measure(sensor_id, rssi)]
|
[SensorServer.measure(sensor_id, rssi, tx_power)]
|
||||||
end
|
end
|
||||||
|
|
||||||
[] ->
|
[] ->
|
||||||
|
|||||||
Reference in New Issue
Block a user