mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04: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";
|
return "Somify Keytis";
|
||||||
case FPS_SOMIFY_TELIS:
|
case FPS_SOMIFY_TELIS:
|
||||||
return "Somify Telis";
|
return "Somify Telis";
|
||||||
|
case FPS_GANGQI:
|
||||||
|
return "GangQi";
|
||||||
|
case FPS_MARANTEC24:
|
||||||
|
return "Marantec24";
|
||||||
case FPS_Invalid:
|
case FPS_Invalid:
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
@ -717,5 +720,18 @@ void SubGhzDRecentEntryDetailView::parseProtocol() {
|
|||||||
serial = dataa & 0xFFFFFF; // address}
|
serial = dataa & 0xFFFFFF; // address}
|
||||||
return;
|
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
|
} // namespace ui
|
@ -26,6 +26,7 @@
|
|||||||
#include "baseband_api.hpp"
|
#include "baseband_api.hpp"
|
||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
#include "portapack_persistent_memory.hpp"
|
#include "portapack_persistent_memory.hpp"
|
||||||
|
#include "../baseband/fprotos/fprotogeneral.hpp"
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
@ -138,7 +139,8 @@ void WeatherView::on_tick_second() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WeatherView::on_data(const WeatherDataMessage* data) {
|
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());
|
auto matching_recent = find(recent, key.key());
|
||||||
if (matching_recent != std::end(recent)) {
|
if (matching_recent != std::end(recent)) {
|
||||||
// Found within. Move to front of list, increment counter.
|
// Found within. Move to front of list, increment counter.
|
||||||
@ -209,6 +211,8 @@ const char* WeatherView::getWeatherSensorTypeName(FPROTO_WEATHER_SENSOR type) {
|
|||||||
return "Acurite5in1";
|
return "Acurite5in1";
|
||||||
case FPW_EmosE601x:
|
case FPW_EmosE601x:
|
||||||
return "EmosE601x";
|
return "EmosE601x";
|
||||||
|
case FPW_SolightTE44:
|
||||||
|
return "SolightTE44";
|
||||||
case FPW_Invalid:
|
case FPW_Invalid:
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
@ -254,4 +258,287 @@ void RecentEntriesTable<ui::WeatherRecentEntries>::draw(
|
|||||||
painter.draw_string(target_rect.location(), style, line);
|
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
|
} // namespace ui
|
||||||
|
@ -96,7 +96,7 @@ class WeatherView : public View {
|
|||||||
private:
|
private:
|
||||||
void on_tick_second();
|
void on_tick_second();
|
||||||
void on_data(const WeatherDataMessage* data);
|
void on_data(const WeatherDataMessage* data);
|
||||||
|
WeatherRecentEntry process_data(const WeatherDataMessage* data);
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
RxRadioState radio_state_{
|
RxRadioState radio_state_{
|
||||||
433'920'000 /* frequency */,
|
433'920'000 /* frequency */,
|
||||||
|
@ -36,7 +36,6 @@ class FProtoSubGhzDBett : public FProtoSubGhzDBase {
|
|||||||
(te_delta * 15)) {
|
(te_delta * 15)) {
|
||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// dip decoder needed
|
// dip decoder needed
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
@ -53,7 +53,6 @@ class FProtoSubGhzDCame : public FProtoSubGhzDBase {
|
|||||||
parser_step = CameDecoderStepFoundStartBit;
|
parser_step = CameDecoderStepFoundStartBit;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == AIRFORCE_COUNT_BIT) ||
|
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)) {
|
(decode_count_bit == PRASTEL_COUNT_BIT) || (decode_count_bit == CAME_24_COUNT_BIT)) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// if flippa hacky, i hacky
|
// if flippa hacky, i hacky
|
||||||
sensorType = FPS_CAME;
|
sensorType = FPS_CAME;
|
||||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDCameAtomo : public FProtoSubGhzDBase {
|
|||||||
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDCameTwee : public FProtoSubGhzDBase {
|
|||||||
} else if (
|
} else if (
|
||||||
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@ class FProtoSubGhzDChambCode : public FProtoSubGhzDBase {
|
|||||||
if (duration > te_short * 5) {
|
if (duration > te_short * 5) {
|
||||||
if (decode_count_bit >= min_count_bit_for_found) {
|
if (decode_count_bit >= min_count_bit_for_found) {
|
||||||
if (subghz_protocol_decoder_chamb_code_check_mask_and_parse()) {
|
if (subghz_protocol_decoder_chamb_code_check_mask_and_parse()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,6 @@ class FProtoSubGhzDClemsa : public FProtoSubGhzDBase {
|
|||||||
|
|
||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,6 @@ class FProtoSubGhzDDoitrand : public FProtoSubGhzDBase {
|
|||||||
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
||||||
parser_step = DoitrandDecoderStepFoundStartBit;
|
parser_step = DoitrandDecoderStepFoundStartBit;
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,6 @@ class FProtoSubGhzDDooya : public FProtoSubGhzDBase {
|
|||||||
parser_step = DooyaDecoderStepFoundStartBit;
|
parser_step = DooyaDecoderStepFoundStartBit;
|
||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDFaac : public FProtoSubGhzDBase {
|
|||||||
if (duration >= ((uint32_t)te_short * 3 + te_delta)) {
|
if (duration >= ((uint32_t)te_short * 3 + te_delta)) {
|
||||||
parser_step = FaacSLHDecoderStepFoundPreambula;
|
parser_step = FaacSLHDecoderStepFoundPreambula;
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
// remark controller skipped
|
// remark controller skipped
|
||||||
if (callback) callback(this);
|
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)) {
|
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
||||||
parser_step = GateTXDecoderStepFoundStartBit;
|
parser_step = GateTXDecoderStepFoundStartBit;
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,6 @@ class FProtoSubGhzDHoltek : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
if ((decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) {
|
if ((decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -44,11 +44,8 @@ class FProtoSubGhzDHoltekHt12x : public FProtoSubGhzDBase {
|
|||||||
if (!level) {
|
if (!level) {
|
||||||
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
if (data != decode_data) {
|
data_count_bit = decode_count_bit;
|
||||||
data = decode_data;
|
if (callback) callback(this);
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
if (callback) callback(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
|
@ -71,7 +71,6 @@ class FProtoSubGhzDHoneywell : public FProtoSubGhzDBase {
|
|||||||
uint16_t crc = decode_data & 0xFFFF;
|
uint16_t crc = decode_data & 0xFFFF;
|
||||||
if (crc == crc_calc) {
|
if (crc == crc_calc) {
|
||||||
// the data is good. process it.
|
// 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
|
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);
|
if (callback) callback(this);
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
|
@ -36,7 +36,6 @@ class FProtoSubGhzDHoneywellWdb : public FProtoSubGhzDBase {
|
|||||||
if (DURATION_DIFF(duration, te_short * 3) < te_delta) {
|
if (DURATION_DIFF(duration, te_short * 3) < te_delta) {
|
||||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
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))) {
|
((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;
|
data_count_bit = decode_count_bit;
|
||||||
// controller has too much, should be done on ui side
|
// controller has too much, should be done on ui side
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
@ -47,7 +47,6 @@ class FProtoSubGhzDHormann : public FProtoSubGhzDBase {
|
|||||||
parser_step = HormannDecoderStepFoundStartBit;
|
parser_step = HormannDecoderStepFoundStartBit;
|
||||||
if (decode_count_bit >=
|
if (decode_count_bit >=
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ class FProtoSubGhzDHormannBiSecure : public FProtoSubGhzDBase {
|
|||||||
|
|
||||||
void subghz_protocol_decoder_hormann_bisecur_reset() {
|
void subghz_protocol_decoder_hormann_bisecur_reset() {
|
||||||
parser_step = HormannBiSecurDecoderStepReset;
|
parser_step = HormannBiSecurDecoderStepReset;
|
||||||
data = 0;
|
|
||||||
for (uint8_t i = 0; i < 22; ++i) dataa[i] = 0;
|
for (uint8_t i = 0; i < 22; ++i) dataa[i] = 0;
|
||||||
data_count_bit = 0;
|
data_count_bit = 0;
|
||||||
manchester_saved_state = ManchesterStateStart1;
|
manchester_saved_state = ManchesterStateStart1;
|
||||||
|
@ -44,7 +44,6 @@ class FProtoSubGhzDIdo : public FProtoSubGhzDBase {
|
|||||||
parser_step = IDoDecoderStepFoundPreambula;
|
parser_step = IDoDecoderStepFoundPreambula;
|
||||||
if (decode_count_bit >=
|
if (decode_count_bit >=
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,6 @@ class FProtoSubGhzDIntertechnoV3 : public FProtoSubGhzDBase {
|
|||||||
parser_step = IntertechnoV3DecoderStepStartSync;
|
parser_step = IntertechnoV3DecoderStepStartSync;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) ||
|
if ((decode_count_bit == min_count_bit_for_found) ||
|
||||||
(decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
|
(decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,8 @@ class FProtoSubGhzDKeeLoq : public FProtoSubGhzDBase {
|
|||||||
parser_step = KeeloqDecoderStepReset;
|
parser_step = KeeloqDecoderStepReset;
|
||||||
if ((decode_count_bit >= min_count_bit_for_found) &&
|
if ((decode_count_bit >= min_count_bit_for_found) &&
|
||||||
(decode_count_bit <= min_count_bit_for_found + 2)) {
|
(decode_count_bit <= min_count_bit_for_found + 2)) {
|
||||||
if (data != decode_data) {
|
data_count_bit = min_count_bit_for_found;
|
||||||
data = decode_data;
|
if (callback) callback(this);
|
||||||
data_count_bit = min_count_bit_for_found;
|
|
||||||
if (callback) callback(this);
|
|
||||||
}
|
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
header_count = 0;
|
header_count = 0;
|
||||||
@ -96,6 +93,8 @@ class FProtoSubGhzDKeeLoq : public FProtoSubGhzDBase {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,7 +50,8 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
|||||||
DURATION_DIFF(duration, te_short * 2) < te_delta * 2) {
|
DURATION_DIFF(duration, te_short * 2) < te_delta * 2) {
|
||||||
parser_step = KingGates_stylo_4kDecoderStepSaveDuration;
|
parser_step = KingGates_stylo_4kDecoderStepSaveDuration;
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
data_2 = 0;
|
// data_2 = 0;
|
||||||
|
// data = 0;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
header_count = 0;
|
header_count = 0;
|
||||||
}
|
}
|
||||||
@ -58,17 +59,17 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
|||||||
case KingGates_stylo_4kDecoderStepSaveDuration:
|
case KingGates_stylo_4kDecoderStepSaveDuration:
|
||||||
if (!level) {
|
if (!level) {
|
||||||
if (duration >= ((uint32_t)te_long * 3)) {
|
if (duration >= ((uint32_t)te_long * 3)) {
|
||||||
if (decode_count_bit ==
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
min_count_bit_for_found) {
|
// data = data_2;
|
||||||
data = data_2;
|
// data_2 = decode_data; // TODO DATA2
|
||||||
data_2 = decode_data; // TODO DATA2
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
// decode_data = data;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_step = KingGates_stylo_4kDecoderStepReset;
|
parser_step = KingGates_stylo_4kDecoderStepReset;
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
data_2 = 0;
|
// data_2 = 0;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
header_count = 0;
|
header_count = 0;
|
||||||
break;
|
break;
|
||||||
@ -101,7 +102,7 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
|||||||
header_count = 0;
|
header_count = 0;
|
||||||
}
|
}
|
||||||
if (decode_count_bit == 53) {
|
if (decode_count_bit == 53) {
|
||||||
data_2 = decode_data;
|
// data_2 = decode_data;
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -113,7 +114,9 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint64_t data_2 = 0;
|
// uint64_t data_2 = 0;
|
||||||
|
// uint64_t data = 0;
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,23 +79,17 @@ class FProtoSubGhzDLegrand : public FProtoSubGhzDBase {
|
|||||||
if (found) {
|
if (found) {
|
||||||
te += duration;
|
te += duration;
|
||||||
|
|
||||||
if (decode_count_bit <
|
if (decode_count_bit < min_count_bit_for_found) {
|
||||||
min_count_bit_for_found) {
|
|
||||||
parser_step = LegrandDecoderStepSaveDuration;
|
parser_step = LegrandDecoderStepSaveDuration;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enough bits for a packet found, save it only if there was a previous packet
|
// enough bits for a packet found, save it only if there was a previous packet
|
||||||
// with the same data
|
// with the same data
|
||||||
if (data && (data != decode_data)) {
|
te /= decode_count_bit * 4;
|
||||||
te /= decode_count_bit * 4;
|
data_count_bit = decode_count_bit;
|
||||||
|
if (callback) {
|
||||||
data = decode_data;
|
callback(this);
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
|
|
||||||
if (callback) {
|
|
||||||
callback(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// fallthrough to reset, the next bit is expected to be a sync
|
// fallthrough to reset, the next bit is expected to be a sync
|
||||||
// it also takes care of resetting the decoder state
|
// it also takes care of resetting the decoder state
|
||||||
|
@ -54,7 +54,6 @@ class FProtoSubGhzDLinear : public FProtoSubGhzDBase {
|
|||||||
subghz_protocol_blocks_add_bit(1);
|
subghz_protocol_blocks_add_bit(1);
|
||||||
}
|
}
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,8 @@ class FProtoSubGhzDLinearDelta3 : public FProtoSubGhzDBase {
|
|||||||
subghz_protocol_blocks_add_bit(0);
|
subghz_protocol_blocks_add_bit(0);
|
||||||
}
|
}
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
if ((data == decode_data) && data) {
|
data_count_bit = decode_count_bit;
|
||||||
data = decode_data;
|
if (callback) callback(this);
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
if (callback) callback(this);
|
|
||||||
}
|
|
||||||
parser_step = LinearD3DecoderStepSaveDuration;
|
parser_step = LinearD3DecoderStepSaveDuration;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -90,7 +90,6 @@ class FProtoSubGhzDMagellan : public FProtoSubGhzDBase {
|
|||||||
// Found stop bit
|
// Found stop bit
|
||||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||||
subghz_protocol_magellan_check_crc()) {
|
subghz_protocol_magellan_check_crc()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
@ -129,6 +128,7 @@ class FProtoSubGhzDMagellan : public FProtoSubGhzDBase {
|
|||||||
}
|
}
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,7 +43,6 @@ class FProtoSubGhzDMarantec : public FProtoSubGhzDBase {
|
|||||||
} else if (
|
} else if (
|
||||||
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
duration >= ((uint32_t)te_long * 2 + te_delta)) {
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
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) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
@ -48,7 +48,6 @@ class FProtoSubGhzDMegacode : public FProtoSubGhzDBase {
|
|||||||
parser_step = MegaCodeDecoderStepReset;
|
parser_step = MegaCodeDecoderStepReset;
|
||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
@ -67,7 +67,6 @@ class FProtoSubGhzDNeroSketch : public FProtoSubGhzDBase {
|
|||||||
// Found stop bit
|
// Found stop bit
|
||||||
parser_step = NeroSketchDecoderStepReset;
|
parser_step = NeroSketchDecoderStepReset;
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
@ -103,6 +102,7 @@ class FProtoSubGhzDNeroSketch : public FProtoSubGhzDBase {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,7 +82,6 @@ class FProtoSubGhzDNeroRadio : public FProtoSubGhzDBase {
|
|||||||
parser_step = NeroRadioDecoderStepReset;
|
parser_step = NeroRadioDecoderStepReset;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) ||
|
if ((decode_count_bit == min_count_bit_for_found) ||
|
||||||
(decode_count_bit == min_count_bit_for_found + 1)) {
|
(decode_count_bit == min_count_bit_for_found + 1)) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
@ -110,6 +109,7 @@ class FProtoSubGhzDNeroRadio : public FProtoSubGhzDBase {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,7 +47,6 @@ class FProtoSubGhzDNiceflo : public FProtoSubGhzDBase {
|
|||||||
if (duration >= (te_short * 4)) {
|
if (duration >= (te_short * 4)) {
|
||||||
parser_step = NiceFloDecoderStepFoundStartBit;
|
parser_step = NiceFloDecoderStepFoundStartBit;
|
||||||
if (decode_count_bit >= min_count_bit_for_found) {
|
if (decode_count_bit >= min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,9 @@ class FProtoSubGhzDNiceflors : public FProtoSubGhzDBase {
|
|||||||
// Found STOP bit
|
// Found STOP bit
|
||||||
parser_step = NiceFlorSDecoderStepReset;
|
parser_step = NiceFlorSDecoderStepReset;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == NICE_ONE_COUNT_BIT)) {
|
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;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
decode_data = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -86,8 +85,8 @@ class FProtoSubGhzDNiceflors : public FProtoSubGhzDBase {
|
|||||||
parser_step = NiceFlorSDecoderStepReset;
|
parser_step = NiceFlorSDecoderStepReset;
|
||||||
}
|
}
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
// data = decode_data;
|
||||||
decode_data = 0;
|
// decode_data = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,6 @@ class FProtoSubGhzDPhoenixV2 : public FProtoSubGhzDBase {
|
|||||||
parser_step = Phoenix_V2DecoderStepFoundStartBit;
|
parser_step = Phoenix_V2DecoderStepFoundStartBit;
|
||||||
if (decode_count_bit ==
|
if (decode_count_bit ==
|
||||||
min_count_bit_for_found) {
|
min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
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 ((decode_data & POWER_SMART_PACKET_HEADER_MASK) == POWER_SMART_PACKET_HEADER) {
|
||||||
if (subghz_protocol_power_smart_chek_valid(decode_data)) {
|
if (subghz_protocol_power_smart_chek_valid(decode_data)) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = min_count_bit_for_found;
|
data_count_bit = min_count_bit_for_found;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
@ -42,7 +42,6 @@ class FProtoSubGhzDPrinceton : public FProtoSubGhzDBase {
|
|||||||
if (duration >= ((uint32_t)te_long * 2)) {
|
if (duration >= ((uint32_t)te_long * 2)) {
|
||||||
parser_step = PrincetonDecoderStepSaveDuration;
|
parser_step = PrincetonDecoderStepSaveDuration;
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ class FProtoSubGhzDSecPlusV2 : public FProtoSubGhzDBase {
|
|||||||
} else if (
|
} else if (
|
||||||
duration >= (te_long * 2UL + te_delta)) {
|
duration >= (te_long * 2UL + te_delta)) {
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (subghz_protocol_secplus_v2_check_packet()) {
|
if (subghz_protocol_secplus_v2_check_packet()) {
|
||||||
// controller too big
|
// controller too big
|
||||||
|
@ -42,7 +42,6 @@ class FProtoSubGhzDSmc5326 : public FProtoSubGhzDBase {
|
|||||||
if (duration >= ((uint32_t)te_long * 2)) {
|
if (duration >= ((uint32_t)te_long * 2)) {
|
||||||
parser_step = SMC5326DecoderStepSaveDuration;
|
parser_step = SMC5326DecoderStepSaveDuration;
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
@ -68,11 +68,9 @@ class FProtoSubGhzDSomifyKeytis : public FProtoSubGhzDBase {
|
|||||||
duration >= (te_long + te_delta)) {
|
duration >= (te_long + te_delta)) {
|
||||||
if (decode_count_bit == min_count_bit_for_found) {
|
if (decode_count_bit == min_count_bit_for_found) {
|
||||||
// check crc
|
// 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)) {
|
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_keytis_crc(data_tmp)) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,6 +122,8 @@ class FProtoSubGhzDSomifyKeytis : public FProtoSubGhzDBase {
|
|||||||
}
|
}
|
||||||
return crc & 0xf;
|
return crc & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -71,7 +71,6 @@ class FProtoSubGhzDSomifyTelis : public FProtoSubGhzDBase {
|
|||||||
// check crc
|
// check crc
|
||||||
uint64_t data_tmp = decode_data ^ (decode_data >> 8);
|
uint64_t data_tmp = decode_data ^ (decode_data >> 8);
|
||||||
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_telis_crc(data_tmp)) {
|
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_telis_crc(data_tmp)) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
@ -118,6 +117,7 @@ class FProtoSubGhzDSomifyTelis : public FProtoSubGhzDBase {
|
|||||||
}
|
}
|
||||||
return crc & 0xf;
|
return crc & 0xf;
|
||||||
}
|
}
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,11 +53,8 @@ class FProtoSubGhzDStarLine : public FProtoSubGhzDBase {
|
|||||||
parser_step = StarLineDecoderStepReset;
|
parser_step = StarLineDecoderStepReset;
|
||||||
if ((decode_count_bit >= min_count_bit_for_found) &&
|
if ((decode_count_bit >= min_count_bit_for_found) &&
|
||||||
(decode_count_bit <= min_count_bit_for_found + 2)) {
|
(decode_count_bit <= min_count_bit_for_found + 2)) {
|
||||||
if (data != decode_data) {
|
data_count_bit = min_count_bit_for_found;
|
||||||
data = decode_data;
|
if (callback) callback(this);
|
||||||
data_count_bit = min_count_bit_for_found;
|
|
||||||
if (callback) callback(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
@ -101,6 +98,7 @@ class FProtoSubGhzDStarLine : public FProtoSubGhzDBase {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint16_t header_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,7 +47,6 @@ class FProtoSubGhzDX10 : public FProtoSubGhzDBase {
|
|||||||
if (decode_count_bit >= min_count_bit_for_found &&
|
if (decode_count_bit >= min_count_bit_for_found &&
|
||||||
((((decode_data >> 24) ^ (decode_data >> 16)) & 0xFF) == 0xFF) &&
|
((((decode_data >> 24) ^ (decode_data >> 16)) & 0xFF) == 0xFF) &&
|
||||||
((((decode_data >> 8) ^ (decode_data)) & 0xFF) == 0xFF)) {
|
((((decode_data >> 8) ^ (decode_data)) & 0xFF) == 0xFF)) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
data_count_bit = decode_count_bit;
|
||||||
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
|
@ -26,7 +26,7 @@ class FProtoSubGhzDBase {
|
|||||||
// General data holder, these will be passed
|
// General data holder, these will be passed
|
||||||
uint8_t sensorType = FPS_Invalid;
|
uint8_t sensorType = FPS_Invalid;
|
||||||
uint16_t data_count_bit = 0;
|
uint16_t data_count_bit = 0;
|
||||||
uint64_t data = 0;
|
uint64_t decode_data = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Helper functions to keep it as compatible with flipper as we can, so adding new protos will be easy.
|
// 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;
|
uint32_t min_count_bit_for_found = UINT32_MAX;
|
||||||
|
|
||||||
SubGhzDProtocolDecoderBaseRxCallback callback = NULL;
|
SubGhzDProtocolDecoderBaseRxCallback callback = NULL;
|
||||||
uint16_t header_count = 0;
|
|
||||||
uint8_t parser_step = 0;
|
uint8_t parser_step = 0;
|
||||||
uint32_t te_last = 0;
|
uint32_t te_last = 0;
|
||||||
uint32_t decode_count_bit = 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-legrand.hpp"
|
||||||
#include "s-somify_keytis.hpp"
|
#include "s-somify_keytis.hpp"
|
||||||
#include "s-somify_telis.hpp"
|
#include "s-somify_telis.hpp"
|
||||||
|
#include "s-gangqi.hpp"
|
||||||
|
#include "s-marantec24.hpp"
|
||||||
// GENIE FROM PR
|
// GENIE FROM PR
|
||||||
|
|
||||||
#ifndef __FPROTO_PROTOLISTSGZ_H__
|
#ifndef __FPROTO_PROTOLISTSGZ_H__
|
||||||
@ -104,6 +105,8 @@ class SubGhzDProtos : public FProtoListGeneral {
|
|||||||
protos[FPS_X10] = new FProtoSubGhzDX10();
|
protos[FPS_X10] = new FProtoSubGhzDX10();
|
||||||
// protos[FPS_HORMANNBISECURE] = new FProtoSubGhzDHormannBiSecure(); //fm
|
// protos[FPS_HORMANNBISECURE] = new FProtoSubGhzDHormannBiSecure(); //fm
|
||||||
protos[FPS_LEGRAND] = new FProtoSubGhzDLegrand();
|
protos[FPS_LEGRAND] = new FProtoSubGhzDLegrand();
|
||||||
|
protos[FPS_GANGQI] = new FProtoSubGhzDGangqi();
|
||||||
|
protos[FPS_MARANTEC24] = new FProtoSubGhzDMarantec24();
|
||||||
|
|
||||||
for (uint8_t i = 0; i < FPS_COUNT; ++i) {
|
for (uint8_t i = 0; i < FPS_COUNT; ++i) {
|
||||||
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
|
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
|
||||||
@ -120,7 +123,7 @@ class SubGhzDProtos : public FProtoListGeneral {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void callbackTarget(FProtoSubGhzDBase* instance) {
|
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);
|
shared_memory.application_queue.push(packet_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,8 @@ enum FPROTO_SUBGHZD_SENSOR : uint8_t {
|
|||||||
FPS_X10,
|
FPS_X10,
|
||||||
FPS_SOMIFY_KEYTIS,
|
FPS_SOMIFY_KEYTIS,
|
||||||
FPS_SOMIFY_TELIS,
|
FPS_SOMIFY_TELIS,
|
||||||
|
FPS_GANGQI,
|
||||||
|
FPS_MARANTEC24,
|
||||||
FPS_COUNT
|
FPS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,9 +80,6 @@ class FProtoWeatherAcurite592TXR : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_acurite_592txr_check_crc()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -138,17 +135,6 @@ class FProtoWeatherAcurite592TXR : public FProtoWeatherBase {
|
|||||||
return false;
|
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
|
#endif
|
||||||
|
@ -73,9 +73,6 @@ class FProtoWeatherAcurite5in1 : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||||
ws_protocol_acurite_5n1_check_crc() &&
|
ws_protocol_acurite_5n1_check_crc() &&
|
||||||
ws_protocol_acurite_5n1_check_message_type()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -133,17 +130,6 @@ class FProtoWeatherAcurite5in1 : public FProtoWeatherBase {
|
|||||||
return false;
|
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
|
#endif
|
||||||
|
@ -48,9 +48,6 @@ class FProtoWeatherAcurite606TX : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_acurite_606tx_check()) {
|
ws_protocol_acurite_606tx_check()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
ws_protocol_acurite_606tx_remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -83,17 +80,6 @@ class FProtoWeatherAcurite606TX : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 150;
|
uint32_t te_delta = 150;
|
||||||
uint32_t min_count_bit_for_found = 32;
|
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() {
|
bool ws_protocol_acurite_606tx_check() {
|
||||||
if (!decode_data) return false;
|
if (!decode_data) return false;
|
||||||
uint8_t msg[] = {
|
uint8_t msg[] = {
|
||||||
|
@ -44,9 +44,6 @@ class FProtoWeatherAcurite609TX : public FProtoWeatherBase {
|
|||||||
// Found syncPostfix
|
// Found syncPostfix
|
||||||
parser_step = Acurite_609TXCDecoderStepReset;
|
parser_step = Acurite_609TXCDecoderStepReset;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_acurite_609txc_check()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -76,19 +73,6 @@ class FProtoWeatherAcurite609TX : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 150;
|
uint32_t te_delta = 150;
|
||||||
uint32_t min_count_bit_for_found = 32;
|
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() {
|
bool ws_protocol_acurite_609txc_check() {
|
||||||
if (!decode_data) return false;
|
if (!decode_data) return false;
|
||||||
uint8_t crc = (uint8_t)(decode_data >> 32) +
|
uint8_t crc = (uint8_t)(decode_data >> 32) +
|
||||||
|
@ -84,9 +84,6 @@ class FProtoWeatherAcurite986 : public FProtoWeatherBase {
|
|||||||
// Found syncPostfix
|
// Found syncPostfix
|
||||||
parser_step = Acurite_986DecoderStepReset;
|
parser_step = Acurite_986DecoderStepReset;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_acurite_986_check()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -105,22 +102,6 @@ class FProtoWeatherAcurite986 : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 50;
|
uint32_t te_delta = 50;
|
||||||
uint32_t min_count_bit_for_found = 40;
|
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() {
|
bool ws_protocol_acurite_986_check() {
|
||||||
if (!decode_data) return false;
|
if (!decode_data) return false;
|
||||||
uint8_t msg[] = {
|
uint8_t msg[] = {
|
||||||
|
@ -42,9 +42,6 @@ class FProtoWeatherAmbient : public FProtoWeatherBase {
|
|||||||
if (((decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == AMBIENT_WEATHER_PACKET_HEADER_1) ||
|
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)) {
|
((decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == AMBIENT_WEATHER_PACKET_HEADER_2)) {
|
||||||
if (ws_protocol_ambient_weather_check_crc()) {
|
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);
|
if (callback) callback(this);
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
decode_count_bit = 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;
|
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_lfsr_digest8(msg, 5, 0x98, 0x3e) ^ 0x64;
|
||||||
return (crc == (uint8_t)(decode_data & 0xFF));
|
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
|
#endif
|
||||||
|
@ -48,9 +48,6 @@ class FProtoWeatherAuriolAhfl : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_auriol_ahfl_check()) {
|
ws_protocol_auriol_ahfl_check()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
ws_protocol_auriol_ahfl_remote_controller();
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(this);
|
callback(this);
|
||||||
}
|
}
|
||||||
@ -88,19 +85,6 @@ class FProtoWeatherAuriolAhfl : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 150;
|
uint32_t te_delta = 150;
|
||||||
uint32_t min_count_bit_for_found = 42;
|
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() {
|
bool ws_protocol_auriol_ahfl_check() {
|
||||||
uint8_t type = (decode_data >> 6) & 0x0F;
|
uint8_t type = (decode_data >> 6) & 0x0F;
|
||||||
if (type != AURIOL_AHFL_CONST_DATA) {
|
if (type != AURIOL_AHFL_CONST_DATA) {
|
||||||
|
@ -47,9 +47,6 @@ class FProtoWeatherAuriolTh : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_auriol_th_check()) {
|
ws_protocol_auriol_th_check()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
ws_protocol_auriol_th_remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
parser_step = auriol_THDecoderStepCheckDuration;
|
parser_step = auriol_THDecoderStepCheckDuration;
|
||||||
}
|
}
|
||||||
@ -87,18 +84,6 @@ class FProtoWeatherAuriolTh : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 150;
|
uint32_t te_delta = 150;
|
||||||
uint32_t min_count_bit_for_found = 37;
|
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() {
|
bool ws_protocol_auriol_th_check() {
|
||||||
uint8_t type = (decode_data >> 8) & 0x0F;
|
uint8_t type = (decode_data >> 8) & 0x0F;
|
||||||
|
|
||||||
|
@ -81,9 +81,7 @@ class FProtoWeatherEmosE601x : public FProtoWeatherBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (decode_count_bit == 120) {
|
if (decode_count_bit == 120) {
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
if (ws_protocol_emose601x_check()) {
|
if (ws_protocol_emose601x_check()) {
|
||||||
ws_protocol_emose601x_extract_data();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -127,20 +125,6 @@ class FProtoWeatherEmosE601x : public FProtoWeatherBase {
|
|||||||
uint8_t sum = FProtoGeneral::subghz_protocol_blocks_add_bytes(msg, 13);
|
uint8_t sum = FProtoGeneral::subghz_protocol_blocks_add_bytes(msg, 13);
|
||||||
return (sum == ((decode_data >> 8) & 0xff));
|
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
|
#endif
|
||||||
|
@ -50,9 +50,6 @@ class FProtoWeatherGTWT02 : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_gt_wt_02_check()) {
|
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);
|
if (callback) callback(this);
|
||||||
} else if (decode_count_bit == 1) {
|
} else if (decode_count_bit == 1) {
|
||||||
parser_step = GT_WT02DecoderStepSaveDuration;
|
parser_step = GT_WT02DecoderStepSaveDuration;
|
||||||
@ -88,25 +85,6 @@ class FProtoWeatherGTWT02 : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 150;
|
uint32_t te_delta = 150;
|
||||||
uint32_t min_count_bit_for_found = 37;
|
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() {
|
bool ws_protocol_gt_wt_02_check() {
|
||||||
if (!decode_data) return false;
|
if (!decode_data) return false;
|
||||||
uint8_t sum = (decode_data >> 5) & 0xe;
|
uint8_t sum = (decode_data >> 5) & 0xe;
|
||||||
|
@ -77,9 +77,6 @@ class FProtoWeatherGTWT03 : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_gt_wt_03_check_crc()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -113,27 +110,6 @@ class FProtoWeatherGTWT03 : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 120;
|
uint32_t te_delta = 120;
|
||||||
uint32_t min_count_bit_for_found = 41;
|
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() {
|
bool ws_protocol_gt_wt_03_check_crc() {
|
||||||
uint8_t msg[] = {
|
uint8_t msg[] = {
|
||||||
static_cast<uint8_t>(decode_data >> 33),
|
static_cast<uint8_t>(decode_data >> 33),
|
||||||
|
@ -71,9 +71,6 @@ class FProtoWeatherInfactory : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_infactory_check_crc()) {
|
ws_protocol_infactory_check_crc()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
ws_protocol_infactory_remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -122,13 +119,6 @@ class FProtoWeatherInfactory : public FProtoWeatherBase {
|
|||||||
crc ^= msg[4] >> 4; // last nibble is only XORed
|
crc ^= msg[4] >> 4; // last nibble is only XORed
|
||||||
return (crc == ((decode_data >> 28) & 0x0F));
|
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
|
#endif
|
||||||
|
@ -78,9 +78,6 @@ class FProtoWeatherKedsum : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_kedsum_th_check_crc()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -127,20 +124,6 @@ class FProtoWeatherKedsum : public FProtoWeatherBase {
|
|||||||
crc ^= msg[4] >> 4; // last nibble is only XORed
|
crc ^= msg[4] >> 4; // last nibble is only XORed
|
||||||
return (crc == (msg[4] & 0x0F));
|
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
|
#endif
|
||||||
|
@ -79,9 +79,6 @@ class FProtoWeatherLaCrosseTx : public FProtoWeatherBase {
|
|||||||
if ((decode_data & LACROSSE_TX_SUNC_MASK) ==
|
if ((decode_data & LACROSSE_TX_SUNC_MASK) ==
|
||||||
LACROSSE_TX_SUNC_PATTERN) {
|
LACROSSE_TX_SUNC_PATTERN) {
|
||||||
if (ws_protocol_lacrosse_tx_check_crc()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,28 +116,6 @@ class FProtoWeatherLaCrosseTx : public FProtoWeatherBase {
|
|||||||
uint32_t te_delta = 120;
|
uint32_t te_delta = 120;
|
||||||
uint32_t min_count_bit_for_found = 40;
|
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() {
|
bool ws_protocol_lacrosse_tx_check_crc() {
|
||||||
if (!decode_data) return false;
|
if (!decode_data) return false;
|
||||||
uint8_t msg[] = {
|
uint8_t msg[] = {
|
||||||
|
@ -67,9 +67,9 @@ class FProtoWeatherLaCrosseTx141thbv2 : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit == min_count_bit_for_found) ||
|
if ((decode_count_bit == min_count_bit_for_found) ||
|
||||||
(decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT)) {
|
(decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT)) {
|
||||||
if (ws_protocol_lacrosse_tx141thbv2_check_crc()) {
|
if (ws_protocol_lacrosse_tx141thbv2_check_crc()) {
|
||||||
data = decode_data;
|
if (decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) {
|
||||||
data_count_bit = decode_count_bit;
|
decode_data >>= 1;
|
||||||
ws_protocol_lacrosse_tx141thbv2_remote_controller();
|
}
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
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);
|
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_lfsr_digest8_reflect(msg, 4, 0x31, 0xF4);
|
||||||
return (crc == (data & 0xFF));
|
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 ws_protocol_decoder_lacrosse_tx141thbv2_add_bit(uint32_t te_last, uint32_t te_current) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (DURATION_DIFF(te_last + te_current, te_short + te_long) < te_delta * 2) {
|
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;
|
parser_step = Nexus_THDecoderStepReset;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||||
ws_protocol_nexus_th_check()) {
|
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);
|
if (callback) callback((FProtoWeatherBase*)this);
|
||||||
parser_step = Nexus_THDecoderStepCheckDuration;
|
parser_step = Nexus_THDecoderStepCheckDuration;
|
||||||
}
|
}
|
||||||
@ -98,23 +95,6 @@ class FProtoWeatherNexusTH : public FProtoWeatherBase {
|
|||||||
}
|
}
|
||||||
return true;
|
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
|
#endif
|
||||||
|
@ -107,7 +107,6 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
|||||||
// waiting for fixed oregon2 data
|
// waiting for fixed oregon2 data
|
||||||
if (decode_count_bit == 32) {
|
if (decode_count_bit == 32) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
decode_data = 0UL;
|
decode_data = 0UL;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
|
|
||||||
@ -117,13 +116,13 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
|||||||
data = (data & 0x33333333) << 2 |
|
data = (data & 0x33333333) << 2 |
|
||||||
(data & 0xCCCCCCCC) >> 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));
|
var_bits = oregon2_sensor_id_var_bits(OREGON2_SENSOR_ID(data));
|
||||||
|
|
||||||
if (!var_bits) {
|
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;
|
parser_step = Oregon2DecoderStepReset;
|
||||||
if (callback) callback(this);
|
// if (callback) callback(this);
|
||||||
} else {
|
} else {
|
||||||
parser_step = Oregon2DecoderStepVarData;
|
parser_step = Oregon2DecoderStepVarData;
|
||||||
}
|
}
|
||||||
@ -139,8 +138,8 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
|||||||
(var_data & 0xAAAAAAAA) >> 1;
|
(var_data & 0xAAAAAAAA) >> 1;
|
||||||
var_data = (var_data & 0x33333333) << 2 |
|
var_data = (var_data & 0x33333333) << 2 |
|
||||||
(var_data & 0xCCCCCCCC) >> 2;
|
(var_data & 0xCCCCCCCC) >> 2;
|
||||||
|
decode_data = var_data;
|
||||||
ws_oregon2_decode_var_data(OREGON2_SENSOR_ID(data), var_data >> OREGON2_CHECKSUM_BITS);
|
// ws_oregon2_decode_var_data(OREGON2_SENSOR_ID(data), var_data >> OREGON2_CHECKSUM_BITS); //a bit stepback, but will work
|
||||||
|
|
||||||
parser_step = Oregon2DecoderStepReset;
|
parser_step = Oregon2DecoderStepReset;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
@ -155,6 +154,7 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
|||||||
uint32_t te_long = 1000;
|
uint32_t te_long = 1000;
|
||||||
uint32_t te_delta = 200;
|
uint32_t te_delta = 200;
|
||||||
uint32_t min_count_bit_for_found = 32;
|
uint32_t min_count_bit_for_found = 32;
|
||||||
|
uint64_t data = 0;
|
||||||
|
|
||||||
bool have_bit = false;
|
bool have_bit = false;
|
||||||
bool prev_bit = 0;
|
bool prev_bit = 0;
|
||||||
@ -202,19 +202,21 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ws_oregon2_decode_const_data() {
|
/* void ws_oregon2_decode_const_data() {
|
||||||
id = OREGON2_SENSOR_ID(data);
|
id = OREGON2_SENSOR_ID(data);
|
||||||
uint8_t ch_bits = (data >> 12) & 0xF;
|
uint8_t ch_bits = (data >> 12) & 0xF;
|
||||||
channel = 1;
|
channel = 1;
|
||||||
while (ch_bits > 1) {
|
while (ch_bits > 1) {
|
||||||
channel++;
|
channel++;
|
||||||
ch_bits >>= 1;
|
ch_bits >>= 1;
|
||||||
}
|
}
|
||||||
battery_low = (data & OREGON2_FLAG_BAT_LOW) ? 1 : 0;
|
battery_low = (data & OREGON2_FLAG_BAT_LOW) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bcd_decode_short(uint32_t data) {
|
uint16_t bcd_decode_short(uint32_t data) {
|
||||||
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
|
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ws_oregon2_decode_temp(uint32_t data) {
|
float ws_oregon2_decode_temp(uint32_t data) {
|
||||||
int32_t temp_val;
|
int32_t temp_val;
|
||||||
temp_val = bcd_decode_short(data >> 4);
|
temp_val = bcd_decode_short(data >> 4);
|
||||||
@ -241,7 +243,7 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -66,7 +66,6 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
|||||||
// waiting for fixed oregon3 data
|
// waiting for fixed oregon3 data
|
||||||
if (decode_count_bit == OREGON3_FIXED_PART_BITS) {
|
if (decode_count_bit == OREGON3_FIXED_PART_BITS) {
|
||||||
data = decode_data;
|
data = decode_data;
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
decode_data = 0UL;
|
decode_data = 0UL;
|
||||||
decode_count_bit = 0;
|
decode_count_bit = 0;
|
||||||
|
|
||||||
@ -76,9 +75,8 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
|||||||
data = (data & 0x33333333) << 2 |
|
data = (data & 0x33333333) << 2 |
|
||||||
(data & 0xCCCCCCCC) >> 2;
|
(data & 0xCCCCCCCC) >> 2;
|
||||||
|
|
||||||
ws_oregon3_decode_const_data();
|
// ws_oregon3_decode_const_data(); //todo fix somehow in the future
|
||||||
var_bits =
|
var_bits = oregon3_sensor_id_var_bits(OREGON3_SENSOR_ID(data));
|
||||||
oregon3_sensor_id_var_bits(OREGON3_SENSOR_ID(data));
|
|
||||||
|
|
||||||
if (!var_bits) {
|
if (!var_bits) {
|
||||||
// sensor is not supported, stop decoding
|
// sensor is not supported, stop decoding
|
||||||
@ -98,8 +96,8 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
|||||||
(var_data & 0xAAAAAAAAAAAAAAAA) >> 1;
|
(var_data & 0xAAAAAAAAAAAAAAAA) >> 1;
|
||||||
var_data = (var_data & 0x3333333333333333) << 2 |
|
var_data = (var_data & 0x3333333333333333) << 2 |
|
||||||
(var_data & 0xCCCCCCCCCCCCCCCC) >> 2;
|
(var_data & 0xCCCCCCCCCCCCCCCC) >> 2;
|
||||||
|
decode_data = var_data;
|
||||||
ws_oregon3_decode_var_data(OREGON3_SENSOR_ID(data), var_data >> OREGON3_CHECKSUM_BITS);
|
// ws_oregon3_decode_var_data(OREGON3_SENSOR_ID(data), var_data >> OREGON3_CHECKSUM_BITS);
|
||||||
parser_step = Oregon3DecoderStepReset;
|
parser_step = Oregon3DecoderStepReset;
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
@ -113,6 +111,7 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
|||||||
uint32_t te_long = 1100;
|
uint32_t te_long = 1100;
|
||||||
uint32_t te_delta = 300;
|
uint32_t te_delta = 300;
|
||||||
uint32_t min_count_bit_for_found = 32;
|
uint32_t min_count_bit_for_found = 32;
|
||||||
|
uint64_t data = 0;
|
||||||
|
|
||||||
bool prev_bit = false;
|
bool prev_bit = false;
|
||||||
uint8_t var_bits{0};
|
uint8_t var_bits{0};
|
||||||
@ -143,31 +142,31 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ws_oregon3_decode_const_data() {
|
/* void ws_oregon3_decode_const_data() {
|
||||||
id = OREGON3_SENSOR_ID(data);
|
id = OREGON3_SENSOR_ID(data);
|
||||||
channel = (data >> 12) & 0xF;
|
channel = (data >> 12) & 0xF;
|
||||||
battery_low = (data & OREGON3_FLAG_BAT_LOW) ? 1 : 0;
|
battery_low = (data & OREGON3_FLAG_BAT_LOW) ? 1 : 0;
|
||||||
}
|
}
|
||||||
uint16_t ws_oregon3_bcd_decode_short(uint32_t data) {
|
uint16_t ws_oregon3_bcd_decode_short(uint32_t data) {
|
||||||
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
|
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
|
||||||
}
|
}
|
||||||
float ws_oregon3_decode_temp(uint32_t data) {
|
float ws_oregon3_decode_temp(uint32_t data) {
|
||||||
int32_t temp_val;
|
int32_t temp_val;
|
||||||
temp_val = ws_oregon3_bcd_decode_short(data >> 4);
|
temp_val = ws_oregon3_bcd_decode_short(data >> 4);
|
||||||
temp_val *= 10;
|
temp_val *= 10;
|
||||||
temp_val += (data >> 12) & 0xF;
|
temp_val += (data >> 12) & 0xF;
|
||||||
if (data & 0xF) temp_val = -temp_val;
|
if (data & 0xF) temp_val = -temp_val;
|
||||||
return (float)temp_val / 10.0;
|
return (float)temp_val / 10.0;
|
||||||
}
|
}
|
||||||
void ws_oregon3_decode_var_data(uint16_t sensor_id, uint32_t data) {
|
void ws_oregon3_decode_var_data(uint16_t sensor_id, uint32_t data) {
|
||||||
switch (sensor_id) {
|
switch (sensor_id) {
|
||||||
case ID_THGR221:
|
case ID_THGR221:
|
||||||
default:
|
default:
|
||||||
humidity = ws_oregon3_bcd_decode_short(data >> 4);
|
humidity = ws_oregon3_bcd_decode_short(data >> 4);
|
||||||
temp = ws_oregon3_decode_temp(data >> 12);
|
temp = ws_oregon3_decode_temp(data >> 12);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -102,9 +102,6 @@ class FProtoWeatherOregonV1 : public FProtoWeatherBase {
|
|||||||
decode_data = ~decode_data | (1 << 31);
|
decode_data = ~decode_data | (1 << 31);
|
||||||
}
|
}
|
||||||
if (ws_protocol_oregon_v1_check()) {
|
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);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,22 +142,6 @@ class FProtoWeatherOregonV1 : public FProtoWeatherBase {
|
|||||||
crc = (crc & 0xff) + ((crc >> 8) & 0xff);
|
crc = (crc & 0xff) + ((crc >> 8) & 0xff);
|
||||||
return (crc == ((data >> 24) & 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
|
#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;
|
parser_step = ThermoPRO_TX4DecoderStepReset;
|
||||||
if ((decode_count_bit == min_count_bit_for_found) &&
|
if ((decode_count_bit == min_count_bit_for_found) &&
|
||||||
ws_protocol_thermopro_tx4_check()) {
|
ws_protocol_thermopro_tx4_check()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
ws_protocol_thermopro_tx4_remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
parser_step = ThermoPRO_TX4DecoderStepCheckDuration;
|
parser_step = ThermoPRO_TX4DecoderStepCheckDuration;
|
||||||
}
|
}
|
||||||
@ -92,19 +89,6 @@ class FProtoWeatherThermoProTx4 : public FProtoWeatherBase {
|
|||||||
return false;
|
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
|
#endif
|
||||||
|
@ -51,12 +51,8 @@ class FProtoWeatherTX8300 : public FProtoWeatherBase {
|
|||||||
if (!level) {
|
if (!level) {
|
||||||
if (duration >= ((uint32_t)te_short * 5)) {
|
if (duration >= ((uint32_t)te_short * 5)) {
|
||||||
// Found syncPostfix
|
// Found syncPostfix
|
||||||
if ((decode_count_bit ==
|
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_tx_8300_check_crc()) {
|
||||||
min_count_bit_for_found) &&
|
decode_data = package_1;
|
||||||
ws_protocol_tx_8300_check_crc()) {
|
|
||||||
data = package_1;
|
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
ws_protocol_tx_8300_remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
decode_data = 0;
|
decode_data = 0;
|
||||||
@ -118,23 +114,6 @@ class FProtoWeatherTX8300 : public FProtoWeatherBase {
|
|||||||
uint8_t crc = (~x & 0xF) << 4 | (~y & 0xF);
|
uint8_t crc = (~x & 0xF) << 4 | (~y & 0xF);
|
||||||
return (crc == (decode_data & 0xFF));
|
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
|
#endif
|
||||||
|
@ -82,9 +82,6 @@ class FProtoWeatherWendoxW6726 : public FProtoWeatherBase {
|
|||||||
if ((decode_count_bit ==
|
if ((decode_count_bit ==
|
||||||
min_count_bit_for_found) &&
|
min_count_bit_for_found) &&
|
||||||
ws_protocol_wendox_w6726_check()) {
|
ws_protocol_wendox_w6726_check()) {
|
||||||
data = decode_data;
|
|
||||||
data_count_bit = decode_count_bit;
|
|
||||||
ws_protocol_wendox_w6726_remote_controller();
|
|
||||||
if (callback) callback(this);
|
if (callback) callback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,24 +128,6 @@ class FProtoWeatherWendoxW6726 : public FProtoWeatherBase {
|
|||||||
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_crc4(msg, 4, 0x9, 0xD);
|
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_crc4(msg, 4, 0x9, 0xD);
|
||||||
return (crc == (decode_data & 0x0F));
|
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
|
#endif
|
||||||
|
@ -24,11 +24,7 @@ class FProtoWeatherBase {
|
|||||||
void setCallback(SubGhzProtocolDecoderBaseRxCallback cb) { callback = cb; } // this is called when there is a hit.
|
void setCallback(SubGhzProtocolDecoderBaseRxCallback cb) { callback = cb; } // this is called when there is a hit.
|
||||||
|
|
||||||
uint8_t getSensorType() { return sensorType; }
|
uint8_t getSensorType() { return sensorType; }
|
||||||
uint8_t getHumidity() { return humidity; }
|
uint64_t getData() { return decode_data; }
|
||||||
uint8_t getBattLow() { return battery_low; }
|
|
||||||
uint8_t getChannel() { return channel; }
|
|
||||||
uint32_t getSensorId() { return id; }
|
|
||||||
float getTemp() { return temp; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Helper functions to keep it as compatible with flipper as we can, so adding new protos will be easy.
|
// 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!
|
// needs to be in this chaotic order, to save flash!
|
||||||
// General weather data holder
|
// General weather data holder
|
||||||
uint8_t sensorType = FPW_Invalid;
|
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
|
// inner logic stuff
|
||||||
uint8_t parser_step = 0;
|
uint8_t parser_step = 0;
|
||||||
// inner logic stuff, also for flipper compatibility.
|
// inner logic stuff, also for flipper compatibility.
|
||||||
uint16_t header_count = 0;
|
uint16_t header_count = 0;
|
||||||
// General weather data holder
|
|
||||||
float temp = WS_NO_TEMPERATURE;
|
|
||||||
uint32_t id = WS_NO_ID;
|
|
||||||
// inner logic stuff,
|
// inner logic stuff,
|
||||||
|
|
||||||
uint32_t te_last = 0;
|
uint32_t te_last = 0;
|
||||||
uint32_t data_count_bit = 0;
|
|
||||||
uint32_t decode_count_bit = 0;
|
uint32_t decode_count_bit = 0;
|
||||||
uint64_t decode_data = 0;
|
uint64_t decode_data = 0;
|
||||||
uint64_t data = 0;
|
|
||||||
SubGhzProtocolDecoderBaseRxCallback callback = NULL;
|
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-kedsum.hpp"
|
||||||
#include "w-acurite5in1.hpp"
|
#include "w-acurite5in1.hpp"
|
||||||
#include "w-emose601x.hpp"
|
#include "w-emose601x.hpp"
|
||||||
|
#include "w-solight_te44.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -64,6 +65,7 @@ class WeatherProtos : public FProtoListGeneral {
|
|||||||
protos[FPW_KEDSUM] = new FProtoWeatherKedsum();
|
protos[FPW_KEDSUM] = new FProtoWeatherKedsum();
|
||||||
protos[FPW_Acurite5in1] = new FProtoWeatherAcurite5in1();
|
protos[FPW_Acurite5in1] = new FProtoWeatherAcurite5in1();
|
||||||
protos[FPW_EmosE601x] = new FProtoWeatherEmosE601x();
|
protos[FPW_EmosE601x] = new FProtoWeatherEmosE601x();
|
||||||
|
protos[FPW_SolightTE44] = new FProtoWeatherSolightTE44();
|
||||||
|
|
||||||
// set callback for them
|
// set callback for them
|
||||||
for (uint8_t i = 0; i < FPW_COUNT; ++i) {
|
for (uint8_t i = 0; i < FPW_COUNT; ++i) {
|
||||||
@ -81,9 +83,7 @@ class WeatherProtos : public FProtoListGeneral {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void callbackTarget(FProtoWeatherBase* instance) {
|
static void callbackTarget(FProtoWeatherBase* instance) {
|
||||||
WeatherDataMessage packet_message{instance->getSensorType(), instance->getSensorId(),
|
WeatherDataMessage packet_message{instance->getSensorType(), instance->getData()};
|
||||||
instance->getTemp(), instance->getHumidity(), instance->getBattLow(),
|
|
||||||
instance->getChannel()};
|
|
||||||
shared_memory.application_queue.push(packet_message);
|
shared_memory.application_queue.push(packet_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ enum FPROTO_WEATHER_SENSOR {
|
|||||||
FPW_KEDSUM = 20,
|
FPW_KEDSUM = 20,
|
||||||
FPW_Acurite5in1 = 21,
|
FPW_Acurite5in1 = 21,
|
||||||
FPW_EmosE601x = 22,
|
FPW_EmosE601x = 22,
|
||||||
|
FPW_SolightTE44 = 23,
|
||||||
FPW_COUNT // this must be the last
|
FPW_COUNT // this must be the last
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1265,25 +1265,13 @@ class WeatherDataMessage : public Message {
|
|||||||
public:
|
public:
|
||||||
constexpr WeatherDataMessage(
|
constexpr WeatherDataMessage(
|
||||||
uint8_t sensorType = 0,
|
uint8_t sensorType = 0,
|
||||||
uint32_t id = 0xFFFFFFFF,
|
uint64_t decode_data = 0xFFFFFFFF)
|
||||||
float temp = -273.0f,
|
|
||||||
uint8_t humidity = 0xFF,
|
|
||||||
uint8_t battery_low = 0xFF,
|
|
||||||
uint8_t channel = 0xFF)
|
|
||||||
: Message{ID::WeatherData},
|
: Message{ID::WeatherData},
|
||||||
sensorType{sensorType},
|
sensorType{sensorType},
|
||||||
id{id},
|
decode_data{decode_data} {
|
||||||
temp{temp},
|
|
||||||
humidity{humidity},
|
|
||||||
battery_low{battery_low},
|
|
||||||
channel{channel} {
|
|
||||||
}
|
}
|
||||||
uint8_t sensorType = 0;
|
uint8_t sensorType = 0;
|
||||||
uint32_t id = 0xFFFFFFFF;
|
uint64_t decode_data = 0;
|
||||||
float temp = -273.0f;
|
|
||||||
uint8_t humidity = 0xFF;
|
|
||||||
uint8_t battery_low = 0xFF;
|
|
||||||
uint8_t channel = 0xFF;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SubGhzDDataMessage : public Message {
|
class SubGhzDDataMessage : public Message {
|
||||||
|
Loading…
Reference in New Issue
Block a user