diff --git a/CHANGELOG.md b/CHANGELOG.md index 9500c727c..8407e8ce4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ - UL: Add signals button editor and real remote simulation (full signal transmit with just one click) (by @Dmitry422) - UL: KeeLoq add counter mode 7 (sends 7 signals increasing counter with 0x3333 steps) - may bypass counter on some receivers! (by @xMasterX) - UL: TX Power setting (by @LeeroysHub) + - UL: Somfy Keytis button switch and Add Manually support (by @xMasterX) + - UL: Genius Echo/Bravo add 2 buttons hold simulation (0xB btn code) (by @xMasterX) - UL: JS: Add IR capabilities to the JS engine (by @LuisMayo) - UL: Docs: Add [full list of supported SubGHz protocols](https://github.com/Next-Flip/Momentum-Firmware/blob/dev/documentation/SubGHzSupportedSystems.md) and their frequencies/modulations that can be used for reading remotes (by @xMasterX) @@ -43,6 +45,7 @@ - UL: BFT KeeLoq try decoding with zero seed too (by @xMasterX) - UL: KeeLoq display BFT programming mode TX (when arrow button is held) (by @xMasterX) - UL: Signal Settings Improvements (by @Dmitry422) + - UL: KeeLoq change delta size (by @xMasterX) - Archive: Support opening and pinning ProtoPirate files from Archive (#510 by @LeeroysHub) - OFW: API: Make `view_port_send_to_back()` public (by @loftyinclination) @@ -54,6 +57,7 @@ - UL: Nice Flor S remove extra uint64 variable (by @xMasterX) - UL: Fix Alutech AT4N false positives (by @xMasterX) - UL: Fix documentation link for HT12A protocol (by @carlogrisetti) + - UL: BFT Mitto fix decode bug (seed was not resetting after one successful decode) (by @xMasterX) - NFC: - Fix sending 32+ byte ISO 15693-3 commands (by @WillyJL) - Fixes to `READ_MULTI` and `GET_BLOCK_SECURITY` commands in ISO 15693-3 emulation (#501 by @WillyJL & aaronjamt) diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index 1ac2058e7..f2160ca3e 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -78,6 +78,7 @@ typedef enum { SetTypeFaacSLH_433, SetTypeBFTMitto, SetTypeSomfyTelis, + SetTypeSomfyKeytis, SetTypeKingGatesStylo4k, SetTypeBenincaARC, SetTypeJarolift, diff --git a/applications/main/subghz/helpers/subghz_gen_info.c b/applications/main/subghz/helpers/subghz_gen_info.c index bfa609e32..bce3d6856 100644 --- a/applications/main/subghz/helpers/subghz_gen_info.c +++ b/applications/main/subghz/helpers/subghz_gen_info.c @@ -523,6 +523,15 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty .somfy_telis.btn = 0x02, .somfy_telis.cnt = 0x03}; break; + case SetTypeSomfyKeytis: + gen_info = (GenInfo){ + .type = GenSomfyKeytis, + .mod = "AM650", + .freq = 433420000, + .somfy_keytis.serial = (key & 0x0000FFFF) | 0x00D50000, + .somfy_keytis.btn = 0x04, + .somfy_keytis.cnt = 0x03}; + break; case SetTypeKingGatesStylo4k: gen_info = (GenInfo){ .type = GenKingGatesStylo4k, @@ -636,7 +645,7 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty .mod = "AM650", .freq = 433920000, .keeloq.serial = key & 0x00FFFFFF, - .keeloq.btn = 0x06, + .keeloq.btn = 0x09, .keeloq.cnt = 0x03, .keeloq.manuf = "Genius_Bravo"}; break; diff --git a/applications/main/subghz/helpers/subghz_gen_info.h b/applications/main/subghz/helpers/subghz_gen_info.h index a680b7ba5..478039c45 100644 --- a/applications/main/subghz/helpers/subghz_gen_info.h +++ b/applications/main/subghz/helpers/subghz_gen_info.h @@ -10,6 +10,7 @@ typedef enum { GenKeeloqBFT, GenAlutechAt4n, GenSomfyTelis, + GenSomfyKeytis, GenKingGatesStylo4k, GenBenincaARC, GenJarolift, @@ -64,6 +65,11 @@ typedef struct { uint8_t btn; uint16_t cnt; } somfy_telis; + struct { + uint32_t serial; + uint8_t btn; + uint16_t cnt; + } somfy_keytis; struct { uint32_t serial; uint8_t btn; diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index b477a780b..6705d9c70 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -335,6 +335,36 @@ bool subghz_txrx_gen_somfy_telis_protocol( return res; } +bool subghz_txrx_gen_somfy_keytis_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt) { + SubGhzTxRx* txrx = context; + + bool res = false; + + txrx->transmitter = + subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME); + subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); + + if(txrx->transmitter && subghz_protocol_somfy_keytis_create_data( + subghz_transmitter_get_protocol_instance(txrx->transmitter), + txrx->fff_data, + serial, + btn, + cnt, + txrx->preset)) { + res = true; + } + + subghz_transmitter_free(txrx->transmitter); + + return res; +} + bool subghz_txrx_gen_kinggates_stylo_4k_protocol( void* context, const char* preset_name, diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h index 285770975..9cd75fad7 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h @@ -108,6 +108,14 @@ bool subghz_txrx_gen_somfy_telis_protocol( uint8_t btn, uint16_t cnt); +bool subghz_txrx_gen_somfy_keytis_protocol( + void* context, + const char* preset_name, + uint32_t frequency, + uint32_t serial, + uint8_t btn, + uint16_t cnt); + bool subghz_txrx_gen_kinggates_stylo_4k_protocol( void* context, const char* preset_name, diff --git a/applications/main/subghz/scenes/subghz_scene_set_button.c b/applications/main/subghz/scenes/subghz_scene_set_button.c index d2ef60a91..9f96f03d2 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_button.c +++ b/applications/main/subghz/scenes/subghz_scene_set_button.c @@ -36,6 +36,10 @@ void subghz_scene_set_button_on_enter(void* context) { byte_ptr = &subghz->gen_info->somfy_telis.btn; byte_count = sizeof(subghz->gen_info->somfy_telis.btn); break; + case GenSomfyKeytis: + byte_ptr = &subghz->gen_info->somfy_keytis.btn; + byte_count = sizeof(subghz->gen_info->somfy_keytis.btn); + break; case GenKingGatesStylo4k: byte_ptr = &subghz->gen_info->kinggates_stylo_4k.btn; byte_count = sizeof(subghz->gen_info->kinggates_stylo_4k.btn); @@ -98,6 +102,7 @@ bool subghz_scene_set_button_on_event(void* context, SceneManagerEvent event) { case GenBenincaARC: case GenJarolift: case GenNiceFlorS: + case GenSomfyKeytis: case GenSecPlus2: scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetCounter); break; diff --git a/applications/main/subghz/scenes/subghz_scene_set_counter.c b/applications/main/subghz/scenes/subghz_scene_set_counter.c index 8510d4aca..d9ad3a42c 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_counter.c +++ b/applications/main/subghz/scenes/subghz_scene_set_counter.c @@ -42,6 +42,10 @@ void subghz_scene_set_counter_on_enter(void* context) { byte_ptr = (uint8_t*)&subghz->gen_info->somfy_telis.cnt; byte_count = sizeof(subghz->gen_info->somfy_telis.cnt); break; + case GenSomfyKeytis: + byte_ptr = (uint8_t*)&subghz->gen_info->somfy_keytis.cnt; + byte_count = sizeof(subghz->gen_info->somfy_keytis.cnt); + break; case GenKingGatesStylo4k: byte_ptr = (uint8_t*)&subghz->gen_info->kinggates_stylo_4k.cnt; byte_count = sizeof(subghz->gen_info->kinggates_stylo_4k.cnt); @@ -125,6 +129,9 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) { case GenSomfyTelis: subghz->gen_info->somfy_telis.cnt = __bswap16(subghz->gen_info->somfy_telis.cnt); break; + case GenSomfyKeytis: + subghz->gen_info->somfy_keytis.cnt = __bswap16(subghz->gen_info->somfy_keytis.cnt); + break; case GenKingGatesStylo4k: subghz->gen_info->kinggates_stylo_4k.cnt = __bswap16(subghz->gen_info->kinggates_stylo_4k.cnt); @@ -193,6 +200,15 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) { subghz->gen_info->somfy_telis.btn, subghz->gen_info->somfy_telis.cnt); break; + case GenSomfyKeytis: + generated_protocol = subghz_txrx_gen_somfy_keytis_protocol( + subghz->txrx, + subghz->gen_info->mod, + subghz->gen_info->freq, + subghz->gen_info->somfy_keytis.serial, + subghz->gen_info->somfy_keytis.btn, + subghz->gen_info->somfy_keytis.cnt); + break; case GenKingGatesStylo4k: generated_protocol = subghz_txrx_gen_kinggates_stylo_4k_protocol( subghz->txrx, diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index 36307f11f..1ba7d4c61 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -30,6 +30,7 @@ void subghz_scene_set_seed_on_enter(void* context) { case GenKeeloq: case GenAlutechAt4n: case GenSomfyTelis: + case GenSomfyKeytis: case GenKingGatesStylo4k: case GenBenincaARC: case GenJarolift: @@ -92,6 +93,7 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { case GenKeeloq: case GenAlutechAt4n: case GenSomfyTelis: + case GenSomfyKeytis: case GenKingGatesStylo4k: case GenBenincaARC: case GenJarolift: diff --git a/applications/main/subghz/scenes/subghz_scene_set_serial.c b/applications/main/subghz/scenes/subghz_scene_set_serial.c index f30b1a4a5..58fbbf026 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_serial.c +++ b/applications/main/subghz/scenes/subghz_scene_set_serial.c @@ -42,6 +42,10 @@ void subghz_scene_set_serial_on_enter(void* context) { byte_ptr = (uint8_t*)&subghz->gen_info->somfy_telis.serial; byte_count = sizeof(subghz->gen_info->somfy_telis.serial); break; + case GenSomfyKeytis: + byte_ptr = (uint8_t*)&subghz->gen_info->somfy_keytis.serial; + byte_count = sizeof(subghz->gen_info->somfy_keytis.serial); + break; case GenKingGatesStylo4k: byte_ptr = (uint8_t*)&subghz->gen_info->kinggates_stylo_4k.serial; byte_count = sizeof(subghz->gen_info->kinggates_stylo_4k.serial); @@ -122,6 +126,10 @@ bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) { subghz->gen_info->somfy_telis.serial = __bswap32(subghz->gen_info->somfy_telis.serial); break; + case GenSomfyKeytis: + subghz->gen_info->somfy_keytis.serial = + __bswap32(subghz->gen_info->somfy_keytis.serial); + break; case GenKingGatesStylo4k: subghz->gen_info->kinggates_stylo_4k.serial = __bswap32(subghz->gen_info->kinggates_stylo_4k.serial); @@ -159,6 +167,7 @@ bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) { case GenKeeloqBFT: case GenAlutechAt4n: case GenSomfyTelis: + case GenSomfyKeytis: case GenKingGatesStylo4k: case GenBenincaARC: case GenJarolift: diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 2be40602b..e696664f5 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -16,6 +16,7 @@ static const char* submenu_names[SetTypeMAX] = { [SetTypeFaacSLH_433] = "FAAC SLH 433MHz", [SetTypeBFTMitto] = "BFT Mitto 433MHz", [SetTypeSomfyTelis] = "Somfy Telis 433MHz", + [SetTypeSomfyKeytis] = "Somfy Keytis 433MHz", [SetTypeANMotorsAT4] = "AN-Motors AT4 433MHz", [SetTypeAlutechAT4N] = "Alutech AT4N 433MHz", [SetTypeRoger_433] = "Roger 433MHz", @@ -56,7 +57,7 @@ static const char* submenu_names[SetTypeMAX] = { [SetTypeCardinS449_433FM] = "KL: Cardin S449 433MHz", [SetTypeFAACRCXT_433_92] = "KL: FAAC RC,XT 433MHz", [SetTypeFAACRCXT_868] = "KL: FAAC RC,XT 868MHz", - [SetTypeGeniusBravo433] = "KL: Genius Bravo 433MHz", + [SetTypeGeniusBravo433] = "KL: Genius TX4RC 433MHz", [SetTypeNiceMHouse_433_92] = "KL: Mhouse 433MHz", [SetTypeNiceSmilo_433_92] = "KL: Nice Smilo 433MHz", [SetTypeNiceFlorS_433_92] = "Nice FloR-S 433MHz", @@ -190,6 +191,15 @@ bool subghz_scene_set_type_generate_protocol_from_infos(SubGhz* subghz) { gen_info.somfy_telis.btn, gen_info.somfy_telis.cnt); break; + case GenSomfyKeytis: + generated_protocol = subghz_txrx_gen_somfy_keytis_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.somfy_keytis.serial, + gen_info.somfy_keytis.btn, + gen_info.somfy_keytis.cnt); + break; case GenKingGatesStylo4k: generated_protocol = subghz_txrx_gen_kinggates_stylo_4k_protocol( subghz->txrx, @@ -296,6 +306,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case GenKeeloqBFT: // Serial (u32), Button (u8), Counter (u16), Seed (u32) case GenAlutechAt4n: // Serial (u32), Button (u8), Counter (u16) case GenSomfyTelis: // Serial (u32), Button (u8), Counter (u16) + case GenSomfyKeytis: // Serial (u32), Button (u8), Counter (u16) case GenKingGatesStylo4k: // Serial (u32), Button (u8), Counter (u16) case GenBenincaARC: // Serial (u32), Button (u8), Counter (u32) case GenJarolift: // Serial (u32), Button (u4), Counter (u16) diff --git a/documentation/SubGHzSupportedSystems.md b/documentation/SubGHzSupportedSystems.md index f37fb64cb..f67e01014 100644 --- a/documentation/SubGHzSupportedSystems.md +++ b/documentation/SubGHzSupportedSystems.md @@ -53,7 +53,7 @@ That list is only for default SubGHz app, apps like *Weather Station* have their - V2 Phoenix (Phox) `433.92MHz` `AM650` (52 bits, Dynamic) (receivers have option to enable Static mode, making them ignore rolling part of the key) - Marantec `433.92MHz, 868MHz` `AM650` (49 bits, Static) - Marantec24 `868MHz` `AM650` (24 bits, Static) -- Somfy Keytis `433.42MHz, 868MHz` `AM650` (80 bits, Dynamic) +- Somfy Keytis `433.42MHz, 868MHz` `AM650` (80 bits, Dynamic) (KeyGo 4 RTS 4 / Keytis NS 2RTS) - ZKTeco `430.5MHz` `AM650` (24 bits, Static - Princeton based) - (Button codes (already mapped to arrow keys): `0x30 (UP)`, `0x03 (STOP)`, `0x0C (DOWN)`) - Linear `300MHz` `AM650` (10 bits, Static) - Linear Delta3 `AM650` (8 bits, Static) diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 31a655fc6..0a4e3ca4e 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -805,6 +805,8 @@ void subghz_protocol_decoder_keeloq_reset(void* context) { // TODO instance->keystore->mfname = ""; instance->keystore->kl_type = 0; + // Reset seed? + instance->generic.seed = 0; } void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t duration) { diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index d80206281..452991f52 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -7,6 +7,8 @@ #include "../blocks/generic.h" #include "../blocks/math.h" +#include "../blocks/custom_btn_i.h" + #define TAG "SubGhzProtocolSomfyKeytis" static const SubGhzBlockConst subghz_protocol_somfy_keytis_const = { @@ -24,7 +26,6 @@ struct SubGhzProtocolDecoderSomfyKeytis { uint16_t header_count; ManchesterState manchester_saved_state; - uint32_t press_duration_counter; }; struct SubGhzProtocolEncoderSomfyKeytis { @@ -124,17 +125,49 @@ void subghz_protocol_decoder_somfy_keytis_reset(void* context) { NULL); } +static void subghz_protocol_somfy_keytis_check_remote_controller(SubGhzBlockGeneric* instance); + +static uint8_t subghz_protocol_somfy_keytis_get_btn_code(void) { + uint8_t custom_btn_id = subghz_custom_btn_get(); + uint8_t original_btn_code = subghz_custom_btn_get_original(); + uint8_t btn = original_btn_code; + + // Set custom button + if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) { + // Restore original button code + btn = original_btn_code; + } else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) { + switch(original_btn_code) { + case 0x4: + btn = 0x3; + break; + case 0x3: + btn = 0x4; + break; + + default: + break; + } + } + + return btn; +} + static bool subghz_protocol_somfy_keytis_gen_data(SubGhzProtocolEncoderSomfyKeytis* instance, uint8_t btn) { - UNUSED(btn); - uint64_t data = instance->generic.data ^ (instance->generic.data >> 8); - instance->generic.btn = (data >> 48) & 0xF; - instance->generic.cnt = (data >> 24) & 0xFFFF; - instance->generic.serial = data & 0xFFFFFF; + //instance->generic.btn = (data >> 48) & 0xF; + //instance->generic.cnt = (data >> 24) & 0xFFFF; + //instance->generic.serial = data & 0xFFFFFF; + // Save original button for later use + if(subghz_custom_btn_get_original() == 0) { + subghz_custom_btn_set_original(btn); + } + + btn = subghz_protocol_somfy_keytis_get_btn_code(); // override button if we change it with signal settings button editor - if(subghz_block_generic_global_button_override_get(&instance->generic.btn)) - FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", instance->generic.btn); + if(subghz_block_generic_global_button_override_get(&btn)) + FURI_LOG_D(TAG, "Button sucessfully changed to 0x%X", btn); // Check for OFEX (overflow experimental) mode if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { @@ -158,7 +191,7 @@ static bool } uint8_t frame[10]; - frame[0] = (0xA << 4) | instance->generic.btn; + frame[0] = (0xA << 4) | btn; frame[1] = 0xF << 4; frame[2] = instance->generic.cnt >> 8; frame[3] = instance->generic.cnt; @@ -180,7 +213,7 @@ static bool for(uint8_t i = 1; i < 7; i++) { frame[i] ^= frame[i - 1]; } - data = 0; + uint64_t data = 0; for(uint8_t i = 0; i < 7; ++i) { data <<= 8; data |= frame[i]; @@ -191,7 +224,7 @@ static bool data <<= 8; data |= frame[i]; } - instance->generic.data_2 = data; + instance->generic.seed = data; return true; } @@ -207,12 +240,25 @@ bool subghz_protocol_somfy_keytis_create_data( instance->generic.serial = serial; instance->generic.cnt = cnt; instance->generic.data_count_bit = 80; - bool res = subghz_protocol_somfy_keytis_gen_data(instance, btn); - if(res) { - return SubGhzProtocolStatusOk == - subghz_block_generic_serialize(&instance->generic, flipper_format, preset); + subghz_protocol_somfy_keytis_gen_data(instance, btn); + + // Encode complete, now serialize + SubGhzProtocolStatus res = + subghz_block_generic_serialize(&instance->generic, flipper_format, preset); + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + res = SubGhzProtocolStatusErrorParserOthers; } - return res; + + if((res == SubGhzProtocolStatusOk) && + !flipper_format_insert_or_update_uint32( + flipper_format, "Duration_Counter", &instance->generic.seed, 1)) { + FURI_LOG_E(TAG, "Unable to add Duration_Counter"); + res = SubGhzProtocolStatusErrorParserOthers; + } + + return res == SubGhzProtocolStatusOk; } /** @@ -278,7 +324,7 @@ static bool subghz_protocol_encoder_somfy_keytis_get_upload( } for(uint8_t i = 24; i > 0; i--) { - if(bit_read(instance->generic.data_2, i - 1)) { + if(bit_read(instance->generic.seed, i - 1)) { if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { instance->encoder.upload[index - 1].duration *= 2; // 00 instance->encoder.upload[index++] = level_duration_make( @@ -356,7 +402,7 @@ static bool subghz_protocol_encoder_somfy_keytis_get_upload( } for(uint8_t i = 24; i > 0; i--) { - if(bit_read(instance->generic.data_2, i - 1)) { + if(bit_read(instance->generic.seed, i - 1)) { if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { instance->encoder.upload[index - 1].duration *= 2; // 00 instance->encoder.upload[index++] = level_duration_make( @@ -422,6 +468,8 @@ SubGhzProtocolStatus flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + subghz_protocol_somfy_keytis_check_remote_controller(&instance->generic); + subghz_protocol_encoder_somfy_keytis_get_upload(instance, instance->generic.btn); if(!flipper_format_rewind(flipper_format)) { @@ -517,7 +565,7 @@ void subghz_protocol_decoder_somfy_keytis_feed(void* context, bool level, uint32 instance->decoder.parser_step = SomfyKeytisDecoderStepDecoderData; instance->decoder.decode_data = 0; instance->decoder.decode_count_bit = 0; - instance->press_duration_counter = 0; + instance->generic.seed = 0; manchester_advance( instance->manchester_saved_state, ManchesterEventReset, @@ -594,8 +642,7 @@ void subghz_protocol_decoder_somfy_keytis_feed(void* context, bool level, uint32 if(instance->decoder.decode_count_bit < 56) { instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; } else { - instance->press_duration_counter = (instance->press_duration_counter << 1) | - data; + instance->generic.seed = (instance->generic.seed << 1) | data; } instance->decoder.decode_count_bit++; @@ -713,6 +760,12 @@ static void subghz_protocol_somfy_keytis_check_remote_controller(SubGhzBlockGene instance->btn = (data >> 48) & 0xF; instance->cnt = (data >> 24) & 0xFFFF; instance->serial = data & 0xFFFFFF; + + // Save original button for later use + if(subghz_custom_btn_get_original() == 0) { + subghz_custom_btn_set_original(instance->btn); + } + subghz_custom_btn_set_max(1); } /** @@ -757,7 +810,7 @@ SubGhzProtocolStatus subghz_protocol_decoder_somfy_keytis_serialize( subghz_block_generic_serialize(&instance->generic, flipper_format, preset); if((ret == SubGhzProtocolStatusOk) && !flipper_format_write_uint32( - flipper_format, "Duration_Counter", &instance->press_duration_counter, 1)) { + flipper_format, "Duration_Counter", &instance->generic.seed, 1)) { FURI_LOG_E(TAG, "Unable to add Duration_Counter"); ret = SubGhzProtocolStatusErrorParserOthers; } @@ -783,10 +836,7 @@ SubGhzProtocolStatus break; } if(!flipper_format_read_uint32( - flipper_format, - "Duration_Counter", - (uint32_t*)&instance->press_duration_counter, - 1)) { + flipper_format, "Duration_Counter", (uint32_t*)&instance->generic.seed, 1)) { FURI_LOG_E(TAG, "Missing Duration_Counter"); ret = SubGhzProtocolStatusErrorParserOthers; break; @@ -824,7 +874,7 @@ void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), (uint32_t)instance->generic.data, - instance->press_duration_counter, + instance->generic.seed, instance->generic.serial, instance->generic.cnt, instance->generic.btn,