Add support for Maverick XR-30 ()

This commit is contained in:
jbfunk 2022-08-06 06:57:01 -07:00 committed by Christian W. Zuckschwerdt
parent fc2256c391
commit fbb5fb32c8
6 changed files with 122 additions and 4 deletions

View file

@ -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).

View file

@ -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")

View file

@ -227,6 +227,7 @@
DECL(emos_e6016_rain) \
DECL(hcs200_fsk) \
DECL(fineoffset_wh45) \
DECL(maverick_xr30) \
/* Add new decoders here. */

View file

@ -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).

View file

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

114
src/devices/maverick_xr30.c Normal file
View file

@ -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,
};