diff --git a/applications/plugins/dht_temp_sensor/DHT.c b/applications/plugins/dht_temp_sensor/DHT.c deleted file mode 100644 index 63a189ce1..000000000 --- a/applications/plugins/dht_temp_sensor/DHT.c +++ /dev/null @@ -1,169 +0,0 @@ -#include "DHT.h" - -#define lineDown() furi_hal_gpio_write(sensor->GPIO, false) -#define lineUp() furi_hal_gpio_write(sensor->GPIO, true) -#define getLine() furi_hal_gpio_read(sensor->GPIO) -#define Delay(d) furi_delay_ms(d) - -DHT_data DHT_getData(DHT_sensor* sensor) { - DHT_data data = {-128.0f, -128.0f}; - -#if DHT_POLLING_CONTROL == 1 - /* Ограничение по частоте опроса датчика */ - //Определение интервала опроса в зависимости от датчика - uint16_t pollingInterval; - if(sensor->type == DHT11) { - pollingInterval = DHT_POLLING_INTERVAL_DHT11; - } else { - pollingInterval = DHT_POLLING_INTERVAL_DHT22; - } - - //Если интервал маленький, то возврат последнего удачного значения - if((furi_get_tick() - sensor->lastPollingTime < pollingInterval) && - sensor->lastPollingTime != 0) { - data.hum = sensor->lastHum; - data.temp = sensor->lastTemp; - return data; - } - sensor->lastPollingTime = furi_get_tick() + 1; -#endif - - //Опускание линии данных на 18 мс - lineDown(); -#ifdef DHT_IRQ_CONTROL - //Выключение прерываний, чтобы ничто не мешало обработке данных - __disable_irq(); -#endif - Delay(18); - - //Подъём линии - lineUp(); - - /* Ожидание ответа от датчика */ - uint16_t timeout = 0; - while(!getLine()) { - timeout++; - if(timeout > DHT_TIMEOUT) { -#ifdef DHT_IRQ_CONTROL - __enable_irq(); -#endif - //Если датчик не отозвался, значит его точно нет - //Обнуление последнего удачного значения, чтобы - //не получать фантомные значения - sensor->lastHum = -128.0f; - sensor->lastTemp = -128.0f; - - return data; - } - } - //Ожидание спада - while(getLine()) { - timeout++; - if(timeout > DHT_TIMEOUT) { -#ifdef DHT_IRQ_CONTROL - __enable_irq(); -#endif - //Если датчик не отозвался, значит его точно нет - //Обнуление последнего удачного значения, чтобы - //не получать фантомные значения - sensor->lastHum = -128.0f; - sensor->lastTemp = -128.0f; - - return data; - } - } - timeout = 0; - //Ожидание подъёма - while(!getLine()) { - timeout++; - if(timeout > DHT_TIMEOUT) { - if(timeout > DHT_TIMEOUT) { -#ifdef DHT_IRQ_CONTROL - __enable_irq(); -#endif - //Если датчик не отозвался, значит его точно нет - //Обнуление последнего удачного значения, чтобы - //не получать фантомные значения - sensor->lastHum = -128.0f; - sensor->lastTemp = -128.0f; - - return data; - } - } - } - timeout = 0; - //Ожидание спада - while(getLine()) { - timeout++; - if(timeout > DHT_TIMEOUT) { -#ifdef DHT_IRQ_CONTROL - __enable_irq(); -#endif - //Если датчик не отозвался, значит его точно нет - //Обнуление последнего удачного значения, чтобы - //не получать фантомные значения - sensor->lastHum = -128.0f; - sensor->lastTemp = -128.0f; - return data; - } - } - - /* Чтение ответа от датчика */ - uint8_t rawData[5] = {0, 0, 0, 0, 0}; - for(uint8_t a = 0; a < 5; a++) { - for(uint8_t b = 7; b != 255; b--) { - uint16_t hT = 0, lT = 0; - //Пока линия в низком уровне, инкремент переменной lT - while(!getLine() && lT != 65535) lT++; - //Пока линия в высоком уровне, инкремент переменной hT - timeout = 0; - while(getLine() && hT != 65535) hT++; - //Если hT больше lT, то пришла единица - if(hT > lT) rawData[a] |= (1 << b); - } - } -#ifdef DHT_IRQ_CONTROL - //Включение прерываний после приёма данных - __enable_irq(); -#endif - /* Проверка целостности данных */ - if((uint8_t)(rawData[0] + rawData[1] + rawData[2] + rawData[3]) == rawData[4]) { - //Если контрольная сумма совпадает, то конвертация и возврат полученных значений - if(sensor->type == DHT22) { - data.hum = (float)(((uint16_t)rawData[0] << 8) | rawData[1]) * 0.1f; - //Проверка на отрицательность температуры - if(!(rawData[2] & (1 << 7))) { - data.temp = (float)(((uint16_t)rawData[2] << 8) | rawData[3]) * 0.1f; - } else { - rawData[2] &= ~(1 << 7); - data.temp = (float)(((uint16_t)rawData[2] << 8) | rawData[3]) * -0.1f; - } - } - if(sensor->type == DHT11) { - data.hum = (float)rawData[0]; - data.temp = (float)rawData[2]; - //DHT11 производства ASAIR имеют дробную часть в температуре - //А ещё температуру измеряет от -20 до +60 *С - //Вот прикол, да? - if(rawData[3] != 0) { - //Проверка знака - if(!(rawData[3] & (1 << 7))) { - //Добавление положительной дробной части - data.temp += rawData[3] * 0.1f; - } else { - //А тут делаем отрицательное значение - rawData[3] &= ~(1 << 7); - data.temp += rawData[3] * 0.1f; - data.temp *= -1; - } - } - } - } - -#if DHT_POLLING_CONTROL == 1 - sensor->lastHum = data.hum; - sensor->lastTemp = data.temp; -#endif - - return data; -} \ No newline at end of file diff --git a/applications/plugins/dht_temp_sensor/DHT.h b/applications/plugins/dht_temp_sensor/DHT.h deleted file mode 100644 index 409847d8b..000000000 --- a/applications/plugins/dht_temp_sensor/DHT.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef DHT_H_ -#define DHT_H_ - -#include - -/* Настройки */ -#define DHT_TIMEOUT 65534 //Количество итераций, после которых функция вернёт пустые значения -#define DHT_POLLING_CONTROL 1 //Включение проверки частоты опроса датчика -#define DHT_POLLING_INTERVAL_DHT11 \ - 2000 //Интервал опроса DHT11 (0.5 Гц по даташиту). Можно поставить 1500, будет работать -//Костыль, временно 2 секунды для датчика AM2302 -#define DHT_POLLING_INTERVAL_DHT22 2000 //Интервал опроса DHT22 (1 Гц по даташиту) -#define DHT_IRQ_CONTROL //Выключать прерывания во время обмена данных с датчиком -/* Структура возвращаемых датчиком данных */ -typedef struct { - float hum; - float temp; -} DHT_data; - -/* Тип используемого датчика */ -typedef enum { DHT11, DHT22 } DHT_type; - -/* Структура объекта датчика */ -typedef struct { - char name[11]; - const GpioPin* GPIO; //Пин датчика - DHT_type type; //Тип датчика (DHT11 или DHT22) - -//Контроль частоты опроса датчика. Значения не заполнять! -#if DHT_POLLING_CONTROL == 1 - uint32_t lastPollingTime; //Время последнего опроса датчика - float lastTemp; //Последнее значение температуры - float lastHum; //Последнее значение влажности -#endif -} DHT_sensor; - -/* Прототипы функций */ -DHT_data DHT_getData(DHT_sensor* sensor); //Получить данные с датчика - -#endif diff --git a/applications/plugins/dht_temp_sensor/application.fam b/applications/plugins/dht_temp_sensor/application.fam deleted file mode 100644 index ad74919a4..000000000 --- a/applications/plugins/dht_temp_sensor/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="quenon_dht_mon", - name="[DHT] Temp. Monitor", - apptype=FlipperAppType.EXTERNAL, - entry_point="quenon_dht_mon_app", - cdefines=["QUENON_DHT_MON"], - requires=[ - "gui", - ], - fap_category="GPIO", - fap_icon="icon.png", - stack_size=2 * 1024, -) \ No newline at end of file diff --git a/applications/plugins/dht_temp_sensor/icon.png b/applications/plugins/dht_temp_sensor/icon.png deleted file mode 100644 index 0e87c26c2..000000000 Binary files a/applications/plugins/dht_temp_sensor/icon.png and /dev/null differ diff --git a/applications/plugins/dht_temp_sensor/quenon_dht_mon.c b/applications/plugins/dht_temp_sensor/quenon_dht_mon.c deleted file mode 100644 index bbb653988..000000000 --- a/applications/plugins/dht_temp_sensor/quenon_dht_mon.c +++ /dev/null @@ -1,464 +0,0 @@ -#include "quenon_dht_mon.h" -#include - -//Порты ввода/вывода, которые не были обозначены в общем списке -const GpioPin SWC_10 = {.pin = LL_GPIO_PIN_14, .port = GPIOA}; -const GpioPin SIO_12 = {.pin = LL_GPIO_PIN_13, .port = GPIOA}; -const GpioPin TX_13 = {.pin = LL_GPIO_PIN_6, .port = GPIOB}; -const GpioPin RX_14 = {.pin = LL_GPIO_PIN_7, .port = GPIOB}; - -//Количество доступных портов ввода/вывода -#define GPIO_ITEMS (sizeof(gpio_item) / sizeof(GpioItem)) - -//Перечень достуных портов ввода/вывода -static const GpioItem gpio_item[] = { - {2, "2 (A7)", &gpio_ext_pa7}, - {3, "3 (A6)", &gpio_ext_pa6}, - {4, "4 (A4)", &gpio_ext_pa4}, - {5, "5 (B3)", &gpio_ext_pb3}, - {6, "6 (B2)", &gpio_ext_pb2}, - {7, "7 (C3)", &gpio_ext_pc3}, - {10, " 10(SWC) ", &SWC_10}, - {12, "12 (SIO)", &SIO_12}, - {13, "13 (TX)", &TX_13}, - {14, "14 (RX)", &RX_14}, - {15, "15 (C1)", &gpio_ext_pc1}, - {16, "16 (C0)", &gpio_ext_pc0}, - {17, "17 (1W)", &ibutton_gpio}}; - -//Данные плагина -static PluginData* app; - -uint8_t DHTMon_GPIO_to_int(const GpioPin* gpio) { - if(gpio == NULL) return 255; - for(uint8_t i = 0; i < GPIO_ITEMS; i++) { - if(gpio_item[i].pin->pin == gpio->pin && gpio_item[i].pin->port == gpio->port) { - return gpio_item[i].num; - } - } - return 255; -} - -const GpioPin* DHTMon_GPIO_form_int(uint8_t name) { - for(uint8_t i = 0; i < GPIO_ITEMS; i++) { - if(gpio_item[i].num == name) { - return gpio_item[i].pin; - } - } - return NULL; -} - -const GpioPin* DHTMon_GPIO_from_index(uint8_t index) { - if(index > GPIO_ITEMS) return NULL; - return gpio_item[index].pin; -} - -uint8_t DHTMon_GPIO_to_index(const GpioPin* gpio) { - if(gpio == NULL) return 255; - for(uint8_t i = 0; i < GPIO_ITEMS; i++) { - if(gpio_item[i].pin->pin == gpio->pin && gpio_item[i].pin->port == gpio->port) { - return i; - } - } - return 255; -} - -const char* DHTMon_GPIO_getName(const GpioPin* gpio) { - if(gpio == NULL) return NULL; - for(uint8_t i = 0; i < GPIO_ITEMS; i++) { - if(gpio_item[i].pin->pin == gpio->pin && gpio_item[i].pin->port == gpio->port) { - return gpio_item[i].name; - } - } - return NULL; -} - -void DHTMon_sensors_init(void) { - //Включение 5V если на порту 1 FZ его нет - if(furi_hal_power_is_otg_enabled() != true) { - furi_hal_power_enable_otg(); - } - - //Настройка GPIO загруженных датчиков - for(uint8_t i = 0; i < app->sensors_count; i++) { - //Высокий уровень по умолчанию - furi_hal_gpio_write(app->sensors[i].GPIO, true); - //Режим работы - OpenDrain, подтяжка включается на всякий случай - furi_hal_gpio_init( - app->sensors[i].GPIO, //Порт FZ - GpioModeOutputOpenDrain, //Режим работы - открытый сток - GpioPullUp, //Принудительная подтяжка линии данных к питанию - GpioSpeedVeryHigh); //Скорость работы - максимальная - } -} - -void DHTMon_sensors_deinit(void) { - //Возврат исходного состояния 5V - if(app->last_OTG_State != true) { - furi_hal_power_disable_otg(); - } - - //Перевод портов GPIO в состояние по умолчанию - for(uint8_t i = 0; i < app->sensors_count; i++) { - furi_hal_gpio_init( - app->sensors[i].GPIO, //Порт FZ - GpioModeAnalog, //Режим работы - аналог - GpioPullNo, //Отключение подтяжки - GpioSpeedLow); //Скорость работы - низкая - //Установка низкого уровня - furi_hal_gpio_write(app->sensors[i].GPIO, false); - } -} - -bool DHTMon_sensor_check(DHT_sensor* sensor) { - /* Проверка имени */ - //1) Строка должна быть длиной от 1 до 10 символов - //2) Первый символ строки должен быть только 0-9, A-Z, a-z и _ - if(strlen(sensor->name) == 0 || strlen(sensor->name) > 10 || - (!(sensor->name[0] >= '0' && sensor->name[0] <= '9') && - !(sensor->name[0] >= 'A' && sensor->name[0] <= 'Z') && - !(sensor->name[0] >= 'a' && sensor->name[0] <= 'z') && !(sensor->name[0] == '_'))) { - FURI_LOG_D(APP_NAME, "Sensor [%s] name check failed\r\n", sensor->name); - return false; - } - //Проверка GPIO - if(DHTMon_GPIO_to_int(sensor->GPIO) == 255) { - FURI_LOG_D( - APP_NAME, - "Sensor [%s] GPIO check failed: %d\r\n", - sensor->name, - DHTMon_GPIO_to_int(sensor->GPIO)); - return false; - } - //Проверка типа датчика - if(sensor->type != DHT11 && sensor->type != DHT22) { - FURI_LOG_D(APP_NAME, "Sensor [%s] type check failed: %d\r\n", sensor->name, sensor->type); - return false; - } - - //Возврат истины если всё ок - FURI_LOG_D(APP_NAME, "Sensor [%s] all checks passed\r\n", sensor->name); - return true; -} - -void DHTMon_sensor_delete(DHT_sensor* sensor) { - if(sensor == NULL) return; - //Делаем параметры датчика неверными - sensor->name[0] = '\0'; - sensor->type = 255; - //Теперь сохраняем текущие датчики. Сохранятор не сохранит неисправный датчик - DHTMon_sensors_save(); - //Перезагружаемся с SD-карты - DHTMon_sensors_reload(); -} - -uint8_t DHTMon_sensors_save(void) { - //Выделение памяти для потока - app->file_stream = file_stream_alloc(app->storage); - uint8_t savedSensorsCount = 0; - //Переменная пути к файлу - FuriString* filepath = furi_string_alloc(); - //Составление пути к файлу - furi_string_printf(filepath, "%s/%s", APP_PATH_FOLDER, APP_FILENAME); - - //Открытие потока. Если поток открылся, то выполнение сохранения датчиков - if(file_stream_open( - app->file_stream, furi_string_get_cstr(filepath), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)) { - const char template[] = - "#DHT monitor sensors file\n#Name - name of sensor. Up to 10 sumbols\n#Type - type of sensor. DHT11 - 0, DHT22 - 1\n#GPIO - connection port. May being 2-7, 10, 12-17\n#Name Type GPIO\n"; - stream_write(app->file_stream, (uint8_t*)template, strlen(template)); - //Сохранение датчиков - for(uint8_t i = 0; i < app->sensors_count; i++) { - //Если параметры датчика верны, то сохраняемся - if(DHTMon_sensor_check(&app->sensors[i])) { - stream_write_format( - app->file_stream, - "%s %d %d\n", - app->sensors[i].name, - app->sensors[i].type, - DHTMon_GPIO_to_int(app->sensors[i].GPIO)); - savedSensorsCount++; - } - } - } else { - //TODO: печать ошибки на экран - FURI_LOG_E(APP_NAME, "cannot create sensors file\r\n"); - } - stream_free(app->file_stream); - - return savedSensorsCount; -} - -bool DHTMon_sensors_load(void) { - //Обнуление количества датчиков - app->sensors_count = -1; - //Очистка предыдущих датчиков - memset(app->sensors, 0, sizeof(app->sensors)); - - //Открытие файла на SD-карте - //Выделение памяти для потока - app->file_stream = file_stream_alloc(app->storage); - //Переменная пути к файлу - FuriString* filepath = furi_string_alloc(); - //Составление пути к файлу - furi_string_printf(filepath, "%s/%s", APP_PATH_FOLDER, APP_FILENAME); - //Открытие потока к файлу - if(!file_stream_open( - app->file_stream, furi_string_get_cstr(filepath), FSAM_READ_WRITE, FSOM_OPEN_EXISTING)) { - //Если файл отсутствует, то создание болванки - FURI_LOG_W(APP_NAME, "Missing sensors file. Creating new file\r\n"); - app->sensors_count = 0; - stream_free(app->file_stream); - DHTMon_sensors_save(); - return false; - } - //Вычисление размера файла - size_t file_size = stream_size(app->file_stream); - if(file_size == (size_t)0) { - //Выход если файл пустой - FURI_LOG_W(APP_NAME, "Sensors file is empty\r\n"); - app->sensors_count = 0; - stream_free(app->file_stream); - return false; - } - - //Выделение памяти под загрузку файла - uint8_t* file_buf = malloc(file_size); - //Опустошение буфера файла - memset(file_buf, 0, file_size); - //Загрузка файла - if(stream_read(app->file_stream, file_buf, file_size) != file_size) { - //Выход при ошибке чтения - FURI_LOG_E(APP_NAME, "Error reading sensor file\r\n"); - app->sensors_count = 0; - stream_free(app->file_stream); - return false; - } - //Построчное чтение файла - //Указатель на начало строки - FuriString* file = furi_string_alloc_set_str((char*)file_buf); - //Сколько байт до конца строки - size_t line_end = 0; - while(line_end != STRING_FAILURE && app->sensors_count < MAX_SENSORS) { - if(((char*)(file_buf + line_end))[1] != '#') { - DHT_sensor s = {0}; - int type, port; - char name[11] = {0}; - sscanf(((char*)(file_buf + line_end)), "%s %d %d", name, &type, &port); - s.type = type; - s.GPIO = DHTMon_GPIO_form_int(port); - - name[10] = '\0'; - strcpy(s.name, name); - //Если данные корректны, то - if(DHTMon_sensor_check(&s) == true) { - //Установка нуля при первом датчике - if(app->sensors_count == -1) app->sensors_count = 0; - //Добавление датчика в общий список - app->sensors[app->sensors_count] = s; - //Увеличение количества загруженных датчиков - app->sensors_count++; - } - } - line_end = furi_string_search_char(file, '\n', line_end + 1); - } - stream_free(app->file_stream); - free(file_buf); - - //Обнуление количества датчиков если ни один из них не был загружен - if(app->sensors_count == -1) app->sensors_count = 0; - - //Инициализация портов датчиков если таковые есть - if(app->sensors_count > 0) { - DHTMon_sensors_init(); - return true; - } else { - return false; - } - return false; -} - -bool DHTMon_sensors_reload(void) { - DHTMon_sensors_deinit(); - return DHTMon_sensors_load(); -} - -/** - * @brief Обработчик отрисовки экрана - * - * @param canvas Указатель на холст - * @param ctx Данные плагина - */ -static void render_callback(Canvas* const canvas, void* ctx) { - PluginData* app = acquire_mutex((ValueMutex*)ctx, 25); - if(app == NULL) { - return; - } - //Вызов отрисовки главного экрана - scene_main(canvas, app); - - release_mutex((ValueMutex*)ctx, app); -} - -/** - * @brief Обработчик нажатия кнопок главного экрана - * - * @param input_event Указатель на событие - * @param event_queue Указатель на очередь событий - */ -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -/** - * @brief Выделение места под переменные плагина - * - * @return true Если всё прошло успешно - * @return false Если в процессе загрузки произошла ошибка - */ -static bool DHTMon_alloc(void) { - //Выделение места под данные плагина - app = malloc(sizeof(PluginData)); - //Выделение места под очередь событий - app->event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - //Обнуление количества датчиков - app->sensors_count = -1; - - //Инициализация мутекса - if(!init_mutex(&app->state_mutex, app, sizeof(PluginData))) { - FURI_LOG_E(APP_NAME, "cannot create mutex\r\n"); - return false; - } - - // Set system callbacks - app->view_port = view_port_alloc(); - view_port_draw_callback_set(app->view_port, render_callback, &app->state_mutex); - view_port_input_callback_set(app->view_port, input_callback, app->event_queue); - - // Open GUI and register view_port - app->gui = furi_record_open(RECORD_GUI); - gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); - - app->view_dispatcher = view_dispatcher_alloc(); - - sensorActions_sceneCreate(app); - sensorEdit_sceneCreate(app); - - app->widget = widget_alloc(); - view_dispatcher_add_view(app->view_dispatcher, WIDGET_VIEW, widget_get_view(app->widget)); - - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, TEXTINPUT_VIEW, text_input_get_view(app->text_input)); - - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - //Уведомления - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - //Подготовка хранилища - app->storage = furi_record_open(RECORD_STORAGE); - storage_common_mkdir(app->storage, APP_PATH_FOLDER); - app->file_stream = file_stream_alloc(app->storage); - - return true; -} - -/** - * @brief Освыбождение памяти после работы приложения - */ -static void DHTMon_free(void) { - //Автоматическое управление подсветкой - notification_message(app->notifications, &sequence_display_backlight_enforce_auto); - - furi_record_close(RECORD_STORAGE); - furi_record_close(RECORD_NOTIFICATION); - - text_input_free(app->text_input); - widget_free(app->widget); - sensorEdit_sceneRemove(); - sensorActions_screneRemove(); - view_dispatcher_free(app->view_dispatcher); - - furi_record_close(RECORD_GUI); - - view_port_enabled_set(app->view_port, false); - gui_remove_view_port(app->gui, app->view_port); - - view_port_free(app->view_port); - furi_message_queue_free(app->event_queue); - delete_mutex(&app->state_mutex); - - free(app); -} - -/** - * @brief Точка входа в приложение - * - * @return Код ошибки - */ -int32_t quenon_dht_mon_app() { - if(!DHTMon_alloc()) { - DHTMon_free(); - return 255; - } - //Постоянное свечение подсветки - notification_message(app->notifications, &sequence_display_backlight_enforce_on); - //Сохранение состояния наличия 5V на порту 1 FZ - app->last_OTG_State = furi_hal_power_is_otg_enabled(); - - //Загрузка датчиков с SD-карты - DHTMon_sensors_load(); - - app->currentSensorEdit = &app->sensors[0]; - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(app->event_queue, &event, 100); - - acquire_mutex_block(&app->state_mutex); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypePress) { - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - break; - case InputKeyLeft: - break; - case InputKeyOk: - view_port_update(app->view_port); - release_mutex(&app->state_mutex, app); - mainMenu_scene(app); - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } - } - } - - view_port_update(app->view_port); - release_mutex(&app->state_mutex, app); - } - //Освобождение памяти и деинициализация - DHTMon_sensors_deinit(); - DHTMon_free(); - - return 0; -} -//TODO: Обработка ошибок -//TODO: Пропуск использованных портов в меню добавления датчиков \ No newline at end of file diff --git a/applications/plugins/dht_temp_sensor/quenon_dht_mon.h b/applications/plugins/dht_temp_sensor/quenon_dht_mon.h deleted file mode 100644 index 4e888f6c1..000000000 --- a/applications/plugins/dht_temp_sensor/quenon_dht_mon.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef QUENON_DHT_MON -#define QUENON_DHT_MON - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "DHT.h" - -#define APP_NAME "DHT_monitor" -#define APP_PATH_FOLDER "/ext/dht_monitor" -#define APP_FILENAME "sensors.txt" -#define MAX_SENSORS 5 - -// //Виды менюшек -typedef enum { - MAIN_MENU_VIEW, - ADDSENSOR_MENU_VIEW, - TEXTINPUT_VIEW, - SENSOR_ACTIONS_VIEW, - WIDGET_VIEW, -} MENU_VIEWS; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef struct { - const uint8_t num; - const char* name; - const GpioPin* pin; -} GpioItem; - -//Структура с данными плагина -typedef struct { - //Очередь сообщений - FuriMessageQueue* event_queue; - //Мутекс - ValueMutex state_mutex; - //Вьюпорт - ViewPort* view_port; - //GUI - Gui* gui; - NotificationApp* notifications; - ViewDispatcher* view_dispatcher; - View* view; - TextInput* text_input; - VariableItem* item; - Widget* widget; - - char txtbuff[30]; //Буффер для печати строк на экране - bool last_OTG_State; //Состояние OTG до запуска приложения - Storage* storage; //Хранилище датчиков - Stream* file_stream; //Поток файла с датчиками - int8_t sensors_count; // Количество загруженных датчиков - DHT_sensor sensors[MAX_SENSORS]; //Сохранённые датчики - DHT_data data; //Инфа из датчика - DHT_sensor* currentSensorEdit; //Указатель на редактируемый датчик - -} PluginData; - -/* ================== Работа с GPIO ================== */ -/** - * @brief Конвертация GPIO в его номер на корпусе FZ - * - * @param gpio Указатель на преобразовываемый GPIO - * @return Номер порта на корпусе FZ - */ -uint8_t DHTMon_GPIO_to_int(const GpioPin* gpio); -/** - * @brief Конвертация номера порта на корпусе FZ в GPIO - * - * @param name Номер порта на корпусе FZ - * @return Указатель на GPIO при успехе, NULL при ошибке - */ -const GpioPin* DHTMon_GPIO_form_int(uint8_t name); -/** - * @brief Преобразование порядкового номера порта в GPIO - * - * @param index Индекс порта от 0 до GPIO_ITEMS-1 - * @return Указатель на GPIO при успехе, NULL при ошибке - */ -const GpioPin* DHTMon_GPIO_from_index(uint8_t index); -/** - * @brief Преобразование GPIO в порядковый номер порта - * - * @param gpio Указатель на GPIO - * @return index при успехе, 255 при ошибке - */ -uint8_t DHTMon_GPIO_to_index(const GpioPin* gpio); - -/** - * @brief Получить имя GPIO в виде строки - * - * @param gpio Искомый порт - * @return char* Указатель на строку с именем порта - */ -const char* DHTMon_GPIO_getName(const GpioPin* gpio); - -/* ================== Работа с датчиками ================== */ -/** - * @brief Инициализация портов ввода/вывода датчиков - */ -void DHTMon_sensors_init(void); -/** - * @brief Функция деинициализации портов ввода/вывода датчиков - */ -void DHTMon_sensors_deinit(void); -/** - * @brief Проверка корректности параметров датчика - * - * @param sensor Указатель на проверяемый датчик - * @return true Параметры датчика корректные - * @return false Параметры датчика некорректные - */ -bool DHTMon_sensor_check(DHT_sensor* sensor); -/** - * @brief Удаление датчика из списка и перезагрузка - * - * @param sensor Указатель на удаляемый датчик - */ -void DHTMon_sensor_delete(DHT_sensor* sensor); -/** - * @brief Сохранение датчиков на SD-карту - * - * @return Количество сохранённых датчиков - */ -uint8_t DHTMon_sensors_save(void); -/** - * @brief Загрузка датчиков с SD-карты - * - * @return true Был загружен хотя бы 1 датчик - * @return false Датчики отсутствуют - */ -bool DHTMon_sensors_load(void); -/** - * @brief Перезагрузка датчиков с SD-карты - * - * @return true Когда был загружен хотя бы 1 датчик - * @return false Ни один из датчиков не был загружен - */ -bool DHTMon_sensors_reload(void); - -void scene_main(Canvas* const canvas, PluginData* app); -void mainMenu_scene(PluginData* app); - -void sensorEdit_sceneCreate(PluginData* app); -void sensorEdit_scene(PluginData* app); -void sensorEdit_sceneRemove(void); - -void sensorActions_sceneCreate(PluginData* app); -void sensorActions_scene(PluginData* app); -void sensorActions_screneRemove(void); -#endif \ No newline at end of file diff --git a/applications/plugins/dht_temp_sensor/scenes/DHTMon_mainMenu_scene.c b/applications/plugins/dht_temp_sensor/scenes/DHTMon_mainMenu_scene.c deleted file mode 100644 index 26ac9ca89..000000000 --- a/applications/plugins/dht_temp_sensor/scenes/DHTMon_mainMenu_scene.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "../quenon_dht_mon.h" -//Текущий вид -static View* view; -//Список -static VariableItemList* variable_item_list; - -/** - * @brief Функция обработки нажатия кнопки "Назад" - * - * @param context Указатель на данные приложения - * @return ID вида в который нужно переключиться - */ -static uint32_t actions_exitCallback(void* context) { - PluginData* app = context; - UNUSED(app); - //Возвращаем ID вида, в который нужно вернуться - return VIEW_NONE; -} -/** - * @brief Функция обработки нажатия средней кнопки - * - * @param context Указатель на данные приложения - * @param index На каком элементе списка была нажата кнопка - */ -static void enterCallback(void* context, uint32_t index) { - PluginData* app = context; - if((uint8_t)index < (uint8_t)app->sensors_count) { - app->currentSensorEdit = &app->sensors[index]; - sensorActions_scene(app); - } - if((uint8_t)index == (uint8_t)app->sensors_count) { - app->currentSensorEdit = &app->sensors[app->sensors_count++]; - strcpy(app->currentSensorEdit->name, "NewSensor"); - app->currentSensorEdit->GPIO = DHTMon_GPIO_from_index(0); - app->currentSensorEdit->type = DHT11; - sensorEdit_scene(app); - } -} - -/** - * @brief Создание списка действий с указанным датчиком - * - * @param app Указатель на данные плагина - */ -void mainMenu_scene(PluginData* app) { - variable_item_list = variable_item_list_alloc(); - //Сброс всех элементов меню - variable_item_list_reset(variable_item_list); - //Добавление названий датчиков в качестве элементов списка - for(uint8_t i = 0; i < app->sensors_count; i++) { - variable_item_list_add(variable_item_list, app->sensors[i].name, 1, NULL, NULL); - } - if(app->sensors_count < (uint8_t)MAX_SENSORS) { - variable_item_list_add(variable_item_list, " + Add new sensor +", 1, NULL, NULL); - } - - //Добавление колбека на нажатие средней кнопки - variable_item_list_set_enter_callback(variable_item_list, enterCallback, app); - - //Создание вида из списка - view = variable_item_list_get_view(variable_item_list); - //Добавление колбека на нажатие кнопки "Назад" - view_set_previous_callback(view, actions_exitCallback); - //Добавление вида в диспетчер - view_dispatcher_add_view(app->view_dispatcher, MAIN_MENU_VIEW, view); - - view_dispatcher_enable_queue(app->view_dispatcher); - - //Переключение на наш вид - view_dispatcher_switch_to_view(app->view_dispatcher, MAIN_MENU_VIEW); - - //Запуск диспетчера - view_dispatcher_run(app->view_dispatcher); - - //Очистка списка элементов - variable_item_list_free(variable_item_list); - //Удаление вида после обработки - view_dispatcher_remove_view(app->view_dispatcher, MAIN_MENU_VIEW); -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - -// static VariableItemList* variable_item_list; -// /* ============== Главное меню ============== */ -// static uint32_t mainMenu_exitCallback(void* context) { -// UNUSED(context); -// variable_item_list_free(variable_item_list); -// DHT_sensors_reload(); -// return VIEW_NONE; -// } -// static void mainMenu_enterCallback(void* context, uint32_t index) { -// PluginData* app = context; -// if((uint8_t)index == (uint8_t)app->sensors_count) { -// addSensor_scene(app); -// view_dispatcher_run(app->view_dispatcher); -// } -// } -// void mainMenu_scene(PluginData* app) { -// variable_item_list = variable_item_list_alloc(); -// variable_item_list_reset(variable_item_list); -// for(uint8_t i = 0; i < app->sensors_count; i++) { -// variable_item_list_add(variable_item_list, app->sensors[i].name, 1, NULL, NULL); -// } -// variable_item_list_add(variable_item_list, "+ Add new sensor +", 1, NULL, NULL); - -// app->view = variable_item_list_get_view(variable_item_list); -// app->view_dispatcher = view_dispatcher_alloc(); - -// view_dispatcher_enable_queue(app->view_dispatcher); -// view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); -// view_dispatcher_add_view(app->view_dispatcher, MAIN_MENU_VIEW, app->view); -// view_dispatcher_switch_to_view(app->view_dispatcher, MAIN_MENU_VIEW); - -// variable_item_list_set_enter_callback(variable_item_list, mainMenu_enterCallback, app); -// view_set_previous_callback(app->view, mainMenu_exitCallback); -// } \ No newline at end of file diff --git a/applications/plugins/dht_temp_sensor/scenes/DHTMon_main_scene.c b/applications/plugins/dht_temp_sensor/scenes/DHTMon_main_scene.c deleted file mode 100644 index aab343752..000000000 --- a/applications/plugins/dht_temp_sensor/scenes/DHTMon_main_scene.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "../quenon_dht_mon.h" - -/* ============== Главный экран ============== */ -void scene_main(Canvas* const canvas, PluginData* app) { - //Рисование бара - canvas_draw_box(canvas, 0, 0, 128, 14); - canvas_set_color(canvas, ColorWhite); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 32, 11, "DHT Monitor"); - - canvas_set_color(canvas, ColorBlack); - if(app->sensors_count > 0) { - if(!furi_hal_power_is_otg_enabled()) { - furi_hal_power_enable_otg(); - } - for(uint8_t i = 0; i < app->sensors_count; i++) { - app->data = DHT_getData(&app->sensors[i]); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 24 + 10 * i, app->sensors[i].name); - - canvas_set_font(canvas, FontSecondary); - if(app->data.hum == -128.0f && app->data.temp == -128.0f) { - canvas_draw_str(canvas, 96, 24 + 10 * i, "timeout"); - } else { - snprintf( - app->txtbuff, - sizeof(app->txtbuff), - "%2.1f*C/%d%%", - (double)app->data.temp, - (int8_t)app->data.hum); - canvas_draw_str(canvas, 64, 24 + 10 * i, app->txtbuff); - } - } - } else { - canvas_set_font(canvas, FontSecondary); - if(app->sensors_count == 0) canvas_draw_str(canvas, 0, 24, "Sensors not found"); - if(app->sensors_count == -1) canvas_draw_str(canvas, 0, 24, "Loading..."); - } -} diff --git a/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorActions_scene.c b/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorActions_scene.c deleted file mode 100644 index ae7674f70..000000000 --- a/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorActions_scene.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "../quenon_dht_mon.h" - -//Текущий вид -static View* view; -//Список -static VariableItemList* variable_item_list; - -/* ================== Информация о датчике ================== */ -/** - * @brief Функция обработки нажатия кнопки "Назад" - * - * @param context Указатель на данные приложения - * @return ID вида в который нужно переключиться - */ -static uint32_t infoWidget_exitCallback(void* context) { - PluginData* app = context; - UNUSED(app); - //Возвращаем ID вида, в который нужно вернуться - return SENSOR_ACTIONS_VIEW; -} -/** - * @brief Обработчик нажатий на кнопку в виджете - * - * @param result Какая из кнопок была нажата - * @param type Тип нажатия - * @param context Указатель на данные плагина - */ -static void infoWidget_callback(GuiButtonType result, InputType type, void* context) { - PluginData* app = context; - //Коротко нажата левая кнопка (Back) - if(result == GuiButtonTypeLeft && type == InputTypeShort) { - view_dispatcher_switch_to_view(app->view_dispatcher, SENSOR_ACTIONS_VIEW); - } -} -/** - * @brief Создание виджета информации о датчике - * - * @param app Указатель на данные плагина - */ -static void sensorInfo_widget(PluginData* app) { - //Очистка виджета - widget_reset(app->widget); - //Добавление кнопок - widget_add_button_element(app->widget, GuiButtonTypeLeft, "Back", infoWidget_callback, app); - - char str[32]; - snprintf(str, sizeof(str), "\e#%s\e#", app->currentSensorEdit->name); - widget_add_text_box_element(app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, str, false); - snprintf(str, sizeof(str), "\e#Type:\e# %s", app->currentSensorEdit->type ? "DHT22" : "DHT11"); - widget_add_text_box_element(app->widget, 0, 0, 128, 47, AlignLeft, AlignCenter, str, false); - snprintf( - str, sizeof(str), "\e#GPIO:\e# %s", DHTMon_GPIO_getName(app->currentSensorEdit->GPIO)); - widget_add_text_box_element(app->widget, 0, 0, 128, 72, AlignLeft, AlignCenter, str, false); - view_set_previous_callback(widget_get_view(app->widget), infoWidget_exitCallback); - view_dispatcher_switch_to_view(app->view_dispatcher, WIDGET_VIEW); -} - -/* ================== Подтверждение удаления ================== */ -/** - * @brief Функция обработки нажатия кнопки "Назад" - * - * @param context Указатель на данные приложения - * @return ID вида в который нужно переключиться - */ -static uint32_t deleteWidget_exitCallback(void* context) { - PluginData* app = context; - UNUSED(app); - //Возвращаем ID вида, в который нужно вернуться - return SENSOR_ACTIONS_VIEW; -} -/** - * @brief Обработчик нажатий на кнопку в виджете - * - * @param result Какая из кнопок была нажата - * @param type Тип нажатия - * @param context Указатель на данные плагина - */ -static void deleteWidget_callback(GuiButtonType result, InputType type, void* context) { - PluginData* app = context; - //Коротко нажата левая кнопка (Cancel) - if(result == GuiButtonTypeLeft && type == InputTypeShort) { - view_dispatcher_switch_to_view(app->view_dispatcher, SENSOR_ACTIONS_VIEW); - } - //Коротко нажата правая кнопка (Delete) - if(result == GuiButtonTypeRight && type == InputTypeShort) { - //Удаление датчика - DHTMon_sensor_delete(app->currentSensorEdit); - //Выход из меню - view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_NONE); - } -} -/** - * @brief Создание виджета удаления датчика - * - * @param app Указатель на данные плагина - */ -static void sensorDelete_widget(PluginData* app) { - //Очистка виджета - widget_reset(app->widget); - //Добавление кнопок - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Cancel", deleteWidget_callback, app); - widget_add_button_element( - app->widget, GuiButtonTypeRight, "Delete", deleteWidget_callback, app); - - char delete_str[32]; - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", app->currentSensorEdit->name); - widget_add_text_box_element( - app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false); - snprintf( - delete_str, - sizeof(delete_str), - "\e#Type:\e# %s", - app->currentSensorEdit->type ? "DHT22" : "DHT11"); - widget_add_text_box_element( - app->widget, 0, 0, 128, 47, AlignLeft, AlignCenter, delete_str, false); - snprintf( - delete_str, - sizeof(delete_str), - "\e#GPIO:\e# %s", - DHTMon_GPIO_getName(app->currentSensorEdit->GPIO)); - widget_add_text_box_element( - app->widget, 0, 0, 128, 72, AlignLeft, AlignCenter, delete_str, false); - view_set_previous_callback(widget_get_view(app->widget), deleteWidget_exitCallback); - view_dispatcher_switch_to_view(app->view_dispatcher, WIDGET_VIEW); -} - -/* ================== Меню действий ================== */ -/** - * @brief Функция обработки нажатия средней кнопки - * - * @param context Указатель на данные приложения - * @param index На каком элементе списка была нажата кнопка - */ -static void enterCallback(void* context, uint32_t index) { - PluginData* app = context; - if(index == 0) { - sensorInfo_widget(app); - } - if(index == 1) { - sensorEdit_scene(app); - } - if(index == 2) { - sensorDelete_widget(app); - } -} - -/** - * @brief Функция обработки нажатия кнопки "Назад" - * - * @param context Указатель на данные приложения - * @return ID вида в который нужно переключиться - */ -static uint32_t actions_exitCallback(void* context) { - PluginData* app = context; - UNUSED(app); - //Возвращаем ID вида, в который нужно вернуться - return MAIN_MENU_VIEW; -} - -/** - * @brief Создание списка действий с указанным датчиком - * - * @param app Указатель на данные плагина - */ -void sensorActions_sceneCreate(PluginData* app) { - variable_item_list = variable_item_list_alloc(); - //Сброс всех элементов меню - variable_item_list_reset(variable_item_list); - //Добавление элементов в список - variable_item_list_add(variable_item_list, "Info", 0, NULL, NULL); - variable_item_list_add(variable_item_list, "Edit", 0, NULL, NULL); - variable_item_list_add(variable_item_list, "Delete", 0, NULL, NULL); - - //Добавление колбека на нажатие средней кнопки - variable_item_list_set_enter_callback(variable_item_list, enterCallback, app); - - //Создание вида из списка - view = variable_item_list_get_view(variable_item_list); - //Добавление колбека на нажатие кнопки "Назад" - view_set_previous_callback(view, actions_exitCallback); - //Добавление вида в диспетчер - view_dispatcher_add_view(app->view_dispatcher, SENSOR_ACTIONS_VIEW, view); -} -void sensorActions_scene(PluginData* app) { - //Сброс выбранного пункта в ноль - variable_item_list_set_selected_item(variable_item_list, 0); - //Переключение на наш вид - view_dispatcher_switch_to_view(app->view_dispatcher, SENSOR_ACTIONS_VIEW); -} - -void sensorActions_screneRemove(void) { - variable_item_list_free(variable_item_list); -} diff --git a/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorEdit_scene.c b/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorEdit_scene.c deleted file mode 100644 index 5decac3d1..000000000 --- a/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorEdit_scene.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "../quenon_dht_mon.h" - -static VariableItem* nameItem; -static VariableItemList* variable_item_list; - -static const char* const sensorsTypes[2] = { - "DHT11", - "DHT22", -}; - -// /* ============== Добавление датчика ============== */ -static uint32_t addSensor_exitCallback(void* context) { - UNUSED(context); - DHTMon_sensors_reload(); - return VIEW_NONE; -} - -static void addSensor_sensorTypeChanged(VariableItem* item) { - uint8_t index = variable_item_get_current_value_index(item); - PluginData* app = variable_item_get_context(item); - variable_item_set_current_value_text(item, sensorsTypes[index]); - app->currentSensorEdit->type = index; -} - -static void addSensor_GPIOChanged(VariableItem* item) { - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, DHTMon_GPIO_getName(DHTMon_GPIO_from_index(index))); - PluginData* app = variable_item_get_context(item); - app->currentSensorEdit->GPIO = DHTMon_GPIO_from_index(index); -} - -static void addSensor_sensorNameChanged(void* context) { - PluginData* app = context; - variable_item_set_current_value_text(nameItem, app->currentSensorEdit->name); - view_dispatcher_switch_to_view(app->view_dispatcher, ADDSENSOR_MENU_VIEW); -} -static void addSensor_sensorNameChange(PluginData* app) { - text_input_set_header_text(app->text_input, "Sensor name"); - //По неясной мне причине в длину строки входит терминатор. Поэтому при длине 10 приходится указывать 11 - text_input_set_result_callback( - app->text_input, addSensor_sensorNameChanged, app, app->currentSensorEdit->name, 11, true); - view_dispatcher_switch_to_view(app->view_dispatcher, TEXTINPUT_VIEW); -} - -static void addSensor_enterCallback(void* context, uint32_t index) { - PluginData* app = context; - if(index == 0) { - addSensor_sensorNameChange(app); - } - if(index == 3) { - //Сохранение датчика - DHTMon_sensors_save(); - DHTMon_sensors_reload(); - view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_NONE); - } -} - -void sensorEdit_sceneCreate(PluginData* app) { - variable_item_list = variable_item_list_alloc(); - - variable_item_list_reset(variable_item_list); - - variable_item_list_set_enter_callback(variable_item_list, addSensor_enterCallback, app); - - app->view = variable_item_list_get_view(variable_item_list); - - view_set_previous_callback(app->view, addSensor_exitCallback); - - view_dispatcher_add_view(app->view_dispatcher, ADDSENSOR_MENU_VIEW, app->view); -} -void sensorEdit_scene(PluginData* app) { - //Очистка списка - variable_item_list_reset(variable_item_list); - - //Имя редактируемого датчика - nameItem = variable_item_list_add(variable_item_list, "Name: ", 1, NULL, NULL); - variable_item_set_current_value_index(nameItem, 0); - variable_item_set_current_value_text(nameItem, app->currentSensorEdit->name); - - //Тип датчика - app->item = - variable_item_list_add(variable_item_list, "Type:", 2, addSensor_sensorTypeChanged, app); - - variable_item_set_current_value_index(app->item, app->currentSensorEdit->type); - variable_item_set_current_value_text(app->item, sensorsTypes[app->currentSensorEdit->type]); - - //GPIO - app->item = - variable_item_list_add(variable_item_list, "GPIO:", 13, addSensor_GPIOChanged, app); - variable_item_set_current_value_index( - app->item, DHTMon_GPIO_to_index(app->currentSensorEdit->GPIO)); - variable_item_set_current_value_text( - app->item, DHTMon_GPIO_getName(app->currentSensorEdit->GPIO)); - variable_item_list_add(variable_item_list, "Save", 1, NULL, app); - - //Сброс выбранного пункта в ноль - variable_item_list_set_selected_item(variable_item_list, 0); - - view_dispatcher_switch_to_view(app->view_dispatcher, ADDSENSOR_MENU_VIEW); -} -void sensorEdit_sceneRemove(void) { - variable_item_list_free(variable_item_list); -} \ No newline at end of file