Skip to content

Commit

Permalink
Improve Ecowitt WH53 (#2934)
Browse files Browse the repository at this point in the history
  • Loading branch information
ProfBoc75 committed May 23, 2024
1 parent 8d35eb3 commit 86abae0
Showing 1 changed file with 24 additions and 29 deletions.
53 changes: 24 additions & 29 deletions src/devices/ecowitt.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Ecowitt Wireless Outdoor Thermometer WH53/WH0280/WH0281A.
55-bit one-row data packet format (inclusive ranges, 0-indexed):
| 0-6 | 7-bit header, ignored for checksum, always 1111111
| 0-6 | 7-bit header, ignored for checksum, always 1111111, not stable, could be 6 x 1 bit see #2933
| 7-14 | Model code, 0x53
| 15-22 | Sensor ID, randomly reinitialized on boot
| 23-24 | Always 00
Expand All @@ -28,31 +28,37 @@ Ecowitt Wireless Outdoor Thermometer WH53/WH0280/WH0281A.

static int ecowitt_decode(r_device *decoder, bitbuffer_t *bitbuffer)
{
uint8_t const preamble_pattern[] = {
0xf5, 0x30 // preamble and model code nominally 7+8 bit, look for 12 bit only #2933
};

// All Ecowitt packets have one row.
if (bitbuffer->num_rows != 1) {
return DECODE_ABORT_LENGTH;
}

// All Ecowitt packets have 55 bits.
if (bitbuffer->bits_per_row[0] != 55) {
return DECODE_ABORT_LENGTH;
}
unsigned pos = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 12);

uint8_t *row = bitbuffer->bb[0];
// Preamble found ?
if (pos >= bitbuffer->bits_per_row[0]) {
decoder_logf(decoder, 2, __func__, "Preamble not found");
return DECODE_ABORT_EARLY;
}

// All Ecowitt packets have the first 7 bits set.
uint8_t first7bits = row[0] >> 1;
if (first7bits != 0x7F) {
// 4 + 6*8 bit required
if ((bitbuffer->bits_per_row[0] - pos) < 52) {
decoder_logf(decoder, 2, __func__, "Too short");
return DECODE_ABORT_EARLY;
}

// Byte-align the rest of the message by skipping the first 7 bits.
// Byte-align the rest of the message by skipping the first 4 bit.
uint8_t b[6];
bitbuffer_extract_bytes(bitbuffer, /* row= */ 0, /* pos= */ 7, b, sizeof(b) * 8); // Skip first 7 bits
bitbuffer_extract_bytes(bitbuffer, 0, pos + 4 , b, sizeof(b) * 8); // Skip first 4 bit but keep model 0x53 needed for crc
decoder_log_bitrow(decoder, 2, __func__, b, sizeof(b) * 8, "MSG");

// All Ecowitt packets continue with a fixed header
if (b[0] != 0x53) {
return DECODE_ABORT_EARLY;
// check crc, poly 0x31, init 0x00
if (crc8(b, 6, 0x31, 0)) {
return DECODE_FAIL_MIC;
}

// Randomly generated at boot time sensor ID.
Expand Down Expand Up @@ -81,24 +87,13 @@ static int ecowitt_decode(r_device *decoder, bitbuffer_t *bitbuffer)
return DECODE_ABORT_EARLY;
}

// Compute checksum skipping first 7 bits
uint8_t wire_crc = b[5];
int computed_crc = crc8(
b,
/* nBytes= */ sizeof(b) - 1, // Exclude the CRC byte itself
/* polynomial= */ 0x31,
/* init= */ 0);
if (wire_crc != computed_crc) {
return DECODE_FAIL_MIC;
}

/* clang-format off */
data_t *data = data_make(
"model", "", DATA_STRING, "Ecowitt-WH53",
"id", "Id", DATA_INT, sensor_id,
"channel", "Channel", DATA_INT, channel,
"model", "", DATA_STRING, "Ecowitt-WH53",
"id", "Id", DATA_INT, sensor_id,
"channel", "Channel", DATA_INT, channel,
"temperature_C", "Temperature", DATA_FORMAT, "%.1f C", DATA_DOUBLE, temp_c,
"mic", "Integrity", DATA_STRING, "CRC",
"mic", "Integrity", DATA_STRING, "CRC",
NULL);
/* clang-format on */

Expand Down

0 comments on commit 86abae0

Please sign in to comment.