pc_monitor.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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 != UINT8_MAX) {
  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 != UINT8_MAX) {
  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 != UINT8_MAX) {
  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 != UINT8_MAX) {
  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. }
  82. }
  83. return 0;
  84. }
  85. static PcMonitorApp* pc_monitor_alloc() {
  86. PcMonitorApp* app = malloc(sizeof(PcMonitorApp));
  87. app->view_port = view_port_alloc();
  88. app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
  89. app->notification = furi_record_open(RECORD_NOTIFICATION);
  90. app->gui = furi_record_open(RECORD_GUI);
  91. app->bt = furi_record_open(RECORD_BT);
  92. app->data.cpu_usage = UINT8_MAX;
  93. app->data.ram_usage = UINT8_MAX;
  94. app->data.gpu_usage = UINT8_MAX;
  95. app->data.vram_usage = UINT8_MAX;
  96. gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen);
  97. view_port_draw_callback_set(app->view_port, render_callback, app);
  98. view_port_input_callback_set(app->view_port, input_callback, app->event_queue);
  99. return app;
  100. }
  101. static void pc_monitor_free(PcMonitorApp* app) {
  102. gui_remove_view_port(app->gui, app->view_port);
  103. view_port_free(app->view_port);
  104. furi_message_queue_free(app->event_queue);
  105. furi_record_close(RECORD_NOTIFICATION);
  106. furi_record_close(RECORD_GUI);
  107. furi_record_close(RECORD_BT);
  108. free(app);
  109. }
  110. int32_t pc_monitor_app(void* p) {
  111. UNUSED(p);
  112. PcMonitorApp* app = pc_monitor_alloc();
  113. if(furi_hal_bt_is_active()) {
  114. furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_callback, app);
  115. furi_hal_bt_start_advertising();
  116. app->bt_state = BtStateWaiting;
  117. FURI_LOG_D(TAG, "Bluetooth is active!");
  118. } else {
  119. app->bt_state = BtStateInactive;
  120. FURI_LOG_W(TAG, "Please, enable the Bluetooth and restart the app");
  121. }
  122. InputEvent event;
  123. while(furi_message_queue_get(app->event_queue, &event, FuriWaitForever) == FuriStatusOk) {
  124. if(event.type == InputTypeShort && event.key == InputKeyBack) break;
  125. }
  126. furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
  127. pc_monitor_free(app);
  128. return 0;
  129. }