Releases
Download the latest Aircast Raspberry Pi images and view version history.
Flashing manually? Write the .img.xz with Raspberry Pi Imager or balenaEtcher, and use the imager's OS customisation to set Wi-Fi and hostname before writing. The Aircast Flasher does all of this for you.
v0.4.5-rc.17
Latest
Pre-release
October 20, 2026v0.4.5-rc.17
Changelog
- •f3b1ba9chore(release): pin QGroundControl web aircast-v5.6.5-beta.9
v0.4.5-rc.16
Pre-release
October 20, 2026v0.4.5-rc.16
Changelog
- •bf739a7chore(release): pin QGroundControl web aircast-v5.6.5-beta.8
v0.4.5-rc.15
Pre-release
October 20, 2026v0.4.5-rc.15
Changelog
- •230a830chore(release): pin QGroundControl web aircast-v5.6.5-beta.7
v0.4.5-rc.9
Pre-release
October 19, 2026v0.4.5-rc.9
Changelog
- •3d3c965chore(release): pin QGroundControl web aircast-v5.6.5-beta.1
- •506465dfix(web): a camera's links say where they work, lead with the app, and are listed once
- •f45cb6dfeat(devicecert): serve a Let's Encrypt certificate for the device's local addresses
v0.4.5-rc.8
Pre-release
October 19, 2026v0.4.5-rc.8
Changelog
- •32f2806fix(web): the device home stops offering to finish setup once every required step is ready
- •f7284bcfeat(mavlink): the hosted fly app opens the device's telemetry link
v0.4.5-rc.14
Pre-release
October 19, 2026v0.4.5-rc.14
Changelog
- •de6c524chore(release): pin QGroundControl web aircast-v5.6.5-beta.6
v0.4.5-rc.13
Pre-release
October 19, 2026v0.4.5-rc.13
Changelog
- •cf1870fchore(release): pin QGroundControl web aircast-v5.6.5-beta.4
v0.4.5-rc.12
Pre-release
October 19, 2026v0.4.5-rc.12
Changelog
- •3a59f6bchore(release): pin QGroundControl web aircast-v5.6.5-beta.5
- •10c708bfix(web): the setup wizard names the camera's real fault, not a generic guess
- •0837f50fix(web): the device home tells the truth and offers one fix per problem
- •c38bd31fix(devicecert): a lapsed certificate is neither served nor offered
- •04df804fix(release): mark -rc, -dev and -stage tags as GitHub pre-releases
- •debc110feat(devicecert): the device answers on its own name, like falcon-k3q7.d.aircast.one
v0.4.5-rc.11
Pre-release
October 19, 2026v0.4.5-rc.11
Changelog
- •09c3213chore(release): pin QGroundControl web aircast-v5.6.5-beta.3
v0.4.5-rc.10
Pre-release
October 19, 2026v0.4.5-rc.10
Changelog
- •4125c8dfix(uplink): treat a tied default route as unrouted
- •40ff8d0chore(release): pin QGroundControl web aircast-v5.6.5-beta.2
- •333622bfix(network): move IPv6 traffic with the uplink too
- •7be0582fix(devicecert): a newly linked device gets its certificate within a minute
- •4534388fix(uplink): promote the chosen uplink above the shipped cellular metric
v0.4.5-rc.7
Pre-release
October 18, 2026v0.4.5-rc.7
Changelog
- •ff2e82drefactor(web): camera previews use the device's one WHEP proxy
- •bb9f807feat(web): aircastd serves an API and a rescue page, not an operator UI
- •9e268e1feat(web): the setup wizard becomes a JSON view the fly app draws
- •b78a42btest(web): the merged specs drive the native screens
- •c5ec5aefeat(web): the camera pages become a JSON view the fly app draws
- •67dcbb9fix(web): page script and live-fragment test survive the page deletions
- •bc86938feat(api): camera previews through the device's own origin
- •190f715feat(web): the Connection page becomes a JSON view the fly app draws
- •6e93789feat(web): Device, Engineering, Video engine and Recordings become JSON views the fly app draws
- •3c8619afeat(web): Ground station links and the flight log become JSON views the fly app draws
- •58ff157feat(web): the hosted fly app may call the device's API
- •9ac498dfeat(web): the aircraft view carries the link and the device health
- •a4b8be6feat(web): the Telemetry page becomes a JSON view the fly app draws
- •113be1cfeat(web): / opens the fly app; the flight page is gone
- •a3c321dfeat(api): device pages as JSON views, live over server-sent events
- •d3b6be0feat(web): framed pages join the fly app, and /fly/aircraft.json says how the device is
- •28b485ffeat(mavlink): 4G standby — the radio flies, aircastd takes over if its link drops
v0.4.5-rc.6
Pre-release
October 18, 2026v0.4.5-rc.6
Changelog
- •1b04b74chore(release): pin QGroundControl web aircast-v5.6.4
- •3641b57test(hil): fly the bench from the firmware's defaults, with no radio
- •ded8837feat(qgcweb): serve the device over https so QGroundControl web can reach USB
v0.4.5-rc.5
Pre-release
October 18, 2026v0.4.5-rc.5
Changelog
- •264c04echore(release): pin QGroundControl web aircast-v5.6.4-beta.1
- •64c2b29feat(qgcweb): QGroundControl syncs record who installed them and send only what changed
- •18a3e5efeat(qgcweb): just qgc-web-dev serves a local QGroundControl build on a device
v0.4.5-rc.4
Pre-release
October 18, 2026v0.4.5-rc.4
Changelog
- •ef5ea4fchore(release): pin QGroundControl web aircast-v5.6.3-beta.16
- •c7ae98cfix(web): back goes where you came from
- •cad1ad7feat(device): measure on the bench where a tap on the picture lands
- •ed40c80fix(mavlink): hand the pilot's sticks back when the app's stream stops
v0.4.5-rc.3
Pre-release
October 18, 2026v0.4.5-rc.3
Changelog
- •784ba5bchore(release): pin QGroundControl web aircast-v5.6.3-beta.15
- •15bead9fix(release): a pinned QGroundControl web build always tags a release candidate
- •f7ec909chore(deps): every gimbal camera reports its field of view
- •0934746feat(release): each QGroundControl release pins its web build here and tags an aircastd release
- •e40d6a4chore(deps): aircast-siyi v0.0.2, the gimbal camera reports its field of view
v0.4.5-rc.2
Pre-release
October 18, 2026v0.4.5-rc.2
Changelog
- •9b2fc7eci(release): queue per apt channel in the shared workflow, not one group for every run
- •7a67bdbtest(recordings): wait for the switch to settle before clicking it again
v0.4.4
October 18, 2026v0.4.4
Changelog
- •f12051cfix(qgcweb): the proxy streams detection events as they come, and PX4 firmware flashes too
- •7653e86fix(web): the stylesheet is built from source, not from whatever binaries sit in the tree
v0.4.3
October 18, 2026v0.4.3
Changelog
- •b1c490bfix(camera): a device with no Ethernet port is not offered cameras that plug into one
- •b80c174fix(security): aircastd answers only on its own names, closing DNS rebinding
- •e3c2ce2feat(release): pin QGroundControl web aircast-v5.6.3-dev.2
- •7c36033fix(web): a copy button says "Copied" on itself
- •f408e90fix(web): switches show their new state at once, long hostnames stay in their card
- •77a25c7fix(network): the idle uplink verdict says no video goes to the cloud
- •5f4d389fix(system): report the built-in engine, not a mediamtx unit it stopped on purpose
- •47f61f9fix(telemetry): offer only listeners a ground station can reach, in their own protocol
- •863d0b0fix(release): the QGroundControl web build is checked against a digest kept in this repo
- •d7ecee9fix(setup): the telemetry step says the flight controller goes in over USB
- •e7b41fbfix(camera): a failed one-click camera setup brings its error into view
- •5899e14fix(share): turning a link off cuts the viewers already watching it
- •330805afix(setup): the Wi-Fi handoff says what to do when .local doesn't open
- •11ea640fix(fcfirmware): restore the inflate cap 071ea67 reverted
- •6a58c9efix(debian): aircastd comes back from any exit, not only failures
- •071ea67fix(flights): restore the flight log changes 711d0ff reverted
- •5aeaa90fix(fcfirmware): a firmware upload cannot inflate past the largest flash
- •711d0fffix(modem): a link counts as dead when the internet stops answering it
- •50f477bfix(flights): each run says whether the aircraft flew, and the log opens on the last flight
- •8c88c57feat(release): the package carries a pinned QGroundControl web build, and deploys refuse to roll back a device
- •6637e8cfeat(qgcweb): give the browser QGroundControl a socket relay, a file store and a fetch proxy
- •1ea1798test(hil): flash the bench autopilot through aircastd on every run
- •9cc45c8test(hil): fly the CUAV-X7 in the simulator it runs on and follow it on the device
- •e3e6247fix(web): QGroundControl is offered only on a device that carries it
- •58753adfix(mavlink): probing a serial port no longer makes it aircastd's terminal
- •4c665abfeat(telemetry): flash ArduPilot firmware onto the attached flight controller
- •4e6af5btest(hil): run the device suite against a real bench with an autopilot and camera
- •6a2af8cfeat(web): QGroundControl runs from the device, telemetry and video connecting by themselves
- •2eea921test: no fixed ports, no machine-local symlink in the tree
- •c3f410dtest(e2e): every Playwright worker runs its own fake device
- •7663415fix(web): Ready to fly asks nothing more, and spent data points at data use
- •7297340feat(web): the uplink card says one thing per line
- •3586711fix(web): the Flight view no longer shows the update notice
- •689d157fix(starlink): the demo leads the card and never shows the real link as green
- •b6884a2feat(fight): a captured drone gives up no launch point
- •1e90072feat(web): the Flight page laid out the way DJI Fly is
- •03151ccfeat(watch): a tap still aims on an unknown lens, modes say what a tap does, the stick centres on a tap
- •49ec2e6feat(web): icons on the Connection cards, and the demo dish as a switch
- •3a0a907feat(starlink): a demo dish on the device itself
- •ef4b619fix(web): the Flight header keeps its chips at the edges while the camera comes and goes
- •4e7af25feat(fight): tailscaled keeps no logs or netmap on a fight card
- •c60894afeat(web): the Flight page gets the watch page's flight overlay
- •f626d80fix(web): a dead link is not "Ready to fly", and the uplink card says what it costs
- •89a6d13fix(fight): the journal goes back to the card when fight mode is lifted
- •b2fa30ffix(fight): bitrate history and data counters stay off the card too
- •c5ec2e2fix(web): the uplink address wraps at its separator, not mid-number
- •33a1afdfix(web): the primary uplink judges its own link and says what is wrong with it
- •ada54fdfeat(fight): a card flagged for fight mode keeps nothing on it
- •abab4fdfix(starlink): the dish card reads at a glance — one line, colour by what to do
- •2095f40feat(starlink): when no dish answers, the card says why
- •4521a47fix(web): a deploy mid-form reloads on the first tick after the form loses focus
- •73336d1feat(starlink): read current dish firmware — say why there is no service
- •16d2dacstyle: gofmt dashboard.go
- •a8b18b7fix(deps): go.mod carries only the gimbal pin bumps
- •7ec1f5afix(gimbal): the rate-span knob reaches Viewpro; libs with a cancellable redial
- •10207bbrefactor(gimbal): one bridge runner, the package named for what it does
- •ab64d17feat(starlink): the header, the uplink and the dish card say what a dish problem means
- •2e97c97feat(web): the Connection page names the port and calls out a camera port carrying the uplink
- •80c4645feat(web): Engineering ends its trails — the cloud link, the restart cost, named carriers
- •9158b0ffeat(web): the Device page leads with the one thing to do
- •9a174abfeat(camera): Viewpro gimbal control, and OpenIPC, Hikvision and Dahua one-click cards
- •2c4965afeat(gimbal): the camera bridge speaks Topotek as well as SIYI
- •1b38ee0feat(stream): one-click cards for Topotek and Viewpro cameras
- •894e709feat(web): the settings sidebar is an icon rail below lg
- •0728871fix(web): one scan button while the checklist is up, and the camera card names the port in words
- •6e189f5feat(web): the camera step speaks to a pilot — checklist first, network details behind a fold
- •170d6ccfix(web): a port already on the camera's subnet asks for the cable, not an address
- •a0f1032feat(web): Reconfigure on a dark camera looks for it instead of replaying the dead setup
- •ea33681fix(stream): the port fixer never proposes a subnet another port already holds
- •84cdf14feat(web): the camera page puts the fix under the fault and folds the links while it's dark
- •80f03d9feat(web): the scan deep-link scans on arrival, and camera pages say what they hold
- •eb59684fix(stream): the camera-fault probe no longer flips verdicts on every page tick
- •254c60efix(web): a way back to Flight from Connect on desktop
- •20ab836fix(web): Connect never offers the camera port as a ground-station address
- •bbeb02dfeat(web): Connect carries telemetry and the by-address links a ground station needs
- •3203652feat(web): one notch bigger type scale
- •e173d82feat(web): the Flight sheet is for the pilot — checklist, camera state, link, health
- •d9f38fffeat(web): a moved camera is offered its scan straight from Flight
- •c3b783ffeat(update): software updates you can see, trust and follow
- •4e79190fix(web): restore the dashboard fonts and logo dropped by a1ba34b
- •4a11c9afeat(web): DJI-style flight view — full-bleed camera, HUD overlays, ⋯ sheet
- •a1ba34bfix(web): stop the flight page saying the camera fault twice and wrapping the checklist
v0.4.2
October 16, 2026v0.4.2
Changelog
- •5edc2e3fix(update): refresh the apt keyring on boot
- •c79c610test(watch): cover More, payload release and the fly view edges in e2e
- •b61275cfeat(watch): one More for camera and payload, no pause, readable status
- •dbde0dbfeat(gripper): reach the gripper through More, as the Android Fly view does
- •29778abci(release): stop asking for a Pi image build
- •de73470feat(gripper): Gripper button and hold-to-confirm sheet, as in the Android Fly view
- •7f19b66feat(gripper): keep payload release in reach and say what happened
- •47c14dffeat(gripper): release and grab the payload from the camera page
- •0e9c43bfeat(release): just release promote ships the latest rc as its stable version
- •0cb64e0Revert "chore: default deploys to production and drop dev/stage/alpha release types"
- •7bd06f7chore: default deploys to production and drop dev/stage/alpha release types
- •cd4eda0feat(mavlink): announce the camera streams over MAVLink so ground stations set up video on connect
- •efc5825feat(web): darker secondary text from aircast-tokens
- •3231dbefeat(time): serve the Pi's clock to cameras that cannot reach the internet
- •d464e27feat(web): take the palette and radius scale from aircast-tokens
- •a8ea9d0fix(deploy): check the aircraft is disarmed before every restart, not just at the start
- •4909c82fix(web): refuse telemetry saves while armed with 409, and tag Cloudflare links
- •5cf632cfix(flight): count viewers on the mediamtx backend too
- •f1d234bfix(flight): a silent autopilot shows as silent, not as its last known state
- •ae783a2fix(mavlink): reopen a silent autopilot with backoff, and give up after three tries
- •3533349fix(atomicfile): sweep temp files an interrupted write left behind
- •598e519fix(network): stop restarting a Wi-Fi hotspot that is still coming up
- •37c853afix(watch): flight data on a landscape phone no longer runs into the picture's centre or the gimbal pad
- •6ffa0d7fix(watch): a landscape phone keeps flight data in the header row and the picture clear
- •ec3cd0cfix(watch): a portrait phone gets one tidy flight panel, not the desktop overlay squeezed
- •3f536eefix(watch): keep flight data off the picture's centre and clear of the controls
- •f0105bcfeat(watch): flight data over the video laid out like DJI Fly
- •0a7a66efeat(watch): the video carries the flight strip a ground station shows
- •b69a56afix(mavlink): a CubePilot autopilot no longer goes silent after ModemManager probes it
v0.4.1
October 16, 2026v0.4.1
Changelog
- •45190eafeat(video): the camera page shows whether its cloud copy is uploading, and the cloud status names the SFU for QGC
- •fc7a3b6feat(video): each camera publishes its own cloud copy only while someone watches it, and the watch page falls back to it
- •9992002perf: stop polling that spends LTE bytes and Pi CPU for nothing
- •ae0e1acfix: two pollers read the wrong thing — a live serial port and a 60 s snapshot
- •b5c6a7bfeat(watch): tell a ground station which cameras to pull through Cloudflare
- •bc0fad1fix(camera): remote viewers get video after the uplink comes up late
- •a351b70chore(web): regenerate output.css against the current templates
- •865f7e0fix(siyi): the camera read as gone the moment the bridge took it over
- •e2bddddfeat(flights): share a sortie with the telemetry burned into the picture
- •8e0bcaefeat(camera): one click sets up a SIYI camera from a template
- •431a651feat(web): the device's own pages send remote viewers through Cloudflare too
- •0cd9795feat(watch): viewers reaching the device over Tailscale watch through Cloudflare
- •2295e4efix(device): refuse what would cut telemetry while the aircraft is armed
- •3bdf841feat(recordings): a sortie's video downloads from the flight log, as one file
- •50bf3cffeat(diag): sign diagnostics with the device's cloud identity, not a baked key
- •986d87cfix(deploy): refuse to deploy to an aircraft that is armed
v0.4.1-rc.1
Pre-release
September 27, 2026v0.4.1-rc.1
Changelog
- •45190eafeat(video): the camera page shows whether its cloud copy is uploading, and the cloud status names the SFU for QGC
- •fc7a3b6feat(video): each camera publishes its own cloud copy only while someone watches it, and the watch page falls back to it
- •9992002perf: stop polling that spends LTE bytes and Pi CPU for nothing
- •ae0e1acfix: two pollers read the wrong thing — a live serial port and a 60 s snapshot
- •b5c6a7bfeat(watch): tell a ground station which cameras to pull through Cloudflare
- •bc0fad1fix(camera): remote viewers get video after the uplink comes up late
- •a351b70chore(web): regenerate output.css against the current templates
- •865f7e0fix(siyi): the camera read as gone the moment the bridge took it over
- •e2bddddfeat(flights): share a sortie with the telemetry burned into the picture
- •8e0bcaefeat(camera): one click sets up a SIYI camera from a template
- •431a651feat(web): the device's own pages send remote viewers through Cloudflare too
- •0cd9795feat(watch): viewers reaching the device over Tailscale watch through Cloudflare
- •2295e4efix(device): refuse what would cut telemetry while the aircraft is armed
- •3bdf841feat(recordings): a sortie's video downloads from the flight log, as one file
- •50bf3cffeat(diag): sign diagnostics with the device's cloud identity, not a baked key
- •986d87cfix(deploy): refuse to deploy to an aircraft that is armed
v0.4.0
September 26, 2026v0.4.0
Changelog
- •322113efeat(uplink): move traffic off an uplink that stops reaching the internet
- •96d4541feat(mavlink): a second MAVLink path through the cloud relay
- •c68008afix(camera): a found camera leaves only its sign-in to fill
- •e0156d7feat(recordings): download a recording with the flight's telemetry as a subtitle track
- •8db0047feat(camera): a Raspberry Pi camera on the ribbon cable can be added from the wizard
- •7703a81fix(camera): the sign-in check asks the camera once, says why it failed, and runs the real setup in e2e
- •bc3a51afeat(watch): stopping a recording offers the device logs for the time it ran
- •7f5efc2feat(modem): the SIM's text messages show on the cellular card
- •af1e20efix(camera): the add-camera wizard leads with the scan and asks for a sign-in
- •6bf7df9fix(watch): the player explains a stream that never opens instead of spinning forever
- •c2b0801fix(cloudflare): watch via Cloudflare on the engine backend, and in the browser at all
- •455b8c5fix(camera): dashboard previews filled the LTE uplink and starved MAVLink
- •374cc2ffix(stream): keep bitrate history across restarts and record what the camera sends
- •1e823affeat(camera): the add-camera wizard checks the picture before saying added
- •08f9a19feat(dashboard): the flight screen shows the aircraft, the Pi and the link it rides on
v0.3.6-rc.3
Pre-release
September 22, 2026v0.3.6-rc.3
Changelog
- •7a13fdbfeat(dashboard): a debrief that charts the flight, and a device that can update itself
- •9505bc3fix(systemd): restarting our own unit reported a failure for a restart that worked
v0.3.6-rc.2
Pre-release
September 22, 2026v0.3.6-rc.2
Changelog
- •86ed1bcfeat(harness): a fake device you can drive, not just a fixture for the suite
- •995ae98fix(diag): answer 'no journal' instead of failing where journalctl does not exist
v0.3.6-rc.1
Pre-release
September 21, 2026v0.3.6-rc.1
Changelog
- •c97fd9efeat(diag): log every link report and let the operator download the device journal from the dashboard
- •fd27078feat(mavlink): report modem quality and camera bitrate to the ground station as CELLULAR_STATUS
- •e950bbdfeat(web): keep an hour of modem signal and camera bitrate history and draw it on the dashboard
- •507fbeddocs: point apt instructions at apt.aircast.one
- •acea873Revert "fix: retire mavp2p" cleanup shims
- •284885dfix: retire mavp2p, which has been crash-looping since the router moved in-process
- •5ff9d6bstyle(ui): carry the blue into the light theme
- •d126357style(ui): share aircast-flasher's palette
- •5867fbfrefactor(ui): every page is one surface, not a pile of panels
- •cdd2d8crefactor(ui): the telemetry page is one surface, not three
- •844b0b3fix: the telemetry page answers the question it is read as asking
- •e86fee7fix: the MSP reader keeps its place, and the aircraft says what it is
- •eda3a36feat: a Betaflight aircraft reaches the ground station, and the ground reaches back
- •4c58464fix: the last camera's port returns to the rescue too
- •c27eec5fix: rescue reconciler creates before it destroys, and never stops trying
- •ad95a4dfeat: managed rescue-ethernet profile that can never steal a camera port
- •374dbb3test(e2e): cover the radio link end to end
- •55a416efeat: the packet radio link works, and says so honestly
- •161daa3feat: the dark-camera diagnosis measures instead of guessing, and closes its own loop
- •e29befefeat: the multi-camera page opens on a wall of live tiles
- •fe52249feat: icons on the setup rows
- •5dd938afix: setup rows are solid surfaces, not windows onto the dot grid
- •4a870e3fix: make the hero's interactive text look interactive
- •51a6c3ffix: give the setup rows a readable hierarchy
- •09cb245feat: redesign the camera page — picture-first hero, everything else folds
- •db00c7fharness: one-tap QGC setup link on MAVLink endpoints, register /telemetry page
- •f41e7a9feat: one-tap Aircast QGC setup link on the MAVLink endpoint card
- •8459717feat: raise the UI type scale and tokenize the stray px sizes
- •5c2b7e3feat: organize the camera page by intent — watch it, share it, send it
- •0e75e70feat: the last hand-plumbed widgets are Alpine components
- •97a0d05feat: the gimbal pad is an Alpine component
- •d7abbf2Merge origin/master
- •b95bc98Merge branch 'release/v0.3.1'
- •91386bcfix: pin templ CLI version for code generation
- •a861c97ci: dispatch a Pi image build on an aircastd release
- •80af8fdchore: ignore playwright-cli, test-results, harness bin, and python sidecar caches
- •cead002fix(release): snapshot versions must sort above the tag they follow
- •44b21dbsave wip work
- •ccd9f95chore: bump aircast-media to v0.10.1
- •27a6fdefix: the radio row said "connecting" and "unverified" at once
- •0fb74dbfeat: ask the radio whether it is transmitting
- •2f28097refactor: one letterbox, shared
- •b4bf345refactor: one letterbox, shared
- •302de25feat: the radio link is a publishing destination, and says whether it works
- •1b6764bfeat: the wizards are Alpine components
- •23d003dfeat: the watch page answers the aiming task review
- •4ed6ea1feat: send a camera over the packet radio link
- •20c5297chore: aircast-media v0.9.5 — a source that will not connect says so
- •7f069eechore: aircast-media v0.9.4
- •6b2134bchore: aircast-media v0.9.3
- •2c1f3f9chore: aircast-media v0.9.1 — on-demand paths can be published to more than once
- •6a1fc52chore: aircast-media v0.9.0 — a publisher path accepts reconnections
- •4c5906afix: consume rtspAnyPort, closing the last dropped path option
- •8348681fix: the demo path waited for a publisher that was never coming
- •ce68d12chore: aircast-media v0.6.1 — publisher paths actually start
- •2b3ea49fix: a cloud destination added later never reached the pipeline
- •7f37e69feat: publish to the cloud from the pipeline that holds the camera
- •a51a7e0fix: cloud publishing would have stopped, silently
- •dd07d6afix: an H265 camera got no HLS at all
- •d174a2ffix: one unhappy sink made a working camera look dead
- •eca44e0fix: finish the esbuild extraction so releases ship the page JS
- •8dc71ddfix: mounting metrics took the engine down
- •ddf9341fix: the engine's own endpoints were never mounted
- •e36a083chore: one rule per artifact in .gitignore
- •fc2a75cfeat: expose what the engine knows about itself
- •914aa7cfix: the browser could not play from the engine at all
- •a66390cfix: the engine came up with no paths, no servers, and mediamtx stopped
- •0b282ebfix: a publisher source waited on a path nothing publishes to
- •0e761d5fix: take mediamtx's ports before the engine reaches for them
- •12c2bf6feat: reconcile the engine's WebRTC addresses instead of refusing them
- •796d267chore: depend on aircast-media v0.2.0
- •dbd29c2feat: carry video in-process, behind a stored setting
- •a9bd0eechore: ignore pycache, playwright-cli and test-results
- •9f7895fdetect: report sidecar model state so a missing accelerator is named
- •32e1581add AI work
- •946624ctest(e2e): cover click-to-track and gimbal follow on the watch overlay
- •931f5c3feat: click-to-track a detection and follow it with the SIYI gimbal
- •8e9d480feat: push detections over SSE; fix detection latency + letterboxing
- •2082c53feat: on-device AI detection, video-file camera source, watch reconnect
- •6707952feat: route MAVLink in-process, and find cameras instead of asking for them
- •5e65a68feat(share): hand someone the picture without handing over the device
- •47beb53fix(flightlog): a fault that lasts an hour is one line, not three hundred
- •5d0e72afix(provision): the exported file is a secret, and now says so
- •df1f9f3docs: record what features 7 and 8 actually needed
- •7b8ac4afeat(provision): make airframe two a flash away, without baking secrets
- •04bdd6ffix(web): make the verdict and the camera row agree on how bad it is
- •d271fe5feat(flightlog): give the operator a way to find out what happened
- •5206b78fix(network): a link carrying none of the video is not a slow link
- •fc4180afeat(network): say whether the link can carry the video, not how strong it is
- •72720a3feat(web): tell the operator which thing to touch, not that something is wrong
- •f9d2a83fix(pilot): a first alert has not been suppressed for 292 years
- •35b868ffeat(pilot): log every alert decision, sent or held back
- •8ce46e6feat(pilot): give the in-flight channel an owner and a policy
- •6a6d7acfeat(web): make the Flight screen answer its question on a phone
- •6156d46fix(stream): stop the camera sweep lying about where it looked
- •cb2f5e7feat(stream): find the camera instead of asking for its RTSP URL
- •47fa1cbfix(web): stop an unknown live page polling the device forever
- •4024314fix(web): land a dark camera on the fix, not on its SFU credentials
- •e4b27cdfeat(web): rebuild the device UI around the operator, not the subsystems
- •4ecf0b7feat(web): make the ground-station links usable, and gate the e2e suite
- •5a11b67test(e2e): cover the device UI end to end, and raise the alert when video stops
- •757a430fix(web): make the Wi-Fi join form's mistakes visible and catchable
- •da4fd40refactor(web): derive the setup summary from one list of checks
- •2024d61fix(web): address code review — expansion, dead code, magic strings, missing tests
- •66981bdfix(web): make the device UI's structure hold up as the fleet grows
- •8992acefix(web): field-level validation plus task-level UX fixes to the setup flow
- •5ecd1a0fix(web): resolve device UI information-architecture defects
- •6b91c7dMerge pull request #45 from aircast-one/fix/telemetry-unconfigured-not-error
- •03db5dbMerge pull request #44 from aircast-one/feat/auto-transport-tcp
- •ab63be1chore: strip explanatory comments (house style)
- •9ea3a9cchore: strip explanatory comments (house style)
- •fb78005fix(telemetry): treat missing/empty mavp2p config as unconfigured, not an error
- •9a16802fix(streaming): address review of auto-transport reconciler
- •2ba1c15feat(streaming): make "automatic" transport fall back to TCP on UDP frame loss
- •7312801Merge pull request #43 from aircast-one/feat/camera-link-diagnosis
- •4701394fix(streaming): address review of camera link diagnosis
- •6f67f5efeat(streaming): name the real cause when a camera is unreachable
- •421b235Merge pull request #41 from aircast-one/chore/ponytail-audit
- •b299408chore: cut duplicated plumbing across stores, poll loops and views
- •d588fb1Merge pull request #40 from aircast-one/fix/factory-reset-software-wipe
- •3247047fix(reset): make factory reset actually clear state on any install
- •2d303e0Merge pull request #39 from aircast-one/feat/operator-first-overview
- •ca0bb41chore(web): drop unused watchButtonVariant (lint)
- •313193bfeat(web): clickable links + "Open in Aircast QGroundControl" deep link
- •77f9ef6feat(web): make ground-station links the centerpiece with a decision aid
- •aa6aff5fix(web): keep ground-station links inline, not hidden
- •56942aafeat(web): operator-first overview with live camera previews
- •63452dfMerge pull request #38 from aircast-one/feat/stat-icons
- •90b0ff2feat(web): add icons to overview stat cards
- •3f0e3e7Merge pull request #37 from aircast-one/chore/strip-comments
- •a042441chore: strip explanatory comments across the codebase
- •2669133Merge pull request #35 from aircast-one/ui/operator-video-links
- •8c1ff37feat(web): operator endpoints UX + BYO public Cloudflare viewer
- •3bf882aMerge pull request #36 from aircast-one/feat/multi-destination-publish
- •00cdc48feat(sfu): publish each camera to multiple destinations concurrently
- •fd45facMerge pull request #34 from aircast-one/ui/cloudflare-card-guidance
- •62f4c6dfix(sfu): harden the Cloudflare WHEP bridge and extract CloudflareWatch
- •04fa539fix(sfu): review follow-ups for the Cloudflare WHEP bridge
- •eafa122fix(sfu): harden cloudflare target parsing for gosec taint findings
- •393d6befeat(sfu): Cloudflare Realtime UX, truthful publish health, and WHEP playback bridge
- •7262655Merge pull request #33 from aircast-one/ui/destination-guidance
- •22edba8fix(web): name the exact action in unsaved-choice guidance
- •7ebed7bMerge pull request #30 from aircast-one/ui/flatten-video-streaming-card
- •164fc5dchore: drop unused badgeIf
- •d89c38cfeat(web): destination-first publishing UX with honest health everywhere
- •520eaeafeat(web): coherent sign-in story — persistent verdict, managed mode, honest actions
- •f290f71feat(sfu): test sign-in on save, configure LiveKit destination in one form
- •a6c8f2achore: review fixes — shared mint status, e2e CI warm-up and browser cache
- •d5192ddfeat(web): flatten video streaming card to two levels with one status
- •2fdf116Merge pull request #31 from aircast-one/fix/overview-watch-live-button
- •8fb3474fix(web): restore Watch live button on overview video card
- •177b61eMerge pull request #29 from aircast-one/ui/operator-friendly-settings
- •1877f3fMerge remote-tracking branch 'origin/master' into ui/operator-friendly-settings
- •e2b5a42Merge pull request #28 from aircast-one/feat/sfu-publish-modes
- •4a805f7fix(web): scope sign-in modes to the WHIP path, keep coexisting credentials
- •b3154e5feat(web): operator-friendly settings page
- •a8da6f0chore: upgrade templ to v0.3.1020 and regenerate
- •cb6f3cfchore(build): pin templ via go.mod tool directive
- •4371ef7Merge remote-tracking branch 'origin/master' into feat/sfu-publish-modes
- •9f401f1feat(web): mode-based SFU publishing form with visible credentials
- •d54fc23Merge pull request #27 from aircast-one/fix/cloud-connect-stuck-working
- •39224e4Merge pull request #26 from aircast-one/chore/upgrade-templ-0.3.1001
- •98278bafeat(stream): relabel WHEP for operators
- •a4d3927fix(web): bound form fetches and reload past dead SSE on cloud connect
- •5b6c37achore: upgrade templ to v0.3.1001 and regenerate
- •946cfc9feat(stream): drop WebRTC from pull-endpoint list
v0.3.5
August 22, 2026v0.3.5
Changelog
- •301cff6refactor: drop redundant DataStalled check from UplinkUsable
- •a68d1e1feat: validate mediamtx path names before merging stream patches
- •8ab6594fix: raise hotspot immediately when the saved wifi fails
- •fc203b8fix: gate hotspot reachability on tailscale being up
- •7554efffix: don't treat a freshly reset bearer as a usable uplink
- •91386bcfix: pin templ CLI version for code generation
- •a861c97ci: dispatch a Pi image build on an aircastd release
- •80af8fdchore: ignore playwright-cli, test-results, harness bin, and python sidecar caches
v0.3.4
August 22, 2026v0.3.4
Changelog
- •ad6d874fix(tailscale): use a pre-auth key without a Headscale control server
v0.3.2
August 22, 2026v0.3.2
Changelog
- •ad6d874fix(tailscale): use a pre-auth key without a Headscale control server
v0.3.1
August 22, 2026v0.3.1
Changelog
- •5ea84abfix(network): raise the hotspot when no Wi-Fi client profile exists
v0.3.0
July 18, 2026v0.3.0
Changelog
- •a022e34Merge pull request #24 from aircast-one/fix/camera-interface-validation
- •1f470ccfeat(web): copy-ready RTSP/WHEP links per camera on overview
- •63655b0Merge pull request #23 from aircast-one/fix/camera-interface-validation
- •0ff1df5fix: harden camera setup review findings
- •dc6c7f7fix: typed interfaces in e2e harness fixture
- •793cc06Merge remote-tracking branch 'origin/master' into fix/camera-interface-validation
- •b12e319fix: type-aware interface handling in camera setup
- •486d82cMerge pull request #20 from aircast-one/feat/sfu-cloud-provisioned-config
- •f74a844Merge branch 'feat/sfu-cloud-provisioned-config' of github.com:aircast-one/aircastd into feat/sfu-cloud-provisioned-config
- •0e94524fix(ui): drop raw WHEP share links — sharing goes through cloud watch links
- •ad72294fix(identity): harden enrollment — flow-scoped failures, https-only cloud API, ctx-scoped OnEnroll
- •73871ecMerge branch 'master' into feat/sfu-cloud-provisioned-config
- •1c46112Merge pull request #22 from aircast-one/feat/sfu-publish-secrets
- •b56c5b6chore: drop LOG_FORMAT; console format is JSON, journalctl renders it
- •16f4d3fsecurity: pipe the streamer publish token via stdin, not env
- •0775e15Merge remote-tracking branch 'origin/master'
- •37c8552feat(sfu): per-camera publish secrets for cloudflare:// and livekit:// targets
- •b1123a0fix(ui): dedupe watch actions and WHEP labels in the camera cloud card
- •7e49e7drefactor(ui): collapse config sections behind one-line disclosures
- •03d592afeat(ui): surface wss:// LiveKit in the custom-SFU target field
- •ab18f9drefactor(sfu): pass publish token via stdin, not an env var
- •fe1d0cetest(e2e): Playwright harness for the settings UI
- •95afa68feat(sfu): native LiveKit publishing and hardened third-party SFU auth
- •2bd01bbfix: CI data race, lint, and unauthenticated pprof exposure
- •e723c34SFU publishing: support static bearer token and configurable scope so aircastd can publish to any third-party WHIP SFU (open, token/API-key, or OAuth)
- •fd8b523Expose net/http/pprof endpoints for on-device profiling
- •697e10daircastd cloud enrollment: OAuth device-flow, auto-provisioned SFU publish creds, camera auto-connect, and /live watch link
- •eb84035Merge pull request #21 from aircast-one/fix/cn-concurrency
- •dd6d9e0Serialize ui.cn behind a mutex; twmerge's global LRU cache is not concurrency-safe and corrupts under concurrent template renders
- •a89387eSerialize ui.cn behind a mutex; twmerge's global LRU cache is not concurrency-safe and corrupts under concurrent template renders
- •3861975resolve review: 600-perm provisioned oauth config, log credential overrides, reject custom issuers on one-click connect, add tests
- •1df28dfSFU cloud: read OAuth from provisioned /etc/aircast/oauth.json, drop hardcoded prod fallbacks, provision per-env via deploy/pi-gen
- •d686fc9Merge pull request #16 from aircast-one/feat/aircastd-oauth-publish-token
- •f602f40feat(web): link to cloud device page when publish token mints
- •88821bafeat(web): show SFU publish-token health; fix token URL placeholder
- •1b883c8feat(sfu): drop publish-token audience; SFU audience is server-set
- •3d66993feat(sfu): configure publish OAuth via UI settings, not env vars
- •b76629cfix(sfu): launch tokenless on mint failure; review follow-ups
- •239015frefactor: mint publish token via x/oauth2/clientcredentials
- •25bcd9csecurity(sfu): OAuth-only publish tokens; harden minter (R3.1 + R3.7)
- •cbfb1bcrefactor: derive device id from /etc/machine-id
- •c5b6c70security(sfu): quarantine required-but-tokenless streamer launches
- •8d45a72security: pass publish token via env, not streamer argv
- •bb89bc1refactor: rename authclient.Manager to Minter
- •b874c9bbuild: fetch tags before releasing; warn when streamer missing on deploy
- •be23260feat(sfu): mint sfu:publish tokens via OAuth2 client credentials
- •a4c929dRemove dead Swagger stack and collapse single-impl interfaces
- •6224eaeMerge pull request #15 from aircast-one/chore/release-via-reusable-workflow
- •89f17e2ci: use the reusable go-release workflow
- •88bcf7efix(release): scope S3 artifact deletion to this repo's package
Flash your Pi in about 5 minutes
The Aircast Flasher downloads the image, sets Wi-Fi and hostname, and verifies the card.
On This Page