xremote_scene_transmit.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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_transmit_callback(XRemoteCustomEvent event, void* context) {
  20. furi_assert(context);
  21. XRemote* app = context;
  22. view_dispatcher_send_custom_event(app->view_dispatcher, event);
  23. }
  24. void xremote_scene_ir_notification_message(XRemote* app, uint32_t message) {
  25. if(app->led == 1) {
  26. notification_message(app->notification, xremote_notification_sequences[message]);
  27. }
  28. }
  29. bool xremote_scene_ir_signal_is_raw(InfraredSignal* signal) {
  30. if(signal->is_raw) {
  31. return true;
  32. }
  33. return false;
  34. }
  35. void xremote_scene_transmit_stop_ir_signal(XRemote* app) {
  36. if(!app->transmitting) {
  37. return;
  38. }
  39. app->transmitting = false;
  40. infrared_worker_tx_stop(app->ir_worker);
  41. infrared_worker_tx_set_get_signal_callback(app->ir_worker, NULL, NULL);
  42. xremote_scene_ir_notification_message(app, InfraredNotificationMessageBlinkStop);
  43. }
  44. void xremote_scene_transmit_send_ir_signal(XRemote* app, CrossRemoteItem* item) {
  45. InfraredSignal* signal = xremote_cross_remote_item_get_ir_signal(item);
  46. dolphin_deed(DolphinDeedIrSend);
  47. xremote_scene_ir_notification_message(app, InfraredNotificationMessageBlinkStartSend);
  48. if(xremote_scene_ir_signal_is_raw(signal)) {
  49. InfraredRawSignal* raw = xremote_ir_signal_get_raw_signal(signal);
  50. infrared_worker_set_raw_signal(
  51. app->ir_worker, raw->timings, raw->timings_size, raw->frequency, raw->duty_cycle);
  52. } else {
  53. InfraredMessage* message = xremote_ir_signal_get_message(signal);
  54. infrared_worker_set_decoded_signal(app->ir_worker, message);
  55. }
  56. infrared_worker_tx_set_get_signal_callback(
  57. app->ir_worker, infrared_worker_tx_get_signal_steady_callback, app);
  58. infrared_worker_tx_start(app->ir_worker);
  59. app->transmitting = true;
  60. uint32_t time = app->ir_timing;
  61. if(item->time > 0) {
  62. time = item->time;
  63. }
  64. furi_thread_flags_wait(0, FuriFlagWaitAny, time);
  65. xremote_scene_transmit_stop_ir_signal(app);
  66. }
  67. void xremote_scene_transmit_send_pause(XRemote* app, CrossRemoteItem* item) {
  68. app->transmitting = true;
  69. xremote_scene_ir_notification_message(app, PauseNotificationMessageBlinkStartSend);
  70. furi_thread_flags_wait(0, FuriFlagWaitAny, item->time * 1000);
  71. app->transmitting = false;
  72. xremote_scene_ir_notification_message(app, PauseNotificationMessageBlinkStop);
  73. }
  74. void xremote_scene_transmit_send_subghz(XRemote* app, CrossRemoteItem* item) {
  75. app->transmitting = true;
  76. xremote_scene_ir_notification_message(app, SubGhzNotificationMessageBlinkStartSend);
  77. if(furi_string_utf8_length(item->filename) < 3) {
  78. xremote_cross_remote_set_transmitting(app->cross_remote, XRemoteTransmittingStop);
  79. app->transmitting = false;
  80. return;
  81. }
  82. subghz_send(app, furi_string_get_cstr(item->filename));
  83. //furi_thread_flags_wait(0, FuriFlagWaitAny, 2000);
  84. }
  85. void xremote_scene_transmit_send_signal(void* context, CrossRemoteItem* item) {
  86. furi_assert(context);
  87. XRemote* app = context;
  88. CrossRemote* remote = app->cross_remote;
  89. if(app->transmitting) {
  90. return;
  91. }
  92. xremote_transmit_model_set_name(
  93. app->xremote_transmit, xremote_cross_remote_item_get_name(item));
  94. xremote_transmit_model_set_type(app->xremote_transmit, item->type);
  95. if(item->type == XRemoteRemoteItemTypeInfrared) {
  96. xremote_scene_transmit_send_ir_signal(app, item);
  97. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStop);
  98. } else if(item->type == XRemoteRemoteItemTypePause) {
  99. xremote_scene_transmit_send_pause(app, item);
  100. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStop);
  101. } else if(item->type == XRemoteRemoteItemTypeSubGhz) {
  102. xremote_scene_transmit_send_subghz(app, item);
  103. }
  104. }
  105. void xremote_scene_transmit_run_remote_inner(void* context) {
  106. furi_assert(context);
  107. XRemote* app = context;
  108. CrossRemote* remote = app->cross_remote;
  109. size_t item_count = xremote_cross_remote_get_item_count(remote);
  110. for(size_t i = 0; i < item_count;) {
  111. if(xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingIdle) {
  112. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStart);
  113. CrossRemoteItem* item = xremote_cross_remote_get_item(remote, i);
  114. xremote_scene_transmit_send_signal(app, item);
  115. //furi_thread_flags_wait(0, FuriFlagWaitAny, 1000);
  116. } else if(xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStopSubghz) {
  117. i++;
  118. app->state_notifications = SubGhzNotificationStateIDLE;
  119. app->transmitting = false;
  120. subghz_txrx_stop(app->subghz->txrx);
  121. xremote_scene_ir_notification_message(app, SubGhzNotificationMessageBlinkStop);
  122. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  123. //furi_thread_flags_wait(0, FuriFlagWaitAny, 1000);
  124. } else if(xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStop) {
  125. i++;
  126. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  127. }
  128. }
  129. xremote_scene_ir_notification_message(app, InfraredNotificationMessageBlinkStop);
  130. scene_manager_previous_scene(app->scene_manager);
  131. //xremote_transmit_model_set_name(app->xremote_transmit, xremote_cross_remote_get_name(remote));
  132. }
  133. void xremote_scene_transmit_run_remote(void* context) {
  134. furi_assert(context);
  135. XRemote* app = context;
  136. CrossRemote* remote = app->cross_remote;
  137. size_t item_count = xremote_cross_remote_get_item_count(remote);
  138. if (app->loopir) {
  139. while (true) {
  140. for (size_t i = 0; i < item_count;) {
  141. if (xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingIdle) {
  142. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStart);
  143. CrossRemoteItem* item = xremote_cross_remote_get_item(remote, i);
  144. xremote_scene_transmit_send_signal(app, item);
  145. } else if (xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStopSubghz) {
  146. i++;
  147. app->state_notifications = SubGhzNotificationStateIDLE;
  148. app->transmitting = false;
  149. subghz_txrx_stop(app->subghz->txrx);
  150. xremote_scene_ir_notification_message(app, SubGhzNotificationMessageBlinkStop);
  151. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  152. } else if (xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStop) {
  153. i++;
  154. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  155. }
  156. }
  157. }
  158. } else {
  159. for (size_t i = 0; i < item_count;) {
  160. if (xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingIdle) {
  161. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingStart);
  162. CrossRemoteItem* item = xremote_cross_remote_get_item(remote, i);
  163. xremote_scene_transmit_send_signal(app, item);
  164. } else if (xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStopSubghz) {
  165. i++;
  166. app->state_notifications = SubGhzNotificationStateIDLE;
  167. app->transmitting = false;
  168. subghz_txrx_stop(app->subghz->txrx);
  169. xremote_scene_ir_notification_message(app, SubGhzNotificationMessageBlinkStop);
  170. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  171. } else if (xremote_cross_remote_get_transmitting(remote) == XRemoteTransmittingStop) {
  172. i++;
  173. xremote_cross_remote_set_transmitting(remote, XRemoteTransmittingIdle);
  174. }
  175. }
  176. }
  177. xremote_scene_ir_notification_message(app, InfraredNotificationMessageBlinkStop);
  178. scene_manager_previous_scene(app->scene_manager);
  179. }
  180. void xremote_scene_transmit_on_enter(void* context) {
  181. furi_assert(context);
  182. XRemote* app = context;
  183. xremote_transmit_set_callback(app->xremote_transmit, xremote_transmit_callback, app);
  184. view_dispatcher_switch_to_view(app->view_dispatcher, XRemoteViewIdTransmit);
  185. xremote_scene_transmit_run_remote(app);
  186. }
  187. bool xremote_scene_transmit_on_event(void* context, SceneManagerEvent event) {
  188. XRemote* app = context;
  189. bool consumed = false;
  190. if(event.type == SceneManagerEventTypeCustom) {
  191. FURI_LOG_D(TAG, "Custom Event");
  192. switch(event.event) {
  193. case XRemoteCustomEventViewTransmitterSendStop:
  194. FURI_LOG_D("SUBGHZ", "stop event"); // doesn't trigger
  195. break;
  196. default:
  197. break;
  198. }
  199. } else if(event.type == SceneManagerEventTypeTick) {
  200. FURI_LOG_D(TAG, "Tick Event");
  201. with_view_model(
  202. xremote_transmit_get_view(app->xremote_transmit),
  203. void* model,
  204. { UNUSED(model); },
  205. true);
  206. if(app->state_notifications == SubGhzNotificationStateTx && app->led == 1) {
  207. //blink for subghz
  208. }
  209. }
  210. return consumed;
  211. }
  212. void xremote_scene_transmit_on_exit(void* context) {
  213. XRemote* app = context;
  214. app->transmitting = false;
  215. app->state_notifications = SubGhzNotificationStateIDLE;
  216. }