weather_station_receiver_info.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "weather_station_receiver.h"
  2. #include "../weather_station_app_i.h"
  3. #include "weather_station_icons.h"
  4. #include "../protocols/ws_generic.h"
  5. #include <input/input.h>
  6. #include <gui/elements.h>
  7. #define abs(x) ((x) > 0 ? (x) : -(x))
  8. struct WSReceiverInfo {
  9. View* view;
  10. };
  11. typedef struct {
  12. FuriString* protocol_name;
  13. WSBlockGeneric* generic;
  14. } WSReceiverInfoModel;
  15. void ws_view_receiver_info_update(WSReceiverInfo* ws_receiver_info, FlipperFormat* fff) {
  16. furi_assert(ws_receiver_info);
  17. furi_assert(fff);
  18. with_view_model(
  19. ws_receiver_info->view,
  20. WSReceiverInfoModel * model,
  21. {
  22. flipper_format_rewind(fff);
  23. flipper_format_read_string(fff, "Protocol", model->protocol_name);
  24. ws_block_generic_deserialize(model->generic, fff);
  25. },
  26. true);
  27. }
  28. void ws_view_receiver_info_draw(Canvas* canvas, WSReceiverInfoModel* model) {
  29. char buffer[64];
  30. canvas_clear(canvas);
  31. canvas_set_color(canvas, ColorBlack);
  32. canvas_set_font(canvas, FontSecondary);
  33. snprintf(
  34. buffer,
  35. sizeof(buffer),
  36. "%s %db",
  37. furi_string_get_cstr(model->protocol_name),
  38. model->generic->data_count_bit);
  39. canvas_draw_str(canvas, 5, 8, buffer);
  40. if(model->generic->channel != WS_NO_CHANNEL) {
  41. snprintf(buffer, sizeof(buffer), "Ch: %01d", model->generic->channel);
  42. canvas_draw_str(canvas, 105, 8, buffer);
  43. }
  44. if(model->generic->id != WS_NO_ID) {
  45. snprintf(buffer, sizeof(buffer), "Sn: 0x%02lX", model->generic->id);
  46. canvas_draw_str(canvas, 5, 20, buffer);
  47. }
  48. if(model->generic->btn != WS_NO_BTN) {
  49. snprintf(buffer, sizeof(buffer), "Btn: %01d", model->generic->btn);
  50. canvas_draw_str(canvas, 62, 20, buffer);
  51. }
  52. if(model->generic->battery_low != WS_NO_BATT) {
  53. snprintf(
  54. buffer, sizeof(buffer), "Batt: %s", (!model->generic->battery_low ? "ok" : "low"));
  55. canvas_draw_str(canvas, 90, 20, buffer);
  56. }
  57. snprintf(buffer, sizeof(buffer), "Data: 0x%llX", model->generic->data);
  58. canvas_draw_str(canvas, 5, 32, buffer);
  59. elements_bold_rounded_frame(canvas, 2, 37, 123, 25);
  60. canvas_set_font(canvas, FontPrimary);
  61. if(model->generic->temp != WS_NO_TEMPERATURE) {
  62. canvas_draw_icon(canvas, 18, 42, &I_Therm_7x16);
  63. snprintf(buffer, sizeof(buffer), "%3.1f C", (double)model->generic->temp);
  64. canvas_draw_str_aligned(canvas, 63, 46, AlignRight, AlignTop, buffer);
  65. canvas_draw_circle(canvas, 55, 45, 1);
  66. }
  67. if(model->generic->humidity != WS_NO_HUMIDITY) {
  68. canvas_draw_icon(canvas, 75, 42, &I_Humid_10x15);
  69. snprintf(buffer, sizeof(buffer), "%d%%", model->generic->humidity);
  70. canvas_draw_str(canvas, 91, 54, buffer);
  71. }
  72. }
  73. bool ws_view_receiver_info_input(InputEvent* event, void* context) {
  74. furi_assert(context);
  75. //WSReceiverInfo* ws_receiver_info = context;
  76. if(event->key == InputKeyBack) {
  77. return false;
  78. }
  79. return true;
  80. }
  81. void ws_view_receiver_info_enter(void* context) {
  82. furi_assert(context);
  83. }
  84. void ws_view_receiver_info_exit(void* context) {
  85. furi_assert(context);
  86. WSReceiverInfo* ws_receiver_info = context;
  87. with_view_model(
  88. ws_receiver_info->view,
  89. WSReceiverInfoModel * model,
  90. { furi_string_reset(model->protocol_name); },
  91. false);
  92. }
  93. WSReceiverInfo* ws_view_receiver_info_alloc() {
  94. WSReceiverInfo* ws_receiver_info = malloc(sizeof(WSReceiverInfo));
  95. // View allocation and configuration
  96. ws_receiver_info->view = view_alloc();
  97. view_allocate_model(ws_receiver_info->view, ViewModelTypeLocking, sizeof(WSReceiverInfoModel));
  98. view_set_context(ws_receiver_info->view, ws_receiver_info);
  99. view_set_draw_callback(ws_receiver_info->view, (ViewDrawCallback)ws_view_receiver_info_draw);
  100. view_set_input_callback(ws_receiver_info->view, ws_view_receiver_info_input);
  101. view_set_enter_callback(ws_receiver_info->view, ws_view_receiver_info_enter);
  102. view_set_exit_callback(ws_receiver_info->view, ws_view_receiver_info_exit);
  103. with_view_model(
  104. ws_receiver_info->view,
  105. WSReceiverInfoModel * model,
  106. {
  107. model->generic = malloc(sizeof(WSBlockGeneric));
  108. model->protocol_name = furi_string_alloc();
  109. },
  110. true);
  111. return ws_receiver_info;
  112. }
  113. void ws_view_receiver_info_free(WSReceiverInfo* ws_receiver_info) {
  114. furi_assert(ws_receiver_info);
  115. with_view_model(
  116. ws_receiver_info->view,
  117. WSReceiverInfoModel * model,
  118. {
  119. furi_string_free(model->protocol_name);
  120. free(model->generic);
  121. },
  122. false);
  123. view_free(ws_receiver_info->view);
  124. free(ws_receiver_info);
  125. }
  126. View* ws_view_receiver_info_get_view(WSReceiverInfo* ws_receiver_info) {
  127. furi_assert(ws_receiver_info);
  128. return ws_receiver_info->view;
  129. }