Выгружаем данные из метеорологической стации Oregon Scientific WMR500

от автора

Однажды мы решили, что нам на сайте нужна своя актуальная погода за окном. А значит нужна какая-то метеорологическая станция с подключением в Интернет. Недорого. Ибо брать что-то типа Davis Vantage Pro2 Plus за овер 100 тысяч рублей, да еще и держать отдельный компьютер для подключения к ней (как это сделали в mail.ru) не хотелось как с точки зрения бюджета, так и с точки зрения сложности.


Выбор пал на недорогую, достаточно свежую метео-станцию Oregon Scientific WMR500. Обзор её я делать не буду, можете самостоятельно поискать в Интернете. Достаточно того, что она умеет измерять температуру, влажность, давление, скорость и направление ветра. В теории она умеет еще качество воздуха и уровень УФ-излучения, но мы не нашли в продаже соответствующих дополнительных датчиков. Ценой за бюджетность была схема её работы. Данные она сама отдает в облако по Wi-Fi. Доступ к данным есть в мобильном приложении, а так же с web, но несколько странный. Об этом, собственно, и пойдет речь.

Для получения доступа к web-части необходим аккаунт, который создается в мобильном приложении. Собственно и настройка станции в части того, какой Wi-Fi ей использовать для подключения происходит только в приложении при первичном подключении к временной точке доступа самой станции. Тут все делается по инструкции и ничего сложного нет. В итоге, в приложении мы получаем добавленное устройство, id которого нам понадобится далее.

Web-интерфейс находится по адресу http://web-wmr500.idtlive.com/

Зайдя в него, можно смотреть графики средней красивости по кнопке «Show», а так же экспортировать данные в формате XLS за выбранный период (кнопка «Export»). Сразу скажу, что показ влажности на график работает, а вот экспорт нет, потому что данные влажности экспортируются вместе с данными температуры. Такая вот странная ситуация. Посматривая в запросы можно увидеть, что для графиков есть некий api, отдающий данные в json, что уже хорошо. Можно грабить корованы!

Для примера «грабим» набор данных по темпрературе за сутки. Запрос пойдет на web-wmr500.idtlive.com/index/api.show/index.html, с параметрами (тут PHP массив параметров для примера):

$request = [ 	'type'		=> 'temperature', 	'unit'		=> '°C', 	'id'		=> 'id-вашего-устройства', 	'channel'	=> 'номер-канала-блока-датчиков', 	'start'		=> "'2020-07-20T00:00:00Z'", 	'end'		=> "'2020-07-21T00:00:00Z'", ]; 

Даты обязательно в одинарных кавычках и в формате ISO 8601 без TimeZone. Номер канала (channel) – 1, 2 или 3, в зависимости от того, на каком канале подключен блок датчиков. Данные запроса по типам отличаются собственно типом запрашиваемых данных (type) и единицами измерения (unit).
Все доступные типы и единицы измерения:

temperature – °C или °F humidity – % rain – mm/h или inch/h wind – m/s, knots, kph, mph pressure – mbar,hPa,mmHg,inHg 

Одно плохо, через api.show можно получить данные только указанных параметров, к примеру нельзя узнать направление ветра, или точку росы, да там много всего статистического. А хотелось бы. И тут нам поможет EXPORT.

Делаем первый запрос на адрес web-wmr500.idtlive.com/index/api.export/index.html с теми же параметрами. В ответ сервер где-то в дебрях генерирует статический XLS файл и отдает ссылку на него. Скачать его можно после этого в любой момент (я видел на сервере чужие файлы за 2018 год, папка открыта для индексирования). В файлах уже существенно больше информации, вернее она там вся доступная.

Но тут тоже есть свои плюсы и свои минусы. Плюс – вы можете получить данные за нужный период. Минус — в web-часть эти данные попадают с 15-ти минутным интервалом. Для хранения погоды у себя в БД это даже хорошо, можно загрузить сразу все данные с момента запуска станции и все такое. А вот если вы хотите чаще, или быстрее получать актуальную информацию, то придется провести более продвинутые изыскания.

Я «психанул» и решил перехватить трафик приложения, оно получает данные практически мгновенно. Вернее оно получает данные «напрямую» от станции, которая отдает последние данные, полученные от блока датчиков. А блок датчиков она опрашивает раз в 15 секунд.

Оказалось, что приложение по протоколу MQTT идет куда-то в инстанс амазона (адрес 35.161.38.128 получен путем перехвата трафика, кхе-кхе), подписывается на топик со случайным topic-id, шлет в топик станции (она сама по wi-fi и подкючена только по MQTT только туда, web-часть судя по всему тоже периодически из брокера MQTT эти же даные и получает) с её id команду типа «родная, дай-ка мне свой статус, ответь в topic-id». И если для получения данных с web-части я использовал php + curl (вы можете использовать то, что вам больше по душе), то тут нужна асинхронщина в рамках одного соединения. Быстро и «на коленке» я придумал только использовать node.js. Понадобится модуль mqtt.
В моем случае это просто консольный скрипт, который через exec я «дергаю» в php.

#!/usr/bin/node  var mqtt = require('mqtt');  /* вместо some@mailhost.com используйте свой адрес почты, на который зарегистрирован аккаунт в приложении */  var client = mqtt.connect( {   host : '35.161.38.128',   port : 1883,   cliendId : 'Android_some@mailhost.com' });  /* придумайте свой id, его приложение генерирует каждый запрос новых, но это не важно */ var some_uniq_topic = 'F456F3A5-F36D-2FE5-AAE4-B71FE528FF01';  /* тут id вашей станции */ var station_id	= '2e846e12-7cd1-5563-9dbd-fc5728db457d';  client.on('connect', function() {   client.subscribe('enno/out/json/'+some_uniq_topic ,     function(err) {       if (!err) {       client.publish('enno/out/json/'+station_id,'{"command":"getChannel1Status","id":"'+some_uniq_topic+'"}');       } else {         console.log('connect error');       }    }) })  client.on('message', function(topic, message) {   console.log(message.toString())   client.end() }) 

Как парсить данные из web-части (JSON), экспорта (Excel) или из MQTT (JSON) я рассказывать не буду, тут уж как хотите, так и обрабатывайте.

Вот собственно и все. Если кому-то вдруг поможет, то буду только рад.

ссылка на оригинал статьи https://habr.com/ru/post/511850/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *