Skip to content

koder95/waterflow-pixel-unit

Repository files navigation

Waterflow Pixel Unit

A firmware project for a "flowing water" LED effect controller built for Raspberry Pi Pico 2 W. The application is written for MicroPython and exposes a REST API for device configuration, user management, and diagnostics.

⚠️ Important (production configuration): before running on a target device, you must change values in config.py, especially:

  • secured['secure']
  • device['uuid']

The current values in this repository are examples and must not remain unchanged on the final device.


1. Hardware target

This project is intended to be installed on:

  • Raspberry Pi Pico 2 W
  • together with a dedicated expansion board (I/O and power handling for LED strip / actuators).

The code uses specific GPIO pins (including 18, 19, 20), so hardware compatibility with the target expansion module is assumed.


2. Architecture overview

  • main.py starts:
    • the LED controller task (WaterflowDriver.run())
    • the HTTP server (phew.server.run()).
  • myhttp.py:
    • connects to Wi‑Fi (or starts AP fallback mode),
    • registers REST API endpoints,
    • handles authentication/authorization.
  • waterflowdriver.py implements LED strip runtime logic with dependencies on:
    • time schedule,
    • sensor state,
    • configuration loaded from JSON files.

3. Required runtime configuration files

The project reads and writes data in JSON files stored on the device.

3.1 config.py

A static file with device metadata and security settings:

  • device – device metadata (uuid, app name, etc.),
  • secured – security section (secure, api-key).

Before deployment:

  • set your own device['uuid'],
  • set your own secured['secure'] (recommended: also update secured['api-key']).

3.2 JSON files used by the app

  • net.json – Wi‑Fi/AP configuration:
    • ssid, pass, ap-ssid, ap-pass
  • users.json – users, passwords, tokens
  • groups.json – role mapping (admin, designer, editor)
  • data.json – device runtime configuration (e.g. pixelProgram, brightness, stepTime, onTime, offTime, on, nol, ...)
  • pixelprograms.json – list of pixel animation programs
  • log file (logging.log_file, depending on phew.logging setup)

On first startup, the backend ensures a default RBAC structure (roles + admin account).


4. API authentication and authorization

4.1 Access model

  • Authentication: user + token passed in request headers.
  • Authorization: role/group based (admin, editor, designer).

4.2 How to log in

Login endpoint:

  • POST /api/secure/auth

Credentials handling:

  • API accepts Basic Auth (Authorization: Basic base64(user:pass)),
  • on successful login it returns a fresh token.

4.3 How to call protected endpoints

For protected endpoints send headers:

  • user: <username>
  • token: <token_from_login>

Many endpoints also refresh token and return newCredentials in response.

4.4 Administrative exception

  • POST /api/secure/admin/reset requires header:
    • secure: <value_of_config.secured['secure']>

5. REST API – detailed reference

Below is a complete endpoint list based on the current backend code.

5.1 Public endpoints

GET /api/info

Returns device metadata (config.device).

200 OK (JSON)

{
  "uuid": "...",
  "manufacturer": "Raspberry Pi",
  "product-name": "Pico 2 W",
  "application-name": "Waterflow Pixel Unit"
}

GET /api/logs

Returns log entries as an array of text lines.

200 OK (JSON)

["line 1", "line 2", "..."]

GET /api/data

Returns current runtime configuration from data.json.

200 OK (JSON) – schema depends on current file content.


GET /api/current-state

Returns current driver state (driver.current_state()), including current action (extending/reducing) and runtime parameters.

200 OK (JSON) – dynamic structure (current state + driver object fields).


GET /api/pixelprograms

Returns list of pixel programs from pixelprograms.json.

200 OK (JSON)

[
  [[255,0,0],[0,0,255]],
  [[0,255,0],[0,0,0]]
]

5.2 Protected endpoints (token / role)

DELETE /api/logs

Clears log file.

  • Required role: admin

200 OK

{
  "logs": ["...previous logs..."],
  "newCredentials": {"user":"...","token":"..."}
}

Errors: 401, 403, 500.


POST /api/restart

Starts countdown to soft restart (machine.soft_reset()).

  • Required role: admin or editor

200 OK

{
  "restartCountdown": 10,
  "newCredentials": {"user":"...","token":"..."}
}

PATCH /api/secure/pass

Changes password for currently authenticated user.

  • Minimum password length: 7

Body (JSON)

{"pass":"NewPassword123"}

202 Accepted

{
  "username":"admin",
  "newCredentials":{"user":"admin","token":"..."}
}

Errors: 401, 406, 500.


PUT /api/data

Replaces full data.json configuration.

PATCH /api/data

Partially updates data.json configuration.

  • Required role: admin or editor
  • If nol is missing, API sets nol = 3.

202 Accepted

{
  "before": {"...": "..."},
  "after": {"...": "..."},
  "newCredentials": {"user":"...","token":"..."}
}

PATCH /api/wifi

