mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-26 03:39:58 -07:00
New plugin: Unitemp
This commit is contained in:
562
applications/plugins/unitemp/views/General_view.c
Normal file
562
applications/plugins/unitemp/views/General_view.c
Normal file
@@ -0,0 +1,562 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "UnitempViews.h"
|
||||
#include "unitemp_icons.h"
|
||||
|
||||
#include <assets_icons.h>
|
||||
|
||||
static View* view;
|
||||
|
||||
typedef enum general_views {
|
||||
G_NO_SENSORS_VIEW, //Нет датчиков
|
||||
G_LIST_VIEW, //Вид в ввиде списка
|
||||
G_CAROUSEL_VIEW, //Карусель
|
||||
} general_view;
|
||||
|
||||
typedef enum carousel_info {
|
||||
CAROUSEL_VALUES, //Отображение значений датчиков
|
||||
CAROUSEL_INFO, //Отображение информации о датчике
|
||||
} carousel_info;
|
||||
|
||||
static general_view current_view;
|
||||
|
||||
carousel_info carousel_info_selector = CAROUSEL_VALUES;
|
||||
uint8_t generalview_sensor_index = 0;
|
||||
|
||||
static void _draw_temperature(Canvas* canvas, Sensor* sensor, uint8_t x, uint8_t y, Color color) {
|
||||
//Рисование рамки
|
||||
canvas_draw_rframe(canvas, x, y, 54, 20, 3);
|
||||
|
||||
if(color == ColorBlack) {
|
||||
canvas_draw_rbox(canvas, x, y, 54, 19, 3);
|
||||
canvas_invert_color(canvas);
|
||||
} else {
|
||||
canvas_draw_rframe(canvas, x, y, 54, 19, 3);
|
||||
}
|
||||
|
||||
int8_t temp_dec = abs((int16_t)(sensor->temp * 10) % 10);
|
||||
|
||||
//Рисование иконки
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
x + 3,
|
||||
y + 3,
|
||||
(app->settings.temp_unit == UT_TEMP_CELSIUS ? &I_temp_C_11x14 : &I_temp_F_11x14));
|
||||
|
||||
if((int16_t)sensor->temp == -128 || sensor->status == UT_SENSORSTATUS_TIMEOUT) {
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
canvas_draw_str_aligned(canvas, x + 27, y + 10, AlignCenter, AlignCenter, "--");
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, x + 50, y + 10 + 3, AlignRight, AlignCenter, ". -");
|
||||
if(color == ColorBlack) canvas_invert_color(canvas);
|
||||
return;
|
||||
}
|
||||
|
||||
//Целая часть температуры
|
||||
//Костыль для отображения знака числа меньше 0
|
||||
uint8_t offset = 0;
|
||||
if(sensor->temp < 0 && sensor->temp > -1) {
|
||||
app->buff[0] = '-';
|
||||
offset = 1;
|
||||
}
|
||||
snprintf((char*)(app->buff + offset), BUFF_SIZE, "%d", (int8_t)sensor->temp);
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
canvas_draw_str_aligned(
|
||||
canvas,
|
||||
x + 27 + ((sensor->temp <= -10 || sensor->temp > 99) ? 5 : 0),
|
||||
y + 10,
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
app->buff);
|
||||
//Печать дробной части температуры в диапазоне от -9 до 99 (когда два знака в числе)
|
||||
if(sensor->temp > -10 && sensor->temp <= 99) {
|
||||
uint8_t int_len = canvas_string_width(canvas, app->buff);
|
||||
snprintf(app->buff, BUFF_SIZE, ".%d", temp_dec);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, x + 27 + int_len / 2 + 2, y + 10 + 7, app->buff);
|
||||
}
|
||||
if(color == ColorBlack) canvas_invert_color(canvas);
|
||||
}
|
||||
|
||||
static void _draw_humidity(Canvas* canvas, Sensor* sensor, const uint8_t pos[2]) {
|
||||
//Рисование рамки
|
||||
canvas_draw_rframe(canvas, pos[0], pos[1], 54, 20, 3);
|
||||
canvas_draw_rframe(canvas, pos[0], pos[1], 54, 19, 3);
|
||||
|
||||
//Рисование иконки
|
||||
canvas_draw_icon(canvas, pos[0] + 3, pos[1] + 2, &I_hum_9x15);
|
||||
|
||||
//Целая часть влажности
|
||||
snprintf(app->buff, BUFF_SIZE, "%d", (uint8_t)sensor->hum);
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
canvas_draw_str_aligned(canvas, pos[0] + 27, pos[1] + 10, AlignCenter, AlignCenter, app->buff);
|
||||
uint8_t int_len = canvas_string_width(canvas, app->buff);
|
||||
//Единица измерения
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, pos[0] + 27 + int_len / 2 + 4, pos[1] + 10 + 7, "%");
|
||||
}
|
||||
|
||||
static void _draw_pressure(Canvas* canvas, Sensor* sensor) {
|
||||
const uint8_t x = 29, y = 39;
|
||||
//Рисование рамки
|
||||
canvas_draw_rframe(canvas, x, y, 69, 20, 3);
|
||||
canvas_draw_rframe(canvas, x, y, 69, 19, 3);
|
||||
|
||||
//Рисование иконки
|
||||
canvas_draw_icon(canvas, x + 3, y + 4, &I_pressure_7x13);
|
||||
|
||||
int16_t press_int = sensor->pressure;
|
||||
int8_t press_dec = (int16_t)(sensor->temp * 10) % 10;
|
||||
|
||||
//Целая часть давления
|
||||
snprintf(app->buff, BUFF_SIZE, "%d", press_int);
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, x + 27 + ((press_int > 99) ? 5 : 0), y + 10, AlignCenter, AlignCenter, app->buff);
|
||||
//Печать дробной части давления в диапазоне от 0 до 99 (когда два знака в числе)
|
||||
if(press_int <= 99) {
|
||||
uint8_t int_len = canvas_string_width(canvas, app->buff);
|
||||
snprintf(app->buff, BUFF_SIZE, ".%d", press_dec);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, x + 27 + int_len / 2 + 2, y + 10 + 7, app->buff);
|
||||
}
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
//Единица измерения
|
||||
if(app->settings.pressure_unit == UT_PRESSURE_MM_HG) {
|
||||
canvas_draw_icon(canvas, x + 50, y + 2, &I_mm_hg_15x15);
|
||||
} else if(app->settings.pressure_unit == UT_PRESSURE_IN_HG) {
|
||||
canvas_draw_icon(canvas, x + 50, y + 2, &I_in_hg_15x15);
|
||||
} else if(app->settings.pressure_unit == UT_PRESSURE_KPA) {
|
||||
canvas_draw_str(canvas, x + 52, y + 13, "kPa");
|
||||
}
|
||||
}
|
||||
|
||||
static void _draw_singleSensor(Canvas* canvas, Sensor* sensor, const uint8_t pos[2], Color color) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
|
||||
const uint8_t max_width = 56;
|
||||
|
||||
char sensor_name[12] = {0};
|
||||
memcpy(sensor_name, sensor->name, 10);
|
||||
|
||||
if(canvas_string_width(canvas, sensor_name) > max_width) {
|
||||
uint8_t i = 10;
|
||||
while((canvas_string_width(canvas, sensor_name) > max_width - 6) && (i != 0)) {
|
||||
sensor_name[i--] = '\0';
|
||||
}
|
||||
sensor_name[++i] = '.';
|
||||
sensor_name[++i] = '.';
|
||||
}
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, pos[0] + 27, pos[1] + 3, AlignCenter, AlignCenter, sensor_name);
|
||||
_draw_temperature(canvas, sensor, pos[0], pos[1] + 8, color);
|
||||
}
|
||||
|
||||
static void _draw_view_noSensors(Canvas* canvas) {
|
||||
canvas_draw_icon(canvas, 7, 17, &I_sherlok_53x45);
|
||||
//Рисование рамки
|
||||
canvas_draw_rframe(canvas, 0, 0, 128, 63, 7);
|
||||
canvas_draw_rframe(canvas, 0, 0, 128, 64, 7);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 63, 10, AlignCenter, AlignCenter, "No sensors found");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
const uint8_t x = 65, y = 32;
|
||||
canvas_draw_rframe(canvas, x - 4, y - 11, 54, 33, 3);
|
||||
canvas_draw_rframe(canvas, x - 4, y - 11, 54, 34, 3);
|
||||
canvas_draw_str(canvas, x, y, "To add the");
|
||||
canvas_draw_str(canvas, x, y + 9, "new sensor");
|
||||
canvas_draw_str(canvas, x, y + 18, "press OK");
|
||||
|
||||
canvas_draw_icon(canvas, x + 37, y + 10, &I_Ok_btn_9x9);
|
||||
}
|
||||
|
||||
static void _draw_view_sensorsList(Canvas* canvas) {
|
||||
//Текущая страница
|
||||
uint8_t page = generalview_sensor_index / 4;
|
||||
//Количество датчиков, которые будут отображаться на странице
|
||||
uint8_t page_sensors_count;
|
||||
if((unitemp_sensors_getActiveCount() - page * 4) / 4) {
|
||||
page_sensors_count = 4;
|
||||
} else {
|
||||
page_sensors_count = (unitemp_sensors_getActiveCount() - page * 4) % 4;
|
||||
}
|
||||
|
||||
//Количество страниц
|
||||
uint8_t pages =
|
||||
unitemp_sensors_getActiveCount() / 4 + (unitemp_sensors_getActiveCount() % 4 ? 1 : 0);
|
||||
|
||||
//Стрелка влево
|
||||
if(page > 0) {
|
||||
canvas_draw_icon(canvas, 2, 32, &I_ButtonLeft_4x7);
|
||||
}
|
||||
//Стрелка вправо
|
||||
if(pages > 0 && page < pages - 1) {
|
||||
canvas_draw_icon(canvas, 122, 32, &I_ButtonRight_4x7);
|
||||
}
|
||||
|
||||
const uint8_t value_positions[][4][2] = {
|
||||
{{36, 18}}, //1 датчик
|
||||
{{7, 18}, {67, 18}}, //2 датчика
|
||||
{{7, 3}, {67, 3}, {37, 33}}, //3 датчика
|
||||
{{7, 3}, {67, 3}, {7, 33}, {67, 33}}}; //4 датчика
|
||||
//Рисование рамки
|
||||
canvas_draw_rframe(canvas, 0, 0, 128, 63, 7);
|
||||
canvas_draw_rframe(canvas, 0, 0, 128, 64, 7);
|
||||
for(uint8_t i = 0; i < page_sensors_count; i++) {
|
||||
_draw_singleSensor(
|
||||
canvas,
|
||||
unitemp_sensor_getActive(page * 4 + i),
|
||||
value_positions[page_sensors_count - 1][i],
|
||||
ColorWhite);
|
||||
}
|
||||
}
|
||||
|
||||
static void _draw_carousel_values(Canvas* canvas) {
|
||||
UnitempStatus sensor_status = unitemp_sensor_getActive(generalview_sensor_index)->status;
|
||||
if(sensor_status == UT_SENSORSTATUS_ERROR || sensor_status == UT_SENSORSTATUS_TIMEOUT) {
|
||||
const Icon* frames[] = {
|
||||
&I_flipper_happy_60x38, &I_flipper_happy_2_60x38, &I_flipper_sad_60x38};
|
||||
canvas_draw_icon(canvas, 34, 23, frames[furi_get_tick() % 2250 / 750]);
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
if(unitemp_sensor_getActive(generalview_sensor_index)->type->interface == &SINGLE_WIRE) {
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"Waiting for module on pin %d",
|
||||
((SingleWireSensor*)unitemp_sensor_getActive(generalview_sensor_index)->instance)
|
||||
->gpio->num);
|
||||
}
|
||||
if(unitemp_sensor_getActive(generalview_sensor_index)->type->interface == &ONE_WIRE) {
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"Waiting for module on pin %d",
|
||||
((OneWireSensor*)unitemp_sensor_getActive(generalview_sensor_index)->instance)
|
||||
->bus->gpio->num);
|
||||
}
|
||||
if(unitemp_sensor_getActive(generalview_sensor_index)->type->interface == &I2C) {
|
||||
snprintf(app->buff, BUFF_SIZE, "Waiting for module on I2C pins");
|
||||
}
|
||||
canvas_draw_str_aligned(canvas, 64, 19, AlignCenter, AlignCenter, app->buff);
|
||||
return;
|
||||
}
|
||||
|
||||
static const uint8_t temp_positions[3][2] = {{37, 23}, {37, 16}, {9, 16}};
|
||||
static const uint8_t hum_positions[2][2] = {{37, 38}, {65, 16}};
|
||||
//Селектор значений для отображения
|
||||
switch(unitemp_sensor_getActive(generalview_sensor_index)->type->datatype) {
|
||||
case UT_DATA_TYPE_TEMP:
|
||||
_draw_temperature(
|
||||
canvas,
|
||||
unitemp_sensor_getActive(generalview_sensor_index),
|
||||
temp_positions[0][0],
|
||||
temp_positions[0][1],
|
||||
ColorWhite);
|
||||
break;
|
||||
case UT_DATA_TYPE_TEMP_HUM:
|
||||
_draw_temperature(
|
||||
canvas,
|
||||
unitemp_sensor_getActive(generalview_sensor_index),
|
||||
temp_positions[1][0],
|
||||
temp_positions[1][1],
|
||||
ColorWhite);
|
||||
_draw_humidity(
|
||||
canvas, unitemp_sensor_getActive(generalview_sensor_index), hum_positions[0]);
|
||||
break;
|
||||
case UT_DATA_TYPE_TEMP_PRESS:
|
||||
_draw_temperature(
|
||||
canvas,
|
||||
unitemp_sensor_getActive(generalview_sensor_index),
|
||||
temp_positions[1][0],
|
||||
temp_positions[1][1],
|
||||
ColorWhite);
|
||||
_draw_pressure(canvas, unitemp_sensor_getActive(generalview_sensor_index));
|
||||
break;
|
||||
case UT_DATA_TYPE_TEMP_HUM_PRESS:
|
||||
_draw_temperature(
|
||||
canvas,
|
||||
unitemp_sensor_getActive(generalview_sensor_index),
|
||||
temp_positions[2][0],
|
||||
temp_positions[2][1],
|
||||
ColorWhite);
|
||||
_draw_humidity(
|
||||
canvas, unitemp_sensor_getActive(generalview_sensor_index), hum_positions[1]);
|
||||
_draw_pressure(canvas, unitemp_sensor_getActive(generalview_sensor_index));
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void _draw_carousel_info(Canvas* canvas) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 10, 23, "Type:");
|
||||
|
||||
if(unitemp_sensor_getActive(generalview_sensor_index)->type->interface == &ONE_WIRE) {
|
||||
OneWireSensor* s = unitemp_sensor_getActive(generalview_sensor_index)->instance;
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 10, 35, "GPIO:");
|
||||
canvas_draw_str(canvas, 10, 47, "ID:");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(
|
||||
canvas,
|
||||
41,
|
||||
23,
|
||||
unitemp_onewire_sensor_getModel(unitemp_sensor_getActive(generalview_sensor_index)));
|
||||
canvas_draw_str(canvas, 41, 35, s->bus->gpio->name);
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
s->deviceID[0],
|
||||
s->deviceID[1],
|
||||
s->deviceID[2],
|
||||
s->deviceID[3],
|
||||
s->deviceID[4],
|
||||
s->deviceID[5],
|
||||
s->deviceID[6],
|
||||
s->deviceID[7]);
|
||||
canvas_draw_str(canvas, 24, 47, app->buff);
|
||||
}
|
||||
|
||||
if(unitemp_sensor_getActive(generalview_sensor_index)->type->interface == &SINGLE_WIRE) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 10, 35, "GPIO:");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(
|
||||
canvas, 41, 23, unitemp_sensor_getActive(generalview_sensor_index)->type->typename);
|
||||
canvas_draw_str(
|
||||
canvas,
|
||||
41,
|
||||
35,
|
||||
((SingleWireSensor*)unitemp_sensor_getActive(generalview_sensor_index)->instance)
|
||||
->gpio->name);
|
||||
}
|
||||
|
||||
if(unitemp_sensor_getActive(generalview_sensor_index)->type->interface == &I2C) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 10, 35, "I2C addr:");
|
||||
canvas_draw_str(canvas, 10, 46, "SDA pin:");
|
||||
canvas_draw_str(canvas, 10, 58, "SCL pin:");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(
|
||||
canvas, 41, 23, unitemp_sensor_getActive(generalview_sensor_index)->type->typename);
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"0x%02X",
|
||||
((I2CSensor*)unitemp_sensor_getActive(generalview_sensor_index)->instance)
|
||||
->currentI2CAdr);
|
||||
canvas_draw_str(canvas, 57, 35, app->buff);
|
||||
canvas_draw_str(canvas, 54, 46, "15 (C0)");
|
||||
canvas_draw_str(canvas, 54, 58, "16 (C1)");
|
||||
}
|
||||
}
|
||||
static void _draw_view_sensorsCarousel(Canvas* canvas) {
|
||||
//Рисование рамки
|
||||
canvas_draw_rframe(canvas, 0, 0, 128, 63, 7);
|
||||
canvas_draw_rframe(canvas, 0, 0, 128, 64, 7);
|
||||
|
||||
//Печать имени
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas,
|
||||
64,
|
||||
7,
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
unitemp_sensor_getActive(generalview_sensor_index)->name);
|
||||
//Подчёркивание
|
||||
uint8_t line_len =
|
||||
canvas_string_width(canvas, unitemp_sensor_getActive(generalview_sensor_index)->name) + 2;
|
||||
canvas_draw_line(canvas, 64 - line_len / 2, 12, 64 + line_len / 2, 12);
|
||||
|
||||
//Стрелка вправо
|
||||
if(unitemp_sensors_getTypesCount() > 0 &&
|
||||
generalview_sensor_index < unitemp_sensors_getActiveCount() - 1) {
|
||||
canvas_draw_icon(canvas, 122, 29, &I_ButtonRight_4x7);
|
||||
}
|
||||
//Стрелка влево
|
||||
if(generalview_sensor_index > 0) {
|
||||
canvas_draw_icon(canvas, 2, 29, &I_ButtonLeft_4x7);
|
||||
}
|
||||
|
||||
switch(carousel_info_selector) {
|
||||
case CAROUSEL_VALUES:
|
||||
_draw_carousel_values(canvas);
|
||||
break;
|
||||
case CAROUSEL_INFO:
|
||||
_draw_carousel_info(canvas);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _draw_callback(Canvas* canvas, void* _model) {
|
||||
UNUSED(_model);
|
||||
|
||||
app->sensors_ready = true;
|
||||
|
||||
uint8_t sensors_count = unitemp_sensors_getActiveCount();
|
||||
|
||||
if(generalview_sensor_index + 1 > sensors_count) generalview_sensor_index = 0;
|
||||
|
||||
if(sensors_count == 0) {
|
||||
current_view = G_NO_SENSORS_VIEW;
|
||||
_draw_view_noSensors(canvas);
|
||||
} else {
|
||||
if(sensors_count == 1) current_view = G_CAROUSEL_VIEW;
|
||||
if(current_view == G_NO_SENSORS_VIEW) current_view = G_CAROUSEL_VIEW;
|
||||
if(current_view == G_LIST_VIEW) _draw_view_sensorsList(canvas);
|
||||
if(current_view == G_CAROUSEL_VIEW) _draw_view_sensorsCarousel(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
static bool _input_callback(InputEvent* event, void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
//Обработка короткого нажатия "ок"
|
||||
if(event->key == InputKeyOk && event->type == InputTypeShort) {
|
||||
//Меню добавления датчика при их отсутствии
|
||||
if(current_view == G_NO_SENSORS_VIEW) {
|
||||
app->sensors_ready = false;
|
||||
unitemp_SensorsList_switch();
|
||||
} else if(current_view == G_LIST_VIEW) {
|
||||
//Переход в главное меню при выключенном селекторе
|
||||
app->sensors_ready = false;
|
||||
unitemp_MainMenu_switch();
|
||||
} else if(current_view == G_CAROUSEL_VIEW) {
|
||||
app->sensors_ready = false;
|
||||
unitemp_SensorActions_switch(unitemp_sensor_getActive(generalview_sensor_index));
|
||||
}
|
||||
}
|
||||
|
||||
//Обработка короткого нажатия "вниз"
|
||||
if(event->key == InputKeyDown && event->type == InputTypeShort) {
|
||||
//Переход из значений в информацию в карусели
|
||||
if(current_view == G_CAROUSEL_VIEW && carousel_info_selector == CAROUSEL_VALUES) {
|
||||
carousel_info_selector = CAROUSEL_INFO;
|
||||
return true;
|
||||
}
|
||||
//Переход в карусель из списка
|
||||
if(current_view == G_LIST_VIEW) {
|
||||
current_view = G_CAROUSEL_VIEW;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//Обработка короткого нажатия "вверх"
|
||||
if(event->key == InputKeyUp && event->type == InputTypeShort) {
|
||||
//Переход из информации в значения в карусели
|
||||
if(current_view == G_CAROUSEL_VIEW && carousel_info_selector == CAROUSEL_INFO) {
|
||||
carousel_info_selector = CAROUSEL_VALUES;
|
||||
return true;
|
||||
}
|
||||
//Переход в список из карусели
|
||||
if(current_view == G_CAROUSEL_VIEW && carousel_info_selector == CAROUSEL_VALUES &&
|
||||
unitemp_sensors_getActiveCount() > 1) {
|
||||
current_view = G_LIST_VIEW;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//Обработка короткого нажатия "вправо"
|
||||
if(event->key == InputKeyRight && event->type == InputTypeShort) {
|
||||
//Пролистывание карусели вперёд
|
||||
if(current_view == G_CAROUSEL_VIEW) {
|
||||
if(++generalview_sensor_index >= unitemp_sensors_getActiveCount()) {
|
||||
generalview_sensor_index = 0;
|
||||
if(carousel_info_selector == CAROUSEL_VALUES) current_view = G_LIST_VIEW;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//Пролистывание списка вперёд
|
||||
if(current_view == G_LIST_VIEW) {
|
||||
generalview_sensor_index += 4;
|
||||
if(generalview_sensor_index >= unitemp_sensors_getActiveCount()) {
|
||||
generalview_sensor_index = 0;
|
||||
current_view = G_CAROUSEL_VIEW;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//Обработка короткого нажатия "влево"
|
||||
if(event->key == InputKeyLeft && event->type == InputTypeShort) {
|
||||
//Пролистывание карусели назад
|
||||
if(current_view == G_CAROUSEL_VIEW) {
|
||||
if(--generalview_sensor_index >= unitemp_sensors_getActiveCount()) {
|
||||
generalview_sensor_index = unitemp_sensors_getActiveCount() - 1;
|
||||
if(carousel_info_selector == CAROUSEL_VALUES) current_view = G_LIST_VIEW;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//Пролистывание списка назад
|
||||
if(current_view == G_LIST_VIEW) {
|
||||
generalview_sensor_index -= 4;
|
||||
if(generalview_sensor_index >= unitemp_sensors_getActiveCount()) {
|
||||
generalview_sensor_index = unitemp_sensors_getActiveCount() - 1;
|
||||
current_view = G_CAROUSEL_VIEW;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//Обработка короткого нажатия "назад"
|
||||
if(event->key == InputKeyBack && event->type == InputTypeShort) {
|
||||
//Выход из приложения при карусели или отсутствии датчиков
|
||||
if(current_view == G_NO_SENSORS_VIEW ||
|
||||
((current_view == G_CAROUSEL_VIEW) && (carousel_info_selector == CAROUSEL_VALUES))) {
|
||||
app->processing = false;
|
||||
return true;
|
||||
}
|
||||
//Переключение селектора вида карусели
|
||||
if((current_view == G_CAROUSEL_VIEW) && (carousel_info_selector != CAROUSEL_VALUES)) {
|
||||
carousel_info_selector = CAROUSEL_VALUES;
|
||||
return true;
|
||||
}
|
||||
//Переход в карусель из списка
|
||||
if(current_view == G_LIST_VIEW) {
|
||||
current_view = G_CAROUSEL_VIEW;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void unitemp_General_alloc(void) {
|
||||
view = view_alloc();
|
||||
view_set_context(view, app);
|
||||
view_set_draw_callback(view, _draw_callback);
|
||||
view_set_input_callback(view, _input_callback);
|
||||
|
||||
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, UnitempViewGeneral);
|
||||
}
|
||||
|
||||
void unitemp_General_free(void) {
|
||||
view_free(view);
|
||||
}
|
||||
99
applications/plugins/unitemp/views/MainMenu_view.c
Normal file
99
applications/plugins/unitemp/views/MainMenu_view.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "UnitempViews.h"
|
||||
#include <gui/modules/variable_item_list.h>
|
||||
|
||||
//Текущий вид
|
||||
static View* view;
|
||||
//Список
|
||||
static VariableItemList* variable_item_list;
|
||||
|
||||
#define VIEW_ID UnitempViewMainMenu
|
||||
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t _exit_callback(void* context) {
|
||||
UNUSED(context);
|
||||
//Возврат в общий вид
|
||||
return UnitempViewGeneral;
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки нажатия средней кнопки
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @param index На каком элементе списка была нажата кнопка
|
||||
*/
|
||||
static void _enter_callback(void* context, uint32_t index) {
|
||||
UNUSED(context);
|
||||
if(index == 0) { //Add new sensor
|
||||
unitemp_SensorsList_switch();
|
||||
}
|
||||
if(index == 1) { //Settings
|
||||
unitemp_Settings_switch();
|
||||
}
|
||||
if(index == 2) {
|
||||
unitemp_widget_help_switch();
|
||||
}
|
||||
if(index == 3) {
|
||||
unitemp_widget_about_switch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Создание списка действий с указанным датчиком
|
||||
*/
|
||||
void unitemp_MainMenu_alloc(void) {
|
||||
variable_item_list = variable_item_list_alloc();
|
||||
//Сброс всех элементов меню
|
||||
variable_item_list_reset(variable_item_list);
|
||||
|
||||
variable_item_list_add(variable_item_list, "Add new sensor", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "Settings", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "Help", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "About", 1, NULL, NULL);
|
||||
|
||||
//Добавление колбека на нажатие средней кнопки
|
||||
variable_item_list_set_enter_callback(variable_item_list, _enter_callback, app);
|
||||
|
||||
//Создание вида из списка
|
||||
view = variable_item_list_get_view(variable_item_list);
|
||||
//Добавление колбека на нажатие кнопки "Назад"
|
||||
view_set_previous_callback(view, _exit_callback);
|
||||
//Добавление вида в диспетчер
|
||||
view_dispatcher_add_view(app->view_dispatcher, VIEW_ID, view);
|
||||
}
|
||||
|
||||
void unitemp_MainMenu_switch(void) {
|
||||
//Обнуление последнего выбранного пункта
|
||||
variable_item_list_set_selected_item(variable_item_list, 0);
|
||||
//Переключение в вид
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
|
||||
void unitemp_MainMenu_free(void) {
|
||||
//Очистка списка элементов
|
||||
variable_item_list_free(variable_item_list);
|
||||
//Очистка вида
|
||||
view_free(view);
|
||||
//Удаление вида после обработки
|
||||
view_dispatcher_remove_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
50
applications/plugins/unitemp/views/Popup_view.c
Normal file
50
applications/plugins/unitemp/views/Popup_view.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
125
applications/plugins/unitemp/views/SensorActions_view.c
Normal file
125
applications/plugins/unitemp/views/SensorActions_view.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "UnitempViews.h"
|
||||
#include <gui/modules/variable_item_list.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//Текущий вид
|
||||
static View* view;
|
||||
//Список
|
||||
static VariableItemList* variable_item_list;
|
||||
//Текущий датчик
|
||||
static Sensor* current_sensor;
|
||||
|
||||
typedef enum carousel_info {
|
||||
CAROUSEL_VALUES, //Отображение значений датчиков
|
||||
CAROUSEL_INFO, //Отображение информации о датчике
|
||||
} carousel_info;
|
||||
extern carousel_info carousel_info_selector;
|
||||
|
||||
#define VIEW_ID UnitempViewSensorActions
|
||||
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t _exit_callback(void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
//Возврат предыдущий вид
|
||||
return UnitempViewGeneral;
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки нажатия средней кнопки
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @param index На каком элементе списка была нажата кнопка
|
||||
*/
|
||||
static void _enter_callback(void* context, uint32_t index) {
|
||||
UNUSED(context);
|
||||
switch(index) {
|
||||
case 0:
|
||||
carousel_info_selector = CAROUSEL_INFO;
|
||||
unitemp_General_switch();
|
||||
return;
|
||||
case 1:
|
||||
unitemp_SensorEdit_switch(current_sensor);
|
||||
break;
|
||||
case 2:
|
||||
unitemp_widget_delete_switch(current_sensor);
|
||||
break;
|
||||
case 3:
|
||||
unitemp_SensorsList_switch();
|
||||
break;
|
||||
case 4:
|
||||
unitemp_Settings_switch();
|
||||
break;
|
||||
case 5:
|
||||
unitemp_widget_help_switch();
|
||||
break;
|
||||
case 6:
|
||||
unitemp_widget_about_switch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Создание меню действий с датчиком
|
||||
*/
|
||||
void unitemp_SensorActions_alloc(void) {
|
||||
variable_item_list = variable_item_list_alloc();
|
||||
//Сброс всех элементов меню
|
||||
variable_item_list_reset(variable_item_list);
|
||||
|
||||
variable_item_list_add(variable_item_list, "Info", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "Edit", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "Delete", 1, NULL, NULL);
|
||||
|
||||
variable_item_list_add(variable_item_list, "Add new sensor", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "Settings", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "Help", 1, NULL, NULL);
|
||||
variable_item_list_add(variable_item_list, "About", 1, NULL, NULL);
|
||||
|
||||
//Добавление колбека на нажатие средней кнопки
|
||||
variable_item_list_set_enter_callback(variable_item_list, _enter_callback, app);
|
||||
//Создание вида из списка
|
||||
view = variable_item_list_get_view(variable_item_list);
|
||||
//Добавление колбека на нажатие кнопки "Назад"
|
||||
view_set_previous_callback(view, _exit_callback);
|
||||
//Добавление вида в диспетчер
|
||||
view_dispatcher_add_view(app->view_dispatcher, VIEW_ID, view);
|
||||
}
|
||||
|
||||
void unitemp_SensorActions_switch(Sensor* sensor) {
|
||||
current_sensor = sensor;
|
||||
//Обнуление последнего выбранного пункта
|
||||
variable_item_list_set_selected_item(variable_item_list, 0);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
|
||||
void unitemp_SensorActions_free(void) {
|
||||
//Очистка списка элементов
|
||||
variable_item_list_free(variable_item_list);
|
||||
//Очистка вида
|
||||
view_free(view);
|
||||
//Удаление вида после обработки
|
||||
view_dispatcher_remove_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
376
applications/plugins/unitemp/views/SensorEdit_view.c
Normal file
376
applications/plugins/unitemp/views/SensorEdit_view.c
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "UnitempViews.h"
|
||||
#include <gui/modules/variable_item_list.h>
|
||||
|
||||
#include "../interfaces/SingleWireSensor.h"
|
||||
#include "../interfaces/OneWireSensor.h"
|
||||
#include "../interfaces/I2CSensor.h"
|
||||
|
||||
//Текущий вид
|
||||
static View* view;
|
||||
//Список
|
||||
static VariableItemList* variable_item_list;
|
||||
//Текущий редактируемый датчик
|
||||
static Sensor* editable_sensor;
|
||||
//Изначальный GPIO датчика
|
||||
static const GPIO* initial_gpio = NULL;
|
||||
|
||||
//Элемент списка - имя датчика
|
||||
static VariableItem* sensor_name_item;
|
||||
//Элемент списка - адрес датчика one wire
|
||||
static VariableItem* onewire_addr_item;
|
||||
//Элемент списка - адрес датчика one wire
|
||||
static VariableItem* onewire_type_item;
|
||||
//Элемент списка - смещение температуры
|
||||
VariableItem* temp_offset_item;
|
||||
|
||||
#define OFFSET_BUFF_SIZE 5
|
||||
//Буффер для текста смещения
|
||||
static char* offset_buff;
|
||||
|
||||
extern uint8_t generalview_sensor_index;
|
||||
|
||||
#define VIEW_ID UnitempViewSensorEdit
|
||||
|
||||
bool _onewire_id_exist(uint8_t* id) {
|
||||
if(id == NULL) return false;
|
||||
for(uint8_t i = 0; i < unitemp_sensors_getActiveCount(); i++) {
|
||||
if(unitemp_sensor_getActive(i)->type == &Dallas) {
|
||||
if(unitemp_onewire_id_compare(
|
||||
id, ((OneWireSensor*)(unitemp_sensor_getActive(i)->instance))->deviceID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void _onewire_scan(void) {
|
||||
OneWireSensor* ow_sensor = editable_sensor->instance;
|
||||
#ifdef UNITEMP_DEBUG
|
||||
FURI_LOG_D(
|
||||
APP_NAME,
|
||||
"devices on wire %d: %d",
|
||||
ow_sensor->bus->gpio->num,
|
||||
ow_sensor->bus->device_count);
|
||||
#endif
|
||||
|
||||
//Сканирование шины one wire
|
||||
unitemp_onewire_bus_init(ow_sensor->bus);
|
||||
uint8_t* id = NULL;
|
||||
do {
|
||||
id = unitemp_onewire_bus_enum_next(ow_sensor->bus);
|
||||
} while(_onewire_id_exist(id));
|
||||
|
||||
if(id == NULL) {
|
||||
unitemp_onewire_bus_enum_init();
|
||||
id = unitemp_onewire_bus_enum_next(ow_sensor->bus);
|
||||
if(_onewire_id_exist(id)) {
|
||||
do {
|
||||
id = unitemp_onewire_bus_enum_next(ow_sensor->bus);
|
||||
} while(_onewire_id_exist(id) && id != NULL);
|
||||
}
|
||||
if(id == NULL) {
|
||||
memset(ow_sensor->deviceID, 0, 8);
|
||||
ow_sensor->familyCode = 0;
|
||||
unitemp_onewire_bus_deinit(ow_sensor->bus);
|
||||
variable_item_set_current_value_text(onewire_addr_item, "empty");
|
||||
variable_item_set_current_value_text(
|
||||
onewire_type_item, unitemp_onewire_sensor_getModel(editable_sensor));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unitemp_onewire_bus_deinit(ow_sensor->bus);
|
||||
|
||||
memcpy(ow_sensor->deviceID, id, 8);
|
||||
ow_sensor->familyCode = id[0];
|
||||
#ifdef UNITEMP_DEBUG
|
||||
FURI_LOG_D(
|
||||
APP_NAME,
|
||||
"Found sensor's ID: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
id[0],
|
||||
id[1],
|
||||
id[2],
|
||||
id[3],
|
||||
id[4],
|
||||
id[5],
|
||||
id[6],
|
||||
id[7]);
|
||||
#endif
|
||||
|
||||
if(ow_sensor->familyCode != 0) {
|
||||
char id_buff[10];
|
||||
snprintf(
|
||||
id_buff,
|
||||
10,
|
||||
"%02X%02X%02X",
|
||||
ow_sensor->deviceID[1],
|
||||
ow_sensor->deviceID[2],
|
||||
ow_sensor->deviceID[3]);
|
||||
//А больше не лезет(
|
||||
variable_item_set_current_value_text(onewire_addr_item, id_buff);
|
||||
} else {
|
||||
variable_item_set_current_value_text(onewire_addr_item, "empty");
|
||||
}
|
||||
variable_item_set_current_value_text(
|
||||
onewire_type_item, unitemp_onewire_sensor_getModel(editable_sensor));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t _exit_callback(void* context) {
|
||||
UNUSED(context);
|
||||
editable_sensor->status = UT_SENSORSTATUS_TIMEOUT;
|
||||
if(!unitemp_sensor_isContains(editable_sensor)) unitemp_sensor_free(editable_sensor);
|
||||
unitemp_sensors_reload();
|
||||
//Возврат предыдущий вид
|
||||
return UnitempViewGeneral;
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки нажатия средней кнопки
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @param index На каком элементе списка была нажата кнопка
|
||||
*/
|
||||
static void _enter_callback(void* context, uint32_t index) {
|
||||
UNUSED(context);
|
||||
//Смена имени
|
||||
if(index == 0) {
|
||||
unitemp_SensorNameEdit_switch(editable_sensor);
|
||||
}
|
||||
//Сохранение
|
||||
if((index == 4 && editable_sensor->type->interface != &ONE_WIRE) ||
|
||||
(index == 5 && editable_sensor->type->interface == &ONE_WIRE)) {
|
||||
//Выход если датчик one wire не имеет ID
|
||||
if(editable_sensor->type->interface == &ONE_WIRE &&
|
||||
((OneWireSensor*)(editable_sensor->instance))->familyCode == 0) {
|
||||
return;
|
||||
}
|
||||
if(initial_gpio != NULL) {
|
||||
unitemp_gpio_unlock(initial_gpio);
|
||||
initial_gpio = NULL;
|
||||
}
|
||||
editable_sensor->status = UT_SENSORSTATUS_TIMEOUT;
|
||||
if(!unitemp_sensor_isContains(editable_sensor)) unitemp_sensors_add(editable_sensor);
|
||||
unitemp_sensors_save();
|
||||
unitemp_sensors_reload();
|
||||
|
||||
generalview_sensor_index = unitemp_sensors_getActiveCount() - 1;
|
||||
unitemp_General_switch();
|
||||
}
|
||||
|
||||
//Адрес устройства на шине one wire
|
||||
if(index == 4 && editable_sensor->type->interface == &ONE_WIRE) {
|
||||
_onewire_scan();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция обработки изменения значения GPIO
|
||||
*
|
||||
* @param item Указатель на элемент списка
|
||||
*/
|
||||
static void _gpio_change_callback(VariableItem* item) {
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
if(editable_sensor->type->interface == &SINGLE_WIRE) {
|
||||
SingleWireSensor* instance = editable_sensor->instance;
|
||||
instance->gpio =
|
||||
unitemp_gpio_getAviablePort(editable_sensor->type->interface, index, initial_gpio);
|
||||
variable_item_set_current_value_text(item, instance->gpio->name);
|
||||
}
|
||||
if(editable_sensor->type->interface == &ONE_WIRE) {
|
||||
OneWireSensor* instance = editable_sensor->instance;
|
||||
instance->bus->gpio =
|
||||
unitemp_gpio_getAviablePort(editable_sensor->type->interface, index, NULL);
|
||||
variable_item_set_current_value_text(item, instance->bus->gpio->name);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки изменения значения GPIO
|
||||
*
|
||||
* @param item Указатель на элемент списка
|
||||
*/
|
||||
static void _i2caddr_change_callback(VariableItem* item) {
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
((I2CSensor*)editable_sensor->instance)->currentI2CAdr =
|
||||
((I2CSensor*)editable_sensor->instance)->minI2CAdr + index;
|
||||
char buff[5];
|
||||
snprintf(buff, 5, "0x%2X", ((I2CSensor*)editable_sensor->instance)->currentI2CAdr);
|
||||
variable_item_set_current_value_text(item, buff);
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки изменения значения имени датчика
|
||||
*
|
||||
* @param item Указатель на элемент списка
|
||||
*/
|
||||
static void _name_change_callback(VariableItem* item) {
|
||||
variable_item_set_current_value_index(item, 0);
|
||||
unitemp_SensorNameEdit_switch(editable_sensor);
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки изменения значения адреса датчика one wire
|
||||
*
|
||||
* @param item Указатель на элемент списка
|
||||
*/
|
||||
static void _onwire_addr_change_callback(VariableItem* item) {
|
||||
variable_item_set_current_value_index(item, 0);
|
||||
_onewire_scan();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция обработки изменения значения смещения температуры
|
||||
*
|
||||
* @param item Указатель на элемент списка
|
||||
*/
|
||||
static void _offset_change_callback(VariableItem* item) {
|
||||
editable_sensor->temp_offset = variable_item_get_current_value_index(item) - 20;
|
||||
snprintf(
|
||||
offset_buff, OFFSET_BUFF_SIZE, "%+1.1f", (double)(editable_sensor->temp_offset / 10.0));
|
||||
variable_item_set_current_value_text(item, offset_buff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Создание меню редактирования датчка
|
||||
*/
|
||||
void unitemp_SensorEdit_alloc(void) {
|
||||
variable_item_list = variable_item_list_alloc();
|
||||
//Сброс всех элементов меню
|
||||
variable_item_list_reset(variable_item_list);
|
||||
|
||||
//Добавление колбека на нажатие средней кнопки
|
||||
variable_item_list_set_enter_callback(variable_item_list, _enter_callback, app);
|
||||
|
||||
//Создание вида из списка
|
||||
view = variable_item_list_get_view(variable_item_list);
|
||||
//Добавление колбека на нажатие кнопки "Назад"
|
||||
view_set_previous_callback(view, _exit_callback);
|
||||
//Добавление вида в диспетчер
|
||||
view_dispatcher_add_view(app->view_dispatcher, VIEW_ID, view);
|
||||
|
||||
offset_buff = malloc(OFFSET_BUFF_SIZE);
|
||||
}
|
||||
|
||||
void unitemp_SensorEdit_switch(Sensor* sensor) {
|
||||
editable_sensor = sensor;
|
||||
|
||||
editable_sensor->status = UT_SENSORSTATUS_INACTIVE;
|
||||
|
||||
//Сброс всех элементов меню
|
||||
variable_item_list_reset(variable_item_list);
|
||||
//Обнуление последнего выбранного пункта
|
||||
variable_item_list_set_selected_item(variable_item_list, 0);
|
||||
|
||||
//Имя датчика
|
||||
sensor_name_item = variable_item_list_add(
|
||||
variable_item_list, "Name", strlen(sensor->name) > 7 ? 1 : 2, _name_change_callback, NULL);
|
||||
variable_item_set_current_value_index(sensor_name_item, 0);
|
||||
variable_item_set_current_value_text(sensor_name_item, sensor->name);
|
||||
|
||||
//Тип датчика (не редактируется)
|
||||
onewire_type_item = variable_item_list_add(variable_item_list, "Type", 1, NULL, NULL);
|
||||
variable_item_set_current_value_index(onewire_type_item, 0);
|
||||
variable_item_set_current_value_text(
|
||||
onewire_type_item,
|
||||
(sensor->type->interface == &ONE_WIRE ? unitemp_onewire_sensor_getModel(editable_sensor) :
|
||||
sensor->type->typename));
|
||||
//Смещение температуры
|
||||
temp_offset_item = variable_item_list_add(
|
||||
variable_item_list, "Temp. offset", 41, _offset_change_callback, NULL);
|
||||
variable_item_set_current_value_index(temp_offset_item, sensor->temp_offset + 20);
|
||||
snprintf(
|
||||
offset_buff, OFFSET_BUFF_SIZE, "%+1.1f", (double)(editable_sensor->temp_offset / 10.0));
|
||||
variable_item_set_current_value_text(temp_offset_item, offset_buff);
|
||||
|
||||
//Порт подключения датчка (для one wire и single wire)
|
||||
if(sensor->type->interface == &ONE_WIRE || sensor->type->interface == &SINGLE_WIRE) {
|
||||
if(sensor->type->interface == &ONE_WIRE) {
|
||||
initial_gpio = ((OneWireSensor*)editable_sensor->instance)->bus->gpio;
|
||||
} else {
|
||||
initial_gpio = ((SingleWireSensor*)editable_sensor->instance)->gpio;
|
||||
}
|
||||
|
||||
uint8_t aviable_gpio_count =
|
||||
unitemp_gpio_getAviablePortsCount(sensor->type->interface, initial_gpio);
|
||||
VariableItem* item = variable_item_list_add(
|
||||
variable_item_list, "GPIO", aviable_gpio_count, _gpio_change_callback, app);
|
||||
|
||||
uint8_t gpio_index = 0;
|
||||
if(unitemp_sensor_isContains(editable_sensor)) {
|
||||
for(uint8_t i = 0; i < aviable_gpio_count; i++) {
|
||||
if(unitemp_gpio_getAviablePort(sensor->type->interface, i, initial_gpio) ==
|
||||
initial_gpio) {
|
||||
gpio_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
variable_item_set_current_value_index(item, gpio_index);
|
||||
variable_item_set_current_value_text(
|
||||
item,
|
||||
unitemp_gpio_getAviablePort(sensor->type->interface, gpio_index, initial_gpio)->name);
|
||||
}
|
||||
//Адрес устройства на шине I2C (для датчиков I2C)
|
||||
if(sensor->type->interface == &I2C) {
|
||||
VariableItem* item = variable_item_list_add(
|
||||
variable_item_list,
|
||||
"I2C address",
|
||||
((I2CSensor*)sensor->instance)->maxI2CAdr - ((I2CSensor*)sensor->instance)->minI2CAdr +
|
||||
1,
|
||||
_i2caddr_change_callback,
|
||||
app);
|
||||
snprintf(app->buff, 5, "0x%2X", ((I2CSensor*)sensor->instance)->currentI2CAdr);
|
||||
variable_item_set_current_value_text(item, app->buff);
|
||||
}
|
||||
|
||||
//Адрес устройства на шине one wire (для датчиков one wire)
|
||||
if(sensor->type->interface == &ONE_WIRE) {
|
||||
onewire_addr_item = variable_item_list_add(
|
||||
variable_item_list, "Address", 2, _onwire_addr_change_callback, NULL);
|
||||
OneWireSensor* ow_sensor = sensor->instance;
|
||||
if(ow_sensor->familyCode == 0) {
|
||||
variable_item_set_current_value_text(onewire_addr_item, "Scan");
|
||||
} else {
|
||||
snprintf(
|
||||
app->buff,
|
||||
10,
|
||||
"%02X%02X%02X",
|
||||
ow_sensor->deviceID[1],
|
||||
ow_sensor->deviceID[2],
|
||||
ow_sensor->deviceID[3]);
|
||||
variable_item_set_current_value_text(onewire_addr_item, app->buff);
|
||||
}
|
||||
}
|
||||
variable_item_list_add(variable_item_list, "Save", 1, NULL, NULL);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
|
||||
void unitemp_SensorEdit_free(void) {
|
||||
//Очистка списка элементов
|
||||
variable_item_list_free(variable_item_list);
|
||||
//Очистка вида
|
||||
view_free(view);
|
||||
//Удаление вида после обработки
|
||||
view_dispatcher_remove_view(app->view_dispatcher, VIEW_ID);
|
||||
free(offset_buff);
|
||||
}
|
||||
46
applications/plugins/unitemp/views/SensorNameEdit_view.c
Normal file
46
applications/plugins/unitemp/views/SensorNameEdit_view.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "UnitempViews.h"
|
||||
#include <gui/modules/text_input.h>
|
||||
|
||||
//Окно ввода текста
|
||||
static TextInput* text_input;
|
||||
//Текущий редактируемый датчик
|
||||
static Sensor* editable_sensor;
|
||||
|
||||
#define VIEW_ID UnitempViewSensorNameEdit
|
||||
|
||||
static void _sensor_name_changed_callback(void* context) {
|
||||
UNUSED(context);
|
||||
unitemp_SensorEdit_switch(editable_sensor);
|
||||
}
|
||||
|
||||
void unitemp_SensorNameEdit_alloc(void) {
|
||||
text_input = text_input_alloc();
|
||||
view_dispatcher_add_view(app->view_dispatcher, VIEW_ID, text_input_get_view(text_input));
|
||||
text_input_set_header_text(text_input, "Sensor name");
|
||||
}
|
||||
void unitemp_SensorNameEdit_switch(Sensor* sensor) {
|
||||
editable_sensor = sensor;
|
||||
text_input_set_result_callback(
|
||||
text_input, _sensor_name_changed_callback, app, sensor->name, 11, true);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
void unitemp_SensorNameEdit_free(void) {
|
||||
text_input_free(text_input);
|
||||
}
|
||||
162
applications/plugins/unitemp/views/SensorsList_view.c
Normal file
162
applications/plugins/unitemp/views/SensorsList_view.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#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 UnitempViewSensorsList
|
||||
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t _exit_callback(void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
//Возврат предыдущий вид
|
||||
return UnitempViewGeneral;
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки нажатия средней кнопки
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @param index На каком элементе списка была нажата кнопка
|
||||
*/
|
||||
static void _enter_callback(void* context, uint32_t index) {
|
||||
UNUSED(context);
|
||||
if(index == unitemp_sensors_getTypesCount()) {
|
||||
unitemp_widget_help_switch();
|
||||
return;
|
||||
}
|
||||
|
||||
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(
|
||||
args,
|
||||
4,
|
||||
"%d",
|
||||
unitemp_gpio_toInt(unitemp_gpio_getAviablePort(type->interface, 0, NULL)));
|
||||
}
|
||||
//Выбор первого доступного порта для датчика one wire и запись нулевого ID
|
||||
if(type->interface == &ONE_WIRE) {
|
||||
snprintf(
|
||||
args,
|
||||
21,
|
||||
"%d %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
unitemp_gpio_toInt(unitemp_gpio_getAviablePort(type->interface, 0, NULL)),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
//Для I2C адрес выберется автоматически
|
||||
|
||||
unitemp_SensorEdit_switch(unitemp_sensor_alloc(sensor_name, type, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Создание меню редактирования настроек
|
||||
*/
|
||||
void unitemp_SensorsList_alloc(void) {
|
||||
variable_item_list = variable_item_list_alloc();
|
||||
//Сброс всех элементов меню
|
||||
variable_item_list_reset(variable_item_list);
|
||||
|
||||
//Добавление в список доступных датчиков
|
||||
for(uint8_t i = 0; i < unitemp_sensors_getTypesCount(); i++) {
|
||||
if(unitemp_sensors_getTypes()[i]->altname == NULL) {
|
||||
variable_item_list_add(
|
||||
variable_item_list, unitemp_sensors_getTypes()[i]->typename, 1, NULL, app);
|
||||
} else {
|
||||
variable_item_list_add(
|
||||
variable_item_list, unitemp_sensors_getTypes()[i]->altname, 1, NULL, app);
|
||||
}
|
||||
}
|
||||
variable_item_list_add(variable_item_list, "I don't know what to choose", 1, NULL, app);
|
||||
|
||||
//Добавление колбека на нажатие средней кнопки
|
||||
variable_item_list_set_enter_callback(variable_item_list, _enter_callback, app);
|
||||
|
||||
//Создание вида из списка
|
||||
view = variable_item_list_get_view(variable_item_list);
|
||||
//Добавление колбека на нажатие кнопки "Назад"
|
||||
view_set_previous_callback(view, _exit_callback);
|
||||
//Добавление вида в диспетчер
|
||||
view_dispatcher_add_view(app->view_dispatcher, VIEW_ID, view);
|
||||
}
|
||||
|
||||
void unitemp_SensorsList_switch(void) {
|
||||
//Обнуление последнего выбранного пункта
|
||||
variable_item_list_set_selected_item(variable_item_list, 0);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
|
||||
void unitemp_SensorsList_free(void) {
|
||||
//Очистка списка элементов
|
||||
variable_item_list_free(variable_item_list);
|
||||
//Очистка вида
|
||||
view_free(view);
|
||||
//Удаление вида после обработки
|
||||
view_dispatcher_remove_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
152
applications/plugins/unitemp/views/Settings_view.c
Normal file
152
applications/plugins/unitemp/views/Settings_view.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "UnitempViews.h"
|
||||
#include <gui/modules/variable_item_list.h>
|
||||
|
||||
//Текущий вид
|
||||
static View* view;
|
||||
//Список
|
||||
static VariableItemList* variable_item_list;
|
||||
|
||||
static const char states[2][9] = {"Auto", "Infinity"};
|
||||
static const char temp_units[UT_TEMP_COUNT][3] = {"*C", "*F"};
|
||||
static const char pressure_units[UT_PRESSURE_COUNT][6] = {"mm Hg", "in Hg", "kPa"};
|
||||
|
||||
//Элемент списка - бесконечная подсветка
|
||||
VariableItem* infinity_backlight_item;
|
||||
//Единица измерения температуры
|
||||
VariableItem* temperature_unit_item;
|
||||
//Единица измерения давления
|
||||
VariableItem* pressure_unit_item;
|
||||
#define VIEW_ID UnitempViewSettings
|
||||
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t _exit_callback(void* context) {
|
||||
UNUSED(context);
|
||||
//Костыль с зависающей подсветкой
|
||||
if((bool)variable_item_get_current_value_index(infinity_backlight_item) !=
|
||||
app->settings.infinityBacklight) {
|
||||
if((bool)variable_item_get_current_value_index(infinity_backlight_item)) {
|
||||
notification_message(app->notifications, &sequence_display_backlight_enforce_on);
|
||||
} else {
|
||||
notification_message(app->notifications, &sequence_display_backlight_enforce_auto);
|
||||
}
|
||||
}
|
||||
|
||||
app->settings.infinityBacklight =
|
||||
(bool)variable_item_get_current_value_index(infinity_backlight_item);
|
||||
app->settings.temp_unit = variable_item_get_current_value_index(temperature_unit_item);
|
||||
app->settings.pressure_unit = variable_item_get_current_value_index(pressure_unit_item);
|
||||
unitemp_saveSettings();
|
||||
unitemp_loadSettings();
|
||||
|
||||
//Возврат предыдущий вид
|
||||
return UnitempViewMainMenu;
|
||||
}
|
||||
/**
|
||||
* @brief Функция обработки нажатия средней кнопки
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @param index На каком элементе списка была нажата кнопка
|
||||
*/
|
||||
static void _enter_callback(void* context, uint32_t index) {
|
||||
UNUSED(context);
|
||||
UNUSED(index);
|
||||
}
|
||||
|
||||
static void _setting_change_callback(VariableItem* item) {
|
||||
if(item == infinity_backlight_item) {
|
||||
variable_item_set_current_value_text(
|
||||
infinity_backlight_item,
|
||||
states[variable_item_get_current_value_index(infinity_backlight_item)]);
|
||||
}
|
||||
if(item == temperature_unit_item) {
|
||||
variable_item_set_current_value_text(
|
||||
temperature_unit_item,
|
||||
temp_units[variable_item_get_current_value_index(temperature_unit_item)]);
|
||||
}
|
||||
if(item == pressure_unit_item) {
|
||||
variable_item_set_current_value_text(
|
||||
pressure_unit_item,
|
||||
pressure_units[variable_item_get_current_value_index(pressure_unit_item)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Создание меню редактирования настроек
|
||||
*/
|
||||
void unitemp_Settings_alloc(void) {
|
||||
variable_item_list = variable_item_list_alloc();
|
||||
//Сброс всех элементов меню
|
||||
variable_item_list_reset(variable_item_list);
|
||||
|
||||
infinity_backlight_item = variable_item_list_add(
|
||||
variable_item_list, "Backlight time", UT_TEMP_COUNT, _setting_change_callback, app);
|
||||
temperature_unit_item =
|
||||
variable_item_list_add(variable_item_list, "Temp. unit", 2, _setting_change_callback, app);
|
||||
pressure_unit_item = variable_item_list_add(
|
||||
variable_item_list, "Press. unit", UT_PRESSURE_COUNT, _setting_change_callback, app);
|
||||
|
||||
//Добавление колбека на нажатие средней кнопки
|
||||
variable_item_list_set_enter_callback(variable_item_list, _enter_callback, app);
|
||||
|
||||
//Создание вида из списка
|
||||
view = variable_item_list_get_view(variable_item_list);
|
||||
//Добавление колбека на нажатие кнопки "Назад"
|
||||
view_set_previous_callback(view, _exit_callback);
|
||||
//Добавление вида в диспетчер
|
||||
view_dispatcher_add_view(app->view_dispatcher, VIEW_ID, view);
|
||||
}
|
||||
|
||||
void unitemp_Settings_switch(void) {
|
||||
//Обнуление последнего выбранного пункта
|
||||
variable_item_list_set_selected_item(variable_item_list, 0);
|
||||
|
||||
variable_item_set_current_value_index(
|
||||
infinity_backlight_item, (uint8_t)app->settings.infinityBacklight);
|
||||
variable_item_set_current_value_text(
|
||||
infinity_backlight_item,
|
||||
states[variable_item_get_current_value_index(infinity_backlight_item)]);
|
||||
|
||||
variable_item_set_current_value_index(temperature_unit_item, (uint8_t)app->settings.temp_unit);
|
||||
variable_item_set_current_value_text(
|
||||
temperature_unit_item,
|
||||
temp_units[variable_item_get_current_value_index(temperature_unit_item)]);
|
||||
|
||||
variable_item_set_current_value_index(
|
||||
pressure_unit_item, (uint8_t)app->settings.pressure_unit);
|
||||
variable_item_set_current_value_text(
|
||||
pressure_unit_item,
|
||||
pressure_units[variable_item_get_current_value_index(pressure_unit_item)]);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
|
||||
void unitemp_Settings_free(void) {
|
||||
//Очистка списка элементов
|
||||
variable_item_list_free(variable_item_list);
|
||||
//Очистка вида
|
||||
view_free(view);
|
||||
//Удаление вида после обработки
|
||||
view_dispatcher_remove_view(app->view_dispatcher, VIEW_ID);
|
||||
}
|
||||
94
applications/plugins/unitemp/views/UnitempViews.h
Normal file
94
applications/plugins/unitemp/views/UnitempViews.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef UNITEMP_SCENES
|
||||
#define UNITEMP_SCENES
|
||||
|
||||
#include "../unitemp.h"
|
||||
|
||||
//Виды менюшек
|
||||
typedef enum UnitempViews {
|
||||
UnitempViewGeneral,
|
||||
UnitempViewMainMenu,
|
||||
UnitempViewSettings,
|
||||
UnitempViewSensorsList,
|
||||
UnitempViewSensorEdit,
|
||||
UnitempViewSensorNameEdit,
|
||||
UnitempViewSensorActions,
|
||||
UnitempViewWidget,
|
||||
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);
|
||||
void unitemp_General_free(void);
|
||||
|
||||
/* Главное меню */
|
||||
void unitemp_MainMenu_alloc(void);
|
||||
void unitemp_MainMenu_switch(void);
|
||||
void unitemp_MainMenu_free(void);
|
||||
|
||||
/* Настройки */
|
||||
void unitemp_Settings_alloc(void);
|
||||
void unitemp_Settings_switch(void);
|
||||
void unitemp_Settings_free(void);
|
||||
|
||||
/* Список датчиков */
|
||||
void unitemp_SensorsList_alloc(void);
|
||||
void unitemp_SensorsList_switch(void);
|
||||
void unitemp_SensorsList_free(void);
|
||||
|
||||
/* Редактор датчка */
|
||||
void unitemp_SensorEdit_alloc(void);
|
||||
//sensor - указатель на редактируемый датчик
|
||||
void unitemp_SensorEdit_switch(Sensor* sensor);
|
||||
void unitemp_SensorEdit_free(void);
|
||||
|
||||
/* Редактор имени датчика */
|
||||
void unitemp_SensorNameEdit_alloc(void);
|
||||
void unitemp_SensorNameEdit_switch(Sensor* sensor);
|
||||
void unitemp_SensorNameEdit_free(void);
|
||||
|
||||
/* Список действий с датчиком */
|
||||
void unitemp_SensorActions_alloc(void);
|
||||
void unitemp_SensorActions_switch(Sensor* sensor);
|
||||
void unitemp_SensorActions_free(void);
|
||||
|
||||
/* Виджеты */
|
||||
void unitemp_widgets_alloc(void);
|
||||
void unitemp_widgets_free(void);
|
||||
|
||||
/* Подтверждение удаления */
|
||||
void unitemp_widget_delete_switch(Sensor* sensor);
|
||||
/* Помощь */
|
||||
void unitemp_widget_help_switch(void);
|
||||
/* О приложении */
|
||||
void unitemp_widget_about_switch(void);
|
||||
#endif
|
||||
204
applications/plugins/unitemp/views/Widgets_view.c
Normal file
204
applications/plugins/unitemp/views/Widgets_view.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
Unitemp - Universal temperature reader
|
||||
Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "UnitempViews.h"
|
||||
#include "unitemp_icons.h"
|
||||
|
||||
#include <assets_icons.h>
|
||||
|
||||
void unitemp_widgets_alloc(void) {
|
||||
app->widget = widget_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, UnitempViewWidget, widget_get_view(app->widget));
|
||||
}
|
||||
|
||||
void unitemp_widgets_free(void) {
|
||||
widget_free(app->widget);
|
||||
}
|
||||
|
||||
/* ================== Подтверждение удаления ================== */
|
||||
Sensor* current_sensor;
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t _delete_exit_callback(void* context) {
|
||||
UNUSED(context);
|
||||
//Возвращаем ID вида, в который нужно вернуться
|
||||
return UnitempViewSensorActions;
|
||||
}
|
||||
/**
|
||||
* @brief Обработчик нажатий на кнопку в виджете
|
||||
*
|
||||
* @param result Какая из кнопок была нажата
|
||||
* @param type Тип нажатия
|
||||
* @param context Указатель на данные плагина
|
||||
*/
|
||||
static void _delete_click_callback(GuiButtonType result, InputType type, void* context) {
|
||||
UNUSED(context);
|
||||
//Коротко нажата левая кнопка (Cancel)
|
||||
if(result == GuiButtonTypeLeft && type == InputTypeShort) {
|
||||
unitemp_SensorActions_switch(current_sensor);
|
||||
}
|
||||
//Коротко нажата правая кнопка (Delete)
|
||||
if(result == GuiButtonTypeRight && type == InputTypeShort) {
|
||||
//Удаление датчика
|
||||
unitemp_sensor_delete(current_sensor);
|
||||
//Выход из меню
|
||||
unitemp_General_switch();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Переключение в виджет удаления датчика
|
||||
*/
|
||||
void unitemp_widget_delete_switch(Sensor* sensor) {
|
||||
current_sensor = sensor;
|
||||
//Очистка виджета
|
||||
widget_reset(app->widget);
|
||||
//Добавление кнопок
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeLeft, "Cancel", _delete_click_callback, app);
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeRight, "Delete", _delete_click_callback, app);
|
||||
|
||||
snprintf(app->buff, BUFF_SIZE, "\e#Delete %s?\e#", current_sensor->name);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, app->buff, false);
|
||||
|
||||
if(current_sensor->type->interface == &ONE_WIRE) {
|
||||
OneWireSensor* s = current_sensor->instance;
|
||||
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"\e#Type:\e# %s",
|
||||
unitemp_onewire_sensor_getModel(current_sensor));
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 16, 128, 23, AlignLeft, AlignTop, app->buff, false);
|
||||
snprintf(app->buff, BUFF_SIZE, "\e#GPIO:\e# %s", s->bus->gpio->name);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 28, 128, 23, AlignLeft, AlignTop, app->buff, false);
|
||||
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"\e#ID:\e# %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
s->deviceID[0],
|
||||
s->deviceID[1],
|
||||
s->deviceID[2],
|
||||
s->deviceID[3],
|
||||
s->deviceID[4],
|
||||
s->deviceID[5],
|
||||
s->deviceID[6],
|
||||
s->deviceID[7]);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 40, 128, 23, AlignLeft, AlignTop, app->buff, false);
|
||||
}
|
||||
|
||||
if(current_sensor->type->interface == &SINGLE_WIRE) {
|
||||
snprintf(app->buff, BUFF_SIZE, "\e#Type:\e# %s", current_sensor->type->typename);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 16, 128, 23, AlignLeft, AlignTop, app->buff, false);
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"\e#GPIO:\e# %s",
|
||||
((SingleWireSensor*)current_sensor->instance)->gpio->name);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 28, 128, 23, AlignLeft, AlignTop, app->buff, false);
|
||||
}
|
||||
|
||||
if(current_sensor->type->interface == &I2C) {
|
||||
snprintf(app->buff, BUFF_SIZE, "\e#Type:\e# %s", current_sensor->type->typename);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 16, 128, 23, AlignLeft, AlignTop, app->buff, false);
|
||||
snprintf(
|
||||
app->buff,
|
||||
BUFF_SIZE,
|
||||
"\e#I2C addr:\e# 0x%02X",
|
||||
((I2CSensor*)current_sensor->instance)->currentI2CAdr);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 28, 128, 23, AlignLeft, AlignTop, app->buff, false);
|
||||
}
|
||||
|
||||
view_set_previous_callback(widget_get_view(app->widget), _delete_exit_callback);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, UnitempViewWidget);
|
||||
}
|
||||
|
||||
/* ========================== Помощь ========================== */
|
||||
|
||||
/**
|
||||
* @brief Функция обработки нажатия кнопки "Назад"
|
||||
*
|
||||
* @param context Указатель на данные приложения
|
||||
* @return ID вида в который нужно переключиться
|
||||
*/
|
||||
static uint32_t _help_exit_callback(void* context) {
|
||||
UNUSED(context);
|
||||
//Возвращаем ID вида, в который нужно вернуться
|
||||
return UnitempViewGeneral;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Переключение в виджет помощи
|
||||
*/
|
||||
void unitemp_widget_help_switch(void) {
|
||||
//Очистка виджета
|
||||
widget_reset(app->widget);
|
||||
|
||||
widget_add_icon_element(app->widget, 3, 7, &I_repo_qr_50x50);
|
||||
widget_add_icon_element(app->widget, 71, 15, &I_DolphinCommon_56x48);
|
||||
|
||||
widget_add_string_multiline_element(
|
||||
app->widget, 55, 5, AlignLeft, AlignTop, FontSecondary, "You can find help\nthere");
|
||||
|
||||
widget_add_frame_element(app->widget, 0, 0, 128, 63, 7);
|
||||
widget_add_frame_element(app->widget, 0, 0, 128, 64, 7);
|
||||
|
||||
view_set_previous_callback(widget_get_view(app->widget), _help_exit_callback);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, UnitempViewWidget);
|
||||
}
|
||||
|
||||
/* ========================== О приложении ========================== */
|
||||
|
||||
/**
|
||||
* @brief Переключение в виджет о приложении
|
||||
*/
|
||||
void unitemp_widget_about_switch(void) {
|
||||
//Очистка виджета
|
||||
widget_reset(app->widget);
|
||||
|
||||
widget_add_frame_element(app->widget, 0, 0, 128, 63, 7);
|
||||
widget_add_frame_element(app->widget, 0, 0, 128, 64, 7);
|
||||
|
||||
snprintf(app->buff, BUFF_SIZE, "#Unitemp %s#", UNITEMP_APP_VER);
|
||||
widget_add_text_box_element(
|
||||
app->widget, 0, 4, 128, 12, AlignCenter, AlignCenter, app->buff, false);
|
||||
|
||||
widget_add_text_scroll_element(
|
||||
app->widget,
|
||||
4,
|
||||
16,
|
||||
121,
|
||||
44,
|
||||
"Universal plugin for viewing the values of temperature\nsensors\n\e#Author: Quenon\ngithub.com/quen0n\n\e#Designer: Svaarich\ngithub.com/Svaarich\n\e#Issues & suggestions\ntiny.one/unitemp");
|
||||
|
||||
view_set_previous_callback(widget_get_view(app->widget), _help_exit_callback);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, UnitempViewWidget);
|
||||
}
|
||||
Reference in New Issue
Block a user