Skip to main content

Complete Weather Station

Multi-sensor weather monitoring with MQTT, InfluxDB time-series storage, and Grafana visualization.

Overview

Build a complete weather station that reads temperature, humidity, pressure, and light level from I2C sensors. Data is published to MQTT for real-time consumption, stored in InfluxDB for historical analysis, and visualized with Grafana dashboards. This intermediate project teaches I2C sensor communication, MQTT publishing, and time-series data management.

Intermediate
Difficulty
6
Nodes Used
~30 min
Setup Time
I2C Bus
Interface

What You'll Need

Hardware

  • * Raspberry Pi (any model with I2C)
  • * BME280 sensor module (temp + humidity + pressure)
  • * BH1750 light sensor module
  • * Jumper wires (4 wires per sensor, shared I2C bus)

Software

  • * EdgeFlow installed on your Pi
  • * MQTT broker (Mosquitto recommended)
  • * InfluxDB 2.x installed (local or cloud)
  • * Grafana (optional, for dashboards)

Wiring Diagram

Both sensors share the same I2C bus (SDA/SCL). They use different I2C addresses so there is no conflict.

BME280 (addr: 0x76)

VCC → 3.3V (Pin 1)

GND → GND (Pin 9)

SDA → GPIO2 / SDA1 (Pin 3)

SCL → GPIO3 / SCL1 (Pin 5)

Some BME280 modules default to 0x77. Check your module and adjust in the node config.

BH1750 (addr: 0x23)

VCC → 3.3V (Pin 1)

GND → GND (Pin 9)

SDA → GPIO2 / SDA1 (Pin 3)

SCL → GPIO3 / SCL1 (Pin 5)

ADDR pin LOW = 0x23, ADDR pin HIGH = 0x5C. Leave floating for 0x23.

Enable I2C on Your Pi

I2C must be enabled before the sensors will work. Run these commands:

# Enable I2C interface
sudo raspi-config nonint do_i2c 0

# Verify I2C is enabled
ls /dev/i2c-*

# Scan for connected devices (should show 0x23 and 0x76)
sudo apt install -y i2c-tools
i2cdetect -y 1

You should see addresses 23 and 76 in the i2cdetect output grid.

Importable Flow JSON

Copy this JSON and import it via Menu → Import in the EdgeFlow editor.

{
  "name": "Complete Weather Station",
  "nodes": [
    {
      "id": "bme280_1",
      "type": "bme280",
      "name": "BME280 Sensor",
      "address": "0x76",
      "interval": 30,
      "x": 120,
      "y": 160
    },
    {
      "id": "bh1750_1",
      "type": "bh1750",
      "name": "BH1750 Light",
      "address": "0x23",
      "interval": 30,
      "mode": "continuous_high",
      "x": 120,
      "y": 320
    },
    {
      "id": "join_sensors",
      "type": "join",
      "name": "Combine Data",
      "mode": "custom",
      "count": 2,
      "build": "object",
      "propertyType": "msg",
      "property": "topic",
      "x": 340,
      "y": 240
    },
    {
      "id": "format_weather",
      "type": "function",
      "name": "Format Weather Data",
      "func": "var bme = msg.payload.bme280 || {};\nvar light = msg.payload.bh1750 || {};\nmsg.payload = {\n  temperature: Math.round(bme.temperature * 100) / 100,\n  humidity: Math.round(bme.humidity * 100) / 100,\n  pressure: Math.round(bme.pressure * 100) / 100,\n  light_lux: Math.round(light.lux || 0),\n  timestamp: Date.now(),\n  station: 'weather-pi-01'\n};\nreturn msg;",
      "x": 540,
      "y": 240
    },
    {
      "id": "mqtt_weather",
      "type": "mqtt-out",
      "name": "MQTT Publish",
      "broker": "localhost",
      "port": 1883,
      "topic": "home/weather",
      "qos": 1,
      "retain": true,
      "x": 760,
      "y": 180
    },
    {
      "id": "influx_write",
      "type": "influxdb",
      "name": "Store in InfluxDB",
      "url": "http://localhost:8086",
      "org": "edgeflow",
      "bucket": "weather_data",
      "measurement": "weather",
      "token": "YOUR_INFLUXDB_TOKEN",
      "x": 760,
      "y": 300
    },
    {
      "id": "mqtt_temp",
      "type": "mqtt-out",
      "name": "MQTT Temperature",
      "broker": "localhost",
      "port": 1883,
      "topic": "home/weather/temperature",
      "qos": 0,
      "x": 760,
      "y": 120
    },
    {
      "id": "split_topics",
      "type": "function",
      "name": "Split to Topics",
      "func": "var data = msg.payload;\nvar msgs = [];\nmsgs.push({ payload: data.temperature, topic: 'home/weather/temperature' });\nmsgs.push({ payload: data.humidity, topic: 'home/weather/humidity' });\nmsgs.push({ payload: data.pressure, topic: 'home/weather/pressure' });\nmsgs.push({ payload: data.light_lux, topic: 'home/weather/light' });\nreturn [msgs];",
      "outputs": 1,
      "x": 540,
      "y": 120
    },
    {
      "id": "debug_weather",
      "type": "debug",
      "name": "Weather Monitor",
      "x": 760,
      "y": 380
    }
  ],
  "connections": [
    { "from": "bme280_1", "to": "join_sensors" },
    { "from": "bh1750_1", "to": "join_sensors" },
    { "from": "join_sensors", "to": "format_weather" },
    { "from": "format_weather", "to": "mqtt_weather" },
    { "from": "format_weather", "to": "influx_write" },
    { "from": "format_weather", "to": "split_topics" },
    { "from": "format_weather", "to": "debug_weather" },
    { "from": "split_topics", "to": "mqtt_temp" }
  ]
}

