Skip to content

Commit

Permalink
minor: Cleanup Bresser-ST1005H code style
Browse files Browse the repository at this point in the history
  • Loading branch information
zuckschwerdt committed Nov 30, 2024
1 parent b503e3f commit a8582c3
Showing 1 changed file with 62 additions and 69 deletions.
131 changes: 62 additions & 69 deletions src/devices/bresser_st1005h.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/

#include "decoder.h"

/**
Bresser ST1005H sensor protocol.
Expand All @@ -19,52 +22,55 @@ The protocol is for a(nother) variant of wireless Temperature/Humidity sensor
Another sensor sold under the same generic name is handled by bresser_3ch.c.
The data of this sensor is grouped in 38 bits that are repeated a few times,
and is send roughly every 90 secs (plus each time TX button is pressed).
Data layout:
The data has the following categorization of the bits:
01234567 89012345 67890123 45678901 234567
0IIIIIII ILBCCTTT TTTTTTTT THHHHHHH ======
01234567 89012345 67890123 45678901 234567
0IIIIIII ILBCCTTT TTTTTTTT THHHHHHH XXXXXX
where:
0 prefixed always null bit
I identity (changed by battery replacement)
L low battery (assumed, always 0 in tests)
B triggered by TX button in battery compartment
C channel 1-3 choosen by switch in battery compartment
T temperature in °C (with one decimal) multiplied by 10
H humidity, values higher than 95 are shown as HH in display
= checksum of nibbles added
- 0 prefixed always null bit
- I identity (changed by battery replacement)
- L low battery (assumed, always 0 in tests)
- B triggered by TX button in battery compartment
- C channel 1-3 choosen by switch in battery compartment
- T temperature in °C (with one decimal) multiplied by 10
- H humidity, values higher than 95 are shown as HH in display
- X checksum of nibbles added
Examples with their temp/humanity reading in display:
0 12345678 9 0 12 345678901234 5678901 234567
0 IIIIIIII L B CC TTTTTTTTTTTT HHHHHHH ====== hum temp
0 01111101 0 0 00 000010110001 1000110 110100 70% 17.7°
0 01111101 0 0 00 000010110010 1000110 110101 70% 17.8°
0 01111101 0 1 00 000010110011 1000110 111010 70% 17.9°
0 01111101 0 1 00 000010110011 1001001 110001 73% 17.9°
0 01111101 0 1 00 000010110100 1000111 111101 71% 18.0°
0 01111101 0 1 00 000010110101 1000101 111010 69% 18.1°
0 11011101 0 0 00 000010110101 1000101 111100 69% 18.1°
0 01001010 0 0 00 000010110101 1000110 110010 70% 18.1°
0 10100000 0 0 00 000010110110 1000100 101011 68% 18.2°
0 01101010 0 0 00 000010110110 1000101 110011 69% 18.2°
0 01101010 0 1 00 000010110110 1000100 110101 68% 18.2°
0 01101010 0 0 00 000010110011 1000101 110000 69% 17.9°
0 01101010 0 1 00 000010110011 1000101 110100 69% 17.9°
0 01101010 0 0 00 000011000101 1101110 111010 HH% 19.7°
0 01101010 0 0 00 000011010000 1101110 110110 HH% 20.8°
0 01101010 0 0 00 000011010011 1011111 111001 95% 21.1°
0 11000010 0 1 00 111101011100 1010011 000010 83% -16.4°
0 11000010 0 1 00 111101110100 1001110 000001 78% -14.0°
0 11000010 0 1 00 111110100010 1101110 000110 HH% -9.4°
0 11000010 0 1 00 000000001101 1011101 110100 93% 1.3°
0 11110000 0 0 00 000010011100 1010010 110010 82% 15.6°
0 11110000 0 1 00 000010011100 1010010 110110 82% 15.6°
0 11110000 0 1 01 000010011100 1010010 110111 82% 15.6°
0 11110000 0 1 10 000010011100 1010010 111000 82% 15.6°
0 12345678 9 0 12 345678901234 5678901 234567
0 IIIIIIII L B CC TTTTTTTTTTTT HHHHHHH ====== hum temp
0 01111101 0 0 00 000010110001 1000110 110100 70% 17.7°
0 01111101 0 0 00 000010110010 1000110 110101 70% 17.8°
0 01111101 0 1 00 000010110011 1000110 111010 70% 17.9°
0 01111101 0 1 00 000010110011 1001001 110001 73% 17.9°
0 01111101 0 1 00 000010110100 1000111 111101 71% 18.0°
0 01111101 0 1 00 000010110101 1000101 111010 69% 18.1°
0 11011101 0 0 00 000010110101 1000101 111100 69% 18.1°
0 01001010 0 0 00 000010110101 1000110 110010 70% 18.1°
0 10100000 0 0 00 000010110110 1000100 101011 68% 18.2°
0 01101010 0 0 00 000010110110 1000101 110011 69% 18.2°
0 01101010 0 1 00 000010110110 1000100 110101 68% 18.2°
0 01101010 0 0 00 000010110011 1000101 110000 69% 17.9°
0 01101010 0 1 00 000010110011 1000101 110100 69% 17.9°
0 01101010 0 0 00 000011000101 1101110 111010 HH% 19.7°
0 01101010 0 0 00 000011010000 1101110 110110 HH% 20.8°
0 01101010 0 0 00 000011010011 1011111 111001 95% 21.1°
0 11000010 0 1 00 111101011100 1010011 000010 83% -16.4°
0 11000010 0 1 00 111101110100 1001110 000001 78% -14.0°
0 11000010 0 1 00 111110100010 1101110 000110 HH% -9.4°
0 11000010 0 1 00 000000001101 1011101 110100 93% 1.3°
0 11110000 0 0 00 000010011100 1010010 110010 82% 15.6°
0 11110000 0 1 00 000010011100 1010010 110110 82% 15.6°
0 11110000 0 1 01 000010011100 1010010 110111 82% 15.6°
0 11110000 0 1 10 000010011100 1010010 111000 82% 15.6°
The device has a second button in the battery compartment to flip
between °C and °F in the display (default is °C), but its state
Expand All @@ -77,62 +83,49 @@ other sensor as valid from their sensor with "plausable" but usually
completely wrong values.
Examples which are misdetected by Oregon:
0 01101010 0 1 00 000010101011 1000110 111101 70% 17.1°
0 11000010 0 0 00 000001010010 1101110 101110 HH% 8.2°
*/
#include "decoder.h"
/* helper for the checksum adding the nibbles of given value */
static int bresser_add_nibbles(int const input, int const count)
{
int output = 0;
for (int i = 0; i < (count * 4); i += 4)
output += ((input & (0x000F << i)) >> i);
return output;
}
0 01101010 0 1 00 000010101011 1000110 111101 70% 17.1°
0 11000010 0 0 00 000001010010 1101110 101110 HH% 8.2°
*/
static int bresser_st1005h_decode(r_device *decoder, bitbuffer_t *bitbuffer)
{
data_t *data;
uint8_t *b;

int id, button, battery_low, channel, temp_raw, humidity, checksum;
double temp_c;

int r = bitbuffer_find_repeated_row(bitbuffer, 3, 38);
if (r < 0 || bitbuffer->bits_per_row[r] > 38) {
return DECODE_ABORT_LENGTH;
}
b = bitbuffer->bb[r];
uint8_t *b = bitbuffer->bb[r];

if (bitrow_get_bit(b, 0) != 0) {
decoder_log(decoder, 1, __func__, "prefix null bit is not null");
return DECODE_FAIL_SANITY;
}

id = bitrow_get_byte(b, 1);
battery_low = bitrow_get_bit(b, 9);
button = bitrow_get_bit(b, 10);
channel = (bitrow_get_bit(b, 11) << 1) + bitrow_get_bit(b, 12) + 1;

temp_raw = bitrow_get_bit(b, 13) ? ~0xFFF : 0;
temp_raw |= (bitrow_get_byte(b, 13) << 4) + (bitrow_get_byte(b, 21) >> 4);
temp_c = temp_raw * 0.1;
uint8_t msg[4];
bitbuffer_extract_bytes(bitbuffer, r, 1, msg, 4*8);
msg[3] &= 0xfe; // remove last bit, it is part of the checksum
int chk = b[4] >> 2;
int sum = add_nibbles(msg, 4) & 0x3f;

humidity = bitrow_get_byte(b, 25) >> 1;

checksum = (bresser_add_nibbles(id, 2) + (battery_low << 3) + (button << 2) + (channel - 1) + bresser_add_nibbles(temp_raw, 3) + bresser_add_nibbles(2 * humidity, 2)) & 0x03F;
if (checksum != (b[4] >> 2)) {
if (chk != sum) {
decoder_log(decoder, 1, __func__, "checksum error");
return DECODE_FAIL_MIC;
}

int id = msg[0];
int battery_low = msg[1] >> 7;
int button = (msg[1] >> 6) & 0x1;
int channel = ((msg[1] >> 4) & 0x3) + 1;
int temp_raw = (int16_t)(((msg[1] & 0xf) << 12) | (msg[2] << 4)); // uses sign-extend from 12 bit
double temp_c = (temp_raw >> 4) * 0.1;
int humidity = msg[3] >> 1;

if ((channel >= 4) || (humidity > 110) || (temp_c < -30.0) || (temp_c > 160.0)) {
decoder_log(decoder, 1, __func__, "data error");
return DECODE_FAIL_SANITY;
}

/* clang-format off */
data = data_make(
data_t *data = data_make(
"model", "", DATA_STRING, "Bresser-ST1005H",
"id", "Id", DATA_INT, id,
"channel", "Channel", DATA_INT, channel,
Expand Down

0 comments on commit a8582c3

Please sign in to comment.