Skip to content

Commit

Permalink
Update to rtl_433 release 22.11 (#75)
Browse files Browse the repository at this point in the history
* WIP

* Updated contrib decoders

* Update oregon scientific

* WIP

* FSK Primitives included

* WIP

* Update signalDecoder.cpp

* tuning

* WIP

* WIP

* Update

* Update tools

* Update platformio.ini

* LINT

* Reporting

* memory tuning

* Further tuning

* Update update_rtl_433_devices.sh

* Reporting

* almost final

* Lint

* Update README.md
  • Loading branch information
NorthernMan54 authored Apr 3, 2023
1 parent e582ebb commit 65bad3c
Show file tree
Hide file tree
Showing 277 changed files with 32,634 additions and 7,374 deletions.
372 changes: 198 additions & 174 deletions README.md

Large diffs are not rendered by default.

2,068 changes: 2,068 additions & 0 deletions contrib/acurite.c

Large diffs are not rendered by default.

407 changes: 407 additions & 0 deletions contrib/govee.c

Large diffs are not rendered by default.

239 changes: 239 additions & 0 deletions contrib/interlogix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/** @file
Interlogix/GE/UTC Wireless Device Decoder.
Copyright (C) 2017 Brent Bailey <[email protected]>
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.
*/
/**
Interlogix/GE/UTC Wireless Device Decoder.
Also tested with ELK-319DWM module as well as a Alula RE101 319.5MHz sensor (both short preamble).
- Frequency: 319.5 MHz
Decoding done per us patent #5761206
https://www.google.com/patents/US5761206
## Protocol Bits
- 00-02 976 uS RF front porch pulse
- 03-14 12 sync pulses, logical zeros
- 15 start pulse, logical one
- 16-35 20 bit sensor identification code (ID bits 0-19)
- 36-39 4 bit device type code (DT bits 0-3)
- 40-42 3 bit trigger count (TC bit 0-2)
- 43 low battery bit
- 44 F1 latch bit NOTE that F1 latch bit and debounce are reversed. Typo or endianness issue?
- 45 F1 debounced level
- 46 F2 latch bit
- 47 F2 debounced level
- 48 F3 latch bit (cover latch for contact sensors)
- 49 F3 debounced level
- 50 F4 latch bit
- 51 F4 debounced level
- 52 F5 positive latch bit
- 53 F5 debounced level
- 54 F5 negative latch bit
- 55 even parity over odd bits 15-55
- 56 odd parity over even bits 16-56
- 57 zero/one, programmable
- 58 RF on for 366 uS (old stop bit)
- 59 one
- 60-62 modulus 8 count of number of ones in bits 15-54
- 63 zero (new stop bit)
## Protocol Description
- Bits 00 to 02 are a 976 ms RF front porch pulse, providing a wake up period that allows the
system controller receiver to synchronize with the incoming packet.
- Bits 3 to 14 include 12 sync pulses, e.g., logical 0's, to synchronize the receiver.
- Bit 15 is a start pulse, e.g., a logical 1, that tells the receiver that data is to follow.
- Bits 16-58 provide information regarding the transmitter and associated sensor. In other
embodiments, bits 16-58 may be replaced by an analog signal.
- Bits 16 to 35 provide a 20-bit sensor identification code that uniquely identifies the particular
sensor sending the message. Bits 36 to 39 provide a 4 bit device-type code that identifies the
specific-type of sensor, e.g., smoke, PIR, door, window, etc. The combination of the sensor
bits and device bits provide a set of data bits.
- Bits 40 through 42 provide a 3-bit trigger count that is incremented for each group of message
packets. The trigger count is a simple but effective way for preventing a third party from
recording a message packet transmission and then re-transmitting that message packet
transmission to make the system controller think that a valid message packet is being transmitted.
- Bit 43 provides the low battery bit.
- Bits 44 through 53 provide the latch bit value and the debounced value for each of the five inputs
associated with the transmitter. For the F5 input, both a positive and negative latch bit are provided.
- Bit 55 provides even parity over odd bits 15 to 55.
- Bit 56 provides odd parity over even bits 16 to 56.
- Bit 57 is a programmable bit that can be used for a variety of applications, including providing an
additional bit that could be used for the sensor identification code or device type code.
- Bit 58 is a 366 ms RF on signal that functions as the "old" stop bit. This bit provides compatibility with
prior system controllers that may be programmed to receive a 58-bit message.
- Bit 59 is a logical 1.
- Bits 60 to 62 are a modulus eight count of the number of 1 bits in bits 15 through 54, providing enhanced
error detection information to be used by the system controller. Finally, bit 63 is the "new" stop bit,
e.g., a logical 0, that tells the system controller that it is the end of the message packet.
## Addendum
GE/Interlogix keyfobs do not follow the documented iti protocol and it
appears the protocol was misread by the team that created the keyfobs.
The button states are sent in the three trigger count bits (bit 40-42)
and no battery status appears to be provided. 4 buttons and a single
multi-button press (buttons 1 - lock and buttons 2 - unlock) for a total
of 5 buttons available on the keyfob.
For contact sensors, latch 3 (typically the tamper/case open latch) will
float (giving misreads) if the external contacts are used (ie; closed)
and there is no 4.7 Kohm end of line resistor in place on the external
circuit
*/

#include "decoder.h"

#define INTERLOGIX_MSG_BIT_LEN 46

static int interlogix_decode(r_device *decoder, bitbuffer_t *bitbuffer)
{
// preamble message
// only searching for 0000 0001 (bottom 8 bits of the 13 bits preamble)
uint8_t const preamble_pattern[1] = {0x01}; // 8 bits

data_t *data;
unsigned int row = 0;
char device_type_id[2];
char const *device_type;
char device_serial[7];
char raw_message[7];
int low_battery;
char const *f1_latch_state;
char const *f2_latch_state;
char const *f3_latch_state;
char const *f4_latch_state;
char const *f5_latch_state;

if (bitbuffer->num_rows != 1) {
return DECODE_ABORT_EARLY;
}

// Check if the message length is between the length seen in test files (57)
// and the 64 bits discussed above.
if (bitbuffer->bits_per_row[0] < 57
|| bitbuffer->bits_per_row[0] > 64) {
return DECODE_ABORT_LENGTH;
}

// search for preamble and exit if not found
unsigned int bit_offset = bitbuffer_search(bitbuffer, row, 0, preamble_pattern, (sizeof preamble_pattern) * 8);
if (bit_offset == bitbuffer->bits_per_row[row]) {
decoder_logf(decoder, 2, __func__, "Preamble not found, bit_offset: %u", bit_offset);
return DECODE_FAIL_SANITY;
}

// set message starting position (just past preamble and sync bit)
bit_offset += (sizeof preamble_pattern) * 8;

uint8_t message[(INTERLOGIX_MSG_BIT_LEN + 7) / 8];

bitbuffer_extract_bytes(bitbuffer, row, bit_offset, message, INTERLOGIX_MSG_BIT_LEN);

// reduce false positives, abort if id or code looks wrong
if (message[0] == 0x00 && message[1] == 0x00 && message[2] == 0x00)
return DECODE_FAIL_SANITY;
if (message[0] == 0xff && message[1] == 0xff && message[2] == 0xff)
return DECODE_FAIL_SANITY;
if (message[3] == 0x00 && message[4] == 0x00 && message[5] == 0x00)
return DECODE_FAIL_SANITY;
if (message[3] == 0xff && message[4] == 0xff && message[5] == 0xff)
return DECODE_FAIL_SANITY;

// parity check: even data bits from message[0 .. 40] and odd data bits from message[1 .. 41]
// i.e. 5 bytes and two (top-most) bits.
int parity = message[0] ^ message[1] ^ message[2] ^ message[3] ^ message[4]; // parity as byte
parity = (parity >> 4) ^ (parity & 0xF); // fold to nibble
parity = (parity >> 2) ^ (parity & 0x3); // fold to 2 bits
parity ^= message[5] >> 6; // add check bits
int parity_error = parity ^ 0x3; // both parities are odd, i.e. 1 on success

if (parity_error) {
decoder_logf(decoder, 1, __func__, "Parity check failed (%d %d)", parity >> 1, parity & 1);
return DECODE_FAIL_MIC;
}

sprintf(device_type_id, "%01x", (reverse8(message[2]) >> 4));

switch ((reverse8(message[2]) >> 4)) {
case 0xa: device_type = "contact"; break;
case 0xf: device_type = "keyfob"; break;
case 0x4: device_type = "motion"; break;
case 0x6: device_type = "heat"; break;
case 0x9: device_type = "glass"; break; // switch1 changes from open to closed on trigger

default: device_type = "unknown"; return DECODE_FAIL_SANITY; break;
}

sprintf(device_serial, "%02x%02x%02x", reverse8(message[2]), reverse8(message[1]), reverse8(message[0]));

sprintf(raw_message, "%02x%02x%02x", message[3], message[4], message[5]);

// keyfob logic. see protocol description addendum for protocol exceptions
if ((reverse8(message[2]) >> 4) == 0xf) {
low_battery = 0;
f1_latch_state = ((message[3] & 0xe) == 0x4) ? "CLOSED" : "OPEN";
f2_latch_state = ((message[3] & 0xe) == 0x8) ? "CLOSED" : "OPEN";
f3_latch_state = ((message[3] & 0xe) == 0xc) ? "CLOSED" : "OPEN";
f4_latch_state = ((message[3] & 0xe) == 0x2) ? "CLOSED" : "OPEN";
f5_latch_state = ((message[3] & 0xe) == 0xa) ? "CLOSED" : "OPEN";
} else {
low_battery = (message[3] & 0x10) ? 1 : 0;
f1_latch_state = (message[3] & 0x04) ? "OPEN" : "CLOSED";
f2_latch_state = (message[3] & 0x01) ? "OPEN" : "CLOSED";
f3_latch_state = (message[4] & 0x40) ? "OPEN" : "CLOSED";
f4_latch_state = (message[4] & 0x10) ? "OPEN" : "CLOSED";
f5_latch_state = (message[4] & 0x04) ? "OPEN" : "CLOSED";
}

/* clang-format off */
data = data_make(
"model", "Model", DATA_STRING, "Interlogix-Security",
"subtype", "Device Type", DATA_STRING, device_type,
"id", "ID", DATA_STRING, device_serial,
"battery_ok", "Battery", DATA_INT, !low_battery,
"switch1", "Switch1 State", DATA_STRING, f1_latch_state,
"switch2", "Switch2 State", DATA_STRING, f2_latch_state,
"switch3", "Switch3 State", DATA_STRING, f3_latch_state,
"switch4", "Switch4 State", DATA_STRING, f4_latch_state,
"switch5", "Switch5 State", DATA_STRING, f5_latch_state,
"raw_message", "Raw Message", DATA_STRING, raw_message,
NULL);
/* clang-format on */

decoder_output_data(decoder, data);
return 1;
}

static char const *const output_fields[] = {
"model",
"subtype",
"id",
"raw_message",
"battery_ok",
"switch1",
"switch2",
"switch3",
"switch4",
"switch5",
NULL,
};

r_device const interlogix = {
.name = "Interlogix GE UTC Security Devices",
.modulation = OOK_PULSE_PPM,
.short_width = 122,
.long_width = 244,
.reset_limit = 500, // Maximum gap size before End Of Message
.decode_fn = &interlogix_decode,
.fields = output_fields,
};
2 changes: 1 addition & 1 deletion contrib/lacrosse_tx141x.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ static int lacrosse_tx141x_decode(r_device *decoder, bitbuffer_t *bitbuffer)
return 1;
}

static char *output_fields[] = {
static char const *output_fields[] = {
"model",
"id",
"channel",
Expand Down
Loading

0 comments on commit 65bad3c

Please sign in to comment.