โ† Boards

Beta

Flash a Personal Hopspot

Choose your device to get started. Flash a signed release from your browser, or follow the setup guide for your board.

Set up Hopspot on the Heltec HT-HD01-V2

Hopspot installs as an app on the Linux system your HT-HD01-V2 already runs. The vendor firmware and radio calibration stay in place.

Development preview. Signed installs, reboots, Remote Control, node pages and automatic radio rollback have passed on two HT-HD01-V2 boards and on a ThinkNode G4. There is no public download or one-click installer yet: developers build from the repository and install over SSH.

Before you start

Your board should match the tested ones. Other Heltec HaLoW products are not covered:

What to checkTested HT-HD01-V2
Board nameHeltec,HT-HD01-V2
Vendor imageOpenWrt 23.05.5, Morse 2.8.5-20250924
Kernel5.15.167
Radio profileUS only: 924 MHz, 8 MHz wide, 18 dBm

You need wired Ethernet to the board for the whole install, SSH access, and a checkout of the Prns repository. Build the app with build.hopspot.g4 (both boards run the same app) and its manager with build.hopspot.appliance, both through ./tools/prns.

Look the board's address up: the sticker on the case may not match the mode or address it is using now. If you reach it at an IPv6 link-local address, include your computer's Ethernet interface (the scope) in the SSH address and the controller endpoint.

Never load these files through LuCI's firmware upgrade or sysupgrade.

1. Check the device and back it up

SSH in over Ethernet, verify the host key, and run:

cat /tmp/sysinfo/board_name
cat /proc/sys/kernel/osrelease
df -Pk /overlay /tmp
uci -q changes

The board name and kernel should match the table above, and uci -q changes should print nothing. Then export the device's configuration with its own backup feature. Keep that file private: it holds passwords and keys.

2. Copy the files over

Two things go onto the device:

  • The manager, the tool that installs the app and can roll it back, at /etc/hopspot/manager.
  • A signed app package (manifest.json, manifest.minisig, app.gz) made for this exact board, in /tmp/hopspot-package.

Upload everything to a private folder such as /tmp/hopspot-upload, including the manager bundle's US radio profile as radio-profile.json. Compare hashes on the device before moving files into place.

Then define this helper, which every later command uses, and inspect:

manager() {
    /etc/hopspot/manager --root /etc/hopspot \
        --max-compressed-bytes 2097152 --max-executable-bytes 4194304 \
        --flash-reserve-bytes 262144 --ram-reserve-bytes 8388608 "$@"
}
manager inspect --profile /tmp/hopspot-upload/radio-profile.json

inspect only reads. It reports what it found as JSON and stops on a device it does not support.

3. Stage the app

Save this as /etc/hopspot/config.json with mode 0600. The radio starts off so the first test is wired only:

{
  "listen": "[::]:4242",
  "tcp_mode": "Gateway",
  "radio": "Disabled"
}
manager stage --package /tmp/hopspot-package --trial-launches 3

Write down the revision and executable_sha256 it returns. You need them to confirm later.

4. Pair your controller and test

The controller is the Remote Control client on your computer: the controller example in personal-hopspot/headless. Create its identity:

controller --state-dir /private/controller-state identity

In the SSH session, set the public_key it prints as CONTROLLER_PUBLIC_KEY and start a three-minute test run:

manager qualify --config /etc/hopspot/config.json --ram-directory /tmp/hopspot \
    --controller-public-key "$CONTROLLER_PUBLIC_KEY" \
    --controller-access application-probe --run-for 180

Save the target_key from its output. While the test runs, check the device from your computer, with its address and port as WIRED_ENDPOINT and that key as TARGET_PUBLIC_KEY:

controller --state-dir /private/controller-state invoke \
    --tcp "$WIRED_ENDPOINT" --target-key "$TARGET_PUBLIC_KEY" --action build
controller --state-dir /private/controller-state invoke \
    --tcp "$WIRED_ENDPOINT" --target-key "$TARGET_PUBLIC_KEY" --action interfaces
controller --state-dir /private/controller-state invoke \
    --tcp "$WIRED_ENDPOINT" --target-key "$TARGET_PUBLIC_KEY" \
    --action app-message --message-hex 0101

All three should answer. Each test run uses one of the three trial launches.

5. Start the service and confirm

Install the bundle's openwrt/hopspot script as /etc/init.d/hopspot with mode 0700, enable and start it, and run the same three checks again. If they pass, confirm:

manager confirm --revision "$APP_REVISION" \
    --executable-sha256 "$APP_EXECUTABLE_SHA256"

If they fail, stop the service and run manager rollback. A trial left unconfirmed ends on its own after three launches.

6. Turn on HaLoW

The radio change is a separate trial with its own safety net: unless you confirm within five minutes, the device restores its original radio settings and reboots. The tested profile is US only, so check it against your region first. Keep Ethernet connected, and have a second HaLoW Hopspot in range to test against.

Stop the service, set radio in the config to the HaLoW device, and start it again:

"radio": { "HaLow": { "device": "wlan0", "scope": "primary-halow" } }

Install the bundle's openwrt/hopspot-radio-recovery script as /etc/init.d/hopspot-radio-recovery and the radio profile as /etc/hopspot/radio-profile.json, then prepare the change:

chmod 700 /etc/init.d/hopspot-radio-recovery
/etc/init.d/hopspot-radio-recovery enable
manager radio prepare --profile /etc/hopspot/radio-profile.json \
    --recovery-seconds 300 --trial-boots 1

Write down this revision and profile_sha256, then apply:

manager radio apply --revision "$RADIO_REVISION" \
    --profile-sha256 "$RADIO_PROFILE_SHA256"

Run the controller's announce action on each board so they find each other over the radio. Then repeat the step 4 checks against this board through the other one. If they pass, confirm:

manager radio confirm --revision "$RADIO_REVISION" \
    --profile-sha256 "$RADIO_PROFILE_SHA256"

If they fail, run manager radio rollback with the same values or let the timer run out. manager radio status should end at Restored.

Keep these afterward

Your backups, the app package, both revision and hash pairs, the controller's public key and the device's target_key. Leave the radio recovery service installed.

Not tested yet: power loss in the middle of an install, updating the manager itself, and other regions.

Extended guide: every check, every failure case, and the reasoning behind each step

Heltec HT-HD01-V2 application installation

Install Hopspot on the working vendor Linux system. Choose the exact HT-HD01-V2; this does not qualify other Heltec HaLoW products or regional variants.

Development preview: the common static application passed authenticated Remote Control, exact HaLoW pages, supervised reboot and protected radio rollback on two HT-HD01-V2 devices and a ThinkNode G4. There is no signed public download or unattended install button yet. Follow the shared guided development flow below.

Inspected propertyQualified Heltec boards
Vendor board nameHeltec,HT-HD01-V2
Vendor image / kernelOpenWrt 23.05.5, Morse 2.8.5-20250924 / 5.15.167
ApplicationStatic MIPS32r2 little-endian O32, soft float
Regional radio profileExplicit US 924 MHz / 8 MHz, MCS2, long guard, 18 dBm

Use independent Ethernet management, authenticated SSH and private backups. Discover the actual address and verify its host key. One inspected board uses scoped IPv6 link-local management: its application listener must accept IPv6, and the controller endpoint needs the computer's Ethernet scope. Do not assume the factory AP/station sticker identifies the current runtime mode or management IP.

Developers use build.hopspot.g4 for the common MIPS application and build.hopspot.appliance for its manager/assets through ./tools/prns. The G4 name identifies the initial build recipe. Development manager checksums are not release authentication; the separate application package must be signed under the manager's trust root. Keep vendor firmware and calibration. Never use LuCI firmware upgrade or sysupgrade for these application files.

Review compatibility, hardware evidence and remaining gates.

Guided application installation

This is a development procedure for the inspected vendor images. Public downloads remain gated on signed manager/bootstrap distribution and physical power-loss qualification. The website offers these steps without an unattended Apply button. Keep Ethernet management throughout. The application installer does not replace the vendor operating system, calibration or Morse firmware.

1. Inspect and back up

Discover the actual management address using your Ethernet connection and vendor panel. Verify the SSH host key through a trusted connection. For IPv6 link-local, include the computer's Ethernet scope in the SSH address and controller endpoint. Keep your Internet connection on a separate interface. Neither an Ethernet USB adapter nor a browser network permission grants installation authority.

Before uploading an executable, inspect the exact vendor board name:

cat /tmp/sysinfo/board_name
cat /proc/sys/kernel/osrelease
df -Pk /overlay /tmp
uci -q changes

Compare the board and image with the model guide. Resolve pending UCI changes deliberately. Export the vendor configuration using its backup facility, download it to a private directory, and record its hash. If updating, gracefully stop Hopspot and privately export its whole application root and /etc/hopspot-radio before proceeding. Record original service enablement and your wired restoration path. Backups can contain passwords and private identities; never share or clone them onto another board. Do not restore arbitrary archives over a running node.

2. Verify the artifacts and transfer them privately

Use a trusted, exact-source development manager build or an authenticated release bundle. Its checksum list detects transfer errors; an unsigned checksum list does not authenticate its publisher. The shipping manager pins the repository release key. The separately built lab manager accepts a lab signer and never belongs in a user bundle. Never upload either bundle through LuCI firmware upgrade or sysupgrade.

A signed application package contains manifest.json, manifest.minisig, and app.gz, and names this exact vendor board. Keep a copy on the computer. Transfer the package and reviewed manager assets into a fresh mode-0700 RAM directory. Use your SSH client's binary transfer facility; some vendor SSH servers do not provide SFTP. Transfer to new names, verify hashes on the device, then publish complete files. If an upload times out, inspect its actual hash and destination before retrying. Do not overwrite an installed manager during an active trial. Manager updates need a separately qualified bootstrap/update procedure.

In the following commands, /etc/hopspot/manager is the reviewed installed manager, /tmp/hopspot-package holds the transferred package, and the supplied budgets are the inspected desk profile. Recheck headroom for your build. The manager enforces each signed package and reserve independently; installing the manager itself also consumes flash.

manager() {
    /etc/hopspot/manager --root /etc/hopspot \
        --max-compressed-bytes 2097152 --max-executable-bytes 4194304 \
        --flash-reserve-bytes 262144 --ram-reserve-bytes 8388608 "$@"
}
manager inspect --profile /tmp/hopspot-upload/radio-profile.json

inspect emits one JSON snapshot with the board, kernel, boot UUID/uptime, actual available overlay/RAM, explicit budgets, signer-text digest and qualified radio plan. It refuses unsupported boot adapters, bindings and pending UCI changes. It creates no application or radio state. Its signer digest is identification, not proof that an untrusted manager is authentic. Inspection does not prove a SKU's regional legality or make a snapshot a reservation.

3. Stage the application and enroll your controller

Install a private launch config with an explicit listener, Gateway TCP mode and stable HaLoW scope. An IPv4 listener accepts IPv4; an IPv6 management path needs an IPv6 listener. For example:

{
  "listen": "[::]:4242",
  "tcp_mode": "Gateway",
  "radio": { "HaLow": { "device": "wlan0", "scope": "primary-halow" } }
}

Keep that scope through updates and interface renames. Set radio to "Disabled" for initial wired-only qualification. The listener carries Reticulum, not HTTP. Install the config at /etc/hopspot/config.json, mode 0600. It contains no controller grants, automatic announcement policy or arbitrary executable options.

manager stage --package /tmp/hopspot-package --trial-launches 3

Save the returned application candidate's revision and executable_sha256. The manager verifies publisher signature, board, lengths, hashes and static soft-float ABI before publishing the trial. A disconnected acknowledgement means completion is uncertain: run manager status and reconcile the candidate before restaging. Staging never replaces the confirmed slot or private state.

On your computer, create or load the controller identity with the repository's headless controller example. Keep its private directory on the computer:

controller --state-dir /private/controller-state identity

Copy only its full 128-character public_key into CONTROLLER_PUBLIC_KEY in the trusted device shell. On first enrollment, while the application service is stopped, run the signed slot through the manager:

manager qualify --config /etc/hopspot/config.json --ram-directory /tmp/hopspot \
    --controller-public-key "$CONTROLLER_PUBLIC_KEY" \
    --controller-access application-probe --run-for 180

