A weather station that only talks to a web page is leaving most of its value on the table. The sensors on your roof already know the wind speed, the rain rate, and the temperature β€” so why are you still checking an app on your phone before deciding whether to water the garden or close the skylights? The answer, for most station operators, is plumbing: nobody showed them how to connect the pipes.

MQTT is that pipe. It is a lightweight messaging protocol designed for exactly the kind of low-bandwidth, high-frequency telemetry that weather stations produce. Pair it with Home Assistant and you get real-time indoor dashboards, automations that react to outdoor conditions in seconds, and long-term data logging that rivals purpose-built weather databases. I have been running this combination across two stations for over three years, and the reliability has been better than any web-upload workflow I have used β€” including the ones I describe in the publishing overview.

This guide walks you through the full integration: MQTT fundamentals as they apply to weather data, configuring your station software to publish messages, setting up Home Assistant to consume them, building dashboards, creating useful automations, and connecting the data pipeline to InfluxDB and Grafana for historical analysis. If you followed the Grafana dashboard guide, this article gives you an alternative ingestion path that sidesteps CSV file tailing entirely.

Quick-Answer Summary

Component Role Key Detail
MQTT Broker Message router Mosquitto is the default; runs on the same box as Home Assistant
Station Publisher Sends weather data to broker Ecowitt firmware, RTL_433, WeeWX extension, or GraphWeather export
Home Assistant Subscriber and automation engine MQTT integration, sensor entities, automations
InfluxDB + Grafana Long-term storage and visualisation Optional but recommended for historical analysis

If you want the shortest path: install Mosquitto as a Home Assistant add-on, point your Ecowitt gateway at it, and let MQTT discovery create the entities automatically. You can be up and running in under twenty minutes.

Prerequisites

Before you start, confirm you have:

  • A working weather station with a gateway or software that can publish MQTT messages (Ecowitt GW1000/GW2000, an RTL_433-compatible SDR setup, WeeWX with the MQTT extension, or a GraphWeather installation).
  • Home Assistant installed and accessible on your local network. Any installation method works β€” Home Assistant OS, Container, or Supervised.
  • Basic familiarity with YAML. Home Assistant's UI editor covers many configurations now, but MQTT sensors still benefit from manual YAML for fine-grained control.
  • A machine on the same network segment as both the station gateway and the Home Assistant instance. If they are on different VLANs (which is good practice β€” more on that in the security article), you will need firewall rules allowing MQTT traffic on port 1883 or 8883.

MQTT Fundamentals for Weather Data

MQTT works on a publish-subscribe model. Your station publishes messages to topics β€” hierarchical strings like weather/station1/temperature β€” and any number of clients can subscribe to those topics to receive updates. The broker (Mosquitto, in most setups) sits in the middle, routing messages from publishers to subscribers.

Three MQTT concepts matter more for weather data than for typical IoT use:

Topics

Organise your topics hierarchically. A sensible structure looks like this:

weather/station1/temperature
weather/station1/humidity
weather/station1/pressure
weather/station1/wind/speed
weather/station1/wind/direction
weather/station1/rain/rate
weather/station1/rain/daily

This hierarchy lets you subscribe to weather/station1/# to capture everything from one station, or weather/+/temperature to compare temperatures across multiple stations. Resist the temptation to dump everything into a single JSON payload on one topic β€” it works, but it makes selective subscriptions impossible and complicates Home Assistant entity creation.

QoS Levels

MQTT defines three Quality of Service levels:

  • QoS 0 β€” fire and forget. The message may be lost if the network hiccups.
  • QoS 1 β€” at least once. The message is delivered, but duplicates are possible.
  • QoS 2 β€” exactly once. Guaranteed delivery, no duplicates, but higher overhead.

For weather data arriving every 30–60 seconds, QoS 1 is the sweet spot. A lost reading is tolerable (the next one arrives in a minute), but you want assurance that data generally makes it through. QoS 2 adds latency and broker overhead that is not justified when the data is ephemeral.

The Retain Flag

This one catches people. When you publish a message with retain = true, the broker stores the last message on that topic and immediately delivers it to any new subscriber. For weather data, always set retain. Without it, a fresh Home Assistant restart shows "Unknown" for every weather entity until the next station update arrives β€” which might be 60 seconds away, or might be 10 minutes if you use a longer upload interval.

Configuring Your Station to Publish MQTT

Ecowitt GW1000/GW2000

The Ecowitt gateways have a "Customized" upload option in their firmware. Set the protocol to Ecowitt and point it at your MQTT broker's IP. However, Ecowitt's native protocol is HTTP POST, not MQTT. To bridge the gap, run the ecowitt2mqtt utility on the same machine as your broker. It listens for Ecowitt HTTP payloads and republishes them as MQTT messages with proper topic hierarchy.

Install it in a Docker container or via pip:

