Search any Home Assistant forum for the name of a cheap weather station and you will find the same thread a hundred times: how do I get its readings without the vendor’s app, without their cloud, and without setting up a Linux box with a radio dongle? The answers trail off into half-working workarounds. This page is the whole answer, three ways, and none of them sends a byte off the property. Pick the route that matches what you own, and by the end your station is a device in Home Assistant with proper entities, and your frost alarm runs on your own data.
The problem everyone has.
A consumer weather station is a sensor array on a pole and a display on the counter, joined by a one-way radio. The array broadcasts on 433 or 915 MHz every few seconds to whoever listens, and the display listens. The maker’s app, if there is one, usually works by the display or a hub uploading to the maker’s cloud and the app reading it back down. When the maker changes their mind, the app stops. When your internet is down, so is your weather. When the company is sold, the data goes with it.
Home Assistant has integrations for some of these clouds. That is the problem restated, not solved. The readings are being made thirty feet from your server and taking a round trip through a data centre to reach it.
The broadcasts themselves are open. The rtl_433 project has spent a decade documenting how more than two hundred of these devices encode their readings, and the decoders are free. What has been missing is a way to run them that does not involve a software-defined-radio dongle on a Raspberry Pi and a weekend of configuration. That gap is what Route 1 closes.
Three routes, all local.
| You have | Route | Hardware | In one line |
|---|---|---|---|
| An AcuRite, La Crosse or Oregon Scientific station, and no hub | 1: the radio listener | ESP32 + CC1101, ~$15 | Hears the broadcasts directly; one MQTT topic per reading, one YAML block per entity. |
| Ecowitt or Ambient WH31, WH51 or WN34 sensors, and no hub | 1: the radio listener, Build 5 | ESP32 + 915 CC1101, ~$15 | Hears each sensor under its own radio id; heard on our bench 2026-10-04. |
| An Ecowitt GW1100/GW2000/HP2551 hub or an Ambient Weather hub already on your network | 2: the hub feed | nothing new | The hub posts to a small bridge on your server; the bridge publishes to MQTT. |
| A WeatherFlow Tempest or a Davis Vantage with WeatherLink Live | 3: the hub feed | nothing new | The same bridge listens to the Tempest hub’s broadcast or polls the Davis hub. |
All three end in the same place: readings in canonical units published to the MQTT broker Home Assistant already uses, one topic per reading, which you declare as entities in YAML. Which means everything from the entities section onward applies whichever route you took.
Route 1: the radio listener.
The Radio Sensor Listener is an OAT sketch flashed from a web page, in three builds. For an AcuRite Iris, an ESP32 with a two-dollar 433 MHz receiver is enough, and that build has heard an Iris on our bench. For other on-off-keying stations, an ESP32 with a five-dollar CC1101 radio module runs the rtl_433 decoders on the board itself; that build is offered as beta. For Ecowitt and Ambient Weather WH31, WH51 and WN34 sensors, Build 5 sets a CC1101 sold for 868/915 MHz to receive their frames in hardware; it heard all three kinds on our bench on 2026-10-04. The listener page’s sensor finder says which build hears what you own. It hears every station and sensor its image decodes on its band, gives each one a stream named by the station’s own broadcast id, and publishes every reading over MQTT on its own topic. No Linux, no dongle, no vendor anything.
- Build it. An ESP32 devkit and either a bare 433 MHz receiver on one pin or a CC1101 module on eight jumper wires. Pick your build on the listener page; the wiring is inside each build. A Heltec WiFi LoRa 32 V2 needs no module at all; its own radio does the job.
- Flash it from the listener page in Chrome or Edge.
- Set it up. Join its setup Wi-Fi, fill in the one form: your Wi-Fi, a name, and for delivery choose MQTT with your broker’s address, user and password. Leave the band at 433.92; that is where AcuRite, La Crosse TX141 and Oregon Scientific broadcast.
- Wait a minute. Under Stations heard on the setup page your station appears with its id, and on a CC1101 its signal strength. If the neighbours’ stations appear too, put your station’s id in the allow-list.
- Open Home Assistant. Settings, Devices & Services, MQTT. The station is a device, its readings are entities. Done.
The listener is also the route for a station out of Wi-Fi range: cable it to an OAT LoRa Field Node and the readings come home over LoRa. That path ends in an OAT gateway rather than the listener itself publishing, but the gateway publishes to the same broker with the same topic shape, so the same YAML applies.
Route 2: the hub you already own.
Ecowitt’s GW1100 and GW2000, the HP2551 console, and Ambient Weather’s hubs all have a setting called custom server (Ambient calls it “customized upload”). It tells the hub to send every report it receives, from all its sensors, to a URL you choose, in a simple form-encoded POST. That is the whole integration: the hub already hears the sensors, so nothing new listens to the air.
The OAT gather bridge is a small Python program that accepts that POST and publishes each reading to MQTT on the same topic shape. It runs on the same machine as Home Assistant, in a container or a terminal.
- Run the bridge with a config whose source is
ecowittand whose sink is your MQTT broker. It listens on port 8085 at/data/report/. - In the hub’s app or web page, open the custom server setting. Protocol Ecowitt, server your Home Assistant machine’s address, port 8085, path
/data/report/, upload interval 60 seconds. - Watch the bridge’s log print one line per report. In Home Assistant the hub’s sensors appear under MQTT, one device per sensor slot.
One honest limit. The Ecowitt protocol names sensors by slot, soil moisture 2, not by the sensor’s radio id. Streams are therefore named hub-and-slot. Swap two soil probes’ channel switches and their histories swap with them. The radio listener in Route 1 hears the sensors’ own ids and does not have this problem, which is one reason to prefer it even when a hub exists.
If nothing arrives, the Ecowitt guide’s checklist covers the usual causes: the setting not saved, HTTPS, a server that redirects, a path that does not match.
The vendor’s cloud upload can stay on or off as you like. The custom server is an addition, and Home Assistant no longer depends on the cloud either way.
Route 3: Tempest and Davis.
Two stations do not broadcast in a form the listener can decode, and both come with a hub that speaks on your network.
- WeatherFlow Tempest. The hub broadcasts every observation as a small JSON message over UDP on your LAN, port 50222, with nothing to configure. The gather bridge with source
tempestlistens for those and publishes them. The station’s serial number is its stream id. Wind, gusts, direction, pressure, temperature, humidity, light, UV, solar radiation, rain per minute, lightning count and distance, and the station’s battery voltage all arrive. - Davis Vantage Vue and Pro2 with WeatherLink Live. The hub serves a local JSON page at
/v1/current_conditions. The bridge with sourceweatherlinkpolls it every minute. The outdoor array, the leaf-and-soil station, the barometer and the indoor sensor each become a stream. Davis’s own radio link between the array and the hub is a frequency-hopping protocol no open decoder handles reliably, so the hub is the honest route.
Both run beside Home Assistant like Route 2, and both leave the vendor’s cloud out of the loop entirely.
What you get in Home Assistant.
Every route publishes one retained message per reading on oat/<gateway>/<stream>/<measurement>, plus a status topic with a Last Will. You declare each reading as an MQTT sensor in YAML: the topic, value_json.value for the value, the status topic for availability, and the Home Assistant device class from the table below, which is what makes the history graphs, the unit conversion and the statistics work. One block per reading, copied and edited; the sketches do not send discovery announcements.
mqtt:
sensor:
- name: "Iris temperature"
unique_id: barn_wx_acurite_5n1_748_a_temperature
state_topic: "oat/barn-wx/acurite-5n1:748-A/temperature"
value_template: "{{ value_json.value }}"
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
availability:
- topic: "oat/barn-wx/status"
value_template: "{{ value_json.state }}"
payload_available: "online"
payload_not_available: "offline"
| Reading | Entity | Device class | Notes |
|---|---|---|---|
| Air temperature | temperature | temperature | Published in °C; Home Assistant shows your unit system. |
| Humidity | humidity | humidity | |
| Wind speed, gust | wind_speed, wind_gust | wind_speed | m/s on the wire; HA converts to mph or km/h. |
| Wind direction | wind_direction | — | Degrees. Never averaged. |
| Rain | rain_total | precipitation | The station’s running total in mm. Use a Utility Meter helper for today, this week, this month. |
| Rain rate | rain_rate | precipitation_intensity | |
| Solar radiation, UV | solar_radiation, uv_index | irradiance | A daily-light-integral template sits on top of solar radiation. |
| Soil moisture | soil_moisture | moisture | One entity per probe. |
| Leaf wetness | leaf_wetness | moisture | |
| Lightning | lightning_total, lightning_distance | distance | Total is a counter; distance is the last strike. |
| Battery | battery_low, voltage | battery | A flag on most stations, volts on Ecowitt soil probes. |
| Signal | rssi | signal_strength | How well the listener hears this station. Watch it fall before the batteries do. |
Rename the device to something human the moment it appears. The id stays underneath, so a renamed device survives the listener being reflashed or replaced. That is the OAT rule about identity applied inside Home Assistant: the hardware names the stream, you name the place.
The dashboard.
The agricultural cards page covers the cards in detail. For a station the ones that earn a place on the wall are:
- A gauge for wind speed with the gust as a secondary, and a compass card for direction. The community compass card from HACS is the usual pick.
- A history graph of temperature with the overnight low visible at a glance. Twelve hours, not twenty-four, so the pre-dawn dip is readable.
- A statistics graph of the rain utility meter, daily bars, thirty days.
- A tile per soil probe with a colour threshold at your irrigation trigger.
- The station’s battery and signal entities somewhere you will see them, because a station dies quietly.
Resist the urge to show everything. The dashboard design page argues for one wall view with five numbers and a phone view with the rest, and a weather station is the strongest case for that discipline.
Automations a station is for.
A station on a dashboard is a curiosity. A station that wakes you up is an instrument. These are the automations that justify the hardware, in the order growers build them.
- Frost warning. Trigger when air temperature drops below a threshold two or three degrees above freezing after sunset. Action: a phone notification, and if you have them, the greenhouse heaters or the row-cover reminder. The single most valuable automation on a farm, and it needs nothing but temperature.
- Frost warning, done properly. Add a condition on humidity and a second trigger on the rate of fall. A clear, dry, still night drops faster than the forecast says. Wind speed near zero and humidity under sixty percent after dusk is the pattern; the station sees all three.
- Irrigation hold on rain. Trigger on the rain utility meter crossing a daily threshold. Action: skip tonight’s irrigation schedule. Pair it with the soil probes for the honest version: hold when the soil says so, not the sky.
- Wind alarm. Gust above a threshold for the shade cloth, the high tunnel sides, or the sprayer. Use the gust entity and a short delay so one puff does not page you.
- Spray window. A binary template sensor that is on when wind is under the label limit, temperature is in range, and no rain is forecast or falling. Put it on the dashboard as a green light. The station makes the wind and rain half of that local and current.
- Disease pressure. Hours of leaf wetness above a threshold at temperatures in a pathogen’s range, accumulated with a history statistics sensor. A notification when the hours cross the model’s trigger. This is where a leaf-wetness sensor earns its twenty dollars.
- Station health. Trigger when the station’s entities have not updated in thirty minutes, or the battery-low flag turns on, or signal drops below a floor. A station that dies in February is found in March otherwise.
Every one of these runs on the local broker. The internet can be down for a week and the frost alarm still fires, because the only thing between the pole and the automation is a radio, a small board and a cable.
Which station to buy.
If you do not own one yet and are buying for Home Assistant:
Buy these
- AcuRite Iris (06004M). The cheapest complete array. Wind, direction, rain, temperature, humidity. Route 1, 433 MHz. The reference station for the OAT listener.
- Ecowitt WS69 or WH65 array with a GW2000 hub. Adds solar and UV. Route 2 through the hub, which gives you Ecowitt’s whole sensor family. The array itself needs the hub today: the listener build for it is still unproven bench images. Its WH31, WH51 and WN34 sensors can also be heard directly by Build 5.
- Ecowitt WH51 soil probes, on their own, with or without a station. Under twenty dollars each, and with a GW1100-class hub on Route 2 the cheapest soil map there is. The Ecowitt guide says which radio version to buy in your country.
- WeatherFlow Tempest, if you want no moving parts and can afford it. Route 3, and its hub’s UDP broadcast is the friendliest local feed of any vendor.
Know what you are buying
- Davis Vantage. Excellent instruments; a closed radio link. Budget for the WeatherLink Live hub and use Route 3.
- Ecowitt and Ambient Weather sensors beyond the WH31, WH51 and WN34. Good instruments, and the whole current family broadcasts FSK (on 915 MHz in the Americas, 868 in Europe, 433 elsewhere). Build 5 of the listener hears the WH31, WH51 and WN34 directly; for the rest, Route 2 through their hub is the route today. The listener’s rtl_433 FSK build for them is published as unproven bench images; it has not yet heard a sensor.
- Netatmo and other Wi-Fi-to-cloud stations. Nothing local to hear or poll. There is no route on this page for them.
Frequently asked questions.
How do I connect an AcuRite weather station to Home Assistant?
Two local ways. The cheapest is a radio listener: an ESP32 with a CC1101 module running the open rtl_433 decoders, flashed from the OAT Radio Sensor Listener page, which hears the station's 433 MHz broadcasts and publishes every reading to your MQTT broker on its own topic; you add each one as an MQTT sensor in YAML. The traditional way is rtl_433 on a Linux computer with an SDR dongle, publishing to MQTT. Both avoid AcuRite's cloud entirely and leave the station's own display working.
How do I get Ecowitt sensors into Home Assistant without the Ecowitt cloud?
With an Ecowitt hub, set its custom server to a small bridge running on your Home Assistant machine, protocol Ecowitt, and the bridge publishes every report to MQTT, one topic per reading, which you declare as entities in YAML. That is the route today: the current Ecowitt sensors broadcast FSK on 915 MHz, which the OAT radio listener images do not decode.
Does the Tempest weather station work locally with Home Assistant?
Yes. The Tempest hub broadcasts every observation as JSON over UDP on the local network, port 50222, with nothing to enable. A bridge that listens on that port and publishes to MQTT gives Home Assistant the station with no cloud involved. The vendor's cloud integration can remain or be removed; the local feed does not depend on it.
Why is rain reported as a total instead of a daily amount?
Because the station itself reports a running total, and forwarding it unchanged means a missed broadcast loses nothing. Home Assistant's Utility Meter helper turns a total into daily, weekly and monthly amounts with resets, which is the right place for that arithmetic. A daily figure computed on the radio link would be wrong the first time a packet was missed.
Can Home Assistant hear both a 433 MHz station and 915 MHz sensors?
Yes, with two listeners, one per band, both publishing to the same broker. A single radio receives one frequency at a time. Two ESP32 boards with two radio modules cost less than one vendor hub.
What happens to my automations when the internet is down?
Nothing. Every route on this page ends at your own MQTT broker on your own network. The station broadcasts, the listener or hub delivers locally, Home Assistant runs the automation. A frost alarm built this way has no dependency outside the property.