Skip to content

Commit

Permalink
Merge pull request #14 from leedave/feature/subghz_encoded
Browse files Browse the repository at this point in the history
Feature/subghz encoded
  • Loading branch information
leedave authored Feb 5, 2024
2 parents 8520f4c + 7f17cb6 commit 4d4962f
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 38 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ Wouldn't it be nicer to simply click one button and let everything happen? This
- Add pauses, becaue target systems are not always fast enough for multiple commands<br>
- Run file containing chained IR & SubGhz commands<br>

### Settings
- LED FX, allow the LED to blink
- Save settings, stores a file with your settings in it on exit
- IR time ms, the default duration of an IR signal transmission. Individual times can be set
- SubG. time ms, the default duration of a SubGhz signal. Only needed for Encoded signals, RAW files play until finished

### Limitations
SubGhz commands will stop working if you move/rename/delete the original files on your Flipper. This is because
of how the Flippers SubGhz worker expects data.
SubGhz commands will stop working if you move/rename/delete the original files on your Flipper. This is because of how the Flippers SubGhz worker expects data.

After an upgrade a crash on exit can occur, due to small improvements to the file formats. Sorry about that, it only happens once.

## How to install on Flipper Zero
- If you do not have one, download a firmware<br>
Expand Down
2 changes: 1 addition & 1 deletion application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ App(
stack_size=3 * 1024,
fap_icon="icons/xremote_10px.png",
fap_icon_assets="icons",
fap_version="2.3",
fap_version="2.4",
fap_category="Infrared",
fap_author="Leedave",
fap_description="One-Click, sends multiple commands",
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This app combines your IR and SubGhz commands into a playlist that can be run wi
- Save your command chain / playlist to flipper
- Disable LED effects if not wanted
- Configure duration of IR Signals
- Configure default duration of Encoded SubGhz Signals

## What good is this?

Expand Down
6 changes: 6 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.4
- Added support for encoded SubGhz files
- Added timer for SubGhz transmission (not needed in RAW files)
- Added version number to app info screen
- Minor updates/instrutions in readme.md

## 2.3
- Fixed Crash after creating chains with SubGhz Items

Expand Down
38 changes: 28 additions & 10 deletions helpers/subghz/subghz.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ SubGhz* subghz_alloc() {

subghz->file_path = furi_string_alloc();
subghz->txrx = subghz_txrx_alloc();
subghz->dialogs = furi_record_open(RECORD_DIALOGS);

return subghz;
}

void subghz_free(SubGhz* subghz) {
subghz_txrx_free(subghz->txrx);
furi_string_free(subghz->file_path);
furi_record_close(RECORD_DIALOGS);

// The rest
free(subghz);
Expand All @@ -38,16 +40,32 @@ void subghz_scene_transmit_callback_end_tx(void* context) {
void subghz_send(void* context, const char* path) {
XRemote* app = context;

subghz_load_protocol_from_file(app->subghz, path);
FURI_LOG_D(TAG, "Starting Transmission");
subghz_txrx_tx_start(
app->subghz->txrx,
subghz_txrx_get_fff_data(app->subghz->txrx)); //Seems like it must be done this way
if(!subghz_load_protocol_from_file(app->subghz, path)) {
xremote_cross_remote_set_transmitting(app->cross_remote, XRemoteTransmittingStop);
app->transmitting = false;
return;
}

FURI_LOG_D(TAG, "setting sugbhz raw file encoder worker callback");
subghz_txrx_set_raw_file_encoder_worker_callback_end(
app->subghz->txrx, subghz_scene_transmit_callback_end_tx, app);
app->state_notifications = SubGhzNotificationStateTx;
if(subghz_get_load_type_file(app->subghz) == SubGhzLoadTypeFileRaw) {
FURI_LOG_D(TAG, "Starting Transmission");
subghz_txrx_tx_start(
app->subghz->txrx,
subghz_txrx_get_fff_data(app->subghz->txrx)); //Seems like it must be done this way

FURI_LOG_D(TAG, "Finished Transmitting");
FURI_LOG_D(TAG, "setting sugbhz raw file encoder worker callback");
subghz_txrx_set_raw_file_encoder_worker_callback_end(
app->subghz->txrx, subghz_scene_transmit_callback_end_tx, app);
app->state_notifications = SubGhzNotificationStateTx;

FURI_LOG_D(TAG, "Finished Transmitting");
} else {
subghz_tx_start(app->subghz, subghz_txrx_get_fff_data(app->subghz->txrx));
app->state_notifications = SubGhzNotificationStateTx;
furi_thread_flags_wait(0, FuriFlagWaitAny, app->sg_timing);
app->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(app->subghz->txrx);

xremote_cross_remote_set_transmitting(app->cross_remote, XRemoteTransmittingStop);
app->transmitting = false;
}
}
27 changes: 5 additions & 22 deletions helpers/subghz/subghz_i.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,22 @@ void subghz_set_default_preset(SubGhz* subghz) {
0);
}*/

/*bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) {
switch(subghz_txrx_tx_start(subghz->txrx, flipper_format)) {
case SubGhzTxRxStartTxStateErrorParserOthers:
dialog_message_show_storage_error(
subghz->dialogs, "Error in protocol\nparameters\ndescription");
break;
case SubGhzTxRxStartTxStateErrorOnlyRx:
FURI_LOG_D(TAG, 'Cannot send, only RX possible');
// FURI_LOG_D(TAG, 'Cannot send, only RX possible');
break;

default:
return true;
break;
}
return false;
}*/
}

bool subghz_key_load(SubGhz* subghz, const char* file_path) { //, bool show_dialog) {
furi_assert(subghz);
Expand Down Expand Up @@ -182,34 +182,17 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { //, bool show_dial
return false;
}

/*SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz) {
SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz) {
furi_assert(subghz);
return subghz->load_type_file;
}*/
}

bool subghz_load_protocol_from_file(SubGhz* subghz, const char* path) {
furi_assert(subghz);

//FuriString* file_path = furi_string_alloc();

bool res = false;

/*DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(
&browser_options, SUBGHZ_APP_FILENAME_EXTENSION, &I_sub1_10px);
browser_options.base_path = SUBGHZ_APP_FOLDER;
// Input events and views are managed by file_select
bool res = dialog_file_browser_show(
subghz->dialogs, subghz->file_path, subghz->file_path, &browser_options);
if(res) {*/
//res = subghz_key_load(subghz, furi_string_get_cstr(subghz->file_path), true);
res = subghz_key_load(subghz, path); //, true);
//}

//furi_string_free(file_path);

return res;
}

Expand Down
6 changes: 4 additions & 2 deletions helpers/subghz/subghz_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef struct SubGhz SubGhz;
struct SubGhz {
SubGhzTxRx* txrx;
FuriString* file_path;
DialogsApp* dialogs;
//FuriString* file_path_tmp;
//char file_name_tmp[SUBGHZ_MAX_LEN_NAME]; // just left it in to make the object not empty
//SubGhzNotificationState state_notifications;
Expand All @@ -67,13 +68,14 @@ struct SubGhz {
//void subghz_blink_start(SubGhz* subghz);
//void subghz_blink_stop(SubGhz* subghz);

//bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format);
// Used on Encoded SubGhz
bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format);
//void subghz_dialog_message_show_only_rx(SubGhz* subghz);

bool subghz_key_load(SubGhz* subghz, const char* file_path); //, bool show_dialog);
bool subghz_load_protocol_from_file(SubGhz* subghz, const char* path);
//bool subghz_file_available(SubGhz* subghz);
//SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz);
SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz);

//void subghz_lock(SubGhz* subghz);
//void subghz_unlock(SubGhz* subghz);
Expand Down
2 changes: 2 additions & 0 deletions helpers/xremote_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ void xremote_save_settings(void* context) {
flipper_format_write_uint32(
fff_file, XREMOTE_SETTINGS_KEY_SAVE_SETTINGS, &app->save_settings, 1);
flipper_format_write_uint32(fff_file, XREMOTE_SETTINGS_KEY_IR_TIMING, &app->ir_timing, 1);
flipper_format_write_uint32(fff_file, XREMOTE_SETTINGS_KEY_SG_TIMING, &app->sg_timing, 1);

if(!flipper_format_rewind(fff_file)) {
xremote_close_config_file(fff_file);
Expand Down Expand Up @@ -110,6 +111,7 @@ void xremote_read_settings(void* context) {
flipper_format_read_uint32(
fff_file, XREMOTE_SETTINGS_KEY_SAVE_SETTINGS, &app->save_settings, 1);
flipper_format_read_uint32(fff_file, XREMOTE_SETTINGS_KEY_IR_TIMING, &app->ir_timing, 1);
flipper_format_read_uint32(fff_file, XREMOTE_SETTINGS_KEY_SG_TIMING, &app->sg_timing, 1);

flipper_format_rewind(fff_file);

Expand Down
1 change: 1 addition & 0 deletions helpers/xremote_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define XREMOTE_SETTINGS_KEY_SPEAKER "Speaker"
#define XREMOTE_SETTINGS_KEY_SAVE_SETTINGS "SaveSettings"
#define XREMOTE_SETTINGS_KEY_IR_TIMING "IRTiming"
#define XREMOTE_SETTINGS_KEY_SG_TIMING "SGTiming"

void xremote_save_settings(void* context);
void xremote_read_settings(void* context);
19 changes: 18 additions & 1 deletion scenes/xremote_scene_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ static void xremote_scene_settings_set_ir_timing(VariableItem* item) {
app->ir_timing = (index * 100);
}

static void xremote_scene_settings_set_sg_timing(VariableItem* item) {
XRemote* app = variable_item_get_context(item);
uint32_t index = variable_item_get_current_value_index(item);

snprintf(app->sg_timing_char, 20, "%lu", (index * 100));
variable_item_set_current_value_text(item, app->sg_timing_char);
app->sg_timing = (index * 100);
}

void xremote_scene_settings_submenu_callback(void* context, uint32_t index) {
XRemote* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
Expand Down Expand Up @@ -121,12 +130,20 @@ void xremote_scene_settings_on_enter(void* context) {

// Set Infrared Timer
item = variable_item_list_add(
app->variable_item_list, "IR Timing in ms:", 30, xremote_scene_settings_set_ir_timing, app);
app->variable_item_list, "IR Time ms", 30, xremote_scene_settings_set_ir_timing, app);

variable_item_set_current_value_index(item, (uint8_t)(app->ir_timing / 100));
snprintf(app->ir_timing_char, 20, "%lu", app->ir_timing);
variable_item_set_current_value_text(item, app->ir_timing_char);

// Set SubGhz Timer
item = variable_item_list_add(
app->variable_item_list, "SubG. Time ms", 30, xremote_scene_settings_set_sg_timing, app);

variable_item_set_current_value_index(item, (uint8_t)(app->sg_timing / 100));
snprintf(app->sg_timing_char, 20, "%lu", app->sg_timing);
variable_item_set_current_value_text(item, app->sg_timing_char);

view_dispatcher_switch_to_view(app->view_dispatcher, XRemoteViewIdSettings);
}

Expand Down
4 changes: 4 additions & 0 deletions views/xremote_infoscreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ void xremote_infoscreen_set_callback(

void xremote_infoscreen_draw(Canvas* canvas, XRemoteInfoscreenModel* model) {
UNUSED(model);
char buffer[64];
canvas_clear(canvas);
canvas_set_color(canvas, ColorBlack);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignTop, "Cross Remote");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 64, 22, AlignCenter, AlignTop, "Chain IR and SubGhz");
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignTop, "Commands");

snprintf(buffer, sizeof(buffer), "Version: %s", XREMOTE_VERSION);
canvas_draw_str_aligned(canvas, 64, 42, AlignCenter, AlignTop, buffer);
elements_button_center(canvas, "Back");
}

Expand Down
2 changes: 2 additions & 0 deletions xremote.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ XRemote* xremote_app_alloc() {
app->transmitting = 0;
app->ir_timing = 1000;
app->ir_timing_char = "1000";
app->sg_timing = 500;
app->sg_timing_char = "500";
app->stop_transmit = false;

// Load configs
Expand Down
2 changes: 2 additions & 0 deletions xremote.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ typedef struct {
uint32_t edit_item;
uint32_t ir_timing;
char* ir_timing_char;
uint32_t sg_timing;
char* sg_timing_char;
bool transmitting;
bool stop_transmit;
char text_store[XREMOTE_TEXT_STORE_NUM][XREMOTE_TEXT_STORE_SIZE + 1];
Expand Down
1 change: 1 addition & 0 deletions xremote_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#define XREMOTE_TEXT_STORE_SIZE 128
#define XREMOTE_MAX_ITEM_NAME_LENGTH 22
#define XREMOTE_MAX_REMOTE_NAME_LENGTH 22
#define XREMOTE_VERSION "2.4"

#define INFRARED_APP_EXTENSION ".ir"
#define INFRARED_APP_FOLDER ANY_PATH("infrared")
Expand Down

0 comments on commit 4d4962f

Please sign in to comment.