Получаем погоду в Home Assistant c WS2032 с помощью rtl_433
Алоха, красноглазые! в этом посте я расскажу, как затащить данные с погодной станции на WS2032 в Home Assistant. данная статья не для новичков, подразумевается, что вы немного знакомы с linux (делать будем на нем) ну и docker надо, куда ж без него
а вот и эта продукция сумрачного китайского гения WS2302
История такова, что мне подарили эту погодную станцию и я ее в загородном доме долго использовал, но у нее только экран с цифрами есть, а как объединить ее и HA - понятных инструкций не было. ну поковыряв интернеты пару вечеров, я придумал как сделать. Вообще данный способ подходит для кучи устройств которые разговаривают по открытому протоколу на частоте 433 мгц, rtl_433 поддерживает дофига всякого
TL;DR
связка работает так - ws2032>usb radio >утилита rtl_433> очередь mqtt> home assistant
Погнали:
покупаем на али погодную станцию на базе WS2032 их там довольно много, и вроде как они самые недорогие, есть варианты с со сбором воды и просто ветер и температура, так же потребуется usb радиоприемник типа soap-sdr (их великое множество, все немного качеством различаются я брал на RTL2838 DVB-T, самые дешманские работают не очень) и usb хаб с питанием.
нам потребуется rtl_433 - утилиту можно взять из системных реп но лучше взять свежую из гита и собрать самостоятельно вот гайд,
для работы rtl_433 потребуется конфиг файл, в нем очень важный момент - нужно будет указать окно девиаций частоты, поскольку станция дешманская и частота передатчика довольно заметно плавает, у меня заработало стабильно вот с таким конфигом (/etc/rtl_433/rtl_433.conf)
device 0
gain 0
# default is "433.92M", other resonable values are 315M, 345M, 915M and 868M
frequency 433.69M
frequency 433.72M
frequency 433.752M
# default is "600" seconds, only used when multiple frequencies are given
hop_interval 10
ppm_error 0
sample_rate 250k
samples_to_read 0
analyze_pulses false
report_meta level
report_meta stats
report_meta time:usec
report_meta protocol
signal_grabber none
output json
convert si
stop_after_successful_events false
protocol 145 # WS2032 weather station
запустить проверить можно вот таким способом
/usr/bin/rtl_433 -F mqtt://127.0.0.1 1883 retain 1 events rtl_433/rtlsdr/event/21770 states rtl_433/rtlsdr/state/21770 -c /etc/rtl_433/rtl_433.conf
в ответ должно получиться что то такое
как видно из выхлопа - приемник уcлышал погодную станцию, она передает раз в минуту и вывод в формате json
rlt_433 и контейнер с mqtt в моем случае на 1 хосте живут
4. далее нам нужен сервер очередей mqtt - проще всего использовать docker compose
вот их репозиторий со всей нужной обвязкой
services:
mosquitto:
image: eclipse-mosquitto:latest
restart: unless-stopped
volumes:
- ./config/:/mosquitto/config/:rw
- ./log/:/mosquitto/log/
- ./data:/mosquitto/data/
ports:
- 1883:1883
- 9001:9001
запускаем композ и смотрим что он начал слушать на порту 1883, рядом в соседнем терминале запускаем rtl_433 (потом можно будет написать systemd unit) - проверить что в mqtt что то пишется нам поможет утилита mqtt explorer - цепляемся к нашей очереди и смотрим события в ней
тут видно что используется 2 очереди event и state (остальные очереди в моем случае всякое остальное типа zigbee устройств) в очереди event можно понаблюдать как меняются данные,
5. раз данные обновляются стабильно, можно переходить к настройке Home Assistant - нам потребуется плагин для mqtt и немного допилить конфиг для того что бы направление ветра показывало не в градусах а в виде букв (N,S,W,E и тд)
сам плагин настраиваем что бы он слушал нашу очередь
тут надо указать ип адрес машины с mqtt
и указываем топик откуда получать данные
а тут надо указать топик который будем слушать
далее настраиваем configuration.yaml от HA (не забываем рестатануть HA и внимательно следим за идетнацией ямла - блоки sensor ws2032_extras и mqtt должны вроде как быть без отступов, но в вашем конфиге может быть иначе)
mqtt:
sensor:
- name: "village_outside_temp"
state_topic: "rtl_433/rtlsdr/event/21770"
unit_of_measurement: "°C"
value_template: "{{ value_json.temperature_C }}"
unique_id: village_outside_temp_id
- name: "village_outside_humidity"
state_topic: "rtl_433/rtlsdr/event/21770"
unit_of_measurement: "%"
value_template: "{{ value_json.humidity }}"
unique_id: village_outside_humidity_id
- name: "village_outside_wind_direction"
state_topic: "rtl_433/rtlsdr/event/21770"
unit_of_measurement: "deg"
value_template: "{{ value_json.wind_dir_deg }}"
unique_id: village_outside_wind_dir_deg
- name: "village_outside_wind_avg_spd"
state_topic: "rtl_433/rtlsdr/event/21770"
unit_of_measurement: "km/h"
value_template: "{{ value_json.wind_avg_km_h }}"
unique_id: village_outside_wind_avg_spd
- name: "village_outside_wind_max_spd"
state_topic: "rtl_433/rtlsdr/event/21770"
unit_of_measurement: "km/h"
value_template: "{{ value_json.wind_max_km_h }}"
unique_id: village_outside_wind_max_spd
- name: "village_outside_battery_ok"
state_topic: "rtl_433/rtlsdr/event/21770"
unit_of_measurement: "state"
value_template: "{{ value_json.battery_ok }}"
unique_id: village_outside_battery_ok
sensor ws2032_extras:
- platform: template
sensors:
ws2032_wdc:
unique_id: ws2032_wdc
friendly_name: "Wind: Direction (Cardinal)"
icon_template: mdi:weather-cloudy-arrow-right
value_template: >
{% set direction = ['N','NNE','NE','ENE','E','ESE','SE','SSE','S','SSW','SW','WSW','W','WNW','NW','NNW','N'] %}
{% set degree = states('sensor.village_outside_wind_direction')|float %}
{{ direction[((degree+11.25)/22.5)|int] }}
ws2032_ws_kmh:
unique_id: ws2032_ws_kmh
friendly_name: "Wind: Speed (km/h)"
icon_template: mdi:windsock
device_class: wind_speed
unit_of_measurement: "km/h"
value_template: "{{ states('sensor.village_outside_wind_avg_spd')}}"
ws2032_gs_kmh:
unique_id: ws2032_gs_kmh
friendly_name: "Wind: Gust Speed (km/h)"
icon_template: mdi:pinwheel-outline
device_class: wind_speed
unit_of_measurement: "km/h"
value_template: "{{ states('sensor.village_outside_wind_max_spd') }}"
это позволит получить более человекочитаемые данные в дашборде, моем случае выглядит результат вот так
Все, осталось только накинуть системд юнит в /etc/systemd/system/rtl_433.service примерно такой
[Unit]
Description=RTL_433 service script
StartLimitIntervalSec=5
Documentation=https://github.com/merbanan/rtl_433/README.md
After=syslog.target network.target
[Service]
Type=exec
ExecStart=/usr/bin/rtl_433 -F 'mqtt://127.0.0.1:1883,retain=1,events=rtl_433/rtlsdr/event/21770,states=rtl_433/rtlsdr/state/21770' -c /etc/rtl_433/rtl_433.conf
# Restart script if stopped
Restart=always
# Wait 30s before restart
RestartSec=30s
# Tag things in the log
# View with: sudo journalctl -f -u rtl_433 -o cat
SyslogIdentifier=rtl_433
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
не забываем сделать релоад системд и сказать нашему юниту enable ну и ребутнуть разок что бы проверить что все это хозяйство переживает рестарт
ВСЕ, ПОБЕДА!
Данный способ ни на что не претендует, но возможно, этот путь кому-либо пригодится, поскольку позволяет дальше домашнюю автоматизацию развивать - например, многие почвенные датчики для садоводов точно так же общаются на 433 и их точно также можно загнать в HA и настроить автоматический полив ну и прочее такое. Этот гайд подойдет далеко не всем, но поскольку у меня очень давно поставлен HA (помните эту проблему про разные регионы для устройств от Xiaomi?) то хотелось использовать именно его. Всем спасибо и удачных данных из радиоэфира!