pip install ecowitt2mqtt
ecowitt2mqtt --mqtt-broker 192.168.1.50 --mqtt-topic weather/ecowitt

Configure the Ecowitt gateway to POST to the machine running ecowitt2mqtt on port 8080. Messages appear on topics like weather/ecowitt/temperature, weather/ecowitt/humidity, and so on.

RTL_433

If you use a software-defined radio to receive 433 MHz sensor transmissions, RTL_433 has native MQTT output:

rtl_433 -F "mqtt://192.168.1.50:1883,retain=1,devices=weather/rtl433"

This publishes each decoded sensor reading as a retained message. The topic structure follows weather/rtl433/{model}/{id}/{field}. You may need to filter by device ID if you pick up neighbours' sensors β€” a common issue in suburban areas.

WeeWX MQTT Extension

WeeWX's weewx-mqtt extension publishes loop packets and archive records to MQTT. Install it with the WeeWX extension manager, then configure in weewx.conf:

[StdRestful]
    [[MQTT]]
        server_url = mqtt://192.168.1.50:1883
        topic = weather/weewx
        unit_system = METRIC
        binding = loop
        [[[tls]]]
            tls_version = tlsv1_2

Setting binding = loop publishes every loop packet (typically every 2.5 seconds on Davis hardware). If that volume is excessive, switch to archive for interval-based updates.

GraphWeather Export

GraphWeather does not have native MQTT output, but its CSV export scheduler can be combined with a lightweight script that reads the latest CSV line and publishes it. A Python script with paho-mqtt handles this in under thirty lines. Alternatively, use the Telegraf pipeline described in the Grafana dashboard guide and add Telegraf's mqtt output plugin alongside the InfluxDB output β€” one data flow, two destinations.

Home Assistant MQTT Sensor Configuration

Automatic Discovery

