subghz somfy keytis button switch and add manually support

This commit is contained in:
MX
2026-02-22 19:44:57 +03:00
parent e681fd2be5
commit 56620ab62f
11 changed files with 150 additions and 11 deletions
@@ -70,6 +70,7 @@ typedef enum {
SetTypeFaacSLH_433,
SetTypeBFTMitto,
SetTypeSomfyTelis,
SetTypeSomfyKeytis,
SetTypeKingGatesStylo4k,
SetTypeBenincaARC,
SetTypeJarolift,
@@ -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 & 0x000FFFFF) | 0x0D500000,
.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;
@@ -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;
@@ -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,
@@ -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,
@@ -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;
@@ -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,
@@ -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:
@@ -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:
@@ -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)
+51 -9
View File
@@ -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 = {
@@ -122,17 +124,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) {
@@ -156,7 +190,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;
@@ -178,7 +212,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];
@@ -420,6 +454,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)) {
@@ -711,6 +747,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);
}
/**