How to receive Temperature and Humidity from 433 MHz Weather Station

I would like to measure the outdoor temperature and humidity and add it to my Openhab home automation. I already got a Baldr 433 MHz weather station outside (similar to Baldr, Tchibo, Bresser…) with indoor receiver and actually do not like to put an ESP outside or feeding a cable somehow outside. Therefore I prefer to receive and decode the 433 MHz signal, ideally with the same ESP which I already use to control my RC remotes. I searched quite a bit and it seems that there are no good solutions published for that. However, I got it to work and would like to share it with you.
What do you need:

  • An ESP 8266 with Tasmota (I used a Wemos D1 mini)
  • A good 433 MHz receiver - I used an RXB6 and soldered an antenna (for example a cable with lambda/4 = 17cm). Finding a good receiver is crucial because the signals are not very strong and most of the receivers are not narrow band (disturbed by any kind of rf). FST XY-MK-5V did not work very well. If you got trouble with your receiver, try to stabilize its supply (5V) by some capacitors.
  • Openhab

Remote temperature sensors use the Nexus protocol. You need to receive 36 bits with the Nexus protocol (GitHub - jorgegarciadev/Arduinonexus: Nexus 433Mhz radio protocol library for Arduino and Esp8266). Tasmota (>=9.2) already supports decoding of RC-switch signals, however the Nexus protocol is not yet supported. It is quite easy to add it. Check the Tasmota documentation for compiling it.

Increase the size of the receive buffer to 40 bit in RCSwitch.h:
#define RCSWITCH_MAX_CHANGES 83

Add the protocol in RCSwitch.c
{ 500, 0, { 0, 0 }, 1, { 0, 7 }, { 1, 2 }, { 1, 4}, false, 0 } // 36 (Nexus, 36 bit)

Compile it and after flashing make sure to activate the new protocol (36 in my case) by typing
RfProtocol36 1

Now you should be able to see messages like that in your Tasmota console:
tele/tasmota_sensor/RESULT = {"Time“:“xxx“,“RfReceived":{"Data":"0xFA075F38","Bits":36,"Protocol":36,"Pulse":555}}
We received 36 bit, the pulse width depends on your transmitter and should be around 500us. If you got that far, the most difficult part is completed. Let’s decode the data section with an Openhab rule.

Add a thing to Openhab to receive the MQTT message:
Type string : nexusmessage "Nexus Message" [ stateTopic="tele/tasmota_sensor/RESULT", transformationPattern="JSONPATH:$.RfReceived"]

My item containing the received message is called Sensors_NexusMessage. Furthermore you need to create items for the decoded temperature and humidity.

Write a rule containing the following code:

rule "Process Nexus Message"
when
    Item Sensors_NexusMessage received update 
then
    /* decode message received by Tasmota */
    val data_hex = transform("REGEX", ".*Data=0x([A-Fa-f0-9]*),.*", Sensoren_NexusMessage.state.toString) 
    val data_bits = transform("REGEX", ".*Bits=(\\d*),.*", Sensoren_NexusMessage.state.toString) 
    logInfo("Nexus","Hex value: " + data_hex)

    var long sensor_channel = 1;
    var long sensor_id = 15;
    
    if (data_bits == "36") {
        var data =  Long.parseLong(data_hex.trim(), 16)

        /* decode bit 0-7: humidiy */
        var data_humid = (data.bitwiseAnd(0xFF)) as Number 

        /* decode bit 8-11: FF pattern */
        var long data_pattern = data.bitwiseAnd(0xF00) >> 8

        /* decode bit 12-23: temperature */
        var data_temp = (data.bitwiseAnd(0x0FFF000) >> 12) as Number
        data_temp = data_temp / 10

        /* decode bit 24-25: channel */
        var long data_chan = data.bitwiseAnd(0x3000000) >> 24

        /* decode bit 27: batttery state */
        var long data_batt = data.bitwiseAnd(0x8000000) >> 27

        /* decode bit 28-35: ID */
        var long data_id = data >> 28
        
        /* check if expected channel and ID match */
        if ((sensor_channel == data_chan) && (sensor_id == data_id)) {
            Sensor_Humidity.postUpdate(data_humid)
            Sensor_Temperature.postUpdate(data_temp)
        }
       
        logInfo("Nexus","Sensor: "+ data_id.toString +", Channel " + data_chan.toString + ", Battery:" + data_batt.toString + ", Temp " + data_temp.toString + "degC, Humid "+ data_humid.toString + "%, Pattern "+ data_pattern)
    }

end

You need to change the channel and the ID in order to ensure, that you receive your weather data instead of your neighbor’s signals. That’s it! If you got an outdoor sensor without humidity the respective value is 0.

Hope it works for you :slight_smile: If you got additional ideas, questions or improvements, let me know. Have fun!