SubGhz: add protocol Intertechno_V3 (#1622)

* SubGhz: add decode Intertechno_V3
* SubGhz: add encoder Intertechno V3
* SubGhz: add uni_test Intertechno V3
* SubGhz: fix syntax
* SubGhz: add Intertechno V3 dimming mode
* SubGhz: fix parsing event Magellen protocol
* SubGhz: fix syntax
* SubGhz: fix encoder dimm mode

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
Skorpionm
2022-08-31 18:27:34 +04:00
committed by GitHub
parent 311b60f815
commit 0ee4573a65
8 changed files with 628 additions and 7 deletions

View File

@@ -0,0 +1,472 @@
#include "intertechno_v3.h"
#include "../blocks/const.h"
#include "../blocks/decoder.h"
#include "../blocks/encoder.h"
#include "../blocks/generic.h"
#include "../blocks/math.h"
#define TAG "SubGhzProtocolIntertechnoV3"
#define CH_PATTERN "%c%c%c%c"
#define CNT_TO_CH(ch) \
(ch & 0x8 ? '1' : '0'), (ch & 0x4 ? '1' : '0'), (ch & 0x2 ? '1' : '0'), (ch & 0x1 ? '1' : '0')
#define INTERTECHNO_V3_DIMMING_COUNT_BIT 36
static const SubGhzBlockConst subghz_protocol_intertechno_v3_const = {
.te_short = 275,
.te_long = 1375,
.te_delta = 150,
.min_count_bit_for_found = 32,
};
struct SubGhzProtocolDecoderIntertechno_V3 {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
SubGhzBlockGeneric generic;
};
struct SubGhzProtocolEncoderIntertechno_V3 {
SubGhzProtocolEncoderBase base;
SubGhzProtocolBlockEncoder encoder;
SubGhzBlockGeneric generic;
};
typedef enum {
IntertechnoV3DecoderStepReset = 0,
IntertechnoV3DecoderStepStartSync,
IntertechnoV3DecoderStepFoundSync,
IntertechnoV3DecoderStepStartDuration,
IntertechnoV3DecoderStepSaveDuration,
IntertechnoV3DecoderStepCheckDuration,
IntertechnoV3DecoderStepEndDuration,
} IntertechnoV3DecoderStep;
const SubGhzProtocolDecoder subghz_protocol_intertechno_v3_decoder = {
.alloc = subghz_protocol_decoder_intertechno_v3_alloc,
.free = subghz_protocol_decoder_intertechno_v3_free,
.feed = subghz_protocol_decoder_intertechno_v3_feed,
.reset = subghz_protocol_decoder_intertechno_v3_reset,
.get_hash_data = subghz_protocol_decoder_intertechno_v3_get_hash_data,
.serialize = subghz_protocol_decoder_intertechno_v3_serialize,
.deserialize = subghz_protocol_decoder_intertechno_v3_deserialize,
.get_string = subghz_protocol_decoder_intertechno_v3_get_string,
};
const SubGhzProtocolEncoder subghz_protocol_intertechno_v3_encoder = {
.alloc = subghz_protocol_encoder_intertechno_v3_alloc,
.free = subghz_protocol_encoder_intertechno_v3_free,
.deserialize = subghz_protocol_encoder_intertechno_v3_deserialize,
.stop = subghz_protocol_encoder_intertechno_v3_stop,
.yield = subghz_protocol_encoder_intertechno_v3_yield,
};
const SubGhzProtocol subghz_protocol_intertechno_v3 = {
.name = SUBGHZ_PROTOCOL_INTERTECHNO_V3_NAME,
.type = SubGhzProtocolTypeStatic,
.flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 |
SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load |
SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send,
.decoder = &subghz_protocol_intertechno_v3_decoder,
.encoder = &subghz_protocol_intertechno_v3_encoder,
};
void* subghz_protocol_encoder_intertechno_v3_alloc(SubGhzEnvironment* environment) {
UNUSED(environment);
SubGhzProtocolEncoderIntertechno_V3* instance =
malloc(sizeof(SubGhzProtocolEncoderIntertechno_V3));
instance->base.protocol = &subghz_protocol_intertechno_v3;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
}
void subghz_protocol_encoder_intertechno_v3_free(void* context) {
furi_assert(context);
SubGhzProtocolEncoderIntertechno_V3* instance = context;
free(instance->encoder.upload);
free(instance);
}
/**
* Generating an upload from data.
* @param instance Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
* @return true On success
*/
static bool subghz_protocol_encoder_intertechno_v3_get_upload(
SubGhzProtocolEncoderIntertechno_V3* instance) {
furi_assert(instance);
size_t index = 0;
//Send header
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short * 38);
//Send sync
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short * 10);
//Send key data
for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) {
if((instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) && (i == 9)) {
//send bit dimm
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] = level_duration_make(
false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] = level_duration_make(
false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
} else if(bit_read(instance->generic.data, i - 1)) {
//send bit 1
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_long);
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] = level_duration_make(
false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
} else {
//send bit 0
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] = level_duration_make(
false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_long);
}
}
instance->encoder.size_upload = index;
return true;
}
bool subghz_protocol_encoder_intertechno_v3_deserialize(
void* context,
FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderIntertechno_V3* instance = context;
bool res = false;
do {
if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
FURI_LOG_E(TAG, "Deserialize error");
break;
}
if((instance->generic.data_count_bit !=
subghz_protocol_intertechno_v3_const.min_count_bit_for_found) &&
(instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
FURI_LOG_E(TAG, "Wrong number of bits in key");
break;
}
//optional parameter parameter
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_intertechno_v3_get_upload(instance);
instance->encoder.is_running = true;
res = true;
} while(false);
return res;
}
void subghz_protocol_encoder_intertechno_v3_stop(void* context) {
SubGhzProtocolEncoderIntertechno_V3* instance = context;
instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_intertechno_v3_yield(void* context) {
SubGhzProtocolEncoderIntertechno_V3* instance = context;
if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
instance->encoder.is_running = false;
return level_duration_reset();
}
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
instance->encoder.front = 0;
}
return ret;
}
void* subghz_protocol_decoder_intertechno_v3_alloc(SubGhzEnvironment* environment) {
UNUSED(environment);
SubGhzProtocolDecoderIntertechno_V3* instance =
malloc(sizeof(SubGhzProtocolDecoderIntertechno_V3));
instance->base.protocol = &subghz_protocol_intertechno_v3;
instance->generic.protocol_name = instance->base.protocol->name;
return instance;
}
void subghz_protocol_decoder_intertechno_v3_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderIntertechno_V3* instance = context;
free(instance);
}
void subghz_protocol_decoder_intertechno_v3_reset(void* context) {
furi_assert(context);
SubGhzProtocolDecoderIntertechno_V3* instance = context;
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
}
void subghz_protocol_decoder_intertechno_v3_feed(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderIntertechno_V3* instance = context;
switch(instance->decoder.parser_step) {
case IntertechnoV3DecoderStepReset:
if((!level) &&
(DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short * 37) <
subghz_protocol_intertechno_v3_const.te_delta * 15)) {
instance->decoder.parser_step = IntertechnoV3DecoderStepStartSync;
}
break;
case IntertechnoV3DecoderStepStartSync:
if(level && (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta)) {
instance->decoder.parser_step = IntertechnoV3DecoderStepFoundSync;
} else {
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
}
break;
case IntertechnoV3DecoderStepFoundSync:
if(!level && (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short * 10) <
subghz_protocol_intertechno_v3_const.te_delta * 3)) {
instance->decoder.parser_step = IntertechnoV3DecoderStepStartDuration;
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
} else {
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
}
break;
case IntertechnoV3DecoderStepStartDuration:
if(level && (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta)) {
instance->decoder.parser_step = IntertechnoV3DecoderStepSaveDuration;
} else {
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
}
break;
case IntertechnoV3DecoderStepSaveDuration:
if(!level) { //save interval
if(duration >= (subghz_protocol_intertechno_v3_const.te_short * 11)) {
instance->decoder.parser_step = IntertechnoV3DecoderStepStartSync;
if((instance->decoder.decode_count_bit ==
subghz_protocol_intertechno_v3_const.min_count_bit_for_found) ||
(instance->decoder.decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
instance->generic.data = instance->decoder.decode_data;
instance->generic.data_count_bit = instance->decoder.decode_count_bit;
if(instance->base.callback)
instance->base.callback(&instance->base, instance->base.context);
}
break;
}
instance->decoder.te_last = duration;
instance->decoder.parser_step = IntertechnoV3DecoderStepCheckDuration;
} else {
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
}
break;
case IntertechnoV3DecoderStepCheckDuration:
if(level) {
//Add 0 bit
if((DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = IntertechnoV3DecoderStepEndDuration;
} else if(
//Add 1 bit
(DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_intertechno_v3_const.te_long) <
subghz_protocol_intertechno_v3_const.te_delta * 2) &&
(DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = IntertechnoV3DecoderStepEndDuration;
} else if(
//Add dimm_state
(DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta * 2) &&
(DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta) &&
(instance->decoder.decode_count_bit == 27)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = IntertechnoV3DecoderStepEndDuration;
} else
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
} else {
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
}
break;
case IntertechnoV3DecoderStepEndDuration:
if(!level && ((DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) <
subghz_protocol_intertechno_v3_const.te_delta) ||
(DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_long) <
subghz_protocol_intertechno_v3_const.te_delta * 2))) {
instance->decoder.parser_step = IntertechnoV3DecoderStepStartDuration;
} else {
instance->decoder.parser_step = IntertechnoV3DecoderStepReset;
}
break;
}
}
/**
* Analysis of received data
* @param instance Pointer to a SubGhzBlockGeneric* instance
*/
static void subghz_protocol_intertechno_v3_check_remote_controller(SubGhzBlockGeneric* instance) {
/*
* A frame is either 32 or 36 bits:
*
* _
* start bit: | |__________ (T,10T)
* _ _
* '0': | |_| |_____ (T,T,T,5T)
* _ _
* '1': | |_____| |_ (T,5T,T,T)
* _ _
* dimm: | |_| |_ (T,T,T,T)
*
* _
* stop bit: | |____...____ (T,38T)
*
* if frame 32 bits
* SSSSSSSSSSSSSSSSSSSSSSSSSS all_ch on/off ~ch
* Key:0x3F86C59F => 00111111100001101100010110 0 1 1111
*
* if frame 36 bits
* SSSSSSSSSSSSSSSSSSSSSSSSSS all_ch dimm ~ch dimm_level
* Key:0x42D2E8856 => 01000010110100101110100010 0 X 0101 0110
*
*/
if(instance->data_count_bit == subghz_protocol_intertechno_v3_const.min_count_bit_for_found) {
instance->serial = (instance->data >> 6) & 0x3FFFFFF;
if((instance->data >> 5) & 0x1) {
instance->cnt = 1 << 5;
} else {
instance->cnt = (~instance->data & 0xF);
}
instance->btn = (instance->data >> 4) & 0x1;
} else if(instance->data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) {
instance->serial = (instance->data >> 10) & 0x3FFFFFF;
if((instance->data >> 9) & 0x1) {
instance->cnt = 1 << 5;
} else {
instance->cnt = (~(instance->data >> 4) & 0xF);
}
instance->btn = (instance->data) & 0xF;
} else {
instance->serial = 0;
instance->cnt = 0;
instance->btn = 0;
}
}
uint8_t subghz_protocol_decoder_intertechno_v3_get_hash_data(void* context) {
furi_assert(context);
SubGhzProtocolDecoderIntertechno_V3* instance = context;
return subghz_protocol_blocks_get_hash_data(
&instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
}
bool subghz_protocol_decoder_intertechno_v3_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzPresetDefinition* preset) {
furi_assert(context);
SubGhzProtocolDecoderIntertechno_V3* instance = context;
return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
}
bool subghz_protocol_decoder_intertechno_v3_deserialize(
void* context,
FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderIntertechno_V3* instance = context;
bool ret = false;
do {
if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
break;
}
if((instance->generic.data_count_bit !=
subghz_protocol_intertechno_v3_const.min_count_bit_for_found) &&
(instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
FURI_LOG_E(TAG, "Wrong number of bits in key");
break;
}
ret = true;
} while(false);
return ret;
}
void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output) {
furi_assert(context);
SubGhzProtocolDecoderIntertechno_V3* instance = context;
subghz_protocol_intertechno_v3_check_remote_controller(&instance->generic);
string_cat_printf(
output,
"%.11s %db\r\n"
"Key:0x%08llX\r\n"
"Sn:%07lX\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,
instance->generic.data,
instance->generic.serial);
if(instance->generic.data_count_bit ==
subghz_protocol_intertechno_v3_const.min_count_bit_for_found) {
if(instance->generic.cnt >> 5) {
string_cat_printf(
output, "Ch: All Btn:%s\r\n", (instance->generic.btn ? "On" : "Off"));
} else {
string_cat_printf(
output,
"Ch:" CH_PATTERN " Btn:%s\r\n",
CNT_TO_CH(instance->generic.cnt),
(instance->generic.btn ? "On" : "Off"));
}
} else if(instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) {
string_cat_printf(
output,
"Ch:" CH_PATTERN " Dimm:%d%%\r\n",
CNT_TO_CH(instance->generic.cnt),
(int)(6.67 * (float)instance->generic.btn));
}
}

