# 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)