pc_monitor.c 5.5 KB

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