View File

@@ -0,0 +1,111 @@
#pragma once
#include "base.h"
#define SUBGHZ_PROTOCOL_INTERTECHNO_V3_NAME "Intertechno_V3"
typedef struct SubGhzProtocolDecoderIntertechno_V3 SubGhzProtocolDecoderIntertechno_V3;
typedef struct SubGhzProtocolEncoderIntertechno_V3 SubGhzProtocolEncoderIntertechno_V3;
extern const SubGhzProtocolDecoder subghz_protocol_intertechno_v3_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_intertechno_v3_encoder;
extern const SubGhzProtocol subghz_protocol_intertechno_v3;
/**
* Allocate SubGhzProtocolEncoderIntertechno_V3.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolEncoderIntertechno_V3* pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
*/
void* subghz_protocol_encoder_intertechno_v3_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolEncoderIntertechno_V3.
* @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
*/
void subghz_protocol_encoder_intertechno_v3_free(void* context);
/**
* Deserialize and generating an upload to send.
* @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return true On success
*/
bool subghz_protocol_encoder_intertechno_v3_deserialize(
void* context,
FlipperFormat* flipper_format);
/**
* Forced transmission stop.
* @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
*/
void subghz_protocol_encoder_intertechno_v3_stop(void* context);
/**
* Getting the level and duration of the upload to be loaded into DMA.
* @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance
* @return LevelDuration
*/
LevelDuration subghz_protocol_encoder_intertechno_v3_yield(void* context);
/**
* Allocate SubGhzProtocolDecoderIntertechno_V3.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolDecoderIntertechno_V3* pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
*/
void* subghz_protocol_decoder_intertechno_v3_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolDecoderIntertechno_V3.
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
*/
void subghz_protocol_decoder_intertechno_v3_free(void* context);
/**
* Reset decoder SubGhzProtocolDecoderIntertechno_V3.
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
*/
void subghz_protocol_decoder_intertechno_v3_reset(void* context);
/**
* Parse a raw sequence of levels and durations received from the air.
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
* @param level Signal level true-high false-low
* @param duration Duration of this level in, us
*/
void subghz_protocol_decoder_intertechno_v3_feed(void* context, bool level, uint32_t duration);
/**
* Getting the hash sum of the last randomly received parcel.
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
* @return hash Hash sum
*/
uint8_t subghz_protocol_decoder_intertechno_v3_get_hash_data(void* context);
/**
* Serialize data SubGhzProtocolDecoderIntertechno_V3.
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param preset The modulation on which the signal was received, SubGhzPresetDefinition
* @return true On success
*/
bool subghz_protocol_decoder_intertechno_v3_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzPresetDefinition* preset);
/**
* Deserialize data SubGhzProtocolDecoderIntertechno_V3.
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return true On success
*/
bool subghz_protocol_decoder_intertechno_v3_deserialize(
void* context,
FlipperFormat* flipper_format);
/**
* Getting a textual representation of the received data.
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
* @param output Resulting text
*/
void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output);

