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 station, or Ecowitt / Ambient sensors, and no hub or a hub you would rather not depend on | 1: the radio listener | ESP32 + CC1101, ~$15 | Hears the broadcasts directly; MQTT discovery creates the entities. |
| 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, with discovery messages, so entities appear on their own. Which means everything from the entities section onward applies whichever route you took.
Route 1: the radio listener.
The Weather-Station Listener is an OAT sketch: an ESP32 with a five-dollar CC1101 radio module, flashed from a web page, that runs the rtl_433 decoders on the board itself. It hears every station and sensor on its band, gives each one a stream named by the station’s own broadcast id, and publishes every reading over MQTT with Home Assistant discovery. No Linux, no dongle, no vendor anything.
- Build it. An ESP32 devkit, a CC1101 module, eight jumper wires. The wiring is on the listener page. 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. Set the band: 433.92 for AcuRite, La Crosse and Oregon; 915.00 for Ecowitt and Ambient in the US.
- Wait a minute. Under Stations heard on the setup page your station appears with its id and 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 discovery, so Home Assistant sees the same device.
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 with discovery. 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.
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 with MQTT discovery, so you do not write YAML. Each station or sensor becomes a device, and each quantity it reports becomes a sensor entity on that device with the matching Home Assistant device class, which is what makes the history graphs, the unit conversion and the statistics work.
| 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 1 on 915 MHz, or Route 2 through the hub, your choice, and the hub gives you Ecowitt’s whole sensor family.
- Ecowitt WH51 soil probes, on their own, with or without a station. Under twenty dollars each, eight per listener, the cheapest soil map there is.
- 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 WS80 / WS90 ultrasonic arrays. Fine stations, but they broadcast FSK, which the listener images on this site do not decode out of the box. Route 2 through the hub, or the listener’s FSK source build.
- 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 Weather-Station Listener page, which hears the station's 433 MHz broadcasts and publishes every reading to your MQTT broker with discovery, so Home Assistant creates the device and entities itself. 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?
If you have 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 with discovery. If you would rather not depend on the hub, or you only own the sensors, a radio listener on 915 MHz hears the sensors directly and publishes the same way, and it uses each sensor's own radio id rather than the hub's slot numbers.
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.