diff --git a/README.md b/README.md index 95888078..cdcace55 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md). [-F kv | json | csv | mqtt | influx | syslog | trigger | null | help] Produce decoded output in given format. Append output to file with :<filename> (e.g. -F csv:log.csv), defaults to stdout. Specify host/port for syslog with e.g. -F syslog:127.0.0.1:1514 - [-M time[:<options>] | protocol | level | noise[:secs] | stats | bits | help] Add various meta data to each output. + [-M time[:<options>] | protocol | level | noise[:<secs>] | stats | bits | help] Add various meta data to each output. [-K FILE | PATH | <tag> | <key>=<tag>] Add an expanded token or fixed tag to every output line. [-C native | si | customary] Convert units in decoded output. [-n <value>] Specify number of samples to take (each sample is an I/Q pair) @@ -302,6 +302,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md). [217] EMOS E6016 rain gauge [218] Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK) [219] Fine Offset Electronics WH45 air quality sensor + [220] Maverick XR-30 BBQ Sensor * Disabled by default, use -R n or a conf file to enable @@ -421,7 +422,7 @@ E.g. -X "n=doorbell,m=OOK_PWM,s=400,l=800,r=7000,g=1000,match={24}0xa9878c,repea Use "replay[:N]" to replay file inputs at (N-times) realtime. Use "protocol" / "noprotocol" to output the decoder protocol number meta data. Use "level" to add Modulation, Frequency, RSSI, SNR, and Noise meta data. - Use "noise[:secs]" to report estimated noise level at intervals (default: 10 seconds). + Use "noise[:<secs>]" to report estimated noise level at intervals (default: 10 seconds). Use "stats[:[<level>][:<interval>]]" to report statistics (default: 600 seconds). level 0: no report, 1: report successful devices, 2: report active devices, 3: report all Use "bits" to add bit representation to code outputs (for debug). diff --git a/conf/rtl_433.example.conf b/conf/rtl_433.example.conf index aa7e2926..98b624a9 100644 --- a/conf/rtl_433.example.conf +++ b/conf/rtl_433.example.conf @@ -441,6 +441,7 @@ stop_after_successful_events false protocol 217 # EMOS E6016 rain gauge protocol 218 # Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK) protocol 219 # Fine Offset Electronics WH45 air quality sensor + protocol 220 # Maverick XR-30 BBQ Sensor ## Flex devices (command line option "-X") diff --git a/include/rtl_433_devices.h b/include/rtl_433_devices.h index 94d95a4e..99f6ba9c 100644 --- a/include/rtl_433_devices.h +++ b/include/rtl_433_devices.h @@ -227,6 +227,7 @@ DECL(emos_e6016_rain) \ DECL(hcs200_fsk) \ DECL(fineoffset_wh45) \ + DECL(maverick_xr30) \ /* Add new decoders here. */ diff --git a/man/man1/rtl_433.1 b/man/man1/rtl_433.1 index 708c94c8..a0c0552d 100644 --- a/man/man1/rtl_433.1 +++ b/man/man1/rtl_433.1 @@ -129,7 +129,7 @@ Produce decoded output in given format. Append output to file with :<filename> (e.g. \-F csv:log.csv), defaults to stdout. Specify host/port for syslog with e.g. \-F syslog:127.0.0.1:1514 .TP -[ \fB\-M\fI time[:<options>] | protocol | level | noise[:secs] | stats | bits | help\fP ] +[ \fB\-M\fI time[:<options>] | protocol | level | noise[:<secs>] | stats | bits | help\fP ] Add various meta data to each output. .TP [ \fB\-K\fI FILE | PATH | <tag> | <key>=<tag>\fP ] @@ -412,7 +412,7 @@ Use "protocol" / "noprotocol" to output the decoder protocol number meta data. Use "level" to add Modulation, Frequency, RSSI, SNR, and Noise meta data. .RE .RS -Use "noise[:secs]" to report estimated noise level at intervals (default: 10 seconds). +Use "noise[:<secs>]" to report estimated noise level at intervals (default: 10 seconds). .RE .RS Use "stats[:[<level>][:<interval>]]" to report statistics (default: 600 seconds). diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 831a58cc..fda252b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -152,6 +152,7 @@ add_library(r_433 STATIC devices/marlec_solar.c devices/maverick_et73.c devices/maverick_et73x.c + devices/maverick_xr30.c devices/mebus.c devices/megacode.c devices/missil_ml0757.c diff --git a/src/devices/maverick_xr30.c b/src/devices/maverick_xr30.c new file mode 100644 index 00000000..929ff0d6 --- /dev/null +++ b/src/devices/maverick_xr30.c @@ -0,0 +1,114 @@ +/** @file + Maverick XR-30 BBQ Sensor. + + Copyright (C) 2022 jbfunk + Heavily derived from Maverick ET-73x BBQ Sensor (maverick_et73x.c), Copyright (C) 2016 gismo2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +/** +Maverick XR-30 BBQ Sensor. + +The thermometer transmits 4 identical messages every 12 seconds at 433.92 MHz, + +Each message consists of 26 nibbles (104 bits total) but the first (non-data) bit (1) is getting dropped sometimes in reception, so for analysis the payload is shifted 7 bits left to align the bytes (or 8 bits if 0xaa is observed rather than 0x55 as the first byte received) + +Payload: + +- P = 32 bit preamble (0xaaaaaaaa; 7 or 8 bits shifted left for analysis) +- S = 32 bit sync-word (0xd391d391) +- F = 4 bit device state (0=default; 5=init) +- T = 10 bit temp1 (degree C, offset by 532) +- t = 10 bit temp2 (degree C, offset by 532) +- D = 16 bit digest (over FTt, includes non-transmitted device id renewed on a device reset) gen 0x8810 init 0x0d42 + + byte (after shift): 0 1 2 3 4 5 6 7 8 9 10 11 + nibble (after shift): 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 + msg: P P P P P P P P S S S S S S S S F T T Tt t t D D D D + PRE:32h SYNC: 32h FLAG:4h T:10d t:10d | DIGEST:16h + +*/ + +#include "decoder.h" + +static int maverick_xr30_callback(r_device *decoder, bitbuffer_t *bitbuffer) +{ + data_t *data; + + if (bitbuffer->num_rows != 1) + return DECODE_ABORT_EARLY; + + //check correct data length + if (bitbuffer->bits_per_row[0] != 104) // 104 bits + return DECODE_ABORT_LENGTH; + + uint8_t b[12]; + //check for correct preamble/sync (0xaaaaaad391d391) + if (bitbuffer->bb[0][0] == 0x55) { + bitbuffer_extract_bytes(bitbuffer, 0, 7, b, 12 * 8); // shift in case first bit was not received properly + } else if (bitbuffer->bb[0][0] == 0xaa) { + bitbuffer_extract_bytes(bitbuffer, 0, 8, b, 12 * 8); // shift in case first bit was received properly + } else { + return DECODE_ABORT_EARLY; // preamble/sync missing + } + if (b[0] != 0xaa || b[1] != 0xaa || b[2] != 0xaa || b[3] != 0xd3 || b[4] != 0x91 || b[5] != 0xd3 || b[6] != 0x91) + return DECODE_ABORT_EARLY; // preamble/sync missing + + int sync = b[3] << 24 | b[4] << 16 | b[5] << 8 | b[6]; + int flags = (b[7] & 0xf0) >> 4; + int temp1 = (b[7] & 0x0f) << 6 | (b[8] & 0xfc) >> 2; + int temp2 = (b[8] & 0x03) << 8 | b[9]; + int digest = b[10] << 8 | b[11]; + + float temp1_c = temp1 - 532.0f; + float temp2_c = temp2 - 532.0f; + + char *status = "unknown"; + if (flags == 0) + status = "default"; + else if (flags == 5) + status = "init"; + + //digest is used to represent a session. This means, we get a new id if a reset or battery exchange is done. + int id = lfsr_digest16(&b[7], 3, 0x8810, 0x0d42) ^ digest; + + decoder_logf(decoder, 1, __func__, "sync %08x, flags %0x, t1 %d, t2 %d, digest %04x, chk_data %02x%02x%02x, digest xor'ed: %04x", + sync, flags, temp1, temp2, digest, b[7], b[8], b[9], id); + + /* clang-format off */ + data = data_make( + "model", "", DATA_STRING, "Maverick-XR30", + "id", "Session_ID", DATA_INT, id, + "status", "Status", DATA_STRING, status, + "temperature_1_C", "TemperatureSensor1", DATA_FORMAT, "%.02f C", DATA_DOUBLE, temp1_c, + "temperature_2_C", "TemperatureSensor2", DATA_FORMAT, "%.02f C", DATA_DOUBLE, temp2_c, + NULL); + /* clang-format on */ + + decoder_output_data(decoder, data); + return 1; +} + +static char *output_fields[] = { + "model", + "id", + "status", + "temperature_1_C", + "temperature_2_C", + "mic", + NULL, +}; + +r_device maverick_xr30 = { + .name = "Maverick XR-30 BBQ Sensor", + .modulation = FSK_PULSE_PCM, + .short_width = 360, + .long_width = 360, + .reset_limit = 4096, + .decode_fn = &maverick_xr30_callback, + .fields = output_fields, +};