Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Bresser 6in1 #1172

Closed
f4gqk opened this issue Oct 21, 2019 · 30 comments
Closed

Add support for Bresser 6in1 #1172

f4gqk opened this issue Oct 21, 2019 · 30 comments
Labels
device support Request for a new/improved device decoder

Comments

@f4gqk
Copy link

f4gqk commented Oct 21, 2019

Hello,

I bought this weather station:

https://www.bresser.de/en/Weather-Time/Weather-Center/BRESSER-PC-Weather-station-with-6-in-1-outdoor-sensor.html

I managed to decode this:

{"time" : "2019-10-21 19:31:35", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea252f8c4001618c7fffff989c7fffffff0127fc"}], "codes" : ["{206}d55555555516ea252f8c4001618c7fffff989c7fffffff0127fc"]}
{"time" : "2019-10-21 19:31:35", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea252f8c4001618c7fffff989c7fffffff0127fc"}], "codes" : ["{206}d55555555516ea252f8c4001618c7fffff989c7fffffff0127fc"]}
{"time" : "2019-10-21 19:31:47", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea56eb0c4001618c7fffff98a408ba44fff80bfe"}], "codes" : ["{207}d55555555516ea56eb0c4001618c7fffff98a408ba44fff80bfe"]}
{"time" : "2019-10-21 19:31:59", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"}], "codes" : ["{206}d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"]}
{"time" : "2019-10-21 19:32:11", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea56eb0c4001618c7fffff98a408ba44fff80bfe"}], "codes" : ["{207}d55555555516ea56eb0c4001618c7fffff98a408ba44fff80bfe"]}
{"time" : "2019-10-21 19:32:23", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 203, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117e"}], "codes" : ["{203}d55555555516ea07e18c4001618c7fffff98a47fffffff0117e"]}
{"time" : "2019-10-21 19:32:35", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"}], "codes" : ["{207}d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"]}
{"time" : "2019-10-21 19:32:47", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 205, "data" : "d55555555516ea07e18c4001618c7fffffb148fffffffe022ff8"}], "codes" : ["{205}d55555555516ea07e18c4001618c7fffffb148fffffffe022ff8"]}
{"time" : "2019-10-21 19:32:59", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea5b388c4001618c7fffffb148116489fff027fc"}], "codes" : ["{206}d55555555516ea5b388c4001618c7fffffb148116489fff027fc"]}
{"time" : "2019-10-21 19:33:11", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"}], "codes" : ["{206}d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"]}
{"time" : "2019-10-21 19:33:23", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"}], "codes" : ["{207}d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"]}
{"time" : "2019-10-21 19:33:35", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 205, "data" : "d55555555516ea07e18c4001618c7fffffb148fffffffe022ff8"}], "codes" : ["{205}d55555555516ea07e18c4001618c7fffffb148fffffffe022ff8"]}
{"time" : "2019-10-21 19:33:47", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"}], "codes" : ["{207}d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"]}
{"time" : "2019-10-21 19:34:11", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"}], "codes" : ["{207}d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"]}
{"time" : "2019-10-21 19:34:23", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 203, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117e"}], "codes" : ["{203}d55555555516ea07e18c4001618c7fffff98a47fffffff0117e"]}
{"time" : "2019-10-21 19:34:35", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"}], "codes" : ["{207}d55555555516ea5b388c4001618c7fffff98a408b244fff813fe"]}
{"time" : "2019-10-21 19:34:47", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"}], "codes" : ["{206}d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"]}
{"time" : "2019-10-21 19:34:59", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea5b388c4001618c7fffffb148116489fff027fc"}], "codes" : ["{206}d55555555516ea5b388c4001618c7fffffb148116489fff027fc"]}
{"time" : "2019-10-21 19:35:11", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"}], "codes" : ["{206}d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"]}
{"time" : "2019-10-21 19:35:23", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea4d4c0c4001618c7fffff98a408aa44fff81bfe"}], "codes" : ["{207}d55555555516ea4d4c0c4001618c7fffff98a408aa44fff81bfe"]}
{"time" : "2019-10-21 19:35:35", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"}], "codes" : ["{206}d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"]}
{"time" : "2019-10-21 19:35:47", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea4d4c0c4001618c7fffff98a408aa44fff81bfe"}], "codes" : ["{207}d55555555516ea4d4c0c4001618c7fffff98a408aa44fff81bfe"]}
{"time" : "2019-10-21 19:35:59", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"}], "codes" : ["{206}d55555555516ea07e18c4001618c7fffff98a47fffffff0117fc"]}
{"time" : "2019-10-21 19:36:11", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 207, "data" : "d55555555516ea4d4c0c4001618c7fffff98a408aa44fff81bfe"}], "codes" : ["{207}d55555555516ea4d4c0c4001618c7fffff98a408aa44fff81bfe"]}
{"time" : "2019-10-21 19:36:23", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 203, "data" : "d55555555516ea07e18c4001618c7fffff98a47fffffff0117e"}], "codes" : ["{203}d55555555516ea07e18c4001618c7fffff98a47fffffff0117e"]}
{"time" : "2019-10-21 19:36:35", "model" : "bresser", "count" : 1, "num_rows" : 1, "rows" : [{"len" : 206, "data" : "d55555555516ea23b50c4001618c7fffffb148115490fff03000"}], "codes" : ["{206}d55555555516ea23b50c4001618c7fffffb148115490fff03000"]}

I would like to decode the information to make it work with weewx.

How to do ?

Thank you

Sebastien

@zuckschwerdt
Copy link
Collaborator

Put the data into a BitBench like this, annotate with the expected readings and find out where the bits for that are.
I guessed a preamble of 55 54, could also be 55 51, but the well-known 2dd4popped out, thus aa aa 2d d4 is a good preamble. This also gives the alignment.
There seems to be distinct types of messages -- length and content differ. Also have a look at bresser_5in1.c it might be similar.

@rege245
Copy link

rege245 commented Jan 5, 2020

hi, i have new model of 5in1 (PN:7002580), which uses protocol of 6in1 . data seem to be ok, but not all strings are decoded. rain info is not true. sometime i received wrong temp and hum info.


time : 2020-01-05 12:54:09
model : Bresser-5in1 Temperature: 1.5 C Humidity : 73 Wind Gust : 3.0 m/s Wind Speed: 2.4 m/s
Direction : 338.0 ° Rain : 30.0 mm Integrity : CHECKSUM


@rege245
Copy link

rege245 commented Jan 5, 2020

time : 2020-01-05 12:56:57
model : bresser count : 1 num_rows : 1 rows :
len : 218 data : 555555555516ea43928c6007880c7f3cff19c400a1397ff80e00000
codes : {218}555555555516ea43928c6007880c7f3cff19c400a1397ff80e00000
bresser_6in1_callback: {160} 87 25 18 c0 0f 10 18 fe 79 fe 33 88 01 42 72 ff f0 1c 00 00


time : 2020-01-05 12:56:57
model : Bresser-5in1 Temperature: 1.4 C Humidity : 72 Wind Gust : 1.8 m/s Wind Speed: 1.6 m/s
Direction : 338.0 ° Rain : 10.0 mm Integrity : CHECKSUM


@rege245
Copy link

rege245 commented Jan 6, 2020

i found that temp under zero (-) not showing correctly. temperature -5.2 is received as 94 8a
{160} 92 7f 18 c0 0f 10 18 ff ff ff 29 28 94 8a 90 ff f0 05 00 00

i add this workaround.

    if (temperature > 60)
            temperature = temp_raw * 0.1f -100;

@zuckschwerdt
Copy link
Collaborator

Thanks. Where did you put that, which decoder are you using?

@rege245
Copy link

rege245 commented Jan 6, 2020

i am using modified bresser_5in1.c
all is ok, but checksum is not calculated, so sometime i get wrong data.

#include "decoder.h"

static int bresser_6in1_callback(r_device *decoder, bitbuffer_t *bitbuffer)
{
    uint8_t const preamble_pattern[] = {0xaa, 0xaa, 0x2d, 0xd4};

    data_t *data;
    uint8_t msg[24];
    uint16_t sensor_id;
    unsigned len = 0;

    if (bitbuffer->num_rows != 1
            || bitbuffer->bits_per_row[0] < 160
            || bitbuffer->bits_per_row[0] > 240) {
        if (decoder->verbose > 1) {
            fprintf(stderr, "%s bit_per_row %u out of range\n", __func__, bitbuffer->bits_per_row[0]);
        }
        return DECODE_ABORT_EARLY; // Unrecognized data
    }

    unsigned start_pos = bitbuffer_search(bitbuffer, 0, 0,
            preamble_pattern, sizeof (preamble_pattern) * 8);

    if (start_pos >= bitbuffer->bits_per_row[0]) {
        return DECODE_ABORT_LENGTH;
    }
    start_pos += sizeof (preamble_pattern) * 8;
    len = bitbuffer->bits_per_row[0] - start_pos;

    if (len < 144) {
        if (decoder->verbose > 1) {
            fprintf(stderr, "%s: %u too short\n", __func__, len);
        }
        return DECODE_ABORT_LENGTH; // message too short
    }
    // truncate any excessive bits
    len = MIN(len, sizeof (msg) * 8);

    bitbuffer_extract_bytes(bitbuffer, 0, start_pos, msg, len);

    bitrow_printf(msg, len, "%s: ", __func__);

    if (msg[12] == 0xff)
        return 0; // no temp
    if (msg[14] == 0xff)
        return 0; // no hum

    int temp_raw = ((msg[12] & 0xf0) >> 4) * 100 + (msg[12] & 0x0f) * 10 + ((msg[13] & 0xf0) >> 4);

        float temperature = temp_raw * 0.1f ;

        if (temperature > 60)
                temperature = temp_raw * 0.1f -100;


    int humidity = (msg[14] & 0x0f) + ((msg[14] & 0xf0) >> 4) * 10;

float wind_direction_deg = ((msg[10] & 0xf0) >> 4) * 100 + (msg[10] & 0x0f) *10 + ((msg[11] &0xf0) >> 4 ) ;
int gust_raw = (0xff-(msg[7]))*10 +(0x0f-((msg[8] &0xf0) >> 4));
float wind_gust = gust_raw * 0.1f;

int wind_raw = (0xff-(msg[9]))*10 +0x0f-(msg[8] & 0x0f);
float wind_avg = wind_raw * 0.1f;
//TO DO
int rain_raw = (0xff-(msg[7]))*100;
float rain = rain_raw * 0.1f;

data = data_make(
        "model",            "",             DATA_STRING, "Bresser-5in1",
        "temperature_C",    "Temperature",  DATA_FORMAT, "%.1f C", DATA_DOUBLE, temperature,
        "humidity",         "Humidity",     DATA_INT, humidity,
        _X("wind_max_m_s","wind_gust"),        "Wind Gust",    DATA_FORMAT, "%.1f m/s",DATA_DOUBLE, wind_gust,
        _X("wind_avg_m_s","wind_speed"),       "Wind Speed",   DATA_FORMAT, "%.1f m/s",DATA_DOUBLE, wind_avg,
        "wind_dir_deg",     "Direction",    DATA_FORMAT, "%.1f °",DATA_DOUBLE, wind_direction_deg,
        "rain_mm",          "Rain",         DATA_FORMAT, "%.1f mm",DATA_DOUBLE, rain,
        "mic",              "Integrity",    DATA_STRING, "CHECKSUM",
        NULL);

    decoder_output_data(decoder, data);
    return 1;
}

static char *output_fields[] = {
        "model",
        "id",
        "temperature_C",
        "humidity",
        "wind_gust",  // TODO: delete this
        "wind_speed", // TODO: delete this
        "wind_max_m_s",
        "wind_avg_m_s",
        "wind_dir_deg",
        "rain_mm",
        "mic",
        NULL,
};

r_device bresser_5in1 = {
        .name        = "Bresser Weather Center 5-in-1",
        .modulation  = FSK_PULSE_PCM,
        .short_width = 122,
        .long_width  = 122,
        .reset_limit = 2400,
        .decode_fn   = &bresser_6in1_callback,
        .disabled    = 0,
        .fields      = output_fields,
};

@rege245
Copy link

rege245 commented Jan 6, 2020

finally i found, how checksum is calculated, but i dont have skills to programm it. it is computed by CheckSum8 2s Complement ,0x100 - Sum Of Bytes
checksum of these bytes "ff ff ff 09 08 99 0a 82 ff" is "CE" which is after "F0"
bresser_6in1_callback: {162} 18 c0 18 c0 0f 10 18 ff ff ff 09 08 99 0a 82 ff f0 ce 00 00 00

i used online calculator from: https://www.scadacore.com/tools/programming-calculators/online-checksum-calculator/

@zuckschwerdt
Copy link
Collaborator

zuckschwerdt commented Jan 6, 2020

Good work. In other words the chk is a sum-8 remainder:

ff+ff+ff+09+08+99+0a+82+ff + ce = 00

@rege245
Copy link

rege245 commented Jan 7, 2020

i got parity check working. i am able to receive message every 24sec, because every second message is not decoded.


time : 2020-01-07 06:35:32
model : Bresser-5in1 Temperature: -8.1 C Humidity : 90 Wind Gust : 0.0 m/s Wind Speed: 0.0 m/s
Direction : 292.0 ° Rain : 0.0 mm Integrity : CHECKSUM
bresser_6in1_callback: {163} d1 60 18 c0 0f 10 18 ff ff ff 29 28 ff fb 69 ff 01 3f 00 00 00
bresser_6in1_callback: {160} aa 8f 18 c0 0f 10 18 ff ff ff 29 28 91 9a 90 ff f0 f8 00 00


time : 2020-01-07 06:35:56
model : Bresser-5in1 Temperature: -8.1 C Humidity : 90 Wind Gust : 0.0 m/s Wind Speed: 0.0 m/s
Direction : 292.0 ° Rain : 0.0 mm Integrity : CHECKSUM
bresser_6in1_callback: {163} d1 60 18 c0 0f 10 18 ff ff ff 29 28 ff fb 69 ff 01 3f 00 00 00
bresser_6in1_callback: {159} aa 8f 18 c0 0f 10 18 ff ff ff 29 28 91 9a 90 ff f0 f0 00 00
bresser_6in1_callback Parity wrong !!!
bresser_6in1_callback: {163} d1 60 18 c0 0f 10 18 ff ff ff 29 28 ff fb 69 ff 01 3f 00 00 00
bresser_6in1_callback: {160} aa 8f 18 c0 0f 10 18 ff ff ff 29 28 91 9a 90 ff f0 f8 00 00


time : 2020-01-07 06:36:44
model : Bresser-5in1 Temperature: -8.1 C Humidity : 90 Wind Gust : 0.0 m/s Wind Speed: 0.0 m/s
Direction : 292.0 ° Rain : 0.0 mm Integrity : CHECKSUM
bresser_6in1_callback: {163} d1 60 18 c0 0f 10 18 ff ff ff 29 28 ff fb 69 ff 01 3f 00 00 00
bresser_6in1_callback: {160} aa 8f 18 c0 0f 10 18 ff ff ff 29 28 91 9a 90 ff f0 f8 00 00


time : 2020-01-07 06:37:08
model : Bresser-5in1 Temperature: -8.1 C Humidity : 90 Wind Gust : 0.0 m/s Wind Speed: 0.0 m/s
Direction : 292.0 ° Rain : 0.0 mm Integrity : CHECKSUM
bresser_6in1_callback: {163} d1 60 18 c0 0f 10 18 ff ff ff 29 28 ff fb 69 ff 01 3f 00 00 00
bresser_6in1_callback: {160} aa 8f 18 c0 0f 10 18 ff ff ff 29 28 91 9a 90 ff f0 f8 00 00


time : 2020-01-07 06:37:32
model : Bresser-5in1 Temperature: -8.1 C Humidity : 90 Wind Gust : 0.0 m/s Wind Speed: 0.0 m/s
Direction : 292.0 ° Rain : 0.0 mm Integrity : CHECKSUM
bresser_6in1_callback: {163} d1 60 18 c0 0f 10 18 ff ff ff 29 28 ff fb 69 ff 01 3f 00 00 00
bresser_6in1_callback: {160} aa 8f 18 c0 0f 10 18 ff ff ff 29 28 91 9a 90 ff f0 f8 00 00


@s118
Copy link

s118 commented Jan 7, 2020

Hi. The coded chains show the temperature, humidity, wind speed and wind direction information. Undecoded strings show rain, wind speed and wind direction information. The information is transported in two different chains that alternate over and over every 12 seconds.
The first string is 100% decoded. In the second chain the rain is not decoded.
For these values:
Temp = 9.8ºC Hum = 75% Wind_Gust = 4m/s Wind_speed = 3.7m/s Dir = 68º Rain = 0mm
The decoded string is (temp, hum, wind and direction information) ins:
{225} 555555555516ea791d0c600d700c7dfc7e034404c13afff8548000000
The bitbench of the string is: SYNC2dd4 CHK? F23a ID? 18c01ae018 WIND SPEED fbf8fc DIR WIND 068 8 TEMP09.8? 2 HUM75 ff ? = F0 a9 00SYNC0000
The non-decoded (rain, wind and direction information) is:
{221} 555555555516ea2fa70c600d700c7dfc7e03447ffeb4ff8099800000
The bitbench of the string is: SYNC2dd4 CHK? 5f4e ID? 18c01ae018 WIND SPEED fbf8fc DIR WIND 068 8 TEMPff.f? D HUM69 ff? = 01 33 00SYNC000
As you can see, I need to decode only the rain of the second chain.

@rege245
Copy link

rege245 commented Jan 7, 2020

i made test :)
rain should be in undecoded chain here: ff ed for 01.2 mm/h
ff-ff 0
ff-ed 12

rain is an summary value since battery was inserted to outdoor unit.

bresser_6in1_callback: {160} 55 a7 18 c0 0f 10 10 ff ff ff 24 88 ff ff ed ff 01 64 00 00

@rege245
Copy link

rege245 commented Jan 7, 2020

Valid checksum for both chains can be computed from bytes 2 to 17 and should be equal to:
CheckSum8 Modulo 256 (Sum of Bytes % 256 ) : FF
or
CheckSum8 2s Complement (0x100 - Sum Of Bytes) : 01

{160} aa 1b 18 c0 0f 10 18 ff bb ff 11 28 96 5a 89 ff f0 96 00 00
{160} ee 73 18 c0 0f 10 18 ff ee ff 11 28 ff fa e9 ff 01 e9 00 00

@jesusangel72
Copy link

Yes, 15 bytes from 2 to 17, you can calculate checksum with included function:

uint16_t crc = crc16(no_CRC_msg, 15, 0x1021, 0x0000);

here no_CRC_msg is the msg array less the 2 first bytes, that are the checksum itself, it is a CRC-16/XMODEM, Poly x1021 and Init 0x0000.

Tomorrow will check with s118 this rain decoding, by now we have saw that data with f0 in byte 16 are temperature, humidity and wind info, and those with 01 have wind info and rain info, but the station sends other data too, that we can ignore if we have rain in this 01 line, maybe athmosferical pressure is sent in these others messages or it is meassured in the receptor.

Regards

@rege245
Copy link

rege245 commented Jan 9, 2020

now i got all parameters , including checksums. hour, day, week and month rain values are computed in home assistant from cumulative rainfall value .
https://community.home-assistant.io/t/how-to-daily-rain-sensor-from-cumulative-sensor-using-mqtt-and-template-sensor/20243

bresser_6in1_callback: {160} ea 2c 18 c0 0f 10 18 ff ff ff 02 28 97 0a 92 ff f0 a7 00 00


time : 2020-01-09 10:20:12
model : Bresser-5in1 Temperature: -3.0 C Humidity : 92 Wind Gust : 0.0 m/s Wind Speed: 0.0 m/s
Direction : 22.0 ° Integrity : CHECKSUM
bresser_6in1_callback: {160} 76 02 18 c0 0f 10 18 fe 7a fe 09 08 ff fe 89 ff 01 e3 00 00


time : 2020-01-09 10:20:24
model : Bresser-5in1 Wind Gust : 1.8 m/s Wind Speed: 1.5 m/s Direction : 90.0 ° Rain : 17.6 mm
Integrity : CHECKSUM
bresser_6in1_callback: {160} 57 3d 18 c0 0f 10 18 ff bb ff 09 08 97 0a 92 ff f0 04 00 00


time : 2020-01-09 10:20:36
model : Bresser-5in1 Temperature: -3.0 C Humidity : 92 Wind Gust : 0.4 m/s Wind Speed: 0.4 m/s
Direction : 90.0 ° Integrity : CHECKSUM
bresser_6in1_callback: {158} 55 dc 18 c0 0f 10 18 ff bb ff 09 08 ff fe 89 ff 01 a0 00 00


time : 2020-01-09 10:20:48
model : Bresser-5in1 Wind Gust : 0.4 m/s Wind Speed: 0.4 m/s Direction : 90.0 ° Rain : 17.6 mm
Integrity : CHECKSUM
bresser_6in1_callback: {160} c6 e3 18 c0 0f 10 18 ff bb ff 11 28 97 0a 92 ff f0 dc 00 00


time : 2020-01-09 10:21:00
model : Bresser-5in1 Temperature: -3.0 C Humidity : 92 Wind Gust : 0.4 m/s Wind Speed: 0.4 m/s
Direction : 112.0 ° Integrity : CHECKSUM
bresser_6in1_callback: {160} 05 d5 18 c0 0f 10 18 ff ff ff 11 28 97 0a 92 ff f0 98 00 00


time : 2020-01-09 10:21:24
model : Bresser-5in1 Temperature: -3.0 C Humidity : 92 Wind Gust : 0.0 m/s Wind Speed: 0.0 m/s
Direction : 112.0 ° Integrity : CHECKSUM
bresser_6in1_callback: {160} c4 02 18 c0 0f 10 18 ff bb ff 11 28 ff fe 89 ff 01 78 00 00


time : 2020-01-09 10:21:36
model : Bresser-5in1 Wind Gust : 0.4 m/s Wind Speed: 0.4 m/s Direction : 112.0 °
Rain : 17.6 mm Integrity : CHECKSUM

@alcarazzam
Copy link

Hi @rege245!
I this your weather station?
Regards

@rege245
Copy link

rege245 commented Jan 12, 2020

yes

@alcarazzam
Copy link

alcarazzam commented Jan 12, 2020

Thanks, @rege245. The code that you posted above works for me, but (like you told) I can't get some messages. Could you post the full code, e.g. in a gist, so I can make it works?.

Thanks a lot!

@rege245
Copy link

rege245 commented Jan 13, 2020

try this with command: rtl_433 -R 119 -f 868.3M
it is still under testing.
rtl_433.zip

@alcarazzam
Copy link

Thanks, but I meant the source code of the bresser_5in1.c file, not the compiled binary. Could you sent it, please?

@rege245
Copy link

rege245 commented Jan 14, 2020

#include "decoder.h"

static int bresser_6in1_callback(r_device *decoder, bitbuffer_t *bitbuffer)
{
    uint8_t const preamble_pattern[] = {0xaa, 0xaa, 0x2d, 0xd4};
    data_t *data;
    uint8_t msg[20];
    uint16_t sensor_id;
    unsigned len = 0;
int humidity =0;
int rainraw = 0;
int temp_raw =0;
float rain =  0;
float temperature = 0;


    if (bitbuffer->num_rows != 1
            || bitbuffer->bits_per_row[0] < 160
            || bitbuffer->bits_per_row[0] > 230) {
        if (decoder->verbose > 1) {
            fprintf(stderr, "%s bit_per_row %u out of range\n", __func__, bitbuffer->bits_per_row[0]);
        }
        return DECODE_ABORT_EARLY; // Unrecognized data
    }

    unsigned start_pos = bitbuffer_search(bitbuffer, 0, 0,
            preamble_pattern, sizeof (preamble_pattern) * 8);

    if (start_pos >= bitbuffer->bits_per_row[0]) {
        return DECODE_ABORT_LENGTH;
    }
    start_pos += sizeof (preamble_pattern) * 8;
    len = bitbuffer->bits_per_row[0] - start_pos;

    if (len < 144) {
        if (decoder->verbose > 1) {
            fprintf(stderr, "%s: %u too short\n", __func__, len);
        }
        return DECODE_ABORT_LENGTH; // message too short
    }
    // truncate any excessive bits
    len = MIN(len, sizeof (msg) * 8);

    bitbuffer_extract_bytes(bitbuffer, 0, start_pos, msg, len);

    bitrow_printf(msg, len, "%s: ", __func__);

//rain

if (msg[12] == 0xff)
        {
        rain = ((((0xff-msg[13])&0x0f)*100)+((((0xff-msg[14])& 0xf0) >> 4) * 10 + ((0xff-msg[14]) & 0x0f) * 1 )) * 0.1f;
        }

//checksum

int chksum = ((0x100-msg[2])+(0x100-msg[3])+(0x100-msg[4])+(0x100-msg[5])+(0x100-msg[6])+(0x100-msg[7])+(0x100-msg[8])+(0x100-msg[9])+(0x100-msg[10])+(0x100-msg[11])+(0x100-msg[12])+(0x100-msg[13])+(0x100-msg[14])+(0x100-msg[15])+(0x100-msg[16])+(0x100-msg[17]))&0xff;

if(chksum!=0x01)      {
                        fprintf(stderr, "%s Parity wrong !!! \n", __func__);
                        return 0;
                   }

//temerature

temp_raw = ((msg[12] & 0xf0) >> 4) * 100 + (msg[12] & 0x0f) * 10 + ((msg[13] & 0xf0) >> 4);
temperature = temp_raw * 0.1f ;

if (temperature > 60)
        temperature = temp_raw * 0.1f -100;


humidity = (msg[14] & 0x0f) + ((msg[14] & 0xf0) >> 4) * 10;

float wind_direction_deg = ((msg[10] & 0xf0) >> 4) * 100 + (msg[10] & 0x0f) *10 + ((msg[11] &0xf0) >> 4 ) ;
int gust_raw = (0xff-(msg[7]))*10 +(0x0f-((msg[8] &0xf0) >> 4));
float wind_gust = gust_raw * 0.1f * 3.6;

int wind_raw = (0xff-(msg[9]))*10 +0x0f-(msg[8] & 0x0f);
float wind_avg = wind_raw * 0.1f * 3.6;


if (msg[12] == 0xff){

data = data_make(
        "model",            "",             DATA_STRING, "Bresser-5in1",
        _X("wind_max_m_s","wind_gust"),        "Wind Gust",    DATA_FORMAT, "%.1f km/h",DATA_DOUBLE, wind_gust,
        _X("wind_avg_m_s","wind_speed"),       "Wind Speed",   DATA_FORMAT, "%.1f km/h",DATA_DOUBLE, wind_avg,
        "wind_dir_deg",     "Direction",    DATA_FORMAT, "%.1f °",DATA_DOUBLE, wind_direction_deg,
        "rain_mm",          "Rain",         DATA_FORMAT, "%.1f mm",DATA_DOUBLE, rain,
        "mic",              "Integrity",    DATA_STRING, "CHECKSUM",
        NULL);

    decoder_output_data(decoder, data);
    return 1;
}

else {
data = data_make(
        "model",            "",             DATA_STRING, "Bresser-5in1",
        "temperature_C",    "Temperature",  DATA_FORMAT, "%.1f C", DATA_DOUBLE, temperature,
        "humidity",         "Humidity",     DATA_INT, humidity,
        _X("wind_max_m_s","wind_gust"),        "Wind Gust",    DATA_FORMAT, "%.1f km/h",DATA_DOUBLE, wind_gust,
        _X("wind_avg_m_s","wind_speed"),       "Wind Speed",   DATA_FORMAT, "%.1f km/h",DATA_DOUBLE, wind_avg,
        "wind_dir_deg",     "Direction",    DATA_FORMAT, "%.1f °",DATA_DOUBLE, wind_direction_deg,
        "mic",              "Integrity",    DATA_STRING, "CHECKSUM",
        NULL);

    decoder_output_data(decoder, data);
    return 1;
}
}

static char *output_fields[] = {
        "model",
        "id",
        "temperature_C",
        "humidity",
        "wind_gust",  // TODO: delete this
        "wind_speed", // TODO: delete this
        "wind_max_m_s",
        "wind_avg_m_s",
        "wind_dir_deg",
        "rain_mm",
        "mic",
        NULL,
};

r_device bresser_5in1 = {
        .name        = "Bresser Weather Center 5-in-1",
        .modulation  = FSK_PULSE_PCM,
        .short_width = 122,
        .long_width  = 122,
        .reset_limit = 2400,
        .decode_fn   = &bresser_6in1_callback,
        .disabled    = 0,
        .fields      = output_fields,
};

@s118
Copy link

s118 commented Jan 14, 2020

This is my weather station:
https://www.bresser.de/Wetter-Zeit/Wetterstationen/National-Geographic-Color-Display-Funk-Wetter-Center-5in1.html?listtype=search&searchparam=national%20geographic%20weather%20station
This is the adaptation of the code to my weather station. Thanks to jesusangel72:

#include "decoder.h"
static const uint8_t preamble_pattern[] = { 0xaa, 0xaa, 0xaa, 0x2d, 0xd4 };
static int bresser_5in1_callback(r_device *decoder, bitbuffer_t *bitbuffer)
{
    data_t *data;
    uint8_t msg[26];
    uint16_t sensor_id;
    unsigned len = 0;
    if (bitbuffer->num_rows != 1
            || bitbuffer->bits_per_row[0] < 248
            || bitbuffer->bits_per_row[0] > 440) {
        if (decoder->verbose > 1) {
            fprintf(stderr, "%s bit_per_row %u out of range\n", __func__, bitbuffer->bits_per_row[0]);
        }
        return 0; // Unrecognized data
    }
    unsigned start_pos = bitbuffer_search(bitbuffer, 0, 0,
            preamble_pattern, sizeof (preamble_pattern) * 8);
    if (start_pos == bitbuffer->bits_per_row[0]) {
        return 0;
    }
    start_pos += sizeof (preamble_pattern) * 8;
    len = bitbuffer->bits_per_row[0] - start_pos;
    if (((len + 7) / 8) < sizeof (msg)) {
        if (decoder->verbose > 1) {
            fprintf(stderr, "%s %u too short\n", __func__, len);
        }
        return 0; // message too short
    }
    // truncate any excessive bits
    len = MIN(len, sizeof (msg) * 8);
    bitbuffer_extract_bytes(bitbuffer, 0, start_pos, msg, len);
    }
    sensor_id = msg[5];
	if (msg[16] == 0xf0){
    int temp_raw = (msg[12] & 0x0f) *10 + ((msg[12] & 0xf0) >> 4) * 100 + ((msg[13] &0xf0) >> 4 ) ;
    if (msg[15] != 0xff)
        temp_raw = -temp_raw;
    float temperature = temp_raw * 0.1f;
    int humidity = (msg[14] & 0x0f) + ((msg[14] & 0xf0) >> 4) * 10;
	if (msg[12] == 0xff)
        return 0; // no temp
    if (msg[14] == 0xff)
        return 0; // no hum
	float wind_direction_deg = ((msg[10] & 0xf0) >> 4) * 100 + (msg[10] & 0x0f) *10 + ((msg[11] &0xf0) >> 4 ) ;
    int gust_raw = (0xff-(msg[7]))*10 +(0x0f-((msg[8] &0xf0) >> 4));
    float wind_gust = gust_raw * 0.1f;
    int wind_raw = (0xff-(msg[9]))*10 +0x0f-(msg[8] & 0x0f);
    float wind_avg = wind_raw * 0.1f;
    data = data_make(
            "model",            "",             DATA_STRING, "Bresser",
            "id",               "",             DATA_INT,    sensor_id,
            "temperature_C",    "Temperature",  DATA_FORMAT, "%.1f C", DATA_DOUBLE, temperature,
            "humidity",         "Humidity",     DATA_INT, humidity,
            _X("wind_max_m_s","wind_gust"),        "Wind Gust",    DATA_FORMAT, "%.1f m/s",DATA_DOUBLE, wind_gust,
            _X("wind_avg_m_s","wind_speed"),       "Wind Speed",   DATA_FORMAT, "%.1f m/s",DATA_DOUBLE, wind_avg,
            "wind_dir_deg",     "Direction",    DATA_FORMAT, "%.1f °",DATA_DOUBLE, wind_direction_deg,
            "mic",              "Integrity",    DATA_STRING, "CHECKSUM",
            NULL);
    decoder_output_data(decoder, data);
	}else if (msg[16] == 0x01 || (msg[16] == 0x02 && msg[13] == 0xff && msg[14] == 0xff  ) ){
		float wind_direction_deg = ((msg[10] & 0xf0) >> 4) * 100 + (msg[10] & 0x0f) *10 + ((msg[11] &0xf0) >> 4 ) ;
		int gust_raw = (0xff-(msg[7]))*10 +(0x0f-((msg[8] &0xf0) >> 4));
		float wind_gust = gust_raw * 0.1f;
		int wind_raw = ((0xff-(msg[9]))*10) +0x0f-(msg[8] & 0x0f);
		float wind_avg = wind_raw * 0.1f;
      int rain_raw = (0x0f-((msg[13] & 0xf0) >> 4)) * 1000 + (0x0f-(msg[13] & 0x0f))*100 + (0x0f-((msg[14] & 0xf0) >> 4)) * 10 + (0x0f-(msg[14] & 0x0f)) ;
		float rain = rain_raw *0.1f;
		data = data_make(
            "model",            "",             DATA_STRING, "Bresser",
            "id",               "",             DATA_INT,    sensor_id,
            _X("wind_max_m_s","wind_gust"),        "Wind Gust",    DATA_FORMAT, "%.1f m/s",DATA_DOUBLE, wind_gust,
            _X("wind_avg_m_s","wind_speed"),       "Wind Speed",   DATA_FORMAT, "%.1f m/s",DATA_DOUBLE, wind_avg,
            "wind_dir_deg",     "Direction",    DATA_FORMAT, "%.1f °",DATA_DOUBLE, wind_direction_deg,
            "rain_mm",          "Rain",         DATA_FORMAT, "%.1f mm",DATA_DOUBLE, rain,
            "mic",              "Integrity",    DATA_STRING, "CHECKSUM",
            NULL);
    decoder_output_data(decoder, data);
	}
    return 1;
}
static char *output_fields[] = {
    "model",
    "id",
    "temperature_C",
    "humidity",
    "wind_gust", // TODO: delete this
    "wind_speed", // TODO: delete this
    "wind_max_m_s",
    "wind_avg_m_s",
    "wind_dir_deg",
    "rain_mm",
    "mic",
    NULL
};
r_device bresser_5in1 = {
    .name          = "Bresser Weather Center 5-in-1",
    .modulation    = FSK_PULSE_PCM,
    .short_width   = 124,
    .long_width    = 124,
    .reset_limit   = 2500,
    .decode_fn     = &bresser_5in1_callback,
    .disabled      = 0,
    .fields        = output_fields,
};

@alcarazzam
Copy link

Hi @rege245,
Thanks for the code. I've tested it and works fine for me, I'm able to get the data from the weather station as expected. The only value that is not reported is the pressure.

@level20peon
Copy link

I also own this weather station (the display is a colored one though). Can I do anything to help implementing it?

stquinn added a commit to stquinn/rtl_433 that referenced this issue Feb 2, 2020
@devZer0
Copy link
Contributor

devZer0 commented Feb 12, 2020

i am using modified bresser_5in1.c
all is ok, but checksum is not calculated, so sometime i get wrong data.

@f4gqk , if you still get wrong data , can you retry with latest git?

there have been pcm decode improvements about 2 weeks ago, my decode/checksum problems went away with a sensor which is using similar protocol to bresser 5in1 (i pulled my hair out before because i did not get consistent results, i.e. there where bits wrong/shifting)

@Mindavi Mindavi added the device support Request for a new/improved device decoder label Aug 10, 2020
@mvdgrift
Copy link

The code posted by @rege245 works perfectly. It is capable of decoding all data from my Bresser 5 in 1 (new model).

Thanks @rege245 for sharing the code!

Are you going to add it to the rtl_433 project here on Github as well?

@zuckschwerdt
Copy link
Collaborator

@mvdgrift
Copy link

No, unfortunately this decoder does not work with the new Bresser 5-in-1 models. The new Bresser 5-in-1 models use the data format comparable to the Bresser 6-in-1 models (see the source code posted by @rege245 ).

@zuckschwerdt
Copy link
Collaborator

Thanks. So we have

  • 5-in-1
  • new 5-in-1
  • 6-in-1
  • 7-in-1 (indoor)
  • 7-in-1 (outdoor)

I guess I'll merge all that work in progress in a single branch to test and refine.

@zuckschwerdt
Copy link
Collaborator

@jesusangel72 CRC is used in the wired communication, for the radio transmission it's an LFSR-16 digest.

#1225 should support this now. There are some details open, let's further discuss in #1214.

@zuckschwerdt
Copy link
Collaborator

@f4gqk @rege245 @s118 @jesusangel72 @m-alzam @level20peon @mvdgrift can you test the code in #1225 and report your exact device name/product number with the ID+Status from the output in #1214?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
device support Request for a new/improved device decoder
Projects
None yet
Development

No branches or pull requests

10 participants