W przypadkowej rozmowie ze znajomy dowiedziałem się, że na zlocie krótkofalowców na jakimś targu kupił stacje meteo z demontażu i podłączył ją radiowo do Home Assistanta. Od razu powiedziałem, że jak tylko będzie miał jeszcze możliwość zakupu to od razu niech mi kupuje dwie. W razie jakby coś nie działało to będzie dawca części. Po 3 miesiącach miałem w ręku. Klasyczna, analogowa stacja pogodowa Garni z czujnikami (temperatura, wilgotność, wiatr, deszcz, nasłonecznienie, UV) — urządzenie, które samo w sobie nie ma żadnego protokołu komunikacji tylko puszcza w eter sygnał raz na 12 sekund. Jedyne co trzeba zrobić to podsłuchać jej transmisję radiową i wciągnąć dane do Home Assistant. Do tego zadania niezbędny jest dongiel RTL-SDR V4.



O co chodzi z RTL-SDR?
RTL-SDR to odbiornik radiowy USB (pierwotnie tunery do telewizji cyfrowej DVB-T), który dzięki społecznościowym sterownikom da się przerobić na uniwersalny odbiornik radiowy szerokiego pasma. W praktyce: jeden mały dongiel potrafi „słuchać” niemal wszystkiego, co nadaje w zakresie kilkudziesięciu MHz do ponad 1 GHz — w tym popularne pasma ISM 433 MHz i 868 MHz, na których pracuje mnóstwo czujników, stacji pogodowych, pilotów czy liczników mediów.
Do dekodowania tych transmisji służy otwarte narzędzie rtl_433 — program, który rozpoznaje kilkadziesiąt popularnych protokołów urządzeń i zamienia surowy sygnał radiowy na czytelny JSON.
Konfiguracja: Docker + MQTT
Całość postawiłem w Dockerze na swoim domowym serwerze:
services:
rtl_433:
image: bademux/rtl_433tomqtt:latest
container_name: rtl_433
restart: unless-stopped
volumes:
- ./rtl_433.conf:/etc/rtl_433/rtl_433.conf:ro
- /etc/localtime:/etc/localtime:ro
devices:
- /dev/bus/usb:/dev/bus/usb
environment:
- TZ=Europe/Warsaw
Konfigurację samego rtl_433 trzymam w prostym pliku tekstowym — częstotliwość, wzmocnienie i adres brokera MQTT:
output mqtt://192.168.0.125:1883,user=xxx,pass=xxx,retain=0,events=rtl_433[/model][/id]
device 0
frequency 868.3M
gain 0
report_meta time:local
Dane z każdego wykrytego urządzenia trafiają na osobny temat MQTT (np. rtl_433/Bresser-7in1/44028), co ułatwia dalszą obróbkę. Aplikacja ma szablony sygnałów dla prawie 200 urządzeń. Moje Garni INT 5 jest rebrandem jednego z obsługiwanych nadajników Bresser – 7in1
Pułapka, na którą warto uważać: RTL-SDR Blog V4
Tu natrafiłem na najciekawszy problem całego projektu. Mój dongiel to nowsza wersja RTL-SDR Blog V4, która wymaga specjalnego, poprawionego sterownika – standardowa biblioteka librtlsdr dostępna w repozytoriach Ubuntu go nie obsługuje w pełni. Efekt? Odbiornik „widział” sygnał (potwierdziłem to wizualnie w programie SDR++ na Macu — wyraźna smuga w waterfallu co ~12 sekund, dokładnie zgodnie z cyklem transmisji stacji), ale rtl_433 uparcie nic nie dekodował.



Rozwiązanie: zbudowanie sterownika ze źródeł producenta i podmienienie systemowej biblioteki:
git clone https://github.com/rtlsdrblog/rtl-sdr-blog
cd rtl-sdr-blog && mkdir build && cd build
cmake ../ -DINSTALL_UDEV_RULES=ON
make && sudo make install
sudo cp ../rtl-sdr.rules /etc/udev/rules.d/
sudo ldconfig
Po tej zmianie dane popłynęły od razu — pierwszy poprawny odczyt: temperatura, wilgotność, wiatr, opady, UV, wszystko z poprawną sumą kontrolną CRC.
Wniosek: jeśli masz nowszy dongiel RTL-SDR Blog V4, a program „widzi” sygnał, ale nic nie dekoduje — sprawdź wersję sterownika, zanim zaczniesz podejrzewać config czy antenę.
Przez to, że kompilowanie sterownika i robienie swojego obrazu nie było w moim planie to zostawiłem zainstalowany rtl_433 bezpośrednio w systemie. Kiedyś będzie czas to faktycznie przygotuję obraz pod odpowiedni kontener. Możliwe jest też, że ktoś to w międzyczasie zrobi 🙂
Przygotowanie pliku rtl_433.service do automatycznego uruchamiania aplikacji przy starcie systemu:
[Unit]
Description=rtl_433 - RTL-SDR generic RF receiver and decoder
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=linux_user
ExecStart=/usr/bin/rtl_433 -c /iot/rtl433/rtl_433.conf
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Uruchomienie serwisu:
sudo cp rtl_433.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable rtl_433
sudo systemctl start rtl_433
Integracja z Home Assistant

Zamiast automatycznego discovery, wybrałem prostsze podejście — zwykłe sensory MQTT z szablonami wyciągającymi konkretne wartości z JSON-a:
mqtt:
sensor:
- name: "Balkon Temperatura"
state_topic: "rtl_433/Bresser-7in1/44028"
value_template: "{{ value_json.temperature_C }}"
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
Analogicznie dla wilgotności, wiatru, opadów i nasłonecznienia. Dodatkowo, template sensor zamienia kierunek wiatru ze stopni na czytelną różę wiatrów (N, NE, E…), żeby dashboard był bardziej czytelny na pierwszy rzut oka.

Stylizacja prezentacji danych
Tu dwie rzeczy do usprawnienia. Kierunek wiatru odbierany ze stacji jest w stopniach. Nie bardzo wiadomo w którą stronę wieje wiatr 252° 🙂 Trzeba to sobie ograć template sensorem:
- name: "Garni Kierunek Wiatru Róża"
unique_id: balkon_bresser_wind_dir_rose
state: >
{% set deg = states('sensor.balkon_garni_kierunek_wiatru') | float(0) %}
{% set kierunki = ['N','NNE','NE','ENE','E','ESE','SE','SSE',
'S','SSW','SW','WSW','W','WNW','NW','NNW'] %}
{{ kierunki[ ((deg + 11.25) / 22.5) | int % 16 ] }}
W przyszłości chciałbym zrobić różę wiatru z obracającą się igłą i miniaturą mieszkania. Dzięki czemu będzie można od razu wyobrazić sobie, z której strony wieje wiatr 🙂
Drugi temat do dopieszczenia to opady. Miernik opadów nalicza narastająco opady. Nie zeruje ich co dobę, tydzień czy miesiąc. Tu Home Assistant przychodzi z pomocą i swoimi utility_meter:
utility_meter:
balkon_opady_dzienne:
source: sensor.balkon_garni_opady
unique_id: balkon_opady_dzienne
cycle: daily
balkon_opady_miesieczne:
source: sensor.balkon_garni_opady
unique_id: balkon_opady_miesieczne
cycle: monthly
W ten sposób mamy kolejne dwie encje, które agregują dane dzienne i miesięczne. Ułatwia to prezentację danych na dashboardach.
Kwestia zasięgu
Ostatnia przeszkoda była czysto fizyczna: dongiel stał w korytarzu, a stacja na balkonie — kilka metrów i ściana wystarczyły, żeby sygnał zniknął. Zamiast stawiać osobne urządzenie (miałem pod ręką wolne Raspberry Pi Zero, ale wolałem zostać przy jednym punkcie zarządzania), rozwiązaniem okazało się po prostu wydłużenie kabla USB w stronę balkonu i… zmiana wzmocnienia z ustawionego na sztywno na tryb automatyczny. Czasem najprostsze rozwiązanie leży najbliżej.
Co dalej
Ten sam dongiel, ten sam pipeline (rtl_433 → MQTT → Home Assistant) obsłuży w praktyce dowolne urządzenie nadające w pasmach ISM — kolejne czujniki, piloty, a nawet niektóre liczniki mediów (choć te bywają szyfrowane, o czym może przy okazji innego artykułu). Do obsługi 433 MHz osobno planuję jeszcze przerobiony Sonoff RF Bridge z firmware ESPHome — ale to już temat na kolejny wpis.
Masz w domu jakieś radiowe urządzenie, które chciałbyś wciągnąć do swojego Home Assistant? Napisz w komentarzu — może da się je podsłuchać tą samą metodą.
