Sensor Readouts
A Flask web application for managing and visualizing sensor data. It provides a REST API for creating sensors and storing readouts, along with a frontend dashboard that displays real-time charts and tabular data.
Tech Stack
- Python 3.13+
- Flask 3 — web framework
- SQLAlchemy (via Flask-SQLAlchemy) — ORM
- SQLite — database
- Alembic — database migrations
- Chart.js — frontend charting library
Project Structure
server/
├── app.py # Flask application factory and API routes
├── models.py # SQLAlchemy models (Sensor, SensorReadout)
├── seed.py # Database seeder with sample data
├── requirements.txt # Python dependencies
├── data.db # SQLite database (auto-created)
├── alembic.ini # Alembic configuration
├── alembic/ # Migration scripts
│ ├── env.py
│ └── versions/
└── templates/
├── sensors.html # Dashboard with chart and table
└── docs.html # API documentation page
Setup
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run database migrations
alembic upgrade head
# (Optional) Seed the database with sample data
python seed.py
Running
python app.py
The server starts on http://localhost:5000.
| Route | Description |
|---|---|
/sensors |
Dashboard with interactive chart and data table |
/api/docs |
API documentation with curl examples |
Database
Two tables are used:
sensor
| Column | Type | Description |
|---|---|---|
id |
Integer | Primary key |
name |
String(128) | Unique sensor name |
created_at |
DateTime | Creation timestamp (UTC) |
sensor_readout
| Column | Type | Description |
|---|---|---|
id |
Integer | Primary key |
sensor_id |
Integer | Foreign key to sensor.id |
type |
String(64) | Readout type (e.g. temperature, pressure, humidity) |
value |
Float | Measured value |
timestamp |
DateTime | Readout timestamp (UTC) |
Migrations
# Create a new migration after model changes
alembic revision --autogenerate -m "description"
# Apply pending migrations
alembic upgrade head
# Roll back one step
alembic downgrade -1
API
Base URL: http://localhost:5000/api
Endpoints
| Method | Path | Description |
|---|---|---|
GET |
/api/sensors |
List all sensors |
POST |
/api/sensors |
Create a new sensor |
GET |
/api/sensors/:id/types |
List readout types for a sensor |
GET |
/api/sensors/:id/readouts |
Latest readouts (max 300, filterable by ?type=) |
GET |
/api/sensors/:id/readouts/hourly |
Hourly averaged readouts (filterable by ?type=) |
POST |
/api/sensors/:id/readouts |
Add a new readout |
Examples
# List sensors
curl http://localhost:5000/api/sensors
# Create a sensor
curl -X POST http://localhost:5000/api/sensors \
-H "Content-Type: application/json" \
-d '{"name": "bmp280"}'
# Get temperature readouts for sensor 1
curl "http://localhost:5000/api/sensors/1/readouts?type=temperature"
# Get hourly averaged data
curl "http://localhost:5000/api/sensors/1/readouts/hourly?type=temperature"
# Add a readout
curl -X POST http://localhost:5000/api/sensors/1/readouts \
-H "Content-Type: application/json" \
-d '{"type": "temperature", "value": 22.5}'
Full API documentation with request/response examples is available at /api/docs.
Frontend
The dashboard at /sensors provides:
- Sensor dropdown — select a sensor from the list
- Type dropdown — select a readout type (populated based on the chosen sensor)
- Line chart — hourly averaged values rendered with Chart.js
- Data table — raw readouts with formatted timestamps (latest 300 entries)