Skip to content

Commit 28cb54b

Browse files
jfbauer432merbanan
authored andcommitted
Add Acurite 985 support
Code based on #1582 Assisted-by: Qwen 3.6 Plus
1 parent 0daa167 commit 28cb54b

3 files changed

Lines changed: 191 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
386386
[298] TRW TPMS OOK OEM and Clone models
387387
[299] TRW TPMS FSK OEM and Clone models
388388
[300] Govee Water Leak Detector H5059
389+
[301] Acurite/Chaney 985 Refrigerator / Freezer Thermometer
389390
390391
* Disabled by default, use -R n or a conf file to enable
391392

include/rtl_433_devices.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@
308308
DECL(tpms_trw_ook) \
309309
DECL(tpms_trw_fsk) \
310310
DECL(govee_h5059) \
311+
DECL(acurite_985) \
311312

312313
/* Add new decoders here. */
313314

src/devices/acurite.c

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Devices decoded:
2121
(Note: Some newer sensors share the 592TXR coding for compatibility.
2222
- Acurite 609TXC "TH" temperature and humidity sensor (609A1TX)
2323
- Acurite 986 Refrigerator / Freezer Thermometer
24+
- Acurite/Chaney 985 Refrigerator / Freezer Thermometer
2425
- Acurite 515 Refrigerator / Freezer Thermometer
2526
- Acurite 606TX / Technoline TX960 temperature sensor, optional with channels and [TX]Button
2627
- Acurite 6045M Lightning Detector
@@ -1592,6 +1593,166 @@ static int acurite_986_decode(r_device *decoder, bitbuffer_t *bitbuffer)
15921593
return result;
15931594
}
15941595

1596+
/**
1597+
Acurite/Chaney 00985 Refrigerator / Freezer Thermometer.
1598+
1599+
Includes two sensors and a display, labeled 1 and 2,
1600+
by default 1 - Refrigerator, 2 - Freezer.
1601+
1602+
This is very similar to the Acurite 00986. The 985 is likely the version
1603+
they sold before they rebranded as Acurite. Chaney Instrument Co. is a
1604+
subsidiary of the Primex Family of Companies and Acurite is a brand.
1605+
1606+
FCC ID: RNE00985TX
1607+
1608+
Temperature range: -40F to 104F (-40C to 40C)
1609+
Accuracy +- 2F
1610+
Base frequency is 433MHz
1611+
1612+
Data Format - 7 bytes, sent LSB first, bit-reversed per byte:
1613+
1614+
XX XX TT II II SS CC
1615+
1616+
- X - Unknown (likely sync pulse / preamble)
1617+
- T - Temperature in Fahrenheit, integer, MSB = sign (sign and magnitude)
1618+
More than maximum is 0x7f
1619+
Less than minimum is 0xff
1620+
- I - 16 bit sensor ID, changes at each power up
1621+
- S - status/sensor type
1622+
bit 0: 0 for channel 1 (Refrigerator), 1 for channel 2 (Freezer)
1623+
bit 1: low battery indicator for channel 1
1624+
bit 2: low battery indicator for channel 2
1625+
low battery: 0=normal, 1=low (under 2.5V)
1626+
All other bits are undefined
1627+
- C - CRC (CRC-8 poly 0x07, little-endian)
1628+
1629+
The devices transmit three groups which are transmitted within 1 second.
1630+
1631+
The transmitting interval is initially 64 seconds upon power on.
1632+
After 20 minutes, the interval of sensor1 is 7.5 minutes, and
1633+
the interval of sensor2 is 6 minutes.
1634+
1635+
*/
1636+
static int acurite_985_decode(r_device *decoder, bitbuffer_t *bitbuffer)
1637+
{
1638+
uint8_t *bb, sensor_num, status, crc, crcc;
1639+
uint8_t br[7];
1640+
int bits;
1641+
int8_t tempf;
1642+
uint16_t sensor_id, valid_cnt = 0;
1643+
char sensor_type;
1644+
char const *channel_str;
1645+
int battery_low;
1646+
int result = 0;
1647+
1648+
for (uint16_t brow = 0; brow < bitbuffer->num_rows; ++brow) {
1649+
bb = bitbuffer->bb[brow];
1650+
bits = bitbuffer->bits_per_row[brow];
1651+
1652+
decoder_logf(decoder, 2, __func__, "row %u bits %u", brow, bits);
1653+
1654+
if (bits < 55 || bits > 59) {
1655+
if (bits > 16)
1656+
decoder_log(decoder, 2, __func__, "skipping wrong len");
1657+
result = DECODE_ABORT_LENGTH;
1658+
continue;
1659+
}
1660+
1661+
// Reduce false positives. All zero bytes will pass the CRC check.
1662+
if (bb[2] == 0x00 && bb[3] == 0x00 && bb[4] == 0x00 &&
1663+
bb[5] == 0x00 && bb[6] == 0x00) {
1664+
decoder_log(decoder, 2, __func__, "skipping all zeros");
1665+
result = DECODE_ABORT_EARLY;
1666+
continue;
1667+
}
1668+
1669+
// Reverse the bits, msg sent LSB first
1670+
for (int i = 0; i < 7; i++)
1671+
br[i] = reverse8(bb[i]);
1672+
1673+
decoder_log_bitrow(decoder, 1, __func__, br, 56, "reversed");
1674+
1675+
// First 2 bytes appear to be sync/preamble
1676+
tempf = br[2];
1677+
sensor_id = (br[3] << 8) | br[4];
1678+
status = br[5];
1679+
sensor_num = (status & 0x01) + 1;
1680+
1681+
// The two sensors use a different bit to denote low battery
1682+
if (sensor_num == 2)
1683+
battery_low = (status & 0x04) ? 1 : 0;
1684+
else
1685+
battery_low = (status & 0x02) ? 1 : 0;
1686+
1687+
// By default Sensor 1 is Refrigerator, 2 is Freezer
1688+
sensor_type = sensor_num == 2 ? 'F' : 'R';
1689+
channel_str = sensor_num == 2 ? "2F" : "1R";
1690+
1691+
crc = br[6];
1692+
crcc = crc8le(br + 2, 4, 0x07, 0);
1693+
1694+
decoder_logf(decoder, 1, __func__, "rawtemp=0x%02x id=%u sensor_num=%d batt=%s",
1695+
tempf, sensor_id, sensor_num, battery_low ? "low" : "ok");
1696+
decoder_logf(decoder, 2, __func__, "crc=0x%02x crcc=0x%02x", crc, crcc);
1697+
1698+
if (crcc != crc) {
1699+
decoder_logf_bitrow(decoder, 2, __func__, br, 56, "bad CRC: %02x -", crcc);
1700+
// HACK: the message is often missing the last 1 bit either due to a
1701+
// problem with the device or demodulator
1702+
// Add 1 (0x80 because message is LSB) and retry CRC.
1703+
if (crcc == (crc | 0x80)) {
1704+
decoder_logf(decoder, 2, __func__, "CRC fix %02x - %02x", crc, crcc);
1705+
}
1706+
else {
1707+
result = DECODE_FAIL_MIC;
1708+
continue;
1709+
}
1710+
}
1711+
1712+
// Convert from sign-and-magnitude
1713+
if (tempf & 0x80) {
1714+
tempf = (tempf & 0x7f) * -1;
1715+
}
1716+
1717+
// Validate temperature
1718+
if (tempf >= -40 && tempf <= 104) {
1719+
decoder_logf(decoder, 1, __func__, "valid temperature: %d", tempf);
1720+
}
1721+
else if (tempf == -127 || tempf == 127) {
1722+
decoder_logf(decoder, 1, __func__, "temperature %s operational range",
1723+
tempf == 127 ? "above" : "below");
1724+
}
1725+
else {
1726+
decoder_logf(decoder, 1, __func__, "skipping bad temperature: %d", tempf);
1727+
result = DECODE_FAIL_SANITY;
1728+
continue;
1729+
}
1730+
1731+
decoder_logf(decoder, 1, __func__, "sensor 0x%04x - %d%c: %d F", sensor_id, sensor_num, sensor_type, tempf);
1732+
1733+
/* clang-format off */
1734+
data_t *data = data_make(
1735+
"model", "", DATA_STRING, "Acurite-985",
1736+
"id", "", DATA_INT, sensor_id,
1737+
"channel", "", DATA_STRING, channel_str,
1738+
"battery_ok", "Battery", DATA_INT, !battery_low,
1739+
"temperature_F", "temperature", DATA_FORMAT, "%f F", DATA_DOUBLE, (float)tempf,
1740+
"status", "Status", DATA_INT, status,
1741+
"mic", "Integrity", DATA_STRING, "CRC",
1742+
NULL);
1743+
/* clang-format on */
1744+
1745+
decoder_output_data(decoder, data);
1746+
1747+
valid_cnt++;
1748+
}
1749+
1750+
if (valid_cnt)
1751+
return 1;
1752+
1753+
return result;
1754+
}
1755+
15951756
/**
15961757
Acurite 606TX / Technoline TX960 Temperature sensor decoder.
15971758
@@ -1954,6 +2115,34 @@ r_device const acurite_986 = {
19542115
.fields = acurite_986_output_fields,
19552116
};
19562117

2118+
/*
2119+
* Acurite/Chaney 00985 Refrigerator / Freezer Thermometer
2120+
*
2121+
* Temperature only
2122+
*/
2123+
static char const *const acurite_985_output_fields[] = {
2124+
"model",
2125+
"id",
2126+
"channel",
2127+
"battery_ok",
2128+
"temperature_F",
2129+
"status",
2130+
"mic",
2131+
NULL,
2132+
};
2133+
2134+
r_device const acurite_985 = {
2135+
.name = "Acurite/Chaney 985 Refrigerator / Freezer Thermometer",
2136+
.modulation = OOK_PULSE_PPM,
2137+
.short_width = 556,
2138+
.long_width = 1104,
2139+
.gap_limit = 4000,
2140+
.reset_limit = 7636,
2141+
.sync_width = 2996,
2142+
.decode_fn = &acurite_985_decode,
2143+
.fields = acurite_985_output_fields,
2144+
};
2145+
19572146
/*
19582147
* Acurite 00606TX Tower Sensor
19592148
*

0 commit comments

Comments
 (0)