pc_monitor.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "pc_monitor.h"
  2. static void render_callback(Canvas* canvas, void* ctx) {
  3. furi_assert(ctx);
  4. PcMonitorApp* app = ctx;
  5. if(app->bt_state == BtStateRecieving) {
  6. canvas_clear(canvas);
  7. canvas_set_color(canvas, ColorBlack);
  8. canvas_set_font(canvas, FontKeyboard);
  9. uint8_t line = 0;
  10. char str[32];
  11. if (app->data.cpu_usage <= 100) {
  12. canvas_draw_str(canvas, 0, 10, "CPU");
  13. snprintf(str, 32, "%d%%", app->data.cpu_usage);
  14. elements_progress_bar_with_text(canvas, BAR_X, 1, BAR_WIDTH, app->data.cpu_usage / 100.0f, str);
  15. line++;
  16. }
  17. if (app->data.ram_usage <= 100) {
  18. canvas_draw_str(canvas, 0, 10 + BAR_MARGIN * line, "RAM");
  19. snprintf(
  20. str,
  21. 32,
  22. "%.1f/%.1f %s",
  23. (double)(app->data.ram_max * 0.1f * app->data.ram_usage * 0.01f),
  24. (double)(app->data.ram_max * 0.1f),
  25. app->data.ram_unit);
  26. elements_progress_bar_with_text(
  27. canvas, BAR_X, 1 + BAR_MARGIN * line, BAR_WIDTH, app->data.ram_usage * 0.01f, str);
  28. line++;
  29. }
  30. if (app->data.gpu_usage <= 100) {
  31. canvas_draw_str(canvas, 0, 10 + BAR_MARGIN * line, "GPU");
  32. snprintf(str, 32, "%d%%", app->data.gpu_usage);
  33. elements_progress_bar_with_text(
  34. canvas, BAR_X, 1 + BAR_MARGIN * line, BAR_WIDTH, app->data.gpu_usage / 100.0f, str);
  35. line++;
  36. }
  37. if (app->data.vram_usage <= 100) {
  38. canvas_draw_str(canvas, 0, 10 + BAR_MARGIN * line, "VRAM");
  39. snprintf(
  40. str,
  41. 32,
  42. "%.1f/%.1f %s",
  43. (double)(app->data.vram_max * 0.1f * app->data.vram_usage * 0.01f),
  44. (double)(app->data.vram_max * 0.1f),
  45. app->data.vram_unit);
  46. elements_progress_bar_with_text(
  47. canvas, BAR_X, 1 + BAR_MARGIN * line, BAR_WIDTH, app->data.vram_usage * 0.01f, str);
  48. line++;
  49. }
  50. } else {
  51. canvas_draw_str_aligned(
  52. canvas,
  53. 64,
  54. 32,
  55. AlignCenter,
  56. AlignCenter,
  57. app->bt_state == BtStateChecking ? "Checking BLE..." :
  58. app->bt_state == BtStateInactive ? "BLE inactive!" :
  59. app->bt_state == BtStateWaiting ? "Waiting for data..." :
  60. "Connection lost!");
  61. }
  62. }
  63. static void input_callback(InputEvent* input_event, void* ctx) {
  64. furi_assert(ctx);
  65. FuriMessageQueue* event_queue = ctx;
  66. furi_message_queue_put(event_queue, input_event, FuriWaitForever);
  67. }
  68. static uint16_t bt_serial_callback(SerialServiceEvent event, void* ctx) {
  69. furi_assert(ctx);
  70. PcMonitorApp* app = ctx;
  71. if(event.event == SerialServiceEventTypeDataReceived) {
  72. FURI_LOG_D(
  73. TAG,
  74. "SerialServiceEventTypeDataReceived. Size: %u/%u. Data: %s",
  75. event.data.size,
  76. sizeof(DataStruct),
  77. (char*)event.data.buffer);
  78. if(event.data.size == sizeof(DataStruct)) {
  79. memcpy(&app->data, event.data.buffer, sizeof(DataStruct));
  80. app->bt_state = BtStateRecieving;
  81. app->last_packet = furi_hal_rtc_get_timestamp();
  82. }
  83. }
  84. return 0;
  85. }
  86. static PcMonitorApp* pc_monitor_alloc() {
  87. PcMonitorApp* app = malloc(sizeof(PcMonitorApp));
  88. app->view_port = view_port_alloc();
  89. app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
  90. app->notification = furi_record_open(RECORD_NOTIFICATION);
  91. app->gui = furi_record_open(RECORD_GUI);
  92. app->bt = furi_record_open(RECORD_BT);
  93. app->data.cpu_usage = UINT8_MAX;
  94. app->data.ram_usage = UINT8_MAX;
  95. app->data.gpu_usage = UINT8_MAX;
  96. app->data.vram_usage = UINT8_MAX;
  97. gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);
  98. view_port_draw_callback_set(app->view_port, render_callback, app);
  99. view_port_input_callback_set(app->view_port, input_callback, app->event_queue);
  100. return app;
  101. }
  102. static void pc_monitor_free(PcMonitorApp* app) {
  103. gui_remove_view_port(app->gui, app->view_port);
  104. view_port_free(app->view_port);
  105. furi_message_queue_free(app->event_queue);
  106. furi_record_close(RECORD_NOTIFICATION);
  107. furi_record_close(RECORD_GUI);
  108. furi_record_close(RECORD_BT);
  109. free(app);
  110. }
  111. int32_t pc_monitor_app(void* p) {
  112. UNUSED(p);
  113. PcMonitorApp* app = pc_monitor_alloc();
  114. if(furi_hal_bt_is_active()) {
  115. furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_callback, app);
  116. furi_hal_bt_start_advertising();
  117. app->bt_state = BtStateWaiting;
  118. FURI_LOG_D(TAG, "Bluetooth is active!");
  119. } else {
  120. app->bt_state = BtStateInactive;
  121. FURI_LOG_W(TAG, "Please, enable the Bluetooth and restart the app");
  122. }
  123. // Main loop
  124. InputEvent event;
  125. while(true) {
  126. if (furi_message_queue_get(app->event_queue, &event, 1) == FuriStatusOk) {
  127. if(event.type == InputTypeShort && event.key == InputKeyBack) break;
  128. }
  129. if(app->bt_state == BtStateRecieving && (furi_hal_rtc_get_timestamp() - app->last_packet > 5)) app->bt_state = BtStateLost;
  130. }
  131. furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
  132. pc_monitor_free(app);
  133. return 0;
  134. }