https://github.com/hannaszalai/iot-benchmonitor
ποΈβοΈ IoT project that monitors benches around Hungaryβs Lake Balaton, tracking temperature, humidity, sunlight, and visitor ratings. It collects real-time data to help people discover the most comfortable spots to relax by the lake.
https://github.com/hannaszalai/iot-benchmonitor
frontend influxdb iot iot-application javascript micropython rapberry-pi-pico-w
Last synced: 2 months ago
JSON representation
ποΈβοΈ IoT project that monitors benches around Hungaryβs Lake Balaton, tracking temperature, humidity, sunlight, and visitor ratings. It collects real-time data to help people discover the most comfortable spots to relax by the lake.
- Host: GitHub
- URL: https://github.com/hannaszalai/iot-benchmonitor
- Owner: hannaszalai
- License: gpl-3.0
- Created: 2025-06-19T19:20:50.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-07-09T09:00:03.000Z (12 months ago)
- Last Synced: 2025-07-09T10:19:49.520Z (12 months ago)
- Topics: frontend, influxdb, iot, iot-application, javascript, micropython, rapberry-pi-pico-w
- Language: Python
- Homepage:
- Size: 17.4 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## Table of Content
- [Author](#author)
- [Project Overview](#project-overview)
- [Estimated Time](#estimated-time)
- [Project Objective](#project-objective)
- [Bill of Material](#bill-of-material)
- [Setup and Installation Guide](#setup-and-installation-guide)
- [Wiring](#wiring)
- [Calculations](#calculations)
- [Environmental Comfort Calculation](#environmental-comfort-calculation)
- [Transmitting Data](#transmitting-data)
- [Data Storage and Visualization](#data-storage-and-visualization)
- [The Code](#the-code)
- [Development Phases](#development-phases)
## Author
Made by Hanna Szalai (hs223xt)
## Project Overview
Each summer, thousands of people circle Lake Balaton by bike or foot, searching for the **perfect bench to relax on**. But what makes a bench perfect? Is it the view, the temperature, the breeze, or the warm sunshine on your shoulders?
This small IoT project tries to figure that out.
A device was placed under one of Balatonβs most iconic benches to monitor:
- when people sit down,
- how warm and humid it is,
- how bright the sun is,
- plus it lets people vote with a 1β5 star button.
All this data flows into a colorful online dashboard, showing:
- real-time comfort scores,
- weather alerts,
- and historical trends.
Think of it as TripAdvisor for benches.
## Estimated Time
| Task | Time |
|------|------|
| Hardware prototyping | 1,5 hours |
| MicroPython firmware | 2 hours |
| Docker (TIG stack) setup | 3 hours |
| Frontend + dashboard | 2 hours |
| Testing | 1,5 hours |
| **Total:** | **~10 hours** |
## Project Objective
Build a low-power, WiFi-based device to monitor bench comfort and user ratings, save data in InfluxDB, and display it live on a custom Flask + Chart.js dashboard.
## Bill of Material
| Image | Component | Price (SEK) | Source | Purpose |
|-------|-----------|-------------|--------|---------|
|
| Raspberry Pi Pico WH | 99 SEK | Electrokit | Main microcontroller with WiFi |
|
| Breadboard | 69 SEK | Electrokit | Prototyping platform |
|
| USB cable | 49 SEK | Electrokit | Power and programming |
|
| Lab cable M/M, F/M | 49 SEK | Electrokit | Connections between components |
|
| Digital temperature and humidity sensor DHT11 | 49 SEK | Electrokit | Environmental sensing |
|
| TLV49645 SIP-3 Hall effect sensor digital | 12,5 SEK | Electrokit | Magnetic field detection |
|
| MCP9700 TO-92 Temperature sensor | 11,5 SEK | Electrokit | Temperature monitoring |
|
| Photoresistor CdS 4-7 kohm | 9 SEK | Electrokit | Light level detection |
|
| LEDs | 15 SEK | Electrokit | Status indicators |
|
| Carbon film resistors | 25 SEK | Electrokit | Current limiting |
|
| Magnet Neo35 Γ5mm x 5mm | 11 SEK | Electrokit | Hall sensor trigger |
|
| Tactile switch PCB 6x6x5mm black | 1,25 SEK | Electrokit | User input button |
| | **TOTAL** | **~400 SEK** | | |
## Setup and Installation Guide
### Step 1: Clone the repository
```bash
git clone https://github.com/hannaszalai/IoT-benchmonitor.git
```
### Step 2: Raspberry Pi Pico W Configuration
#### Install MicroPython Firmware
1. Download the latest MicroPython firmware for Pico W from the [official repository](https://micropython.org/download/RPI_PICO_W/)
2. Hold the **BOOTSEL** button while connecting the Pico W to your computer via USB
3. The Pico W will appear as a removable drive (RPI-RP2)
4. Copy the downloaded `.uf2` file to the drive
5. The device will automatically reboot with MicroPython installed
#### Configure Development Environment
Install these VS Code extensions:
**Python Extension:**
**MicroPico Extension:**
#### Connect and Deploy Code
1. Disconnect and reconnect the Pico W
2. Open VS Code in the project directory
3. Press `Ctrl + Shift + P`
4. Select **"MicroPico: Connect"**
5. Navigate to `micropython/main.py`
6. Click **"Run"** in the status bar to deploy the code
### Step 3: Infrastructure Setup
#### Install Docker Desktop
Download Docker Desktop from the [official website](https://docs.docker.com/get-started/introduction/get-docker-desktop/)
#### Deploy Database Services
Start the InfluxDB container in the background:
```bash
docker-compose up -d
```
### Step 4: Web Setup
#### Start the Flask Server
```bash
cd web
python server.py
```
### Step 5: Access the Dashboard
Open your web browser and navigate to:
```
http://127.0.0.1:5000
```
You should see the real-time bench monitoring dashboard with live sensor data.
## Wiring
## Calculations
### β Disclaimer
This is an approximation. Do not rely solely on these calculations if you want to replicate this project.
Always verify all connections, resistor values, and current ratings yourself to ensure safety and proper functioning.
| Component | Operating Voltage | Current (approx) | Resistor Needed | Remarks |
|-----------------------------------|-------------------|------------------|-----------------|-----------------------------------|
| Raspberry Pi Pico W | 3.3V | ~50 mA idle | - | Powers everything, connects via WiFi |
| DHT11 Temp+Humidity Sensor | 3.3V | ~2.5 mA | - | On `GP17` (Pin 22) |
| MCP9700 Analog Temp Sensor | 3.3V | <1 mA | - | On `ADC2` (GP28) |
| CdS Photoresistor (light sensor) | 3.3V | <1 mA | Voltage divider | On `ADC0` (GP26) & `ADC1` (GP27) |
| Hall Effect Sensor | 3.3V | ~4 mA | - | On `GP16` (Pin 21), detects sitting |
| 3x Status LEDs (green/yellow/red) | 3.3V | ~20 mA each | ~220Ξ© each | On `GP8`, `GP9`, `GP10` |
| 2x Bench LEDs | 3.3V | ~20 mA each | ~220Ξ© each | On `GP6`, `GP7` |
| 5x Rating Buttons | - | - (pulled up) | - | On `GP11-15`, uses internal pull-up |
| WiFi Module (built-in) | 3.3V | ~50-120 mA active| - | For HTTP uploads |
**Total Estimated Current:**
β 50 mA (Pico) + sensors + LEDs + WiFi peaks β 150-180 mA max
### Environmental Comfort Calculation
The device uses several calculations to interpret environmental readings in `main.py`:
#### 1. ADC to Voltage Conversion
```python
def read_voltage(adc):
return adc.read_u16() * VREF / ADC_RES
# Constants:
VREF = 3.3 # ADC reference voltage
ADC_RES = 65535 # 16-bit ADC resolution
```
#### 2. MCP9700 Temperature Sensor Reading
```python
def read_mcp9700_temp():
voltage = read_voltage(adc_mcp)
return round((voltage - MCP9700_V0) / MCP9700_TCOEFF, 1)
# Constants:
MCP9700_V0 = 0.5 # 500mV at 0Β°C
MCP9700_TCOEFF = 0.01 # 10mV per Β°C
```
#### 3. Heat Index "Feels-Like" Calculation (Rothfusz Regression)
```python
def compute_heat_index(temp_c, humidity):
# Convert to Fahrenheit
T = temp_c * 9 / 5 + 32
R = humidity
# Heat index formula
HI = -42.379 + 2.04901523*T + 10.14333127*R \
- 0.22475541*T*R - 0.00683783*T*T \
- 0.05481717*R*R + 0.00122874*T*T*R \
+ 0.00085282*T*R*R - 0.00000199*T*T*R*R
# Convert back to Celsius
return round((HI - 32) * 5 / 9, 1)
```
#### 4. Sun/Shade Detection
```python
sun_voltage = read_voltage(adc_sun)
shade_voltage = read_voltage(adc_shade)
sun_score = round(sun_voltage - shade_voltage, 2)
# Classification:
if sun_score < 0.2:
status = "Mostly shaded"
elif sun_score < 0.6:
status = "Partial sun"
else:
status = "Full sun exposure"
```
#### 5. Rain Chance Estimation
```python
rain_chance = "Low"
if dht_hum > 90:
if last_dht_temp is not None and dht_temp < last_dht_temp:
rain_chance = "High"
elif last_dht_temp is None:
rain_chance = "Unknown"
```
#### 6. User Rating Average
```python
# When button pressed (1-5 stars):
total_reviews += 1
total_score += stars
avg_score = round(total_score / total_reviews, 2)
```
## Transmitting Data
- The Raspberry Pi Pico W reads all sensors and user inputs, then transmits data **every 2 seconds** over WiFi (2.4 GHz) to a local InfluxDB server.
- It uses the built-in HTTP POST (via urequests), sending data in InfluxDBβs line protocol format like:
``` python
bench_data dht_temp=25.6,dht_hum=48,feels_like=26.9,rain=0,sun_score=0.3,sitting=1,avg_score=4.2,total_reviews=5
```
- Data is sent directly to the InfluxDB HTTP API running in Docker on the local network.
- From there, itβs queried by the Flask server and visualized live in the browser with Chart.js.
- LoRa or MQTT werenβt needed since the benches stay close to local WiFi, and I didn't have additional hardware to support anything besides WiFi.
I chose WiFi mainly for its simplicity, immediate availability, and because itβs built into the Pico W. This allowed using standard HTTP requests without extra modules. However, WiFi draws more power (~120β―mA during uploads) and is best for nearby infrastructure with constant power. If the project needed to work kilometers away or run on batteries for weeks, a LoRa solution would be better for their much lower current consumption and extended range, but with more complex gateways and slower data rates. For this bench logger, WiFi provided an easier solution.
## Data Storage and Visualization
### Storage
- Data is saved in InfluxDB on each send (every 2s) and kept for full history.
- Influx was chosen for time-series data, and the Pico automates everything by pushing readings in a loop.
### Visualization
- The dashboard is a simple HTML + CSS page with Chart.js that updates every 2 seconds from Flask + InfluxDB.
## The Code
The project consists of three main components: MicroPython firmware for the Pico W, a Flask web server, and Docker services for data storage and visualization. (TIG)
#### `main.py` - Main Sensor Loop
The heart of the IoT device, running continuously on the Pico W:
- **Sensor Reading**: Polls DHT11, MCP9700, photoresistors, hall sensor, and buttons every 2 seconds
- **Data Processing**: Applies environmental calculations (heat index, sun/shade detection, rain estimation)
- **LED Control**: Updates status LEDs based on sensor readings and user interactions
- **Data Transmission**: Sends all collected data to InfluxDB via WiFi
Key features:
- Non-blocking button detection with debouncing
- Real-time comfort scoring based on multiple sensors
- Automatic WiFi reconnection handling
- Error handling for sensor failures
#### `wifiConnection.py` - WiFi Management
Handles network connectivity:
- Connects to specified WiFi network with credentials
- Returns assigned IP address for debugging
- Implements retry logic for connection failures
- Manages power-saving WiFi modes
#### `influxSender.py` - Data Transmission
Manages communication with the database:
- Formats sensor data into InfluxDB line protocol
- Sends HTTP POST requests to InfluxDB API
- Handles authentication with API tokens
- Provides error feedback for failed transmissions
### Flask Web Application
#### `server.py` - Backend Server
Python Flask server that bridges the database and frontend:
- **Data Retrieval**: Queries InfluxDB for latest sensor readings and historical data
- **API Endpoints**: Provides JSON data for the frontend to consume
- **Real-time Updates**: Serves fresh data every 2 seconds to match Pico transmission rate
- **Static File Serving**: Hosts the HTML dashboard and assets
#### `index.html` - Dashboard Frontend
Single-page application displaying real-time bench data:
- **Live Status Cards**: Shows current temperature, humidity, occupancy, and ratings
- **Interactive Charts**: Real-time graphs using Chart.js for trends over time
- **Responsive Design**: Works on desktop and mobile devices
- **Auto-refresh**: Updates every 2 seconds without page reload
#### `static/script.js` - Frontend Logic
JavaScript handling the dynamic behavior:
- Fetches data from Flask API endpoints
- Updates Chart.js graphs with new data points
- Manages real-time status card updates
- Handles error states and connection issues
#### `static/styles.css` - Dashboard Styling
Modern CSS styling for the dashboard:
- Clean, responsive layout using CSS Grid and Flexbox
- Color-coded status indicators for different comfort levels
- Smooth animations for data updates
- Mobile-first responsive design
### Infrastructure & Data Storage
#### `docker-compose.yml` - Service Orchestration
Defines the complete data stack:
- **InfluxDB**: Time-series database for sensor data storage
Benefits of this architecture:
- **Scalable**: Easy to add more Pico devices or sensors
- **Reliable**: Database persistence and automatic restarts
- **Portable**: Entire stack runs anywhere Docker is available
### File Structure
```
IoT-benchmonitor/
βββ README.md
βββ LICENSE
βββ docker-compose.yml # Docker services
β
βββ micropython/
β βββ main.py # Main sensor loop
β βββ wifiConnection.py # WiFi connection helper
β βββ influxSender.py # Data transmission to InfluxDB
β
βββ web/
β βββ server.py # Flask backend server
β βββ index.html # Main dashboard page
β βββ static/
β βββ styles.css # Dashboard styling
β βββ script.js # Frontend JavaScript + Chart.js
β βββ images/
β βββ bench.png
β βββ icon.png
β
βββ assets/ # Documentation images
βββ images/
βββ header.png
βββ map.png
βββ micropico.png
βββ ...
```
### Development Phases
Outline the project in phases:
1. Phase β Terminal output (basic testing)

3. Phase β Custom website with graphs and live data
