Bladeren bron

Merge quac from https://github.com/rdefeo/quac

WillyJL 7 maanden geleden
bovenliggende
commit
99a6de413a

+ 12 - 1
quac/CHANGELOG.md

@@ -1,10 +1,21 @@
-## 0.8.0
+## 0.9.1
+
+- Fixed About screen
+- Updated readme
+
+## 0.9.0
 
 - Complete refactor of SubGhz code
 - Supports dynamic SubGhz signals with rolling codes
 - Auto-detect External SubGhz Antenna and use/prefer if available
 - Removed SugGhz External Antenna setting due to new auto-detect feature
 - Removed SubGhz Repeat setting, no longer needed (was non-standard)
+- Added SubGhz Duration setting for non-RAW signals
+
+## 0.8
+
+- Added Import Link Here, which creates Quac Link files
+- Scroll long action names
 
 ## 0.7.2
 

+ 5 - 3
quac/README.md

@@ -78,7 +78,8 @@ Long pressing the `Right` button will launch a settings menu for the currently s
 * **Import Here**: Launches file browser to let you select a signal file from anywhere on the SDcard and then copies it to the current folder.
   * When importing an IR file, you are prompted to select which IR command to import. This individual command is imported as it's own `.ir` file into the current location. You can also select `* IMPORT ALL *` to, well, import all commands.
   * If an Import fails, the Flipperzero will flash red and buzz - this may be caused by a duplicate filename (i.e. that file/IR command already exists in the current folder) or the target file can not be read.
-* **Import Link Here**: Similar to Link Here, but instead of copying the file, it will generate a Quac Link file (`.ql`) which contains the path of the selected file.
+* **Import Link Here**: Similar to Import Here, but instead of copying the file, it will generate a Quac Link file (`.ql`) which contains the path of the selected file. This acts like a symbolic link on linux or other operating systems.
+  * This feature is most useful for dynamic subghz files. Each transmission/playback of those subghz files can result in an incremented counter/value within the signal file. By referring to a single "source of truth" for that signal, then no matter which app is playing back this signal, the original will have its counter updated accordingly. If, instead, you imported the file directly (i.e. copied), then the counters within that file would get out of sync with the original and it will eventually stop working.
   * At this time, you can not create a link to an IR file, as this would need to also include a reference to the specific signal within the target file.
   * You can not create a link to a Quac Link file.
 * **Create Group**: Prompts for the name of a new folder that will be created at that point in the folder structure.
@@ -90,7 +91,7 @@ You can chain multiple signal playback actions together by creating a playlist.
 * Comments: lines that start with a `#` are ignored
 * `pause <ms>` on a line will pause the playback by the specified millisecond duration
 * Signal file names can be absolute (full path) or relative to the current directory
-* RFID and NFC files can have an optional duration specified. Simply add a space after the signal's file name, followed by a millisecond duration. This duration will override the Quac! Settings value, just for this one signal.
+* SubGhz, RFID, and NFC files can have an optional duration specified. Simply add a space after the signal's file name, followed by a millisecond duration. This duration will override the Quac! Settings value, just for this one signal.
 
 Errors found in the playlist will halt playback and vibrate the Flipper. Blank lines are ignored.
 
@@ -121,11 +122,12 @@ The list view UI is based on the sorted file and folder order. This is enforced
 
 ![Settings menu](screenshots/screenshot_2.png)
 
-The settings menu will appear as the last item when you are viewing the "root" directory. Within the settings you can control:
+The settings menu will appear as the last item when you are viewing the "root" (top level) directory. Within the settings you can control:
 
 * Layout: Switch between Horizontal and Vertical layout
 * Show Icons: Toggles display of all icons
 * Show Headers: Toggles display of header/folder text at the top, giving you room for one more item on screen!
+* SubGhz Duration: Changes the length of time a non-RAW SubGhz signal is trasmitted. This allows for repeated transmissions during the interval. Within playlists, this can be overridden per `.sub` file.
 * RFID Duration: Changes the length of time a RFID signal is transmitted. Within playlists, this can be overridden per `.rfid` file.
 * NFC Duration: Changes the length of time a NFC signal is transmitted. Within playlists, this can be overridden per `.nfc` file.
 * iButton Duration: Changes the length of time a iButton signal is transmitted. Within playlists, this can be overridden per `.ibtn` file.

+ 4 - 2
quac/README_flipperlab.md

@@ -10,17 +10,18 @@ The app does not provide any recording functionality - you can use the existing
 
 ## Features
 
-* Playback of rfid, sub-ghz, IR, NFC, and iButton signals
+* Playback of sub-ghz, rfid, IR, NFC, and iButton signals
 * Easy navigation
 * Flexible signal organization
 * In-app file management
 * Playlist support
 * Flexible naming/sorting, hidden file/folder support
+* File linking
 * Customizable UI
 
 ## Signal playback
 
-The signal files are played back as recorded. During playback/transmit, the LED light will flash blue until the action is complete. For RFID, NFC, anbd iButton signals, they are continuously played back for the durations specified in the Settings.
+The signal files are played back as recorded. During playback/transmit, the LED light will flash blue until the action is complete. For SubGhz (non-RAW), RFID, NFC, and iButton signals, they are continuously played back for the durations specified in the Settings.
 
 ## Signal Organization
 
@@ -43,6 +44,7 @@ The settings menu will appear as the last item when you are viewing the "root" d
 * Layout: Switch between Horizontal and Vertical layout
 * Show Icons: Toggles display of all icons
 * Show Headers: Toggles display of header/folder text at the top, giving you room for one more item on screen!
+* SubGhz Duration: Changes the length of time a non-RAW SubGhz signal is transmitted. Can be overridden, per SubGhz file in a Playlist
 * RFID Duration: Changes the length of time a RFID signal is transmitted. Can be overridden, per RFID file in a Playlist
 * NFC Duration: Changes the length of time a NFC signal is transmitted. Can be overridden, per NFC file in a Playlist
 * iButton Duration: Changes the length of time a iButton signal is transmitted. Can be overridden, per iButton file in a Playlist

+ 0 - 3
quac/actions/action.c

@@ -3,8 +3,6 @@
 #include "item.h"
 #include "action_i.h"
 
-#define MAX_FILE_LEN (size_t)256
-
 void action_ql_resolve(
     void* context,
     const FuriString* action_path,
@@ -44,7 +42,6 @@ void action_ql_resolve(
                 "Quac Link: Linked file does not exist! %s", furi_string_get_cstr(new_path));
             break;
         }
-
     } while(false);
     storage_file_close(file_link);
     storage_file_free(file_link);

+ 4 - 9
quac/actions/action.h

@@ -78,13 +78,8 @@ void action_ir_power_otg(bool enable) {
 
     if(tx_pin_detected == FuriHalInfraredTxPinInternal) return;
 
-    if(enable) {
-        if(!furi_hal_power_is_otg_enabled()) {
-            furi_hal_power_enable_otg();
-        }
-    } else {
-        if(furi_hal_power_is_otg_enabled()) {
-            furi_hal_power_disable_otg();
-        }
-    }
+    if(enable)
+        furi_hal_power_enable_otg();
+    else
+        furi_hal_power_disable_otg();
 }

+ 11 - 1
quac/actions/action_ir_utils.c

