Анализаторы спектра и широкополосные радиоприемники — довольно популярные устройства, но ценовой диапазон может быть совершенно разный. У нас под рукой был свободный контроллер под Linux, мы решили собрать на его основе систему анализа радиочастот. Пришлось докупить разве что недорогой «USB-свисток» RTL-SDR, который подключили к контроллеру. С помощью софта мы переводим полученную информацию в удобные топики MQTT, которые затем можно обрабатывать.
Посмотрим, что полезного можно «нарыбачить» в эфире. И получится ли использовать пойманные данные для домашней автоматизации?
Сборка и установка
Мы купили универсальный USB-модуль RTL-SDR за пару тысяч рублей на алике. Поскольку под рукой уже был контроллер Wiren Board, мы подключили к нему модуль через порт USB. Затем прицепили к модулю небольшую антенну.
На стороне контроллера мы запустили установку утилиты rtl-433 строкой
apt install rtl-433
Затем достаточно запустить утилиту:
rtl_433 -F json
и парсить «выхлоп» json, который раскладываем в топики MQTT.
Запуск с ключом А включает режим отладки:
rtl_433 -A
Отладка также дает вывод со ссылкой на сайт, где можно посмотреть кодирование сигнала.
Практический опыт
Мы ограничились прослушиванием популярной частоты 433 МГц.
Сначала нам удалось поймать сигнал датчиков температуры и давления в шинах соседского автомобиля Toyota. Польза околонулевая.
Затем удалось найти соседский уличный датчик температуры и влажности, а это уже полезно. Можно сэкономить на собственном 🙂 Затем мы продолжили поиски и поймали еще несколько.
Команда
rtl_433 -F json
ловит такие данные с соседских датчиков
{"time" : "2024-01-20 19:02:07", "model" : "inFactory-TH", "id" : 17, "channel" : 3, "battery_ok" : 1, "temperature_F" : 14.500, "humidity" : 20, "mic" : "CRC"}
{"time" : "2024-01-20 19:02:12", "model" : "Nexus-T", "id" : 28, "channel" : 1, "battery_ok" : 1, "temperature_C" : -14.000}
{"time" : "2024-01-20 19:02:30", "model" : "Nexus-TH", "id" : 251, "channel" : 1, "battery_ok" : 1, "temperature_C" : -13.500, "humidity" : 14}
{"time" : "2024-01-20 19:02:42", "model" : "Solight-TE44", "id" : 151, "channel" : 1, "temperature_C" : -14.100, "mic" : "CRC"}
{"time" : "2024-01-20 19:02:39", "model" : "Hideki-TS04", "id" : 15, "channel" : 1, "battery_ok" : 1, "temperature_C" : -13.000, "humidity" : 5, "mic" : "CRC"}
{"time" : "2024-01-20 19:03:39", "model" : "Solight-TE44", "id" : 151, "channel" : 1, "temperature_C" : -14.100, "mic" : "CRC"}
{"time" : "2024-01-20 21:06:15", "model" : "Fineoffset-WH2", "id" : 59, "temperature_C" : -14.000, "mic" : "CRC"}
{"time" : "2024-01-20 20:50:30", "model" : "Hyundai-VDO", "type" : "TPMS", "id" : "21c154c2", "state" : 48, "flags" : 10, "repeat" : 1, "pressure_kPa" : 226.875, "temperature_C" : -16.000, "maybe_battery" : 1, "mic" : "CRC"}
{"time" : "2024-01-20 19:04:07", "model" : "TFA-TwinPlus", "id" : 57, "channel" : 1, "battery_ok" : 1, "temperature_C" : -13.700, "humidity" : 20, "mic" : "CHECKSUM"}
Для удобства предлагаем код, который «ловит» метеоданные с соседских датчиков.
#!/bin/bash
HOST=127.0.0.1
wirenBoardPubHeaderMQTT() {
local model=$1
local name=$2
mosquitto_pub -h $HOST -r -t "/devices/rtl-${model}/meta/name" -m "${name}"
mosquitto_pub -h $HOST -r -t "/devices/rtl-${model}/meta/driver" -m "gateRTL433-MQTT.sh"
}
# однократный вызов при старте
wirenBoardPubHeaderMQTT "sdr" "Radio Meteo/RTL_433"
wirenBoardPubHeaderMQTT "Hideki-Wind" "Radio My Weather"
# Функция для отправки данных в MQTT
wirenBoardPubMQTT() {
local filename="gateRTL433-MQTT_log_output_$(date +'%Y%m%d').txt"
local model=$1
local param=$2
local value=$3
local type=$4
if [ "$value" != "null" ]; then
echo -e "$(date +'%Y%m%d_%H%M%S') ${model} ${param}=${value}" | tee -a $filename
mosquitto_pub -h $HOST -r -t "/devices/rtl-${model}/controls/${param}/meta/type" -m "$type"
mosquitto_pub -h $HOST -r -t "/devices/rtl-${model}/controls/${param}/meta/readonly" -m "1"
mosquitto_pub -h $HOST -r -t "/devices/rtl-${model}/controls/${param}" -m "$value"
# else
# echo "$model / $param / $type is null !!!"
fi
}
# Функция для обработки данных
process_weather_wind() {
local data=$1
# echo $data
model=$(echo $data | jq -r '.model')
if [[ $model == "Hideki-Wind" ]]; then
# Извлекаем и отправляем каждый параметр
temperature=$(echo $data | jq -r '.temperature_C')
wind_avg_km_h=$(echo $data | jq -r '.wind_avg_km_h')
wind_max_km_h=$(echo $data | jq -r '.wind_max_km_h')
wind_approach=$(echo $data | jq -r '.wind_approach')
wind_dir_deg=$(echo $data | jq -r '.wind_dir_deg')
# Отправка данных в MQTT
wirenBoardPubMQTT "$model" "temperature_C" "$temperature" "temperature"
wirenBoardPubMQTT "$model" "wind_avg_km_h" "$wind_avg_km_h" "wind_speed"
wirenBoardPubMQTT "$model" "wind_max_km_h" "$wind_max_km_h" "wind_speed"
wirenBoardPubMQTT "$model" "wind_approach" "$wind_approach" "counter"
wirenBoardPubMQTT "$model" "wind_dir_deg" "$wind_dir_deg" "value"
fi
}
# Функция для обработки данных
process_data() {
local data=$1
#echo "Обработка данных: $data"
echo $data | grep "Hideki-Wind" > /dev/null
if [[ $? -eq 0 ]]; then
model=$(echo $data | jq -r '.model')
if [[ $model == "Hideki-Wind" ]]; then
process_weather_wind "$data"
fi
else
echo $data | grep temperature_C > /dev/null
if [[ $? -eq 0 ]]; then
model=$(echo $data | jq -r '.model')
temperature=$(echo $data | jq -r '.temperature_C')
wirenBoardPubMQTT "sdr" $model $temperature "temperature"
fi
fi
}
rtl_433 -C si -F json | while IFS= read -r line; do
process_data "$line"
done
Также удалось поймать сигнал с пролетающего самолета (на другой частоте) и сравнить его с картой Flightradar. Бортовой номер и скорость совпали, ура!
Еще одна польза — отладка сигналов Z-Wave и Lora в тестовой лаборатории, но мы пока только думаем над этим.
Вообще мы рекомендуем заглянуть в таблицу, где приведен список программ, которые работают с RTL-SDR.
Подключаем метеостанцию
Несколько лет назад родственнику была подарена старая метеостанция с уличным блоком, измеряющим направление и скорость ветра. Пришлось на время «вернуть на родину». Думали придется хакать протокол, но все заработало из коробки. Конечно, возможности уступают метеостанции «Ласточка» в предыдущем обзоре, но для дома польза будет.
Поиск свободных радиоканалов
Еще один полезный сценарий — поиск свободных радиоканалов с целью пообщаться с тусовкой друзей. В нашем случае, например, обычно собирается тусовка на 100+ раций.
Здесь мы пошли на небольшой чит и воспользовались ПК, поскольку нужен был графический вывод. На контроллере Wiren Board придется довольствоваться текстовой информацией, которую можно вывести в файл и потом обработать, например.
Ниже приведен скриншот программы gqrx, которую можно установить командой:
sudo apt install gqrx-sdr
По горизонтали частота в районе 433 МГц, по вертикали — время: на скриншоте показаны 10 минут. Диапазон LDP, показаны каналы от 1 до 69. Желтые и красные — это шумы: они есть почти на всех каналах. Немного поменьше шума на 1, 2 и 68, 69 каналах. Тональный субкод весьма удобен для фильтрации шумов.
Есть режим, помогающий разработчикам проектировать свои устройства. Через SSH на контроллере можно запустить утилиту командой:
rtl_433 -A
причем утилита к каждому распознанному цифровому пакету добавляет ссылку на сайт, где можно посмотреть подробную развертку сигнала. Ниже приведен пример скриншота сайта.
Ретранслятор FM-радио
Еще один сценарий, который мы проверили — ретранслятор FM-радио в браузер по сети. Вдохновила статья, где приведены все команды. Чтобы подобрать нужные команды, пришлось развлекаться. Вот они:
rtl_fm -f 102.0M -M fm -s 170k -A fast -r 32k -l 2 -E deemp | play -t raw -r 32k -es -b 16 -c 1 -V1 -
Затем достаточно набрать IP-адрес и порт контроллера в браузере, после чего можно будет слушать радио. Кроме того, можно установить в контроллер Wiren Board звуковую карту USB и через нее выводить звук на колонки.
Заключение
Как видим, подключить различное оборудование на 433 Мгц к своей домашней автоматизации легко и просто. И крупные бюджеты не нужны, особенно если под рукой есть контроллер на Linux. Для нас подобный широкополосный радиоприемник — больше игрушка. Но можно найти и практическое применение: мы, например, получили данные с метеостанции, датчика температуры и давления в шинах, дверного звонка.
Возможно, вы подскажете какие-либо практически применения в комментариях? Или поделитесь своим опытом?