Downloading data from the Oregon Scientific WMR500 meteorological station

Once we decided that the site needs its own actual weather outside the window. This means that you need some kind of meteorological station with an Internet connection. Inexpensive. For taking something like Davis Vantage Pro2 Plus for an over 100 thousand rubles, and even keeping a separate computer to connect to it (as they did in mail.ru ) did not want to, both in terms of budget and complexity.







The choice fell on an inexpensive, fairly fresh meteorological station Oregon Scientific WMR500. I will not review it, you can search the Internet yourself. It is enough that she can measure temperature, humidity, pressure, wind speed and direction. In theory, it also knows about air quality and the level of UV radiation, but we did not find the corresponding additional sensors on sale. The price for the budget was the way it worked. She herself sends data to the cloud via Wi-Fi. Data access is available in the mobile application, as well as from the web, but somewhat strange. This, in fact, will be discussed.



To access the web part, you need an account that is created in the mobile application. Actually, the configuration of the station in terms of which Wi-Fi to use for connection occurs only in the application during the initial connection to the temporary access point of the station itself. Here everything is done according to the instructions and there is nothing complicated. As a result, in the application we get the added device, the id of which we will need further.







The web interface is located at http://web-wmr500.idtlive.com/







Having entered it, you can view graphs of average beauty by clicking the β€œShow” button, as well as export data in XLS format for the selected period (the β€œExport” button). I must say right away that showing humidity on the graph works, but export does not, because humidity data is exported along with temperature data. Such is the strange situation. Looking at the requests, you can see that there is a certain api for charts that returns data to json, which is already good. You can rob cows!







For example, we "rob" a set of data on temperature per day. The request will go to web-wmr500.idtlive.com/index/api.show/index.html , with parameters (here is a PHP array of parameters for an example):



$request = [
	'type'		=> 'temperature',
	'unit'		=> 'Β°C',
	'id'		=> 'id--',
	'channel'	=> '---',
	'start'		=> "'2020-07-20T00:00:00Z'",
	'end'		=> "'2020-07-21T00:00:00Z'",
];


Dates are required in single quotes and in ISO 8601 format without TimeZone. The channel number (channel) - 1, 2 or 3, depending on which channel the sensor unit is connected to. Request data by types differ by the actual type of the requested data (type) and units of measurement (unit).



All available types and units:



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


One thing is bad, through api.show you can get data only for the specified parameters, for example, you cannot find out the wind direction, or the dew point, but there is a lot of statistical information. I would like to. And here EXPORT will help us.



We make the first request to the address web-wmr500.idtlive.com/index/api.export/index.html with the same parameters. In response, the server somewhere in the wild generates a static XLS file and gives a link to it. You can download it after that at any time (I saw other people's files for 2018 on the server, the folder is open for indexing). The files already contain significantly more information, or rather, it is all available there.







But this also has its pluses and minuses. Plus - you can get data for the required period. Minus - this data is sent to the web part with a 15-minute interval. It's even good for storing the weather in your database, you can download all the data at once from the moment the station was started and all that. But if you want to receive up-to-date information more often or faster, then you will have to conduct more advanced research.



I "freaked out" and decided to intercept the traffic of the application, it receives data almost instantly. Rather, it receives data "directly" from the station, which gives the latest data received from the sensor unit. And it polls the sensor unit every 15 seconds.



It turned out that the application via the MQTT protocol goes somewhere in the Amazon instance (the address 35.161.38.128 was obtained by intercepting traffic, cough-cough), subscribes to a topic with a random topic-id, sends it to the station's topic (she herself via wi-fi and connected only to MQTT only there, the web-part, apparently, also periodically receives the same data from the MQTT broker) with its id a command like "dear, give me your status, answer in topic-id". And if I used php + curl to get data from the web part (you can use whatever you like), then asynchrony is needed within one connection. Quickly and on my knees, I only thought of using node.js. You will need the mqtt module.



In my case, this is just a console script that I "pull" through exec into php.



#!/usr/bin/node

var mqtt  = require('mqtt');
var md5   = require('md5');

String.prototype.insert = function (index, string) {
  if (index > 0)
   return this.substring(0, index) + string + this.substring(index, this.length);
  else
    return string + this;
};

var host       = 'mqtt.idtlive.com';
var your_mail  = 'your_account_mail@somehost.com'; // see in app, registered account
var clientId   = 'Android_' + your_mail;
var deviceId   = 'your-device-id'; // see in app connected device section, something like F9987D92-E180-64DE-A202-D43AAD0D5784
var channelId  = 1; // channel beetwen station & external sensors block

var timeInMs   = Date.now();
var uniqTopic  = md5(timeInMs).toUpperCase().insert(8,'-').insert(13,'-').insert(18,'-').insert(23,'-');

var client = mqtt.connect( {
  host : host,
  port : 1883,
  cliendId : clientId
});

client.on('connect', function() {
  client.subscribe('enno/out/json/'+uniqTopic,
    function(err) {
      if (!err) {
        client.publish('enno/out/json/'+deviceId, '{"command":"getChannel'+channelId+'Status","id":"'+uniqTopic+'"}');
      } else {
        console.log('connect error');
      }
    })
});

client.on('message', function(topic, message) {
  console.log(message.toString())
  client.end()
});


I will not tell you how to parse data from the web part (JSON), export (Excel) or from MQTT (JSON), here you can handle it as you like.



That's all. If someone suddenly helps, I will only be glad.



PS> Update, the script code is combed, the generation of a random MQTT topic has been added, to simulate work both from the application, and also posted here



All Articles