Просмотр исходного кода

Fixed incorrect loading of a large number of sensors. Added restriction on adding sensors if the interface is not available

Victor 3 лет назад
Родитель
Сommit
494edf920b

+ 19 - 4
Sensors.c

@@ -162,6 +162,18 @@ void unitemp_gpio_unlock(const GPIO* gpio) {
 
 const GPIO*
     unitemp_gpio_getAviablePort(const Interface* interface, uint8_t index, const GPIO* extraport) {
+    //Проверка для I2C
+    if(interface == &I2C) {
+        if((gpio_interfaces_list[10] == NULL || gpio_interfaces_list[10] == &I2C) &&
+           (gpio_interfaces_list[11] == NULL || gpio_interfaces_list[11] == &I2C)) {
+            //Возврат истины
+            return unitemp_gpio_getFromIndex(0);
+        } else {
+            //Возврат лжи
+            return NULL;
+        }
+    }
+
     uint8_t aviable_index = 0;
     for(uint8_t i = 0; i < GPIO_ITEMS; i++) {
         //Проверка для one wire
@@ -188,6 +200,7 @@ const GPIO*
             }
         }
     }
+
     return NULL;
 }
 
@@ -270,7 +283,7 @@ bool unitemp_sensors_load(void) {
     }
 
     //Вычисление размера файла
-    uint8_t file_size = stream_size(app->file_stream);
+    uint16_t file_size = stream_size(app->file_stream);
     //Если файл пустой, то:
     if(file_size == (uint8_t)0) {
         FURI_LOG_W(APP_NAME, "Sensors file is empty");
@@ -458,10 +471,10 @@ Sensor* unitemp_sensor_alloc(char* name, const SensorType* type, char* args) {
         FURI_LOG_I(APP_NAME, "Sensor %s allocated", name);
         return sensor;
     }
-    //Если ни один из типов не подошёл, то выход с очисткой
+    //Выход с очисткой если память для датчика не была выделена
     free(sensor->name);
     free(sensor);
-    FURI_LOG_E(APP_NAME, "Sensor %s type is unsupported: %s", name, type->typename);
+    FURI_LOG_E(APP_NAME, "Sensor %s(%s) allocation error", name, type->typename);
     return NULL;
 }
 
@@ -563,7 +576,9 @@ UnitempStatus unitemp_sensor_updateData(Sensor* sensor) {
 
     sensor->status = sensor->type->interface->updater(sensor);
 
-    FURI_LOG_D(APP_NAME, "Sensor %s update status %d", sensor->name, sensor->status);
+    if(sensor->status != UT_OK && sensor->status != UT_POLLING)
+        FURI_LOG_D(APP_NAME, "Sensor %s update status %d", sensor->name, sensor->status);
+
     if(app->settings.unit == FAHRENHEIT && sensor->status == UT_OK)
         uintemp_celsiumToFarengate(sensor);
     if(sensor->status == UT_OK) {

+ 1 - 1
interfaces/SingleWireSensor.c

@@ -67,7 +67,7 @@ bool unitemp_singlewire_alloc(Sensor* sensor, char* args) {
     }
     sensor->instance = instance;
 
-    int gpio;
+    int gpio = 255;
     sscanf(args, "%d", &gpio);
 
     if(unitemp_singlewire_sensorSetGPIO(sensor, unitemp_gpio_getFromInt(gpio))) {

+ 11 - 5
unitemp.c

@@ -7,11 +7,8 @@
 #include <m-string.h>
 
 /* ****************************** Интерфейс ****************************** */
-//TODO: Вынести информирующих дельфинов в отдельную функцию
-//TODO: Реализовать ограничение на добавление датчиков если интерфейс недоступен
-
-//TODO: Ограничение на добавление датчика I2C с адресом уже имеющегося датчика
 //TODO: В режиме ожидания датчика указать в какому пину цепляться
+//TODO: Исправить: при редактировании датчика индекс GPIO нулевой
 //TODO: В меню выбора нового датчика добавить помогалку выбора датчика
 //TODO: Добавить настройку единицы измерения давления
 //TODO: Ограничивать длину имени датчика только тогда, когда имя действительно не вмещается
@@ -20,6 +17,7 @@
 /* ******************************* Датчики ******************************* */
 //TODO: Исправить зависание BMP280
 
+//TODO: Ограничение на добавление датчика I2C с адресом уже имеющегося датчика
 //TODO: Не выкидывать датчик в ошибку при первом же неудачном опросе
 //TODO: BMP280 SPI
 
@@ -212,9 +210,15 @@ static bool unitemp_alloc(void) {
     unitemp_SensorEdit_alloc();
     unitemp_SensorNameEdit_alloc();
     unitemp_SensorActions_alloc();
+
+    //Виджет
     app->widget = widget_alloc();
     view_dispatcher_add_view(
-        app->view_dispatcher, VIEW_SENSOR_DELETE, widget_get_view(app->widget));
+        app->view_dispatcher, UnitempViewSensorDelete, widget_get_view(app->widget));
+
+    //Всплывающее окно
+    app->popup = popup_alloc();
+    view_dispatcher_add_view(app->view_dispatcher, UnitempViewPopup, popup_get_view(app->popup));
 
     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
 
@@ -225,7 +229,9 @@ static bool unitemp_alloc(void) {
  * @brief Освыбождение памяти после работы приложения
  */
 static void unitemp_free(void) {
+    popup_free(app->popup);
     widget_free(app->widget);
+
     unitemp_SensorActions_free();
     unitemp_SensorNameEdit_free();
     unitemp_SensorEdit_free();

+ 2 - 1
unitemp.h

@@ -10,6 +10,7 @@
 #include <gui/gui.h>
 #include <gui/view_dispatcher.h>
 #include <gui/modules/widget.h>
+#include <gui/modules/popup.h>
 //Уведомления
 #include <notification/notification.h>
 #include <notification/notification_messages.h>
@@ -65,7 +66,7 @@ typedef struct {
     ViewDispatcher* view_dispatcher;
     NotificationApp* notifications;
     Widget* widget;
-
+    Popup* popup;
     //Буффер для различного текста
     char* buff;
 } Unitemp;

+ 2 - 2
views/General_view.c

@@ -476,12 +476,12 @@ void unitemp_General_alloc(void) {
     view_set_draw_callback(view, _draw_callback);
     view_set_input_callback(view, _input_callback);
 
-    view_dispatcher_add_view(app->view_dispatcher, VIEW_GENERAL, view);
+    view_dispatcher_add_view(app->view_dispatcher, UnitempViewGeneral, view);
 }
 
 void unitemp_General_switch(void) {
     app->sensors_ready = true;
-    view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_GENERAL);
+    view_dispatcher_switch_to_view(app->view_dispatcher, UnitempViewGeneral);
 }
 
 void unitemp_General_free(void) {

+ 2 - 2
views/MainMenu_view.c

@@ -6,7 +6,7 @@ static View* view;
 //Список
 static VariableItemList* variable_item_list;
 
-#define VIEW_ID VIEW_MAIN_MENU
+#define VIEW_ID UnitempViewMainMenu
 
 /**
  * @brief Функция обработки нажатия кнопки "Назад"
@@ -17,7 +17,7 @@ static VariableItemList* variable_item_list;
 static uint32_t _exit_callback(void* context) {
     UNUSED(context);
     //Возврат в общий вид
-    return VIEW_GENERAL;
+    return UnitempViewGeneral;
 }
 /**
  * @brief Функция обработки нажатия средней кнопки

+ 33 - 0
views/Popup_view.c

@@ -0,0 +1,33 @@
+#include "UnitempViews.h"
+#include <gui/modules/variable_item_list.h>
+#include <stdio.h>
+#include <assets_icons.h>
+
+uint32_t _prev_view_id;
+
+#define VIEW_ID UnitempViewPopup
+
+static void _popup_callback(void* context) {
+    UNUSED(context);
+    view_dispatcher_switch_to_view(app->view_dispatcher, _prev_view_id);
+}
+
+void unitemp_popup(const Icon* icon, char* header, char* message, uint32_t prev_view_id) {
+    _prev_view_id = prev_view_id;
+    popup_reset(app->popup);
+    popup_set_icon(app->popup, 0, 64 - icon_get_height(icon), icon);
+    popup_set_header(app->popup, header, 64, 6, AlignCenter, AlignCenter);
+    popup_set_text(
+        app->popup,
+        message,
+        (128 - icon_get_width(icon)) / 2 + icon_get_width(icon),
+        32,
+        AlignCenter,
+        AlignCenter);
+
+    popup_set_timeout(app->popup, 5000);
+    popup_set_callback(app->popup, _popup_callback);
+    popup_enable_timeout(app->popup);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_ID);
+}

+ 4 - 4
views/SensorActions_view.c

@@ -15,7 +15,7 @@ typedef enum carousel_info {
 } carousel_info;
 extern carousel_info carousel_info_selector;
 
-#define VIEW_ID VIEW_SENSOR_ACTIONS
+#define VIEW_ID UnitempViewSensorActions
 
 /* ================== Подтверждение удаления ================== */
 /**
@@ -27,7 +27,7 @@ extern carousel_info carousel_info_selector;
 static uint32_t _delete_exit_callback(void* context) {
     UNUSED(context);
     //Возвращаем ID вида, в который нужно вернуться
-    return VIEW_SENSOR_ACTIONS;
+    return UnitempViewSensorActions;
 }
 /**
  * @brief Обработчик нажатий на кнопку в виджете
@@ -124,7 +124,7 @@ static void _delete_widget_switch(void) {
     }
 
     view_set_previous_callback(widget_get_view(app->widget), _delete_exit_callback);
-    view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_SENSOR_DELETE);
+    view_dispatcher_switch_to_view(app->view_dispatcher, UnitempViewSensorDelete);
 }
 
 /**
@@ -137,7 +137,7 @@ static uint32_t _exit_callback(void* context) {
     UNUSED(context);
 
     //Возврат предыдущий вид
-    return VIEW_GENERAL;
+    return UnitempViewGeneral;
 }
 /**
  * @brief Функция обработки нажатия средней кнопки

+ 2 - 2
views/SensorEdit_view.c

@@ -23,7 +23,7 @@ static VariableItem* onewire_type_item;
 
 extern uint8_t generalview_sensor_index;
 
-#define VIEW_ID VIEW_SENSOR_EDIT
+#define VIEW_ID UnitempViewSensorEdit
 
 bool _onewire_id_exist(uint8_t* id) {
     if(id == NULL) return false;
@@ -118,7 +118,7 @@ static uint32_t _exit_callback(void* context) {
     if(!unitemp_sensor_isContains(editable_sensor)) unitemp_sensor_free(editable_sensor);
     unitemp_sensors_reload();
     //Возврат предыдущий вид
-    return VIEW_GENERAL;
+    return UnitempViewGeneral;
 }
 /**
  * @brief Функция обработки нажатия средней кнопки

+ 1 - 1
views/SensorNameEdit_view.c

@@ -6,7 +6,7 @@ static TextInput* text_input;
 //Текущий редактируемый датчик
 static Sensor* editable_sensor;
 
-#define VIEW_ID VIEW_SENSOR_NAME_EDIT
+#define VIEW_ID UnitempViewSensorNameEdit
 
 static void _sensor_name_changed_callback(void* context) {
     UNUSED(context);

+ 22 - 2
views/SensorsList_view.c

@@ -1,13 +1,14 @@
 #include "UnitempViews.h"
 #include <gui/modules/variable_item_list.h>
 #include <stdio.h>
+#include <assets_icons.h>
 
 //Текущий вид
 static View* view;
 //Список
 static VariableItemList* variable_item_list;
 
-#define VIEW_ID VIEW_SENSORS_LIST
+#define VIEW_ID UnitempViewSensorsList
 
 /**
  * @brief Функция обработки нажатия кнопки "Назад"
@@ -19,7 +20,7 @@ static uint32_t _exit_callback(void* context) {
     UNUSED(context);
 
     //Возврат предыдущий вид
-    return VIEW_GENERAL;
+    return UnitempViewGeneral;
 }
 /**
  * @brief Функция обработки нажатия средней кнопки
@@ -31,18 +32,37 @@ static void _enter_callback(void* context, uint32_t index) {
     UNUSED(context);
     const SensorType* type = unitemp_sensors_getTypes()[index];
     uint8_t sensor_type_count = 0;
+
+    //Подсчёт имеющихся датчиков данного типа
     for(uint8_t i = 0; i < unitemp_sensors_getActiveCount(); i++) {
         if(unitemp_sensor_getActive(i)->type == type) {
             sensor_type_count++;
         }
     }
+
     //Имя датчка
     char sensor_name[11];
+    //Добавление счётчика к имени если такой датчик имеется
     if(sensor_type_count == 0)
         snprintf(sensor_name, 11, "%s", type->typename);
     else
         snprintf(sensor_name, 11, "%s_%d", type->typename, sensor_type_count);
+
     char args[22] = {0};
+
+    //Проверка доступности датчика
+    if(unitemp_gpio_getAviablePort(type->interface, 0, NULL) == NULL) {
+        if(type->interface == &SINGLE_WIRE || type->interface == &ONE_WIRE) {
+            unitemp_popup(
+                &I_Cry_dolph_55x52, "Sensor is unavailable", "All GPIOs\nare busy", VIEW_ID);
+        }
+        if(type->interface == &I2C) {
+            unitemp_popup(
+                &I_Cry_dolph_55x52, "Sensor is unavailable", "GPIOs 15 or 16\nare busy", VIEW_ID);
+        }
+        return;
+    }
+
     //Выбор первого доступного порта для датчика single wire
     if(type->interface == &SINGLE_WIRE) {
         snprintf(

+ 2 - 2
views/Settings_view.c

@@ -13,7 +13,7 @@ static const char units[2][3] = {"*C", "*F"};
 VariableItem* infinity_backlight_item;
 //Единица измерения температуры
 VariableItem* temperature_unit_item;
-#define VIEW_ID VIEW_SETTINGS
+#define VIEW_ID UnitempViewSettings
 
 /**
  * @brief Функция обработки нажатия кнопки "Назад"
@@ -40,7 +40,7 @@ static uint32_t _exit_callback(void* context) {
     unitemp_loadSettings();
 
     //Возврат предыдущий вид
-    return VIEW_MAIN_MENU;
+    return UnitempViewMainMenu;
 }
 /**
  * @brief Функция обработки нажатия средней кнопки

+ 21 - 10
views/UnitempViews.h

@@ -5,18 +5,29 @@
 
 //Виды менюшек
 typedef enum UnitempViews {
-    VIEW_GENERAL,
-    VIEW_MAIN_MENU,
-    VIEW_SETTINGS,
-    VIEW_SENSORS_LIST,
-    VIEW_SENSOR_EDIT,
-    VIEW_SENSOR_NAME_EDIT,
-    VIEW_SENSOR_ACTIONS,
-    VIEW_SENSOR_DELETE,
-
-    VIEWS_COUNT
+    UnitempViewGeneral,
+    UnitempViewMainMenu,
+    UnitempViewSettings,
+    UnitempViewSensorsList,
+    UnitempViewSensorEdit,
+    UnitempViewSensorNameEdit,
+    UnitempViewSensorActions,
+    UnitempViewSensorDelete,
+    UnitempViewPopup,
+
+    UnitempViewsCount
 } UnitempViews;
 
+/**
+ * @brief Вывести всплывающее окно
+ * 
+ * @param icon Указатель на иконку
+ * @param header Заголовок
+ * @param message Сообщение
+ * @param prev_view_id ID вида куда в который нужно вернуться
+ */
+void unitemp_popup(const Icon* icon, char* header, char* message, uint32_t prev_view_id);
+
 /* Общий вид на датчики */
 void unitemp_General_alloc(void);
 void unitemp_General_switch(void);