feat: support firmware uploads, OTA pushes

This commit is contained in:
2026-05-17 14:39:29 +02:00
parent e4e4065c2b
commit 2601484fad
7 changed files with 198 additions and 3 deletions
+37
View File
@@ -0,0 +1,37 @@
defmodule Localiser.Domain.Firmware do
@moduledoc false
def firmware_dir do
dir = Application.app_dir(:localiserd, "priv/firmware")
File.mkdir_p!(dir)
dir
end
def store(version, %Plug.Upload{path: tmp_path}) do
dest = Path.join(firmware_dir(), "#{version}.bin")
case File.cp(tmp_path, dest) do
:ok -> {:ok, version}
{:error, reason} -> {:error, reason}
end
end
def list do
dir = firmware_dir()
dir
|> File.ls!()
|> Enum.filter(&String.ends_with?(&1, ".bin"))
|> Enum.map(fn filename ->
version = String.replace_suffix(filename, ".bin", "")
path = Path.join(dir, filename)
stat = File.stat!(path, time: :posix)
%{version: version, size: stat.size, uploaded_at: stat.mtime}
end)
|> Enum.sort_by(& &1.uploaded_at, :desc)
end
def get(version) do
path = Path.join(firmware_dir(), "#{version}.bin")
if File.exists?(path), do: {:ok, path}, else: :not_found
end
end
+21
View File
@@ -59,6 +59,27 @@ defmodule Localiser.Domain.Sensors do
{:ok, sensor}
end
def send_ota_update(%Sensor{} = sensor, url, version) do
payload = %{
action: "ota",
url: url,
version: version
}
Localiser.MQTT.Connection.publish(cmd_topic(sensor), Jason.encode!(payload))
{:ok, sensor}
end
def send_ota_broadcast(url, version) do
payload = %{
action: "ota",
url: url,
version: version
}
Localiser.MQTT.Connection.publish("localiser/ota", Jason.encode!(payload))
end
# Pushes new WiFi and/or MQTT broker settings to the sensor. The sensor will
# apply the changes and restart. All keys are optional — omit any you don't
# want to change. Valid keys: "ssid", "password", "mqtt_host", "mqtt_port".