A Flask-based web application for generating and downloading custom SmartPoi firmware for Arduino (ESP8266) and PlatformIO (ESP32-C3) targets. Provides a WebSerial-based flash tool for direct browser-to-ESP32 firmware installation.
This application serves as a firmware distribution and customisation platform for SmartPoi devices:
- Arduino ESP8266 Tab – Clones the SmartPoi-Firmware repo, patches pin assignments, LED counts, AP credentials and LED type, then serves a ZIP download.
- PlatformIO ESP32-C3 Tab – Clones the SmartPoi_ESP32 repo, patches build flags for the
other_c3_boardenvironment, runspio runto compile firmware + littlefs filesystem, and offers both ZIP download and WebSerial flashing directly from the browser. - WebSerial Flashing – Uses
esptool-js(loaded from CDN) to flash compiled binaries over a serial port connection. Supports partial (firmware + filesystem only) or full install (bootloader + partition table + OTA boot_app0 + firmware + filesystem). - Static Binary Assets – Pre-compiled LED animation binaries for various pixel counts (36, 60, 72, 120, 144) are served from
static/bins/. - Usage Tracking – Access, usage and check-in logs are written to rotating files under
logs/.
- Ubuntu 24.04 LTS (or any modern Linux distribution)
- Python 3.10+ (3.12 is the default on 24.04)
- Git – to clone firmware repositories (
apt install git) - PlatformIO Core – for ESP32 firmware compilation
- pip /
venv– Python package management - Nginx (recommended for production reverse proxy)
- A domain name (optional, but recommended for TLS)
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip git nginxOn Ubuntu 24.04, pip3 install --user is blocked by PEP 668 (externally-managed-environment). Use pipx instead:
# Install pipx (Python app installer in isolated environments)
sudo apt install -y pipx
pipx ensurepath
# Install PlatformIO Core using pipx
pipx install platformio
# Add pipx binaries to PATH (log out & back in, or run:)
source ~/.bashrc
# Verify installation
pio --versioncd /opt
sudo git clone https://github.com/tomjuggler/Arduino_Template_Aider.git smartpoi-firmware-downloader
sudo chown -R $USER:$USER /opt/smartpoi-firmware-downloader
cd /opt/smartpoi-firmware-downloaderpython3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txtCreate wsgi.py in the project root:
#!/usr/bin/env python3
from app import app
if __name__ == "__main__":
app.run()# Start the development server to verify everything works
python wsgi.pyVisit http://<your-server-ip>:5000 in a browser. You should see the SmartPoi Firmware Downloader interface.
pip install gunicornTest gunicorn serves correctly:
gunicorn -w 4 -b 127.0.0.1:8000 wsgi:appCreate /etc/systemd/system/smartpoi.service:
[Unit]
Description=SmartPoi Firmware Downloader (Flask/Gunicorn)
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/opt/smartpoi-firmware-downloader
Environment="PATH=/opt/smartpoi-firmware-downloader/venv/bin"
ExecStart=/opt/smartpoi-firmware-downloader/venv/bin/gunicorn -w 4 -b 127.0.0.1:8000 wsgi:app
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetImportant: The www-data user needs write access to the application directory (for logs, zip output, cloned repos):
sudo chown -R www-data:www-data /opt/smartpoi-firmware-downloader
sudo chmod -R g+w /opt/smartpoi-firmware-downloaderEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable smartpoi
sudo systemctl start smartpoi
sudo systemctl status smartpoiCreate /etc/nginx/sites-available/smartpoi:
server {
listen 80;
server_name smartpoi.example.com;
# Increase upload size for firmware compilation requests
client_max_body_size 10M;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /;
proxy_set_header Host $host;
# Increase timeouts for long compilations
proxy_read_timeout 3600s;
proxy_connect_timeout 3600s;
}
# Serve static files directly via nginx
location /static/ {
alias /opt/smartpoi-firmware-downloader/static/;
expires 1h;
add_header Cache-Control "public, immutable";
}
}Enable the site:
sudo ln -s /etc/nginx/sites-available/smartpoi /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxAdd the ProxyFix middleware to app.py (already present or add at the top after app = Flask(__name__)):
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1)sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d smartpoi.example.com- Navigate to the Arduino ESP8266 tab.
- Configure:
- Data Pin – Default
D2 - Clock Pin – Default
D1 - Number of Pixels – Select LED count (36, 60, 72, 120, 144)
- Access Point Name/Password – The Wi-Fi AP the device will broadcast
- LED Type –
WS2812orAPA102
- Data Pin – Default
- Click Generate Arduino Project – a ZIP file downloads automatically.
- Navigate to the PlatformIO ESP32 (C3) tab.
- Configure the same parameters as above.
- Click Build ESP32 Firmware – The server will:
- Clone/pull the latest SmartPoi_ESP32 repository
- Patch
platformio.iniwith your settings - Run
pio run -e other_c3_board(may take several minutes on first build) - Build the LittleFS filesystem image
- A ZIP file downloads automatically
- The Flash via WebSerial button appears, along with flash option checkboxes.
- After a successful ESP32 build, click Flash via WebSerial.
- A browser dialog asks you to select the serial port your ESP32-C3 is connected to.
- Choose your flash mode:
- Full install – Flashes everything: bootloader @
0x0, partitions @0x8000, boot_app0 @0xe000, firmware @0x10000, filesystem @0x290000. Select this for a brand-new or bricked device. - Individual mode (Full install unchecked) – Use the Firmware and LittleFS checkboxes to flash only what you need.
- Full install – Flashes everything: bootloader @
- Watch the progress bar and log output. The device resets automatically when done.
Note: WebSerial requires Chrome or Edge version 89+. It is not supported in Firefox or Safari.
| Endpoint | Method | Description |
|---|---|---|
/ or /home |
GET | Serves the main web interface |
/generate_project |
POST | Builds Arduino ESP8266 firmware ZIP |
/generate_esp32_project |
POST | Compiles ESP32-C3 firmware + filesystem |
/download_esp32_zip/<filename> |
GET | Downloads a previously compiled ESP32 ZIP |
/download_controls |
POST | Builds SmartPoi JS utilities ZIP |
/api/smartpoi-checkin |
GET | Logs a SmartPoi check-in event |
/api/controls-checkin |
GET | Logs a Controls check-in event |
/api/esp32-checkin |
GET | Logs an ESP32 check-in event |
/opt/smartpoi-firmware-downloader/
├── app.py # Flask application (main logic)
├── image.py # Image processing utilities
├── test.py # Unit tests
├── requirements.txt # Python dependencies
├── wsgi.py # WSGI entry point (create manually)
├── templates/
│ └── index.html # Web UI (Jinja2 template)
├── static/
│ ├── bins/ # Pre-compiled LED animation binaries
│ ├── esp32_output/ # Dynamically generated ESP32 firmware files
│ ├── favicon.ico
│ └── ic_launcher-web.png
├── logs/ # Rotating access, usage and check-in logs
├── SmartPoi-Firmware/ # Cloned Arduino repo (auto-managed)
├── SmartPoi_ESP32/ # Cloned ESP32 repo (auto-managed)
└── SmartPoi-js-utilities/ # Cloned JS utilities repo (auto-managed)
If you see errors about missing .o files in .pio/build/other_c3_board/, the build cache is stale. Clean it manually:
cd /opt/smartpoi-firmware-downloader/SmartPoi_ESP32
pio run -e other_c3_board -t cleanThen try building again from the web interface.
- Ensure you are using Chrome or Edge version 89+.
- The device must be connected via USB.
- Some ESP32-C3 boards require holding the BOOT button during the initial connection.
If the application cannot write logs, clone repos or create ZIP files:
sudo chown -R www-data:www-data /opt/smartpoi-firmware-downloader
sudo chmod -R 775 /opt/smartpoi-firmware-downloaderThis project is developed and maintained by Circus Scientist.
Support development on Patreon.
Check out Magic Poi for the next generation.