mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-29 02:08:10 -07:00
[DHT Monitor (By quen0n)]
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
#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);
|
||||
// }
|
||||
@@ -0,0 +1,40 @@
|
||||
#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...");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
#include "../quenon_dht_mon.h"
|
||||
|
||||
//Текущий вид
|
||||
static View* view;
|
||||
//Список
|
||||
static VariableItemList* variable_item_list;
|
||||
|
||||
/* ================== Подтверждение удаления ================== */
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t delete_exitCallback(void* context) {
|
||||
PluginData* app = context;
|
||||
UNUSED(app);
|
||||
//Возвращаем ID вида, в который нужно вернуться
|
||||
return SENSOR_ACTIONS_VIEW;
|
||||
}
|
||||
/**
|
||||
* @brief Обработчик нажатий на кнопку в виджете
|
||||
*
|
||||
* @param result Какая из кнопок была нажата
|
||||
* @param type Тип нажатия
|
||||
* @param context Указатель на данные плагина
|
||||
*/
|
||||
static void widgetCallback(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 sensorDeleteWidget(PluginData* app) {
|
||||
//Очистка виджета
|
||||
widget_reset(app->widget);
|
||||
//Добавление кнопок
|
||||
widget_add_button_element(app->widget, GuiButtonTypeLeft, "Cancel", widgetCallback, app);
|
||||
widget_add_button_element(app->widget, GuiButtonTypeRight, "Delete", widgetCallback, 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# %d",
|
||||
DHTMon_GPIO_to_int(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), delete_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) {
|
||||
sensorEdit_scene(app);
|
||||
}
|
||||
if(index == 1) {
|
||||
sensorDeleteWidget(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, "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) {
|
||||
//Переключение на наш вид
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SENSOR_ACTIONS_VIEW);
|
||||
}
|
||||
|
||||
void sensorActions_screneRemove(void) {
|
||||
variable_item_list_free(variable_item_list);
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "../quenon_dht_mon.h"
|
||||
|
||||
static VariableItem* nameItem;
|
||||
static VariableItemList* variable_item_list;
|
||||
|
||||
static const char* const sensorsTypes[2] = {
|
||||
"DHT11",
|
||||
"DHT22",
|
||||
};
|
||||
static const char* const GPIOs[13] = {
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"10",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"15",
|
||||
"16",
|
||||
"17",
|
||||
};
|
||||
|
||||
// /* ============== Добавление датчика ============== */
|
||||
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, GPIOs[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) {
|
||||
//Сохранение датчика
|
||||
//TODO: проверить правильность данных датчика
|
||||
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(nameItem, 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, GPIOs[DHTMon_GPIO_to_index(app->currentSensorEdit->GPIO)]);
|
||||
|
||||
variable_item_list_add(variable_item_list, "Save", 1, NULL, app);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, ADDSENSOR_MENU_VIEW);
|
||||
}
|
||||
void sensorEdit_sceneRemove(void) {
|
||||
variable_item_list_free(variable_item_list);
|
||||
}
|
||||
Reference in New Issue
Block a user