rtl433  UNKNOWN
RTL-433 utility
acurite.c File Reference

Acurite weather stations and temperature / humidity sensors. More...

Functions

static char acurite_getChannel (uint8_t byte)
 
static int acurite_rain_896_decode (r_device *decoder, bitbuffer_t *bitbuffer)
 
static int acurite_th_decode (r_device *decoder, bitbuffer_t *bitbuffer)
 Acurite 609 Temperature and Humidity Sensor. More...
 
static int acurite_6045_decode (r_device *decoder, bitrow_t bb, int browlen)
 Acurite 06045m Lightning Sensor decoding. More...
 
static int acurite_txr_decode (r_device *decoder, bitbuffer_t *bitbuffer)
 This callback handles several Acurite devices that use a very similar RF encoding and data format: More...
 
static int acurite_986_decode (r_device *decoder, bitbuffer_t *bitbuffer)
 Acurite 00986 Refrigerator / Freezer Thermometer. More...
 
static int acurite_606_decode (r_device *decoder, bitbuffer_t *bitbuffer)
 
static int acurite_00275rm_decode (r_device *decoder, bitbuffer_t *bitbuffer)
 

Variables

int const acurite_5n1_winddirections []
 
static char chLetter [4] = {'C','E','B','A'}
 
static char * acurite_rain_gauge_output_fields []
 
r_device acurite_rain_896
 
static char * acurite_th_output_fields []
 
r_device acurite_th
 
static char * acurite_txr_output_fields []
 
r_device acurite_txr
 
static char * acurite_986_output_fields []
 
r_device acurite_986
 
static char * acurite_606_output_fields []
 
r_device acurite_606
 
static char * acurite_00275rm_output_fields []
 
r_device acurite_00275rm
 

Detailed Description

Acurite weather stations and temperature / humidity sensors.

Copyright (c) 2015, Jens Jenson, Helge Weissig, David Ray Thompson, Robert Terzi