Step-by-Step Walkthrough

1

Enable I2C and Wire Sensors

Enable I2C via raspi-config, then wire both sensors to the same I2C bus (SDA on GPIO2, SCL on GPIO3). Both sensors can share the same 3.3V and GND connections. Run i2cdetect -y 1 to verify both addresses appear.

2

Install and Configure Mosquitto MQTT Broker

sudo apt install -y mosquitto mosquitto-clients
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

# Test with a quick subscribe/publish
mosquitto_sub -t "test" &
mosquitto_pub -t "test" -m "hello"
# You should see "hello" printed
3

Install InfluxDB 2.x

# Install InfluxDB on Raspberry Pi
wget https://dl.influxdata.com/influxdb/releases/influxdb2_2.7.1-1_arm64.deb
sudo dpkg -i influxdb2_2.7.1-1_arm64.deb
sudo systemctl enable influxdb
sudo systemctl start influxdb

# Open http://YOUR_PI_IP:8086 to complete setup
# Create org: "edgeflow", bucket: "weather_data"
# Copy the generated API token
4

Import Flow and Configure Credentials

Import the flow JSON above into EdgeFlow. Then double-click the InfluxDB node and paste your API token, org name, and bucket name. If your MQTT broker uses authentication, update the MQTT nodes with username and password.

5

Deploy and Verify Data Flow

Click Deploy. Monitor the Debug panel for combined weather readings every 30 seconds. Verify MQTT messages arrive using a subscriber:

mosquitto_sub -t "home/weather/#" -v
6

Add Grafana Dashboard (Optional)

Install Grafana, add InfluxDB as a data source, and create panels for each measurement. A sample Flux query for the temperature panel:

from(bucket: "weather_data")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "weather")
  |> filter(fn: (r) => r._field == "temperature")
  |> aggregateWindow(every: 5m, fn: mean, createEmpty: false)

Configuration Details

Parameter Value Description
BME280 Address 0x76 I2C address (some modules use 0x77)
BH1750 Address 0x23 I2C address (ADDR pin LOW)
Poll Interval 30 seconds Both sensors read simultaneously
MQTT Topic home/weather Combined JSON payload; subtopics for individual values
MQTT QoS 1 (at least once) Guaranteed delivery for the combined topic
InfluxDB Bucket weather_data Measurement name: "weather"

MQTT Topic Structure

home/weather              ← Combined JSON (all readings)
home/weather/temperature  ← Float: 22.45
home/weather/humidity     ← Float: 58.3
home/weather/pressure     ← Float: 1013.25
home/weather/light        ← Integer: 4520

Expected Output

The formatted weather data published to MQTT and stored in InfluxDB:

{
  "temperature": 22.45,
  "humidity": 58.3,
  "pressure": 1013.25,
  "light_lux": 4520,
  "timestamp": 1707750000000,
  "station": "weather-pi-01"
}

InfluxDB stores each field as a separate column in the "weather" measurement:

_time temperature humidity pressure light_lux
2026-02-12T15:00:00Z 22.45 58.3 1013.25 4520
2026-02-12T15:00:30Z 22.51 57.9 1013.20 4485
2026-02-12T15:01:00Z 22.48 58.1 1013.22 4510

Troubleshooting

i2cdetect shows no devices
  • Verify I2C is enabled: sudo raspi-config nonint do_i2c 0
  • Check that SDA is on Pin 3 (GPIO2) and SCL is on Pin 5 (GPIO3)
  • Ensure sensors are powered (3.3V, not 5V for most I2C modules)
  • Try shorter wires or a different breadboard
MQTT messages are not arriving
  • Check Mosquitto is running: sudo systemctl status mosquitto
  • Verify the broker address is "localhost" if running on the same Pi
  • Test manually: mosquitto_pub -t test -m hello
  • Check firewall settings if connecting from another device
InfluxDB write errors
  • Verify the API token has write permissions for the bucket
  • Check org and bucket names match exactly (case-sensitive)
  • Confirm InfluxDB is running: sudo systemctl status influxdb
  • Test the API endpoint in a browser: http://localhost:8086
Join node never fires
  • Ensure both sensors have the same polling interval (30s)
  • Verify each sensor node sets a unique msg.topic
  • Check Join node is set to "count: 2" in object mode
  • Add a timeout (e.g., 35s) so it fires even if one sensor is slow

Next Steps