An IoT device management platform written in Python. It provides a REST API for devices and a web-based management UI, both served from a single process — no database, no message queue, no external services required to get started.
- Features
- Quick Start
- Screenshots
- Tech Stack
- Documentation
- Deployment
- Open Questions / TODO
- Contributing
- Licence
- Project & device management — organise devices into projects, manage metadata and lifecycle via a web UI
- Token-based provisioning — devices self-register using a project-scoped provisioning token and receive a short-lived device token in return
- Telemetry ingestion & charting — devices push measurements; nice4iot forwards them to a time-series backend (Prometheus remote write or InfluxDB line protocol) and always stores the last 2 000 readings locally. The Data tab charts directly from the configured backend (long history) and falls back to the local ring buffer when none is set up. Recommended backend: VictoriaMetrics via the Prometheus backend —
push_url: http://host:8428/api/v1/write,pull_url: http://host:8428/api/v1/ - Log ingestion — devices push log lines; nice4iot forwards them to a log backend (Grafana Loki or a Loki-compatible endpoint such as VictoriaLogs, or a local file); the UI shows a live tail of the file log
- HTTP forwarding — authenticated devices can proxy arbitrary requests through the platform to configured backend URLs
- File serving, upload & editing — devices can fetch and upload files; device-specific files take precedence over project-wide defaults (ETag caching supported). In the UI, browse files with a drill-down editor, preview images, and edit JSON as raw text or as a form — optionally driven by an uploaded schema you approve (docs/concepts.md)
- Auto-generated UI — forms and tables are derived from Pydantic models via niceview, keeping model and UI in sync without boilerplate
- Alarm system — per-project alarm rules (metric thresholds + built-in device-offline rule); state-based with acknowledgment; alarm panels on project and device dashboards
- System health — project dashboard shows live green/red status for MQTT, telemetry, and logging backends; external-call errors are captured without raising exceptions
- Extensions — separately deployed packages can add their own REST endpoints, MQTT pub/sub, and UI cards/tabs, and get notified when a new device is provisioned; see docs/extensions.md
- Admin UI authentication — optional, pluggable (
none/proxy/password), disabled by default
| Page | Tabs |
|---|---|
| Projects list | — card grid |
| Project | Dashboard · General · Provisioning · Files · Devices |
| Device | Dashboard · General · Files · Data · Logs · Alarms |
Requires Python 3.12+ and uv.
git clone https://github.com/clausgf/nice4iot.git
cd nice4iot
uv sync
mkdir -p data/projects
uv run uvicorn app.main:app --reload --port 8000Open http://localhost:8000 for the management UI, or http://localhost:8000/docs for the interactive API documentation. Create a project, generate a provisioning token under Provisioning, then simulate a device without any hardware:
uv run python tools/device_client.py cycle \
--url http://localhost:8000 --project myproject --device mydevice \
--token <provisioning_token> \
--sensors '{"temperature": 22.4, "humidity": 60}' --log "Device started"For running it as a service, see Deployment. For development details, see docs/development.md.
Telemetry Explorer — the device Data tab charts directly from the configured backend, falling back to the local ring buffer (shown here) when none is set up.
Device table — every device in a project with its live status, location, last-seen time, and active-alarm count.
Alarm rules — per-project metric thresholds and the built-in device-offline rule; forms are generated from the Pydantic models via niceview.
| Layer | Technology |
|---|---|
| Web framework | FastAPI |
| Web UI | NiceGUI (Quasar/Vue under the hood) |
| Data modelling | Pydantic v2 |
| UI generation | niceview (custom library) |
| Telemetry backends | Prometheus remote write · InfluxDB line protocol |
| Log backends | Grafana Loki / VictoriaLogs (Loki push API) · rotating file |
| Persistence | Filesystem (JSON files + JSONL) |
| Package management | uv |
| Runtime | uvicorn |
| Deployment | Docker / Docker Compose |
FastAPI and NiceGUI share a single uvicorn process via ui.run_with(app, ...). The REST API is reachable at /api/*; the NiceGUI UI occupies all other paths via ui.sub_pages.
Full documentation lives in docs/:
| Document | Contents |
|---|---|
| What is an IoT manager? | The problem nice4iot solves, for readers new to the category |
| Core Concepts | Data storage, token model, device lifecycle, file editing and schema forms, firmware distribution, alarms, system health |
| Device API Reference | The REST contract devices depend on, plus the device simulator |
| Configuration | Environment variables and UI authentication |
| MQTT Support | Topic layout, file delivery, broker settings |
| Architecture | Module layout and the design decisions behind it |
| Extensions | Adding endpoints, MQTT handlers, and UI from a separate package |
| Development | Setup, running from source, tests, linting |
| Deployment | Container image and Docker Compose examples |
A container image and three Docker Compose files live in deploy/ —
a pre-built image from GHCR (recommended), a build-it-yourself variant, and a
development one with live reload:
cd deploy
mkdir -p data # once, owned by your user
docker compose -f compose-ghcr.yml pull && docker compose -f compose-ghcr.yml up -dThe production files run nice4iot behind an external reverse proxy (it joins a proxy Docker network and only exposes port 8080 internally); deploy/Caddyfile is a copy-ready example for that proxy. Releases are published to ghcr.io/clausgf/nice4iot on every v* tag. See deploy/README.md for the details — including the security note to read before exposing nice4iot to a network, serving under a sub-path, serving e-paper images over plain HTTP to displays that can't do TLS, and the epaper extension (built in by default).
- Forwarding security — forwarding strips the
Authorizationheader but forwards all other client headers verbatim; review whether this is appropriate for all backends. - Multi-user / RBAC — all UI operators share the same access level.
- Backup and restore — no tooling or documentation for backup, restore, or migration of the
data/projects/directory. - Pagination — project and device lists load all items into memory; large deployments will need pagination.
- Telemetry read from InfluxDB — the Data tab reads from Prometheus-compatible backends (Prometheus, VictoriaMetrics, Mimir) with local fallback; a read path for the InfluxDB line-protocol backend (InfluxQL/Flux) is not implemented.
- MQTT device commands —
{base}/cmd/{name}downlink topic for server-to-device commands is planned. - MQTT authentication — currently managed by the broker. A future version will integrate with Mosquitto's Dynamic Security Plugin for per-device credential provisioning from the UI.
- device/data_ui.py - which backend shall we use? Influx is write only, thus now we no use the file backend which is always active.
Issues and pull requests are welcome — see CONTRIBUTING.md for the development setup and the project rules enforced in review. For security issues please use private reporting rather than a public issue.
nice4iot is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). The full text is in LICENSE.
In short: you may use, modify, and redistribute it, provided derivative works stay under the same licence. The AGPL additionally covers network use — if you run a modified version as a service that others interact with over a network, you must offer them its source code. Running an unmodified nice4iot for your own devices carries no such obligation; the UI links to this repository from the user menu.