Devices decoded:

  • 5-n-1 weather sensor, Model; VN1TXC, 06004RM
  • 5-n-1 pro weather sensor, Model: 06014RM
  • 896 Rain gauge, Model: 00896
  • 592TXR / 06002RM Tower sensor (temperature and humidity) (Note: Some newer sensors share the 592TXR coding for compatibility.
  • 609TXC "TH" temperature and humidity sensor (609A1TX)
  • Acurite 986 Refrigerator / Freezer Thermometer
  • Acurite 606TX temperature sensor
  • Acurite 6045M Lightning Detector (Work in Progress)
  • Acurite 00275rm and 00276rm temp. and humidity with optional probe.

Function Documentation

◆ acurite_00275rm_decode()

◆ acurite_6045_decode()

static int acurite_6045_decode ( r_device decoder,
bitrow_t  bb,
int  browlen 
)
static

Acurite 06045m Lightning Sensor decoding.

Specs:

  • lightning strike count
  • estimated distance to front of storm, up to 25 miles / 40 km
  • Temperature -40 to 158 F / -40 to 70 C
  • Humidity 1 - 99% RH

Status Information sent per 06047M/01021 display

  • (RF) interference (preventing lightning detection)
  • low battery

Message format:

Somewhat similar to 592TXR and 5-n-1 weather stations. Same pulse characteristics. checksum, and parity checking on data bytes.

0   1   2   3   4   5   6   7   8
CI II  BB  HH  ST  TT  LL  DD? KK
  • C = Channel
  • I = ID
  • B = Battery + Message type 0x2f
  • S = Status/Message type/Temperature MSB.
  • T = Temperature
  • D = Lightning distance and status bits?
  • L = Lightning strike count.
  • K = Checksum

Byte 0 - channel/?/ID?

  • 0xC0: channel (A: 0xC, B: 0x8, C: 00)
  • 0x3F: most significant 6 bits of bit ID (14 bits, same as Acurite Tower sensor family)

Byte 1 - ID all 8 bits, no parity.

  • 0xFF = least significant 8 bits of ID Note that ID is just a number and that least/most is not externally meaningful.

Byte 2 - Battery and Message type

  • Bitmask PBMMMMMM
  • 0x80 = Parity
  • 0x40 = 1 is battery OK, 0 is battery low
  • 0x3f = Message type is 0x2f to indicate 06045M lightning

Byte 3 - Humidity

  • 0x80 - even parity
  • 0x7f - humidity

Byte 4 - Status (2 bits) and Temperature MSB (5 bits)

  • Bitmask PAUTTTTT (P = Parity, A = Active, U = unknown, T = Temperature)
  • 0x80 - even parity
  • 0x40 - Active Mode Transmitting every 8 seconds (lightning possibly detected) normal, off, transmits every 24 seconds
  • 0x20 - TBD: always off?
  • 0x1F - Temperature most significant 5 bits

Byte 5 - Temperature LSB (7 bits, 8th is parity)

  • 0x80 - even parity
  • 0x7F - Temperature least significant 7 bits

Byte 6 - Lightning Strike count (7 bits, 8th is parity)

  • 0x80 - even parity
  • 0x7F - strike count (wraps at 127) Stored in EEPROM (or something non-volatile)
    Todo:

    Does it go from 127 to 1, or to 0?

    needs cross-checking with light and/or console

Byte 7 - Edge of Storm Distance Approximation

  • Bits PSSDDDDD (P = Parity, S = Status, D = Distance
  • 0x80 - even parity
  • 0x40 - USSB1 (unknown strike status bit) - (possible activity?) currently decoded into "ussb1" output field
    Todo:
    needs understanding

Byte 8 - checksum. 8 bits, no parity.

Data fields:

  • active (vs standby) whether the AS39335 is in active scanning mode will be transmitting evey 8 seconds instead of every 24.
  • RFI detected - the AS3935 uses broad RFI for detection Somewhat correlates with the Yellow LED, but stays set longer Short periods of RFI on is normal long periods of RFI means interference, solid yellow, relocate sensor
  • Strike count - count of detection events, 7 bits, non-volatile
  • Distance to edge of storm - See AS3935 documentation. sensor will make a distance estimate with each strike event. Units unknown, data needed from people with Acurite consoles 0x1f (31) is invalid/undefined value, consumers should check for this.
  • USSB1 - Unknown Strike Status Bit May indicate validity of distance estimate, cleared after sensor beeps Might need to also correlate against RFI bit.
  • exception - bits that were invariant for me have changed. save raw_msg for further examination.
Todo:
  • check parity on bytes 2 - 7

Additional reverse engineering needed:

Todo:
  • Get distance to front of storm to match display

References acurite_getChannel(), DATA_DOUBLE, DATA_FORMAT, DATA_INT, data_make(), DATA_STRING, decoder_output_data(), parity8(), valid(), and r_device::verbose.

Referenced by acurite_txr_decode().

◆ acurite_606_decode()

◆ acurite_986_decode()

static int acurite_986_decode ( r_device decoder,
bitbuffer_t bitbuffer 
)
static

Acurite 00986 Refrigerator / Freezer Thermometer.

Includes two sensors and a display, labeled 1 and 2, by default 1 - Refrigerator, 2 - Freezer.

PPM, 5 bytes, sent twice, no gap between repeaters start/sync pulses two short, with short gaps, followed by 4 long pulse/gaps.

Todo:
, the 2 short sync pulses get confused as data.

Data Format - 5 bytes, sent LSB first, reversed:

TT II II SS CC
  • T - Temperature in Fahrenheit, integer, MSB = sign. Encoding is "Sign and magnitude"
  • I - 16 bit sensor ID changes at each power up
  • S - status/sensor type 0x01 = Sensor 2 0x02 = low battery
  • C = CRC (CRC-8 poly 0x07, little-endian)
Todo:
  • needs new PPM demod that can separate out the short start/sync pulses which confuse things and cause one data bit to be lost in the check value.

2018-04 A user with a dedicated receiver indicated the possibility that the transmitter actually drops the last bit instead of the demod.

leaving some of the debugging code until the missing bit issue gets resolved.

References bitbuffer::bb, bitrow_printf(), bitbuffer::bits_per_row, crc8le(), DATA_DOUBLE, DATA_FORMAT, DATA_INT, data_make(), DATA_STRING, decoder_output_data(), bitbuffer::num_rows, reverse8(), and r_device::verbose.

◆ acurite_getChannel()

static char acurite_getChannel ( uint8_t  byte)
static

References chLetter.

Referenced by acurite_6045_decode(), and acurite_txr_decode().

◆ acurite_rain_896_decode()

◆ acurite_th_decode()

static int acurite_th_decode ( r_device decoder,
bitbuffer_t bitbuffer 
)
static

Acurite 609 Temperature and Humidity Sensor.

5 byte messages:

II ST TT HH CC
II - ID byte, changes at each power up
S - Status bitmask, normally 0x2,
    0xa - battery low (bit 0x80)
TTT - Temp in Celsius * 10, 12 bit with complement.
HH - Humidity
CC - Checksum
Todo:
  • see if the 3rd nybble is battery/status

References bitbuffer::bb, bitbuffer::bits_per_row, DATA_DOUBLE, DATA_FORMAT, DATA_INT, data_make(), DATA_STRING, decoder_output_data(), bitbuffer::num_rows, and valid().

◆ acurite_txr_decode()

static int acurite_txr_decode ( r_device decoder,
bitbuffer_t bitbuffer 
)
static

This callback handles several Acurite devices that use a very similar RF encoding and data format:

  • 592TXR temperature and humidity sensor
  • 5-n-1 weather station
  • 6045M Lightning Detector with Temperature and Humidity

    CC RR IIII | IIII IIII | pBMMMMMM | pxxWWWWW | pWWWTTTT | pTTTTTTT | pSSSSSSS C:2d R:2d ID:12d 1x BATT:1b TYPE:6h 1x ?2b W:5b 1x 3b T:4b 1x 7b S: 1x 7d

Todo:
  • refactor, move 5n1 and txr decoding into separate functions.

- TBD Are parity and checksum the same across these devices? (opportunity to DRY-up and simplify?)

References acurite_5n1_winddirections, acurite_6045_decode(), acurite_getChannel(), add_bytes(), bitbuffer::bb, bitbuffer_invert(), bitbuffer_printf(), bitrow_printf(), bitbuffer::bits_per_row, DATA_DOUBLE, DATA_FORMAT, DATA_INT, data_make(), DATA_STRING, decoder_output_data(), bitbuffer::num_rows, parity8(), valid(), and r_device::verbose.

Variable Documentation

◆ acurite_00275rm

r_device acurite_00275rm
Initial value:
= {
.name = "Acurite 00275rm,00276rm Temp/Humidity with optional probe",
.modulation = OOK_PULSE_PWM,
.short_width = 232,
.long_width = 420,
.gap_limit = 520,
.reset_limit = 708,
.sync_width = 632,
.decode_fn = &acurite_00275rm_decode,
.disabled = 0,
}
static int acurite_00275rm_decode(r_device *decoder, bitbuffer_t *bitbuffer)
Definition: acurite.c:859
Pulse Width Modulation with precise timing parameters.
Definition: r_device.h:13
static char * acurite_00275rm_output_fields[]
Definition: acurite.c:1117

◆ acurite_00275rm_output_fields

char* acurite_00275rm_output_fields[]
static
Initial value:
= {
"model",
"probe",
"id",
"battery",
"temperature_C",
"humidity",
"water",
"temperature_1_C",
"humidity_1",
"ptemperature_C",
"phumidity",
"mic",
NULL,
}

◆ acurite_5n1_winddirections

int const acurite_5n1_winddirections[]
Initial value:
= {
14,
11,
13,
12,
15,
10,
0,
9,
3,
6,
4,
5,
2,
7,
1,
8,
}

Referenced by acurite_txr_decode().

◆ acurite_606

r_device acurite_606
Initial value:
= {
.name = "Acurite 606TX Temperature Sensor",
.modulation = OOK_PULSE_PPM,
.short_width = 2000,
.long_width = 4000,
.gap_limit = 7000,
.reset_limit = 10000,
.decode_fn = &acurite_606_decode,
.disabled = 0,
}
Pulse Position Modulation. Short gap = 0, Long = 1.
Definition: r_device.h:12
static char * acurite_606_output_fields[]
Definition: acurite.c:1090
static int acurite_606_decode(r_device *decoder, bitbuffer_t *bitbuffer)
Definition: acurite.c:802

◆ acurite_606_output_fields

char* acurite_606_output_fields[]
static
Initial value:
= {
"model",
"id",
"battery",
"temperature_C",
"mic",
NULL,
}

◆ acurite_986

r_device acurite_986
Initial value:
= {
.name = "Acurite 986 Refrigerator / Freezer Thermometer",
.modulation = OOK_PULSE_PPM,
.short_width = 520,
.long_width = 880,
.gap_limit = 1280,
.reset_limit = 4000,
.decode_fn = &acurite_986_decode,
.disabled = 0,
}
Pulse Position Modulation. Short gap = 0, Long = 1.
Definition: r_device.h:12
static int acurite_986_decode(r_device *decoder, bitbuffer_t *bitbuffer)
Acurite 00986 Refrigerator / Freezer Thermometer.
Definition: acurite.c:704
static char * acurite_986_output_fields[]
Definition: acurite.c:1061

◆ acurite_986_output_fields

char* acurite_986_output_fields[]
static
Initial value:
= {
"model",
"id",
"channel",
"temperature_F",
"battery",
"status",
NULL,
}

◆ acurite_rain_896

r_device acurite_rain_896
Initial value:
= {
.name = "Acurite 896 Rain Gauge",
.modulation = OOK_PULSE_PPM,
.short_width = 1000,
.long_width = 2000,
.gap_limit = 3500,
.reset_limit = 5000,
.decode_fn = &acurite_rain_896_decode,
.disabled = 1,
}
Pulse Position Modulation. Short gap = 0, Long = 1.
Definition: r_device.h:12
static int acurite_rain_896_decode(r_device *decoder, bitbuffer_t *bitbuffer)
Definition: acurite.c:102
static char * acurite_rain_gauge_output_fields[]
Definition: acurite.c:967

◆ acurite_rain_gauge_output_fields

char* acurite_rain_gauge_output_fields[]
static
Initial value:
= {
"model",
"id",
"rain",
"rain_mm",
NULL,
}

◆ acurite_th

r_device acurite_th
Initial value:
= {
.name = "Acurite 609TXC Temperature and Humidity Sensor",
.modulation = OOK_PULSE_PPM,
.short_width = 1000,
.long_width = 2000,
.gap_limit = 3000,
.reset_limit = 10000,
.decode_fn = &acurite_th_decode,
.disabled = 0,
}
Pulse Position Modulation. Short gap = 0, Long = 1.
Definition: r_device.h:12
static char * acurite_th_output_fields[]
Definition: acurite.c:988
static int acurite_th_decode(r_device *decoder, bitbuffer_t *bitbuffer)
Acurite 609 Temperature and Humidity Sensor.
Definition: acurite.c:152

◆ acurite_th_output_fields

char* acurite_th_output_fields[]
static
Initial value:
= {
"model",
"id",
"battery",
"status",
"temperature_C",
"humidity",
NULL,
}

◆ acurite_txr

r_device acurite_txr
Initial value:
= {
.name = "Acurite 592TXR Temp/Humidity, 5n1 Weather Station, 6045 Lightning",
.modulation = OOK_PULSE_PWM,
.short_width = 220,
.long_width = 408,
.sync_width = 620,
.gap_limit = 500,
.reset_limit = 4000,
.decode_fn = &acurite_txr_decode,
.disabled = 0,
}
static char * acurite_txr_output_fields[]
Definition: acurite.c:1014
static int acurite_txr_decode(r_device *decoder, bitbuffer_t *bitbuffer)
This callback handles several Acurite devices that use a very similar RF encoding and data format: ...
Definition: acurite.c:423
Pulse Width Modulation with precise timing parameters.
Definition: r_device.h:13

◆ acurite_txr_output_fields

char* acurite_txr_output_fields[]
static
Initial value:
= {
"model",
"id",
"sensor_id",
"channel",
"temperature_C",
"humidity",
"battery_low",
"battery_ok",
"sequence_num",
"battery",
"message_type",
"wind_speed_mph",
"wind_speed_kph",
"wind_avg_mi_h",
"wind_avg_km_h",
"wind_dir_deg",
"rain_inch",
"rain_in",
"rain_mm",
"temperature_F",
NULL,
}

◆ chLetter

char chLetter[4] = {'C','E','B','A'}
static

Referenced by acurite_getChannel().