mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-01-03 10:48:47 +03:00
[FL-3917] Add the ability to send a signal once via RPC (#4000)
* Add the ability to send a signal once * Update protobuf * Fix sending infrared signals * Review changes * Update protobuf * Separate sending an IR signal once into a function * Update protobuf module --------- Co-authored-by: あく <alleteam@gmail.com> Co-authored-by: Georgii Surkov <georgii.surkov@outlook.com>
This commit is contained in:
parent
7d5358b9d3
commit
256c1a1140
@ -88,6 +88,19 @@ static void infrared_rpc_command_callback(const RpcAppSystemEvent* event, void*
|
||||
view_dispatcher_send_custom_event(
|
||||
infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonPressIndex);
|
||||
}
|
||||
} else if(event->type == RpcAppEventTypeButtonPressRelease) {
|
||||
furi_assert(
|
||||
event->data.type == RpcAppSystemEventDataTypeString ||
|
||||
event->data.type == RpcAppSystemEventDataTypeInt32);
|
||||
if(event->data.type == RpcAppSystemEventDataTypeString) {
|
||||
furi_string_set(infrared->button_name, event->data.string);
|
||||
view_dispatcher_send_custom_event(
|
||||
infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonPressReleaseName);
|
||||
} else {
|
||||
infrared->app_state.current_button_index = event->data.i32;
|
||||
view_dispatcher_send_custom_event(
|
||||
infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonPressReleaseIndex);
|
||||
}
|
||||
} else if(event->type == RpcAppEventTypeButtonRelease) {
|
||||
view_dispatcher_send_custom_event(
|
||||
infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonRelease);
|
||||
@ -411,6 +424,26 @@ void infrared_tx_stop(InfraredApp* infrared) {
|
||||
infrared->app_state.last_transmit_time = furi_get_tick();
|
||||
}
|
||||
|
||||
void infrared_tx_send_once(InfraredApp* infrared) {
|
||||
if(infrared->app_state.is_transmitting) {
|
||||
return;
|
||||
}
|
||||
|
||||
dolphin_deed(DolphinDeedIrSend);
|
||||
infrared_signal_transmit(infrared->current_signal);
|
||||
}
|
||||
|
||||
InfraredErrorCode infrared_tx_send_once_button_index(InfraredApp* infrared, size_t button_index) {
|
||||
furi_assert(button_index < infrared_remote_get_signal_count(infrared->remote));
|
||||
|
||||
InfraredErrorCode error = infrared_remote_load_signal(
|
||||
infrared->remote, infrared->current_signal, infrared->app_state.current_button_index);
|
||||
if(!INFRARED_ERROR_PRESENT(error)) {
|
||||
infrared_tx_send_once(infrared);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
void infrared_blocking_task_start(InfraredApp* infrared, FuriThreadCallback callback) {
|
||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewLoading);
|
||||
furi_thread_set_callback(infrared->task_thread, callback);
|
||||
|
@ -218,6 +218,20 @@ InfraredErrorCode infrared_tx_start_button_index(InfraredApp* infrared, size_t b
|
||||
*/
|
||||
void infrared_tx_stop(InfraredApp* infrared);
|
||||
|
||||
/**
|
||||
* @brief Transmit the currently loaded signal once.
|
||||
*
|
||||
* @param[in,out] infrared pointer to the application instance.
|
||||
*/
|
||||
void infrared_tx_send_once(InfraredApp* infrared);
|
||||
|
||||
/**
|
||||
* @brief Load the signal under the given index and transmit it once.
|
||||
*
|
||||
* @param[in,out] infrared pointer to the application instance.
|
||||
*/
|
||||
InfraredErrorCode infrared_tx_send_once_button_index(InfraredApp* infrared, size_t button_index);
|
||||
|
||||
/**
|
||||
* @brief Start a blocking task in a separate thread.
|
||||
*
|
||||
|
@ -21,6 +21,8 @@ enum InfraredCustomEventType {
|
||||
InfraredCustomEventTypeRpcButtonPressName,
|
||||
InfraredCustomEventTypeRpcButtonPressIndex,
|
||||
InfraredCustomEventTypeRpcButtonRelease,
|
||||
InfraredCustomEventTypeRpcButtonPressReleaseName,
|
||||
InfraredCustomEventTypeRpcButtonPressReleaseIndex,
|
||||
InfraredCustomEventTypeRpcSessionClose,
|
||||
|
||||
InfraredCustomEventTypeGpioTxPinChanged,
|
||||
|
@ -124,6 +124,49 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
||||
|
||||
rpc_system_app_confirm(infrared->rpc_ctx, result);
|
||||
|
||||
} else if(
|
||||
event.event == InfraredCustomEventTypeRpcButtonPressReleaseName ||
|
||||
event.event == InfraredCustomEventTypeRpcButtonPressReleaseIndex) {
|
||||
bool result = false;
|
||||
|
||||
// Send the signal once and stop
|
||||
if(rpc_state == InfraredRpcStateLoaded) {
|
||||
if(event.event == InfraredCustomEventTypeRpcButtonPressReleaseName) {
|
||||
const char* button_name = furi_string_get_cstr(infrared->button_name);
|
||||
size_t index;
|
||||
const bool index_found =
|
||||
infrared_remote_get_signal_index(infrared->remote, button_name, &index);
|
||||
app_state->current_button_index = index_found ? (signed)index :
|
||||
InfraredButtonIndexNone;
|
||||
FURI_LOG_D(TAG, "Sending signal with name \"%s\"", button_name);
|
||||
} else {
|
||||
FURI_LOG_D(
|
||||
TAG, "Sending signal with index \"%ld\"", app_state->current_button_index);
|
||||
}
|
||||
if(infrared->app_state.current_button_index != InfraredButtonIndexNone) {
|
||||
InfraredErrorCode error = infrared_tx_send_once_button_index(
|
||||
infrared, app_state->current_button_index);
|
||||
if(!INFRARED_ERROR_PRESENT(error)) {
|
||||
const char* remote_name = infrared_remote_get_name(infrared->remote);
|
||||
infrared_text_store_set(infrared, 0, "emulating\n%s", remote_name);
|
||||
|
||||
infrared_scene_rpc_show(infrared);
|
||||
result = true;
|
||||
} else {
|
||||
rpc_system_app_set_error_code(
|
||||
infrared->rpc_ctx, RpcAppSystemErrorCodeInternalParse);
|
||||
rpc_system_app_set_error_text(
|
||||
infrared->rpc_ctx, "Cannot load button data");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(result) {
|
||||
scene_manager_set_scene_state(
|
||||
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded);
|
||||
}
|
||||
rpc_system_app_confirm(infrared->rpc_ctx, result);
|
||||
} else if(
|
||||
event.event == InfraredCustomEventTypeRpcExit ||
|
||||
event.event == InfraredCustomEventTypeRpcSessionClose ||
|
||||
|
@ -49,6 +49,7 @@ typedef enum {
|
||||
SubGhzCustomEventSceneRpcLoad,
|
||||
SubGhzCustomEventSceneRpcButtonPress,
|
||||
SubGhzCustomEventSceneRpcButtonRelease,
|
||||
SubGhzCustomEventSceneRpcButtonPressRelease,
|
||||
SubGhzCustomEventSceneRpcSessionClose,
|
||||
|
||||
SubGhzCustomEventViewReceiverOK,
|
||||
|
@ -85,6 +85,43 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle);
|
||||
rpc_system_app_confirm(subghz->rpc_ctx, result);
|
||||
} else if(event.event == SubGhzCustomEventSceneRpcButtonPressRelease) {
|
||||
bool result = false;
|
||||
if(state == SubGhzRpcStateLoaded) {
|
||||
switch(
|
||||
subghz_txrx_tx_start(subghz->txrx, subghz_txrx_get_fff_data(subghz->txrx))) {
|
||||
case SubGhzTxRxStartTxStateErrorOnlyRx:
|
||||
rpc_system_app_set_error_code(
|
||||
subghz->rpc_ctx, RpcAppSystemErrorCodeRegionLock);
|
||||
rpc_system_app_set_error_text(
|
||||
subghz->rpc_ctx,
|
||||
"Transmission on this frequency is restricted in your region");
|
||||
break;
|
||||
case SubGhzTxRxStartTxStateErrorParserOthers:
|
||||
rpc_system_app_set_error_code(
|
||||
subghz->rpc_ctx, RpcAppSystemErrorCodeInternalParse);
|
||||
rpc_system_app_set_error_text(
|
||||
subghz->rpc_ctx, "Error in protocol parameters description");
|
||||
break;
|
||||
|
||||
default: //if(SubGhzTxRxStartTxStateOk)
|
||||
result = true;
|
||||
subghz_blink_start(subghz);
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateTx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop transmission
|
||||
if(state == SubGhzRpcStateTx) {
|
||||
subghz_txrx_stop(subghz->txrx);
|
||||
subghz_blink_stop(subghz);
|
||||
result = true;
|
||||
}
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle);
|
||||
rpc_system_app_confirm(subghz->rpc_ctx, result);
|
||||
} else if(event.event == SubGhzCustomEventSceneRpcLoad) {
|
||||
bool result = false;
|
||||
if(state == SubGhzRpcStateIdle) {
|
||||
|
@ -43,6 +43,9 @@ static void subghz_rpc_command_callback(const RpcAppSystemEvent* event, void* co
|
||||
} else if(event->type == RpcAppEventTypeButtonRelease) {
|
||||
view_dispatcher_send_custom_event(
|
||||
subghz->view_dispatcher, SubGhzCustomEventSceneRpcButtonRelease);
|
||||
} else if(event->type == RpcAppEventTypeButtonPressRelease) {
|
||||
view_dispatcher_send_custom_event(
|
||||
subghz->view_dispatcher, SubGhzCustomEventSceneRpcButtonPressRelease);
|
||||
} else {
|
||||
rpc_system_app_confirm(subghz->rpc_ctx, false);
|
||||
}
|
||||
|
@ -258,6 +258,41 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context)
|
||||
}
|
||||
}
|
||||
|
||||
static void rpc_system_app_button_press_release(const PB_Main* request, void* context) {
|
||||
furi_assert(request);
|
||||
furi_assert(request->which_content == PB_Main_app_button_press_release_request_tag);
|
||||
|
||||
RpcAppSystem* rpc_app = context;
|
||||
furi_assert(rpc_app);
|
||||
|
||||
if(rpc_app->callback) {
|
||||
FURI_LOG_D(TAG, "ButtonPressRelease");
|
||||
|
||||
RpcAppSystemEvent event;
|
||||
event.type = RpcAppEventTypeButtonPressRelease;
|
||||
|
||||
if(strlen(request->content.app_button_press_release_request.args) != 0) {
|
||||
event.data.type = RpcAppSystemEventDataTypeString;
|
||||
event.data.string = request->content.app_button_press_release_request.args;
|
||||
} else {
|
||||
event.data.type = RpcAppSystemEventDataTypeInt32;
|
||||
event.data.i32 = request->content.app_button_press_release_request.index;
|
||||
}
|
||||
|
||||
rpc_system_app_error_reset(rpc_app);
|
||||
rpc_system_app_set_last_command(rpc_app, request->command_id, &event);
|
||||
|
||||
rpc_app->callback(&event, rpc_app->callback_context);
|
||||
|
||||
} else {
|
||||
rpc_system_app_send_error_response(
|
||||
rpc_app,
|
||||
request->command_id,
|
||||
PB_CommandStatus_ERROR_APP_NOT_RUNNING,
|
||||
"ButtonPressRelease");
|
||||
}
|
||||
}
|
||||
|
||||
static void rpc_system_app_get_error_process(const PB_Main* request, void* context) {
|
||||
furi_assert(request);
|
||||
furi_assert(request->which_content == PB_Main_app_get_error_request_tag);
|
||||
@ -332,6 +367,7 @@ void rpc_system_app_confirm(RpcAppSystem* rpc_app, bool result) {
|
||||
rpc_app->last_event_type == RpcAppEventTypeLoadFile ||
|
||||
rpc_app->last_event_type == RpcAppEventTypeButtonPress ||
|
||||
rpc_app->last_event_type == RpcAppEventTypeButtonRelease ||
|
||||
rpc_app->last_event_type == RpcAppEventTypeButtonPressRelease ||
|
||||
rpc_app->last_event_type == RpcAppEventTypeDataExchange);
|
||||
|
||||
const uint32_t last_command_id = rpc_app->last_command_id;
|
||||
@ -432,6 +468,9 @@ void* rpc_system_app_alloc(RpcSession* session) {
|
||||
rpc_handler.message_handler = rpc_system_app_button_release;
|
||||
rpc_add_handler(session, PB_Main_app_button_release_request_tag, &rpc_handler);
|
||||
|
||||
rpc_handler.message_handler = rpc_system_app_button_press_release;
|
||||
rpc_add_handler(session, PB_Main_app_button_press_release_request_tag, &rpc_handler);
|
||||
|
||||
rpc_handler.message_handler = rpc_system_app_get_error_process;
|
||||
rpc_add_handler(session, PB_Main_app_get_error_request_tag, &rpc_handler);
|
||||
|
||||
|
@ -90,6 +90,13 @@ typedef enum {
|
||||
* all activities to be conducted while a button is being pressed.
|
||||
*/
|
||||
RpcAppEventTypeButtonRelease,
|
||||
/**
|
||||
* @brief The client has informed the application that a button has been pressed and released.
|
||||
*
|
||||
* This command's meaning is application-specific, e.g. to perform an action
|
||||
* once without repeating it.
|
||||
*/
|
||||
RpcAppEventTypeButtonPressRelease,
|
||||
/**
|
||||
* @brief The client has sent a byte array of arbitrary size.
|
||||
*
|
||||
@ -162,6 +169,7 @@ void rpc_system_app_send_exited(RpcAppSystem* rpc_app);
|
||||
* - RpcAppEventTypeLoadFile
|
||||
* - RpcAppEventTypeButtonPress
|
||||
* - RpcAppEventTypeButtonRelease
|
||||
* - RpcAppEventTypeButtonPressRelease
|
||||
* - RpcAppEventTypeDataExchange
|
||||
*
|
||||
* Not confirming these events will result in a client-side timeout.
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 6c7c0d55e82cb89223cf4890a540af4cff837fa7
|
||||
Subproject commit 1c84fa48919cbb71d1cc65236fc0ee36740e24c6
|
Loading…
Reference in New Issue
Block a user