143 lines
3.9 KiB
Markdown
143 lines
3.9 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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)
|