Infrared: Add option to "Load from Library File" for Universal Remotes (#255)

* init

* comments

* remove trash

* remove code that mistakenly added from merging conflicts

* remove code that mistakenly added from merging conflicts

* format

* remove header that added during debugging

* ecit name

* Revert some whitespace changes to avoid future conflicts

* get_button_count()

* Use same index values

* Use common functions where possible

* Unroll long if into guard check

* Fix furi check failed due to inflated button index

* Show "assets" folders

* Load DB file only once and show loading animation

* Add bool for auto_detect_buttons

* Show error when tryingto load remote file as universal library

* Remove unnecessary includes

* Fix inputs

* more_devices -> from_file

* Consistency

* Remember last selected library file

* Update changelog

---------

Co-authored-by: Willy-JL <49810075+Willy-JL@users.noreply.github.com>
This commit is contained in:
sommermorgentraum
2024-10-12 09:08:20 +08:00
committed by GitHub
parent 925481ffd0
commit 2f22fad58b
9 changed files with 233 additions and 5 deletions

View File

@@ -6,6 +6,12 @@
#include "infrared_signal.h"
#define TAG "InfraredBruteforce"
#define INFRARED_FILE_HEADER "IR signals file"
#define INFRARED_LIBRARY_HEADER "IR library file"
#define INFRARED_LIBRARY_VERSION (1)
typedef struct {
uint32_t index;
uint32_t count;
@@ -50,7 +56,9 @@ void infrared_brute_force_set_db_filename(InfraredBruteForce* brute_force, const
brute_force->db_filename = db_filename;
}
InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) {
InfraredErrorCode infrared_brute_force_calculate_messages(
InfraredBruteForce* brute_force,
bool auto_detect_buttons) {
furi_assert(!brute_force->is_started);
furi_assert(brute_force->db_filename);
InfraredErrorCode error = InfraredErrorCodeNone;
@@ -66,7 +74,33 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br
break;
}
uint32_t version;
// Temporarily use signal_name to get header info
if(!flipper_format_read_header(ff, signal_name, &version)) {
error = InfraredErrorCodeFileOperationFailed;
break;
}
if(furi_string_equal(signal_name, INFRARED_FILE_HEADER)) {
FURI_LOG_E(TAG, "Remote file can't be loaded in this context");
error = InfraredErrorCodeWrongFileType;
break;
}
if(!furi_string_equal(signal_name, INFRARED_LIBRARY_HEADER)) {
error = InfraredErrorCodeWrongFileType;
FURI_LOG_E(TAG, "Filetype unknown");
break;
}
if(version != INFRARED_LIBRARY_VERSION) {
error = InfraredErrorCodeWrongFileVersion;
FURI_LOG_E(TAG, "Wrong file version");
break;
}
bool signals_valid = false;
uint32_t auto_detect_button_index = 0;
while(infrared_signal_read_name(ff, signal_name) == InfraredErrorCodeNone) {
error = infrared_signal_read_body(signal, ff);
signals_valid = (!INFRARED_ERROR_PRESENT(error)) && infrared_signal_is_valid(signal);
@@ -74,6 +108,11 @@ InfraredErrorCode infrared_brute_force_calculate_messages(InfraredBruteForce* br
InfraredBruteForceRecord* record =
InfraredBruteForceRecordDict_get(brute_force->records, signal_name);
if(!record && auto_detect_buttons) {
infrared_brute_force_add_record(
brute_force, auto_detect_button_index++, furi_string_get_cstr(signal_name));
record = InfraredBruteForceRecordDict_get(brute_force->records, signal_name);
}
if(record) { //-V547
++(record->count);
}
@@ -167,3 +206,31 @@ void infrared_brute_force_reset(InfraredBruteForce* brute_force) {
furi_assert(!brute_force->is_started);
InfraredBruteForceRecordDict_reset(brute_force->records);
}
size_t infrared_brute_force_get_button_count(const InfraredBruteForce* brute_force) {
size_t size = InfraredBruteForceRecordDict_size(brute_force->records);
return size;
}
const char*
infrared_brute_force_get_button_name(const InfraredBruteForce* brute_force, size_t index) {
if(index >= infrared_brute_force_get_button_count(brute_force)) {
return NULL;
}
InfraredBruteForceRecordDict_it_t it;
for(InfraredBruteForceRecordDict_it(it, brute_force->records);
!InfraredBruteForceRecordDict_end_p(it);
InfraredBruteForceRecordDict_next(it)) {
// Dict elements are unordered, they may be shuffled while adding elements, so the
// index used in add_record() may differ when iterating here, so we have to check
// the stored index not "position" index
const InfraredBruteForceRecordDict_itref_t* pair = InfraredBruteForceRecordDict_cref(it);
if(pair->value.index == index) {
const char* button_name = furi_string_get_cstr(pair->key);
return button_name;
}
}
return NULL; //just as fallback
}