This consumes one of the trial's three launches and preserves procd/Unix exec signal ownership. It exits gracefully after the specified application lifetime (1โ€“300 seconds). Choose inspection for inspection plus explicit AnnounceSelf, application-probe to additionally test the bounded app message, or interface-watch to additionally permit the bounded interface stream. Neither extra grant implies the other. Private controller keys never leave your computer.

Read and retain the target's full target_key and node-page destination from its ready output through this trusted SSH session. The effective retained grant is proven by a successful authenticated operation, not the printed initial-grant count. Previously retained authorization can override initial grants. An update must preserve it; do not rerun enrollment or delete state to fix an access timeout. An already enrolled update can use the normal service launch and existing pinned controller. Grants persist outside the slots; service restarts cannot reenroll a revoked controller.

4. Prove health before confirming

While the candidate runs, use the wired endpoint and pinned target key on your computer. Replace the endpoint with the actual IPv4 or scoped IPv6 address. The last command requires the explicitly selected application-probe access:

controller --state-dir /private/controller-state invoke \
    --tcp "$WIRED_ENDPOINT" --target-key "$TARGET_PUBLIC_KEY" --action build
controller --state-dir /private/controller-state invoke \
    --tcp "$WIRED_ENDPOINT" --target-key "$TARGET_PUBLIC_KEY" --action interfaces
controller --state-dir /private/controller-state invoke \
    --tcp "$WIRED_ENDPOINT" --target-key "$TARGET_PUBLIC_KEY" \
    --action app-message --message-hex 0101

Fetch configuration and peer pages for actual inventory interface IDs, and fetch the complete node page through a separate client. Check expected build identity, real interface availability, verified-controller probe response and exact page bytes. A PID, socket or radio association does not qualify the candidate. The controller emits JSON lines and names its local timeout stage; a timeout alone does not prove denial. Unauthorized requests intentionally remain silent.

After qualification exits, install the reviewed openwrt/hopspot service asset as /etc/init.d/hopspot, mode 0700, then enable and start it. It uses the same signed slot and state, without enrollment or automatic announcements. Check the same pinned target and page again. Before trial launches are exhausted, confirm the exact application candidate using your saved values:

manager confirm --revision "$APP_REVISION" \
    --executable-sha256 "$APP_EXECUTABLE_SHA256"

Never substitute the journal revision for the candidate revision. If health fails, stop the service, use manager rollback, then start and verify the previous application. On first installation there is no previous application; failure is closed. Three unconfirmed launches exhaust the trial. Confirmation is an explicit operator action, never inferred automatically from readiness output.

5. Activate HaLoW as a separate protected transaction

Review the explicit radio profile for your actual region and SKU. The current qualified profile is US-only: 924 MHz / 8 MHz, MCS2, long guard, 18 dBm, open 802.11s with PRNS forwarding and proactive HWMP paths. Other regions require qualification. Keep independent wired access. Install and enable the reviewed openwrt/hopspot-radio-recovery asset before applying any radio candidate.

If initial wired qualification used "Disabled", gracefully stop the application service, change only the private config's radio to the named HaLow device and stable scope shown above, then restart normally. Verify the existing pinned wired controller again. A temporarily unavailable radio must leave wired control usable; do not reenroll the controller or delete state during this change.

chmod 700 /etc/init.d/hopspot-radio-recovery
/etc/init.d/hopspot-radio-recovery enable
manager radio prepare --profile /etc/hopspot/radio-profile.json \
    --recovery-seconds 300 --trial-boots 1

Save this separate candidate's revision and profile_sha256. Preparation starts the independent service, keeps originals/modes privately and changes no live vendor files. Apply only when the controller and peer gateway are ready:

manager radio apply --revision "$RADIO_REVISION" \
    --profile-sha256 "$RADIO_PROFILE_SHA256"

Do not shorten the example window without accounting for management reacquisition. Reboot within the trial only deliberately; the one allowed extra boot consumes a persisted allowance and starts one new bounded window. Reconcile the actual new boot UUID before calling it a reboot success. Discover the restored management address again when necessary; reboot can interrupt Ethernet DHCP.

