mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-23 14:29:23 -05:00
SubghzD & Weather improvments (#2237)
* Weather restructure * Added Solight TE44 protocol * Add disabled Marantec24, and GangQi * More opt in subghzd
This commit is contained in:
parent
76763b9bab
commit
e6afd7744d
@ -212,7 +212,10 @@ const char* SubGhzDView::getSensorTypeName(FPROTO_SUBGHZD_SENSOR type) {
|
||||
return "Somify Keytis";
|
||||
case FPS_SOMIFY_TELIS:
|
||||
return "Somify Telis";
|
||||
|
||||
case FPS_GANGQI:
|
||||
return "GangQi";
|
||||
case FPS_MARANTEC24:
|
||||
return "Marantec24";
|
||||
case FPS_Invalid:
|
||||
default:
|
||||
return "Unknown";
|
||||
@ -717,5 +720,18 @@ void SubGhzDRecentEntryDetailView::parseProtocol() {
|
||||
serial = dataa & 0xFFFFFF; // address}
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry_.sensorType == FPS_GANGQI) {
|
||||
btn = 0; // parser needs some time i think in flipper side.
|
||||
cnt = (uint8_t)(entry_.data >> 32);
|
||||
serial = (entry_.data & 0xFFFFFFFF);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry_.sensorType == FPS_MARANTEC24) {
|
||||
serial = (entry_.data >> 4);
|
||||
btn = entry_.data & 0xf;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // namespace ui
|
@ -26,6 +26,7 @@
|
||||
#include "baseband_api.hpp"
|
||||
#include "string_format.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "../baseband/fprotos/fprotogeneral.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
using namespace ui;
|
||||
@ -138,7 +139,8 @@ void WeatherView::on_tick_second() {
|
||||
}
|
||||
|
||||
void WeatherView::on_data(const WeatherDataMessage* data) {
|
||||
WeatherRecentEntry key{data->sensorType, data->id, data->temp, data->humidity, data->channel, data->battery_low};
|
||||
WeatherRecentEntry key = process_data(data);
|
||||
// WeatherRecentEntry key{data->sensorType, data->id, data->temp, data->humidity, data->channel, data->battery_low};
|
||||
auto matching_recent = find(recent, key.key());
|
||||
if (matching_recent != std::end(recent)) {
|
||||
// Found within. Move to front of list, increment counter.
|
||||
@ -209,6 +211,8 @@ const char* WeatherView::getWeatherSensorTypeName(FPROTO_WEATHER_SENSOR type) {
|
||||
return "Acurite5in1";
|
||||
case FPW_EmosE601x:
|
||||
return "EmosE601x";
|
||||
case FPW_SolightTE44:
|
||||
return "SolightTE44";
|
||||
case FPW_Invalid:
|
||||
default:
|
||||
return "Unknown";
|
||||
@ -254,4 +258,287 @@ void RecentEntriesTable<ui::WeatherRecentEntries>::draw(
|
||||
painter.draw_string(target_rect.location(), style, line);
|
||||
}
|
||||
|
||||
#define LACROSSE_TX_MSG_TYPE_TEMP 0x00
|
||||
#define LACROSSE_TX_MSG_TYPE_HUM 0x0E
|
||||
|
||||
WeatherRecentEntry WeatherView::process_data(const WeatherDataMessage* data) {
|
||||
WeatherRecentEntry ret = {};
|
||||
ret.sensorType = data->sensorType;
|
||||
int16_t i16 = 0;
|
||||
uint16_t u16 = 0;
|
||||
uint64_t u64 = 0;
|
||||
uint8_t u8 = 0;
|
||||
uint8_t channel_3021[] = {3, 0, 2, 1};
|
||||
float flo = 0.0;
|
||||
switch (data->sensorType) {
|
||||
case FPW_NexusTH:
|
||||
ret.id = (data->decode_data >> 28) & 0xFF;
|
||||
ret.battery_low = !((data->decode_data >> 27) & 1);
|
||||
ret.channel = ((data->decode_data >> 24) & 0x03) + 1;
|
||||
if (!((data->decode_data >> 23) & 1)) {
|
||||
ret.temp = (float)((data->decode_data >> 12) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 12) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
ret.humidity = data->decode_data & 0xFF;
|
||||
if (ret.humidity > 95)
|
||||
ret.humidity = 95;
|
||||
else if (ret.humidity < 20)
|
||||
ret.humidity = 20;
|
||||
break;
|
||||
case FPW_Acurite592TXR:
|
||||
|
||||
u8 = ((data->decode_data >> 54) & 0x03);
|
||||
ret.channel = channel_3021[u8];
|
||||
ret.id = (data->decode_data >> 40) & 0x3FFF;
|
||||
ret.battery_low = !((data->decode_data >> 38) & 1);
|
||||
ret.humidity = (data->decode_data >> 24) & 0x7F;
|
||||
u16 = ((data->decode_data >> 9) & 0xF80) | ((data->decode_data >> 8) & 0x7F);
|
||||
ret.temp = ((float)(u16)-1000) / 10.0f;
|
||||
break;
|
||||
case FPW_Acurite606TX:
|
||||
ret.id = (data->decode_data >> 24) & 0xFF;
|
||||
ret.battery_low = (data->decode_data >> 23) & 1;
|
||||
if (!((data->decode_data >> 19) & 1)) {
|
||||
ret.temp = (float)((data->decode_data >> 8) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 8) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
break;
|
||||
case FPW_Acurite609TX:
|
||||
ret.id = (data->decode_data >> 32) & 0xFF;
|
||||
ret.battery_low = (data->decode_data >> 31) & 1;
|
||||
ret.channel = WS_NO_CHANNEL;
|
||||
// Temperature in Celsius is encoded as a 12 bit integer value
|
||||
// multiplied by 10 using the 4th - 6th nybbles (bytes 1 & 2)
|
||||
// negative values are recovered by sign extend from int16_t.
|
||||
i16 = (int16_t)(((data->decode_data >> 12) & 0xf000) | ((data->decode_data >> 16) << 4));
|
||||
ret.temp = (i16 >> 4) * 0.1f;
|
||||
ret.humidity = (data->decode_data >> 8) & 0xff;
|
||||
break;
|
||||
case FPW_Ambient:
|
||||
id = (data->decode_data >> 32) & 0xFF;
|
||||
ret.battery_low = (data->decode_data >> 31) & 1;
|
||||
ret.channel = ((data->decode_data >> 28) & 0x07) + 1;
|
||||
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data->decode_data >> 16) & 0x0FFF) - 400.0f) / 10.0f);
|
||||
ret.humidity = (data->decode_data >> 8) & 0xFF;
|
||||
break;
|
||||
case FPW_AuriolAhfl:
|
||||
ret.id = data->decode_data >> 34;
|
||||
ret.battery_low = (data->decode_data >> 33) & 1;
|
||||
// btn = (data >> 32) & 1;
|
||||
ret.channel = ((data->decode_data >> 30) & 0x3) + 1;
|
||||
if (!((data->decode_data >> 29) & 1)) {
|
||||
ret.temp = (float)((data->decode_data >> 18) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 18) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
ret.humidity = (data->decode_data >> 11) & 0x7F;
|
||||
break;
|
||||
case FPW_AuriolTH:
|
||||
ret.id = (data->decode_data >> 31) & 0xFF;
|
||||
ret.battery_low = ((data->decode_data >> 30) & 1);
|
||||
ret.channel = ((data->decode_data >> 25) & 0x03) + 1;
|
||||
if (!((data->decode_data >> 23) & 1)) {
|
||||
ret.temp = (float)((data->decode_data >> 13) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 13) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
ret.humidity = (data->decode_data >> 1) & 0x7F;
|
||||
break;
|
||||
case FPW_GTWT02:
|
||||
ret.id = (data->decode_data >> 29) & 0xFF;
|
||||
ret.battery_low = (data->decode_data >> 28) & 1;
|
||||
// btn = (data->decode_data >> 27) & 1;
|
||||
ret.channel = ((data->decode_data >> 25) & 0x3) + 1;
|
||||
|
||||
if (!((data->decode_data >> 24) & 1)) {
|
||||
ret.temp = (float)((data->decode_data >> 13) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 13) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
ret.humidity = (data->decode_data >> 6) & 0x7F;
|
||||
if (ret.humidity <= 10) // actually the sensors sends 10 below working range of 20%
|
||||
ret.humidity = 0;
|
||||
else if (ret.humidity > 90) // actually the sensors sends 110 above working range of 90%
|
||||
ret.humidity = 100;
|
||||
break;
|
||||
case FPW_GTWT03:
|
||||
ret.id = data->decode_data >> 33;
|
||||
ret.humidity = (data->decode_data >> 25) & 0xFF;
|
||||
if (ret.humidity <= 10) { // actually the sensors sends 10 below working range of 20%
|
||||
ret.humidity = 0;
|
||||
} else if (ret.humidity > 95) { // actually the sensors sends 110 above working range of 90%
|
||||
ret.humidity = 100;
|
||||
}
|
||||
ret.battery_low = (data->decode_data >> 24) & 1;
|
||||
// (data->decode_data >> 23) & 1;
|
||||
ret.channel = ((data->decode_data >> 21) & 0x03) + 1;
|
||||
if (!((data->decode_data >> 20) & 1)) {
|
||||
ret.temp = (float)((data->decode_data >> 9) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 9) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
break;
|
||||
case FPW_INFACTORY:
|
||||
ret.id = data->decode_data >> 32;
|
||||
ret.battery_low = (data->decode_data >> 26) & 1;
|
||||
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data->decode_data >> 12) & 0x0FFF) - 900.0f) / 10.0f);
|
||||
ret.humidity = (((data->decode_data >> 8) & 0x0F) * 10) + ((data->decode_data >> 4) & 0x0F); // BCD, 'A0'=100%rH
|
||||
ret.channel = data->decode_data & 0x03;
|
||||
break;
|
||||
case FPW_LACROSSETX:
|
||||
u8 = (data->decode_data >> 32) & 0x0F;
|
||||
ret.id = (((data->decode_data >> 28) & 0x0F) << 3) | (((data->decode_data >> 24) & 0x0F) >> 1);
|
||||
flo = (float)((data->decode_data >> 20) & 0x0F) * 10.0f + (float)((data->decode_data >> 16) & 0x0F) + (float)((data->decode_data >> 12) & 0x0F) * 0.1f;
|
||||
if (u8 == LACROSSE_TX_MSG_TYPE_TEMP) { //-V1051
|
||||
ret.temp = flo - 50.0f;
|
||||
ret.humidity = WS_NO_HUMIDITY;
|
||||
} else if (u8 == LACROSSE_TX_MSG_TYPE_HUM) {
|
||||
// ToDo for verification, records are needed with sensors maintaining temperature and temperature for this standard
|
||||
ret.humidity = (uint8_t)flo;
|
||||
}
|
||||
break;
|
||||
case FPW_LACROSSETX141thbv2:
|
||||
ret.id = data->decode_data >> 32;
|
||||
ret.battery_low = (data->decode_data >> 31) & 1;
|
||||
// btn = (data->decode_data >> 30) & 1;
|
||||
ret.channel = ((data->decode_data >> 28) & 0x03) + 1;
|
||||
ret.temp = ((float)((data->decode_data >> 16) & 0x0FFF) - 500.0f) / 10.0f;
|
||||
ret.humidity = (data->decode_data >> 8) & 0xFF;
|
||||
break;
|
||||
case FPW_OREGON2:
|
||||
i16 = ((data->decode_data >> 4) & 0xF) * 10 + (((data->decode_data >> 4) >> 4) & 0xF);
|
||||
i16 *= 10;
|
||||
i16 += (data->decode_data >> 12) & 0xF;
|
||||
if (data->decode_data & 0xF) i16 = -i16;
|
||||
ret.temp = (float)i16 / 10.0;
|
||||
// todo fix missing parts.
|
||||
break;
|
||||
case FPW_OREGON3:
|
||||
// todo check
|
||||
ret.humidity = ((data->decode_data >> 4) & 0xF) * 10 + (((data->decode_data >> 4) >> 4) & 0xF);
|
||||
i16 = (((data->decode_data >> 12) >> 4) & 0xF) * 10 + ((((data->decode_data >> 12) >> 4) >> 4) & 0xF); // ws_oregon3_bcd_decode_short((data->decode_data >> 12) >> 4);
|
||||
i16 *= 10;
|
||||
i16 += ((data->decode_data >> 12) >> 12) & 0xF;
|
||||
if ((data->decode_data >> 12) & 0xF) i16 = -i16;
|
||||
ret.temp = (float)i16 / 10.0;
|
||||
break;
|
||||
case FPW_OREGONv1:
|
||||
u64 = FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data, 32);
|
||||
id = u64 & 0xFF;
|
||||
ret.channel = ((u64 >> 6) & 0x03) + 1;
|
||||
ret.temp = ((u64 >> 8) & 0x0F) * 0.1f + ((u64 >> 12) & 0x0F) + ((u64 >> 16) & 0x0F) * 10.0f;
|
||||
if (!((u64 >> 21) & 1)) {
|
||||
ret.temp = ret.temp;
|
||||
} else {
|
||||
ret.temp = -ret.temp;
|
||||
}
|
||||
ret.battery_low = !((u64 >> 23) & 1ULL);
|
||||
break;
|
||||
case FPW_THERMOPROTX4:
|
||||
ret.id = (data->decode_data >> 25) & 0xFF;
|
||||
ret.battery_low = (data->decode_data >> 24) & 1;
|
||||
// btn = (data->decode_data >> 23) & 1;
|
||||
ret.channel = ((data->decode_data >> 21) & 0x03) + 1;
|
||||
if (!((data->decode_data >> 20) & 1)) {
|
||||
ret.temp = (float)((data->decode_data >> 9) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 9) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
ret.humidity = (data->decode_data >> 1) & 0xFF;
|
||||
break;
|
||||
case FPW_TX_8300:
|
||||
ret.humidity = (((data->decode_data >> 28) & 0x0F) * 10) + ((data->decode_data >> 24) & 0x0F);
|
||||
if (!((data->decode_data >> 22) & 0x03))
|
||||
ret.battery_low = 0;
|
||||
else
|
||||
ret.battery_low = 1;
|
||||
ret.channel = (data->decode_data >> 20) & 0x03;
|
||||
ret.id = (data->decode_data >> 12) & 0x7F;
|
||||
ret.temp = ((data->decode_data >> 8) & 0x0F) * 10.0f + ((data->decode_data >> 4) & 0x0F) +
|
||||
(data->decode_data & 0x0F) * 0.1f;
|
||||
if (!((data->decode_data >> 19) & 1)) {
|
||||
ret.temp = ret.temp;
|
||||
} else {
|
||||
ret.temp = -ret.temp;
|
||||
}
|
||||
break;
|
||||
case FPW_WENDOX_W6726:
|
||||
ret.id = (data->decode_data >> 24) & 0xFF;
|
||||
ret.battery_low = (data->decode_data >> 6) & 1;
|
||||
if (((data->decode_data >> 23) & 1)) {
|
||||
ret.temp = (float)(((data->decode_data >> 14) & 0x1FF) + 12) / 10.0f;
|
||||
} else {
|
||||
ret.temp = (float)((~(data->decode_data >> 14) & 0x1FF) + 1 - 12) / -10.0f;
|
||||
}
|
||||
if (ret.temp < -50.0f) {
|
||||
ret.temp = -50.0f;
|
||||
} else if (ret.temp > 70.0f) {
|
||||
ret.temp = 70.0f;
|
||||
}
|
||||
break;
|
||||
case FPW_Acurite986:
|
||||
ret.id = FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data >> 24, 8);
|
||||
ret.id = (id << 8) | FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data >> 16, 8);
|
||||
ret.battery_low = (data->decode_data >> 14) & 1;
|
||||
ret.channel = ((data->decode_data >> 15) & 1) + 1;
|
||||
i16 = FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data >> 32, 8);
|
||||
if (i16 & 0x80) {
|
||||
i16 = -(i16 & 0x7F);
|
||||
}
|
||||
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius((float)i16);
|
||||
break;
|
||||
case FPW_KEDSUM:
|
||||
ret.id = data->decode_data >> 32;
|
||||
if ((data->decode_data >> 30) & 0x3) {
|
||||
ret.battery_low = 0;
|
||||
} else {
|
||||
ret.battery_low = 1;
|
||||
}
|
||||
ret.channel = ((data->decode_data >> 28) & 0x3) + 1;
|
||||
u16 = ((data->decode_data >> 16) & 0x0f) << 8 | ((data->decode_data >> 20) & 0x0f) << 4 | ((data->decode_data >> 24) & 0x0f);
|
||||
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)u16 - 900.0f) / 10.0f);
|
||||
ret.humidity = ((data->decode_data >> 8) & 0x0f) << 4 | ((data->decode_data >> 12) & 0x0f);
|
||||
break;
|
||||
case FPW_Acurite5in1:
|
||||
u8 = ((data->decode_data >> 62) & 0x03);
|
||||
ret.channel = channel_3021[u8];
|
||||
ret.id = (data->decode_data >> 48) & 0x3FFF;
|
||||
ret.battery_low = !((data->decode_data >> 46) & 1);
|
||||
ret.humidity = (data->decode_data >> 8) & 0x7F;
|
||||
u16 = ((data->decode_data >> (24 - 7)) & 0x780) | ((data->decode_data >> 16) & 0x7F);
|
||||
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)(u16)-400) / 10.0f);
|
||||
break;
|
||||
case FPW_EmosE601x:
|
||||
ret.id = 0xffff; //(upper_decode_data >> 24) & 0xff; //todo maybe with oregon, and +64bit usage/message
|
||||
ret.battery_low = (data->decode_data >> 10) & 1;
|
||||
i16 = (data->decode_data >> 40) & 0xfff;
|
||||
/* Handle signed data */
|
||||
if (i16 & 0x800) {
|
||||
i16 |= 0xf000;
|
||||
}
|
||||
ret.temp = (float)i16 / 10.0;
|
||||
ret.humidity = (data->decode_data >> 32) & 0xff;
|
||||
ret.channel = (data->decode_data >> 52) & 0x03;
|
||||
break;
|
||||
case FPW_SolightTE44:
|
||||
ret.id = (data->decode_data >> 28) & 0xff;
|
||||
ret.battery_low = !(data->decode_data >> 27) & 0x01;
|
||||
ret.channel = ((data->decode_data >> 24) & 0x03) + 1;
|
||||
i16 = (data->decode_data >> 12) & 0x0fff;
|
||||
/* Handle signed data */
|
||||
if (i16 & 0x0800) {
|
||||
i16 |= 0xf000;
|
||||
}
|
||||
ret.temp = (float)i16 / 10.0;
|
||||
break;
|
||||
case FPW_Invalid:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -96,7 +96,7 @@ class WeatherView : public View {
|
||||
private:
|
||||
void on_tick_second();
|
||||
void on_data(const WeatherDataMessage* data);
|
||||
|
||||
WeatherRecentEntry process_data(const WeatherDataMessage* data);
|
||||
NavigationView& nav_;
|
||||
RxRadioState radio_state_{
|
||||
433'920'000 /* frequency */,
|
||||
|
@ -36,7 +36,6 @@ class FProtoSubGhzDBett : public FProtoSubGhzDBase {
|
||||
(te_delta * 15)) {
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
// dip decoder needed
|
||||
if (callback) callback(this);
|
||||
|
@ -53,7 +53,6 @@ class FProtoSubGhzDCame : public FProtoSubGhzDBase {
|
||||
parser_step = CameDecoderStepFoundStartBit;
|
||||
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == AIRFORCE_COUNT_BIT) ||
|
||||
(decode_count_bit == PRASTEL_COUNT_BIT) || (decode_count_bit == CAME_24_COUNT_BIT)) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
// if flippa hacky, i hacky
|
||||
sensorType = FPS_CAME;
|
||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDCameAtomo : public FProtoSubGhzDBase {
|
||||
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDCameTwee : public FProtoSubGhzDBase {
|
||||
} else if (
|
||||
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ class FProtoSubGhzDChambCode : public FProtoSubGhzDBase {
|
||||
if (duration > te_short * 5) {
|
||||
if (decode_count_bit >= min_count_bit_for_found) {
|
||||
if (subghz_protocol_decoder_chamb_code_check_mask_and_parse()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -62,7 +62,6 @@ class FProtoSubGhzDClemsa : public FProtoSubGhzDBase {
|
||||
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ class FProtoSubGhzDDoitrand : public FProtoSubGhzDBase {
|
||||
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
||||
parser_step = DoitrandDecoderStepFoundStartBit;
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ class FProtoSubGhzDDooya : public FProtoSubGhzDBase {
|
||||
parser_step = DooyaDecoderStepFoundStartBit;
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDFaac : public FProtoSubGhzDBase {
|
||||
if (duration >= ((uint32_t)te_short * 3 + te_delta)) {
|
||||
parser_step = FaacSLHDecoderStepFoundPreambula;
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
// remark controller skipped
|
||||
if (callback) callback(this);
|
||||
|
86
firmware/baseband/fprotos/s-gangqi.hpp
Normal file
86
firmware/baseband/fprotos/s-gangqi.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
#ifndef __FPROTO_GANGQI_H__
|
||||
#define __FPROTO_GANGQI_H__
|
||||
|
||||
#include "subghzdbase.hpp"
|
||||
|
||||
typedef enum {
|
||||
GangQiDecoderStepReset = 0,
|
||||
GangQiDecoderStepSaveDuration,
|
||||
GangQiDecoderStepCheckDuration,
|
||||
} GangQiDecoderStep;
|
||||
|
||||
class FProtoSubGhzDGangqi : public FProtoSubGhzDBase {
|
||||
public:
|
||||
FProtoSubGhzDGangqi() {
|
||||
sensorType = FPS_GANGQI;
|
||||
te_short = 500;
|
||||
te_long = 1200;
|
||||
te_delta = 200;
|
||||
min_count_bit_for_found = 34;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) {
|
||||
switch (parser_step) {
|
||||
case GangQiDecoderStepReset:
|
||||
if ((!level) && (DURATION_DIFF(duration, te_long * 2) < te_delta * 3)) {
|
||||
// Found GAP
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = GangQiDecoderStepSaveDuration;
|
||||
}
|
||||
break;
|
||||
case GangQiDecoderStepSaveDuration:
|
||||
if (level) {
|
||||
te_last = duration;
|
||||
parser_step = GangQiDecoderStepCheckDuration;
|
||||
} else {
|
||||
parser_step = GangQiDecoderStepReset;
|
||||
}
|
||||
break;
|
||||
case GangQiDecoderStepCheckDuration:
|
||||
if (!level) {
|
||||
// Bit 0 is short and long timing
|
||||
if ((DURATION_DIFF(te_last, te_short) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_long) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
parser_step = GangQiDecoderStepSaveDuration;
|
||||
// Bit 1 is long and short timing
|
||||
} else if (
|
||||
(DURATION_DIFF(te_last, te_long) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_short) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
parser_step = GangQiDecoderStepSaveDuration;
|
||||
} else if (
|
||||
// End of the key
|
||||
DURATION_DIFF(duration, te_short * 4) <
|
||||
te_delta) {
|
||||
// Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes)
|
||||
if ((DURATION_DIFF(te_last, te_short) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_short * 4) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
}
|
||||
if ((DURATION_DIFF(te_last, te_long) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_short * 4) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
}
|
||||
// If got 34 bits key reading is finished
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = GangQiDecoderStepReset;
|
||||
} else {
|
||||
parser_step = GangQiDecoderStepReset;
|
||||
}
|
||||
} else {
|
||||
parser_step = GangQiDecoderStepReset;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -44,7 +44,6 @@ class FProtoSubGhzDGateTx : public FProtoSubGhzDBase {
|
||||
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
||||
parser_step = GateTXDecoderStepFoundStartBit;
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ class FProtoSubGhzDHoltek : public FProtoSubGhzDBase {
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
if ((decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -44,11 +44,8 @@ class FProtoSubGhzDHoltekHt12x : public FProtoSubGhzDBase {
|
||||
if (!level) {
|
||||
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
if (data != decode_data) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
|
@ -71,7 +71,6 @@ class FProtoSubGhzDHoneywell : public FProtoSubGhzDBase {
|
||||
uint16_t crc = decode_data & 0xFFFF;
|
||||
if (crc == crc_calc) {
|
||||
// the data is good. process it.
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit; // maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it
|
||||
if (callback) callback(this);
|
||||
decode_data = 0;
|
||||
|
@ -36,7 +36,6 @@ class FProtoSubGhzDHoneywellWdb : public FProtoSubGhzDBase {
|
||||
if (DURATION_DIFF(duration, te_short * 3) < te_delta) {
|
||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||
((decode_data & 0x01) == FProtoGeneral::subghz_protocol_blocks_get_parity(decode_data >> 1, min_count_bit_for_found - 1))) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
// controller has too much, should be done on ui side
|
||||
if (callback) callback(this);
|
||||
|
@ -47,7 +47,6 @@ class FProtoSubGhzDHormann : public FProtoSubGhzDBase {
|
||||
parser_step = HormannDecoderStepFoundStartBit;
|
||||
if (decode_count_bit >=
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ class FProtoSubGhzDHormannBiSecure : public FProtoSubGhzDBase {
|
||||
|
||||
void subghz_protocol_decoder_hormann_bisecur_reset() {
|
||||
parser_step = HormannBiSecurDecoderStepReset;
|
||||
data = 0;
|
||||
for (uint8_t i = 0; i < 22; ++i) dataa[i] = 0;
|
||||
data_count_bit = 0;
|
||||
manchester_saved_state = ManchesterStateStart1;
|
||||
|
@ -44,7 +44,6 @@ class FProtoSubGhzDIdo : public FProtoSubGhzDBase {
|
||||
parser_step = IDoDecoderStepFoundPreambula;
|
||||
if (decode_count_bit >=
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -66,7 +66,6 @@ class FProtoSubGhzDIntertechnoV3 : public FProtoSubGhzDBase {
|
||||
parser_step = IntertechnoV3DecoderStepStartSync;
|
||||
if ((decode_count_bit == min_count_bit_for_found) ||
|
||||
(decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -57,11 +57,8 @@ class FProtoSubGhzDKeeLoq : public FProtoSubGhzDBase {
|
||||
parser_step = KeeloqDecoderStepReset;
|
||||
if ((decode_count_bit >= min_count_bit_for_found) &&
|
||||
(decode_count_bit <= min_count_bit_for_found + 2)) {
|
||||
if (data != decode_data) {
|
||||
data = decode_data;
|
||||
data_count_bit = min_count_bit_for_found;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
data_count_bit = min_count_bit_for_found;
|
||||
if (callback) callback(this);
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
header_count = 0;
|
||||
@ -96,6 +93,8 @@ class FProtoSubGhzDKeeLoq : public FProtoSubGhzDBase {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -50,7 +50,8 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
||||
DURATION_DIFF(duration, te_short * 2) < te_delta * 2) {
|
||||
parser_step = KingGates_stylo_4kDecoderStepSaveDuration;
|
||||
decode_data = 0;
|
||||
data_2 = 0;
|
||||
// data_2 = 0;
|
||||
// data = 0;
|
||||
decode_count_bit = 0;
|
||||
header_count = 0;
|
||||
}
|
||||
@ -58,17 +59,17 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
||||
case KingGates_stylo_4kDecoderStepSaveDuration:
|
||||
if (!level) {
|
||||
if (duration >= ((uint32_t)te_long * 3)) {
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
data = data_2;
|
||||
data_2 = decode_data; // TODO DATA2
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
// data = data_2;
|
||||
// data_2 = decode_data; // TODO DATA2
|
||||
data_count_bit = decode_count_bit;
|
||||
// decode_data = data;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
||||
parser_step = KingGates_stylo_4kDecoderStepReset;
|
||||
decode_data = 0;
|
||||
data_2 = 0;
|
||||
// data_2 = 0;
|
||||
decode_count_bit = 0;
|
||||
header_count = 0;
|
||||
break;
|
||||
@ -101,7 +102,7 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
||||
header_count = 0;
|
||||
}
|
||||
if (decode_count_bit == 53) {
|
||||
data_2 = decode_data;
|
||||
// data_2 = decode_data;
|
||||
decode_data = 0;
|
||||
}
|
||||
} else {
|
||||
@ -113,7 +114,9 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
||||
}
|
||||
|
||||
protected:
|
||||
uint64_t data_2 = 0;
|
||||
// uint64_t data_2 = 0;
|
||||
// uint64_t data = 0;
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -79,23 +79,17 @@ class FProtoSubGhzDLegrand : public FProtoSubGhzDBase {
|
||||
if (found) {
|
||||
te += duration;
|
||||
|
||||
if (decode_count_bit <
|
||||
min_count_bit_for_found) {
|
||||
if (decode_count_bit < min_count_bit_for_found) {
|
||||
parser_step = LegrandDecoderStepSaveDuration;
|
||||
break;
|
||||
}
|
||||
|
||||
// enough bits for a packet found, save it only if there was a previous packet
|
||||
// with the same data
|
||||
if (data && (data != decode_data)) {
|
||||
te /= decode_count_bit * 4;
|
||||
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
te /= decode_count_bit * 4;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
// fallthrough to reset, the next bit is expected to be a sync
|
||||
// it also takes care of resetting the decoder state
|
||||
|
@ -54,7 +54,6 @@ class FProtoSubGhzDLinear : public FProtoSubGhzDBase {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
}
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -49,11 +49,8 @@ class FProtoSubGhzDLinearDelta3 : public FProtoSubGhzDBase {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
}
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
if ((data == decode_data) && data) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
parser_step = LinearD3DecoderStepSaveDuration;
|
||||
}
|
||||
break;
|
||||
|
@ -90,7 +90,6 @@ class FProtoSubGhzDMagellan : public FProtoSubGhzDBase {
|
||||
// Found stop bit
|
||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||
subghz_protocol_magellan_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
@ -129,6 +128,7 @@ class FProtoSubGhzDMagellan : public FProtoSubGhzDBase {
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDMarantec : public FProtoSubGhzDBase {
|
||||
} else if (
|
||||
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
93
firmware/baseband/fprotos/s-marantec24.hpp
Normal file
93
firmware/baseband/fprotos/s-marantec24.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
#ifndef __FPROTO_MARANTEC24_H__
|
||||
#define __FPROTO_MARANTEC24_H__
|
||||
|
||||
#include "subghzdbase.hpp"
|
||||
|
||||
typedef enum {
|
||||
Marantec24DecoderStepReset = 0,
|
||||
Marantec24DecoderStepSaveDuration,
|
||||
Marantec24DecoderStepCheckDuration,
|
||||
} Marantec24DecoderStep;
|
||||
|
||||
class FProtoSubGhzDMarantec24 : public FProtoSubGhzDBase {
|
||||
public:
|
||||
FProtoSubGhzDMarantec24() {
|
||||
sensorType = FPS_MARANTEC24;
|
||||
te_short = 800;
|
||||
te_long = 1600;
|
||||
te_delta = 200;
|
||||
min_count_bit_for_found = 24;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) {
|
||||
// Key samples
|
||||
// 101011000000010111001000 = AC05C8
|
||||
// 101011000000010111000100 = AC05C4
|
||||
// 101011000000010111001100 = AC05CC
|
||||
// 101011000000010111000000 = AC05C0
|
||||
|
||||
switch (parser_step) {
|
||||
case Marantec24DecoderStepReset:
|
||||
if ((!level) && (DURATION_DIFF(duration, te_long * 9) < te_delta * 4)) {
|
||||
// Found GAP
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = Marantec24DecoderStepSaveDuration;
|
||||
}
|
||||
break;
|
||||
case Marantec24DecoderStepSaveDuration:
|
||||
if (level) {
|
||||
te_last = duration;
|
||||
parser_step = Marantec24DecoderStepCheckDuration;
|
||||
} else {
|
||||
parser_step = Marantec24DecoderStepReset;
|
||||
}
|
||||
break;
|
||||
case Marantec24DecoderStepCheckDuration:
|
||||
if (!level) {
|
||||
// Bit 0 is long and short x2 timing = 1600us HIGH (te_last) and 2400us LOW
|
||||
if ((DURATION_DIFF(te_last, te_long) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_short * 3) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
parser_step = Marantec24DecoderStepSaveDuration;
|
||||
// Bit 1 is short and long x2 timing = 800us HIGH (te_last) and 3200us LOW
|
||||
} else if (
|
||||
(DURATION_DIFF(te_last, te_short) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_long * 2) < te_delta)) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
parser_step = Marantec24DecoderStepSaveDuration;
|
||||
} else if (
|
||||
// End of the key
|
||||
DURATION_DIFF(duration, te_long * 9) < te_delta * 4) {
|
||||
// Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes)
|
||||
if ((DURATION_DIFF(te_last, te_long) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_long * 9) < te_delta * 4)) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
}
|
||||
if ((DURATION_DIFF(te_last, te_short) < te_delta) &&
|
||||
(DURATION_DIFF(duration, te_long * 9) < te_delta * 4)) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
}
|
||||
// If got 24 bits key reading is finished
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = Marantec24DecoderStepReset;
|
||||
} else {
|
||||
parser_step = Marantec24DecoderStepReset;
|
||||
}
|
||||
} else {
|
||||
parser_step = Marantec24DecoderStepReset;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif
|
@ -61,7 +61,6 @@ class FProtoSubGhzDMastercode : public FProtoSubGhzDBase {
|
||||
}
|
||||
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) callback(this);
|
||||
|
@ -48,7 +48,6 @@ class FProtoSubGhzDMegacode : public FProtoSubGhzDBase {
|
||||
parser_step = MegaCodeDecoderStepReset;
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) callback(this);
|
||||
|
@ -67,7 +67,6 @@ class FProtoSubGhzDNeroSketch : public FProtoSubGhzDBase {
|
||||
// Found stop bit
|
||||
parser_step = NeroSketchDecoderStepReset;
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
@ -103,6 +102,7 @@ class FProtoSubGhzDNeroSketch : public FProtoSubGhzDBase {
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -82,7 +82,6 @@ class FProtoSubGhzDNeroRadio : public FProtoSubGhzDBase {
|
||||
parser_step = NeroRadioDecoderStepReset;
|
||||
if ((decode_count_bit == min_count_bit_for_found) ||
|
||||
(decode_count_bit == min_count_bit_for_found + 1)) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) callback(this);
|
||||
@ -110,6 +109,7 @@ class FProtoSubGhzDNeroRadio : public FProtoSubGhzDBase {
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -47,7 +47,6 @@ class FProtoSubGhzDNiceflo : public FProtoSubGhzDBase {
|
||||
if (duration >= (te_short * 4)) {
|
||||
parser_step = NiceFloDecoderStepFoundStartBit;
|
||||
if (decode_count_bit >= min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -56,10 +56,9 @@ class FProtoSubGhzDNiceflors : public FProtoSubGhzDBase {
|
||||
// Found STOP bit
|
||||
parser_step = NiceFlorSDecoderStepReset;
|
||||
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == NICE_ONE_COUNT_BIT)) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) callback(this);
|
||||
decode_data = 0;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
@ -86,8 +85,8 @@ class FProtoSubGhzDNiceflors : public FProtoSubGhzDBase {
|
||||
parser_step = NiceFlorSDecoderStepReset;
|
||||
}
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
decode_data = 0;
|
||||
// data = decode_data;
|
||||
// decode_data = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ class FProtoSubGhzDPhoenixV2 : public FProtoSubGhzDBase {
|
||||
parser_step = Phoenix_V2DecoderStepFoundStartBit;
|
||||
if (decode_count_bit ==
|
||||
min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ class FProtoSubGhzDPowerSmart : public FProtoSubGhzDBase {
|
||||
}
|
||||
if ((decode_data & POWER_SMART_PACKET_HEADER_MASK) == POWER_SMART_PACKET_HEADER) {
|
||||
if (subghz_protocol_power_smart_chek_valid(decode_data)) {
|
||||
data = decode_data;
|
||||
data_count_bit = min_count_bit_for_found;
|
||||
|
||||
if (callback) callback(this);
|
||||
|
@ -42,7 +42,6 @@ class FProtoSubGhzDPrinceton : public FProtoSubGhzDBase {
|
||||
if (duration >= ((uint32_t)te_long * 2)) {
|
||||
parser_step = PrincetonDecoderStepSaveDuration;
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ class FProtoSubGhzDSecPlusV2 : public FProtoSubGhzDBase {
|
||||
} else if (
|
||||
duration >= (te_long * 2UL + te_delta)) {
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (subghz_protocol_secplus_v2_check_packet()) {
|
||||
// controller too big
|
||||
|
@ -42,7 +42,6 @@ class FProtoSubGhzDSmc5326 : public FProtoSubGhzDBase {
|
||||
if (duration >= ((uint32_t)te_long * 2)) {
|
||||
parser_step = SMC5326DecoderStepSaveDuration;
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
@ -68,11 +68,9 @@ class FProtoSubGhzDSomifyKeytis : public FProtoSubGhzDBase {
|
||||
duration >= (te_long + te_delta)) {
|
||||
if (decode_count_bit == min_count_bit_for_found) {
|
||||
// check crc
|
||||
uint64_t data_tmp = data ^ (data >> 8);
|
||||
uint64_t data_tmp = decode_data ^ (decode_data >> 8);
|
||||
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_keytis_crc(data_tmp)) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) callback(this);
|
||||
}
|
||||
}
|
||||
@ -124,6 +122,8 @@ class FProtoSubGhzDSomifyKeytis : public FProtoSubGhzDBase {
|
||||
}
|
||||
return crc & 0xf;
|
||||
}
|
||||
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -71,7 +71,6 @@ class FProtoSubGhzDSomifyTelis : public FProtoSubGhzDBase {
|
||||
// check crc
|
||||
uint64_t data_tmp = decode_data ^ (decode_data >> 8);
|
||||
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_telis_crc(data_tmp)) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) callback(this);
|
||||
@ -118,6 +117,7 @@ class FProtoSubGhzDSomifyTelis : public FProtoSubGhzDBase {
|
||||
}
|
||||
return crc & 0xf;
|
||||
}
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -53,11 +53,8 @@ class FProtoSubGhzDStarLine : public FProtoSubGhzDBase {
|
||||
parser_step = StarLineDecoderStepReset;
|
||||
if ((decode_count_bit >= min_count_bit_for_found) &&
|
||||
(decode_count_bit <= min_count_bit_for_found + 2)) {
|
||||
if (data != decode_data) {
|
||||
data = decode_data;
|
||||
data_count_bit = min_count_bit_for_found;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
data_count_bit = min_count_bit_for_found;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
@ -101,6 +98,7 @@ class FProtoSubGhzDStarLine : public FProtoSubGhzDBase {
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint16_t header_count = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -47,7 +47,6 @@ class FProtoSubGhzDX10 : public FProtoSubGhzDBase {
|
||||
if (decode_count_bit >= min_count_bit_for_found &&
|
||||
((((decode_data >> 24) ^ (decode_data >> 16)) & 0xFF) == 0xFF) &&
|
||||
((((decode_data >> 8) ^ (decode_data)) & 0xFF) == 0xFF)) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
|
||||
if (callback) callback(this);
|
||||
|
@ -26,7 +26,7 @@ class FProtoSubGhzDBase {
|
||||
// General data holder, these will be passed
|
||||
uint8_t sensorType = FPS_Invalid;
|
||||
uint16_t data_count_bit = 0;
|
||||
uint64_t data = 0;
|
||||
uint64_t decode_data = 0;
|
||||
|
||||
protected:
|
||||
// Helper functions to keep it as compatible with flipper as we can, so adding new protos will be easy.
|
||||
@ -42,11 +42,11 @@ class FProtoSubGhzDBase {
|
||||
uint32_t min_count_bit_for_found = UINT32_MAX;
|
||||
|
||||
SubGhzDProtocolDecoderBaseRxCallback callback = NULL;
|
||||
uint16_t header_count = 0;
|
||||
|
||||
uint8_t parser_step = 0;
|
||||
uint32_t te_last = 0;
|
||||
uint32_t decode_count_bit = 0;
|
||||
uint64_t decode_data = 0;
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons
|
||||
#include "s-legrand.hpp"
|
||||
#include "s-somify_keytis.hpp"
|
||||
#include "s-somify_telis.hpp"
|
||||
|
||||
#include "s-gangqi.hpp"
|
||||
#include "s-marantec24.hpp"
|
||||
// GENIE FROM PR
|
||||
|
||||
#ifndef __FPROTO_PROTOLISTSGZ_H__
|
||||
@ -104,6 +105,8 @@ class SubGhzDProtos : public FProtoListGeneral {
|
||||
protos[FPS_X10] = new FProtoSubGhzDX10();
|
||||
// protos[FPS_HORMANNBISECURE] = new FProtoSubGhzDHormannBiSecure(); //fm
|
||||
protos[FPS_LEGRAND] = new FProtoSubGhzDLegrand();
|
||||
protos[FPS_GANGQI] = new FProtoSubGhzDGangqi();
|
||||
protos[FPS_MARANTEC24] = new FProtoSubGhzDMarantec24();
|
||||
|
||||
for (uint8_t i = 0; i < FPS_COUNT; ++i) {
|
||||
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
|
||||
@ -120,7 +123,7 @@ class SubGhzDProtos : public FProtoListGeneral {
|
||||
};
|
||||
|
||||
static void callbackTarget(FProtoSubGhzDBase* instance) {
|
||||
SubGhzDDataMessage packet_message{instance->sensorType, instance->data_count_bit, instance->data};
|
||||
SubGhzDDataMessage packet_message{instance->sensorType, instance->data_count_bit, instance->decode_data};
|
||||
shared_memory.application_queue.push(packet_message);
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,8 @@ enum FPROTO_SUBGHZD_SENSOR : uint8_t {
|
||||
FPS_X10,
|
||||
FPS_SOMIFY_KEYTIS,
|
||||
FPS_SOMIFY_TELIS,
|
||||
FPS_GANGQI,
|
||||
FPS_MARANTEC24,
|
||||
FPS_COUNT
|
||||
};
|
||||
|
||||
|
@ -80,9 +80,6 @@ class FProtoWeatherAcurite592TXR : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_acurite_592txr_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_acurite_592txr_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -138,17 +135,6 @@ class FProtoWeatherAcurite592TXR : public FProtoWeatherBase {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ws_protocol_acurite_592txr_remote_controller() {
|
||||
uint8_t channel_[] = {3, 0, 2, 1};
|
||||
uint8_t channel_raw = ((data >> 54) & 0x03);
|
||||
channel = channel_[channel_raw];
|
||||
id = (data >> 40) & 0x3FFF;
|
||||
battery_low = !((data >> 38) & 1);
|
||||
humidity = (data >> 24) & 0x7F;
|
||||
uint16_t temp_raw = ((data >> 9) & 0xF80) | ((data >> 8) & 0x7F);
|
||||
temp = ((float)(temp_raw)-1000) / 10.0f;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -73,9 +73,6 @@ class FProtoWeatherAcurite5in1 : public FProtoWeatherBase {
|
||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||
ws_protocol_acurite_5n1_check_crc() &&
|
||||
ws_protocol_acurite_5n1_check_message_type()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_acurite_5n1_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -133,17 +130,6 @@ class FProtoWeatherAcurite5in1 : public FProtoWeatherBase {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ws_protocol_acurite_5n1_remote_controller() {
|
||||
uint8_t channell[] = {3, 0, 2, 1};
|
||||
uint8_t channel_raw = ((data >> 62) & 0x03);
|
||||
channel = channell[channel_raw];
|
||||
id = (data >> 48) & 0x3FFF;
|
||||
battery_low = !((data >> 46) & 1);
|
||||
humidity = (data >> 8) & 0x7F;
|
||||
uint16_t temp_raw = ((data >> (24 - 7)) & 0x780) | ((data >> 16) & 0x7F);
|
||||
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)(temp_raw)-400) / 10.0f);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -48,9 +48,6 @@ class FProtoWeatherAcurite606TX : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_acurite_606tx_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_acurite_606tx_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -83,17 +80,6 @@ class FProtoWeatherAcurite606TX : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 150;
|
||||
uint32_t min_count_bit_for_found = 32;
|
||||
|
||||
void ws_protocol_acurite_606tx_remote_controller() {
|
||||
id = (data >> 24) & 0xFF;
|
||||
battery_low = (data >> 23) & 1;
|
||||
channel = WS_NO_CHANNEL;
|
||||
if (!((data >> 19) & 1)) {
|
||||
temp = (float)((data >> 8) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 8) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
humidity = WS_NO_HUMIDITY;
|
||||
}
|
||||
bool ws_protocol_acurite_606tx_check() {
|
||||
if (!decode_data) return false;
|
||||
uint8_t msg[] = {
|
||||
|
@ -44,9 +44,6 @@ class FProtoWeatherAcurite609TX : public FProtoWeatherBase {
|
||||
// Found syncPostfix
|
||||
parser_step = Acurite_609TXCDecoderStepReset;
|
||||
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_acurite_609txc_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_acurite_609txc_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -76,19 +73,6 @@ class FProtoWeatherAcurite609TX : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 150;
|
||||
uint32_t min_count_bit_for_found = 32;
|
||||
|
||||
void ws_protocol_acurite_609txc_remote_controller() {
|
||||
id = (data >> 32) & 0xFF;
|
||||
battery_low = (data >> 31) & 1;
|
||||
channel = WS_NO_CHANNEL;
|
||||
|
||||
// Temperature in Celsius is encoded as a 12 bit integer value
|
||||
// multiplied by 10 using the 4th - 6th nybbles (bytes 1 & 2)
|
||||
// negative values are recovered by sign extend from int16_t.
|
||||
int16_t temp_raw =
|
||||
(int16_t)(((data >> 12) & 0xf000) | ((data >> 16) << 4));
|
||||
temp = (temp_raw >> 4) * 0.1f;
|
||||
humidity = (data >> 8) & 0xff;
|
||||
}
|
||||
bool ws_protocol_acurite_609txc_check() {
|
||||
if (!decode_data) return false;
|
||||
uint8_t crc = (uint8_t)(decode_data >> 32) +
|
||||
|
@ -84,9 +84,6 @@ class FProtoWeatherAcurite986 : public FProtoWeatherBase {
|
||||
// Found syncPostfix
|
||||
parser_step = Acurite_986DecoderStepReset;
|
||||
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_acurite_986_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_acurite_986_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -105,22 +102,6 @@ class FProtoWeatherAcurite986 : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 50;
|
||||
uint32_t min_count_bit_for_found = 40;
|
||||
|
||||
void ws_protocol_acurite_986_remote_controller() {
|
||||
int temp;
|
||||
|
||||
id = FProtoGeneral::subghz_protocol_blocks_reverse_key(data >> 24, 8);
|
||||
id = (id << 8) | FProtoGeneral::subghz_protocol_blocks_reverse_key(data >> 16, 8);
|
||||
battery_low = (data >> 14) & 1;
|
||||
channel = ((data >> 15) & 1) + 1;
|
||||
|
||||
temp = FProtoGeneral::subghz_protocol_blocks_reverse_key(data >> 32, 8);
|
||||
if (temp & 0x80) {
|
||||
temp = -(temp & 0x7F);
|
||||
}
|
||||
temp = FProtoGeneral::locale_fahrenheit_to_celsius((float)temp);
|
||||
humidity = WS_NO_HUMIDITY;
|
||||
}
|
||||
|
||||
bool ws_protocol_acurite_986_check() {
|
||||
if (!decode_data) return false;
|
||||
uint8_t msg[] = {
|
||||
|
@ -42,9 +42,6 @@ class FProtoWeatherAmbient : public FProtoWeatherBase {
|
||||
if (((decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == AMBIENT_WEATHER_PACKET_HEADER_1) ||
|
||||
((decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == AMBIENT_WEATHER_PACKET_HEADER_2)) {
|
||||
if (ws_protocol_ambient_weather_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = min_count_bit_for_found;
|
||||
ws_protocol_ambient_weather_remote_controller();
|
||||
if (callback) callback(this);
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
@ -74,14 +71,6 @@ class FProtoWeatherAmbient : public FProtoWeatherBase {
|
||||
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_lfsr_digest8(msg, 5, 0x98, 0x3e) ^ 0x64;
|
||||
return (crc == (uint8_t)(decode_data & 0xFF));
|
||||
}
|
||||
|
||||
void ws_protocol_ambient_weather_remote_controller() {
|
||||
id = (data >> 32) & 0xFF;
|
||||
battery_low = (data >> 31) & 1;
|
||||
channel = ((data >> 28) & 0x07) + 1;
|
||||
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data >> 16) & 0x0FFF) - 400.0f) / 10.0f);
|
||||
humidity = (data >> 8) & 0xFF;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -48,9 +48,6 @@ class FProtoWeatherAuriolAhfl : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_auriol_ahfl_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_auriol_ahfl_remote_controller();
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
@ -88,19 +85,6 @@ class FProtoWeatherAuriolAhfl : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 150;
|
||||
uint32_t min_count_bit_for_found = 42;
|
||||
|
||||
void ws_protocol_auriol_ahfl_remote_controller() {
|
||||
id = data >> 34;
|
||||
battery_low = (data >> 33) & 1;
|
||||
// btn = (data >> 32) & 1;
|
||||
channel = ((data >> 30) & 0x3) + 1;
|
||||
if (!((data >> 29) & 1)) {
|
||||
temp = (float)((data >> 18) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 18) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
humidity = (data >> 11) & 0x7F;
|
||||
}
|
||||
|
||||
bool ws_protocol_auriol_ahfl_check() {
|
||||
uint8_t type = (decode_data >> 6) & 0x0F;
|
||||
if (type != AURIOL_AHFL_CONST_DATA) {
|
||||
|
@ -47,9 +47,6 @@ class FProtoWeatherAuriolTh : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_auriol_th_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_auriol_th_remote_controller();
|
||||
if (callback) callback(this);
|
||||
parser_step = auriol_THDecoderStepCheckDuration;
|
||||
}
|
||||
@ -87,18 +84,6 @@ class FProtoWeatherAuriolTh : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 150;
|
||||
uint32_t min_count_bit_for_found = 37;
|
||||
|
||||
void ws_protocol_auriol_th_remote_controller() {
|
||||
id = (data >> 31) & 0xFF;
|
||||
battery_low = ((data >> 30) & 1);
|
||||
channel = ((data >> 25) & 0x03) + 1;
|
||||
if (!((data >> 23) & 1)) {
|
||||
temp = (float)((data >> 13) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 13) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
|
||||
humidity = (data >> 1) & 0x7F;
|
||||
}
|
||||
bool ws_protocol_auriol_th_check() {
|
||||
uint8_t type = (decode_data >> 8) & 0x0F;
|
||||
|
||||
|
@ -81,9 +81,7 @@ class FProtoWeatherEmosE601x : public FProtoWeatherBase {
|
||||
}
|
||||
|
||||
if (decode_count_bit == 120) {
|
||||
data_count_bit = decode_count_bit;
|
||||
if (ws_protocol_emose601x_check()) {
|
||||
ws_protocol_emose601x_extract_data();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
break;
|
||||
@ -127,20 +125,6 @@ class FProtoWeatherEmosE601x : public FProtoWeatherBase {
|
||||
uint8_t sum = FProtoGeneral::subghz_protocol_blocks_add_bytes(msg, 13);
|
||||
return (sum == ((decode_data >> 8) & 0xff));
|
||||
}
|
||||
|
||||
void ws_protocol_emose601x_extract_data() {
|
||||
id = (upper_decode_data >> 24) & 0xff;
|
||||
battery_low = (decode_data >> 10) & 1;
|
||||
int16_t temp = (decode_data >> 40) & 0xfff;
|
||||
/* Handle signed data */
|
||||
if (temp & 0x800) {
|
||||
temp |= 0xf000;
|
||||
}
|
||||
temp = (float)temp / 10.0;
|
||||
humidity = (decode_data >> 32) & 0xff;
|
||||
channel = (decode_data >> 52) & 0x03;
|
||||
data = (decode_data >> 16);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -50,9 +50,6 @@ class FProtoWeatherGTWT02 : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_gt_wt_02_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_gt_wt_02_remote_controller();
|
||||
if (callback) callback(this);
|
||||
} else if (decode_count_bit == 1) {
|
||||
parser_step = GT_WT02DecoderStepSaveDuration;
|
||||
@ -88,25 +85,6 @@ class FProtoWeatherGTWT02 : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 150;
|
||||
uint32_t min_count_bit_for_found = 37;
|
||||
|
||||
void ws_protocol_gt_wt_02_remote_controller() {
|
||||
id = (data >> 29) & 0xFF;
|
||||
battery_low = (data >> 28) & 1;
|
||||
// btn = (data >> 27) & 1;
|
||||
channel = ((data >> 25) & 0x3) + 1;
|
||||
|
||||
if (!((data >> 24) & 1)) {
|
||||
temp = (float)((data >> 13) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 13) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
|
||||
humidity = (data >> 6) & 0x7F;
|
||||
if (humidity <= 10) // actually the sensors sends 10 below working range of 20%
|
||||
humidity = 0;
|
||||
else if (humidity > 90) // actually the sensors sends 110 above working range of 90%
|
||||
humidity = 100;
|
||||
}
|
||||
|
||||
bool ws_protocol_gt_wt_02_check() {
|
||||
if (!decode_data) return false;
|
||||
uint8_t sum = (decode_data >> 5) & 0xe;
|
||||
|
@ -77,9 +77,6 @@ class FProtoWeatherGTWT03 : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_gt_wt_03_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_gt_wt_03_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -113,27 +110,6 @@ class FProtoWeatherGTWT03 : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 120;
|
||||
uint32_t min_count_bit_for_found = 41;
|
||||
|
||||
void ws_protocol_gt_wt_03_remote_controller() {
|
||||
id = data >> 33;
|
||||
humidity = (data >> 25) & 0xFF;
|
||||
|
||||
if (humidity <= 10) { // actually the sensors sends 10 below working range of 20%
|
||||
humidity = 0;
|
||||
} else if (humidity > 95) { // actually the sensors sends 110 above working range of 90%
|
||||
humidity = 100;
|
||||
}
|
||||
|
||||
battery_low = (data >> 24) & 1;
|
||||
// (data >> 23) & 1;
|
||||
channel = ((data >> 21) & 0x03) + 1;
|
||||
|
||||
if (!((data >> 20) & 1)) {
|
||||
temp = (float)((data >> 9) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 9) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool ws_protocol_gt_wt_03_check_crc() {
|
||||
uint8_t msg[] = {
|
||||
static_cast<uint8_t>(decode_data >> 33),
|
||||
|
@ -71,9 +71,6 @@ class FProtoWeatherInfactory : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_infactory_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_infactory_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -122,13 +119,6 @@ class FProtoWeatherInfactory : public FProtoWeatherBase {
|
||||
crc ^= msg[4] >> 4; // last nibble is only XORed
|
||||
return (crc == ((decode_data >> 28) & 0x0F));
|
||||
}
|
||||
void ws_protocol_infactory_remote_controller() {
|
||||
id = data >> 32;
|
||||
battery_low = (data >> 26) & 1;
|
||||
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data >> 12) & 0x0FFF) - 900.0f) / 10.0f);
|
||||
humidity = (((data >> 8) & 0x0F) * 10) + ((data >> 4) & 0x0F); // BCD, 'A0'=100%rH
|
||||
channel = data & 0x03;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -78,9 +78,6 @@ class FProtoWeatherKedsum : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_kedsum_th_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_kedsum_th_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -127,20 +124,6 @@ class FProtoWeatherKedsum : public FProtoWeatherBase {
|
||||
crc ^= msg[4] >> 4; // last nibble is only XORed
|
||||
return (crc == (msg[4] & 0x0F));
|
||||
}
|
||||
|
||||
void ws_protocol_kedsum_th_remote_controller() {
|
||||
id = data >> 32;
|
||||
if ((data >> 30) & 0x3) {
|
||||
battery_low = 0;
|
||||
} else {
|
||||
battery_low = 1;
|
||||
}
|
||||
channel = ((data >> 28) & 0x3) + 1;
|
||||
uint16_t temp_raw = ((data >> 16) & 0x0f) << 8 |
|
||||
((data >> 20) & 0x0f) << 4 | ((data >> 24) & 0x0f);
|
||||
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)temp_raw - 900.0f) / 10.0f);
|
||||
humidity = ((data >> 8) & 0x0f) << 4 | ((data >> 12) & 0x0f);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -79,9 +79,6 @@ class FProtoWeatherLaCrosseTx : public FProtoWeatherBase {
|
||||
if ((decode_data & LACROSSE_TX_SUNC_MASK) ==
|
||||
LACROSSE_TX_SUNC_PATTERN) {
|
||||
if (ws_protocol_lacrosse_tx_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = LACROSSE_TX_BIT_SIZE;
|
||||
ws_protocol_lacrosse_tx_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
}
|
||||
@ -119,28 +116,6 @@ class FProtoWeatherLaCrosseTx : public FProtoWeatherBase {
|
||||
uint32_t te_delta = 120;
|
||||
uint32_t min_count_bit_for_found = 40;
|
||||
|
||||
void ws_protocol_lacrosse_tx_remote_controller() {
|
||||
uint8_t msg_type = (data >> 32) & 0x0F;
|
||||
id = (((data >> 28) & 0x0F) << 3) | (((data >> 24) & 0x0F) >> 1);
|
||||
|
||||
float msg_value = (float)((data >> 20) & 0x0F) * 10.0f +
|
||||
(float)((data >> 16) & 0x0F) +
|
||||
(float)((data >> 12) & 0x0F) * 0.1f;
|
||||
|
||||
if (msg_type == LACROSSE_TX_MSG_TYPE_TEMP) { //-V1051
|
||||
temp = msg_value - 50.0f;
|
||||
humidity = WS_NO_HUMIDITY;
|
||||
} else if (msg_type == LACROSSE_TX_MSG_TYPE_HUM) {
|
||||
// ToDo for verification, records are needed with sensors maintaining temperature and temperature for this standard
|
||||
humidity = (uint8_t)msg_value;
|
||||
} else {
|
||||
// furi_crash("WS: WSProtocolLaCrosse_TX incorrect msg_type.");
|
||||
}
|
||||
|
||||
battery_low = WS_NO_BATT;
|
||||
channel = WS_NO_CHANNEL;
|
||||
}
|
||||
|
||||
bool ws_protocol_lacrosse_tx_check_crc() {
|
||||
if (!decode_data) return false;
|
||||
uint8_t msg[] = {
|
||||
|
@ -67,9 +67,9 @@ class FProtoWeatherLaCrosseTx141thbv2 : public FProtoWeatherBase {
|
||||
if ((decode_count_bit == min_count_bit_for_found) ||
|
||||
(decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT)) {
|
||||
if (ws_protocol_lacrosse_tx141thbv2_check_crc()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_lacrosse_tx141thbv2_remote_controller();
|
||||
if (decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) {
|
||||
decode_data >>= 1;
|
||||
}
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -107,17 +107,7 @@ class FProtoWeatherLaCrosseTx141thbv2 : public FProtoWeatherBase {
|
||||
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_lfsr_digest8_reflect(msg, 4, 0x31, 0xF4);
|
||||
return (crc == (data & 0xFF));
|
||||
}
|
||||
void ws_protocol_lacrosse_tx141thbv2_remote_controller() {
|
||||
if (data_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) {
|
||||
data >>= 1;
|
||||
}
|
||||
id = data >> 32;
|
||||
battery_low = (data >> 31) & 1;
|
||||
// btn = (data >> 30) & 1;
|
||||
channel = ((data >> 28) & 0x03) + 1;
|
||||
temp = ((float)((data >> 16) & 0x0FFF) - 500.0f) / 10.0f;
|
||||
humidity = (data >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
bool ws_protocol_decoder_lacrosse_tx141thbv2_add_bit(uint32_t te_last, uint32_t te_current) {
|
||||
bool ret = false;
|
||||
if (DURATION_DIFF(te_last + te_current, te_short + te_long) < te_delta * 2) {
|
||||
|
@ -51,9 +51,6 @@ class FProtoWeatherNexusTH : public FProtoWeatherBase {
|
||||
parser_step = Nexus_THDecoderStepReset;
|
||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||
ws_protocol_nexus_th_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_nexus_th_remote_controller();
|
||||
if (callback) callback((FProtoWeatherBase*)this);
|
||||
parser_step = Nexus_THDecoderStepCheckDuration;
|
||||
}
|
||||
@ -98,23 +95,6 @@ class FProtoWeatherNexusTH : public FProtoWeatherBase {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// fill the base class's variables before calling the callback
|
||||
void ws_protocol_nexus_th_remote_controller() {
|
||||
id = (data >> 28) & 0xFF;
|
||||
battery_low = !((data >> 27) & 1);
|
||||
channel = ((data >> 24) & 0x03) + 1;
|
||||
if (!((data >> 23) & 1)) {
|
||||
temp = (float)((data >> 12) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 12) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
humidity = data & 0xFF;
|
||||
if (humidity > 95)
|
||||
humidity = 95;
|
||||
else if (humidity < 20)
|
||||
humidity = 20;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -107,7 +107,6 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
||||
// waiting for fixed oregon2 data
|
||||
if (decode_count_bit == 32) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
decode_data = 0UL;
|
||||
decode_count_bit = 0;
|
||||
|
||||
@ -117,13 +116,13 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
||||
data = (data & 0x33333333) << 2 |
|
||||
(data & 0xCCCCCCCC) >> 2;
|
||||
|
||||
ws_oregon2_decode_const_data();
|
||||
// ws_oregon2_decode_const_data();
|
||||
var_bits = oregon2_sensor_id_var_bits(OREGON2_SENSOR_ID(data));
|
||||
|
||||
if (!var_bits) {
|
||||
// sensor is not supported, stop decoding, but showing the decoded fixed part
|
||||
// sensor is not supported, stop decoding, so won't showing the decoded fixed part
|
||||
parser_step = Oregon2DecoderStepReset;
|
||||
if (callback) callback(this);
|
||||
// if (callback) callback(this);
|
||||
} else {
|
||||
parser_step = Oregon2DecoderStepVarData;
|
||||
}
|
||||
@ -139,8 +138,8 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
||||
(var_data & 0xAAAAAAAA) >> 1;
|
||||
var_data = (var_data & 0x33333333) << 2 |
|
||||
(var_data & 0xCCCCCCCC) >> 2;
|
||||
|
||||
ws_oregon2_decode_var_data(OREGON2_SENSOR_ID(data), var_data >> OREGON2_CHECKSUM_BITS);
|
||||
decode_data = var_data;
|
||||
// ws_oregon2_decode_var_data(OREGON2_SENSOR_ID(data), var_data >> OREGON2_CHECKSUM_BITS); //a bit stepback, but will work
|
||||
|
||||
parser_step = Oregon2DecoderStepReset;
|
||||
if (callback) callback(this);
|
||||
@ -155,6 +154,7 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
||||
uint32_t te_long = 1000;
|
||||
uint32_t te_delta = 200;
|
||||
uint32_t min_count_bit_for_found = 32;
|
||||
uint64_t data = 0;
|
||||
|
||||
bool have_bit = false;
|
||||
bool prev_bit = 0;
|
||||
@ -202,19 +202,21 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void ws_oregon2_decode_const_data() {
|
||||
id = OREGON2_SENSOR_ID(data);
|
||||
uint8_t ch_bits = (data >> 12) & 0xF;
|
||||
channel = 1;
|
||||
while (ch_bits > 1) {
|
||||
channel++;
|
||||
ch_bits >>= 1;
|
||||
}
|
||||
battery_low = (data & OREGON2_FLAG_BAT_LOW) ? 1 : 0;
|
||||
}
|
||||
/* void ws_oregon2_decode_const_data() {
|
||||
id = OREGON2_SENSOR_ID(data);
|
||||
uint8_t ch_bits = (data >> 12) & 0xF;
|
||||
channel = 1;
|
||||
while (ch_bits > 1) {
|
||||
channel++;
|
||||
ch_bits >>= 1;
|
||||
}
|
||||
battery_low = (data & OREGON2_FLAG_BAT_LOW) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint16_t bcd_decode_short(uint32_t data) {
|
||||
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
|
||||
}
|
||||
|
||||
float ws_oregon2_decode_temp(uint32_t data) {
|
||||
int32_t temp_val;
|
||||
temp_val = bcd_decode_short(data >> 4);
|
||||
@ -241,7 +243,7 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -66,7 +66,6 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
||||
// waiting for fixed oregon3 data
|
||||
if (decode_count_bit == OREGON3_FIXED_PART_BITS) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
decode_data = 0UL;
|
||||
decode_count_bit = 0;
|
||||
|
||||
@ -76,9 +75,8 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
||||
data = (data & 0x33333333) << 2 |
|
||||
(data & 0xCCCCCCCC) >> 2;
|
||||
|
||||
ws_oregon3_decode_const_data();
|
||||
var_bits =
|
||||
oregon3_sensor_id_var_bits(OREGON3_SENSOR_ID(data));
|
||||
// ws_oregon3_decode_const_data(); //todo fix somehow in the future
|
||||
var_bits = oregon3_sensor_id_var_bits(OREGON3_SENSOR_ID(data));
|
||||
|
||||
if (!var_bits) {
|
||||
// sensor is not supported, stop decoding
|
||||
@ -98,8 +96,8 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
||||
(var_data & 0xAAAAAAAAAAAAAAAA) >> 1;
|
||||
var_data = (var_data & 0x3333333333333333) << 2 |
|
||||
(var_data & 0xCCCCCCCCCCCCCCCC) >> 2;
|
||||
|
||||
ws_oregon3_decode_var_data(OREGON3_SENSOR_ID(data), var_data >> OREGON3_CHECKSUM_BITS);
|
||||
decode_data = var_data;
|
||||
// ws_oregon3_decode_var_data(OREGON3_SENSOR_ID(data), var_data >> OREGON3_CHECKSUM_BITS);
|
||||
parser_step = Oregon3DecoderStepReset;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
@ -113,6 +111,7 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
||||
uint32_t te_long = 1100;
|
||||
uint32_t te_delta = 300;
|
||||
uint32_t min_count_bit_for_found = 32;
|
||||
uint64_t data = 0;
|
||||
|
||||
bool prev_bit = false;
|
||||
uint8_t var_bits{0};
|
||||
@ -143,31 +142,31 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void ws_oregon3_decode_const_data() {
|
||||
id = OREGON3_SENSOR_ID(data);
|
||||
channel = (data >> 12) & 0xF;
|
||||
battery_low = (data & OREGON3_FLAG_BAT_LOW) ? 1 : 0;
|
||||
}
|
||||
uint16_t ws_oregon3_bcd_decode_short(uint32_t data) {
|
||||
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
|
||||
}
|
||||
float ws_oregon3_decode_temp(uint32_t data) {
|
||||
int32_t temp_val;
|
||||
temp_val = ws_oregon3_bcd_decode_short(data >> 4);
|
||||
temp_val *= 10;
|
||||
temp_val += (data >> 12) & 0xF;
|
||||
if (data & 0xF) temp_val = -temp_val;
|
||||
return (float)temp_val / 10.0;
|
||||
}
|
||||
void ws_oregon3_decode_var_data(uint16_t sensor_id, uint32_t data) {
|
||||
switch (sensor_id) {
|
||||
case ID_THGR221:
|
||||
default:
|
||||
humidity = ws_oregon3_bcd_decode_short(data >> 4);
|
||||
temp = ws_oregon3_decode_temp(data >> 12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* void ws_oregon3_decode_const_data() {
|
||||
id = OREGON3_SENSOR_ID(data);
|
||||
channel = (data >> 12) & 0xF;
|
||||
battery_low = (data & OREGON3_FLAG_BAT_LOW) ? 1 : 0;
|
||||
}
|
||||
uint16_t ws_oregon3_bcd_decode_short(uint32_t data) {
|
||||
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
|
||||
}
|
||||
float ws_oregon3_decode_temp(uint32_t data) {
|
||||
int32_t temp_val;
|
||||
temp_val = ws_oregon3_bcd_decode_short(data >> 4);
|
||||
temp_val *= 10;
|
||||
temp_val += (data >> 12) & 0xF;
|
||||
if (data & 0xF) temp_val = -temp_val;
|
||||
return (float)temp_val / 10.0;
|
||||
}
|
||||
void ws_oregon3_decode_var_data(uint16_t sensor_id, uint32_t data) {
|
||||
switch (sensor_id) {
|
||||
case ID_THGR221:
|
||||
default:
|
||||
humidity = ws_oregon3_bcd_decode_short(data >> 4);
|
||||
temp = ws_oregon3_decode_temp(data >> 12);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
@ -102,9 +102,6 @@ class FProtoWeatherOregonV1 : public FProtoWeatherBase {
|
||||
decode_data = ~decode_data | (1 << 31);
|
||||
}
|
||||
if (ws_protocol_oregon_v1_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_oregon_v1_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
}
|
||||
@ -145,22 +142,6 @@ class FProtoWeatherOregonV1 : public FProtoWeatherBase {
|
||||
crc = (crc & 0xff) + ((crc >> 8) & 0xff);
|
||||
return (crc == ((data >> 24) & 0xFF));
|
||||
}
|
||||
void ws_protocol_oregon_v1_remote_controller() {
|
||||
uint64_t data2 = FProtoGeneral::subghz_protocol_blocks_reverse_key(data, 32);
|
||||
|
||||
id = data2 & 0xFF;
|
||||
channel = ((data2 >> 6) & 0x03) + 1;
|
||||
|
||||
float temp_raw =
|
||||
((data2 >> 8) & 0x0F) * 0.1f + ((data2 >> 12) & 0x0F) + ((data2 >> 16) & 0x0F) * 10.0f;
|
||||
if (!((data2 >> 21) & 1)) {
|
||||
temp = temp_raw;
|
||||
} else {
|
||||
temp = -temp_raw;
|
||||
}
|
||||
battery_low = !((data2 >> 23) & 1ULL);
|
||||
humidity = WS_NO_HUMIDITY;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
90
firmware/baseband/fprotos/w-solight_te44.hpp
Normal file
90
firmware/baseband/fprotos/w-solight_te44.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
|
||||
#ifndef __FPROTO_SOLIGHT_TE44_H__
|
||||
#define __FPROTO_SOLIGHT_TE44_H__
|
||||
|
||||
#include "weatherbase.hpp"
|
||||
|
||||
typedef enum {
|
||||
SolightTE44DecoderStepReset = 0,
|
||||
SolightTE44DecoderStepSaveDuration,
|
||||
SolightTE44DecoderStepCheckDuration,
|
||||
} SolightTE44DecoderStep;
|
||||
|
||||
class FProtoWeatherSolightTE44 : public FProtoWeatherBase {
|
||||
public:
|
||||
FProtoWeatherSolightTE44() {
|
||||
sensorType = FPW_SolightTE44;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) override {
|
||||
switch (parser_step) {
|
||||
case SolightTE44DecoderStepReset:
|
||||
if ((!level) && duration >= te_long) {
|
||||
parser_step = SolightTE44DecoderStepSaveDuration;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SolightTE44DecoderStepSaveDuration:
|
||||
if (level) {
|
||||
te_last = duration;
|
||||
parser_step = SolightTE44DecoderStepCheckDuration;
|
||||
} else {
|
||||
parser_step = SolightTE44DecoderStepReset;
|
||||
}
|
||||
break;
|
||||
|
||||
case SolightTE44DecoderStepCheckDuration:
|
||||
if (!level) {
|
||||
if (DURATION_DIFF(duration, te_short) < te_delta) {
|
||||
if (decode_count_bit == min_count_bit_for_found &&
|
||||
ws_protocol_solight_te44_check()) {
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = SolightTE44DecoderStepReset;
|
||||
} else if (
|
||||
DURATION_DIFF(te_last, te_short) < te_delta) {
|
||||
if (DURATION_DIFF(duration, te_short * 2) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
parser_step = SolightTE44DecoderStepSaveDuration;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short * 4) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
parser_step = SolightTE44DecoderStepSaveDuration;
|
||||
} else
|
||||
parser_step = SolightTE44DecoderStepReset;
|
||||
} else
|
||||
parser_step = SolightTE44DecoderStepReset;
|
||||
} else
|
||||
parser_step = SolightTE44DecoderStepReset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// timing values
|
||||
uint32_t te_short = 490;
|
||||
uint32_t te_long = 3000;
|
||||
uint32_t te_delta = 150;
|
||||
uint32_t min_count_bit_for_found = 36;
|
||||
|
||||
bool ws_protocol_solight_te44_check() {
|
||||
if (((decode_data >> 8) & 0x0f) != 0x0f) return false; // const not 1111
|
||||
// Rubicson CRC check
|
||||
uint8_t msg_rubicson_crc[] = {
|
||||
(uint8_t)(decode_data >> 28),
|
||||
(uint8_t)(decode_data >> 20),
|
||||
(uint8_t)(decode_data >> 12),
|
||||
0xf0,
|
||||
(uint8_t)(((uint8_t)decode_data & 0xf0) | ((uint8_t)decode_data & 0x0f))};
|
||||
|
||||
return FProtoGeneral::subghz_protocol_blocks_crc8(msg_rubicson_crc, 5, 0x31, 0x6c) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -45,9 +45,6 @@ class FProtoWeatherThermoProTx4 : public FProtoWeatherBase {
|
||||
parser_step = ThermoPRO_TX4DecoderStepReset;
|
||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||
ws_protocol_thermopro_tx4_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_thermopro_tx4_remote_controller();
|
||||
if (callback) callback(this);
|
||||
parser_step = ThermoPRO_TX4DecoderStepCheckDuration;
|
||||
}
|
||||
@ -92,19 +89,6 @@ class FProtoWeatherThermoProTx4 : public FProtoWeatherBase {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ws_protocol_thermopro_tx4_remote_controller() {
|
||||
id = (data >> 25) & 0xFF;
|
||||
battery_low = (data >> 24) & 1;
|
||||
// btn = (data >> 23) & 1;
|
||||
channel = ((data >> 21) & 0x03) + 1;
|
||||
if (!((data >> 20) & 1)) {
|
||||
temp = (float)((data >> 9) & 0x07FF) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 9) & 0x07FF) + 1) / -10.0f;
|
||||
}
|
||||
humidity = (data >> 1) & 0xFF;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -51,12 +51,8 @@ class FProtoWeatherTX8300 : public FProtoWeatherBase {
|
||||
if (!level) {
|
||||
if (duration >= ((uint32_t)te_short * 5)) {
|
||||
// Found syncPostfix
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_tx_8300_check_crc()) {
|
||||
data = package_1;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_tx_8300_remote_controller();
|
||||
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_tx_8300_check_crc()) {
|
||||
decode_data = package_1;
|
||||
if (callback) callback(this);
|
||||
}
|
||||
decode_data = 0;
|
||||
@ -118,23 +114,6 @@ class FProtoWeatherTX8300 : public FProtoWeatherBase {
|
||||
uint8_t crc = (~x & 0xF) << 4 | (~y & 0xF);
|
||||
return (crc == (decode_data & 0xFF));
|
||||
}
|
||||
void ws_protocol_tx_8300_remote_controller() {
|
||||
humidity = (((data >> 28) & 0x0F) * 10) + ((data >> 24) & 0x0F);
|
||||
if (!((data >> 22) & 0x03))
|
||||
battery_low = 0;
|
||||
else
|
||||
battery_low = 1;
|
||||
channel = (data >> 20) & 0x03;
|
||||
id = (data >> 12) & 0x7F;
|
||||
|
||||
float temp_raw = ((data >> 8) & 0x0F) * 10.0f + ((data >> 4) & 0x0F) +
|
||||
(data & 0x0F) * 0.1f;
|
||||
if (!((data >> 19) & 1)) {
|
||||
temp = temp_raw;
|
||||
} else {
|
||||
temp = -temp_raw;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -82,9 +82,6 @@ class FProtoWeatherWendoxW6726 : public FProtoWeatherBase {
|
||||
if ((decode_count_bit ==
|
||||
min_count_bit_for_found) &&
|
||||
ws_protocol_wendox_w6726_check()) {
|
||||
data = decode_data;
|
||||
data_count_bit = decode_count_bit;
|
||||
ws_protocol_wendox_w6726_remote_controller();
|
||||
if (callback) callback(this);
|
||||
}
|
||||
|
||||
@ -131,24 +128,6 @@ class FProtoWeatherWendoxW6726 : public FProtoWeatherBase {
|
||||
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_crc4(msg, 4, 0x9, 0xD);
|
||||
return (crc == (decode_data & 0x0F));
|
||||
}
|
||||
void ws_protocol_wendox_w6726_remote_controller() {
|
||||
id = (data >> 24) & 0xFF;
|
||||
battery_low = (data >> 6) & 1;
|
||||
channel = WS_NO_CHANNEL;
|
||||
|
||||
if (((data >> 23) & 1)) {
|
||||
temp = (float)(((data >> 14) & 0x1FF) + 12) / 10.0f;
|
||||
} else {
|
||||
temp = (float)((~(data >> 14) & 0x1FF) + 1 - 12) / -10.0f;
|
||||
}
|
||||
|
||||
if (temp < -50.0f) {
|
||||
temp = -50.0f;
|
||||
} else if (temp > 70.0f) {
|
||||
temp = 70.0f;
|
||||
}
|
||||
humidity = WS_NO_HUMIDITY;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,11 +24,7 @@ class FProtoWeatherBase {
|
||||
void setCallback(SubGhzProtocolDecoderBaseRxCallback cb) { callback = cb; } // this is called when there is a hit.
|
||||
|
||||
uint8_t getSensorType() { return sensorType; }
|
||||
uint8_t getHumidity() { return humidity; }
|
||||
uint8_t getBattLow() { return battery_low; }
|
||||
uint8_t getChannel() { return channel; }
|
||||
uint32_t getSensorId() { return id; }
|
||||
float getTemp() { return temp; }
|
||||
uint64_t getData() { return decode_data; }
|
||||
|
||||
protected:
|
||||
// Helper functions to keep it as compatible with flipper as we can, so adding new protos will be easy.
|
||||
@ -40,23 +36,16 @@ class FProtoWeatherBase {
|
||||
// needs to be in this chaotic order, to save flash!
|
||||
// General weather data holder
|
||||
uint8_t sensorType = FPW_Invalid;
|
||||
uint8_t humidity = WS_NO_HUMIDITY;
|
||||
uint8_t battery_low = WS_NO_BATT;
|
||||
uint8_t channel = WS_NO_CHANNEL;
|
||||
// inner logic stuff
|
||||
uint8_t parser_step = 0;
|
||||
// inner logic stuff, also for flipper compatibility.
|
||||
uint16_t header_count = 0;
|
||||
// General weather data holder
|
||||
float temp = WS_NO_TEMPERATURE;
|
||||
uint32_t id = WS_NO_ID;
|
||||
// inner logic stuff,
|
||||
|
||||
uint32_t te_last = 0;
|
||||
uint32_t data_count_bit = 0;
|
||||
uint32_t decode_count_bit = 0;
|
||||
uint64_t decode_data = 0;
|
||||
uint64_t data = 0;
|
||||
|
||||
SubGhzProtocolDecoderBaseRxCallback callback = NULL;
|
||||
};
|
||||
|
||||
|
@ -28,6 +28,7 @@ So include here the .hpp, and add a new element to the protos vector in the cons
|
||||
#include "w-kedsum.hpp"
|
||||
#include "w-acurite5in1.hpp"
|
||||
#include "w-emose601x.hpp"
|
||||
#include "w-solight_te44.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
@ -64,6 +65,7 @@ class WeatherProtos : public FProtoListGeneral {
|
||||
protos[FPW_KEDSUM] = new FProtoWeatherKedsum();
|
||||
protos[FPW_Acurite5in1] = new FProtoWeatherAcurite5in1();
|
||||
protos[FPW_EmosE601x] = new FProtoWeatherEmosE601x();
|
||||
protos[FPW_SolightTE44] = new FProtoWeatherSolightTE44();
|
||||
|
||||
// set callback for them
|
||||
for (uint8_t i = 0; i < FPW_COUNT; ++i) {
|
||||
@ -81,9 +83,7 @@ class WeatherProtos : public FProtoListGeneral {
|
||||
};
|
||||
|
||||
static void callbackTarget(FProtoWeatherBase* instance) {
|
||||
WeatherDataMessage packet_message{instance->getSensorType(), instance->getSensorId(),
|
||||
instance->getTemp(), instance->getHumidity(), instance->getBattLow(),
|
||||
instance->getChannel()};
|
||||
WeatherDataMessage packet_message{instance->getSensorType(), instance->getData()};
|
||||
shared_memory.application_queue.push(packet_message);
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ enum FPROTO_WEATHER_SENSOR {
|
||||
FPW_KEDSUM = 20,
|
||||
FPW_Acurite5in1 = 21,
|
||||
FPW_EmosE601x = 22,
|
||||
FPW_SolightTE44 = 23,
|
||||
FPW_COUNT // this must be the last
|
||||
};
|
||||
|
||||
|
@ -1265,25 +1265,13 @@ class WeatherDataMessage : public Message {
|
||||
public:
|
||||
constexpr WeatherDataMessage(
|
||||
uint8_t sensorType = 0,
|
||||
uint32_t id = 0xFFFFFFFF,
|
||||
float temp = -273.0f,
|
||||
uint8_t humidity = 0xFF,
|
||||
uint8_t battery_low = 0xFF,
|
||||
uint8_t channel = 0xFF)
|
||||
uint64_t decode_data = 0xFFFFFFFF)
|
||||
: Message{ID::WeatherData},
|
||||
sensorType{sensorType},
|
||||
id{id},
|
||||
temp{temp},
|
||||
humidity{humidity},
|
||||
battery_low{battery_low},
|
||||
channel{channel} {
|
||||
decode_data{decode_data} {
|
||||
}
|
||||
uint8_t sensorType = 0;
|
||||
uint32_t id = 0xFFFFFFFF;
|
||||
float temp = -273.0f;
|
||||
uint8_t humidity = 0xFF;
|
||||
uint8_t battery_low = 0xFF;
|
||||
uint8_t channel = 0xFF;
|
||||
uint64_t decode_data = 0;
|
||||
};
|
||||
|
||||
class SubGhzDDataMessage : public Message {
|
||||
|
Loading…
Reference in New Issue
Block a user