Compare commits

...

7 Commits

Author SHA1 Message Date
Totoo e6afd7744d SubghzD & Weather improvments (#2237)
* Weather restructure

* Added Solight TE44 protocol

* Add disabled Marantec24, and GangQi

* More opt in subghzd
2024-09-06 20:23:11 +02:00
Dongping Guo (Donny) 76763b9bab Add BLE RX filter options (#2236) 2024-09-06 20:22:00 +02:00
Totoo 02b75f567a Setfreq usb command (#2235)
* SetFreq usb command for rx apps
* code format, better check
2024-09-04 20:26:31 +02:00
Erwin Ried a2c4fefe34 Slighty smaller video on readme 2024-09-03 09:27:22 +02:00
Erwin Ried 121352b149 Fully remove references to bountysource + ltt video (#2233)
-Permanently remove the references to the bountysource scammers
-Added LTT video about the device
2024-09-02 21:47:11 +08:00
Totoo 0ae7768f20 Battery info switcher (#2230) 2024-08-28 11:32:24 +02:00
jLynx 1a0555f9eb Update README.md 2024-08-27 22:38:39 +12:00
117 changed files with 1104 additions and 576 deletions
+6 -11
View File
@@ -1,6 +1,7 @@
> [!WARNING]
> __IF YOU'VE PAID FOR MAYHEM OR ANY PREPACKAGED PACKAGES, YOU'RE BEING SCAMMED.__
> The only legitimate link leading to our repositories is the organization [portapack-mayhem](https://github.com/portapack-mayhem/mayhem-firmware).
> __IF YOU'VE PAID FOR MAYHEM OR ANY PREPACKAGED VERSIONS, YOU'RE BEING SCAMMED.__
>
> The only legitimate link to our repositories is the [portapack-mayhem](https://github.com/portapack-mayhem/mayhem-firmware) organization on GitHub.
# PortaPack Mayhem
@@ -16,9 +17,9 @@ This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/) firmw
If you are new to *HackRF+PortaPack+Mayhem*, check these:
[<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="512">](https://grabify.link/9UZGEW)
[<img alt="Its TOO Easy to Accidentally Do Illegal Stuff with This" src="https://img.youtube.com/vi/OPckpjBSAOw/maxresdefault.jpg" width="700">](https://grabify.link/X4D5TF)
[<img alt="Beginner's Guide To The HackRF & Portapak With Mayhem" src="https://img.youtube.com/vi/H-bqdWfbhpg/maxresdefault.jpg" width="254">](https://grabify.link/5MU2VH) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="254">](https://grabify.link/C0J6ZR)
[<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="230">](https://grabify.link/9UZGEW) [<img alt="Beginner's Guide To The HackRF & Portapak With Mayhem" src="https://img.youtube.com/vi/H-bqdWfbhpg/maxresdefault.jpg" width="230">](https://grabify.link/5MU2VH) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="230">](https://grabify.link/C0J6ZR)
# Frequently Asked Questions
@@ -54,13 +55,7 @@ Consider that the hardware and firmware has been created and maintain by a [lot]
To support the people behind the hardware, please buy a genuine [HackRF](https://greatscottgadgets.com/hackrf/) and [PortaPack](https://store.sharebrained.com/products/portapack-for-hackrf-one-kit).
## What if I really want something specific?
If what you need can be relevant in general, you can [request a feature](https://github.com/portapack-mayhem/mayhem-firmware/issues/new?labels=enhancement&template=feature_request.md).
<del>You can create a bounty and invite people to your own bounty. This will incentivize coders to work on a new feature, solving a bug or even writting documentation. Start a bounty by [creating](https://github.com/portapack-mayhem/mayhem-firmware/issues/new/choose) or [choosing](https://github.com/portapack-mayhem/mayhem-firmware/issues/) an existing issue. Then, go to [Bountysource](https://www.bountysource.com/) and post a bounty using the link to that specific [issue](https://www.bountysource.com/teams/portapack-mayhem/issues).</del>
<del>Promote your bounty over our Discord by clicking the chat badge on [top](#portapack-mayhem).</del>
Bountysource has not been reliable lately, so until this changes, please **DO NOT** post a bounty there. Go to our Discord by clicking the chat badge on [top](#portapack-mayhem) and discuss there.
If what you need can be relevant in general, you can [request a feature](https://github.com/portapack-mayhem/mayhem-firmware/issues/new?labels=enhancement&template=feature_request.md). Alternatively, go to our Discord by clicking the chat badge on [top](#portapack-mayhem) and discuss there.
## What if I need help?
First, check the [documentation](https://github.com/portapack-mayhem/mayhem-firmware/wiki). If you find a bug or you think the problem is related to the current repository, please open an [issue](https://github.com/portapack-mayhem/mayhem-firmware/issues/new/choose).
@@ -435,4 +435,7 @@ void AnalogAudioView::handle_coded_squelch(uint32_t value) {
text_ctcss.set(tone_key_string_by_value(value, text_ctcss.parent_rect().width() / 8));
}
void AnalogAudioView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
} /* namespace ui */
@@ -247,12 +247,21 @@ class AnalogAudioView : public View {
void handle_coded_squelch(uint32_t value);
void on_freqchg(int64_t freq);
MessageHandlerRegistration message_handler_coded_squelch{
Message::ID::CodedSquelch,
[this](const Message* p) {
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
this->handle_coded_squelch(message.value);
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
};
} /* namespace ui */
+38 -9
View File
@@ -428,6 +428,7 @@ BLERxView::BLERxView(NavigationView& nav)
&text_found_count,
&check_serial_log,
&button_filter,
&options_filter,
&button_save_list,
&button_clear_list,
&button_switch,
@@ -499,6 +500,7 @@ BLERxView::BLERxView(NavigationView& nav)
check_name.on_select = [this](Checkbox&, bool v) {
name_enable = v;
// update the include_name instance variable value of each entry in recent entries
setAllMembersToValue(recent, &BleRecentEntry::include_name, v);
recent_entries_view.set_dirty();
};
@@ -525,8 +527,14 @@ BLERxView::BLERxView(NavigationView& nav)
handle_entries_sort(v);
};
options_filter.on_change = [this](size_t index, int32_t v) {
filter_index = (uint8_t)index;
handle_filter_options(v);
};
options_channel.set_selected_index(channel_index, true);
options_sort.set_selected_index(sort_index, true);
options_filter.set_selected_index(filter_index, true);
button_find.on_select = [this](Button&) {
auto open_view = nav_.push<FileLoadView>(".TXT");
@@ -716,10 +724,11 @@ void BLERxView::on_data(BlePacketData* packet) {
updateEntry(packet, entry, (ADV_PDU_TYPE)packet->type);
// Add entries if they meet the criteria.
auto value = filter;
resetFilteredEntries(recent, [&value](const BleRecentEntry& entry) {
return (entry.dataString.find(value) == std::string::npos) && (entry.nameString.find(value) == std::string::npos);
});
// auto value = filter;
// resetFilteredEntries(recent, [&value](const BleRecentEntry& entry) {
// return (entry.dataString.find(value) == std::string::npos) && (entry.nameString.find(value) == std::string::npos);
// });
handle_filter_options(options_filter.selected_index());
handle_entries_sort(options_sort.selected_index());
@@ -756,12 +765,13 @@ void BLERxView::on_data(BlePacketData* packet) {
void BLERxView::on_filter_change(std::string value) {
// New filter? Reset list from recent entries.
if (filter != value) {
resetFilteredEntries(recent, [&value](const BleRecentEntry& entry) {
return (entry.dataString.find(value) == std::string::npos) && (entry.nameString.find(value) == std::string::npos);
});
// resetFilteredEntries(recent, [&value](const BleRecentEntry& entry) {
// // return (entry.dataString.find(value) == std::string::npos) && (entry.nameString.find(value) == std::string::npos);
// return (entry.dataString.find(value) == std::string::npos) && (entry.nameString.find(value) == std::string::npos) && (to_string_mac_address(entry.packetData.macAddress, 6, false).find(value) == std::string::npos);
// });
filter = value;
handle_filter_options(options_filter.selected_index());
}
filter = value;
}
void BLERxView::on_file_changed(const std::filesystem::path& new_file_path) {
@@ -852,6 +862,24 @@ void BLERxView::handle_entries_sort(uint8_t index) {
recent_entries_view.set_dirty();
}
void BLERxView::handle_filter_options(uint8_t index) {
auto value = filter;
switch (index) {
case 0: // filter by Data
resetFilteredEntries(recent, [&value](const BleRecentEntry& entry) {
return (entry.dataString.find(value) == std::string::npos) && (entry.nameString.find(value) == std::string::npos);
});
break;
case 1: // filter by MAC address (All caps: e.g. AA:BB:CC:DD:EE:FF)
resetFilteredEntries(recent, [&value](const BleRecentEntry& entry) {
return (to_string_mac_address(entry.packetData.macAddress, 6, false).find(value) == std::string::npos);
});
break;
default:
break;
}
}
void BLERxView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
const Rect content_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height - switch_button_height};
@@ -914,6 +942,7 @@ void BLERxView::updateEntry(const BlePacketData* packet, BleRecentEntry& entry,
// Subtract 1 because type is part of the length.
for (int i = 0; i < length - 1; i++) {
// parse the name of bluetooth device: 0x08->Shortened Local Name; 0x09->Complete Local Name
if (type == 0x08 || type == 0x09) {
decoded_data += (char)advertiseData->Data[currentByte];
}
+24 -15
View File
@@ -203,6 +203,7 @@ class BLERxView : public View {
void file_error();
void on_timer();
void handle_entries_sort(uint8_t index);
void handle_filter_options(uint8_t index);
void updateEntry(const BlePacketData* packet, BleRecentEntry& entry, ADV_PDU_TYPE pdu_type);
NavigationView& nav_;
@@ -214,6 +215,7 @@ class BLERxView : public View {
uint8_t channel_index{0};
uint8_t sort_index{0};
uint8_t filter_index{0};
std::string filter{};
bool logging{false};
bool serial_logging{false};
@@ -227,6 +229,7 @@ class BLERxView : public View {
{"sort_index"sv, &sort_index},
{"filter"sv, &filter},
{"log"sv, &logging},
{"filter_index"sv, &filter_index},
// disabled to always start without USB serial activated until we can make it non blocking if not connected
// {"serial_log"sv, &serial_logging},
{"name"sv, &name_enable},
@@ -255,13 +258,13 @@ class BLERxView : public View {
std::filesystem::path log_packets_path{blerx_dir / u"Logs/????.TXT"};
std::filesystem::path packet_save_path{blerx_dir / u"Lists/????.csv"};
static constexpr auto header_height = 4 * 16;
static constexpr auto header_height = 9 * 8;
static constexpr auto switch_button_height = 3 * 16;
OptionsField options_channel{
{0 * 8, 0 * 8},
5,
{{"Ch.37 ", 37},
{{"Ch.37", 37},
{"Ch.38", 38},
{"Ch.39", 39},
{"Auto", 40}}};
@@ -286,10 +289,10 @@ class BLERxView : public View {
{24 * 8, 5, 6 * 8, 4}};
Labels label_sort{
{{0 * 8, 3 * 8}, "Sort:", Theme::getInstance()->fg_light->foreground}};
{{0 * 8, 2 * 8}, "Sort:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_sort{
{5 * 8, 3 * 8},
{5 * 8, 2 * 8},
4,
{{"MAC", 0},
{"Hits", 1},
@@ -298,40 +301,46 @@ class BLERxView : public View {
{"Name", 4}}};
Button button_filter{
{11 * 8, 3 * 8, 4 * 8, 16},
"Filter"};
{11 * 8, 2 * 8, 7 * 8, 16},
"Filter:"};
OptionsField options_filter{
{18 * 8 + 2, 2 * 8},
4,
{{"Data", 0},
{"MAC", 1}}};
Checkbox check_log{
{17 * 8, 3 * 8},
{10 * 8, 4 * 8 + 2},
3,
"Log",
true};
Checkbox check_name{
{23 * 8, 3 * 8},
{0 * 8, 4 * 8 + 2},
3,
"Name",
true};
Button button_find{
{0 * 8, 6 * 8, 4 * 8, 16},
{0 * 8, 7 * 8 - 2, 4 * 8, 16},
"Find"};
Labels label_found{
{{5 * 8, 6 * 8}, "Found:", Theme::getInstance()->fg_light->foreground}};
{{5 * 8, 7 * 8 - 2}, "Found:", Theme::getInstance()->fg_light->foreground}};
Text text_found_count{
{11 * 8, 3 * 16, 20 * 8, 16},
{11 * 8, 7 * 8 - 2, 20 * 8, 16},
"0/0"};
Checkbox check_serial_log{
{17 * 8, 3 * 16 - 2},
{18 * 8 + 2, 4 * 8 + 2},
7,
"USB Log",
true};
Console console{
{0, 4 * 16, 240, 240}};
// Console console{
// {0, 10 * 8, 240, 240}};
Button button_clear_list{
{2 * 8, 320 - (16 + 32), 7 * 8, 32},
@@ -371,7 +380,7 @@ class BLERxView : public View {
[this](const Message* const) {
this->on_timer();
}};
};
}; /* BLERxView */
} /* namespace ui */
@@ -128,4 +128,8 @@ void CaptureAppView::focus() {
record_view.focus();
}
void CaptureAppView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
} /* namespace ui */
@@ -108,6 +108,15 @@ class CaptureAppView : public View {
3};
spectrum::WaterfallView waterfall{};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
};
} /* namespace ui */
+4
View File
@@ -178,4 +178,8 @@ void ERTAppView::on_show_list() {
recent_entries_view.focus();
}
void ERTAppView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
} /* namespace ui */
+8
View File
@@ -176,6 +176,14 @@ class ERTAppView : public View {
this->on_packet(packet);
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
void on_packet(const ert::Packet& packet);
void on_show_list();
};
+4
View File
@@ -321,6 +321,10 @@ void POCSAGAppView::on_stats(const POCSAGStatsMessage* stats) {
widget_frames.set_sync(stats->has_sync);
}
void POCSAGAppView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
void BaudIndicator::paint(Painter& painter) {
auto p = screen_pos();
char top = '-';
+9
View File
@@ -292,6 +292,15 @@ class POCSAGAppView : public View {
Console console{
{0, 2 * 16 + 6, screen_width, screen_height - 54}};
void on_freqchg(int64_t freq);
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
MessageHandlerRegistration message_handler_packet{
Message::ID::POCSAGPacket,
[this](Message* const p) {
+4
View File
@@ -122,6 +122,10 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect)
receiver_model.enable();
}
void APRSRxView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
void APRSRxView::on_packet(const APRSPacketMessage* message) {
std::string str_console = "\x1B";
+8
View File
@@ -185,6 +185,7 @@ class APRSRxView : public View {
std::string title() const override { return "APRS RX"; };
void on_packet(const APRSPacketMessage* message);
void on_freqchg(int64_t freq);
private:
void on_data(uint32_t value, bool is_data);
@@ -271,6 +272,13 @@ class APRSRXView : public View {
this->view_stream.on_packet(message);
this->view_table.on_pkt(message);
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->view_stream.on_freqchg(message->freq);
}};
};
} /* namespace ui */
+21 -1
View File
@@ -49,6 +49,7 @@ void BattinfoView::update_result() {
text_voltage.set("UNKNOWN");
text_current.set("-");
text_charge.set("-");
text_method.set("-");
return;
}
bool uichg = false;
@@ -78,6 +79,13 @@ void BattinfoView::update_result() {
text_current.hidden(true);
text_charge.hidden(true);
}
if ((valid_mask & battery::BatteryManagement::BATT_VALID_PERCENT) == battery::BatteryManagement::BATT_VALID_PERCENT) {
text_method.set("IC");
button_mode.set_text("Volt");
} else {
text_method.set("Voltage");
button_mode.set_text("IC");
}
if (uichg) set_dirty();
// to update status bar too, send message in behalf of batt manager
BatteryStateMessage msg{valid_mask, percent, current >= 0, voltage};
@@ -92,12 +100,24 @@ BattinfoView::BattinfoView(NavigationView& nav)
&text_voltage,
&text_current,
&text_charge,
&text_method,
&button_mode,
&button_exit});
button_exit.on_select = [this, &nav](Button&) {
nav.pop();
};
button_mode.on_select = [this, &nav](Button&) {
if (button_mode.text() == "IC") {
battery::BatteryManagement::set_calc_override(false);
persistent_memory::set_ui_override_batt_calc(false);
button_mode.set_text("Volt");
} else {
battery::BatteryManagement::set_calc_override(true);
persistent_memory::set_ui_override_batt_calc(true);
button_mode.set_text("IC");
}
};
update_result();
if (thread == nullptr) thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, BattinfoView::static_fn, this);
}
+15 -5
View File
@@ -53,11 +53,14 @@ class BattinfoView : public View {
Labels labels{
{{2 * 8, 1 * 16}, "Percent:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 2 * 16}, "Voltage:", Theme::getInstance()->fg_light->foreground}};
{{2 * 8, 2 * 16}, "Voltage:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 3 * 16}, "Method:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 7 * 16}, "Change method:", Theme::getInstance()->fg_light->foreground},
};
Labels labels_opt{
{{2 * 8, 3 * 16}, "Current:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 4 * 16}, "Charge:", Theme::getInstance()->fg_light->foreground}};
{{2 * 8, 4 * 16}, "Current:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 5 * 16}, "Charge:", Theme::getInstance()->fg_light->foreground}};
Text text_percent{
{13 * 8, 1 * 16, 10 * 16, 16},
@@ -65,12 +68,19 @@ class BattinfoView : public View {
Text text_voltage{
{13 * 8, 2 * 16, 10 * 16, 16},
"-"};
Text text_current{
Text text_method{
{13 * 8, 3 * 16, 10 * 16, 16},
"-"};
Text text_charge{
Text text_current{
{13 * 8, 4 * 16, 10 * 16, 16},
"-"};
Text text_charge{
{13 * 8, 5 * 16, 10 * 16, 16},
"-"};
Button button_mode{
{2 * 8, 8 * 16 + 5, 5 * 16, 32},
"Volt"};
Button button_exit{
{72, 17 * 16, 96, 32},
+5
View File
@@ -323,4 +323,9 @@ void LevelView::handle_coded_squelch(const uint32_t value) {
text_ctcss.set(" ");
}
void LevelView::on_freqchg(int64_t freq) {
receiver_model.set_target_frequency(freq);
button_frequency.set_text("<" + to_string_short_freq(freq) + " MHz>");
}
} /* namespace ui */
+9
View File
@@ -188,6 +188,15 @@ class LevelView : public View {
void handle_coded_squelch(const uint32_t value);
void on_freqchg(int64_t freq);
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
MessageHandlerRegistration message_handler_coded_squelch{
Message::ID::CodedSquelch,
[this](const Message* const p) {
+27
View File
@@ -948,6 +948,32 @@ void SetThemeView::focus() {
options.focus();
}
/* SetBatteryView ************************************/
SetBatteryView::SetBatteryView(NavigationView& nav) {
add_children({&labels,
&button_save,
&button_cancel,
&checkbox_overridebatt});
button_save.on_select = [&nav, this](Button&) {
pmem::set_ui_override_batt_calc(checkbox_overridebatt.value());
battery::BatteryManagement::set_calc_override(checkbox_overridebatt.value());
send_system_refresh();
nav.pop();
};
checkbox_overridebatt.set_value(pmem::ui_override_batt_calc());
button_cancel.on_select = [&nav, this](Button&) {
nav.pop();
};
}
void SetBatteryView::focus() {
button_cancel.focus();
}
/* SettingsMenuView **************************************/
SettingsMenuView::SettingsMenuView(NavigationView& nav)
@@ -978,6 +1004,7 @@ void SettingsMenuView::on_populate() {
{"Theme", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetThemeView>(); }},
{"Autostart", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetAutostartView>(); }},
});
if (battery::BatteryManagement::isDetected()) add_item({"Battery", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetBatteryView>(); }});
}
} /* namespace ui */
+29
View File
@@ -888,6 +888,35 @@ class SetThemeView : public View {
};
};
class SetBatteryView : public View {
public:
SetBatteryView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Battery"; };
private:
int32_t selected = 0;
Labels labels{
{{1 * 8, 1 * 16}, "Override batt calculation", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "method to voltage based", Theme::getInstance()->fg_light->foreground}};
Button button_save{
{2 * 8, 16 * 16, 12 * 8, 32},
"Save"};
Checkbox checkbox_overridebatt{
{2 * 8, 6 * 16},
23,
"Override"};
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel",
};
};
class SettingsMenuView : public BtnGridView {
public:
SettingsMenuView(NavigationView& nav);
+4
View File
@@ -187,4 +187,8 @@ void SondeView::on_packet(const sonde::Packet& packet) {
}
}
void SondeView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
} /* namespace ui */
+8
View File
@@ -195,6 +195,14 @@ class SondeView : public View {
const auto message = static_cast<const OrientationDataMessage*>(p);
this->on_orientation(message);
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
void on_gps(const GPSPosDataMessage* msg);
void on_orientation(const OrientationDataMessage* msg);
+21 -1
View File
@@ -212,7 +212,10 @@ const char* SubGhzDView::getSensorTypeName(FPROTO_SUBGHZD_SENSOR type) {
return "Somify Keytis";
case FPS_SOMIFY_TELIS:
return "Somify Telis";
case FPS_GANGQI:
return "GangQi";
case FPS_MARANTEC24:
return "Marantec24";
case FPS_Invalid:
default:
return "Unknown";
@@ -224,6 +227,10 @@ std::string SubGhzDView::pad_string_with_spaces(int snakes) {
return paddedStr;
}
void SubGhzDView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
template <>
void RecentEntriesTable<ui::SubGhzDRecentEntries>::draw(
const Entry& entry,
@@ -713,5 +720,18 @@ void SubGhzDRecentEntryDetailView::parseProtocol() {
serial = dataa & 0xFFFFFF; // address}
return;
}
if (entry_.sensorType == FPS_GANGQI) {
btn = 0; // parser needs some time i think in flipper side.
cnt = (uint8_t)(entry_.data >> 32);
serial = (entry_.data & 0xFFFFFFFF);
return;
}
if (entry_.sensorType == FPS_MARANTEC24) {
serial = (entry_.data >> 4);
btn = entry_.data & 0xf;
return;
}
}
} // namespace ui
+8
View File
@@ -127,6 +127,14 @@ class SubGhzDView : public View {
}};
SubGhzDRecentEntriesView recent_entries_view{columns, recent};
void on_freqchg(int64_t freq);
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
MessageHandlerRegistration message_handler_packet{
Message::ID::SubGhzDData,
[this](Message* const p) {
+292 -1
View File
@@ -26,6 +26,7 @@
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "portapack_persistent_memory.hpp"
#include "../baseband/fprotos/fprotogeneral.hpp"
using namespace portapack;
using namespace ui;
@@ -138,7 +139,8 @@ void WeatherView::on_tick_second() {
}
void WeatherView::on_data(const WeatherDataMessage* data) {
WeatherRecentEntry key{data->sensorType, data->id, data->temp, data->humidity, data->channel, data->battery_low};
WeatherRecentEntry key = process_data(data);
// WeatherRecentEntry key{data->sensorType, data->id, data->temp, data->humidity, data->channel, data->battery_low};
auto matching_recent = find(recent, key.key());
if (matching_recent != std::end(recent)) {
// Found within. Move to front of list, increment counter.
@@ -209,6 +211,8 @@ const char* WeatherView::getWeatherSensorTypeName(FPROTO_WEATHER_SENSOR type) {
return "Acurite5in1";
case FPW_EmosE601x:
return "EmosE601x";
case FPW_SolightTE44:
return "SolightTE44";
case FPW_Invalid:
default:
return "Unknown";
@@ -220,6 +224,10 @@ std::string WeatherView::pad_string_with_spaces(int snakes) {
return paddedStr;
}
void WeatherView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
template <>
void RecentEntriesTable<ui::WeatherRecentEntries>::draw(
const Entry& entry,
@@ -250,4 +258,287 @@ void RecentEntriesTable<ui::WeatherRecentEntries>::draw(
painter.draw_string(target_rect.location(), style, line);
}
#define LACROSSE_TX_MSG_TYPE_TEMP 0x00
#define LACROSSE_TX_MSG_TYPE_HUM 0x0E
WeatherRecentEntry WeatherView::process_data(const WeatherDataMessage* data) {
WeatherRecentEntry ret = {};
ret.sensorType = data->sensorType;
int16_t i16 = 0;
uint16_t u16 = 0;
uint64_t u64 = 0;
uint8_t u8 = 0;
uint8_t channel_3021[] = {3, 0, 2, 1};
float flo = 0.0;
switch (data->sensorType) {
case FPW_NexusTH:
ret.id = (data->decode_data >> 28) & 0xFF;
ret.battery_low = !((data->decode_data >> 27) & 1);
ret.channel = ((data->decode_data >> 24) & 0x03) + 1;
if (!((data->decode_data >> 23) & 1)) {
ret.temp = (float)((data->decode_data >> 12) & 0x07FF) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 12) & 0x07FF) + 1) / -10.0f;
}
ret.humidity = data->decode_data & 0xFF;
if (ret.humidity > 95)
ret.humidity = 95;
else if (ret.humidity < 20)
ret.humidity = 20;
break;
case FPW_Acurite592TXR:
u8 = ((data->decode_data >> 54) & 0x03);
ret.channel = channel_3021[u8];
ret.id = (data->decode_data >> 40) & 0x3FFF;
ret.battery_low = !((data->decode_data >> 38) & 1);
ret.humidity = (data->decode_data >> 24) & 0x7F;
u16 = ((data->decode_data >> 9) & 0xF80) | ((data->decode_data >> 8) & 0x7F);
ret.temp = ((float)(u16)-1000) / 10.0f;
break;
case FPW_Acurite606TX:
ret.id = (data->decode_data >> 24) & 0xFF;
ret.battery_low = (data->decode_data >> 23) & 1;
if (!((data->decode_data >> 19) & 1)) {
ret.temp = (float)((data->decode_data >> 8) & 0x07FF) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 8) & 0x07FF) + 1) / -10.0f;
}
break;
case FPW_Acurite609TX:
ret.id = (data->decode_data >> 32) & 0xFF;
ret.battery_low = (data->decode_data >> 31) & 1;
ret.channel = WS_NO_CHANNEL;
// Temperature in Celsius is encoded as a 12 bit integer value
// multiplied by 10 using the 4th - 6th nybbles (bytes 1 & 2)
// negative values are recovered by sign extend from int16_t.
i16 = (int16_t)(((data->decode_data >> 12) & 0xf000) | ((data->decode_data >> 16) << 4));
ret.temp = (i16 >> 4) * 0.1f;
ret.humidity = (data->decode_data >> 8) & 0xff;
break;
case FPW_Ambient:
id = (data->decode_data >> 32) & 0xFF;
ret.battery_low = (data->decode_data >> 31) & 1;
ret.channel = ((data->decode_data >> 28) & 0x07) + 1;
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data->decode_data >> 16) & 0x0FFF) - 400.0f) / 10.0f);
ret.humidity = (data->decode_data >> 8) & 0xFF;
break;
case FPW_AuriolAhfl:
ret.id = data->decode_data >> 34;
ret.battery_low = (data->decode_data >> 33) & 1;
// btn = (data >> 32) & 1;
ret.channel = ((data->decode_data >> 30) & 0x3) + 1;
if (!((data->decode_data >> 29) & 1)) {
ret.temp = (float)((data->decode_data >> 18) & 0x07FF) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 18) & 0x07FF) + 1) / -10.0f;
}
ret.humidity = (data->decode_data >> 11) & 0x7F;
break;
case FPW_AuriolTH:
ret.id = (data->decode_data >> 31) & 0xFF;
ret.battery_low = ((data->decode_data >> 30) & 1);
ret.channel = ((data->decode_data >> 25) & 0x03) + 1;
if (!((data->decode_data >> 23) & 1)) {
ret.temp = (float)((data->decode_data >> 13) & 0x07FF) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 13) & 0x07FF) + 1) / -10.0f;
}
ret.humidity = (data->decode_data >> 1) & 0x7F;
break;
case FPW_GTWT02:
ret.id = (data->decode_data >> 29) & 0xFF;
ret.battery_low = (data->decode_data >> 28) & 1;
// btn = (data->decode_data >> 27) & 1;
ret.channel = ((data->decode_data >> 25) & 0x3) + 1;
if (!((data->decode_data >> 24) & 1)) {
ret.temp = (float)((data->decode_data >> 13) & 0x07FF) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 13) & 0x07FF) + 1) / -10.0f;
}
ret.humidity = (data->decode_data >> 6) & 0x7F;
if (ret.humidity <= 10) // actually the sensors sends 10 below working range of 20%
ret.humidity = 0;
else if (ret.humidity > 90) // actually the sensors sends 110 above working range of 90%
ret.humidity = 100;
break;
case FPW_GTWT03:
ret.id = data->decode_data >> 33;
ret.humidity = (data->decode_data >> 25) & 0xFF;
if (ret.humidity <= 10) { // actually the sensors sends 10 below working range of 20%
ret.humidity = 0;
} else if (ret.humidity > 95) { // actually the sensors sends 110 above working range of 90%
ret.humidity = 100;
}
ret.battery_low = (data->decode_data >> 24) & 1;
// (data->decode_data >> 23) & 1;
ret.channel = ((data->decode_data >> 21) & 0x03) + 1;
if (!((data->decode_data >> 20) & 1)) {
ret.temp = (float)((data->decode_data >> 9) & 0x07FF) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 9) & 0x07FF) + 1) / -10.0f;
}
break;
case FPW_INFACTORY:
ret.id = data->decode_data >> 32;
ret.battery_low = (data->decode_data >> 26) & 1;
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data->decode_data >> 12) & 0x0FFF) - 900.0f) / 10.0f);
ret.humidity = (((data->decode_data >> 8) & 0x0F) * 10) + ((data->decode_data >> 4) & 0x0F); // BCD, 'A0'=100%rH
ret.channel = data->decode_data & 0x03;
break;
case FPW_LACROSSETX:
u8 = (data->decode_data >> 32) & 0x0F;
ret.id = (((data->decode_data >> 28) & 0x0F) << 3) | (((data->decode_data >> 24) & 0x0F) >> 1);
flo = (float)((data->decode_data >> 20) & 0x0F) * 10.0f + (float)((data->decode_data >> 16) & 0x0F) + (float)((data->decode_data >> 12) & 0x0F) * 0.1f;
if (u8 == LACROSSE_TX_MSG_TYPE_TEMP) { //-V1051
ret.temp = flo - 50.0f;
ret.humidity = WS_NO_HUMIDITY;
} else if (u8 == LACROSSE_TX_MSG_TYPE_HUM) {
// ToDo for verification, records are needed with sensors maintaining temperature and temperature for this standard
ret.humidity = (uint8_t)flo;
}
break;
case FPW_LACROSSETX141thbv2:
ret.id = data->decode_data >> 32;
ret.battery_low = (data->decode_data >> 31) & 1;
// btn = (data->decode_data >> 30) & 1;
ret.channel = ((data->decode_data >> 28) & 0x03) + 1;
ret.temp = ((float)((data->decode_data >> 16) & 0x0FFF) - 500.0f) / 10.0f;
ret.humidity = (data->decode_data >> 8) & 0xFF;
break;
case FPW_OREGON2:
i16 = ((data->decode_data >> 4) & 0xF) * 10 + (((data->decode_data >> 4) >> 4) & 0xF);
i16 *= 10;
i16 += (data->decode_data >> 12) & 0xF;
if (data->decode_data & 0xF) i16 = -i16;
ret.temp = (float)i16 / 10.0;
// todo fix missing parts.
break;
case FPW_OREGON3:
// todo check
ret.humidity = ((data->decode_data >> 4) & 0xF) * 10 + (((data->decode_data >> 4) >> 4) & 0xF);
i16 = (((data->decode_data >> 12) >> 4) & 0xF) * 10 + ((((data->decode_data >> 12) >> 4) >> 4) & 0xF); // ws_oregon3_bcd_decode_short((data->decode_data >> 12) >> 4);
i16 *= 10;
i16 += ((data->decode_data >> 12) >> 12) & 0xF;
if ((data->decode_data >> 12) & 0xF) i16 = -i16;
ret.temp = (float)i16 / 10.0;
break;
case FPW_OREGONv1:
u64 = FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data, 32);
id = u64 & 0xFF;
ret.channel = ((u64 >> 6) & 0x03) + 1;
ret.temp = ((u64 >> 8) & 0x0F) * 0.1f + ((u64 >> 12) & 0x0F) + ((u64 >> 16) & 0x0F) * 10.0f;
if (!((u64 >> 21) & 1)) {
ret.temp = ret.temp;
} else {
ret.temp = -ret.temp;
}
ret.battery_low = !((u64 >> 23) & 1ULL);
break;
case FPW_THERMOPROTX4:
ret.id = (data->decode_data >> 25) & 0xFF;
ret.battery_low = (data->decode_data >> 24) & 1;
// btn = (data->decode_data >> 23) & 1;
ret.channel = ((data->decode_data >> 21) & 0x03) + 1;
if (!((data->decode_data >> 20) & 1)) {
ret.temp = (float)((data->decode_data >> 9) & 0x07FF) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 9) & 0x07FF) + 1) / -10.0f;
}
ret.humidity = (data->decode_data >> 1) & 0xFF;
break;
case FPW_TX_8300:
ret.humidity = (((data->decode_data >> 28) & 0x0F) * 10) + ((data->decode_data >> 24) & 0x0F);
if (!((data->decode_data >> 22) & 0x03))
ret.battery_low = 0;
else
ret.battery_low = 1;
ret.channel = (data->decode_data >> 20) & 0x03;
ret.id = (data->decode_data >> 12) & 0x7F;
ret.temp = ((data->decode_data >> 8) & 0x0F) * 10.0f + ((data->decode_data >> 4) & 0x0F) +
(data->decode_data & 0x0F) * 0.1f;
if (!((data->decode_data >> 19) & 1)) {
ret.temp = ret.temp;
} else {
ret.temp = -ret.temp;
}
break;
case FPW_WENDOX_W6726:
ret.id = (data->decode_data >> 24) & 0xFF;
ret.battery_low = (data->decode_data >> 6) & 1;
if (((data->decode_data >> 23) & 1)) {
ret.temp = (float)(((data->decode_data >> 14) & 0x1FF) + 12) / 10.0f;
} else {
ret.temp = (float)((~(data->decode_data >> 14) & 0x1FF) + 1 - 12) / -10.0f;
}
if (ret.temp < -50.0f) {
ret.temp = -50.0f;
} else if (ret.temp > 70.0f) {
ret.temp = 70.0f;
}
break;
case FPW_Acurite986:
ret.id = FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data >> 24, 8);
ret.id = (id << 8) | FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data >> 16, 8);
ret.battery_low = (data->decode_data >> 14) & 1;
ret.channel = ((data->decode_data >> 15) & 1) + 1;
i16 = FProtoGeneral::subghz_protocol_blocks_reverse_key(data->decode_data >> 32, 8);
if (i16 & 0x80) {
i16 = -(i16 & 0x7F);
}
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius((float)i16);
break;
case FPW_KEDSUM:
ret.id = data->decode_data >> 32;
if ((data->decode_data >> 30) & 0x3) {
ret.battery_low = 0;
} else {
ret.battery_low = 1;
}
ret.channel = ((data->decode_data >> 28) & 0x3) + 1;
u16 = ((data->decode_data >> 16) & 0x0f) << 8 | ((data->decode_data >> 20) & 0x0f) << 4 | ((data->decode_data >> 24) & 0x0f);
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)u16 - 900.0f) / 10.0f);
ret.humidity = ((data->decode_data >> 8) & 0x0f) << 4 | ((data->decode_data >> 12) & 0x0f);
break;
case FPW_Acurite5in1:
u8 = ((data->decode_data >> 62) & 0x03);
ret.channel = channel_3021[u8];
ret.id = (data->decode_data >> 48) & 0x3FFF;
ret.battery_low = !((data->decode_data >> 46) & 1);
ret.humidity = (data->decode_data >> 8) & 0x7F;
u16 = ((data->decode_data >> (24 - 7)) & 0x780) | ((data->decode_data >> 16) & 0x7F);
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)(u16)-400) / 10.0f);
break;
case FPW_EmosE601x:
ret.id = 0xffff; //(upper_decode_data >> 24) & 0xff; //todo maybe with oregon, and +64bit usage/message
ret.battery_low = (data->decode_data >> 10) & 1;
i16 = (data->decode_data >> 40) & 0xfff;
/* Handle signed data */
if (i16 & 0x800) {
i16 |= 0xf000;
}
ret.temp = (float)i16 / 10.0;
ret.humidity = (data->decode_data >> 32) & 0xff;
ret.channel = (data->decode_data >> 52) & 0x03;
break;
case FPW_SolightTE44:
ret.id = (data->decode_data >> 28) & 0xff;
ret.battery_low = !(data->decode_data >> 27) & 0x01;
ret.channel = ((data->decode_data >> 24) & 0x03) + 1;
i16 = (data->decode_data >> 12) & 0x0fff;
/* Handle signed data */
if (i16 & 0x0800) {
i16 |= 0xf000;
}
ret.temp = (float)i16 / 10.0;
break;
case FPW_Invalid:
default:
break;
}
return ret;
}
} // namespace ui
@@ -96,7 +96,7 @@ class WeatherView : public View {
private:
void on_tick_second();
void on_data(const WeatherDataMessage* data);
WeatherRecentEntry process_data(const WeatherDataMessage* data);
NavigationView& nav_;
RxRadioState radio_state_{
433'920'000 /* frequency */,
@@ -151,6 +151,14 @@ class WeatherView : public View {
}};
WeatherRecentEntriesView recent_entries_view{columns, recent};
void on_freqchg(int64_t freq);
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
MessageHandlerRegistration message_handler_packet{
Message::ID::WeatherData,
[this](Message* const p) {
+4
View File
@@ -143,6 +143,10 @@ void AFSKRxView::on_data(uint32_t value, bool is_data) {
}
}
void AFSKRxView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
AFSKRxView::~AFSKRxView() {
audio::output::stop();
receiver_model.disable();
+9
View File
@@ -117,6 +117,15 @@ class AFSKRxView : public View {
const auto message = static_cast<const AFSKDataMessage*>(p);
this->on_data(message->value, message->is_data);
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
};
} // namespace ui::external_app::afsk_rx
@@ -202,4 +202,8 @@ void AnalogTvView::update_modulation(const ReceiverModel::Mode modulation) {
receiver_model.enable();
}
void AnalogTvView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
} // namespace ui::external_app::analogtv
@@ -108,6 +108,15 @@ class AnalogTvView : public View {
void set_options_widget(std::unique_ptr<Widget> new_widget);
void update_modulation(const ReceiverModel::Mode modulation);
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
};
} // namespace ui::external_app::analogtv
@@ -103,4 +103,8 @@ void FoxhuntRxView::on_orientation(const OrientationDataMessage* msg) {
geomap.update_my_orientation(msg->angle, true);
}
void FoxhuntRxView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
} // namespace ui::external_app::foxhunt_rx
@@ -103,6 +103,14 @@ class FoxhuntRxView : public View {
[this](const Message* const p) {
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
float my_lat = 200;
float my_lon = 200;
+4
View File
@@ -125,6 +125,10 @@ void NRFRxView::on_data(uint32_t value, bool is_data) {
}
}
void NRFRxView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
NRFRxView::~NRFRxView() {
audio::output::stop();
receiver_model.disable();
+9
View File
@@ -89,6 +89,15 @@ class NRFRxView : public View {
const auto message = static_cast<const AFSKDataMessage*>(p);
this->on_data(message->value, message->is_data);
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
};
} /* namespace ui::external_app::nrf_rx */
@@ -186,6 +186,10 @@ void ProtoView::on_data(const ProtoViewDataMessage* message) {
draw2();
}
void ProtoView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
ProtoView::~ProtoView() {
audio::output::stop();
receiver_model.disable();
@@ -157,6 +157,15 @@ class ProtoView : public View {
[this](const Message* const) {
this->on_timer();
}};
MessageHandlerRegistration message_handler_freqchg{
Message::ID::FreqChangeCommand,
[this](Message* const p) {
const auto message = static_cast<const FreqChangeCommandMessage*>(p);
this->on_freqchg(message->freq);
}};
void on_freqchg(int64_t freq);
};
} // namespace ui::external_app::protoview
+1 -1
View File
@@ -586,7 +586,7 @@ init_status_t init() {
chThdSleepMilliseconds(10);
audio::init(portapack_audio_codec());
battery::BatteryManagement::init();
battery::BatteryManagement::init(persistent_memory::ui_override_batt_calc());
if (lcd_fast_setup)
draw_splash_screen_icon(4, ui::bitmap_icon_speaker);
+18
View File
@@ -1147,6 +1147,23 @@ static void cmd_asyncmsg(BaseSequentialStream* chp, int argc, char* argv[]) {
chprintf(chp, usage);
}
}
static void cmd_setfreq(BaseSequentialStream* chp, int argc, char* argv[]) {
const char* usage = "usage: setfreq freq_in_hz\r\n";
if (argc != 1) {
chprintf(chp, usage);
return;
}
int64_t freq = atol(argv[0]);
if (freq <= 0) {
chprintf(chp, usage);
return;
}
// radio::set_tuning_frequency(freq); // sadly this doesn't update any widget, just change the frequency.
FreqChangeCommandMessage message{freq};
EventDispatcher::send_message(message);
chprintf(chp, "ok\r\n");
}
static const ShellCommand commands[] = {
{"reboot", cmd_reboot},
@@ -1180,6 +1197,7 @@ static const ShellCommand commands[] = {
{"settingsreset", cmd_settingsreset},
{"sendpocsag", cmd_sendpocsag},
{"asyncmsg", cmd_asyncmsg},
{"setfreq", cmd_setfreq},
{NULL, NULL}};
static const ShellConfig shell_cfg1 = {
-1
View File
@@ -36,7 +36,6 @@ class FProtoSubGhzDBett : public FProtoSubGhzDBase {
(te_delta * 15)) {
if (decode_count_bit ==
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
// dip decoder needed
if (callback) callback(this);
-1
View File
@@ -53,7 +53,6 @@ class FProtoSubGhzDCame : public FProtoSubGhzDBase {
parser_step = CameDecoderStepFoundStartBit;
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == AIRFORCE_COUNT_BIT) ||
(decode_count_bit == PRASTEL_COUNT_BIT) || (decode_count_bit == CAME_24_COUNT_BIT)) {
data = decode_data;
data_count_bit = decode_count_bit;
// if flippa hacky, i hacky
sensorType = FPS_CAME;
@@ -43,7 +43,6 @@ class FProtoSubGhzDCameAtomo : public FProtoSubGhzDBase {
duration >= ((uint32_t)te_long * 2 + te_delta)) {
if (decode_count_bit ==
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -43,7 +43,6 @@ class FProtoSubGhzDCameTwee : public FProtoSubGhzDBase {
} else if (
duration >= ((uint32_t)te_long * 2 + te_delta)) {
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -58,7 +58,6 @@ class FProtoSubGhzDChambCode : public FProtoSubGhzDBase {
if (duration > te_short * 5) {
if (decode_count_bit >= min_count_bit_for_found) {
if (subghz_protocol_decoder_chamb_code_check_mask_and_parse()) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
-1
View File
@@ -62,7 +62,6 @@ class FProtoSubGhzDClemsa : public FProtoSubGhzDBase {
if (decode_count_bit ==
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
-1
View File
@@ -44,7 +44,6 @@ class FProtoSubGhzDDoitrand : public FProtoSubGhzDBase {
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
parser_step = DoitrandDecoderStepFoundStartBit;
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
-1
View File
@@ -72,7 +72,6 @@ class FProtoSubGhzDDooya : public FProtoSubGhzDBase {
parser_step = DooyaDecoderStepFoundStartBit;
if (decode_count_bit ==
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
-1
View File
@@ -43,7 +43,6 @@ class FProtoSubGhzDFaac : public FProtoSubGhzDBase {
if (duration >= ((uint32_t)te_short * 3 + te_delta)) {
parser_step = FaacSLHDecoderStepFoundPreambula;
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
// remark controller skipped
if (callback) callback(this);
+86
View 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
-1
View File
@@ -44,7 +44,6 @@ class FProtoSubGhzDGateTx : public FProtoSubGhzDBase {
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
parser_step = GateTXDecoderStepFoundStartBit;
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
-1
View File
@@ -49,7 +49,6 @@ class FProtoSubGhzDHoltek : public FProtoSubGhzDBase {
if (decode_count_bit ==
min_count_bit_for_found) {
if ((decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
+2 -5
View File
@@ -44,11 +44,8 @@ class FProtoSubGhzDHoltekHt12x : public FProtoSubGhzDBase {
if (!level) {
if (duration >= ((uint32_t)te_short * 10 + te_delta)) {
if (decode_count_bit == min_count_bit_for_found) {
if (data != decode_data) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
decode_data = 0;
decode_count_bit = 0;
@@ -71,7 +71,6 @@ class FProtoSubGhzDHoneywell : public FProtoSubGhzDBase {
uint16_t crc = decode_data & 0xFFFF;
if (crc == crc_calc) {
// the data is good. process it.
data = decode_data;
data_count_bit = decode_count_bit; // maybe set it to 64, and hack the first 2 bits to 1! will see if replay needs it
if (callback) callback(this);
decode_data = 0;
@@ -36,7 +36,6 @@ class FProtoSubGhzDHoneywellWdb : public FProtoSubGhzDBase {
if (DURATION_DIFF(duration, te_short * 3) < te_delta) {
if ((decode_count_bit == min_count_bit_for_found) &&
((decode_data & 0x01) == FProtoGeneral::subghz_protocol_blocks_get_parity(decode_data >> 1, min_count_bit_for_found - 1))) {
data = decode_data;
data_count_bit = decode_count_bit;
// controller has too much, should be done on ui side
if (callback) callback(this);
-1
View File
@@ -47,7 +47,6 @@ class FProtoSubGhzDHormann : public FProtoSubGhzDBase {
parser_step = HormannDecoderStepFoundStartBit;
if (decode_count_bit >=
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -24,7 +24,6 @@ class FProtoSubGhzDHormannBiSecure : public FProtoSubGhzDBase {
void subghz_protocol_decoder_hormann_bisecur_reset() {
parser_step = HormannBiSecurDecoderStepReset;
data = 0;
for (uint8_t i = 0; i < 22; ++i) dataa[i] = 0;
data_count_bit = 0;
manchester_saved_state = ManchesterStateStart1;
-1
View File
@@ -44,7 +44,6 @@ class FProtoSubGhzDIdo : public FProtoSubGhzDBase {
parser_step = IDoDecoderStepFoundPreambula;
if (decode_count_bit >=
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -66,7 +66,6 @@ class FProtoSubGhzDIntertechnoV3 : public FProtoSubGhzDBase {
parser_step = IntertechnoV3DecoderStepStartSync;
if ((decode_count_bit == min_count_bit_for_found) ||
(decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
+4 -5
View File
@@ -57,11 +57,8 @@ class FProtoSubGhzDKeeLoq : public FProtoSubGhzDBase {
parser_step = KeeloqDecoderStepReset;
if ((decode_count_bit >= min_count_bit_for_found) &&
(decode_count_bit <= min_count_bit_for_found + 2)) {
if (data != decode_data) {
data = decode_data;
data_count_bit = min_count_bit_for_found;
if (callback) callback(this);
}
data_count_bit = min_count_bit_for_found;
if (callback) callback(this);
decode_data = 0;
decode_count_bit = 0;
header_count = 0;
@@ -96,6 +93,8 @@ class FProtoSubGhzDKeeLoq : public FProtoSubGhzDBase {
break;
}
}
uint16_t header_count = 0;
};
#endif
@@ -50,7 +50,8 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
DURATION_DIFF(duration, te_short * 2) < te_delta * 2) {
parser_step = KingGates_stylo_4kDecoderStepSaveDuration;
decode_data = 0;
data_2 = 0;
// data_2 = 0;
// data = 0;
decode_count_bit = 0;
header_count = 0;
}
@@ -58,17 +59,17 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
case KingGates_stylo_4kDecoderStepSaveDuration:
if (!level) {
if (duration >= ((uint32_t)te_long * 3)) {
if (decode_count_bit ==
min_count_bit_for_found) {
data = data_2;
data_2 = decode_data; // TODO DATA2
if (decode_count_bit == min_count_bit_for_found) {
// data = data_2;
// data_2 = decode_data; // TODO DATA2
data_count_bit = decode_count_bit;
// decode_data = data;
if (callback) callback(this);
}
parser_step = KingGates_stylo_4kDecoderStepReset;
decode_data = 0;
data_2 = 0;
// data_2 = 0;
decode_count_bit = 0;
header_count = 0;
break;
@@ -101,7 +102,7 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
header_count = 0;
}
if (decode_count_bit == 53) {
data_2 = decode_data;
// data_2 = decode_data;
decode_data = 0;
}
} else {
@@ -113,7 +114,9 @@ class FProtoSubGhzDKinggatesStylo4K : public FProtoSubGhzDBase {
}
protected:
uint64_t data_2 = 0;
// uint64_t data_2 = 0;
// uint64_t data = 0;
uint16_t header_count = 0;
};
#endif
+5 -11
View File
@@ -79,23 +79,17 @@ class FProtoSubGhzDLegrand : public FProtoSubGhzDBase {
if (found) {
te += duration;
if (decode_count_bit <
min_count_bit_for_found) {
if (decode_count_bit < min_count_bit_for_found) {
parser_step = LegrandDecoderStepSaveDuration;
break;
}
// enough bits for a packet found, save it only if there was a previous packet
// with the same data
if (data && (data != decode_data)) {
te /= decode_count_bit * 4;
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) {
callback(this);
}
te /= decode_count_bit * 4;
data_count_bit = decode_count_bit;
if (callback) {
callback(this);
}
// fallthrough to reset, the next bit is expected to be a sync
// it also takes care of resetting the decoder state
-1
View File
@@ -54,7 +54,6 @@ class FProtoSubGhzDLinear : public FProtoSubGhzDBase {
subghz_protocol_blocks_add_bit(1);
}
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -49,11 +49,8 @@ class FProtoSubGhzDLinearDelta3 : public FProtoSubGhzDBase {
subghz_protocol_blocks_add_bit(0);
}
if (decode_count_bit == min_count_bit_for_found) {
if ((data == decode_data) && data) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
data_count_bit = decode_count_bit;
if (callback) callback(this);
parser_step = LinearD3DecoderStepSaveDuration;
}
break;
+1 -1
View File
@@ -90,7 +90,6 @@ class FProtoSubGhzDMagellan : public FProtoSubGhzDBase {
// Found stop bit
if ((decode_count_bit == min_count_bit_for_found) &&
subghz_protocol_magellan_check_crc()) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -129,6 +128,7 @@ class FProtoSubGhzDMagellan : public FProtoSubGhzDBase {
}
return crc;
}
uint16_t header_count = 0;
};
#endif
-1
View File
@@ -43,7 +43,6 @@ class FProtoSubGhzDMarantec : public FProtoSubGhzDBase {
} else if (
duration >= ((uint32_t)te_long * 2 + te_delta)) {
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -0,0 +1,93 @@
#ifndef __FPROTO_MARANTEC24_H__
#define __FPROTO_MARANTEC24_H__
#include "subghzdbase.hpp"
typedef enum {
Marantec24DecoderStepReset = 0,
Marantec24DecoderStepSaveDuration,
Marantec24DecoderStepCheckDuration,
} Marantec24DecoderStep;
class FProtoSubGhzDMarantec24 : public FProtoSubGhzDBase {
public:
FProtoSubGhzDMarantec24() {
sensorType = FPS_MARANTEC24;
te_short = 800;
te_long = 1600;
te_delta = 200;
min_count_bit_for_found = 24;
}
void feed(bool level, uint32_t duration) {
// Key samples
// 101011000000010111001000 = AC05C8
// 101011000000010111000100 = AC05C4
// 101011000000010111001100 = AC05CC
// 101011000000010111000000 = AC05C0
switch (parser_step) {
case Marantec24DecoderStepReset:
if ((!level) && (DURATION_DIFF(duration, te_long * 9) < te_delta * 4)) {
// Found GAP
decode_data = 0;
decode_count_bit = 0;
parser_step = Marantec24DecoderStepSaveDuration;
}
break;
case Marantec24DecoderStepSaveDuration:
if (level) {
te_last = duration;
parser_step = Marantec24DecoderStepCheckDuration;
} else {
parser_step = Marantec24DecoderStepReset;
}
break;
case Marantec24DecoderStepCheckDuration:
if (!level) {
// Bit 0 is long and short x2 timing = 1600us HIGH (te_last) and 2400us LOW
if ((DURATION_DIFF(te_last, te_long) < te_delta) &&
(DURATION_DIFF(duration, te_short * 3) < te_delta)) {
subghz_protocol_blocks_add_bit(0);
parser_step = Marantec24DecoderStepSaveDuration;
// Bit 1 is short and long x2 timing = 800us HIGH (te_last) and 3200us LOW
} else if (
(DURATION_DIFF(te_last, te_short) < te_delta) &&
(DURATION_DIFF(duration, te_long * 2) < te_delta)) {
subghz_protocol_blocks_add_bit(1);
parser_step = Marantec24DecoderStepSaveDuration;
} else if (
// End of the key
DURATION_DIFF(duration, te_long * 9) < te_delta * 4) {
// Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes)
if ((DURATION_DIFF(te_last, te_long) < te_delta) &&
(DURATION_DIFF(duration, te_long * 9) < te_delta * 4)) {
subghz_protocol_blocks_add_bit(0);
}
if ((DURATION_DIFF(te_last, te_short) < te_delta) &&
(DURATION_DIFF(duration, te_long * 9) < te_delta * 4)) {
subghz_protocol_blocks_add_bit(1);
}
// If got 24 bits key reading is finished
if (decode_count_bit == min_count_bit_for_found) {
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
decode_data = 0;
decode_count_bit = 0;
parser_step = Marantec24DecoderStepReset;
} else {
parser_step = Marantec24DecoderStepReset;
}
} else {
parser_step = Marantec24DecoderStepReset;
}
break;
}
}
protected:
};
#endif
@@ -61,7 +61,6 @@ class FProtoSubGhzDMastercode : public FProtoSubGhzDBase {
}
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
-1
View File
@@ -48,7 +48,6 @@ class FProtoSubGhzDMegacode : public FProtoSubGhzDBase {
parser_step = MegaCodeDecoderStepReset;
if (decode_count_bit ==
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
+1 -1
View File
@@ -67,7 +67,6 @@ class FProtoSubGhzDNeroSketch : public FProtoSubGhzDBase {
// Found stop bit
parser_step = NeroSketchDecoderStepReset;
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -103,6 +102,7 @@ class FProtoSubGhzDNeroSketch : public FProtoSubGhzDBase {
break;
}
}
uint16_t header_count = 0;
};
#endif
+1 -1
View File
@@ -82,7 +82,6 @@ class FProtoSubGhzDNeroRadio : public FProtoSubGhzDBase {
parser_step = NeroRadioDecoderStepReset;
if ((decode_count_bit == min_count_bit_for_found) ||
(decode_count_bit == min_count_bit_for_found + 1)) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
@@ -110,6 +109,7 @@ class FProtoSubGhzDNeroRadio : public FProtoSubGhzDBase {
break;
}
}
uint16_t header_count = 0;
};
#endif
-1
View File
@@ -47,7 +47,6 @@ class FProtoSubGhzDNiceflo : public FProtoSubGhzDBase {
if (duration >= (te_short * 4)) {
parser_step = NiceFloDecoderStepFoundStartBit;
if (decode_count_bit >= min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
+3 -4
View File
@@ -56,10 +56,9 @@ class FProtoSubGhzDNiceflors : public FProtoSubGhzDBase {
// Found STOP bit
parser_step = NiceFlorSDecoderStepReset;
if ((decode_count_bit == min_count_bit_for_found) || (decode_count_bit == NICE_ONE_COUNT_BIT)) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
decode_data = 0;
}
break;
} else {
@@ -86,8 +85,8 @@ class FProtoSubGhzDNiceflors : public FProtoSubGhzDBase {
parser_step = NiceFlorSDecoderStepReset;
}
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
decode_data = 0;
// data = decode_data;
// decode_data = 0;
}
break;
}
@@ -45,7 +45,6 @@ class FProtoSubGhzDPhoenixV2 : public FProtoSubGhzDBase {
parser_step = Phoenix_V2DecoderStepFoundStartBit;
if (decode_count_bit ==
min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -49,7 +49,6 @@ class FProtoSubGhzDPowerSmart : public FProtoSubGhzDBase {
}
if ((decode_data & POWER_SMART_PACKET_HEADER_MASK) == POWER_SMART_PACKET_HEADER) {
if (subghz_protocol_power_smart_chek_valid(decode_data)) {
data = decode_data;
data_count_bit = min_count_bit_for_found;
if (callback) callback(this);
@@ -42,7 +42,6 @@ class FProtoSubGhzDPrinceton : public FProtoSubGhzDBase {
if (duration >= ((uint32_t)te_long * 2)) {
parser_step = PrincetonDecoderStepSaveDuration;
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -50,7 +50,6 @@ class FProtoSubGhzDSecPlusV2 : public FProtoSubGhzDBase {
} else if (
duration >= (te_long * 2UL + te_delta)) {
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (subghz_protocol_secplus_v2_check_packet()) {
// controller too big
-1
View File
@@ -42,7 +42,6 @@ class FProtoSubGhzDSmc5326 : public FProtoSubGhzDBase {
if (duration >= ((uint32_t)te_long * 2)) {
parser_step = SMC5326DecoderStepSaveDuration;
if (decode_count_bit == min_count_bit_for_found) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
@@ -68,11 +68,9 @@ class FProtoSubGhzDSomifyKeytis : public FProtoSubGhzDBase {
duration >= (te_long + te_delta)) {
if (decode_count_bit == min_count_bit_for_found) {
// check crc
uint64_t data_tmp = data ^ (data >> 8);
uint64_t data_tmp = decode_data ^ (decode_data >> 8);
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_keytis_crc(data_tmp)) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
}
}
@@ -124,6 +122,8 @@ class FProtoSubGhzDSomifyKeytis : public FProtoSubGhzDBase {
}
return crc & 0xf;
}
uint16_t header_count = 0;
};
#endif
+1 -1
View File
@@ -71,7 +71,6 @@ class FProtoSubGhzDSomifyTelis : public FProtoSubGhzDBase {
// check crc
uint64_t data_tmp = decode_data ^ (decode_data >> 8);
if (((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_telis_crc(data_tmp)) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
@@ -118,6 +117,7 @@ class FProtoSubGhzDSomifyTelis : public FProtoSubGhzDBase {
}
return crc & 0xf;
}
uint16_t header_count = 0;
};
#endif
+3 -5
View File
@@ -53,11 +53,8 @@ class FProtoSubGhzDStarLine : public FProtoSubGhzDBase {
parser_step = StarLineDecoderStepReset;
if ((decode_count_bit >= min_count_bit_for_found) &&
(decode_count_bit <= min_count_bit_for_found + 2)) {
if (data != decode_data) {
data = decode_data;
data_count_bit = min_count_bit_for_found;
if (callback) callback(this);
}
data_count_bit = min_count_bit_for_found;
if (callback) callback(this);
}
decode_data = 0;
decode_count_bit = 0;
@@ -101,6 +98,7 @@ class FProtoSubGhzDStarLine : public FProtoSubGhzDBase {
break;
}
}
uint16_t header_count = 0;
};
#endif
-1
View File
@@ -47,7 +47,6 @@ class FProtoSubGhzDX10 : public FProtoSubGhzDBase {
if (decode_count_bit >= min_count_bit_for_found &&
((((decode_data >> 24) ^ (decode_data >> 16)) & 0xFF) == 0xFF) &&
((((decode_data >> 8) ^ (decode_data)) & 0xFF) == 0xFF)) {
data = decode_data;
data_count_bit = decode_count_bit;
if (callback) callback(this);
+3 -3
View File
@@ -26,7 +26,7 @@ class FProtoSubGhzDBase {
// General data holder, these will be passed
uint8_t sensorType = FPS_Invalid;
uint16_t data_count_bit = 0;
uint64_t data = 0;
uint64_t decode_data = 0;
protected:
// Helper functions to keep it as compatible with flipper as we can, so adding new protos will be easy.
@@ -42,11 +42,11 @@ class FProtoSubGhzDBase {
uint32_t min_count_bit_for_found = UINT32_MAX;
SubGhzDProtocolDecoderBaseRxCallback callback = NULL;
uint16_t header_count = 0;
uint8_t parser_step = 0;
uint32_t te_last = 0;
uint32_t decode_count_bit = 0;
uint64_t decode_data = 0;
//
};
+5 -2
View File
@@ -51,7 +51,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons
#include "s-legrand.hpp"
#include "s-somify_keytis.hpp"
#include "s-somify_telis.hpp"
#include "s-gangqi.hpp"
#include "s-marantec24.hpp"
// GENIE FROM PR
#ifndef __FPROTO_PROTOLISTSGZ_H__
@@ -104,6 +105,8 @@ class SubGhzDProtos : public FProtoListGeneral {
protos[FPS_X10] = new FProtoSubGhzDX10();
// protos[FPS_HORMANNBISECURE] = new FProtoSubGhzDHormannBiSecure(); //fm
protos[FPS_LEGRAND] = new FProtoSubGhzDLegrand();
protos[FPS_GANGQI] = new FProtoSubGhzDGangqi();
protos[FPS_MARANTEC24] = new FProtoSubGhzDMarantec24();
for (uint8_t i = 0; i < FPS_COUNT; ++i) {
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
@@ -120,7 +123,7 @@ class SubGhzDProtos : public FProtoListGeneral {
};
static void callbackTarget(FProtoSubGhzDBase* instance) {
SubGhzDDataMessage packet_message{instance->sensorType, instance->data_count_bit, instance->data};
SubGhzDDataMessage packet_message{instance->sensorType, instance->data_count_bit, instance->decode_data};
shared_memory.application_queue.push(packet_message);
}
@@ -56,6 +56,8 @@ enum FPROTO_SUBGHZD_SENSOR : uint8_t {
FPS_X10,
FPS_SOMIFY_KEYTIS,
FPS_SOMIFY_TELIS,
FPS_GANGQI,
FPS_MARANTEC24,
FPS_COUNT
};
@@ -80,9 +80,6 @@ class FProtoWeatherAcurite592TXR : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_acurite_592txr_check_crc()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_acurite_592txr_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -138,17 +135,6 @@ class FProtoWeatherAcurite592TXR : public FProtoWeatherBase {
return false;
}
}
void ws_protocol_acurite_592txr_remote_controller() {
uint8_t channel_[] = {3, 0, 2, 1};
uint8_t channel_raw = ((data >> 54) & 0x03);
channel = channel_[channel_raw];
id = (data >> 40) & 0x3FFF;
battery_low = !((data >> 38) & 1);
humidity = (data >> 24) & 0x7F;
uint16_t temp_raw = ((data >> 9) & 0xF80) | ((data >> 8) & 0x7F);
temp = ((float)(temp_raw)-1000) / 10.0f;
}
};
#endif
@@ -73,9 +73,6 @@ class FProtoWeatherAcurite5in1 : public FProtoWeatherBase {
if ((decode_count_bit == min_count_bit_for_found) &&
ws_protocol_acurite_5n1_check_crc() &&
ws_protocol_acurite_5n1_check_message_type()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_acurite_5n1_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -133,17 +130,6 @@ class FProtoWeatherAcurite5in1 : public FProtoWeatherBase {
return false;
}
}
void ws_protocol_acurite_5n1_remote_controller() {
uint8_t channell[] = {3, 0, 2, 1};
uint8_t channel_raw = ((data >> 62) & 0x03);
channel = channell[channel_raw];
id = (data >> 48) & 0x3FFF;
battery_low = !((data >> 46) & 1);
humidity = (data >> 8) & 0x7F;
uint16_t temp_raw = ((data >> (24 - 7)) & 0x780) | ((data >> 16) & 0x7F);
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)(temp_raw)-400) / 10.0f);
};
};
#endif
@@ -48,9 +48,6 @@ class FProtoWeatherAcurite606TX : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_acurite_606tx_check()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_acurite_606tx_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -83,17 +80,6 @@ class FProtoWeatherAcurite606TX : public FProtoWeatherBase {
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 32;
void ws_protocol_acurite_606tx_remote_controller() {
id = (data >> 24) & 0xFF;
battery_low = (data >> 23) & 1;
channel = WS_NO_CHANNEL;
if (!((data >> 19) & 1)) {
temp = (float)((data >> 8) & 0x07FF) / 10.0f;
} else {
temp = (float)((~(data >> 8) & 0x07FF) + 1) / -10.0f;
}
humidity = WS_NO_HUMIDITY;
}
bool ws_protocol_acurite_606tx_check() {
if (!decode_data) return false;
uint8_t msg[] = {
@@ -44,9 +44,6 @@ class FProtoWeatherAcurite609TX : public FProtoWeatherBase {
// Found syncPostfix
parser_step = Acurite_609TXCDecoderStepReset;
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_acurite_609txc_check()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_acurite_609txc_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -76,19 +73,6 @@ class FProtoWeatherAcurite609TX : public FProtoWeatherBase {
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 32;
void ws_protocol_acurite_609txc_remote_controller() {
id = (data >> 32) & 0xFF;
battery_low = (data >> 31) & 1;
channel = WS_NO_CHANNEL;
// Temperature in Celsius is encoded as a 12 bit integer value
// multiplied by 10 using the 4th - 6th nybbles (bytes 1 & 2)
// negative values are recovered by sign extend from int16_t.
int16_t temp_raw =
(int16_t)(((data >> 12) & 0xf000) | ((data >> 16) << 4));
temp = (temp_raw >> 4) * 0.1f;
humidity = (data >> 8) & 0xff;
}
bool ws_protocol_acurite_609txc_check() {
if (!decode_data) return false;
uint8_t crc = (uint8_t)(decode_data >> 32) +
@@ -84,9 +84,6 @@ class FProtoWeatherAcurite986 : public FProtoWeatherBase {
// Found syncPostfix
parser_step = Acurite_986DecoderStepReset;
if ((decode_count_bit == min_count_bit_for_found) && ws_protocol_acurite_986_check()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_acurite_986_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -105,22 +102,6 @@ class FProtoWeatherAcurite986 : public FProtoWeatherBase {
uint32_t te_delta = 50;
uint32_t min_count_bit_for_found = 40;
void ws_protocol_acurite_986_remote_controller() {
int temp;
id = FProtoGeneral::subghz_protocol_blocks_reverse_key(data >> 24, 8);
id = (id << 8) | FProtoGeneral::subghz_protocol_blocks_reverse_key(data >> 16, 8);
battery_low = (data >> 14) & 1;
channel = ((data >> 15) & 1) + 1;
temp = FProtoGeneral::subghz_protocol_blocks_reverse_key(data >> 32, 8);
if (temp & 0x80) {
temp = -(temp & 0x7F);
}
temp = FProtoGeneral::locale_fahrenheit_to_celsius((float)temp);
humidity = WS_NO_HUMIDITY;
}
bool ws_protocol_acurite_986_check() {
if (!decode_data) return false;
uint8_t msg[] = {
-11
View File
@@ -42,9 +42,6 @@ class FProtoWeatherAmbient : public FProtoWeatherBase {
if (((decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == AMBIENT_WEATHER_PACKET_HEADER_1) ||
((decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == AMBIENT_WEATHER_PACKET_HEADER_2)) {
if (ws_protocol_ambient_weather_check_crc()) {
data = decode_data;
data_count_bit = min_count_bit_for_found;
ws_protocol_ambient_weather_remote_controller();
if (callback) callback(this);
decode_data = 0;
decode_count_bit = 0;
@@ -74,14 +71,6 @@ class FProtoWeatherAmbient : public FProtoWeatherBase {
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_lfsr_digest8(msg, 5, 0x98, 0x3e) ^ 0x64;
return (crc == (uint8_t)(decode_data & 0xFF));
}
void ws_protocol_ambient_weather_remote_controller() {
id = (data >> 32) & 0xFF;
battery_low = (data >> 31) & 1;
channel = ((data >> 28) & 0x07) + 1;
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data >> 16) & 0x0FFF) - 400.0f) / 10.0f);
humidity = (data >> 8) & 0xFF;
}
};
#endif
@@ -48,9 +48,6 @@ class FProtoWeatherAuriolAhfl : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_auriol_ahfl_check()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_auriol_ahfl_remote_controller();
if (callback) {
callback(this);
}
@@ -88,19 +85,6 @@ class FProtoWeatherAuriolAhfl : public FProtoWeatherBase {
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 42;
void ws_protocol_auriol_ahfl_remote_controller() {
id = data >> 34;
battery_low = (data >> 33) & 1;
// btn = (data >> 32) & 1;
channel = ((data >> 30) & 0x3) + 1;
if (!((data >> 29) & 1)) {
temp = (float)((data >> 18) & 0x07FF) / 10.0f;
} else {
temp = (float)((~(data >> 18) & 0x07FF) + 1) / -10.0f;
}
humidity = (data >> 11) & 0x7F;
}
bool ws_protocol_auriol_ahfl_check() {
uint8_t type = (decode_data >> 6) & 0x0F;
if (type != AURIOL_AHFL_CONST_DATA) {
-15
View File
@@ -47,9 +47,6 @@ class FProtoWeatherAuriolTh : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_auriol_th_check()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_auriol_th_remote_controller();
if (callback) callback(this);
parser_step = auriol_THDecoderStepCheckDuration;
}
@@ -87,18 +84,6 @@ class FProtoWeatherAuriolTh : public FProtoWeatherBase {
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 37;
void ws_protocol_auriol_th_remote_controller() {
id = (data >> 31) & 0xFF;
battery_low = ((data >> 30) & 1);
channel = ((data >> 25) & 0x03) + 1;
if (!((data >> 23) & 1)) {
temp = (float)((data >> 13) & 0x07FF) / 10.0f;
} else {
temp = (float)((~(data >> 13) & 0x07FF) + 1) / -10.0f;
}
humidity = (data >> 1) & 0x7F;
}
bool ws_protocol_auriol_th_check() {
uint8_t type = (decode_data >> 8) & 0x0F;
-16
View File
@@ -81,9 +81,7 @@ class FProtoWeatherEmosE601x : public FProtoWeatherBase {
}
if (decode_count_bit == 120) {
data_count_bit = decode_count_bit;
if (ws_protocol_emose601x_check()) {
ws_protocol_emose601x_extract_data();
if (callback) callback(this);
}
break;
@@ -127,20 +125,6 @@ class FProtoWeatherEmosE601x : public FProtoWeatherBase {
uint8_t sum = FProtoGeneral::subghz_protocol_blocks_add_bytes(msg, 13);
return (sum == ((decode_data >> 8) & 0xff));
}
void ws_protocol_emose601x_extract_data() {
id = (upper_decode_data >> 24) & 0xff;
battery_low = (decode_data >> 10) & 1;
int16_t temp = (decode_data >> 40) & 0xfff;
/* Handle signed data */
if (temp & 0x800) {
temp |= 0xf000;
}
temp = (float)temp / 10.0;
humidity = (decode_data >> 32) & 0xff;
channel = (decode_data >> 52) & 0x03;
data = (decode_data >> 16);
}
};
#endif
-22
View File
@@ -50,9 +50,6 @@ class FProtoWeatherGTWT02 : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_gt_wt_02_check()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_gt_wt_02_remote_controller();
if (callback) callback(this);
} else if (decode_count_bit == 1) {
parser_step = GT_WT02DecoderStepSaveDuration;
@@ -88,25 +85,6 @@ class FProtoWeatherGTWT02 : public FProtoWeatherBase {
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 37;
void ws_protocol_gt_wt_02_remote_controller() {
id = (data >> 29) & 0xFF;
battery_low = (data >> 28) & 1;
// btn = (data >> 27) & 1;
channel = ((data >> 25) & 0x3) + 1;
if (!((data >> 24) & 1)) {
temp = (float)((data >> 13) & 0x07FF) / 10.0f;
} else {
temp = (float)((~(data >> 13) & 0x07FF) + 1) / -10.0f;
}
humidity = (data >> 6) & 0x7F;
if (humidity <= 10) // actually the sensors sends 10 below working range of 20%
humidity = 0;
else if (humidity > 90) // actually the sensors sends 110 above working range of 90%
humidity = 100;
}
bool ws_protocol_gt_wt_02_check() {
if (!decode_data) return false;
uint8_t sum = (decode_data >> 5) & 0xe;
-24
View File
@@ -77,9 +77,6 @@ class FProtoWeatherGTWT03 : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_gt_wt_03_check_crc()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_gt_wt_03_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -113,27 +110,6 @@ class FProtoWeatherGTWT03 : public FProtoWeatherBase {
uint32_t te_delta = 120;
uint32_t min_count_bit_for_found = 41;
void ws_protocol_gt_wt_03_remote_controller() {
id = data >> 33;
humidity = (data >> 25) & 0xFF;
if (humidity <= 10) { // actually the sensors sends 10 below working range of 20%
humidity = 0;
} else if (humidity > 95) { // actually the sensors sends 110 above working range of 90%
humidity = 100;
}
battery_low = (data >> 24) & 1;
// (data >> 23) & 1;
channel = ((data >> 21) & 0x03) + 1;
if (!((data >> 20) & 1)) {
temp = (float)((data >> 9) & 0x07FF) / 10.0f;
} else {
temp = (float)((~(data >> 9) & 0x07FF) + 1) / -10.0f;
}
}
bool ws_protocol_gt_wt_03_check_crc() {
uint8_t msg[] = {
static_cast<uint8_t>(decode_data >> 33),
-10
View File
@@ -71,9 +71,6 @@ class FProtoWeatherInfactory : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_infactory_check_crc()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_infactory_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -122,13 +119,6 @@ class FProtoWeatherInfactory : public FProtoWeatherBase {
crc ^= msg[4] >> 4; // last nibble is only XORed
return (crc == ((decode_data >> 28) & 0x0F));
}
void ws_protocol_infactory_remote_controller() {
id = data >> 32;
battery_low = (data >> 26) & 1;
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)((data >> 12) & 0x0FFF) - 900.0f) / 10.0f);
humidity = (((data >> 8) & 0x0F) * 10) + ((data >> 4) & 0x0F); // BCD, 'A0'=100%rH
channel = data & 0x03;
}
};
#endif
-17
View File
@@ -78,9 +78,6 @@ class FProtoWeatherKedsum : public FProtoWeatherBase {
if ((decode_count_bit ==
min_count_bit_for_found) &&
ws_protocol_kedsum_th_check_crc()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_kedsum_th_remote_controller();
if (callback) callback(this);
}
decode_data = 0;
@@ -127,20 +124,6 @@ class FProtoWeatherKedsum : public FProtoWeatherBase {
crc ^= msg[4] >> 4; // last nibble is only XORed
return (crc == (msg[4] & 0x0F));
}
void ws_protocol_kedsum_th_remote_controller() {
id = data >> 32;
if ((data >> 30) & 0x3) {
battery_low = 0;
} else {
battery_low = 1;
}
channel = ((data >> 28) & 0x3) + 1;
uint16_t temp_raw = ((data >> 16) & 0x0f) << 8 |
((data >> 20) & 0x0f) << 4 | ((data >> 24) & 0x0f);
temp = FProtoGeneral::locale_fahrenheit_to_celsius(((float)temp_raw - 900.0f) / 10.0f);
humidity = ((data >> 8) & 0x0f) << 4 | ((data >> 12) & 0x0f);
}
};
#endif
@@ -79,9 +79,6 @@ class FProtoWeatherLaCrosseTx : public FProtoWeatherBase {
if ((decode_data & LACROSSE_TX_SUNC_MASK) ==
LACROSSE_TX_SUNC_PATTERN) {
if (ws_protocol_lacrosse_tx_check_crc()) {
data = decode_data;
data_count_bit = LACROSSE_TX_BIT_SIZE;
ws_protocol_lacrosse_tx_remote_controller();
if (callback) callback(this);
}
}
@@ -119,28 +116,6 @@ class FProtoWeatherLaCrosseTx : public FProtoWeatherBase {
uint32_t te_delta = 120;
uint32_t min_count_bit_for_found = 40;
void ws_protocol_lacrosse_tx_remote_controller() {
uint8_t msg_type = (data >> 32) & 0x0F;
id = (((data >> 28) & 0x0F) << 3) | (((data >> 24) & 0x0F) >> 1);
float msg_value = (float)((data >> 20) & 0x0F) * 10.0f +
(float)((data >> 16) & 0x0F) +
(float)((data >> 12) & 0x0F) * 0.1f;
if (msg_type == LACROSSE_TX_MSG_TYPE_TEMP) { //-V1051
temp = msg_value - 50.0f;
humidity = WS_NO_HUMIDITY;
} else if (msg_type == LACROSSE_TX_MSG_TYPE_HUM) {
// ToDo for verification, records are needed with sensors maintaining temperature and temperature for this standard
humidity = (uint8_t)msg_value;
} else {
// furi_crash("WS: WSProtocolLaCrosse_TX incorrect msg_type.");
}
battery_low = WS_NO_BATT;
channel = WS_NO_CHANNEL;
}
bool ws_protocol_lacrosse_tx_check_crc() {
if (!decode_data) return false;
uint8_t msg[] = {
@@ -67,9 +67,9 @@ class FProtoWeatherLaCrosseTx141thbv2 : public FProtoWeatherBase {
if ((decode_count_bit == min_count_bit_for_found) ||
(decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT)) {
if (ws_protocol_lacrosse_tx141thbv2_check_crc()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_lacrosse_tx141thbv2_remote_controller();
if (decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) {
decode_data >>= 1;
}
if (callback) callback(this);
}
decode_data = 0;
@@ -107,17 +107,7 @@ class FProtoWeatherLaCrosseTx141thbv2 : public FProtoWeatherBase {
uint8_t crc = FProtoGeneral::subghz_protocol_blocks_lfsr_digest8_reflect(msg, 4, 0x31, 0xF4);
return (crc == (data & 0xFF));
}
void ws_protocol_lacrosse_tx141thbv2_remote_controller() {
if (data_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) {
data >>= 1;
}
id = data >> 32;
battery_low = (data >> 31) & 1;
// btn = (data >> 30) & 1;
channel = ((data >> 28) & 0x03) + 1;
temp = ((float)((data >> 16) & 0x0FFF) - 500.0f) / 10.0f;
humidity = (data >> 8) & 0xFF;
}
bool ws_protocol_decoder_lacrosse_tx141thbv2_add_bit(uint32_t te_last, uint32_t te_current) {
bool ret = false;
if (DURATION_DIFF(te_last + te_current, te_short + te_long) < te_delta * 2) {
-20
View File
@@ -51,9 +51,6 @@ class FProtoWeatherNexusTH : public FProtoWeatherBase {
parser_step = Nexus_THDecoderStepReset;
if ((decode_count_bit == min_count_bit_for_found) &&
ws_protocol_nexus_th_check()) {
data = decode_data;
data_count_bit = decode_count_bit;
ws_protocol_nexus_th_remote_controller();
if (callback) callback((FProtoWeatherBase*)this);
parser_step = Nexus_THDecoderStepCheckDuration;
}
@@ -98,23 +95,6 @@ class FProtoWeatherNexusTH : public FProtoWeatherBase {
}
return true;
}
// fill the base class's variables before calling the callback
void ws_protocol_nexus_th_remote_controller() {
id = (data >> 28) & 0xFF;
battery_low = !((data >> 27) & 1);
channel = ((data >> 24) & 0x03) + 1;
if (!((data >> 23) & 1)) {
temp = (float)((data >> 12) & 0x07FF) / 10.0f;
} else {
temp = (float)((~(data >> 12) & 0x07FF) + 1) / -10.0f;
}
humidity = data & 0xFF;
if (humidity > 95)
humidity = 95;
else if (humidity < 20)
humidity = 20;
}
};
#endif
+19 -17
View File
@@ -107,7 +107,6 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
// waiting for fixed oregon2 data
if (decode_count_bit == 32) {
data = decode_data;
data_count_bit = decode_count_bit;
decode_data = 0UL;
decode_count_bit = 0;
@@ -117,13 +116,13 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
data = (data & 0x33333333) << 2 |
(data & 0xCCCCCCCC) >> 2;
ws_oregon2_decode_const_data();
// ws_oregon2_decode_const_data();
var_bits = oregon2_sensor_id_var_bits(OREGON2_SENSOR_ID(data));
if (!var_bits) {
// sensor is not supported, stop decoding, but showing the decoded fixed part
// sensor is not supported, stop decoding, so won't showing the decoded fixed part
parser_step = Oregon2DecoderStepReset;
if (callback) callback(this);
// if (callback) callback(this);
} else {
parser_step = Oregon2DecoderStepVarData;
}
@@ -139,8 +138,8 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
(var_data & 0xAAAAAAAA) >> 1;
var_data = (var_data & 0x33333333) << 2 |
(var_data & 0xCCCCCCCC) >> 2;
ws_oregon2_decode_var_data(OREGON2_SENSOR_ID(data), var_data >> OREGON2_CHECKSUM_BITS);
decode_data = var_data;
// ws_oregon2_decode_var_data(OREGON2_SENSOR_ID(data), var_data >> OREGON2_CHECKSUM_BITS); //a bit stepback, but will work
parser_step = Oregon2DecoderStepReset;
if (callback) callback(this);
@@ -155,6 +154,7 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
uint32_t te_long = 1000;
uint32_t te_delta = 200;
uint32_t min_count_bit_for_found = 32;
uint64_t data = 0;
bool have_bit = false;
bool prev_bit = 0;
@@ -202,19 +202,21 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
return 0;
}
}
void ws_oregon2_decode_const_data() {
id = OREGON2_SENSOR_ID(data);
uint8_t ch_bits = (data >> 12) & 0xF;
channel = 1;
while (ch_bits > 1) {
channel++;
ch_bits >>= 1;
}
battery_low = (data & OREGON2_FLAG_BAT_LOW) ? 1 : 0;
}
/* void ws_oregon2_decode_const_data() {
id = OREGON2_SENSOR_ID(data);
uint8_t ch_bits = (data >> 12) & 0xF;
channel = 1;
while (ch_bits > 1) {
channel++;
ch_bits >>= 1;
}
battery_low = (data & OREGON2_FLAG_BAT_LOW) ? 1 : 0;
}
uint16_t bcd_decode_short(uint32_t data) {
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
}
float ws_oregon2_decode_temp(uint32_t data) {
int32_t temp_val;
temp_val = bcd_decode_short(data >> 4);
@@ -241,7 +243,7 @@ class FProtoWeatherOregon2 : public FProtoWeatherBase {
default:
break;
}
}
}*/
};
#endif
+31 -32
View File
@@ -66,7 +66,6 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
// waiting for fixed oregon3 data
if (decode_count_bit == OREGON3_FIXED_PART_BITS) {
data = decode_data;
data_count_bit = decode_count_bit;
decode_data = 0UL;
decode_count_bit = 0;
@@ -76,9 +75,8 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
data = (data & 0x33333333) << 2 |
(data & 0xCCCCCCCC) >> 2;
ws_oregon3_decode_const_data();
var_bits =
oregon3_sensor_id_var_bits(OREGON3_SENSOR_ID(data));
// ws_oregon3_decode_const_data(); //todo fix somehow in the future
var_bits = oregon3_sensor_id_var_bits(OREGON3_SENSOR_ID(data));
if (!var_bits) {
// sensor is not supported, stop decoding
@@ -98,8 +96,8 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
(var_data & 0xAAAAAAAAAAAAAAAA) >> 1;
var_data = (var_data & 0x3333333333333333) << 2 |
(var_data & 0xCCCCCCCCCCCCCCCC) >> 2;
ws_oregon3_decode_var_data(OREGON3_SENSOR_ID(data), var_data >> OREGON3_CHECKSUM_BITS);
decode_data = var_data;
// ws_oregon3_decode_var_data(OREGON3_SENSOR_ID(data), var_data >> OREGON3_CHECKSUM_BITS);
parser_step = Oregon3DecoderStepReset;
if (callback) callback(this);
}
@@ -113,6 +111,7 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
uint32_t te_long = 1100;
uint32_t te_delta = 300;
uint32_t min_count_bit_for_found = 32;
uint64_t data = 0;
bool prev_bit = false;
uint8_t var_bits{0};
@@ -143,31 +142,31 @@ class FProtoWeatherOregon3 : public FProtoWeatherBase {
return 0;
}
}
void ws_oregon3_decode_const_data() {
id = OREGON3_SENSOR_ID(data);
channel = (data >> 12) & 0xF;
battery_low = (data & OREGON3_FLAG_BAT_LOW) ? 1 : 0;
}
uint16_t ws_oregon3_bcd_decode_short(uint32_t data) {
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
}
float ws_oregon3_decode_temp(uint32_t data) {
int32_t temp_val;
temp_val = ws_oregon3_bcd_decode_short(data >> 4);
temp_val *= 10;
temp_val += (data >> 12) & 0xF;
if (data & 0xF) temp_val = -temp_val;
return (float)temp_val / 10.0;
}
void ws_oregon3_decode_var_data(uint16_t sensor_id, uint32_t data) {
switch (sensor_id) {
case ID_THGR221:
default:
humidity = ws_oregon3_bcd_decode_short(data >> 4);
temp = ws_oregon3_decode_temp(data >> 12);
break;
}
}
/* void ws_oregon3_decode_const_data() {
id = OREGON3_SENSOR_ID(data);
channel = (data >> 12) & 0xF;
battery_low = (data & OREGON3_FLAG_BAT_LOW) ? 1 : 0;
}
uint16_t ws_oregon3_bcd_decode_short(uint32_t data) {
return (data & 0xF) * 10 + ((data >> 4) & 0xF);
}
float ws_oregon3_decode_temp(uint32_t data) {
int32_t temp_val;
temp_val = ws_oregon3_bcd_decode_short(data >> 4);
temp_val *= 10;
temp_val += (data >> 12) & 0xF;
if (data & 0xF) temp_val = -temp_val;
return (float)temp_val / 10.0;
}
void ws_oregon3_decode_var_data(uint16_t sensor_id, uint32_t data) {
switch (sensor_id) {
case ID_THGR221:
default:
humidity = ws_oregon3_bcd_decode_short(data >> 4);
temp = ws_oregon3_decode_temp(data >> 12);
break;
}
}*/
};
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More