Updates network configuration (net.json).

  • Required role: admin
  • Accepted fields: ssid, pass, ap-ssid, ap-pass

Body (JSON)

{
  "ssid":"MyNetwork",
  "pass":"MyPassword",
  "ap-ssid":"Waterflow-Setup",
  "ap-pass":"SetupPass123"
}

202 Accepted

{
  "net": {
    "ssid": "...",
    "pass": "...",
    "ap-ssid": "...",
    "ap-pass": "..."
  },
  "newCredentials": {"user":"...","token":"..."}
}

PUT /api/pixelprograms

Overwrites full list of pixel programs.

PATCH /api/pixelprograms

Appends programs to existing list.

  • Required role: admin or designer

202 Accepted – returns before, after, newCredentials.


GET /api/secure/admin

Returns secured section from config.py.

  • Required role: admin

200 OK

{
  "secure": {"secure":"...","api-key":"..."},
  "newCredentials": {"user":"...","token":"..."}
}

GET /api/secure/users

Returns mapping of users to roles.

  • Required role: admin

200 OK

{
  "users": {
    "admin": ["admin"],
    "operator": ["editor"]
  },
  "newCredentials": {"user":"...","token":"..."}
}

POST /api/secure/users

Creates user and assigns groups.

  • Required role: admin

Body (JSON)

{
  "user":"operator",
  "pass":"StrongPassword123",
  "groups":["editor"]
}

200 OK

{
  "username":"operator",
  "groups":["editor"],
  "newCredentials":{"user":"admin","token":"..."}
}

Errors: 400, 401, 403, 409.


DELETE /api/secure/users/<username>

Deletes user (except admin) and related roles.

  • Required role: admin

200 OK

{
  "username":"operator",
  "groups":["editor"],
  "newCredentials":{"user":"admin","token":"..."}
}

5.3 “secure header” endpoint

POST /api/secure/admin/reset

Emergency reset of admin account password.

Required headers

  • secure: <config.secured['secure']>

Body (JSON)

{"pass":"NewAdminPassword"}

Response codes

  • 202 Accepted – password changed
  • 400 Bad Request – missing pass
  • 401 Unauthorized – wrong/missing secure
  • 406 Not Acceptable – password too short
  • 500 Internal Server Error – save error

5.4 Login

POST /api/secure/auth

User login endpoint.

Header

  • Authorization: Basic base64(user:pass)

200 OK

{"token":"...","user":"admin"}

401 Unauthorized – invalid credentials.


5.5 Fallback endpoint

For non-existing paths backend returns:

  • 404
  • body: {"massage": "Page not exists"}

6. Quick curl examples

Login

curl -X POST http://<DEVICE_IP>/api/secure/auth \
  -H "Authorization: Basic $(printf 'admin:administrator' | base64)"

Public data read

curl http://<DEVICE_IP>/api/current-state

Configuration update (PATCH /api/data)

curl -X PATCH http://<DEVICE_IP>/api/data \
  -H "Content-Type: application/json" \
  -H "user: admin" \
  -H "token: <TOKEN>" \
  -d '{"brightness":128,"on":true}'

Admin password reset with secure

curl -X POST http://<DEVICE_IP>/api/secure/admin/reset \
  -H "Content-Type: application/json" \
  -H "secure: <CONFIG_SECURED_SECURE>" \
  -d '{"pass":"NewAdminPassword"}'

7. USB installation on Raspberry Pi Pico 2 W

A practical and safe deployment path:

  1. Flash MicroPython UF2

    • Disconnect Pico from USB.
    • Hold BOOTSEL and connect USB.
    • Pico appears as RPI-RP2 mass storage.
    • Copy MicroPython .uf2 firmware for Pico 2 W.
  2. Copy project files to device

    • Most convenient via Thonny (Interpreter: MicroPython (Raspberry Pi Pico)).
    • Copy to device storage:
      • main.py, myhttp.py, waterflowdriver.py, waterflowpixel.py, auth.py, utils.py, config.py, ktime.py, neopixel.py
      • lib/ folder
      • required JSON files (net.json, users.json, groups.json, data.json, pixelprograms.json) configured for your environment.
  3. Adjust configuration before first run

    • Set unique values in config.py, especially:
      • secured['secure']
      • device['uuid']
    • Set Wi‑Fi/AP credentials in net.json.
  4. Restart and test API

    • Restart device (soft/hard reset).
    • Read IP from serial/log output.
    • Verify GET /api/info and POST /api/secure/auth.

8. Security best practices

  • Do not use example secrets or UUIDs in production.
  • Use strong user passwords (minimum 7 chars required; significantly longer recommended).
  • Restrict network access to API (VLAN/firewall).
  • Treat tokens as sensitive secrets (API rotates them frequently).

9. Project status

This repository contains MicroPython application firmware for a Pico 2 W based LED controller with a REST API for remote management.

About

A modular unit for controlling and rendering pixel-based water flow effects in real time, designed for integration with programmable LED systems and custom graphics pipelines

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages