1870 lines
82 KiB
C
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "utility_functions.h"
SysState_t state = {.mode = 0x01, .te1 = -50, .te2 = 230, .te3 = 0, .te4 = 180, .kpd = 868, .speedB3 = 25, .speedB4 = 30};
uint64_t errorMask;
lv_obj_t *currentTab;
lv_obj_t *tabSettingsModeTime;
lv_obj_t *tabSettingsTime;
lv_obj_t *tabSettingsScreen;
lv_obj_t *tabFilters;
lv_obj_t *tabIntervals;
lv_obj_t *tabPower;
lv_obj_t *tabTemperature;
lv_obj_t *btnOkModes;
lv_obj_t *btnOkTime;
lv_obj_t *btnOkScreen;
lv_obj_t *btnOkFilters;
lv_obj_t *btnOkIntervals;
lv_obj_t *btnOkPower;
lv_obj_t *btnOkTemperature;
lv_obj_t *mainScreen;
lv_obj_t *saveScreen;
lv_obj_t *tabMain;
lv_obj_t *tabSettings;
lv_obj_t *tabService;
lv_obj_t *tabHelp;
uint16_t selectedTestDay;
lv_obj_t *imgMode;
lv_obj_t *dateLabel;
lv_obj_t *dayLabel;
lv_obj_t *timeLabel;
lv_obj_t *sliderFilterSup;
lv_obj_t *sliderFilterExh;
lv_obj_t *powerMainLabel;
lv_obj_t *balanceSwitch;
lv_obj_t *labelTempSupStreet;
lv_obj_t *labelTempSupHome;
lv_obj_t *labelTempExhStreet;
lv_obj_t *labelTempExhHome;
lv_obj_t *btnStartStop;
bool btnStartStopIsStop = false;
lv_obj_t *btnConditioner;
bool btnConditionerState = false;
bool btnConditionerEnabled = false;
lv_obj_t *rollerDaymodePower;
lv_obj_t *rollerNightmodePower;
lv_obj_t *rollerDayHour;
lv_obj_t *rollerDayMinute;
lv_obj_t *rollerNightHour;
lv_obj_t *rollerNightMinute;
lv_obj_t *rollerHour;
lv_obj_t *rollerMinute;
lv_obj_t *ddDay;
lv_obj_t *ddMonth;
lv_obj_t *ddYear;
lv_obj_t *rollerScreenOff;
lv_obj_t *passwordScreen;
lv_obj_t *matrixFilterDays;
lv_obj_t *rollerFilterHour;
lv_obj_t *rollerFilterMinute;
lv_obj_t *spinboxTempInterval;
lv_obj_t *spinboxRotorPause;
lv_obj_t *spinboxRotorPulse;
lv_obj_t *spinboxNumRotors;
lv_obj_t *labelServiceSup;
lv_obj_t *labelServiceExh;
lv_obj_t *rollerServiceSup;
lv_obj_t *rollerServiceExh;
lv_obj_t *ledSup;
lv_obj_t *ledExh;
lv_obj_t *labelServiceTempSupStreet;
lv_obj_t *labelServiceTempSupHome;
lv_obj_t *labelServiceTempExhStreet;
lv_obj_t *labelServiceTempExhHome;
lv_obj_t *spinboxServiceTempSupStreet;
lv_obj_t *spinboxServiceTempSupHome;
lv_obj_t *spinboxServiceTempExhStreet;
lv_obj_t *spinboxServiceTempExhHome;
lv_obj_t *labelHelpTempSupStreet;
lv_obj_t *labelHelpTempSupHome;
lv_obj_t *labelHelpTempExhStreet;
lv_obj_t *labelHelpTempExhHome;
lv_obj_t *labelHelpKpd;
lv_obj_t *kpdHint;
lv_obj_t *labelHelpSup;
lv_obj_t *labelHelpExh;
lv_obj_t *rotorSection;
lv_obj_t *labelRotorSpeed[MAX_NUM_ROTORS];
lv_obj_t *rotorSpeedLine[MAX_NUM_ROTORS];
lv_obj_t *popupBg;
lv_obj_t *loadingLabel;
PopupWindow_t popupWindows[NUM_OF_POPUP_WINDOWS];
void placeWidgets();
void initStyles();
void createMainTab(lv_obj_t *parent);
void createSettingsTab(lv_obj_t *parent);
void createModePage(lv_obj_t *parent);
void createTimePage(lv_obj_t *parent);
void createScreenPage(lv_obj_t *parent);
void createFiltersPage(lv_obj_t *parent);
void createServiceTab(lv_obj_t *parent);
lv_obj_t *createPasswordInput(lv_obj_t *parent);
void createIntervalsPage(lv_obj_t *parent);
void createServicePowerPage(lv_obj_t *parent);
void createTempAdjustPage(lv_obj_t *parent);
void createHelpTab(lv_obj_t *parent);
void createDescrPage(lv_obj_t *parent);
void createStatePage(lv_obj_t *parent);
void createContactPage(lv_obj_t *parent);
void createRotorSpeed(lv_obj_t *parent, uint8_t num);
void createPopupScreen();
void updateConfigWidgets();
void updateWidgets();
void enableConditionerBtn();
void disableConditionerBtn();
void setConditionerBtnState(bool state);
static void passwordKeyboardEventCb(lv_event_t *e);
static void mainTabviewEventCb(lv_event_t *e);
static void settingsTabviewEventCb(lv_event_t *e);
static void serviceTabviewEventCb(lv_event_t *e);
static lv_obj_t *getActiveTabSettings(lv_obj_t *matrix);
static lv_obj_t *getActiveTabService(lv_obj_t *matrix);
static void filterButtonsCb(lv_event_t *e);
static void balanceSwitchCb(lv_event_t *e);
static void startStopBtnCb(lv_event_t *e);
static void conditionerBtnCb(lv_event_t *e);
static void valueChangedCb(lv_event_t *e);
static void OkBtnModeTimeCb(lv_event_t *e);
static void OkBtnTimeCb(lv_event_t *e);
static void OkBtnScreenCb(lv_event_t *e);
static void OkBtnFiltersCb(lv_event_t *e);
static void OkBtnIntervalCb(lv_event_t *e);
static void OkBtnServicePowerCb(lv_event_t *e);
static void OkBtnTempAdjustCb(lv_event_t *e);
static void kpdLabelCb(lv_event_t *e);
static void ddDateCb(lv_event_t *e);
static void timePageClickedCb(lv_event_t *e);
static void clearModesTab();
static void clearTimeTab();
static void clearScreenTab();
static void clearFiltersTab();
static void clearIntervalsTab();
static void clearPowerTab();
static void clearTemperatureTab();
static void clearCurrentTab();
void initStyles() {
lv_style_init(&text_16);
lv_style_set_text_font(&text_16, &montserrat_16_ru_en);
lv_style_init(&text_20);
lv_style_set_text_font(&text_20, &montserrat_20_ru_en);
lv_style_init(&text_24);
lv_style_set_text_font(&text_24, &montserrat_24_ru_en);
lv_style_init(&text_28);
lv_style_set_text_font(&text_28, &montserrat_28_ru_en);
lv_style_init(&text_20_semibold);
lv_style_set_text_font(&text_20_semibold, &montserrat_semibold_20_ru_en);
lv_style_init(&text_24_semibold);
lv_style_set_text_font(&text_24_semibold, &montserrat_semibold_24_ru_en);
lv_style_init(&text_28_semibold);
lv_style_set_text_font(&text_28_semibold, &montserrat_semibold_28_ru_en);
lv_style_init(&styleRollerMain);
lv_style_set_bg_color(&styleRollerMain, lv_color_white());
lv_style_set_text_color(&styleRollerMain, lv_color_black());
lv_style_set_border_color(&styleRollerMain, lv_palette_lighten(LV_PALETTE_BLUE, 1));
lv_style_set_border_width(&styleRollerMain, 3);
lv_style_set_pad_all(&styleRollerMain, 7);
lv_style_set_text_font(&styleRollerMain, &montserrat_20_ru_en);
lv_style_set_anim_time(&styleRollerMain, 200);
lv_style_init(&styleRollerSelected);
lv_style_set_bg_color(&styleRollerSelected, lv_palette_lighten(LV_PALETTE_GREY, 2));
lv_style_set_text_color(&styleRollerSelected, lv_color_black());
lv_style_set_border_width(&styleRollerSelected, 0);
lv_style_set_pad_all(&styleRollerSelected, 7);
lv_style_set_text_font(&styleRollerSelected, &montserrat_28_ru_en);
lv_style_set_anim_time(&styleRollerSelected, 1000);
lv_style_init(&styleBackground);
lv_style_set_bg_color(&styleBackground, lv_palette_lighten(LV_PALETTE_BLUE, 5));
lv_style_set_border_color(&styleBackground, lv_palette_lighten(LV_PALETTE_BLUE, 4));
lv_style_set_border_width(&styleBackground, 3);
createRollerOptions(0, 23, 1, 2, rollerOptionsHour, sizeof(rollerOptionsHour));
createRollerOptions(0, 59, 1, 2, rollerOptionsMinute, sizeof(rollerOptionsMinute));
}
void placeWidgets() {
initStyles();
lv_obj_t *tabview = lv_tabview_create(lv_scr_act());
lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT);
lv_tabview_set_tab_bar_size(tabview, 140);
lv_obj_add_style(tabview, &text_20_semibold, 0);
lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_event_cb(tabview, mainTabviewEventCb, LV_EVENT_CLICKED, lv_tabview_get_tab_btns(tabview));
tabMain = lv_tabview_add_tab(tabview, "Главная");
tabSettings = lv_tabview_add_tab(tabview, "Настройки");
tabService = lv_tabview_add_tab(tabview, "Сервис");
tabHelp = lv_tabview_add_tab(tabview, "Помощь");
lv_obj_set_flex_flow(tabMain, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabMain, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabMain, LV_OBJ_FLAG_SCROLLABLE);
createMainTab(tabMain);
createSettingsTab(tabSettings);
createServiceTab(tabService);
createHelpTab(tabHelp);
createPopupScreen();
mainScreen = lv_scr_act();
saveScreen = lv_obj_create(NULL);
updateConfigWidgets();
updateWidgets();
}
void createMainTab(lv_obj_t *parent) {
lv_obj_t *headerSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(headerSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(headerSection, 0, 0);
lv_obj_set_size(headerSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(headerSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(headerSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_hor(headerSection, 5, 0);
lv_obj_set_style_pad_ver(headerSection, 20, 0);
lv_obj_set_style_pad_column(headerSection, 15, 0);
imgMode = lv_img_create(headerSection);
lv_img_set_src(imgMode, &sun_yellow);
lv_obj_set_size(imgMode, 100, 100);
lv_obj_t *filtersSection = lv_obj_create(headerSection);
lv_obj_set_style_bg_opa(filtersSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(filtersSection, 0, 0);
lv_obj_set_size(filtersSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(filtersSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(filtersSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(filtersSection, 20, 0);
sliderFilterSup = lv_slider_create(filtersSection);
lv_obj_set_style_bg_color(sliderFilterSup, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_clear_flag(sliderFilterSup, LV_OBJ_FLAG_CLICKABLE);
lv_slider_set_range(sliderFilterSup, 0, 100);
lv_slider_set_value(sliderFilterSup, 0, LV_ANIM_OFF);
lv_obj_set_style_bg_opa(sliderFilterSup, LV_OPA_TRANSP, LV_PART_KNOB);
sliderFilterExh = lv_slider_create(filtersSection);
lv_obj_set_style_bg_color(sliderFilterExh, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN);
lv_obj_set_style_bg_color(sliderFilterExh, lv_palette_main(LV_PALETTE_RED), LV_PART_INDICATOR);
lv_obj_set_style_bg_color(sliderFilterExh, lv_palette_main(LV_PALETTE_RED), LV_PART_KNOB );
lv_obj_clear_flag(sliderFilterExh, LV_OBJ_FLAG_CLICKABLE);
lv_slider_set_range(sliderFilterExh, 0, 100);
lv_slider_set_value(sliderFilterExh, 0, LV_ANIM_OFF);
lv_obj_set_style_bg_opa(sliderFilterExh, LV_OPA_TRANSP, LV_PART_KNOB);
lv_obj_t *timeSection = lv_obj_create(headerSection);
lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(timeSection, 0, 0);
lv_obj_set_size(timeSection, 200, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_END);
lv_obj_set_style_pad_all(timeSection, 5, 0);
dateLabel = lv_label_create(timeSection);
lv_obj_add_style(dateLabel, &text_24, 0);
lv_label_set_text(dateLabel, "");
dayLabel = lv_label_create(timeSection);
lv_obj_add_style(dayLabel, &text_24, 0);
lv_label_set_text(dayLabel, "");
timeLabel = lv_label_create(timeSection);
lv_obj_add_style(timeLabel, &text_24, 0);
lv_label_set_text(timeLabel, "");
lv_obj_t *powerSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(powerSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(powerSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(powerSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(powerSection, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_hor(powerSection, 5, 0);
lv_obj_set_style_pad_ver(powerSection, 10, 0);
lv_obj_t *powerLabelSection = lv_obj_create(powerSection);
lv_obj_set_style_bg_opa(powerLabelSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(powerLabelSection, 0, 0);
lv_obj_set_size(powerLabelSection, LV_PCT(35), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(powerLabelSection, 0, 0);
lv_obj_remove_flag(powerLabelSection, LV_OBJ_FLAG_SCROLLABLE);
powerMainLabel = lv_label_create(powerLabelSection);
lv_obj_add_style(powerMainLabel, &text_24_semibold, 0);
lv_label_set_text(powerMainLabel, "Мощность: ");
lv_obj_t *balanceLabelSection = lv_obj_create(powerSection);
lv_obj_set_style_bg_opa(balanceLabelSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(balanceLabelSection, 0, 0);
lv_obj_set_size(balanceLabelSection, LV_PCT(50), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(balanceLabelSection, 0, 0);
lv_obj_t *balanceLabel = lv_label_create(balanceLabelSection);
lv_obj_add_style(balanceLabel, &text_24, 0);
lv_label_set_text(balanceLabel, "Соблюдение баланса");
lv_obj_center(balanceLabel);
lv_obj_t *balanceSwitchSection = lv_obj_create(powerSection);
lv_obj_set_style_bg_opa(balanceSwitchSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(balanceSwitchSection, 0, 0);
lv_obj_set_size(balanceSwitchSection, LV_PCT(10), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(balanceSwitchSection, 0, 0);
balanceSwitch = lv_switch_create(balanceSwitchSection);
lv_obj_add_state(balanceSwitch, LV_STATE_CHECKED);
lv_obj_add_event_cb(balanceSwitch, balanceSwitchCb, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_center(balanceSwitch);
lv_obj_t *tempSupSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(tempSupSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(tempSupSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(tempSupSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(tempSupSection, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_remove_flag(tempSupSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_pad_all(tempSupSection, 0, 0);
lv_obj_set_style_pad_hor(tempSupSection, 5, 0);
lv_obj_set_style_pad_ver(tempSupSection, 5, 0);
lv_obj_t *tempLabelSection = lv_obj_create(tempSupSection);
lv_obj_set_style_bg_opa(tempLabelSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempLabelSection, 0, 0);
lv_obj_set_size(tempLabelSection, LV_PCT(35), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempLabelSection, 0, 0);
lv_obj_t *labelTempSup = lv_label_create(tempLabelSection);
lv_obj_add_style(labelTempSup, &text_24_semibold, 0);
lv_label_set_text(labelTempSup, "Приток");
lv_obj_t *tempStreetSection = lv_obj_create(tempSupSection);
lv_obj_set_style_bg_opa(tempStreetSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempStreetSection, 0, 0);
lv_obj_set_size(tempStreetSection, LV_PCT(20), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempStreetSection, 0, 0);
labelTempSupStreet = lv_label_create(tempStreetSection);
lv_obj_add_style(labelTempSupStreet, &text_24, 0);
lv_label_set_text(labelTempSupStreet, "");
lv_obj_center(labelTempSupStreet);
lv_obj_t *tempArrowSection = lv_obj_create(tempSupSection);
lv_obj_set_style_bg_opa(tempArrowSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempArrowSection, 0, 0);
lv_obj_set_size(tempArrowSection, LV_PCT(20), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempArrowSection, 0, 0);
lv_obj_t *imgArrowSup = lv_img_create(tempArrowSection);
lv_img_set_src(imgArrowSup, &arrow);
lv_obj_set_style_img_recolor_opa(imgArrowSup, 255, 0);
lv_obj_set_style_img_recolor(imgArrowSup, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_set_size(imgArrowSup, 63, 65);
lv_obj_center(imgArrowSup);
lv_obj_t *tempHomeSection = lv_obj_create(tempSupSection);
lv_obj_set_style_bg_opa(tempHomeSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempHomeSection, 0, 0);
lv_obj_set_size(tempHomeSection, LV_PCT(20), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempHomeSection, 0, 0);
labelTempSupHome = lv_label_create(tempHomeSection);
lv_obj_add_style(labelTempSupHome, &text_24, 0);
lv_label_set_text(labelTempSupHome, "");
lv_obj_center(labelTempSupHome);
lv_obj_t *tempExhSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(tempExhSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(tempExhSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(tempExhSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(tempExhSection, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_remove_flag(tempExhSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_pad_all(tempExhSection, 0, 0);
lv_obj_set_style_pad_hor(tempExhSection, 5, 0);
lv_obj_set_style_pad_ver(tempExhSection, 5, 0);
tempLabelSection = lv_obj_create(tempExhSection);
lv_obj_set_style_bg_opa(tempLabelSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempLabelSection, 0, 0);
lv_obj_set_size(tempLabelSection, LV_PCT(35), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempLabelSection, 0, 0);
lv_obj_t *labelTempExh = lv_label_create(tempLabelSection);
lv_obj_add_style(labelTempExh, &text_24_semibold, 0);
lv_label_set_text(labelTempExh, "Вытяжка");
tempStreetSection = lv_obj_create(tempExhSection);
lv_obj_set_style_bg_opa(tempStreetSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempStreetSection, 0, 0);
lv_obj_set_size(tempStreetSection, LV_PCT(20), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempStreetSection, 0, 0);
labelTempExhStreet = lv_label_create(tempStreetSection);
lv_obj_add_style(labelTempExhStreet, &text_24, 0);
lv_label_set_text(labelTempExhStreet, "");
lv_obj_center(labelTempExhStreet);
tempArrowSection = lv_obj_create(tempExhSection);
lv_obj_set_style_bg_opa(tempArrowSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempArrowSection, 0, 0);
lv_obj_set_size(tempArrowSection, LV_PCT(20), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempArrowSection, 0, 0);
lv_obj_t *imgArrowExh = lv_img_create(tempArrowSection);
lv_img_set_src(imgArrowExh, &arrow);
lv_obj_set_style_img_recolor_opa(imgArrowExh, 255, 0);
lv_obj_set_style_img_recolor(imgArrowExh, lv_palette_main(LV_PALETTE_RED), 0);
lv_img_set_angle(imgArrowExh, 1800);
lv_obj_set_size(imgArrowExh, 63, 65);
lv_obj_center(imgArrowExh);
tempHomeSection = lv_obj_create(tempExhSection);
lv_obj_set_style_bg_opa(tempHomeSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tempHomeSection, 0, 0);
lv_obj_set_size(tempHomeSection, LV_PCT(20), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(tempHomeSection, 0, 0);
labelTempExhHome = lv_label_create(tempHomeSection);
lv_obj_add_style(labelTempExhHome, &text_24, 0);
lv_label_set_text(labelTempExhHome, "");
lv_obj_center(labelTempExhHome);
lv_obj_t *buttonSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(buttonSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(buttonSection, 0, 0);
lv_obj_set_size(buttonSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(buttonSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(buttonSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_hor(buttonSection, 5, 0);
lv_obj_set_style_pad_ver(buttonSection, 10, 0);
lv_obj_set_style_pad_column(buttonSection, 50, 0);
btnStartStop = lv_btn_create(buttonSection);
lv_obj_add_event_cb(btnStartStop, startStopBtnCb, LV_EVENT_CLICKED, NULL);
lv_obj_t *btnStartLabel = lv_label_create(btnStartStop);
lv_obj_add_style(btnStartLabel, &text_28, 0);
lv_label_set_text(btnStartLabel, "Пуск");
lv_obj_center(btnStartLabel);
btnConditioner = lv_btn_create(buttonSection);
lv_obj_add_event_cb(btnConditioner, conditionerBtnCb, LV_EVENT_CLICKED, NULL);
lv_obj_set_size(btnConditioner, 70, 70);
lv_obj_set_style_bg_opa(btnConditioner, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_color(btnConditioner, lv_palette_lighten(LV_PALETTE_GREY, 2), 0);
lv_obj_set_style_border_width(btnConditioner, 3, 0);
lv_obj_clear_flag(btnConditioner, LV_OBJ_FLAG_CLICKABLE);
lv_obj_t *icon = lv_label_create(btnConditioner);
lv_obj_set_style_text_color(icon, lv_palette_lighten(LV_PALETTE_GREY, 2), 0);
lv_obj_set_style_text_font(icon, &lv_font_montserrat_24, 0);
lv_label_set_text(icon, LV_SYMBOL_REFRESH);
lv_obj_center(icon);
}
void createSettingsTab(lv_obj_t *parent) {
lv_obj_t *tabviewSettings = lv_tabview_create(parent);
lv_tabview_set_tab_bar_position(tabviewSettings, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabviewSettings, 70);
lv_obj_add_style(tabviewSettings, &text_20_semibold, 0);
lv_obj_add_event_cb(tabviewSettings, settingsTabviewEventCb, LV_EVENT_CLICKED, lv_tabview_get_tab_btns(tabviewSettings));
tabSettingsModeTime = lv_tabview_add_tab(tabviewSettings, "Режимы");
tabSettingsTime = lv_tabview_add_tab(tabviewSettings, "Время");
tabSettingsScreen = lv_tabview_add_tab(tabviewSettings, "Экран");
tabFilters = lv_tabview_add_tab(tabviewSettings, "Фильтры");
lv_obj_clear_flag(lv_tabview_get_content(tabviewSettings), LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_flex_flow(tabSettingsModeTime, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabSettingsModeTime, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabSettingsModeTime, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_flex_flow(tabSettingsTime, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabSettingsTime, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabSettingsTime, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_flex_flow(tabSettingsScreen, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabSettingsScreen, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabSettingsScreen, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_flex_flow(tabFilters, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabFilters, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabFilters, LV_OBJ_FLAG_SCROLLABLE);
createModePage(tabSettingsModeTime);
createTimePage(tabSettingsTime);
createScreenPage(tabSettingsScreen);
createFiltersPage(tabFilters);
}
void createModePage(lv_obj_t *parent) {
lv_obj_t *rollersSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(rollersSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(rollersSection, 0, 0);
lv_obj_set_size(rollersSection, LV_PCT(105), LV_PCT(80));
lv_obj_set_flex_flow(rollersSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(rollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(rollersSection, 0, 0);
lv_obj_remove_flag(rollersSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *daySection = lv_obj_create(rollersSection);
lv_obj_set_style_bg_opa(daySection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(daySection, 0, 0);
lv_obj_set_size(daySection, LV_PCT(50), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(daySection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(daySection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(daySection, 0, 0);
lv_obj_set_style_pad_right(daySection, 5, 0);
lv_obj_remove_flag(daySection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *dayLabel = lv_label_create(daySection);
lv_obj_add_style(dayLabel, &text_28, 0);
lv_label_set_text(dayLabel, "Дневной режим");
lv_obj_t *dayRollersSection = lv_obj_create(daySection);
lv_obj_set_style_bg_opa(dayRollersSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(dayRollersSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(dayRollersSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(dayRollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(dayRollersSection, 0, 0);
lv_obj_set_style_pad_hor(dayRollersSection, 7, 0);
lv_obj_set_style_pad_ver(dayRollersSection, 5, 0);
lv_obj_remove_flag(dayRollersSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *timeSection = lv_obj_create(dayRollersSection);
lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(timeSection, 0, 0);
lv_obj_set_size(timeSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(timeSection, 0, 0);
lv_obj_set_style_pad_column(timeSection, 5, 0);
lv_obj_remove_flag(timeSection, LV_OBJ_FLAG_SCROLLABLE);
rollerDayHour = createRoller(timeSection, rollerOptionsHour, ROLLER_ROWS_DEFAULT);
lv_obj_t *labelColon = lv_label_create(timeSection);
lv_obj_add_style(labelColon, &text_28, 0);
lv_label_set_text(labelColon, ":");
rollerDayMinute = createRoller(timeSection, rollerOptionsMinute, ROLLER_ROWS_DEFAULT);
char optionsPowerAuto[600];
createRollerOptions(20, 90, 1, 1, optionsPowerAuto, sizeof(optionsPowerAuto));
rollerDaymodePower = createRoller(dayRollersSection, optionsPowerAuto, ROLLER_ROWS_DEFAULT);
lv_obj_set_width(rollerDaymodePower, 90);
lv_obj_set_style_text_align(rollerDaymodePower, LV_TEXT_ALIGN_LEFT, 0);
lv_obj_t *labelPercent = lv_label_create(rollerDaymodePower);
lv_obj_add_style(labelPercent, &text_28, 0);
lv_label_set_text(labelPercent, "%");
lv_obj_align(labelPercent, LV_ALIGN_CENTER, 20, 0);
lv_obj_t *nightSection = lv_obj_create(rollersSection);
lv_obj_set_style_bg_opa(nightSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(nightSection, 0, 0);
lv_obj_set_size(nightSection, LV_PCT(50), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(nightSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(nightSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(nightSection, 0, 0);
lv_obj_set_style_pad_left(nightSection, 5, 0);
lv_obj_remove_flag(nightSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *nightLabel = lv_label_create(nightSection);
lv_obj_add_style(nightLabel, &text_28, 0);
lv_label_set_text(nightLabel, "Ночной режим");
lv_obj_t *nightRollersSection = lv_obj_create(nightSection);
lv_obj_set_style_bg_opa(nightRollersSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(nightRollersSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(nightRollersSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(nightRollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(nightRollersSection, 0, 0);
lv_obj_set_style_pad_hor(nightRollersSection, 7, 0);
lv_obj_set_style_pad_ver(nightRollersSection, 5, 0);
lv_obj_remove_flag(nightRollersSection, LV_OBJ_FLAG_SCROLLABLE);
timeSection = lv_obj_create(nightRollersSection);
lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(timeSection, 0, 0);
lv_obj_set_size(timeSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(timeSection, 0, 0);
lv_obj_set_style_pad_column(timeSection, 5, 0);
lv_obj_remove_flag(timeSection, LV_OBJ_FLAG_SCROLLABLE);
rollerNightHour = createRoller(timeSection, rollerOptionsHour, ROLLER_ROWS_DEFAULT);
labelColon = lv_label_create(timeSection);
lv_obj_add_style(labelColon, &text_28, 0);
lv_label_set_text(labelColon, ":");
rollerNightMinute = createRoller(timeSection, rollerOptionsMinute, ROLLER_ROWS_DEFAULT);
rollerNightmodePower = createRoller(nightRollersSection, optionsPowerAuto, ROLLER_ROWS_DEFAULT);
lv_obj_set_width(rollerNightmodePower, 90);
lv_obj_set_style_text_align(rollerNightmodePower, LV_TEXT_ALIGN_LEFT, 0);
labelPercent = lv_label_create(rollerNightmodePower);
lv_obj_add_style(labelPercent, &text_28, 0);
lv_label_set_text(labelPercent, "%");
lv_obj_align(labelPercent, LV_ALIGN_CENTER, 20, 0);
lv_obj_t *btnSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btnSection, 0, 0);
lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20));
lv_obj_set_style_pad_all(btnSection, 0, 0);
lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE);
btnOkModes = lv_btn_create(btnSection);
lv_obj_add_event_cb(btnOkModes, OkBtnModeTimeCb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btnOkModes);
lv_obj_add_flag(btnOkModes, LV_OBJ_FLAG_HIDDEN);
lv_obj_t *btnOkLabel = lv_label_create(btnOkModes);
lv_obj_add_style(btnOkLabel, &text_28, 0);
lv_label_set_text(btnOkLabel, "Ок");
lv_obj_center(btnOkLabel);
lv_obj_add_event_cb(rollerDayHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes);
lv_obj_add_event_cb(rollerDayMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes);
lv_obj_add_event_cb(rollerDaymodePower, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes);
lv_obj_add_event_cb(rollerNightHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes);
lv_obj_add_event_cb(rollerNightMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes);
lv_obj_add_event_cb(rollerNightmodePower, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes);
}
void createTimePage(lv_obj_t *parent) {
lv_obj_t *rollersSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(rollersSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(rollersSection, 0, 0);
lv_obj_set_size(rollersSection, LV_PCT(100), LV_PCT(80));
lv_obj_set_flex_flow(rollersSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(rollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_set_style_pad_all(rollersSection, 0, 0);
lv_obj_remove_flag(rollersSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *timeSection = lv_obj_create(rollersSection);
lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(timeSection, 0, 0);
lv_obj_set_size(timeSection, LV_PCT(50), LV_PCT(100));
lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(timeSection, 10, 0);
lv_obj_remove_flag(timeSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *labelTime = lv_label_create(timeSection);
lv_obj_add_style(labelTime, &text_28, 0);
lv_label_set_text(labelTime, "Время");
lv_obj_t *timeRollersSection = lv_obj_create(timeSection);
lv_obj_set_style_bg_opa(timeRollersSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(timeRollersSection, 0, 0);
lv_obj_set_size(timeRollersSection, LV_SIZE_CONTENT, LV_PCT(85));
lv_obj_set_flex_flow(timeRollersSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(timeRollersSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(timeRollersSection, 10, 0);
lv_obj_remove_flag(timeRollersSection, LV_OBJ_FLAG_SCROLLABLE);
rollerHour = createRoller(timeRollersSection, rollerOptionsHour, ROLLER_ROWS_DEFAULT);
lv_obj_t *labelColon = lv_label_create(timeRollersSection);
lv_obj_add_style(labelColon, &text_28, 0);
lv_label_set_text(labelColon, ":");
rollerMinute = createRoller(timeRollersSection, rollerOptionsMinute, ROLLER_ROWS_DEFAULT);
lv_obj_t *dateSection = lv_obj_create(rollersSection);
lv_obj_set_style_bg_opa(dateSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(dateSection, 0, 0);
lv_obj_set_size(dateSection, LV_PCT(50), LV_PCT(100));
lv_obj_set_flex_flow(dateSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(dateSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(dateSection, 10, 0);
lv_obj_remove_flag(dateSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *labelDate = lv_label_create(dateSection);
lv_obj_add_style(labelDate, &text_28, 0);
lv_label_set_text(labelDate, "Дата");
lv_obj_t *dateDropdownSection = lv_obj_create(dateSection);
lv_obj_set_style_bg_opa(dateDropdownSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(dateDropdownSection, 0, 0);
lv_obj_set_size(dateDropdownSection, LV_SIZE_CONTENT, LV_PCT(85));
lv_obj_set_flex_flow(dateDropdownSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(dateDropdownSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(dateDropdownSection, 10, 0);
lv_obj_set_style_pad_row(dateDropdownSection, 20, 0);
lv_obj_remove_flag(dateDropdownSection, LV_OBJ_FLAG_SCROLLABLE);
char optionsDay[128] = {0};
const char *optionsMonth = "Января\nФевраля\nМарта\nАпреля\nМая\nИюня\nИюля\nАвгуста\nСентября\nОктября\nНоября\nДекабря";
char optionsYear[512] = {0};
createRollerOptions(1, 31, 1, 1, optionsDay, sizeof(optionsDay));
createRollerOptions(2025, 2099, 1, 1, optionsYear, sizeof(optionsYear));
createDateSetting(dateDropdownSection, optionsDay, &ddDay);
createDateSetting(dateDropdownSection, optionsMonth, &ddMonth);
createDateSetting(dateDropdownSection, optionsYear, &ddYear);
lv_obj_add_event_cb(ddMonth, ddDateCb, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_add_event_cb(ddYear, ddDateCb, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_t *btnSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btnSection, 0, 0);
lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20));
lv_obj_set_style_pad_all(btnSection, 0, 0);
lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE);
btnOkTime = lv_btn_create(btnSection);
lv_obj_add_event_cb(btnOkTime, OkBtnTimeCb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btnOkTime);
lv_obj_add_flag(btnOkTime, LV_OBJ_FLAG_HIDDEN);
lv_obj_t *btnOkLabel = lv_label_create(btnOkTime);
lv_obj_add_style(btnOkLabel, &text_28, 0);
lv_label_set_text(btnOkLabel, "Ок");
lv_obj_center(btnOkLabel);
lv_obj_add_event_cb(rollerHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime);
lv_obj_add_event_cb(rollerMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime);
lv_obj_add_event_cb(ddDay, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime);
lv_obj_add_event_cb(ddMonth, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime);
lv_obj_add_event_cb(ddYear, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime);
}
void createScreenPage(lv_obj_t *parent) {
lv_obj_t *mainSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(mainSection, 0, 0);
lv_obj_set_size(mainSection, LV_PCT(100), LV_PCT(80));
lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(mainSection, 0, 0);
lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *label = lv_label_create(mainSection);
lv_obj_add_style(label, &text_28, 0);
lv_label_set_text(label, "Выключение экрана");
lv_obj_t *minSection = lv_obj_create(mainSection);
lv_obj_set_style_bg_opa(minSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(minSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(minSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(minSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(minSection, 10, 0);
char rollerOptions[] = "1\n2\n5\n10\n15";
rollerScreenOff = lv_roller_create(minSection);
lv_roller_set_options(rollerScreenOff, rollerOptions, LV_ROLLER_MODE_NORMAL);
lv_roller_set_visible_row_count(rollerScreenOff, ROLLER_ROWS_DEFAULT);
lv_obj_set_width(rollerScreenOff, 80);
lv_obj_add_style(rollerScreenOff, &styleRollerMain, LV_PART_MAIN);
lv_obj_add_style(rollerScreenOff, &styleRollerSelected, LV_PART_SELECTED);
label = lv_label_create(minSection);
lv_obj_add_style(label, &text_28, 0);
lv_label_set_text(label, "мин.");
lv_obj_t *btnSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btnSection, 0, 0);
lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20));
lv_obj_set_style_pad_all(btnSection, 0, 0);
lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE);
btnOkScreen = lv_btn_create(btnSection);
lv_obj_add_event_cb(btnOkScreen, OkBtnScreenCb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btnOkScreen);
lv_obj_add_flag(btnOkScreen, LV_OBJ_FLAG_HIDDEN);
lv_obj_t *btnOkLabel = lv_label_create(btnOkScreen);
lv_obj_add_style(btnOkLabel, &text_28, 0);
lv_label_set_text(btnOkLabel, "Ок");
lv_obj_center(btnOkLabel);
lv_obj_add_event_cb(rollerScreenOff, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkScreen);
}
void createFiltersPage(lv_obj_t *parent) {
static const char *daysMap[] = {
"Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс", ""
};
lv_obj_t *mainSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(mainSection, 0, 0);
lv_obj_set_size(mainSection, LV_PCT(100), LV_PCT(80));
lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(mainSection, 0, 0);
lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE);
matrixFilterDays = lv_btnmatrix_create(mainSection);
lv_obj_add_style(matrixFilterDays, &text_24, 0);
lv_obj_set_style_bg_opa(matrixFilterDays, LV_OPA_TRANSP, LV_PART_MAIN);
lv_obj_set_style_border_width(matrixFilterDays, 0, 0);
lv_obj_set_style_bg_color(matrixFilterDays, lv_palette_main(LV_PALETTE_BLUE), LV_PART_ITEMS|LV_STATE_CHECKED);
lv_obj_set_style_pad_all(matrixFilterDays, 10, LV_PART_MAIN);
lv_obj_set_style_pad_gap(matrixFilterDays, 5, LV_PART_MAIN);
lv_btnmatrix_set_map(matrixFilterDays, daysMap);
lv_btnmatrix_set_btn_ctrl_all(matrixFilterDays, LV_BTNMATRIX_CTRL_CHECKABLE|LV_BTNMATRIX_CTRL_CLICK_TRIG);
lv_btnmatrix_set_one_checked(matrixFilterDays, true);
lv_btnmatrix_set_btn_ctrl(matrixFilterDays, 0, LV_BTNMATRIX_CTRL_CHECKED);
lv_obj_set_size(matrixFilterDays, LV_PCT(95), 60);
lv_obj_add_event_cb(matrixFilterDays, filterButtonsCb, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_t *labelCheckTime = lv_label_create(mainSection);
lv_obj_add_style(labelCheckTime, &text_28, 0);
lv_label_set_text(labelCheckTime, "Время проверки");
lv_obj_align(labelCheckTime, LV_ALIGN_TOP_MID, 0, 70);
lv_obj_t *timeRollersSection = lv_obj_create(mainSection);
lv_obj_set_style_bg_opa(timeRollersSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(timeRollersSection, 0, 0);
lv_obj_set_size(timeRollersSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(timeRollersSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(timeRollersSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(timeRollersSection, 10, 0);
lv_obj_remove_flag(timeRollersSection, LV_OBJ_FLAG_SCROLLABLE);
rollerFilterHour = createRoller(timeRollersSection, rollerOptionsHour, 4);
lv_obj_t *labelColon = lv_label_create(timeRollersSection);
lv_obj_add_style(labelColon, &text_28, 0);
lv_label_set_text(labelColon, ":");
rollerFilterMinute = createRoller(timeRollersSection, rollerOptionsMinute, 4);
lv_obj_t *btnSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btnSection, 0, 0);
lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20));
lv_obj_set_style_pad_all(btnSection, 0, 0);
lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE);
btnOkFilters = lv_btn_create(btnSection);
lv_obj_add_event_cb(btnOkFilters, OkBtnFiltersCb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btnOkFilters);
lv_obj_add_flag(btnOkFilters, LV_OBJ_FLAG_HIDDEN);
lv_obj_t *btnOkLabel = lv_label_create(btnOkFilters);
lv_obj_add_style(btnOkLabel, &text_28, 0);
lv_label_set_text(btnOkLabel, "Ок");
lv_obj_center(btnOkLabel);
lv_obj_add_event_cb(matrixFilterDays, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkFilters);
lv_obj_add_event_cb(rollerFilterHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkFilters);
lv_obj_add_event_cb(rollerFilterMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkFilters);
}
void createServiceTab(lv_obj_t *parent) {
passwordScreen = createPasswordInput(parent);
lv_obj_t *tabview = lv_tabview_create(parent);
lv_tabview_set_tab_bar_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 70);
lv_obj_add_flag(tabview, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_style(tabview, &text_20_semibold, 0);
lv_obj_add_event_cb(tabview, serviceTabviewEventCb, LV_EVENT_CLICKED, lv_tabview_get_tab_btns(tabview));
lv_obj_clear_flag(tabview, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
tabIntervals = lv_tabview_add_tab(tabview, "Интервалы");
tabPower = lv_tabview_add_tab(tabview, "Мощность");
tabTemperature = lv_tabview_add_tab(tabview, "Температура");
lv_obj_set_flex_flow(tabIntervals, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabIntervals, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabIntervals, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_flex_flow(tabPower, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabPower, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabPower, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_flex_flow(tabTemperature, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabTemperature, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(tabTemperature, LV_OBJ_FLAG_SCROLLABLE);
createIntervalsPage(tabIntervals);
createServicePowerPage(tabPower);
createTempAdjustPage(tabTemperature);
}
lv_obj_t *createPasswordInput(lv_obj_t *parent) {
// Create a container for better layout control
lv_obj_t *cont = lv_obj_create(parent);
lv_obj_set_size(cont, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
// Create the text area for password input
lv_obj_t* ta = lv_textarea_create(cont);
lv_obj_set_width(ta, LV_PCT(80));
lv_obj_set_height(ta, 50);
lv_textarea_set_password_mode(ta, true);
lv_textarea_set_one_line(ta, true);
lv_textarea_set_placeholder_text(ta, "Введите пароль");
lv_obj_add_style(ta, &text_28, 0);
lv_obj_set_align(ta, LV_ALIGN_TOP_MID);
lv_obj_t* kbContainer = lv_obj_create(cont);
lv_obj_set_size(kbContainer, 400, 225);
lv_obj_set_align(kbContainer, LV_ALIGN_BOTTOM_MID);
lv_obj_clear_flag(kbContainer, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_bg_color(kbContainer, lv_palette_lighten(LV_PALETTE_GREY, 3), 0);
lv_obj_set_style_border_width(kbContainer, 0, 0);
// Create the keyboard with specified layout
lv_obj_t* keyboard = lv_keyboard_create(kbContainer);
lv_obj_set_style_text_font(keyboard, &lv_font_montserrat_24, 0);
lv_obj_set_style_bg_opa(keyboard, LV_OPA_TRANSP, 0);
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kbMap, kbCtrlMap);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
lv_obj_set_size(keyboard, 400, 250);
lv_obj_align(keyboard, LV_ALIGN_CENTER, 0, 25);
lv_obj_add_event_cb(keyboard, passwordKeyboardEventCb, LV_EVENT_READY, NULL);
// Link the text area to the keyboard
lv_keyboard_set_textarea(keyboard, ta);
return cont;
}
void createIntervalsPage(lv_obj_t *parent) {
lv_obj_t *mainSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(mainSection, 0, 0);
lv_obj_set_size(mainSection, LV_PCT(105), LV_PCT(80));
lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(mainSection, 0, 0);
lv_obj_set_style_pad_ver(mainSection, 5, 0);
lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *tempSection = lv_obj_create(mainSection);
lv_obj_set_size(tempSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(tempSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(tempSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(tempSection, 0, 0);
lv_obj_set_style_pad_hor(tempSection, 10, 0);
lv_obj_set_style_pad_ver(tempSection, 4, 0);
lv_obj_t *title = lv_label_create(tempSection);
lv_label_set_text(title, "Интервал корректировки температуры (мин)");
lv_obj_add_style(title, &text_20, 0);
lv_obj_set_width(title, LV_PCT(55));
lv_obj_t *spinbox = createSpinbox(tempSection, 1, 5, 1, 1, 0);
spinboxTempInterval = lv_obj_get_child(spinbox, 1);
lv_obj_t *rotorPauseSection = lv_obj_create(mainSection);
lv_obj_set_size(rotorPauseSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(rotorPauseSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(rotorPauseSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(rotorPauseSection, 0, 0);
lv_obj_set_style_pad_hor(rotorPauseSection, 10, 0);
lv_obj_set_style_pad_ver(rotorPauseSection, 4, 0);
title = lv_label_create(rotorPauseSection);
lv_label_set_text(title, "Пауза между импульсами барабана (сек)");
lv_obj_add_style(title, &text_20, 0);
lv_obj_set_width(title, LV_PCT(55));
spinbox = createSpinbox(rotorPauseSection, 10, 120, 10, 3, 0);
spinboxRotorPause = lv_obj_get_child(spinbox, 1);
lv_obj_t *rotorPulseSection = lv_obj_create(mainSection);
lv_obj_set_size(rotorPulseSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(rotorPulseSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(rotorPulseSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(rotorPulseSection, 0, 0);
lv_obj_set_style_pad_hor(rotorPulseSection, 10, 0);
lv_obj_set_style_pad_ver(rotorPulseSection, 4, 0);
title = lv_label_create(rotorPulseSection);
lv_label_set_text(title, "Импульс барабана (мс)");
lv_obj_add_style(title, &text_20, 0);
lv_obj_set_width(title, LV_PCT(55));
spinbox = createSpinbox(rotorPulseSection, 100, 1000, 100, 4, 0);
spinboxRotorPulse = lv_obj_get_child(spinbox, 1);
lv_obj_t *rotorNumSection = lv_obj_create(mainSection);
lv_obj_set_size(rotorNumSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(rotorNumSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(rotorNumSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(rotorNumSection, 0, 0);
lv_obj_set_style_pad_hor(rotorNumSection, 10, 0);
lv_obj_set_style_pad_ver(rotorNumSection, 4, 0);
title = lv_label_create(rotorNumSection);
lv_label_set_text(title, "Количество барабанов");
lv_obj_add_style(title, &text_20, 0);
lv_obj_set_width(title, LV_PCT(55));
spinbox = createSpinbox(rotorNumSection, 1, 11, 1, 2, 0);
spinboxNumRotors = lv_obj_get_child(spinbox, 1);
lv_obj_t *btnSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btnSection, 0, 0);
lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20));
lv_obj_set_style_pad_all(btnSection, 0, 0);
lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE);
btnOkIntervals = lv_btn_create(btnSection);
lv_obj_add_event_cb(btnOkIntervals, OkBtnIntervalCb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btnOkIntervals);
lv_obj_add_flag(btnOkIntervals, LV_OBJ_FLAG_HIDDEN);
lv_obj_t *btnOkLabel = lv_label_create(btnOkIntervals);
lv_obj_add_style(btnOkLabel, &text_28, 0);
lv_label_set_text(btnOkLabel, "Ок");
lv_obj_center(btnOkLabel);
lv_obj_add_event_cb(spinboxTempInterval, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals);
lv_obj_add_event_cb(spinboxRotorPause, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals);
lv_obj_add_event_cb(spinboxRotorPulse, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals);
lv_obj_add_event_cb(spinboxNumRotors, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals);
}
void createServicePowerPage(lv_obj_t *parent) {
lv_obj_t *mainSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(mainSection, 0, 0);
lv_obj_set_size(mainSection, LV_PCT(105), LV_PCT(80));
lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(mainSection, 0, 0);
lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *topSection = lv_obj_create(mainSection);
lv_obj_set_style_bg_opa(topSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(topSection, 0, 0);
lv_obj_set_size(topSection, LV_PCT(105), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(topSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(topSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(topSection, 0, 0);
lv_obj_clear_flag(topSection, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *supplySection = lv_obj_create(topSection);
lv_obj_set_style_bg_opa(supplySection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(supplySection, 0, 0);
lv_obj_set_size(supplySection, LV_PCT(50), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(supplySection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(supplySection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(supplySection, 5, 0);
lv_obj_t *label = lv_label_create(supplySection);
lv_obj_add_style(label, &text_28, 0);
lv_label_set_text(label, "Приток");
lv_obj_t *rollerSection = lv_obj_create(supplySection);
lv_obj_set_style_bg_opa(rollerSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(rollerSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(rollerSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(rollerSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(rollerSection, 10, 0);
lv_obj_set_style_pad_column(rollerSection, 30, 0);
labelServiceSup = lv_label_create(rollerSection);
lv_obj_add_style(labelServiceSup, &text_28, 0);
char powerOptions[300] = "0\n";
createRollerOptions(20, 100, 1, 1, powerOptions + 2, sizeof(powerOptions - 2));
rollerServiceSup = createRoller(rollerSection, powerOptions, ROLLER_ROWS_DEFAULT);
ledSup = lv_led_create(rollerSection);
lv_led_set_color(ledSup, lv_palette_main(LV_PALETTE_GREEN));
lv_led_off(ledSup);
lv_obj_t *exhaustSection = lv_obj_create(topSection);
lv_obj_set_style_bg_opa(exhaustSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(exhaustSection, 0, 0);
lv_obj_set_size(exhaustSection, LV_PCT(50), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(exhaustSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(exhaustSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(exhaustSection, 5, 0);
label = lv_label_create(exhaustSection);
lv_obj_add_style(label, &text_28, 0);
lv_label_set_text(label, "Вытяжка");
rollerSection = lv_obj_create(exhaustSection);
lv_obj_set_style_bg_opa(rollerSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(rollerSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_flex_flow(rollerSection, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(rollerSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(rollerSection, 10, 0);
lv_obj_set_style_pad_column(rollerSection, 30, 0);
labelServiceExh = lv_label_create(rollerSection);
lv_obj_add_style(labelServiceExh, &text_28, 0);
rollerServiceExh = createRoller(rollerSection, powerOptions, ROLLER_ROWS_DEFAULT);
ledExh = lv_led_create(rollerSection);
lv_led_set_color(ledExh, lv_palette_main(LV_PALETTE_GREEN));
lv_led_off(ledExh);
lv_obj_t *btnSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btnSection, 0, 0);
lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20));
lv_obj_set_style_pad_all(btnSection, 0, 0);
lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE);
btnOkPower = lv_btn_create(btnSection);
lv_obj_add_event_cb(btnOkPower, OkBtnServicePowerCb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btnOkPower);
lv_obj_add_flag(btnOkPower, LV_OBJ_FLAG_HIDDEN);
lv_obj_t *btnOkLabel = lv_label_create(btnOkPower);
lv_obj_add_style(btnOkLabel, &text_28, 0);
lv_label_set_text(btnOkLabel, "Ок");
lv_obj_center(btnOkLabel);
lv_obj_add_event_cb(rollerServiceSup, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkPower);
lv_obj_add_event_cb(rollerServiceExh, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkPower);
}
void createTempAdjustPage(lv_obj_t *parent) {
const char* labels[] = {
"Приток с улицы",
"Приток в помещение",
"Вытяжка из помещения",
"Вытяжка на улицу"
};
lv_obj_t **tempLabels[] = {&labelServiceTempSupStreet, &labelServiceTempSupHome,
&labelServiceTempExhStreet, &labelServiceTempExhHome};
lv_obj_t **tempSettings[] = {&spinboxServiceTempSupStreet, &spinboxServiceTempSupHome,
&spinboxServiceTempExhStreet, &spinboxServiceTempExhHome};
lv_obj_t *mainSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(mainSection, 0, 0);
lv_obj_set_size(mainSection, LV_PCT(105), LV_PCT(80));
lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_all(mainSection, 0, 0);
lv_obj_set_style_pad_ver(mainSection, 5, 0);
lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE);
for (uint8_t i = 0; i < 4; i++) {
lv_obj_t *line = createTempSetting(mainSection, labels[i], tempLabels[i], tempSettings[i]);
}
lv_obj_t *btnSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(btnSection, 0, 0);
lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20));
lv_obj_set_style_pad_all(btnSection, 0, 0);
lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE);
btnOkTemperature = lv_btn_create(btnSection);
lv_obj_add_event_cb(btnOkTemperature, OkBtnTempAdjustCb, LV_EVENT_CLICKED, NULL);
lv_obj_center(btnOkTemperature);
lv_obj_add_flag(btnOkTemperature, LV_OBJ_FLAG_HIDDEN);
lv_obj_t *btnOkLabel = lv_label_create(btnOkTemperature);
lv_obj_add_style(btnOkLabel, &text_28, 0);
lv_label_set_text(btnOkLabel, "Ок");
lv_obj_center(btnOkLabel);
lv_obj_add_event_cb(spinboxServiceTempSupStreet, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature);
lv_obj_add_event_cb(spinboxServiceTempSupHome, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature);
lv_obj_add_event_cb(spinboxServiceTempExhStreet, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature);
lv_obj_add_event_cb(spinboxServiceTempExhHome, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature);
}
void createHelpTab(lv_obj_t *parent) {
lv_obj_t *tabview = lv_tabview_create(parent);
lv_tabview_set_tab_bar_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 70);
lv_obj_add_style(tabview, &text_20_semibold, 0);
lv_obj_clear_flag(tabview, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *tabDescr = lv_tabview_add_tab(tabview, "Описание");
lv_obj_t *tabState = lv_tabview_add_tab(tabview, "Состояние");
lv_obj_t *tabContacts = lv_tabview_add_tab(tabview, "Контакты");
lv_obj_set_flex_flow(tabDescr, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabDescr, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_set_flex_flow(tabState, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabState, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_flex_flow(tabContacts, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tabContacts, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
createDescrPage(tabDescr);
createStatePage(tabState);
createContactPage(tabContacts);
}
void createDescrPage(lv_obj_t *parent) {
lv_obj_t *label = lv_label_create(parent);
lv_obj_add_style(label, &text_24, 0);
lv_label_set_text(label,
"На Главной странице отображаются основные параметры работы установки.\n\n"
"В левом верхнем углу показан текущий режим работы - дневной или ночной.");
lv_obj_set_width(label, LV_PCT(100));
createSliderDescr(parent, "Показывает состояние приточного фильтра.", lv_palette_main(LV_PALETTE_BLUE));
createSliderDescr(parent, "Показывает состояние вытяжного фильтра.", lv_palette_main(LV_PALETTE_RED));
label = lv_label_create(parent);
lv_obj_add_style(label, &text_24, 0);
lv_label_set_text(label,
"Пустая шкала состояния фильтра означает, что фильтр засорен либо отсутствует.");
lv_obj_set_width(label, LV_PCT(100));
createArrowDescr(
parent,
"Обозначает направление движения приточного воздуха: температура на улице → температура в помещении.",
lv_palette_main(LV_PALETTE_BLUE), false
);
createArrowDescr(
parent,
"Обозначает направление движения вытяжного воздуха: температура на улице ← температура в помещении.",
lv_palette_main(LV_PALETTE_RED), true
);
label = lv_label_create(parent);
lv_obj_add_style(label, &text_24, 0);
lv_label_set_text(label,
"Переключатель \"Соблюдение баланса\" используется для включения автоматического поддержания "
"баланса между приточным и удаляемым воздухом. Эта функция включена по умолчанию. Рекомендуется "
"оставить включенным в исправной ПВУ.");
lv_obj_set_width(label, LV_PCT(100));
label = lv_label_create(parent);
lv_obj_add_style(label, &text_24, 0);
lv_label_set_text(label, "Кнопка для включения режима \"Ночного бриза\":");
lv_obj_set_width(label, LV_PCT(100));
createConditionerBtnMock(parent, "Выключено", lv_palette_main(LV_PALETTE_GREY));
createConditionerBtnMock(parent, "Включено", lv_palette_main(LV_PALETTE_BLUE));
createConditionerBtnMock(parent, "Недоступно", lv_palette_lighten(LV_PALETTE_GREY, 2));
label = lv_label_create(parent);
lv_obj_add_style(label, &text_24, 0);
lv_label_set_text(label,
"Кнопка \"Пуск/Стоп\" служит для запуска и остановки работы ПВУ.\n\n"
"Страница Настроек позволяет настроить мощность вентиляции в зависимости от времени "
"суток, текущие время и дату, время автоматического выключения экрана, "
"а также время проверки состояния фильтров.");
lv_obj_set_width(label, LV_PCT(100));
}
void createStatePage(lv_obj_t *parent) {
lv_obj_t *tempSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(tempSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(tempSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(tempSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(tempSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_set_style_pad_all(tempSection, 10, 0);
lv_obj_set_style_pad_hor(tempSection, 15, 0);
lv_obj_t *label = lv_label_create(tempSection);
lv_obj_add_style(label, &text_24_semibold, 0);
lv_label_set_text(label, "Температура");
createStateLine(tempSection, "Приток с улицы", &labelHelpTempSupStreet);
createStateLine(tempSection, "Приток в помещение", &labelHelpTempSupHome);
createStateLine(tempSection, "Вытяжка на улицу", &labelHelpTempExhStreet);
createStateLine(tempSection, "Вытяжка из помещения", &labelHelpTempExhHome);
createStateLine(tempSection, "КПД", &labelHelpKpd);
lv_obj_add_flag(labelHelpKpd, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(labelHelpKpd, kpdLabelCb, LV_EVENT_CLICKED, tempSection);
lv_obj_t *fanSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(fanSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(fanSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(fanSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(fanSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_set_style_pad_all(fanSection, 10, 0);
lv_obj_set_style_pad_hor(fanSection, 15, 0);
label = lv_label_create(fanSection);
lv_obj_add_style(label, &text_24_semibold, 0);
lv_label_set_text(label, "Мощность вентиляторов");
createStateLine(fanSection, "Приток", &labelHelpSup);
createStateLine(fanSection, "Вытяжка", &labelHelpExh);
rotorSection = lv_obj_create(parent);
lv_obj_set_style_bg_opa(rotorSection, LV_OPA_TRANSP, 0);
lv_obj_set_size(rotorSection, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_flex_flow(rotorSection, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(rotorSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_set_style_pad_all(rotorSection, 10, 0);
lv_obj_set_style_pad_hor(rotorSection, 15, 0);
label = lv_label_create(rotorSection);
lv_obj_add_style(label, &text_24_semibold, 0);
lv_label_set_text(label, "Скорость барабанов");
}
void createContactPage(lv_obj_t *parent) {
lv_obj_t *label = lv_label_create(parent);
lv_obj_add_style(label, &text_24, 0);
lv_label_set_text(label,
"Контактная информация представлена на нашем сайте:");
lv_obj_set_width(label, LV_PCT(100));
label = lv_label_create(parent);
lv_obj_add_style(label, &text_24_semibold, 0);
lv_label_set_text(label,
"https://vorteks.su/kontakty/");
lv_obj_set_width(label, LV_PCT(100));
label = lv_label_create(parent);
lv_obj_add_style(label, &text_24, 0);
lv_label_set_text(label,
"vorteks@vorteks.su\n\n"
"(383) 335-63-06,\n"
"(383) 363-10-28,\n"
"факс: 335-65-30.");
lv_obj_set_width(label, LV_PCT(100));
}
void createRotorSpeed(lv_obj_t *parent, uint8_t num) {
for (uint8_t i = 0; i < num; i++) {
char rotorText[20];
sprintf(rotorText, "Барабан %i", i + 1);
rotorSpeedLine[i] = createStateLine(parent, rotorText, &labelRotorSpeed[i]);
}
}
void createPopupScreen() {
lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_SCROLLABLE);
popupBg = lv_obj_create(lv_layer_top());
lv_obj_set_size(popupBg, LV_PCT(105), LV_PCT(105));
lv_obj_center(popupBg);
lv_obj_set_style_bg_color(popupBg, lv_color_black(), 0);
lv_obj_set_style_border_width(popupBg, 0, 0);
lv_obj_set_style_bg_opa(popupBg, LV_OPA_70, 0);
loadingLabel = lv_label_create(popupBg);
lv_obj_add_style(loadingLabel, &text_28, 0);
lv_label_set_text(loadingLabel, "Загрузка");
lv_obj_set_style_text_color(loadingLabel, lv_color_white(), 0);
lv_obj_center(loadingLabel);
}
void updateConfigWidgets() {
lv_obj_del(loadingLabel);
uint8_t hour, min;
lv_roller_set_selected(rollerDaymodePower, 30 - 20, LV_ANIM_OFF);
lv_roller_set_selected(rollerNightmodePower, 20 - 20, LV_ANIM_OFF);
lv_roller_set_selected(rollerDayHour, 10, LV_ANIM_OFF);
lv_roller_set_selected(rollerDayMinute, 0, LV_ANIM_OFF);
lv_roller_set_selected(rollerNightHour, 22, LV_ANIM_OFF);
lv_roller_set_selected(rollerNightMinute, 0, LV_ANIM_OFF);
selectedTestDay = 0;
lv_btnmatrix_set_selected_btn(matrixFilterDays, 0);
lv_btnmatrix_set_btn_ctrl(matrixFilterDays, 0, LV_BTNMATRIX_CTRL_CHECKED);
lv_roller_set_selected(rollerFilterHour, 12, LV_ANIM_OFF);
lv_roller_set_selected(rollerFilterMinute, 0, LV_ANIM_OFF);
createRotorSpeed(rotorSection, 1);
}
void updateWidgets() {
bool showPopup = false;
// errorMask = (uint64_t) 1 << 5;
for (uint8_t i = 0; i < 64; i++) {
if (!(errorMask & (uint64_t) 1 << i)) {
deletePopup(&popupWindows[i]);
continue;
}
if (!popupWindows[i].window) {
if (i == 0) {
createPopup(popupBg, "Нет соединения с главным модулем", false, 0, &popupWindows[0]);
}
if (i == ERROR_FILT_SUP_MISSING) {
createPopup(popupBg, "Отсутствует приточный фильтр", true, i, &popupWindows[i]);
} else if (i == ERROR_FILT_EXH_MISSING) {
createPopup(popupBg, "Отсутствует вытяжной фильтр", true, i, &popupWindows[i]);
} else if (i == ERROR_FILT_SUP_DIRTY) {
createPopup(popupBg, "Засорен приточный фильтр", true, i, &popupWindows[i]);
} else if (i == ERROR_FILT_EXH_DIRTY) {
createPopup(popupBg, "Засорен вытяжной фильтр", true, i, &popupWindows[i]);
} else if (ERROR_ROTOR_BASE <= i && i < ERROR_MODULE_BASE) {
char errText[150] = {0};
sprintf(errText, "Неисправен барабан %u. Устраните неисправность и перезагрузите устройство.",
i - ERROR_ROTOR_BASE + 1);
createPopup(popupBg, errText, false, i, &popupWindows[i]);
} else if (ERROR_MODULE_BASE <= i) {
char errText[100] = {0};
sprintf(errText, "Нет соединения с модулем расширения %u", i - ERROR_MODULE_BASE + 1);
createPopup(popupBg, errText, true, i, &popupWindows[i]);
}
}
if (!popupWindows[i].ignored) {
showPopup = true;
}
}
if (showPopup) {
lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_HIDDEN);
} else {
lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_HIDDEN);
}
lv_img_set_src(imgMode, &sun_yellow);
// lv_img_set_src(imgMode, &moon_purple);
lv_slider_set_value(sliderFilterSup, 0, LV_ANIM_ON);
lv_slider_set_value(sliderFilterExh, 0, LV_ANIM_ON);
static const char *const months[] = {
"января", "февраля", "марта", "апреля", "мая", "июня",
"июля", "августа", "сентября", "октября", "ноября", "декабря"
};
lv_label_set_text_fmt(dateLabel, "%u %s", 1, months[1 - 1]);
lv_label_set_text(dayLabel, days[2]);
lv_label_set_text_fmt(timeLabel, "%02i:%02i", 12, 0);
lv_label_set_text_fmt(powerMainLabel, "Мощность: %u%%", state.speedB4);
lv_label_set_text_fmt(labelTempSupStreet, "%.1f °C", state.te1 / 10.0f);
lv_label_set_text_fmt(labelTempSupHome, "%.1f °C", state.te4 / 10.0f);
lv_label_set_text_fmt(labelTempExhStreet, "%.1f °C", state.te3 / 10.0f);
lv_label_set_text_fmt(labelTempExhHome, "%.1f °C", state.te2 / 10.0f);
bool isStarted = state.mode & 0x01;
if (isStarted && !btnStartStopIsStop) {
setStartStopButtonState(true);
} else if (!isStarted && btnStartStopIsStop) {
setStartStopButtonState(false);
}
lv_label_set_text_fmt(labelServiceSup, "%u%%", state.speedB4);
lv_label_set_text_fmt(labelServiceExh, "%u%%", state.speedB3);
lv_led_on(ledSup);
// lv_led_off(ledSup);
// lv_led_on(ledExh);
lv_led_off(ledExh);
lv_label_set_text_fmt(labelServiceTempSupStreet, "%.1f °C", state.te1 / 10.0f);
lv_label_set_text_fmt(labelServiceTempSupHome, "%.1f °C", state.te4 / 10.0f);
lv_label_set_text_fmt(labelServiceTempExhStreet, "%.1f °C", state.te3 / 10.0f);
lv_label_set_text_fmt(labelServiceTempExhHome, "%.1f °C", state.te2 / 10.0f);
if (state.te1 <= -100) { // *10
disableConditionerBtn();
} else {
enableConditionerBtn();
}
lv_label_set_text_fmt(labelHelpTempSupStreet, "%.1f °C", state.te1 / 10.0f);
lv_label_set_text_fmt(labelHelpTempSupHome, "%.1f °C", state.te4 / 10.0f);
lv_label_set_text_fmt(labelHelpTempExhStreet, "%.1f °C", state.te3 / 10.0f);
lv_label_set_text_fmt(labelHelpTempExhHome, "%.1f °C", state.te2 / 10.0f);
if (state.kpd == KPD_NONE * 10) {
lv_label_set_text(labelHelpKpd, "-");
} else {
lv_label_set_text_fmt(labelHelpKpd, "%.1f%%", state.kpd / 10.0f);
if (kpdHint) {
lv_obj_del(kpdHint);
kpdHint = NULL;
}
}
lv_label_set_text_fmt(labelHelpSup, "%u%%", 30);
lv_label_set_text_fmt(labelHelpExh, "%u%%", 30);
lv_label_set_text_fmt(labelRotorSpeed[0], "%.2f об./час", (float) 100 / 100.0f);
}
void enableConditionerBtn() {
if (btnConditionerEnabled) return;
lv_obj_t *icon = lv_obj_get_child(btnConditioner, 0);
btnConditionerState = false;
lv_obj_set_style_border_color(btnConditioner, lv_palette_main(LV_PALETTE_GREY), 0);
lv_obj_set_style_text_color(icon, lv_palette_main(LV_PALETTE_GREY), 0);
lv_obj_add_flag(btnConditioner, LV_OBJ_FLAG_CLICKABLE);
btnConditionerEnabled = true;
}
void disableConditionerBtn() {
if (!btnConditionerEnabled) return;
lv_obj_t *icon = lv_obj_get_child(btnConditioner, 0);
btnConditionerState = false;
lv_obj_set_style_border_color(btnConditioner, lv_palette_lighten(LV_PALETTE_GREY, 2), 0);
lv_obj_set_style_text_color(icon, lv_palette_lighten(LV_PALETTE_GREY, 2), 0);
lv_obj_clear_flag(btnConditioner, LV_OBJ_FLAG_CLICKABLE);
btnConditionerEnabled = false;
}
void setConditionerBtnState(bool state) {
if (btnConditionerState == state || !btnConditionerEnabled) return;
lv_obj_t *btn = btnConditioner;
lv_obj_t *icon = lv_obj_get_child(btn, 0);
if (state) {
lv_obj_set_style_border_color(btn, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_set_style_text_color(icon, lv_palette_main(LV_PALETTE_BLUE), 0);
} else {
lv_obj_set_style_border_color(btn, lv_palette_main(LV_PALETTE_GREY), 0);
lv_obj_set_style_text_color(icon, lv_palette_main(LV_PALETTE_GREY), 0);
}
btnConditionerState = state;
}
void setStartStopButtonState(bool isStop) {
lv_obj_t *btn = btnStartStop;
lv_obj_t *label = lv_obj_get_child(btn, 0);
if (isStop) {
lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN);
lv_label_set_text(label, "Стоп");
lv_obj_center(label);
} else {
lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_BLUE), LV_PART_MAIN);
lv_label_set_text(label, "Пуск");
lv_obj_center(label);
}
btnStartStopIsStop = isStop;
}
/* Callbacks */
static void passwordKeyboardEventCb(lv_event_t *e) {
lv_obj_t *keyboard = lv_event_get_target(e);
lv_obj_t *textArea = lv_keyboard_get_textarea(keyboard);
lv_obj_t *mainScreen = lv_obj_get_child(tabService, 1);
if (lv_event_get_code(e) == LV_EVENT_READY) {
if (textArea) {
int value = atoi(lv_textarea_get_text(textArea));
lv_textarea_set_text(textArea, "");
if (value == PASSWORD) {
lv_obj_add_flag(passwordScreen, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(mainScreen, LV_OBJ_FLAG_HIDDEN);
bool isStarted = state.mode & 0x01;
uint16_t selectedOptionB3 = 0;
uint16_t selectedOptionB4 = 0;
if (isStarted) {
selectedOptionB3 = CLAMP(state.speedB3, 20, 100) - 19;
selectedOptionB4 = CLAMP(state.speedB4, 20, 100) - 19;
}
lv_roller_set_selected(rollerServiceSup, selectedOptionB4, LV_ANIM_OFF);
lv_roller_set_selected(rollerServiceExh, selectedOptionB3, LV_ANIM_OFF);
}
}
}
}
static void mainTabviewEventCb(lv_event_t *e) {
lv_obj_t *matrix = lv_event_get_user_data(e);
uint16_t currentTabId = lv_btnmatrix_get_selected_btn(matrix);
// Get references to the service tab screens (assuming they're children of tabService)
lv_obj_t *passwordScreen = lv_obj_get_child(tabService, 0); // First child
lv_obj_t *mainScreen = lv_obj_get_child(tabService, 1); // Second child
if (currentTabId != TAB_SERVICE_ID) {
lv_obj_clear_flag(passwordScreen, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(mainScreen, LV_OBJ_FLAG_HIDDEN);
}
clearCurrentTab();
if (currentTabId == TAB_SETTINGS_ID) {
currentTab = getActiveTabSettings(lv_tabview_get_tab_btns(tabSettings));
} else if (currentTabId == TAB_SERVICE_ID) {
currentTab = getActiveTabService(lv_tabview_get_tab_btns(tabService));
} else {
currentTab = NULL;
}
}
static void settingsTabviewEventCb(lv_event_t *e) {
clearCurrentTab();
currentTab = getActiveTabSettings(lv_event_get_user_data(e));
lv_roller_set_selected(rollerMinute, state.time % 60, LV_ANIM_OFF);
lv_roller_set_selected(rollerHour, state.time / 60, LV_ANIM_OFF);
lv_dropdown_set_selected(ddDay, state.date - 1);
lv_dropdown_set_selected(ddMonth, state.month - 1);
lv_dropdown_set_selected(ddYear, state.year - 2025);
}
static void serviceTabviewEventCb(lv_event_t *e) {
clearCurrentTab();
currentTab = getActiveTabService(lv_event_get_user_data(e));
}
static lv_obj_t *getActiveTabSettings(lv_obj_t *matrix) {
uint16_t currentTabId = lv_btnmatrix_get_selected_btn(matrix);
if (currentTabId == TAB_MODES) return tabSettingsModeTime;
else if (currentTabId == TAB_TIME) return tabSettingsTime;
else if (currentTabId == TAB_SCREEN) return tabSettingsScreen;
else if (currentTabId == TAB_FILTERS) return tabFilters;
else return NULL;
}
static lv_obj_t *getActiveTabService(lv_obj_t *matrix) {
uint16_t currentTabId = lv_btnmatrix_get_selected_btn(matrix);
if (currentTabId == TAB_INTERVALS) return tabIntervals;
else if (currentTabId == TAB_POWER) return tabPower;
else if (currentTabId == TAB_TEMPERATURE) return tabTemperature;
else return NULL;
}
static void filterButtonsCb(lv_event_t *e) {
selectedTestDay = lv_btnmatrix_get_selected_btn(matrixFilterDays);
}
static void balanceSwitchCb(lv_event_t *e) {}
static void startStopBtnCb(lv_event_t *e) {
setStartStopButtonState(!btnStartStopIsStop);
}
static void conditionerBtnCb(lv_event_t *e) {
if (!btnConditionerEnabled) return;
setConditionerBtnState(!btnConditionerState);
}
static void valueChangedCb(lv_event_t *e) {
lv_obj_t *associatedBtn = lv_event_get_user_data(e);
lv_obj_remove_flag(associatedBtn, LV_OBJ_FLAG_HIDDEN);
}
static void OkBtnModeTimeCb(lv_event_t *e) {
lv_obj_t *btn = lv_event_get_target(e);
lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN);
}
static void OkBtnTimeCb(lv_event_t *e) {
lv_obj_t *btn = lv_event_get_target(e);
lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN);
}
static void OkBtnScreenCb(lv_event_t *e) {
lv_obj_t *btn = lv_event_get_target(e);
lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN);
}
static void OkBtnFiltersCb(lv_event_t *e) {
lv_obj_t *btn = lv_event_get_target(e);
lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN);
}
static void OkBtnIntervalCb(lv_event_t *e) {
lv_obj_t *btn = lv_event_get_target(e);
lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN);
}
static void OkBtnServicePowerCb(lv_event_t *e) {
lv_obj_t *btn = lv_event_get_target(e);
lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN);
}
static void OkBtnTempAdjustCb(lv_event_t *e) {
lv_obj_t *btn = lv_event_get_target(e);
lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN);
}
static void kpdLabelCb(lv_event_t *e) {
lv_obj_t *parent = lv_event_get_user_data(e);
lv_obj_t *kpdLabel = lv_event_get_target(e);
if (strcmp(lv_label_get_text(kpdLabel), "-") != 0) return;
if (kpdHint) {
lv_obj_del(kpdHint);
kpdHint = NULL;
return;
}
kpdHint = lv_label_create(parent);
lv_obj_add_style(kpdHint, &text_24, 0);
lv_obj_set_width(kpdHint, LV_PCT(100));
lv_label_set_text(kpdHint, "Значение КПД неактуально, когда разница температур внутри и снаружи меньше 10°C.");
}
static void ddDateCb(lv_event_t *e) {
static const uint8_t monTable[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
uint16_t year = lv_dropdown_get_selected(ddYear) + 2025;
uint16_t month = lv_dropdown_get_selected(ddMonth) + 1;
uint16_t date = lv_dropdown_get_selected(ddDay) + 1;
uint8_t numDays = isLeapYear(year) && month == 2 ? 29 : monTable[month - 1];
if (numDays == lv_dropdown_get_option_cnt(ddDay)) return;
char optionsDay[128] = {0};
createRollerOptions(1, numDays, 1, 1, optionsDay, sizeof(optionsDay));
lv_dropdown_set_options(ddDay, optionsDay);
lv_dropdown_set_selected(ddDay, MIN(date, numDays) - 1);
}
static void timePageClickedCb(lv_event_t *e) {
}
static void clearModesTab() {
// uint8_t hour, min;
// lv_roller_set_selected(rollerDaymodePower, CLAMP(config.daySpeed, 20, 90) - 20, LV_ANIM_OFF);
// lv_roller_set_selected(rollerNightmodePower, CLAMP(config.nightSpeed, 20, 90) - 20, LV_ANIM_OFF);
// hour = config.dayStart / 60;
// min = config.dayStart % 60;
// lv_roller_set_selected(rollerDayHour, hour, LV_ANIM_OFF);
// lv_roller_set_selected(rollerDayMinute, min, LV_ANIM_OFF);
// hour = config.nightStart / 60;
// min = config.nightStart % 60;
// lv_roller_set_selected(rollerNightHour, hour, LV_ANIM_OFF);
// lv_roller_set_selected(rollerNightMinute, min, LV_ANIM_OFF);
lv_obj_add_flag(btnOkModes, LV_OBJ_FLAG_HIDDEN);
}
static void clearTimeTab() {
lv_roller_set_selected(rollerMinute, state.time % 60, LV_ANIM_OFF);
lv_roller_set_selected(rollerHour, state.time / 60, LV_ANIM_OFF);
lv_dropdown_set_selected(ddDay, state.date - 1);
lv_dropdown_set_selected(ddMonth, state.month - 1);
lv_dropdown_set_selected(ddYear, state.year - 2025);
lv_obj_add_flag(btnOkTime, LV_OBJ_FLAG_HIDDEN);
}
static void clearScreenTab() {
// lv_roller_set_selected(rollerScreenOff, config.screenOff, LV_ANIM_OFF);
lv_obj_add_flag(btnOkScreen, LV_OBJ_FLAG_HIDDEN);
}
static void clearFiltersTab() {
// selectedTestDay = config.testDay;
// lv_btnmatrix_set_selected_btn(matrixFilterDays, config.testDay);
// lv_btnmatrix_set_btn_ctrl(matrixFilterDays, config.testDay, LV_BTNMATRIX_CTRL_CHECKED);
// hour = config.testTime / 60;
// min = config.testTime % 60;
// lv_roller_set_selected(rollerFilterHour, hour, LV_ANIM_OFF);
// lv_roller_set_selected(rollerFilterMinute, min, LV_ANIM_OFF);
lv_obj_add_flag(btnOkFilters, LV_OBJ_FLAG_HIDDEN);
}
static void clearIntervalsTab() {
// lv_spinbox_set_value(spinboxTempInterval, config.adjustInterval);
// lv_spinbox_set_value(spinboxRotorPause, config.rotorPause);
// lv_spinbox_set_value(spinboxRotorPulse, config.rotorImpulse);
// lv_spinbox_set_value(spinboxNumRotors, config.numRotors);
lv_obj_add_flag(btnOkIntervals, LV_OBJ_FLAG_HIDDEN);
}
static void clearPowerTab() {
bool isStarted = state.mode & 0x01;
uint16_t selectedOptionB3 = 0;
uint16_t selectedOptionB4 = 0;
if (isStarted) {
selectedOptionB3 = CLAMP(state.speedB3, 20, 100) - 19;
selectedOptionB4 = CLAMP(state.speedB4, 20, 100) - 19;
}
lv_roller_set_selected(rollerServiceSup, selectedOptionB4, LV_ANIM_OFF);
lv_roller_set_selected(rollerServiceExh, selectedOptionB3, LV_ANIM_OFF);
lv_obj_add_flag(btnOkPower, LV_OBJ_FLAG_HIDDEN);
}
static void clearTemperatureTab() {
// lv_spinbox_set_value(spinboxServiceTempSupStreet, config.temperatureCorrections[0]);
// lv_spinbox_set_value(spinboxServiceTempSupHome, config.temperatureCorrections[3]);
// lv_spinbox_set_value(spinboxServiceTempExhStreet, config.temperatureCorrections[2]);
// lv_spinbox_set_value(spinboxServiceTempExhHome, config.temperatureCorrections[1]);
lv_obj_add_flag(btnOkTemperature, LV_OBJ_FLAG_HIDDEN);
}
static void clearCurrentTab() {
if (currentTab == tabSettingsModeTime) {
clearModesTab();
} else if (currentTab == tabSettingsTime) {
clearTimeTab();
} else if (currentTab == tabSettingsScreen) {
clearScreenTab();
} else if (currentTab == tabFilters) {
clearFiltersTab();
} else if (currentTab == tabIntervals) {
clearIntervalsTab();
} else if (currentTab == tabPower) {
clearPowerTab();
} else if (currentTab == tabTemperature) {
clearTemperatureTab();
}
}