Why did we make the MeteoHelix weather station message format public?

We decided to release the MeteoHelix weather station message format and its Java-Script decoder code as open-source because of a wide array of customer requests. Our customers have very wide ranging applications for weather data.

We will keep offering our allMETEO web portal platform as the default data solution for the MeteoHelix IoT weather stations. Making the MeteoHelix weather station message format public will enable 3rd parties, which to not wish to use the allMETEO cloud, to build their own software applications and mobile apps as they see fit.

Being the only micro-weather station to meet the World Meteorological Organization (WMO) measurement precision standards for climatology and meteorology makes the MeteoHelix an ideal platform for research and high-density climatic networks. Its data can be reliably used by national weather services for precision weather forecasting. Opening up the communication protocol will enable meteorological, oceanographic and private organizations to bring real benefits to their customers.

Build your own weather app with the MeteoHelix

MeteoHelix IoT Pro LoraWAN smart-cities application for urban climate and urban heat island monitoring

MeteoHelix IoT Pro LoraWAN smart-cities application for urban climate and urban heat island monitoring


Type = 1, MeteoHelix wireless message format (11 byte for 10min transmit intervals)
bits2 bits5 bits11 bits6 bits6 bits9 bits14 bits10 bits9 bits8 bits8 bits
Physical propertyMessage typeBatteryTemperatureT_minT_maxHumidityPressureIrradiationIrr_maxRain (revolving counter)Min_time_between
rain_gauge_clicks
UnitsV°C°C°C%PaW/m2W/m2Rain gauge dependent182 ÷ Time in seconds
Resolution10.050.10.10.10.2522Rain gauge dependent1
Minimum value03 V-100 °C00050000 Pa0000
  • T_max & Irr_max values are added to the Temperature and Irradiation readings which are currently set to be 10 min averages of 10 s measuring intervals.

  • T_min is subtracted from the Temperature reading. (Future versions of the MeteoHelix will feature 10 or 5 second measuring intervals.)

  • Sensor Error or N/A = Maximum possible value for the physical property which in binary = 111111…. (FFFFF…. In hex)

  • Rain (revolving counter) value is a revolving counter which returns to zero after the maximum 255 value (8bits^2 - 1) is reached and starts counting up again. For each 10 minute data transmit interval, the amount of rain is equal to the difference between two consecutive values of this register times the rain gauge resolution.

    • So if the previous value was 253 and the current value is 3, then 7 clicks have been recorded as written out here: 253, 254, 255, 0, 1, 2, 3.

  • Min_time_between_rain_gauge_clicks (May not be implemented on some versions of MeteoHelix) is the minimum elapsed time between 2 successive rain gauge tipping bucket mechanism signals. It is used to determine the maximum instantaneous rain rate. It is transmitted as 182 / Time. (Rain rate = Rain gauge resolution divided by Minimum time between clicks)


Web based & Excel spreadsheet weather data message decoder/verifier


The Things Network Payload Decoder

MeteoHelix weather station payload message decoder JavaScript code can be pasted directly into your application on The Things Network LoRaWAN console.

Paste the unmodified javascript code into the decoder section of your the things network application.

Paste the unmodified javascript code into the decoder section of your the things network application.


Sigfox Network Payload Decoder

For Sigfox wireless network based MeteoHelix weather stations, this JavaScript code can be integrated into your application which receives the MeteoHelix message payload from the Sigfox Backend.


Decoder Code Modification Tips

For changing the rain gauge resolution directly in the JavaScript decoder code as listed here, please see the following FAQ article:

Open-Source Decoder JavaScript Code

Decoder for LoRaWAN and Sigfox MeteoHelix weather stations for message type = 1.

var pos = 0;
var bindata = "";

var ConvertBase = function (num) {
    return {
        from : function (baseFrom) {
            return {
                to : function (baseTo) {
                    return parseInt(num, baseFrom).toString(baseTo);
                }
            };
        }
    };
};

function pad(num) {
    var s = "0000000" + num;
    return s.slice(-8);
}

ConvertBase.dec2bin = function (num) {
    return pad(ConvertBase(num).from(10).to(2));
};

ConvertBase.bin2dec = function (num) {
    return ConvertBase(num).from(2).to(10);
};

function data2bits(data) {
    var binary = "";
    for(var i=0; i<data.length; i++) {
        binary += ConvertBase.dec2bin(data[i]);
    }
    return binary;
}

function bitShift(bits) {
    var num = ConvertBase.bin2dec(bindata.substr(pos, bits));
    pos += bits;
    return Number(num);
}

function precisionRound(number, precision) {
  var factor = Math.pow(10, precision);
  return Math.round(number * factor) / factor;
}

function Decoder(bytes, port) {
  bindata = data2bits(bytes);
 
  //if(bytes.length != 12) return {"status": "ERROR", "describtion": "11 bytes are required"}
    Type =  bitShift(2);
    Battery = precisionRound(bitShift(5)*0.05+3, 2);
    Temperature = precisionRound(bitShift(11)*0.1-100, 1);
    T_min = precisionRound(Temperature - bitShift(6)*0.1, 1);
    T_max = precisionRound(Temperature + bitShift(6)*0.1, 1);
    Humidity = precisionRound(bitShift(9)*0.2, 1);
    Pressure = bitShift(14)*5+50000;
    Irradiation = bitShift(10)*2;
    Irr_max = Irradiation + bitShift(9)*2;
    Rain = precisionRound(bitShift(8), 1);
    Rain_min_time = precisionRound(bitShift(8), 1);
 
 
  decoded = {
    "Type": Type,
    "Battery": Battery,
    "Temperature": Temperature,
    "T_min": T_min ,
    "T_max": T_max,
    "Humidity": Humidity,
    "Pressure": Pressure,
    "Irradiation": Irradiation,
    "Irr_max": Irr_max,
    "Rain": Rain,
    "Rain min time": Rain_min_time
  };

  return decoded;
}