MeteoWind ioT Pro LoRaWAN for environmental monitoring

MeteoWind ioT Pro LoRaWAN for environmental monitoring

MeteoWind IoT Pro wireless wind speed and direction sensor message format

We decided to release the MeteoWind IoT Pro (formerly IoT-Wind) message format for LoRaWAN and Sigfox weather transmitters and its Java-Script decoder code as open-source to give our customers the freedom to create customer-centric applications with our hardware.

The MeteoWind IoT wireless wind sensor not only far exceeds WMO data quality and accuracy levels, it is perfectly suited for wind resource assessment with a class leading preliminary classification for MEASNET/IEC 61400-12-1:2017 edition 2 class A = 4.4 and class C = 4.7. Whats more, its response to changing wind speeds and gusts is lightning fast as shown by its very low 0.2 second step response time constant at 8m/s, which is faster than just about all ultrasonic anemometers, thereby making the MeteoWind IoT Pro more responsive and more accurate that any ultrasonic anemometer on the market.

We will keep offering our allMETEO web portal platform as the default data solution for the MeteoWind IoT Pro and MeteoHelix IoT Pro and MeteoRain IoT Compact wireless weather transmitters. Making our weather station sensors’ message format public while maintaining data transmission security will enable 3rd parties, to build their own software applications and mobile apps as they see fit, to suit their customers.

Being the only compact anemometer with a wind vane to meet the World Meteorological Organization (WMO) measurement precision standards for climatology and meteorology makes the MeteoWind IoT Pro an ideal platform for climatic research 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 wind vector map app with the MeteoWind IoT Pro wind transmitter

(USED ON DEVICES WITH PRODUCTION DATE UP TO AND INCLUDING YEAR 2021)
Type = 0, MeteoWind IoT Pro wireless message format (8 bytes with 10 minute transmit interval)
bits2 bits5 bits9 bits9 bits9 bits9 bits9 bits8 bits8 bits4 bits
Physical
property
Message
type
BatteryWind_ave10Wind_max10Wind_min10Dir_ave10Dir_max10Dir_hi10Dir_lo10free
Units-Vm/sm/sm/sdegreesdegreesdegreesdegrees-
Resolution-0.050.10.10.11111-
Minimum value03.00000000-
  • Wind_ave10 value is mean (average) wind speed for the 10 minute interval.

  • Wind_max10 value is added to the Wind_ave10 value.

  • Wind_min10 value is subtracted from the Wind_ave10 value.

  • Sensor Error or N/A = Maximum possible bit value for each measurand in binary = 111111…. (FFFFF…. In hex) signifies measurement error code.

  • Dir_ave10 is the mean (average) wind direction for the 10 minute interval.

  • Dir_max10 is the wind direction of the maximum gust wind speed (Wind_max10).

  • Dir_hi10 value is added and Dir_lo10 subtracted from the Dir_ave10.
    These values set the range of wind directions to the right and left of the mean wind value, inbetween which 68.2% wind speeds occured during the sampling time interval of 10 minutes.


The Things Network Payload Decoder

MeteoWind IoT Pro wind transmitter payload 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 MeteoWind IoT Pro wind transmitters, this JavaScript code can be integrated into your application which receives the MeteoWind IoT Pro message payload from the Sigfox Backend.


2021 Open-Source Decoder JavaScript Code

Decoder for LoRaWAN and Sigfox MeteoWindIoT Pro wind transmitter for message type = 0, valid for MeteoWind IoT units with 2021 production dates and earlier.

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 != 9) return {"status": "ERROR", "description": "9 bytes are required"};
 
    Type =  bitShift(2);
    Battery = precisionRound(bitShift(5)*0.05+3, 1);
    Wind_ave10 = precisionRound(bitShift(9)*0.1, 1);
    Wind_max10 = Wind_ave10 + precisionRound(bitShift(9)*0.1, 1);
    Wind_min10 = Wind_ave10 - precisionRound(bitShift(9)*0.1, 1);
    Dir_ave10 = precisionRound(bitShift(9)*1, 1);
    Dir_max10 = precisionRound(bitShift(9)*1, 1);
    Dir_hi10 = precisionRound(bitShift(8)*1, 1);
    Dir_lo10 = precisionRound(bitShift(8)*1, 1);
  
  decoded = {
    "1_Type": Type,
    "2_Battery": Battery,
    "3_Wind_ave10": Wind_ave10,
    "4_Wind_max10": Wind_max10,
    "5_Wind_min10": Wind_min10,
    "6_Dir_ave10": Dir_ave10,
    "7_Dir_max10": Dir_max10,
    "8_Dir_hi10": Dir_hi10,
    "9_Dir_lo10": Dir_lo10,
  };
  
  return decoded;
}

2022 Open-Source Decoder JavaScript Code

Decoder for LoRaWAN and Sigfox MeteoWindIoT Pro wind transmitter, valid for MeteoWind IoT units with 2022 production dates.

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 != 10) return {"status": "ERROR", "description": "10 bytes are required"};
 
    Index = precisionRound(bitShift(8)*1, 1);
    Battery = precisionRound(bitShift(3)*0.2+3, 1);
    Wind_ave = precisionRound(bitShift(9)*0.1, 1);
    Wind_3sgust = Wind_ave + precisionRound(bitShift(9)*0.1, 1);
    Wind_3smin = Wind_ave - precisionRound(bitShift(9)*0.1, 1);
    Wind_stdev = precisionRound(bitShift(8)*0.1, 1);
    Dir_ave = precisionRound(bitShift(9)*1, 1);
    Dir_3sgust = precisionRound(bitShift(9)*1, 1);
    Dir_stdev = precisionRound(bitShift(7)*1, 1);
    Gust_time = precisionRound(bitShift(7)*5, 1);
    Vector_scalar = precisionRound(bitShift(1)*1, 1);
    Alarm_sent = precisionRound(bitShift(1)*1, 1); 
  
  decoded = {
    "1_Index": Index,
    "2_Battery": Battery,
    "3_Wind_ave": Wind_ave,
    "4_Wind_3sgust": Wind_3sgust,
    "5_Wind_3smin": Wind_3smin,
    "6_Wind_stdev": Wind_stdev,
    "7_Dir_ave": Dir_ave,
    "8_Dir_3sgust": Dir_3sgust,
    "9_Dir_stdev": Dir_stdev,
    "10_Gust_time": Gust_time,
    "11_Vector_scalar": Vector_scalar,
    "12_Alarm_sent": Alarm_sent,
  };
  
  return decoded;
}