View File

@@ -360,11 +360,11 @@ static void subghz_protocol_magellen_check_remote_controller(SubGhzBlockGeneric*
* 0x1275EC => 0x12-event codes, 0x75EC-serial (dec 117236)
*
* event codes
* bit_0: 1-alarm, 0-close
* bit_0: 1-Open/Motion, 0-close/ok
* bit_1: 1-Tamper On (alarm), 0-Tamper Off (ok)
* bit_2: ?
* bit_3: 1-power on
* bit_4: model type - door alarm
* bit_4: model type - wireless reed
* bit_5: model type - motion sensor
* bit_6: ?
* bit_7: ?
@@ -379,11 +379,12 @@ static void subghz_protocol_magellen_get_event_serialize(uint8_t event, string_t
string_cat_printf(
output,
"%s%s%s%s%s%s%s%s",
(event & 0x1 ? " Alarm" : "Ok"),
((event >> 4) & 0x1 ? (event & 0x1 ? " Open" : " Close") :
(event & 0x1 ? " Motion" : " Ok")),
((event >> 1) & 0x1 ? ", Tamper On (Alarm)" : ""),
((event >> 2) & 0x1 ? ", ?" : ""),
((event >> 3) & 0x1 ? ", Power On" : ""),
((event >> 4) & 0x1 ? ", MT:Door_Alarm" : ""),
((event >> 4) & 0x1 ? ", MT:Wireless_Reed" : ""),
((event >> 5) & 0x1 ? ", MT:Motion_Sensor" : ""),
((event >> 6) & 0x1 ? ", ?" : ""),
((event >> 7) & 0x1 ? ", ?" : ""));

View File

@@ -11,7 +11,7 @@ const SubGhzProtocol* subghz_protocol_registry[] = {
&subghz_protocol_secplus_v1, &subghz_protocol_megacode, &subghz_protocol_holtek,
&subghz_protocol_chamb_code, &subghz_protocol_power_smart, &subghz_protocol_marantec,
&subghz_protocol_bett, &subghz_protocol_doitrand, &subghz_protocol_phoenix_v2,
&subghz_protocol_honeywell_wdb, &subghz_protocol_magellen,
&subghz_protocol_honeywell_wdb, &subghz_protocol_magellen, &subghz_protocol_intertechno_v3,
};

View File

@@ -34,6 +34,7 @@
#include "phoenix_v2.h"
#include "honeywell_wdb.h"
#include "magellen.h"
#include "intertechno_v3.h"
/**
* Registration by name SubGhzProtocol.