116 lines
3.2 KiB
Markdown
116 lines
3.2 KiB
Markdown
# ESP32-C3 Universal MicroPython Launcher
|
|
|
|
A fault-tolerant launcher intended for the Magnifica ESP32-C3 project, but kept generic enough to reuse elsewhere.
|
|
|
|
## Core behavior
|
|
|
|
- `/.env` on the device holds all secrets and per-device options.
|
|
- Wi-Fi, BLE and UART are independent startup options.
|
|
- One Git repository can hold both the launcher and main application.
|
|
- The ESP32 does **not** need Git. It downloads a tiny JSON manifest and only changed raw files.
|
|
- `/launcher.py`, `/app/main.py`, and other manifest-listed files can update in one staged transaction.
|
|
- SHA-256 is verified before any file is committed.
|
|
- `.bak` rollback files plus a stable `boot.py` protect against interrupted or broken OTA.
|
|
- Secrets are never updated and are never in the manifest.
|
|
|
|
## Energy / update behavior
|
|
|
|
There is no 5-second repository polling loop.
|
|
|
|
Defaults are:
|
|
|
|
- remote manifest check: **once every 24 hours**
|
|
- boot delay before a possible check: **3 minutes**
|
|
- minimum inactivity before OTA may begin: **5 minutes**
|
|
- if busy when due: reconsider locally after **15 minutes**
|
|
- network failure: wait **1 hour** before another remote attempt
|
|
- BLE disabled by default
|
|
- Wi-Fi power saving enabled best-effort
|
|
|
|
If Wi-Fi exists only for OTA, set `WIFI_KEEP_CONNECTED=false`. If the app itself needs Wi-Fi for remote control, leave it `true`.
|
|
|
|
## Repository layout
|
|
|
|
```text
|
|
repo/
|
|
├─ README.md
|
|
├─ .gitignore
|
|
├─ .env.example
|
|
├─ firmware/
|
|
│ ├─ boot.py # stable recovery stub; install manually
|
|
│ ├─ launcher.py # OTA-updatable launcher
|
|
│ ├─ manifest.json # generated SHA-256 manifest
|
|
│ └─ app/
|
|
│ ├─ __init__.py
|
|
│ └─ main.py # actual Magnifica logic
|
|
├─ tools/
|
|
│ └─ build_manifest.py
|
|
└─ docs/
|
|
├─ DIGITAL_PROBE.md
|
|
├─ SETUP.md
|
|
└─ OTA_PROTOCOL.md
|
|
```
|
|
|
|
On the ESP32:
|
|
|
|
```text
|
|
/
|
|
├─ boot.py
|
|
├─ launcher.py
|
|
├─ .env
|
|
├─ update_state.json # generated automatically
|
|
└─ app/
|
|
├─ __init__.py
|
|
└─ main.py
|
|
```
|
|
|
|
## Safe inactivity-aware updates
|
|
|
|
The application receives `ctx["activity"]`.
|
|
|
|
Call this whenever a real interaction or machine-state change occurs:
|
|
|
|
```python
|
|
ctx["activity"].touch()
|
|
```
|
|
|
|
Bracket anything that must never be interrupted by OTA:
|
|
|
|
```python
|
|
ctx["activity"].begin()
|
|
try:
|
|
await brew_or_move_mechanism()
|
|
finally:
|
|
ctx["activity"].end()
|
|
```
|
|
|
|
OTA can start only after the long check interval is due **and** the device has been idle for `UPDATE_MIN_IDLE_SECONDS` **and** no busy lock is active.
|
|
|
|
## Gitea example
|
|
|
|
```env
|
|
UPDATE_PROVIDER=gitea
|
|
UPDATE_REPO_URL=https://git.example.com/user/repo
|
|
UPDATE_BRANCH=main
|
|
UPDATE_AUTH_MODE=auto
|
|
UPDATE_TOKEN=your_token
|
|
```
|
|
|
|
A public Gitea repo uses:
|
|
|
|
```env
|
|
UPDATE_AUTH_MODE=none
|
|
```
|
|
|
|
## Other platforms
|
|
|
|
Built-in URL/auth handling exists for Gitea/Forgejo/Codeberg, GitLab, GitHub and Bitbucket. For unusual self-hosted layouts, use `UPDATE_MANIFEST_URL` or `UPDATE_RAW_BASE_URL` and optionally a custom auth header.
|
|
|
|
See `docs/SETUP.md` and `docs/OTA_PROTOCOL.md`.
|
|
|
|
## Development probe
|
|
|
|
The first Magnifica S development tool is an input-only digital probe for
|
|
front-panel signal discovery. See `docs/DIGITAL_PROBE.md`; do not connect an
|
|
unknown machine wire directly to an ESP32 GPIO.
|