xremote_scene_transmit.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "../xremote.h"
  2. #include "../views/xremote_transmit.h"
  3. #include "../models/infrared/xremote_ir_signal.h"
  4. #include "../helpers/subghz/subghz.h"
  5. static const NotificationSequence* xremote_notification_sequences[] = {
  6. &sequence_success,
  7. &sequence_set_only_green_255,
  8. &sequence_reset_green,
  9. &sequence_solid_yellow,
  10. &sequence_reset_rgb,
  11. &sequence_blink_start_cyan,
  12. &sequence_blink_start_magenta,
  13. &sequence_blink_stop,
  14. &sequence_blink_start_yellow,
  15. &sequence_blink_stop,
  16. &sequence_blink_start_blue,
  17. &sequence_blink_stop,
  18. };
  19. void xremote_scene_transmit_callback(XRemoteCustomEvent event, void* context) {
  20. furi_assert(context);
  21. XRemote* app = context;
  22. FURI_LOG_D(TAG, "trigger xremote_transmit_callback");
  23. view_dispatcher_send_custom_event(app->view_dispatcher, event);
  24. }
  25. void xremote_scene_ir_notification_message(XRemote* app, uint32_t message) {
  26. if(app->led == 1) {
  27. notification_message(app->notification, xremote_notification_sequences[message]);
  28. }
  29. }
  30. bool xremote_scene_ir_signal_is_raw(InfraredSignal* signal) {
  31. if(signal->is_raw) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. void xremote_scene_transmit_stop_ir_signal(XRemote* app) {
  37. if(!app->transmitting) {
  38. return;
  39. }
  40. app->transmitting = false;
  41. infrared_worker_tx_stop(app->ir_worker);
  42. infrared_worker_tx_set_get_signal_callback(app->ir_worker, NULL, NULL);
  43. xremote_scene_ir_notification_message(app, InfraredNotificationMessageBlinkStop);
  44. }
  45. void xremote_scene_transmit_send_ir_signal(XRemote* app, CrossRemoteItem* item) {
  46. InfraredSignal* signal = xremote_cross_remote_item_get_ir_signal(item);
  47. dolphin_deed(DolphinDeedIrSend);
  48. xremote_scene_ir_notification_message(app, InfraredNotificationMessageBlinkStartSend);
  49. if(xremote_scene_ir_signal_is_raw(signal)) {
  50. InfraredRawSignal* raw = xremote_ir_signal_get_raw_signal(signal);
  51. infrared_worker_set_raw_signal(
  52. app->ir_worker, raw->timings, raw->timings_size, raw->frequency, raw->duty_cycle);
  53. } else {
  54. InfraredMessage* message = xremote_ir_signal_get_message(signal);
  55. infrared_worker_set_decoded_signal(app->ir_worker, message);
  56. }
  57. infrared_worker_tx_set_get_signal_callback(
  58. app->ir_worker, infrared_worker_tx_get_signal_steady_callback, app);
  59. infrared_worker_tx_start(app->ir_worker);
  60. app->transmitting = true;
  61. uint32_t time = app->ir_timing;
  62. if(item->time > 0) {
  63. time = item->time;
  64. }
  65. furi_thread_flags_wait(0, FuriFlagWaitAny, time);
  66. xremote_scene_transmit_stop_ir_signal(app);
  67. }
  68. void xremote_scene_transmit_send_pause(XRemote* app, CrossRemoteItem* item) {
  69. app->transmitting = true;
  70. xremote_scene_ir_notification_message(app, PauseNotificationMessageBlinkStartSend);
  71. furi_thread_flags_wait(0, FuriFlagWaitAny, item->time * 1000);
  72. app->transmitting = false;
  73. xremote_scene_ir_notification_message(app, PauseNotificationMessageBlinkStop);
  74. }
  75. void xremote_scene_transmit_send_subghz(XRemote* app, CrossRemoteItem* item) {
  76. app->transmitting = true;
  77. xremote_scene_ir_notification_message(app, SubGhzNotificationMessageBlinkStartSend);
  78. if(furi_string_utf8_length(item->filename) < 3) {
  79. xremote_cross_remote_set_transmitting(app->cross_remote, XRemoteTransmittingStop);
  80. app->transmitting = false;
  81. return;
  82. }
  83. subghz_send(app, furi_string_get_cstr(item->filename));
  84. //furi_thread_flags_wait(0, FuriFlagWaitAny, 2000);
  85. }
  86. void xremote_scene_transmit_send_signal(void* context, CrossRemoteItem* item) {
  87. furi_assert(context);
  88. XRemote* app = context;
  89. CrossRemote* remote = app->cross_remote;
  90. if(app->transmitting) {
  91. return;
  92. }
  93. xremote_transmit_model_set_name(
  94. app->xremote_transmit, xremote_cross_remote_item_get_name(item));
  95. xremote_transmit_model_set_type(app->xremote_transmit, item->type);
  96. if(item->type == XRemoteRemoteItemTypeInfrared) {
  97. xremote_scene_transmit_send_ir_signal(app, item);
  98. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStop);
  99. } else if(item->type == XRemoteRemoteItemTypePause) {
  100. xremote_scene_transmit_send_pause(app, item);
  101. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStop);
  102. } else if(item->type == XRemoteRemoteItemTypeSubGhz) {
  103. xremote_scene_transmit_send_subghz(app, item);
  104. }
  105. }
  106. static void xremote_scene_transmit_end_scene(XRemote* app) {
  107. xremote_scene_ir_notification_message(app, InfraredNotificationMessageBlinkStop);
  108. if (app->loadFavorite) {
  109. scene_manager_stop(app->scene_manager);
  110. view_dispatcher_stop(app->view_dispatcher);
  111. } else {
  112. scene_manager_previous_scene(app->scene_manager);
  113. }
  114. }
  115. static void xremote_scene_transmit_run_single_transmit(XRemote* app) {
  116. CrossRemote* remote = app->cross_remote;
  117. if(xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingIdle) {
  118. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStart);
  119. CrossRemoteItem* item = xremote_cross_remote_get_item(remote, app->transmit_item);
  120. xremote_scene_transmit_send_signal(app, item);
  121. } else if(xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStopSubghz) {
  122. app->transmit_item++;
  123. app->state_notifications = SubGhzNotificationStateIDLE;
  124. app->transmitting = false;
  125. subghz_txrx_stop(app->subghz->txrx);
  126. xremote_scene_ir_notification_message(app, SubGhzNotificationMessageBlinkStop);
  127. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  128. } else if(xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStop) {
  129. app->transmit_item++;
  130. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  131. }
  132. }
  133. static void xremote_scene_transmit_run_next_transmission(XRemote* app) {
  134. CrossRemote* remote = app->cross_remote;
  135. size_t item_count = xremote_cross_remote_get_item_count(remote);
  136. if(app->transmit_item < item_count) {
  137. xremote_scene_transmit_run_single_transmit(app);
  138. return;
  139. }
  140. if(app->loop_transmit && !app->stop_transmit) {
  141. app->transmit_item = 0;
  142. return;
  143. }
  144. xremote_scene_transmit_end_scene(app);
  145. }
  146. void xremote_scene_transmit_on_enter(void* context) {
  147. furi_assert(context);
  148. XRemote* app = context;
  149. app->transmit_item = 0;
  150. xremote_transmit_set_callback(app->xremote_transmit, xremote_scene_transmit_callback, app);
  151. view_dispatcher_switch_to_view(app->view_dispatcher, XRemoteViewIdTransmit);
  152. }
  153. bool xremote_scene_transmit_on_event(void* context, SceneManagerEvent event) {
  154. XRemote* app = context;
  155. bool consumed = false;
  156. if(event.type == SceneManagerEventTypeCustom) {
  157. FURI_LOG_D(TAG, "Custom Event");
  158. switch(event.event) {
  159. case XRemoteCustomEventViewTransmitterSendStop:
  160. app->stop_transmit = true;
  161. break;
  162. default:
  163. break;
  164. }
  165. } else if(event.type == SceneManagerEventTypeTick) {
  166. FURI_LOG_D(TAG, "Tick Event");
  167. xremote_scene_transmit_run_next_transmission(app);
  168. with_view_model(
  169. xremote_transmit_get_view(app->xremote_transmit),
  170. void* model,
  171. { UNUSED(model); },
  172. true);
  173. if(app->state_notifications == SubGhzNotificationStateTx && app->led == 1) {
  174. //blink for subghz
  175. }
  176. if(app->stop_transmit == true) {
  177. app->stop_transmit = false;
  178. xremote_scene_transmit_end_scene(app);
  179. }
  180. }
  181. return consumed;
  182. }
  183. void xremote_scene_transmit_on_exit(void* context) {
  184. XRemote* app = context;
  185. app->transmitting = false;
  186. app->state_notifications = SubGhzNotificationStateIDLE;
  187. }