merbanan / rtl_433

Program to decode radio transmissions from devices on the ISM bands (and other frequencies)
GNU General Public License v2.0
6.12k stars 1.32k forks source link

Add support for Bresser 6in1 #1172

Closed f4gqk closed 4 years ago

f4gqk commented 5 years ago

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 commented 5 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

rege245 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

ff+ff+ff+09+08+99+0a+82+ff + ce = 00
rege245 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

Hi @rege245! I this your weather station? Regards

rege245 commented 4 years ago

yes

alcarazzam commented 4 years ago

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 commented 4 years ago

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

alcarazzam commented 4 years ago

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

rege245 commented 4 years ago
#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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

devZer0 commented 4 years ago

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)

mvdgrift commented 4 years ago

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 commented 4 years ago

Isn't the 5-in-1 code what we have in https://github.com/merbanan/rtl_433/blob/master/src/devices/bresser_5in1.c ?

mvdgrift commented 4 years ago

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 commented 4 years ago

Thanks. So we have

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

zuckschwerdt commented 4 years ago

@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 commented 4 years ago

@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?