WS: fix protocol TX141TH-BV2 (#2559)

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Skorpionm 2023-04-04 08:37:54 +04:00 committed by GitHub
parent efc52ab469
commit 494002505e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,11 +2,15 @@
#define TAG "WSProtocolLaCrosse_TX141THBv2" #define TAG "WSProtocolLaCrosse_TX141THBv2"
#define LACROSSE_TX141TH_BV2_BIT_COUNT 41
/* /*
* Help * Help
* https://github.com/merbanan/rtl_433/blob/master/src/devices/lacrosse_tx141x.c * https://github.com/merbanan/rtl_433/blob/master/src/devices/lacrosse_tx141x.c
* *
* iiii iiii | bkcc tttt | tttt tttt | hhhh hhhh | cccc cccc | u * iiii iiii | bkcc tttt | tttt tttt | hhhh hhhh | cccc cccc | u - 41 bit
* or
* iiii iiii | bkcc tttt | tttt tttt | hhhh hhhh | cccc cccc | -40 bit
* - i: identification; changes on battery switch * - i: identification; changes on battery switch
* - c: lfsr_digest8_reflect; * - c: lfsr_digest8_reflect;
* - u: unknown; * - u: unknown;
@ -17,10 +21,10 @@
*/ */
static const SubGhzBlockConst ws_protocol_lacrosse_tx141thbv2_const = { static const SubGhzBlockConst ws_protocol_lacrosse_tx141thbv2_const = {
.te_short = 250, .te_short = 208,
.te_long = 500, .te_long = 417,
.te_delta = 120, .te_delta = 120,
.min_count_bit_for_found = 41, .min_count_bit_for_found = 40,
}; };
struct WSProtocolDecoderLaCrosse_TX141THBv2 { struct WSProtocolDecoderLaCrosse_TX141THBv2 {
@ -102,14 +106,14 @@ void ws_protocol_decoder_lacrosse_tx141thbv2_reset(void* context) {
static bool static bool
ws_protocol_lacrosse_tx141thbv2_check_crc(WSProtocolDecoderLaCrosse_TX141THBv2* instance) { ws_protocol_lacrosse_tx141thbv2_check_crc(WSProtocolDecoderLaCrosse_TX141THBv2* instance) {
if(!instance->decoder.decode_data) return false; if(!instance->decoder.decode_data) return false;
uint8_t msg[] = { uint64_t data = instance->decoder.decode_data;
instance->decoder.decode_data >> 33, if(instance->decoder.decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) {
instance->decoder.decode_data >> 25, data >>= 1;
instance->decoder.decode_data >> 17, }
instance->decoder.decode_data >> 9}; uint8_t msg[] = {data >> 32, data >> 24, data >> 16, data >> 8};
uint8_t crc = subghz_protocol_blocks_lfsr_digest8_reflect(msg, 4, 0x31, 0xF4); uint8_t crc = subghz_protocol_blocks_lfsr_digest8_reflect(msg, 4, 0x31, 0xF4);
return (crc == ((instance->decoder.decode_data >> 1) & 0xFF)); return (crc == (data & 0xFF));
} }
/** /**
@ -117,14 +121,43 @@ static bool
* @param instance Pointer to a WSBlockGeneric* instance * @param instance Pointer to a WSBlockGeneric* instance
*/ */
static void ws_protocol_lacrosse_tx141thbv2_remote_controller(WSBlockGeneric* instance) { static void ws_protocol_lacrosse_tx141thbv2_remote_controller(WSBlockGeneric* instance) {
instance->id = instance->data >> 33; uint64_t data = instance->data;
instance->battery_low = (instance->data >> 32) & 1; if(instance->data_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) {
instance->btn = (instance->data >> 31) & 1; data >>= 1;
instance->channel = ((instance->data >> 29) & 0x03) + 1; }
instance->temp = ((float)((instance->data >> 17) & 0x0FFF) - 500.0f) / 10.0f; instance->id = data >> 32;
instance->humidity = (instance->data >> 9) & 0xFF; instance->battery_low = (data >> 31) & 1;
instance->btn = (data >> 30) & 1;
instance->channel = ((data >> 28) & 0x03) + 1;
instance->temp = ((float)((data >> 16) & 0x0FFF) - 500.0f) / 10.0f;
instance->humidity = (data >> 8) & 0xFF;
} }
/**
* Analysis of received data
* @param instance Pointer to a WSBlockGeneric* instance
*/
static bool ws_protocol_decoder_lacrosse_tx141thbv2_add_bit(
WSProtocolDecoderLaCrosse_TX141THBv2* instance,
uint32_t te_last,
uint32_t te_current) {
furi_assert(instance);
bool ret = false;
if(DURATION_DIFF(
te_last + te_current,
ws_protocol_lacrosse_tx141thbv2_const.te_short +
ws_protocol_lacrosse_tx141thbv2_const.te_long) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) {
if(te_last > te_current) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
} else {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
}
ret = true;
}
return ret;
}
void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uint32_t duration) { void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uint32_t duration) {
furi_assert(context); furi_assert(context);
WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; WSProtocolDecoderLaCrosse_TX141THBv2* instance = context;
@ -132,7 +165,7 @@ void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uin
switch(instance->decoder.parser_step) { switch(instance->decoder.parser_step) {
case LaCrosse_TX141THBv2DecoderStepReset: case LaCrosse_TX141THBv2DecoderStepReset:
if((level) && if((level) &&
(DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 3) < (DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2)) { ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2)) {
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepCheckPreambule; instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepCheckPreambule;
instance->decoder.te_last = duration; instance->decoder.te_last = duration;
@ -146,33 +179,17 @@ void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uin
} else { } else {
if((DURATION_DIFF( if((DURATION_DIFF(
instance->decoder.te_last, instance->decoder.te_last,
ws_protocol_lacrosse_tx141thbv2_const.te_short * 3) < ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) && ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) &&
(DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 3) < (DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2)) { ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2)) {
//Found preambule //Found preambule
instance->header_count++; instance->header_count++;
} else if(instance->header_count == 4) { } else if(instance->header_count == 4) {
if((DURATION_DIFF( if(ws_protocol_decoder_lacrosse_tx141thbv2_add_bit(
instance->decoder.te_last, instance, instance->decoder.te_last, duration)) {
ws_protocol_lacrosse_tx141thbv2_const.te_short) < instance->decoder.decode_data = instance->decoder.decode_data & 1;
ws_protocol_lacrosse_tx141thbv2_const.te_delta) && instance->decoder.decode_count_bit = 1;
(DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_long) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta)) {
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration;
} else if(
(DURATION_DIFF(
instance->decoder.te_last,
ws_protocol_lacrosse_tx141thbv2_const.te_long) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta) &&
(DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta)) {
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration; instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration;
} else { } else {
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset;
@ -198,11 +215,17 @@ void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uin
instance->decoder.te_last, instance->decoder.te_last,
ws_protocol_lacrosse_tx141thbv2_const.te_short * 3) < ws_protocol_lacrosse_tx141thbv2_const.te_short * 3) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) && ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) &&
(DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 3) < (DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2))) { ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2))) {
FURI_LOG_E(
"WS",
"%llX %d",
instance->decoder.decode_data,
instance->decoder.decode_count_bit);
if((instance->decoder.decode_count_bit == if((instance->decoder.decode_count_bit ==
ws_protocol_lacrosse_tx141thbv2_const.min_count_bit_for_found) && ws_protocol_lacrosse_tx141thbv2_const.min_count_bit_for_found) ||
ws_protocol_lacrosse_tx141thbv2_check_crc(instance)) { (instance->decoder.decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT)) {
if(ws_protocol_lacrosse_tx141thbv2_check_crc(instance)) {
instance->generic.data = instance->decoder.decode_data; instance->generic.data = instance->decoder.decode_data;
instance->generic.data_count_bit = instance->decoder.decode_count_bit; instance->generic.data_count_bit = instance->decoder.decode_count_bit;
ws_protocol_lacrosse_tx141thbv2_remote_controller(&instance->generic); ws_protocol_lacrosse_tx141thbv2_remote_controller(&instance->generic);
@ -214,21 +237,9 @@ void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uin
instance->header_count = 1; instance->header_count = 1;
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepCheckPreambule; instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepCheckPreambule;
break; break;
} else if( }
(DURATION_DIFF( } else if(ws_protocol_decoder_lacrosse_tx141thbv2_add_bit(
instance->decoder.te_last, ws_protocol_lacrosse_tx141thbv2_const.te_short) < instance, instance->decoder.te_last, duration)) {
ws_protocol_lacrosse_tx141thbv2_const.te_delta) &&
(DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_long) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration;
} else if(
(DURATION_DIFF(
instance->decoder.te_last, ws_protocol_lacrosse_tx141thbv2_const.te_long) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta) &&
(DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short) <
ws_protocol_lacrosse_tx141thbv2_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration; instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration;
} else { } else {
instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset;