Introduction: Read 433Mhz Sensors Values by RF Bridge and Node-RED

Finishing my greenhouse i decided to monitor the temperature in it and as i already have some home automation in place (Node-RED running on Raspberry Pi and SONOFF devices communicating over MQTT) of course i wanted to be able to record the values in my database so i can look back at them in future and also know what is happening inside the greenhouse without leaving house. The only problem is that i dont have there any power supply and any sensor i place there must be able to withstand the negative temperatures in the winter and very humid environment as well. Sure there are plenty of options to be found on internet however for my home monitoring and automation i use Node-RED and Tasmota flashed devices or devices able to communicate using MQTT which i would prefer to keep that way and so my options were limited. The WIFI connection in the greenhouse is almost none so any sensor using WIFI was also not a good option and anyway most of sensors i found were for home environment or had no specification for it. After couple of weeks searching i decided to take some simpler approach. Few years back when i was first experimenting with Tasmota i bought RF Bridge from SONOFF so i thought it would be cool to try use it for reading 433Mhz sensors. Such sensors are quite cheap and designed for outdoor environment. So i have made some research to see on which brands and models i can find some documentation and decided to buy Auriol RC Weather station with 3 sensors 4-LD6032. It came with batteries for 20€ so if this wouldn't have worked no big deal.

Step 1: Prepare SONOFF RF Bridge

As mentioned above few years ago i have purchased SONOFF RF Bridge R2 v1 and i have used it with PIR 433Mhz sensor and door bell button. I have flashed Tasmota firmware to it those years ago as i do for most my devices however soon after looking into reading 433Mhz temperature sensor values i have realized the Tasmota firmware on its own is not enough. But nothing was lost yet as there is another piece of firmware for frequency reading chip called Portish. There are many guides describing flashing of this firmware even on Tasmota website but the best i found was Youtube video explaining exactly what i needed to do with same version of RF Bridge i had. Following the instructions soon i had RF Bridge ready to catch 433Mhz messages flying around.

So once the RF Bridge had all necessary firmware the first step was to set it into raw mode and see if we are receiving anything. To enter raw mode i used command

rfraw 177 

as described in Tasmota documentation and straight away i started to see messages like this:

20:57:38.614 MQT: tele/rf_bridge/RESULT = {"Time":"2023-12-12T20:57:38","RfRaw":{"Data":"AA B1 04 0244 078A 03B6 0F5A 38182818282828182818281828282828281828280818282818181818182818281828281818 55"}}

Now all i needed was to extract temperature and humidity values from it.

Step 2: Converting RF Bridge Message Into Binary Code

Searching for guidelines how to decode RF Bridge message did not return a lot of information and I end up following documentation on Portish github. The part withbitwise operation was bit unclear to me but after reading it over and over somehow i managed to get correct binary.

So first in the documentation it is described the structure of the message. Important for me is that it is split into 9 parts where part number 8 contains the data i need.

1_ 2_ 3_ 4___ 5___ 6___ 7___ 8_________________________________________________________________________ 9_
AA B1 04 0244 078A 03B6 0F5A 38182818282828182818281828282828281828280818282818181818182818281828281818 55

So i start with a string from part 8 (last but one)

38182818282828182818281828282828281828280818282818181818182818281828281818

where first number is number of sync bucket which i dont need so i remove it. According the documentation the last or second character indicate "second sync bucket" which is depending on protocol. I didnt find any information about this so i simply tried to remove last character and see if it works. So after these 2 character removal i get string

818281828282818281828182828282828182828081828281818181818281828182828181

The next step was bit confusing as the terms like long high or short low are completely foreign to me and google gave me unrelated answers but this is what i have done. For each two characters lets do bitwise AND operation by 0x77 (hexadecimal) and if the result is 1 lets print 1 if else lets print zero. For example 0x81 & 0x77 = 0x1 -> 1, 0x82 & 0x77 = 0x2 -> 0. So finally we get the binary string we are after:

81 82 81 82 82 82 81 82 81 82 81 82 82 82 82 82 81 82 82 80 81 82 82 81 81 81 81 81 82 81 82 81 82 82 81 81
1  0  1  0  0  0  1  0  1  0  1  0  0  0  0  0  1  0  0  0  1  0  0  1  1  1  1  1  0  1  0  1  0  0  1  1 

And now we need to decode this binary string and get the sensor values.

Step 3: Decoding Sensor Binary Data

Right so now we have binary string sent from temperature and humidity sensor we need to find out how to read it. Before i even purchased my sensors i have had a look on internet if i can find any documentation on it. It appears the format of binary depends on brand as each company can do it bit differently. Luckily i have managed to find some info about Auriol weather station protocol. Its not the same model i have but i hoped it would be similar enough to work it out.

