{"id":29462066,"url":"https://github.com/hannaszalai/iot-benchmonitor","last_synced_at":"2026-04-17T05:03:22.481Z","repository":{"id":300772321,"uuid":"1005163644","full_name":"hannaszalai/IoT-benchmonitor","owner":"hannaszalai","description":"🏞️☀️ 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.","archived":false,"fork":false,"pushed_at":"2025-07-09T09:00:03.000Z","size":18278,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-09T10:19:49.520Z","etag":null,"topics":["frontend","influxdb","iot","iot-application","javascript","micropython","rapberry-pi-pico-w"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hannaszalai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-19T19:20:50.000Z","updated_at":"2025-07-09T09:00:06.000Z","dependencies_parsed_at":"2025-07-09T10:19:53.732Z","dependency_job_id":"5c949fee-9a18-48cf-ba09-0bc8f222f98e","html_url":"https://github.com/hannaszalai/IoT-benchmonitor","commit_stats":null,"previous_names":["hannaszalai/iot-benchmonitor"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hannaszalai/IoT-benchmonitor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannaszalai%2FIoT-benchmonitor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannaszalai%2FIoT-benchmonitor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannaszalai%2FIoT-benchmonitor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannaszalai%2FIoT-benchmonitor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hannaszalai","download_url":"https://codeload.github.com/hannaszalai/IoT-benchmonitor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannaszalai%2FIoT-benchmonitor/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267505099,"owners_count":24098346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["frontend","influxdb","iot","iot-application","javascript","micropython","rapberry-pi-pico-w"],"created_at":"2025-07-14T04:00:47.432Z","updated_at":"2026-04-17T05:03:22.428Z","avatar_url":"https://github.com/hannaszalai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"assets/images/readme-title.png\" alt=\"Lake Balaton Bench Logger\" width=\"350\"\u003e\n\u003c/div\u003e\n\n## Table of Content\n- [Author](#author)  \n- [Project Overview](#project-overview)  \n- [Estimated Time](#estimated-time)\n- [Project Objective](#project-objective)  \n- [Bill of Material](#bill-of-material)  \n- [Setup and Installation Guide](#setup-and-installation-guide)  \n- [Wiring](#wiring)  \n- [Calculations](#calculations)\n- [Environmental Comfort Calculation](#environmental-comfort-calculation)  \n- [Transmitting Data](#transmitting-data)  \n- [Data Storage and Visualization](#data-storage-and-visualization)  \n- [The Code](#the-code)  \n- [Development Phases](#development-phases)  \n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"assets/images/header.png\" alt=\"Lake Balaton Bench\" width=\"500\"\u003e\n\u003c/div\u003e\n\n## Author\nMade by Hanna Szalai (hs223xt)\n\n## Project Overview  \nEach 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?  \nThis small IoT project tries to figure that out.  \nA device was placed under one of Balaton’s most iconic benches to monitor:\n- when people sit down,\n- how warm and humid it is,\n- how bright the sun is,\n- plus it lets people vote with a 1–5 star button.  \nAll this data flows into a colorful online dashboard, showing:\n- real-time comfort scores,\n- weather alerts,\n- and historical trends.  \nThink of it as TripAdvisor for benches.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"assets/images/map.png\" alt=\"Map\" width=\"400\"\u003e\n\u003c/div\u003e\n\n\n## Estimated Time\n\u003cdiv align=\"center\"\u003e\n\n| Task | Time |\n|------|------|\n| Hardware prototyping | 1,5 hours |\n| MicroPython firmware | 2 hours |\n| Docker (TIG stack) setup | 3 hours |\n| Frontend + dashboard | 2 hours |\n| Testing | 1,5 hours |\n| **Total:** | **~10 hours** |\n\n\u003c/div\u003e\n\n## Project Objective\nBuild 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.\n\n## Bill of Material\n| Image | Component | Price (SEK) | Source | Purpose |\n|-------|-----------|-------------|--------|---------|\n| \u003cimg src=\"https://www.electrokit.com/cache/ba/700x700-product_41019_41019114_PICO-WH-HERO.jpg\" alt=\"Raspberry Pi Pico W\" width=\"100\"\u003e | Raspberry Pi Pico WH | 99 SEK | Electrokit | Main microcontroller with WiFi |\n| \u003cimg src=\"https://www.electrokit.com/upload/product/10160/10160840/10160840.jpg\" alt=\"Breadboard\" width=\"100\"\u003e | Breadboard | 69 SEK | Electrokit | Prototyping platform |\n| \u003cimg src=\"https://vilros.com/cdn/shop/products/Micro-USB-Cable_ab6b931f-d217-4399-b7f9-0b37495ee98a.jpg?v=1615916114\" alt=\"USB cable\" width=\"100\"\u003e | USB cable | 49 SEK | Electrokit | Power and programming |\n| \u003cimg src=\"https://techfun.hu/wp-content/uploads/2017/09/kabliky-20-cm-M-F.jpg\" alt=\"Lab cable M/M, F/M\" width=\"100\"\u003e | Lab cable M/M, F/M | 49 SEK | Electrokit | Connections between components |\n| \u003cimg src=\"https://www.electrokit.com/upload/product/41015/41015728/41015728.jpg\" alt=\"DHT11 sensor\" width=\"100\"\u003e | Digital temperature and humidity sensor DHT11 | 49 SEK | Electrokit | Environmental sensing |\n| \u003cimg src=\"https://www.electrokit.com/upload/product/41017/41017004/41013729.jpg\" alt=\"Hall effect sensor\" width=\"100\"\u003e | TLV49645 SIP-3 Hall effect sensor digital | 12,5 SEK | Electrokit | Magnetic field detection |\n| \u003cimg src=\"https://www.electrokit.com/upload/product/common/TO-92.jpg\" alt=\"MCP9700 temperature sensor\" width=\"100\"\u003e | MCP9700 TO-92 Temperature sensor | 11,5 SEK | Electrokit | Temperature monitoring |\n| \u003cimg src=\"https://cdn11.bigcommerce.com/s-yo2n39m6g3/images/stencil/1280x1280/products/704/4600/31U4JA_4gVL__53211.1600158986.jpg?c=2\" alt=\"Photoresistor\" width=\"100\"\u003e | Photoresistor CdS 4-7 kohm | 9 SEK | Electrokit | Light level detection |\n| \u003cimg src=\"https://www.arborsci.com/cdn/shop/products/red_green_blue_LEDs_1500x1000_ed3ff09f-4d16-4078-b543-09328397583a.jpg?v=1618408505\" alt=\"LEDs\" width=\"100\"\u003e | LEDs | 15 SEK | Electrokit | Status indicators |\n| \u003cimg src=\"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSYS5MRbPo3chgwaMeB4KWvihCI8anBmW69WA\u0026s\" alt=\"Carbon film resistors\" width=\"100\"\u003e | Carbon film resistors | 25 SEK | Electrokit | Current limiting |\n| \u003cimg src=\"https://www.electrokit.com/upload/product/41011/41011480/41011480.jpg\" alt=\"Neodymium magnet\" width=\"100\"\u003e | Magnet Neo35 Ø5mm x 5mm | 11 SEK | Electrokit | Hall sensor trigger |\n| \u003cimg src=\"https://www.electrokit.com/upload/quick/33/77/2c0e_41001412-1.jpg\" alt=\"Tactile switch\" width=\"100\"\u003e | Tactile switch PCB 6x6x5mm black | 1,25 SEK | Electrokit | User input button |\n| | **TOTAL** | **~400 SEK** | | |\n\n## Setup and Installation Guide\n### Step 1: Clone the repository\n```bash\ngit clone https://github.com/hannaszalai/IoT-benchmonitor.git\n```\n\n### Step 2: Raspberry Pi Pico W Configuration\n\n#### Install MicroPython Firmware\n1. Download the latest MicroPython firmware for Pico W from the [official repository](https://micropython.org/download/RPI_PICO_W/)\n2. Hold the **BOOTSEL** button while connecting the Pico W to your computer via USB\n3. The Pico W will appear as a removable drive (RPI-RP2)\n4. Copy the downloaded `.uf2` file to the drive\n5. The device will automatically reboot with MicroPython installed\n\n#### Configure Development Environment\nInstall these VS Code extensions:\n\n**Python Extension:**\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"assets/images/python.png\" alt=\"Python Extension\" width=\"400\"\u003e\n\u003c/div\u003e\n\n**MicroPico Extension:**\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"assets/images/micropico.png\" alt=\"MicroPico Extension\" width=\"400\"\u003e\n\u003c/div\u003e\n\n#### Connect and Deploy Code\n1. Disconnect and reconnect the Pico W\n2. Open VS Code in the project directory\n3. Press `Ctrl + Shift + P`\n4. Select **\"MicroPico: Connect\"**\n5. Navigate to `micropython/main.py`\n6. Click **\"Run\"** in the status bar to deploy the code\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"assets/images/terminal_tut.png\" alt=\"MicroPico Run Command\" width=\"300\"\u003e\n\u003c/div\u003e\n\n### Step 3: Infrastructure Setup\n\n#### Install Docker Desktop\nDownload Docker Desktop from the [official website](https://docs.docker.com/get-started/introduction/get-docker-desktop/)\n\n#### Deploy Database Services\nStart the InfluxDB container in the background:\n```bash\ndocker-compose up -d\n```\n\n### Step 4: Web Setup\n\n#### Start the Flask Server\n```bash\ncd web\npython server.py\n```\n\n### Step 5: Access the Dashboard\nOpen your web browser and navigate to:\n```\nhttp://127.0.0.1:5000\n```\n\nYou should see the real-time bench monitoring dashboard with live sensor data.\n\n\n## Wiring\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://www.raspberrypi.com/documentation/microcontrollers/images/picow-pinout.svg\" alt=\"Pico\" width=\"300\"\u003e\n\u003cimg src=\"assets/images/fritzing.png\" alt=\"Pico\" width=\"500\"\u003e\n\u003c/div\u003e\n\n\n\n## Calculations\n\n### ⚠ Disclaimer\nThis is an approximation. Do not rely solely on these calculations if you want to replicate this project.  \nAlways verify all connections, resistor values, and current ratings yourself to ensure safety and proper functioning.\n\n\n| Component                        | Operating Voltage | Current (approx) | Resistor Needed | Remarks                           |\n|-----------------------------------|-------------------|------------------|-----------------|-----------------------------------|\n| Raspberry Pi Pico W               | 3.3V               | ~50 mA idle      | -               | Powers everything, connects via WiFi |\n| DHT11 Temp+Humidity Sensor        | 3.3V               | ~2.5 mA          | -               | On `GP17` (Pin 22) |\n| MCP9700 Analog Temp Sensor        | 3.3V               | \u003c1 mA            | -               | On `ADC2` (GP28) |\n| CdS Photoresistor (light sensor)  | 3.3V               | \u003c1 mA            | Voltage divider | On `ADC0` (GP26) \u0026 `ADC1` (GP27) |\n| Hall Effect Sensor                | 3.3V               | ~4 mA            | -               | On `GP16` (Pin 21), detects sitting |\n| 3x Status LEDs (green/yellow/red) | 3.3V               | ~20 mA each      | ~220Ω each      | On `GP8`, `GP9`, `GP10` |\n| 2x Bench LEDs                     | 3.3V               | ~20 mA each      | ~220Ω each      | On `GP6`, `GP7` |\n| 5x Rating Buttons                 | -                  | - (pulled up)    | -               | On `GP11-15`, uses internal pull-up |\n| WiFi Module (built-in)            | 3.3V               | ~50-120 mA active| -               | For HTTP uploads |\n\n**Total Estimated Current:**  \n≈ 50 mA (Pico) + sensors + LEDs + WiFi peaks ≈ 150-180 mA max\n\n\n### Environmental Comfort Calculation  \nThe device uses several calculations to interpret environmental readings in `main.py`:\n\n#### 1. ADC to Voltage Conversion\n```python\ndef read_voltage(adc):\n    return adc.read_u16() * VREF / ADC_RES\n\n# Constants:\nVREF = 3.3        # ADC reference voltage\nADC_RES = 65535   # 16-bit ADC resolution\n```\n\n#### 2. MCP9700 Temperature Sensor Reading\n```python\ndef read_mcp9700_temp():\n    voltage = read_voltage(adc_mcp)\n    return round((voltage - MCP9700_V0) / MCP9700_TCOEFF, 1)\n\n# Constants:\nMCP9700_V0 = 0.5      # 500mV at 0°C\nMCP9700_TCOEFF = 0.01 # 10mV per °C\n```\n\n#### 3. Heat Index \"Feels-Like\" Calculation (Rothfusz Regression)\n```python\ndef compute_heat_index(temp_c, humidity):\n    # Convert to Fahrenheit\n    T = temp_c * 9 / 5 + 32\n    R = humidity\n\n    # Heat index formula\n    HI = -42.379 + 2.04901523*T + 10.14333127*R \\\n         - 0.22475541*T*R - 0.00683783*T*T \\\n         - 0.05481717*R*R + 0.00122874*T*T*R \\\n         + 0.00085282*T*R*R - 0.00000199*T*T*R*R\n\n    # Convert back to Celsius\n    return round((HI - 32) * 5 / 9, 1)\n```\n\n#### 4. Sun/Shade Detection\n```python\nsun_voltage = read_voltage(adc_sun)\nshade_voltage = read_voltage(adc_shade)\nsun_score = round(sun_voltage - shade_voltage, 2)\n\n# Classification:\nif sun_score \u003c 0.2:\n    status = \"Mostly shaded\"\nelif sun_score \u003c 0.6:\n    status = \"Partial sun\"\nelse:\n    status = \"Full sun exposure\"\n```\n\n#### 5. Rain Chance Estimation\n```python\nrain_chance = \"Low\"\nif dht_hum \u003e 90:\n    if last_dht_temp is not None and dht_temp \u003c last_dht_temp:\n        rain_chance = \"High\"\n    elif last_dht_temp is None:\n        rain_chance = \"Unknown\"\n```\n\n#### 6. User Rating Average\n```python\n# When button pressed (1-5 stars):\ntotal_reviews += 1\ntotal_score += stars\navg_score = round(total_score / total_reviews, 2)\n```\n\n## Transmitting Data\n- 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.\n- It uses the built-in HTTP POST (via urequests), sending data in InfluxDB’s line protocol format like:\n\n``` python\nbench_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\n```\n- Data is sent directly to the InfluxDB HTTP API running in Docker on the local network.\n- From there, it’s queried by the Flask server and visualized live in the browser with Chart.js.\n- 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.\n\nI 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.\n\n## Data Storage and Visualization  \n### Storage  \n- Data is saved in InfluxDB on each send (every 2s) and kept for full history.\n- Influx was chosen for time-series data, and the Pico automates everything by pushing readings in a loop.\n\n### Visualization  \n- The dashboard is a simple HTML + CSS page with Chart.js that updates every 2 seconds from Flask + InfluxDB.\n\n## The Code\n\nThe 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)\n\n#### `main.py` - Main Sensor Loop\nThe heart of the IoT device, running continuously on the Pico W:\n- **Sensor Reading**: Polls DHT11, MCP9700, photoresistors, hall sensor, and buttons every 2 seconds\n- **Data Processing**: Applies environmental calculations (heat index, sun/shade detection, rain estimation)\n- **LED Control**: Updates status LEDs based on sensor readings and user interactions\n- **Data Transmission**: Sends all collected data to InfluxDB via WiFi\n\nKey features:\n- Non-blocking button detection with debouncing\n- Real-time comfort scoring based on multiple sensors\n- Automatic WiFi reconnection handling\n- Error handling for sensor failures\n\n#### `wifiConnection.py` - WiFi Management\nHandles network connectivity:\n- Connects to specified WiFi network with credentials\n- Returns assigned IP address for debugging\n- Implements retry logic for connection failures\n- Manages power-saving WiFi modes\n\n#### `influxSender.py` - Data Transmission\nManages communication with the database:\n- Formats sensor data into InfluxDB line protocol\n- Sends HTTP POST requests to InfluxDB API\n- Handles authentication with API tokens\n- Provides error feedback for failed transmissions\n\n### Flask Web Application\n\n#### `server.py` - Backend Server\nPython Flask server that bridges the database and frontend:\n- **Data Retrieval**: Queries InfluxDB for latest sensor readings and historical data\n- **API Endpoints**: Provides JSON data for the frontend to consume\n- **Real-time Updates**: Serves fresh data every 2 seconds to match Pico transmission rate\n- **Static File Serving**: Hosts the HTML dashboard and assets\n\n#### `index.html` - Dashboard Frontend\nSingle-page application displaying real-time bench data:\n- **Live Status Cards**: Shows current temperature, humidity, occupancy, and ratings\n- **Interactive Charts**: Real-time graphs using Chart.js for trends over time\n- **Responsive Design**: Works on desktop and mobile devices\n- **Auto-refresh**: Updates every 2 seconds without page reload\n\n#### `static/script.js` - Frontend Logic\nJavaScript handling the dynamic behavior:\n- Fetches data from Flask API endpoints\n- Updates Chart.js graphs with new data points\n- Manages real-time status card updates\n- Handles error states and connection issues\n\n#### `static/styles.css` - Dashboard Styling\nModern CSS styling for the dashboard:\n- Clean, responsive layout using CSS Grid and Flexbox\n- Color-coded status indicators for different comfort levels\n- Smooth animations for data updates\n- Mobile-first responsive design\n\n### Infrastructure \u0026 Data Storage\n\n#### `docker-compose.yml` - Service Orchestration\nDefines the complete data stack:\n- **InfluxDB**: Time-series database for sensor data storage\n\nBenefits of this architecture:\n- **Scalable**: Easy to add more Pico devices or sensors\n- **Reliable**: Database persistence and automatic restarts\n- **Portable**: Entire stack runs anywhere Docker is available\n\n### File Structure\n```\nIoT-benchmonitor/\n├── README.md\n├── LICENSE\n├── docker-compose.yml          # Docker services\n│\n├── micropython/             \n│   ├── main.py                # Main sensor loop\n│   ├── wifiConnection.py      # WiFi connection helper\n│   └── influxSender.py        # Data transmission to InfluxDB\n│\n├── web/                      \n│   ├── server.py              # Flask backend server\n│   ├── index.html             # Main dashboard page\n│   └── static/\n│       ├── styles.css         # Dashboard styling\n│       ├── script.js          # Frontend JavaScript + Chart.js\n│       └── images/\n│           ├── bench.png\n│           └── icon.png\n│\n└── assets/                    # Documentation images\n    └── images/\n        ├── header.png\n        ├── map.png\n        ├── micropico.png\n        └── ...\n```\n\n### Development Phases  \nOutline the project in phases:\n\n1. Phase – Terminal output (basic testing)  \n![alt text](assets/images/terminal-print.png)\n3. Phase – Custom website with graphs and live data\n![alt text](assets/images/frontend.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhannaszalai%2Fiot-benchmonitor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhannaszalai%2Fiot-benchmonitor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhannaszalai%2Fiot-benchmonitor/lists"}