{"id":49075273,"url":"https://github.com/mangobanaani/weatherprobe","last_synced_at":"2026-04-20T09:36:24.385Z","repository":{"id":341540945,"uuid":"1170291030","full_name":"mangobanaani/weatherprobe","owner":"mangobanaani","description":"Solar-powered ESP32 weather station -- BME280, GPS, MQTT/TLS, SPIFFS offline buffer","archived":false,"fork":false,"pushed_at":"2026-03-02T08:28:24.000Z","size":46,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-02T12:32:52.426Z","etag":null,"topics":["bme280","esp-idf","esp32","gps","iot","mqtt","weather-station"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mangobanaani.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-02T00:38:11.000Z","updated_at":"2026-03-02T08:28:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mangobanaani/weatherprobe","commit_stats":null,"previous_names":["mangobanaani/weatherprobe"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mangobanaani/weatherprobe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mangobanaani%2Fweatherprobe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mangobanaani%2Fweatherprobe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mangobanaani%2Fweatherprobe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mangobanaani%2Fweatherprobe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mangobanaani","download_url":"https://codeload.github.com/mangobanaani/weatherprobe/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mangobanaani%2Fweatherprobe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32041848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"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":["bme280","esp-idf","esp32","gps","iot","mqtt","weather-station"],"created_at":"2026-04-20T09:36:20.180Z","updated_at":"2026-04-20T09:36:24.359Z","avatar_url":"https://github.com/mangobanaani.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WeatherProbe\n\nSolar-powered ESP32 weather station that collects temperature, humidity,\npressure, and GPS location every 5 minutes and publishes to GCP Pub/Sub\nvia MQTT over TLS.\n\n## Hardware\n\n| Component | Part | Interface |\n|-----------|------|-----------|\n| MCU | ESP32-WROOM-32 DevKit | -- |\n| Environment sensor | BME280 | I2C (addr 0x76) |\n| GPS receiver | NEO-M8N | UART @ 9600 baud |\n| Battery | 18650 Li-ion 3.7 V | ADC via voltage divider |\n| Solar panel | 6 V panel | TP4056 charge controller |\n\n## Wiring Diagram\n\n```mermaid\ngraph LR\n    subgraph Solar Power\n        SOLAR[\"6 V Solar Panel\"] --\u003e TP4056[\"TP4056\\nCharge Controller\"]\n        TP4056 --\u003e BAT[\"18650 Li-ion\\n3.7 V\"]\n    end\n\n    BAT --\u003e |VCC / GND| ESP32[\"ESP32-WROOM-32\"]\n\n    subgraph Voltage Divider\n        BAT --\u003e R1[\"R1\\n100 k\"]\n        R1 --\u003e MID((\" \"))\n        MID --\u003e R2[\"R2\\n100 k\"]\n        R2 --\u003e GND1[\"GND\"]\n    end\n    MID --\u003e |GPIO34 / ADC1_CH6| ESP32\n\n    subgraph BME280 Sensor\n        BME[\"BME280\\nTemp / Hum / Press\"]\n    end\n    ESP32 --\u003e |GPIO21 SDA| BME\n    ESP32 --\u003e |GPIO22 SCL| BME\n\n    subgraph GPS Module\n        GPS[\"NEO-M8N\\nGPS Receiver\"]\n    end\n    ESP32 --\u003e |GPIO17 TX2| GPS\n    GPS --\u003e |GPIO16 RX2| ESP32\n```\n\n## Data Path\n\n```mermaid\ngraph LR\n    ESP32[\"ESP32\"] --\u003e|MQTT / TLS| HMQ[\"HiveMQ Cloud\"]\n    HMQ --\u003e|Webhook| CF[\"GCP Cloud\\nFunction\"]\n    CF --\u003e|Publish| PS[\"Pub/Sub\\nweatherprobe-readings\"]\n    ESP32 -.-\u003e|Offline| SPIFFS[\"SPIFFS\\nRing Buffer\"]\n    SPIFFS -.-\u003e|Drain on reconnect| ESP32\n```\n\n## Wake Cycle\n\nEvery 5 minutes the firmware:\n\n1. Reads BME280 (temperature, humidity, pressure) over I2C\n2. Reads GPS (latitude, longitude, altitude) over UART -- 30 s timeout,\n   falls back to last-known position stored in RTC memory\n3. Reads battery voltage via ADC (16-sample average)\n4. Connects WiFi, synchronises time via SNTP\n5. Publishes a JSON reading to HiveMQ via MQTT/TLS (QoS 1)\n6. Drains up to 10 buffered readings from SPIFFS\n7. If publish fails, stores the reading in the SPIFFS ring buffer\n8. Enters deep sleep\n\n## JSON Payload\n\n```json\n{\n  \"device_id\": \"weatherprobe-01\",\n  \"ts\": 1709380800,\n  \"temp_c\": 22.5,\n  \"humidity_pct\": 45.2,\n  \"pressure_hpa\": 1013.25,\n  \"lat\": 60.1699,\n  \"lon\": 24.9384,\n  \"alt_m\": 15.3,\n  \"battery_pct\": 78,\n  \"battery_v\": 3.82,\n  \"gps_fix\": true\n}\n```\n\n## Project Structure\n\n```\nard_weatherprobe/\n├── CMakeLists.txt          Project-level CMake\n├── Makefile                Convenience wrapper for idf.py\n├── sdkconfig.defaults      ESP-IDF Kconfig defaults\n├── partitions.csv          Custom partition table (NVS + SPIFFS)\n├── provision.sh            Interactive credential provisioning\n├── main/\n│   ├── CMakeLists.txt      Component source list\n│   ├── main.c              Entry point and wake-cycle orchestration\n│   ├── config.h            Pin assignments, timing, buffer limits\n│   ├── sensor_bme280.c/h   BME280 I2C driver with Bosch compensation\n│   ├── sensor_gps.c/h      NEO-M8N UART NMEA GGA parser\n│   ├── battery.c/h         ADC battery voltage monitor\n│   ├── data_buffer.c/h     SPIFFS FIFO ring buffer\n│   ├── credentials.c/h     NVS credential loader\n│   └── wp_mqtt.c/h         WiFi STA + MQTT/TLS client\n└── cloud/\n    ├── cloud_function/\n    │   ├── main.py         GCP Cloud Function (MQTT webhook -\u003e Pub/Sub)\n    │   └── requirements.txt\n    └── pubsub_setup.sh     Create Pub/Sub topic and subscription\n```\n\n## Build\n\nRequires the [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/)\ntoolchain (v5.x).\n\n```sh\n# Build\nmake build\n\n# Flash and monitor (most common)\nmake fm\n\n# Override serial port\nmake flash PORT=/dev/ttyACM0\n\n# Provision WiFi and MQTT credentials to NVS\nmake provision\n\n# Other targets: clean, fullclean, menuconfig, size, erase\n```\n\nOr use `idf.py` directly:\n\n```sh\nidf.py build\nidf.py -p /dev/ttyUSB0 flash monitor\n```\n\n## Provisioning\n\nBefore first use, flash WiFi and MQTT credentials into the NVS partition:\n\n```sh\n./provision.sh\n```\n\nThe script prompts for WiFi SSID/password and MQTT broker details, then\nwrites them to the ESP32's NVS flash.  Credentials never appear in source\ncode.\n\n## Cloud Setup\n\n1. Create the Pub/Sub topic and subscription:\n   ```sh\n   cd cloud \u0026\u0026 bash pubsub_setup.sh\n   ```\n2. Deploy the Cloud Function:\n   ```sh\n   cd cloud/cloud_function\n   gcloud functions deploy weatherprobe-bridge \\\n       --runtime python312 \\\n       --trigger-http \\\n       --entry-point webhook \\\n       --set-env-vars GCP_PROJECT=\u003cproject\u003e,WEBHOOK_SECRET=\u003csecret\u003e\n   ```\n3. Configure HiveMQ Cloud to forward messages to the Cloud Function URL.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmangobanaani%2Fweatherprobe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmangobanaani%2Fweatherprobe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmangobanaani%2Fweatherprobe/lists"}