In the protocol documentation the binary string is split into parts which contains information like temperature, humidity channel and sensor id. The Auriol weather station which i have purchased (model 4-LD6032) is slightly different from that protocol description but by some trial and error i was able to get the values i am interested in (temperature, humidity and channel to help identify sensor). So in my case the data is stored as follows:

1010 0010 1010 0000 1000 1001 1111 0101 0011
-ID------ ??ch ---temper----- ???? --humid--

The first 8bits is random id of sensor which generated when the sensor is powered by battery. It can be used to identify sensor but the id will change when battery is taken out and inserted back.

The bit 9 and 10 i am not sure about.

The bit 11 and 12 indicates channel. In above example its 10 which in decimal is number 2. I have 3 sensors each on separate channel (1, 2 and 3).

The bits 13-24 is temperature as twos complement signed binary number. Basically the positive values is quite easy to decode as its simple conversion of binary to decimal however it took me a little while to find the formula to decode negative numbers (I will add JavaScript code i used in next chapter). In the example above binary number 0000 1000 1001 is 137 in decimal. In case of Auriol sensors the temperature is send with one decimal place so we need to multiply the result by 0.1 which in our example is 13.7 °C.

The bits 25-28 again i dont know what they are in my case they are always 1111.

And the bits 29-32 represents humidity in %. In example above its 01010011 which converted to decimal is 83%.

So here we are. We are able to read and understand the 433 Mhz sensor messages and now its time to put it into Node-RED for automation.

Step 4: Process Data Using Node-RED

As i already mentioned i am using MQTT protocol to transfer messages from Iot devices to Node-RED and it is same in case of RF Bridge. Message received from RF Bridge is in JSON format like this:

{
   "Time":"2023-12-12T20:57:38",
   "RfRaw":{
      "Data":"AA B1 04 0244 078A 03B6 0F5A 38182818282828182818281828282828281828280818282818181818182818281828281818 55"
   }
}

Once received i convert it to JSON object using JSON node and then i process it using JavaScript function node with following code:

var rfdata = msg.payload.RfRaw.Data;

//extract portion of data containing sensors binary string
var buckets = rfdata.split(' ');
var databucket = buckets[buckets.length - 2];

// remove first and last characters indicating sync bucket and second sync bucket
var data = databucket.substring(1, databucket.length-1);

//convert data to binary string
var convertedData = "";
for (let i = 0; i < data.length; i=i+2) {
  var oc = parseInt(data.substring(i, i+2), 16);
  var cc = oc & 119; //119 decimal = 0x77;
  if (cc == 1) {
    convertedData = convertedData + 1;
  }
  else {
    convertedData = convertedData + 0;
  }
}

msg.payload.convertedData = convertedData;

// check we have correct length of binary string (pir sensor is only 24)    
if (convertedData.length == 36) {
// get the binary parts we are interested in (temperature, humidity and channel)
    var channelbimary = convertedData.substring(10, 12);
    var tempbinary = convertedData.substring(12, 24);
    var humbinary = convertedData.substring(28, 36);

// define small function to convert signed twos complement binary to decimal value
    const getSigned = binStr => parseInt(binStr.length >= 8 && binStr[0] === "1" ?
      binStr.padStart(32, "1") : binStr.padStart(32, "0"), 2) >> 0;

//convert binary values to decimal/integer
    var temp = getSigned(tempbinary) * 0.1;
    var hum = getSigned(humbinary);
var channel = parseInt(channelbimary, 2);

// create new payload to send to next node  
    msg.payload = {
        type: "THSENSOR",
        channel: channel,
        temperature: temp,
        humidity: hum,
        convertedData: convertedData,
    };
}

Once the data is parsed to human readable format I send it to my web application which i use for recording of values and then presenting it in form of charts and informative dashboard.

Here is the final JSON

{
   "type":"THSENSOR",
   "channel":2,
   "temperature":13.700000000000001,
   "humidity":83,
   "convertedData":"101000101010000010001001111101010011"
}

Step 5: The End

Finally one more thing todo is to make sure RF Bridge automatically enters raw sniffing mode after boot by setting the rule

on system#boot do rfraw 177 endon

and that's it.

I hope this might be helpful for anyone who tries same approach to read the 433Mhz data. For me this is perfect as i can still use RF Bridge for reading SONOFF PIR sensor and door bell button as was doing before only now I get also info about my new greenhouse and i did not need to get any expensive or specialized hardware for it.