@@ -31,6 +31,7 @@ void action_qpl_tx(void* context, const FuriString* action_path, FuriString* err
     App* app = context;
 
     // Save the current durations, in case the are changed during playback
+    uint32_t orig_subghz_duration = app->settings.subghz_duration;
     uint32_t orig_rfid_duration = app->settings.rfid_duration;
     uint32_t orig_nfc_duration = app->settings.nfc_duration;
     uint32_t orig_ibutton_duration = app->settings.ibutton_duration;
@@ -97,7 +98,14 @@ void action_qpl_tx(void* context, const FuriString* action_path, FuriString* err
 
                 // FURI_LOG_I(TAG, " - Found extension of %s", ext);
 
-                if(!strcmp(ext, ".rfid")) {
+                if(!strcmp(ext, ".sub")) {
+                    uint32_t subghz_duration = 0;
+                    // FURI_LOG_I(TAG, "SubGhz file with duration");
+                    if(sscanf(furi_string_get_cstr(buffer), "%lu", &subghz_duration) == 1) {
+                        FURI_LOG_I(TAG, "SubGhz duration = %lu", subghz_duration);
+                        app->settings.subghz_duration = subghz_duration;
+                    }
+                } else if(!strcmp(ext, ".rfid")) {
                     uint32_t rfid_duration = 0;
                     // FURI_LOG_I(TAG, "RFID file with duration");
                     if(sscanf(furi_string_get_cstr(buffer), "%lu", &rfid_duration) == 1) {
@@ -142,6 +150,8 @@ void action_qpl_tx(void* context, const FuriString* action_path, FuriString* err
             path_extract_extension(buffer, ext, MAX_EXT_LEN);
             if(!strcmp(ext, ".sub")) {
                 action_subghz_tx(context, buffer, error);
+                // Reset our default duration back - in case it was changed during playback
+                app->settings.subghz_duration = orig_subghz_duration;
             } else if(!strcmp(ext, ".rfid")) {
                 action_rfid_tx(context, buffer, error);
                 // Reset our default duration back - in case it was changed during playback

+ 1 - 2
quac/actions/action_rfid.c

@@ -186,8 +186,7 @@ void action_subghz_tx(void* context, const FuriString* action_path, FuriString*
             txrx, action_subghz_raw_end_callback, furi_thread_get_current());
         furi_thread_flags_wait(0, FuriFlagWaitAll, FuriWaitForever);
     } else {
-        // TODO: Should this be based on a Setting?
-        furi_delay_ms(1500);
+        furi_delay_ms(app->settings.subghz_duration);
     }
 
     FURI_LOG_I(TAG, "SUBGHZ: Action complete.");

+ 1 - 1
quac/actions/helpers/subghz_txrx.c

@@ -8,7 +8,7 @@ App(
     stack_size=2 * 1024,
     fap_category="Tools",
     # Optional values
-    fap_version="0.8.0",
+    fap_version="0.9.1",
     fap_icon="images/quac.png",  # 10x10 1-bit PNG
     fap_description="Quick Action remote control app",
     fap_author="Roberto De Feo",

+ 2 - 1
quac/images/.gitkeep

@@ -17,7 +17,7 @@
 #include "item.h"
 
 #define QUAC_NAME    "Quac!"
-#define QUAC_VERSION "v0.8.0"
+#define QUAC_VERSION "v0.9.1"
 #define QUAC_ABOUT                                    \
     "Quick Action remote control\n" QUAC_VERSION "\n" \
     "github.com/rdefeo/quac"
@@ -58,6 +58,7 @@ typedef struct App {
         QuacAppLayout layout; // Defaults to Portrait
         bool show_icons; // Defaults to True
         bool show_headers; // Defaults to True
+        uint32_t subghz_duration; // Defaults to 1500 ms
         uint32_t rfid_duration; // Defaults to 2500 ms
         uint32_t nfc_duration; // Defaults to 1000 ms
         uint32_t ibutton_duration; // Defaults to 1000 ms

+ 12 - 0
quac/quac_settings.c

@@ -10,6 +10,7 @@ void quac_set_default_settings(App* app) {
     app->settings.layout = QUAC_APP_LANDSCAPE;
     app->settings.show_icons = true;
     app->settings.show_headers = true;
+    app->settings.subghz_duration = 1500;
     app->settings.rfid_duration = 2500;
     app->settings.nfc_duration = 1000;
     app->settings.ibutton_duration = 1000;
@@ -70,6 +71,12 @@ void quac_load_settings(App* app) {
             app->settings.show_headers = (temp_data32 == 1) ? true : false;
         }
 
+        if(!flipper_format_read_uint32(fff_settings, "SubGhz Duration", &temp_data32, 1)) {
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'SubGhz Duration'");
+        } else {
+            app->settings.subghz_duration = temp_data32;
+        }
+
         if(!flipper_format_read_uint32(fff_settings, "RFID Duration", &temp_data32, 1)) {
             FURI_LOG_W(TAG, "SETTINGS: Missing 'RFID Duration'");
         } else {
@@ -141,6 +148,11 @@ void quac_save_settings(App* app) {
             FURI_LOG_E(TAG, "SETTINGS: Failed to write 'Show Headers'");
             break;
         }
+        if(!flipper_format_write_uint32(
+               fff_settings, "SubGhz Duration", &app->settings.subghz_duration, 1)) {
+            FURI_LOG_E(TAG, "SETTINGS: Failed to write 'SubGhz Duration'");
+            break;
+        }
         if(!flipper_format_write_uint32(
                fff_settings, "RFID Duration", &app->settings.rfid_duration, 1)) {
             FURI_LOG_E(TAG, "SETTINGS: Failed to write 'RFID Duration'");

+ 15 - 1
quac/quac_settings.h

@@ -17,7 +17,7 @@
 // dynamically know it's list index for our on_event method. However, we'll need to
 // hardcode the value..
 // TODO: Figure out a better way to do this
-#define SCENE_SETTINGS_ABOUT 8 // 9 items in our Settings list, so last index is 8
+#define SCENE_SETTINGS_ABOUT 9 // 10 items in our Settings list, so last index is 9
 
 static const char* const layout_text[2] = {"Vert", "Horiz"};
 static const uint32_t layout_value[2] = {QUAC_APP_PORTRAIT, QUAC_APP_LANDSCAPE};
@@ -71,6 +71,13 @@ static void scene_settings_show_headers_changed(VariableItem* item) {
     app->settings.show_headers = show_offon_value[index];
 }
 
+static void scene_settings_subghz_duration_changed(VariableItem* item) {
+    App* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    variable_item_set_current_value_text(item, duration_text[index]);
+    app->settings.subghz_duration = duration_value[index];
+}
+
 static void scene_settings_rfid_duration_changed(VariableItem* item) {
     App* app = variable_item_get_context(item);
     uint8_t index = variable_item_get_current_value_index(item);
@@ -137,6 +144,13 @@ void scene_settings_on_enter(void* context) {
     variable_item_set_current_value_index(item, value_index);
     variable_item_set_current_value_text(item, show_offon_text[value_index]);
 
+    item = variable_item_list_add(
+        vil, "SubGhz Duration", V_DURATION_COUNT, scene_settings_subghz_duration_changed, app);
+    value_index =
+        value_index_uint32(app->settings.subghz_duration, duration_value, V_DURATION_COUNT);
+    variable_item_set_current_value_index(item, value_index);
+    variable_item_set_current_value_text(item, duration_text[value_index]);
+
     item = variable_item_list_add(
         vil, "RFID Duration", V_DURATION_COUNT, scene_settings_rfid_duration_changed, app);
     value_index =

+ 0 - 0
quac/scenes/scene_settings.h