If your publisher supports MQTT discovery (Home Assistant's auto-configuration protocol), entities appear automatically under Settings β†’ Devices & Services β†’ MQTT. The ecowitt2mqtt utility supports discovery out of the box when launched with the --hass-discovery flag.

Manual YAML Configuration

For publishers that do not support discovery, define sensors manually in configuration.yaml:

mqtt:
  sensor:
    - name: "Outdoor Temperature"
      state_topic: "weather/station1/temperature"
      unit_of_measurement: "Β°C"
      device_class: temperature
      state_class: measurement
      value_template: "{{ value | float }}"

    - name: "Outdoor Humidity"
      state_topic: "weather/station1/humidity"
      unit_of_measurement: "%"
      device_class: humidity
      state_class: measurement
      value_template: "{{ value | float }}"

    - name: "Barometric Pressure"
      state_topic: "weather/station1/pressure"
      unit_of_measurement: "hPa"
      device_class: atmospheric_pressure
      state_class: measurement
      value_template: "{{ value | float }}"

    - name: "Wind Speed"
      state_topic: "weather/station1/wind/speed"
      unit_of_measurement: "km/h"
      device_class: wind_speed
      state_class: measurement
      value_template: "{{ value | float }}"

    - name: "Rain Rate"
      state_topic: "weather/station1/rain/rate"
      unit_of_measurement: "mm/h"
      state_class: measurement
      value_template: "{{ value | float }}"

Key points:

  • device_class tells Home Assistant how to display and graph the entity. Use the correct class for each sensor type.
  • state_class: measurement enables long-term statistics in the Home Assistant recorder β€” essential for min/max/mean calculations.
  • value_template with | float ensures the value is numeric even if the publisher sends strings.

After saving, restart Home Assistant or reload the MQTT integration. Entities should populate within one station update cycle.

Building Home Assistant Dashboards

Home Assistant's Lovelace UI makes dashboard creation straightforward. A weather-focused dashboard benefits from these card types:

  • Gauge cards for temperature, humidity, and pressure β€” set min/max ranges and colour thresholds (blue below 0 Β°C, red above 35 Β°C).
  • History graph cards for 24-hour traces of each parameter.
  • Entity cards for wind direction (display as text) and rain daily total.
  • Conditional cards that show alerts only when conditions cross thresholds (frost warning, high wind).

Arrange the cards in a grid layout with weather parameters grouped logically: atmospheric conditions (temp, humidity, pressure) in one row, wind in a second row, precipitation in a third. This mirrors the structure of a standard METAR observation and makes the dashboard scannable at a glance.

Automations Triggered by Weather Conditions

This is where the integration earns its keep. Some automations I run daily:

Frost Alert

automation:
  - alias: "Frost Alert"
    trigger:
      - platform: numeric_state
        entity_id: sensor.outdoor_temperature
        below: 2
    condition:
      - condition: time
        after: "18:00:00"
        before: "09:00:00"
    action:
      - service: notify.mobile_app
        data:
          title: "Frost Warning"
          message: "Outdoor temperature has dropped to {{ states('sensor.outdoor_temperature') }} Β°C. Cover tender plants."

High Wind β€” Close Skylights

  - alias: "High Wind Close Skylights"
    trigger:
      - platform: numeric_state
        entity_id: sensor.wind_speed
        above: 45
        for:
          minutes: 2
    action:
      - service: cover.close_cover
        target:
          entity_id: cover.skylight_south

The for: minutes: 2 clause prevents a single gust from triggering the automation. Two minutes of sustained wind above 45 km/h is a genuine event.

Irrigation Skip on Rain

  - alias: "Skip Irrigation After Rain"
    trigger:
      - platform: time
        at: "05:30:00"
    condition:
      - condition: numeric_state
        entity_id: sensor.rain_daily
        above: 3
    action:
      - service: switch.turn_off
        target:
          entity_id: switch.irrigation_zone_1

If more than 3 mm of rain fell in the last 24 hours, the irrigation system stays off. Simple, effective, and surprisingly satisfying when it works on autopilot.

Long-Term Logging with InfluxDB and Grafana

Home Assistant's built-in recorder database (SQLite or MariaDB) stores history, but it is not designed for multi-year, high-resolution weather archives. For serious historical analysis, forward the MQTT data to InfluxDB as well.

The easiest approach: add Telegraf's mqtt_consumer input alongside the Home Assistant subscriber. Both listen on the same topics β€” MQTT supports multiple subscribers natively. Telegraf writes to InfluxDB, and Grafana reads from InfluxDB. This is the same pipeline described in the Grafana dashboard guide, but with MQTT as the ingestion layer instead of CSV tailing.

The advantage is immediacy β€” data arrives in InfluxDB within milliseconds of the station reading, rather than waiting for a CSV flush cycle. If you validate your data before it reaches the database, the station data sanity checks guide covers the thresholds and patterns to watch for.

Common Mistakes

  1. Not setting the retain flag. After a Home Assistant restart, every weather entity shows "Unknown" until the next station update. Retain solves this instantly. I cannot overstate how much frustration this one setting prevents.

  2. Wrong QoS for intermittent connections. If your station gateway is on flaky Wi-Fi, QoS 0 means lost messages with no retry. Use QoS 1 at minimum for unreliable links.

  3. Sensor entity naming chaos. Home Assistant generates entity IDs from the name field. If you change the name later, the entity ID changes, breaking every automation and dashboard card that referenced the old ID. Decide on a naming convention before you start β€” sensor.wx_outdoor_temperature is better than sensor.temperature when you inevitably add indoor sensors.

  4. Publishing everything as a single JSON blob. It works, but it means writing value_template expressions with value_json.temperature for every entity. Flat topics per measurement are cleaner and let you use MQTT wildcards effectively.

  5. Ignoring TLS. MQTT on port 1883 is unencrypted. On a home network this is often acceptable, but if the broker is accessible from outside your LAN, configure TLS (port 8883) and client certificates. The FTP publishing guide makes the same argument for upgrading FTP to SFTP β€” the principle is identical.

  6. Flooding the broker. Some SDR setups with RTL_433 publish every packet from every sensor in range, including neighbours' pool thermometers and tyre-pressure monitors. Filter aggressively by device ID to keep your topic tree manageable.

Related Reading

FAQ

Do I need a dedicated MQTT broker, or can I use the Home Assistant add-on? The Mosquitto add-on bundled with Home Assistant OS is perfectly adequate for weather data. It runs on the same hardware, requires no separate maintenance, and supports TLS and authentication. You would only need an external broker if you run Home Assistant in Container mode without add-on support, or if you have dozens of high-frequency publishers saturating the broker.

Can I use MQTT and FTP publishing at the same time? Absolutely. They serve different purposes. MQTT feeds real-time dashboards and automations inside your home. FTP publishes static pages to a public web server. Most station software supports both simultaneously β€” WeeWX, for example, runs MQTT via its restful service and FTP via its report engine in parallel.

What happens if the broker goes down? With QoS 1, the publisher retries. Most MQTT client libraries queue messages locally during broker outages and flush the queue when the connection recovers. You may see a burst of readings arrive at once, but no data is lost. For Home Assistant, automations simply pause until the sensor entities update again.

How much bandwidth does MQTT weather data use? Almost nothing. A single sensor reading is typically 20–50 bytes. A full station publishing ten parameters every 60 seconds generates under 500 bytes per minute β€” less than 1 MB per day. Even on a metered cellular connection, MQTT weather data is negligible.

Can I subscribe to someone else's station via MQTT? Only if they expose their broker to the internet or federate through a shared broker. MQTT is inherently a LAN protocol unless the broker is publicly accessible. For sharing data with the wider community, network platforms like CWOP and Weather Underground are the established channels β€” the METAR and CWOP basics guide covers those.