Skip to content

Latest commit

 

History

History
135 lines (95 loc) · 6.64 KB

File metadata and controls

135 lines (95 loc) · 6.64 KB

Releasing Blipscope firmware

Blipscope ships several hardware SKUs from one codebase (see include/variants/). All SKUs are versioned and released together from a single commit, and each device self-updates to its own binary over OTA. This doc is the release checklist.

How OTA works

  • A device checks releases/latest/download/version.txt — a single integer, the latest firmware version, shared by all SKUs.
  • If that integer is greater than the device's compiled FW_VERSION, the device downloads firmware-<slug>.bin, where <slug> is its own variant::SLUG (e.g. s3-146). Each SKU only ever downloads its own image.
  • The flow lives in src/OtaUpdater.cpp; FW_VERSION is in src/OtaUpdater.h.

Cutting a release

  1. Bump the version: edit FW_VERSION in src/OtaUpdater.h (one number, all SKUs).
  2. Commit + merge to main.
  3. Create a GitHub Release with a tag (e.g. v5). Publishing it triggers .github/workflows/firmware.yml, which:
    • builds every SKU in the matrix,
    • attaches each as firmware-<slug>.bin,
    • attaches a version.txt containing FW_VERSION.
  4. Devices pick up the update on their next daily check (or reboot).

Don't hand-upload assets — the workflow names them so they match what devices request.

Adding a new SKU to releases

A new SKU needs three entries that stay in sync:

  1. variant::SLUG in its include/variants/<sku>.h
  2. an [env:*] in platformio.ini, named <product>-<board> (e.g. blipscope-s3-146, quakescope-s3-146)
  3. its { env, slug } row in the matrix.include of .github/workflows/firmware.ymlslug MUST equal FW_OTA_PREFIX + variant::SLUG (it names the OTA asset devices download)

Add all three, and the next release automatically builds and publishes that SKU's binary.

Missileer builds — a separate OTA channel

The missileer-* envs build a different product (Missileer, the EAM monitor, -DFEATURE_EAM; see CLAUDE.md) from the same boards. So a Missileer device never pulls a radar image for its board, the Missileer envs set -DFW_OTA_PREFIX="eam-", and their CI slug is prefixed to match:

env slug (CI + OTA asset)
missileer-s3-146 eam-s3-146firmware-eam-s3-146.bin

These ride the same version.txt gate (one FW_VERSION bump releases radar and Missileer together), and a device only ever downloads its own <prefix><slug> binary. Releasing is otherwise identical — the matrix rows are already in .github/workflows/firmware.yml.

Orbitscope builds — another separate OTA channel

The orbitscope-* envs build a third product (Orbitscope, the Space edition, -DFEATURE_SPACE; see CLAUDE.md) from the same boards. Same arrangement as Missileer: -DFW_OTA_PREFIX="space-", and a CI slug prefixed to match so an Orbitscope device never pulls a radar or Missileer image:

env slug (CI + OTA asset)
orbitscope-s3-146 space-s3-146firmware-space-s3-146.bin

Same version.txt gate (one FW_VERSION bump releases radar, Missileer, and Orbitscope together).

Quakescope builds — another separate OTA channel

The quakescope-* envs build a fourth product (Quakescope, the Seismic edition, -DFEATURE_SEISMIC; see CLAUDE.md) from the same boards. Same arrangement as Missileer/Orbitscope: -DFW_OTA_PREFIX="seismic-", and a CI slug prefixed to match so a Quakescope device never pulls a radar, Missileer, or Orbitscope image:

env slug (CI + OTA asset)
quakescope-s3-146 seismic-s3-146firmware-seismic-s3-146.bin

Same version.txt gate (one FW_VERSION bump releases radar, Missileer, Orbitscope, and Quakescope together).

Quillscope builds — another separate OTA channel

The quillscope-* envs build a fifth product (Quillscope, the Birding edition, -DFEATURE_BIRDING; see CLAUDE.md) from the same boards. Same arrangement as the others: -DFW_OTA_PREFIX="birding-", and a CI slug prefixed to match so a Quillscope device never pulls another edition's image:

env slug (CI + OTA asset)
quillscope-s3-146 birding-s3-146firmware-birding-s3-146.bin

Same version.txt gate (one FW_VERSION bump releases every edition together).

Reelscope builds — another separate OTA channel

The reelscope-* envs build a sixth product (Reelscope, the Fishing edition, -DFEATURE_FISHING; see CLAUDE.md) from the same boards. Same arrangement as the others: -DFW_OTA_PREFIX="fishing-", and a CI slug prefixed to match so a Reelscope device never pulls another edition's image:

env slug (CI + OTA asset)
reelscope-s3-146 fishing-s3-146firmware-fishing-s3-146.bin

Same version.txt gate (one FW_VERSION bump releases every edition together).

Claudescope builds — another separate OTA channel

The claudescope-* envs build a seventh product (the Claudescope edition, -DFEATURE_CLAUDESCOPE; see CLAUDE.md) from the same boards — a live Claude usage-limit gauge. Same arrangement: -DFW_OTA_PREFIX="claudescope-", and a CI slug prefixed to match so a Claudescope device never pulls another edition's image:

env slug (CI + OTA asset)
claudescope-s3-146 claudescope-s3-146firmware-claudescope-s3-146.bin

Same version.txt gate (one FW_VERSION bump releases every edition together).

Speedscope builds — another separate OTA channel

The speedscope-* envs build an eighth product (the Speedscope edition, -DFEATURE_SPEED; see CLAUDE.md) from the same boards — a desk speed-radar that ties into a MiniSpeedCam (minispeedcam.com) over the LAN. Same arrangement as the others: -DFW_OTA_PREFIX="speed-", and a CI slug prefixed to match so a Speedscope device never pulls another edition's image:

env slug (CI + OTA asset)
speedscope-s3-146 speed-s3-146firmware-speed-s3-146.bin

Same version.txt gate (one FW_VERSION bump releases every edition together).

Legacy note: the retired C3

The original ESP32-C3 Kit is retired — Blipscope is S3-only going forward. The workflow no longer builds a c3-128 slug, and the plain firmware.bin alias it used to publish for the very first (pre-per-SKU-naming) devices is gone, so those C3 units no longer receive OTA updates. The variant header (include/variants/c3_128.h) and the single-core guards it drove stay in the tree, inert behind their capability flags, so the board can be revived by re-adding its [env:*] and CI matrix row.