Through each board's wired controller, explicitly invoke announce to seed a fresh lab's HaLoW neighbors. Verify the intended frequency/width/rate, and fetch authenticated build/interface/config/peer snapshots, probe and exact page through another live gateway. Peers and HWMP paths alone do not prove PRNS delivery. Only then confirm this exact radio candidate:

manager radio confirm --revision "$RADIO_REVISION" \
    --profile-sha256 "$RADIO_PROFILE_SHA256"

If checks fail, request radio rollback with those same candidate values, or let the lease expire. The independent service restores vendor files, clears owned pending deltas and requests a clean vendor reboot. radio status must reach Restored with a new boot, matching original files, carrier and Morse health. RebootUnavailable and RestorationUnavailable remain failures requiring wired investigation. Do not start another trial or remove the recovery guard to bypass them. App confirmation and radio confirmation never imply one another.

6. Retain recovery information

Keep the verified package, private backups, both exact candidate receipts, pinned controller/target public identities, service/config hashes and verified boot UUIDs. Remove RAM upload directories after reconciliation. Keep the independent radio recovery service and its durable guard installed. Graceful updates preserve state and grants and use the same slot owner. Physical power cuts, manager upgrades, other regional/vendor profiles, sustained load and field range remain separate qualification requirements. Browser assets, WebSockets and Auto-WiFi are optional features with separately measured resource and exposure budgets.

Change board

Each card shows the current support status and next steps for that device.

Heltec LoRa 32 V4 (S3R2)flashable

ESP32-S3R2 + SX1262 (Quad PSRAM)

Heltec LoRa 32 V4 (S3R8)flashable

ESP32-S3R8 + SX1262 (Octal PSRAM)

Heltec Vision Master E290-HFflashable

ESP32-S3R8 + HT-RA62-HF/SX1262 (Octal PSRAM)

Heltec Wireless Stick Lite V3flashable

ESP32-S3FN8 + SX1262

LilyGO T-Beam Supremeflashable

ESP32-S3 + SX1262 + AXP2101

Seeed XIAO ESP32-C6flashable

ESP32-C6

LilyGO T-Echoflashable

nRF52840 + SX1262

Heltec Mesh Node T114flashable

nRF52840 + SX1262

Heltec MeshPocket 5000 mAhflashable

nRF52840 + SX1262 + 2.13-inch e-ink

Heltec MeshPocket 10000 mAhflashable

nRF52840 + SX1262 + 2.13-inch e-ink

Heltec Mesh Node T096flashable

nRF52840 + SX1262 + KCT8103L PA

RAK WisBlock Starter Kitflashable

nRF52840 + SX1262

Seeed SenseCAP T1000-Eflashable

nRF52840 + LR1110

Heltec MeshTower V2flashable

nRF52840 + SX1262 + KCT8103L PA

muzi works Base Duoflashable

nRF52840 + LR1121

Heltec V3/V3.1flashable

ESP32-S3 + SX1262 (no PSRAM)

Seeed Wio Tracker L1flashable

nRF52840 + SX1262

Seeed XIAO ESP32-S3 + Wio-SX1262flashable

ESP32-S3 + SX1262

RAK WisMesh 1W Booster Kitflashable

nRF52840 + SX1262 1W

SenseCAP Solar Node P1 / P1-Proflashable

nRF52840 + SX1262

Elecrow ThinkNode G4preview

MT7628 + MM6108

Heltec HT-HD01-V2preview

MT7628

Selected

Active bring-up

These boards are actively being brought online. They are visible here for progress tracking, but are not public flash targets yet.

Raspberry Pi Zero 2 Wbring-up

RP3A0, quad-core Arm Cortex-A53

Bring-up in progress

Elecrow ThinkNode M7bring-up

ESP32-S3 + LR1110 + CH390D Ethernet

Bring-up in progress

Roadmap
LILYGO LoRa32 T3-S3roadmap

ESP32-S3 + SX1262/SX1276/SX1280/LR1121 variants

Planned

B&Q Nano G2 Ultraroadmap

nRF52840 + SX1262

Planned

B&Q Station G2roadmap

ESP32-S3 + SX1262

Planned

Not seeing a board you want supported? Let us know in a GitHub issue and help steer what comes next.