From 3cd2e6e8f2889c5a7c727ca70224f0e4cadf53b7 Mon Sep 17 00:00:00 2001 From: 01trisha Date: Wed, 4 Mar 2026 21:42:28 +0700 Subject: [PATCH] new ver --- .gitignore | 3 + src/gui_generated.c | 1843 +++++++++++++++++++++++++++---------------- 2 files changed, 1154 insertions(+), 692 deletions(-) diff --git a/.gitignore b/.gitignore index b48d0b8..e64ed3c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ ui/ .vscode .DS_Store + +src/gui_generated.c.bak +src/gui_generated.c.bak2 diff --git a/src/gui_generated.c b/src/gui_generated.c index 8ae31e9..ed88b56 100644 --- a/src/gui_generated.c +++ b/src/gui_generated.c @@ -142,6 +142,14 @@ static module_config_t modules[MODULE_COUNT] = { /* Panel for schema (needed globally for drag) */ static lv_obj_t *schema_panel = NULL; +/* Mode control buttons */ +static lv_obj_t *btn_stop_mode = NULL; +static lv_obj_t *btn_standby_mode = NULL; +static lv_obj_t *btn_work_mode = NULL; +static lv_obj_t *lbl_stop_mode = NULL; +static lv_obj_t *lbl_standby_mode = NULL; +static lv_obj_t *lbl_work_mode = NULL; + /* Pipe placeholders for inactive modules in active line */ static lv_obj_t *pipe_placeholders[MODULE_COUNT] = {NULL}; @@ -156,11 +164,28 @@ typedef struct { char message[80]; char timestamp[20]; int active; + int confirmed; /* 1=подтверждена */ + char confirm_timestamp[20]; /* дата подтверждения */ } alarm_entry_t; static alarm_entry_t alarm_log[MAX_ALARMS]; static int alarm_count = 0; +/* Pagination state for alarm log */ +static int alarm_page = 0; +#define ALARMS_PER_PAGE 4 + +/* Pagination state for setpoints (Work mode) */ +static int setpoint_work_page = 0; +#define SETPOINTS_PER_PAGE 4 + +/* Pagination state for setpoints (Standby mode) */ +static int setpoint_standby_page = 0; + +/* Pagination state for config screen */ +static int config_page = 0; +#define CONFIG_ITEMS_PER_PAGE 6 + /* Settings/Setpoints for Work and Standby modes */ typedef struct { float temp; /* Температура */ @@ -290,10 +315,20 @@ static void create_screen_screen2(void); static void module_drag_cb(lv_event_t *e); static void update_module_display(int module_idx); static void refresh_setpoints_display(void); -static void btn_reset_alarm_cb(lv_event_t *e); +static void btn_confirm_alarm_cb(lv_event_t *e); +static void btn_alarm_page_prev_cb(lv_event_t *e); +static void btn_alarm_page_next_cb(lv_event_t *e); static void btn_clear_log_cb(lv_event_t *e); +static void btn_setpoint_work_prev_cb(lv_event_t *e); +static void btn_setpoint_work_next_cb(lv_event_t *e); +static void btn_setpoint_standby_prev_cb(lv_event_t *e); +static void btn_setpoint_standby_next_cb(lv_event_t *e); +static void btn_config_page_prev_cb(lv_event_t *e); +static void btn_config_page_next_cb(lv_event_t *e); +static void create_screen_screen3(void); static lv_obj_t* create_module_widget(lv_obj_t *parent, int module_idx, int x, int y); static void update_module_positions(void); +static void update_mode_button_colors(void); /* Get image for module type */ static const lv_image_dsc_t* get_module_image(int module_idx) { @@ -367,35 +402,49 @@ static void module_drag_cb(lv_event_t *e) { /* Check if module should be enabled/disabled based on Y position */ lv_coord_t y = lv_obj_get_y(obj); int threshold = (MODULES_ACTIVE_Y + MODULES_INACTIVE_Y) / 2; - + if (y < threshold) { modules[module_idx].enabled = 1; } else { modules[module_idx].enabled = 0; } - + /* Reposition all modules */ update_module_positions(); } } -/* Update positions of all modules (pipe line is continuous background) */ +/* Update positions of all modules and pipe placeholders */ static void update_module_positions(void) { int active_x = 50; /* Start after the inlet pipe */ int inactive_x = 10; - + for (int i = 0; i < MODULE_COUNT; i++) { if (modules[i].obj == NULL) continue; - + if (modules[i].enabled) { /* Module is active - position it on the active line */ lv_obj_set_pos(modules[i].obj, active_x, MODULES_ACTIVE_Y); + lv_obj_clear_flag(modules[i].obj, LV_OBJ_FLAG_HIDDEN); + + /* Hide pipe placeholder if exists */ + if (pipe_placeholders[i]) { + lv_obj_add_flag(pipe_placeholders[i], LV_OBJ_FLAG_HIDDEN); + } + active_x += MODULE_WIDTH + MODULE_SPACING; } else { - /* Module is inactive - move to inactive area, pipe line shows through */ - active_x += MODULE_WIDTH + MODULE_SPACING; /* Reserve space on pipe line */ - + /* Module is inactive - move to inactive area */ lv_obj_set_pos(modules[i].obj, inactive_x, MODULES_INACTIVE_Y); + lv_obj_clear_flag(modules[i].obj, LV_OBJ_FLAG_HIDDEN); + + /* Show pipe placeholder on active line */ + if (pipe_placeholders[i]) { + lv_obj_set_pos(pipe_placeholders[i], active_x, MODULES_ACTIVE_Y); + lv_obj_clear_flag(pipe_placeholders[i], LV_OBJ_FLAG_HIDDEN); + } + + active_x += MODULE_WIDTH + MODULE_SPACING; inactive_x += MODULE_WIDTH + MODULE_SPACING; } } @@ -413,7 +462,7 @@ static lv_obj_t* create_module_widget(lv_obj_t *parent, int module_idx, int x, i lv_obj_set_style_border_color(cont, lv_color_hex(COLOR_BORDER), 0); lv_obj_set_style_pad_all(cont, 2, 0); lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); - + /* Add drag flag */ lv_obj_add_flag(cont, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_event_cb(cont, module_drag_cb, LV_EVENT_PRESSING, (void*)(intptr_t)module_idx); @@ -430,26 +479,26 @@ static lv_obj_t* create_module_widget(lv_obj_t *parent, int module_idx, int x, i lv_obj_t *img = lv_image_create(cont); lv_image_set_src(img, get_module_image(module_idx)); lv_image_set_scale(img, MODULE_SCALE); - lv_obj_align(img, LV_ALIGN_CENTER, 0, 5); - + lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); + /* Value label at bottom */ lv_obj_t *lbl_value = lv_label_create(cont); lv_obj_align(lbl_value, LV_ALIGN_BOTTOM_MID, 0, -2); lv_obj_set_style_text_color(lbl_value, lv_color_hex(COLOR_TEXT_ACCENT), 0); lv_obj_set_style_text_font(lbl_value, &montserrat_16_ru_en, 0); - + modules[module_idx].obj = cont; modules[module_idx].img = img; modules[module_idx].label_name = lbl_name; modules[module_idx].label_value = lbl_value; - + return cont; } /* Apply setpoints to system state based on current mode */ static void apply_mode_setpoints(void) { setpoint_mode_t *sp = (state.mode == 2) ? &setpoint_work : &setpoint_standby; - + if (state.mode == 0) { /* Остановка - выключаем только активные элементы (вентилятор, нагреватель) */ /* Клапаны остаются на своих позициях */ @@ -459,10 +508,10 @@ static void apply_mode_setpoints(void) { /* Дежурный или Рабочий режим - применяем уставки */ state.valve_inlet = (uint8_t)sp->valve_inlet; state.valve_recirc = (uint8_t)sp->valve_recirc; - + /* Вентилятор по уставке */ state.fan_on = sp->fan; - + /* Электронагреватель по уставке */ if (sp->heater == 0) { state.heater_on = 0; /* ВЫКЛ */ @@ -470,7 +519,7 @@ static void apply_mode_setpoints(void) { state.heater_on = 1; /* ВКЛ */ } /* heater == 2 (АВТО) - управляется автоматикой */ - + /* KWS и PWW */ if (!sp->kws_auto) { state.kws_valve = (uint8_t)sp->kws_manual; @@ -481,11 +530,40 @@ static void apply_mode_setpoints(void) { } } +/* Update mode button colors based on current mode */ +static void update_mode_button_colors(void) { + if (!btn_stop_mode || !btn_standby_mode || !btn_work_mode) return; + if (!lbl_stop_mode || !lbl_standby_mode || !lbl_work_mode) return; + + /* Reset all buttons to default color */ + lv_obj_set_style_bg_color(btn_stop_mode, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_bg_color(btn_standby_mode, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_bg_color(btn_work_mode, lv_color_hex(COLOR_BG_BTN), 0); + + /* Reset text colors to original */ + lv_obj_set_style_text_color(lbl_stop_mode, lv_color_hex(COLOR_DANGER), 0); + lv_obj_set_style_text_color(lbl_standby_mode, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_color(lbl_work_mode, lv_color_hex(COLOR_ACCENT), 0); + + /* Highlight active mode button with background and change text to black */ + if (state.mode == 0) { + lv_obj_set_style_bg_color(btn_stop_mode, lv_color_hex(COLOR_DANGER), 0); + lv_obj_set_style_text_color(lbl_stop_mode, lv_color_hex(0x000000), 0); + } else if (state.mode == 1) { + lv_obj_set_style_bg_color(btn_standby_mode, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_color(lbl_standby_mode, lv_color_hex(0x000000), 0); + } else if (state.mode == 2) { + lv_obj_set_style_bg_color(btn_work_mode, lv_color_hex(COLOR_ACCENT), 0); + lv_obj_set_style_text_color(lbl_work_mode, lv_color_hex(0x000000), 0); + } +} + /* Button callbacks */ static void btn_stop_cb(lv_event_t *e) { (void)e; state.mode = 0; apply_mode_setpoints(); + update_mode_button_colors(); gui_update_values(); } @@ -493,6 +571,7 @@ static void btn_standby_cb(lv_event_t *e) { (void)e; state.mode = 1; apply_mode_setpoints(); + update_mode_button_colors(); gui_update_values(); } @@ -500,6 +579,7 @@ static void btn_work_cb(lv_event_t *e) { (void)e; state.mode = 2; apply_mode_setpoints(); + update_mode_button_colors(); gui_update_values(); } @@ -518,14 +598,13 @@ static void btn_readings_cb(lv_event_t *e) { create_popup_readings(); } -static void btn_reset_alarm_cb(lv_event_t *e) { - (void)e; - /* Reset first active alarm */ - for (int i = 0; i < alarm_count; i++) { - if (alarm_log[i].active) { - alarm_log[i].active = 0; - break; - } +static void btn_confirm_alarm_cb(lv_event_t *e) { + int alarm_idx = (int)(intptr_t)lv_event_get_user_data(e); + if (alarm_idx >= 0 && alarm_idx < alarm_count) { + alarm_log[alarm_idx].confirmed = 1; + alarm_log[alarm_idx].active = 0; + snprintf(alarm_log[alarm_idx].confirm_timestamp, 20, "%02d.%02d.%04d %02d:%02d", + state.day, state.month, state.year, state.hour, state.minute); } /* Refresh journal screen */ if (scr_screen2) { @@ -536,6 +615,33 @@ static void btn_reset_alarm_cb(lv_event_t *e) { lv_scr_load(scr_screen2); } +static void btn_alarm_page_prev_cb(lv_event_t *e) { + (void)e; + if (alarm_page > 0) { + alarm_page--; + if (scr_screen2) { + lv_obj_del(scr_screen2); + scr_screen2 = NULL; + } + create_screen_screen2(); + lv_scr_load(scr_screen2); + } +} + +static void btn_alarm_page_next_cb(lv_event_t *e) { + (void)e; + int total_pages = (alarm_count + ALARMS_PER_PAGE - 1) / ALARMS_PER_PAGE; + if (alarm_page < total_pages - 1) { + alarm_page++; + if (scr_screen2) { + lv_obj_del(scr_screen2); + scr_screen2 = NULL; + } + create_screen_screen2(); + lv_scr_load(scr_screen2); + } +} + static void btn_clear_log_cb(lv_event_t *e) { (void)e; /* Check if any active alarms */ @@ -548,6 +654,7 @@ static void btn_clear_log_cb(lv_event_t *e) { } if (!has_active) { alarm_count = 0; + alarm_page = 0; /* Refresh journal screen */ if (scr_screen2) { lv_obj_del(scr_screen2); @@ -558,6 +665,90 @@ static void btn_clear_log_cb(lv_event_t *e) { } } +/* Setpoints pagination callbacks - Work mode */ +static void btn_setpoint_work_prev_cb(lv_event_t *e) { + (void)e; + if (setpoint_work_page > 0) { + setpoint_work_page--; + if (scr_screen3) { + lv_obj_del(scr_screen3); + scr_screen3 = NULL; + } + create_screen_screen3(); + lv_scr_load(scr_screen3); + } +} + +static void btn_setpoint_work_next_cb(lv_event_t *e) { + (void)e; + /* 8 parameters total, 4 per page = 2 pages */ + if (setpoint_work_page < 1) { + setpoint_work_page++; + if (scr_screen3) { + lv_obj_del(scr_screen3); + scr_screen3 = NULL; + } + create_screen_screen3(); + lv_scr_load(scr_screen3); + } +} + +/* Setpoints pagination callbacks - Standby mode */ +static void btn_setpoint_standby_prev_cb(lv_event_t *e) { + (void)e; + if (setpoint_standby_page > 0) { + setpoint_standby_page--; + if (scr_screen3) { + lv_obj_del(scr_screen3); + scr_screen3 = NULL; + } + create_screen_screen3(); + lv_scr_load(scr_screen3); + } +} + +static void btn_setpoint_standby_next_cb(lv_event_t *e) { + (void)e; + /* 8 parameters total, 4 per page = 2 pages */ + if (setpoint_standby_page < 1) { + setpoint_standby_page++; + if (scr_screen3) { + lv_obj_del(scr_screen3); + scr_screen3 = NULL; + } + create_screen_screen3(); + lv_scr_load(scr_screen3); + } +} + +/* Config pagination callbacks */ +static void btn_config_page_prev_cb(lv_event_t *e) { + (void)e; + if (config_page > 0) { + config_page--; + if (scr_screen4) { + lv_obj_del(scr_screen4); + scr_screen4 = NULL; + } + create_screen_config(); + lv_scr_load(scr_screen4); + } +} + +static void btn_config_page_next_cb(lv_event_t *e) { + (void)e; + /* Total ~15 items, 6 per page = 3 pages */ + if (config_page < 2) { + config_page++; + if (scr_screen4) { + lv_obj_del(scr_screen4); + scr_screen4 = NULL; + } + create_screen_config(); + lv_scr_load(scr_screen4); + } +} + static void close_popup_cb(lv_event_t *e) { lv_obj_t *popup = lv_event_get_user_data(e); if (popup) { @@ -903,6 +1094,7 @@ static void create_popup_datetime(void) { lv_obj_set_size(roller_day, 60, 80); lv_obj_set_style_text_font(roller_day, &montserrat_16_ru_en, 0); lv_obj_set_style_bg_color(roller_day, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_text_color(roller_day, lv_color_hex(0xFFFFFF), LV_PART_SELECTED); /* Month roller */ roller_month = lv_roller_create(popup_datetime); @@ -912,6 +1104,7 @@ static void create_popup_datetime(void) { lv_obj_set_size(roller_month, 60, 80); lv_obj_set_style_text_font(roller_month, &montserrat_16_ru_en, 0); lv_obj_set_style_bg_color(roller_month, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_text_color(roller_month, lv_color_hex(0xFFFFFF), LV_PART_SELECTED); /* Year roller (2024-2035) */ roller_year = lv_roller_create(popup_datetime); @@ -921,6 +1114,7 @@ static void create_popup_datetime(void) { lv_obj_set_size(roller_year, 80, 80); lv_obj_set_style_text_font(roller_year, &montserrat_16_ru_en, 0); lv_obj_set_style_bg_color(roller_year, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_text_color(roller_year, lv_color_hex(0xFFFFFF), LV_PART_SELECTED); /* Time section label */ lbl = lv_label_create(popup_datetime); @@ -946,6 +1140,7 @@ static void create_popup_datetime(void) { lv_obj_set_size(roller_hour, 60, 80); lv_obj_set_style_text_font(roller_hour, &montserrat_16_ru_en, 0); lv_obj_set_style_bg_color(roller_hour, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_text_color(roller_hour, lv_color_hex(0xFFFFFF), LV_PART_SELECTED); lbl = lv_label_create(popup_datetime); lv_label_set_text(lbl, ":"); @@ -970,6 +1165,7 @@ static void create_popup_datetime(void) { lv_obj_set_size(roller_minute, 60, 80); lv_obj_set_style_text_font(roller_minute, &montserrat_16_ru_en, 0); lv_obj_set_style_bg_color(roller_minute, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_text_color(roller_minute, lv_color_hex(0xFFFFFF), LV_PART_SELECTED); /* OK button */ lv_obj_t *btn_ok = lv_btn_create(popup_datetime); @@ -1395,6 +1591,8 @@ static void add_alarm_to_log(const char *message, int active) { snprintf(alarm_log[alarm_count].timestamp, 20, "%02d.%02d.%04d %02d:%02d", state.day, state.month, state.year, state.hour, state.minute); alarm_log[alarm_count].active = active; + alarm_log[alarm_count].confirmed = 0; + alarm_log[alarm_count].confirm_timestamp[0] = '\0'; alarm_count++; } } @@ -1456,8 +1654,8 @@ static void create_screen_main(void) { /* === STATUS PANEL === (нижняя часть экрана) */ lv_obj_t *panel_status = lv_obj_create(scr); - lv_obj_set_pos(panel_status, 10, 275); - lv_obj_set_size(panel_status, 240, 195); + lv_obj_set_pos(panel_status, 10, 300); + lv_obj_set_size(panel_status, 240, 170); lv_obj_set_style_bg_color(panel_status, lv_color_hex(COLOR_BG_PANEL), 0); lv_obj_set_style_radius(panel_status, 6, 0); lv_obj_set_style_border_width(panel_status, 0, 0); @@ -1500,14 +1698,14 @@ static void create_screen_main(void) { state.day, state.month, state.year, state.hour, state.minute); lv_label_set_text(lbl_datetime, dt_buf); } - lv_obj_set_pos(lbl_datetime, 10, 135); + lv_obj_set_pos(lbl_datetime, 10, 130); lv_obj_set_style_text_color(lbl_datetime, lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl_datetime, &montserrat_16_ru_en, 0); /* === CLIMATE PANEL === */ lv_obj_t *panel_climate = lv_obj_create(scr); - lv_obj_set_pos(panel_climate, 260, 275); - lv_obj_set_size(panel_climate, 230, 195); + lv_obj_set_pos(panel_climate, 260, 300); + lv_obj_set_size(panel_climate, 230, 170); lv_obj_set_style_bg_color(panel_climate, lv_color_hex(COLOR_BG_PANEL), 0); lv_obj_set_style_radius(panel_climate, 6, 0); lv_obj_set_style_border_width(panel_climate, 0, 0); @@ -1564,49 +1762,49 @@ static void create_screen_main(void) { /* === CONTROL BUTTONS === (правая часть нижней половины) */ int btn_x = 500; - int btn_y = 275; + int btn_y = 300; /* Stop button */ - lv_obj_t *btn = lv_btn_create(scr); - lv_obj_set_pos(btn, btn_x, btn_y); - lv_obj_set_size(btn, 140, 100); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 6, 0); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "ОСТАНОВ"); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_center(lbl); - lv_obj_add_event_cb(btn, btn_stop_cb, LV_EVENT_CLICKED, NULL); + btn_stop_mode = lv_btn_create(scr); + lv_obj_set_pos(btn_stop_mode, btn_x, btn_y); + lv_obj_set_size(btn_stop_mode, 140, 100); + lv_obj_set_style_bg_color(btn_stop_mode, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn_stop_mode, 6, 0); + lbl_stop_mode = lv_label_create(btn_stop_mode); + lv_label_set_text(lbl_stop_mode, "ОСТАНОВ"); + lv_obj_set_style_text_color(lbl_stop_mode, lv_color_hex(COLOR_DANGER), 0); + lv_obj_set_style_text_font(lbl_stop_mode, &montserrat_16_ru_en, 0); + lv_obj_center(lbl_stop_mode); + lv_obj_add_event_cb(btn_stop_mode, btn_stop_cb, LV_EVENT_CLICKED, NULL); /* Standby button */ - btn = lv_btn_create(scr); - lv_obj_set_pos(btn, btn_x + 150, btn_y); - lv_obj_set_size(btn, 140, 48); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 6, 0); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "Дежурный"); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_center(lbl); - lv_obj_add_event_cb(btn, btn_standby_cb, LV_EVENT_CLICKED, NULL); + btn_standby_mode = lv_btn_create(scr); + lv_obj_set_pos(btn_standby_mode, btn_x + 150, btn_y); + lv_obj_set_size(btn_standby_mode, 140, 48); + lv_obj_set_style_bg_color(btn_standby_mode, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn_standby_mode, 6, 0); + lbl_standby_mode = lv_label_create(btn_standby_mode); + lv_label_set_text(lbl_standby_mode, "Дежурный"); + lv_obj_set_style_text_color(lbl_standby_mode, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_font(lbl_standby_mode, &montserrat_16_ru_en, 0); + lv_obj_center(lbl_standby_mode); + lv_obj_add_event_cb(btn_standby_mode, btn_standby_cb, LV_EVENT_CLICKED, NULL); /* Work button */ - btn = lv_btn_create(scr); - lv_obj_set_pos(btn, btn_x + 150, btn_y + 52); - lv_obj_set_size(btn, 140, 48); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 6, 0); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "Рабочий"); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_center(lbl); - lv_obj_add_event_cb(btn, btn_work_cb, LV_EVENT_CLICKED, NULL); + btn_work_mode = lv_btn_create(scr); + lv_obj_set_pos(btn_work_mode, btn_x + 150, btn_y + 52); + lv_obj_set_size(btn_work_mode, 140, 48); + lv_obj_set_style_bg_color(btn_work_mode, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn_work_mode, 6, 0); + lbl_work_mode = lv_label_create(btn_work_mode); + lv_label_set_text(lbl_work_mode, "Рабочий"); + lv_obj_set_style_text_color(lbl_work_mode, lv_color_hex(COLOR_ACCENT), 0); + lv_obj_set_style_text_font(lbl_work_mode, &montserrat_16_ru_en, 0); + lv_obj_center(lbl_work_mode); + lv_obj_add_event_cb(btn_work_mode, btn_work_cb, LV_EVENT_CLICKED, NULL); /* Menu button */ - btn = lv_btn_create(scr); + lv_obj_t *btn = lv_btn_create(scr); lv_obj_set_pos(btn, btn_x, btn_y + 108); lv_obj_set_size(btn, 140, 48); lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); @@ -1631,22 +1829,25 @@ static void create_screen_main(void) { lv_obj_center(lbl); lv_obj_add_event_cb(btn, btn_readings_cb, LV_EVENT_CLICKED, NULL); + /* Update mode button colors based on current state */ + update_mode_button_colors(); + /* === EQUIPMENT SCHEMA AREA === (верхняя половина экрана) */ schema_panel = lv_obj_create(scr); lv_obj_set_pos(schema_panel, 10, 10); - lv_obj_set_size(schema_panel, 780, 255); + lv_obj_set_size(schema_panel, 780, 280); lv_obj_set_style_bg_color(schema_panel, lv_color_hex(COLOR_BG_PANEL), 0); lv_obj_set_style_radius(schema_panel, 6, 0); lv_obj_set_style_border_width(schema_panel, 0, 0); lv_obj_clear_flag(schema_panel, LV_OBJ_FLAG_SCROLLABLE); - + /* Hint labels */ lv_obj_t *hint1 = lv_label_create(schema_panel); lv_label_set_text(hint1, "Активные модули (перетащите вниз для отключения):"); lv_obj_set_pos(hint1, 10, 2); lv_obj_set_style_text_color(hint1, lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(hint1, &montserrat_16_ru_en, 0); - + lv_obj_t *hint2 = lv_label_create(schema_panel); lv_label_set_text(hint2, "Неактивные (перетащите вверх для включения):"); lv_obj_set_pos(hint2, 10, 155); @@ -1659,40 +1860,54 @@ static void create_screen_main(void) { int pipe_y = MODULES_ACTIVE_Y + 25; int pipe_segment_width = 35; /* Scaled pipe image width approximately */ int total_modules_width = 50 + MODULE_COUNT * (MODULE_WIDTH + MODULE_SPACING) + 50; - - /* Create pipe segments to form continuous line */ - for (int px = pipe_x; px < total_modules_width; px += pipe_segment_width) { - lv_obj_t *pipe_seg = lv_image_create(schema_panel); - lv_image_set_src(pipe_seg, &img_pipe); - lv_image_set_scale(pipe_seg, MODULE_SCALE); - lv_obj_set_pos(pipe_seg, px, pipe_y); - } - - /* Create all modules (they will appear on top of pipe line) */ + + /* Create edge pipes (at the start and end of the line) */ + lv_obj_t *pipe_start = lv_image_create(schema_panel); + lv_image_set_src(pipe_start, &img_pipe); + lv_image_set_scale(pipe_start, MODULE_SCALE); + lv_obj_set_pos(pipe_start, 5, pipe_y); + + lv_obj_t *pipe_end = lv_image_create(schema_panel); + lv_image_set_src(pipe_end, &img_pipe); + lv_image_set_scale(pipe_end, MODULE_SCALE); + lv_obj_set_pos(pipe_end, total_modules_width - 40, pipe_y); + + /* Create all modules and pipe placeholders */ int active_x = 50; /* Start after the inlet pipe */ int inactive_x = 10; - + for (int i = 0; i < MODULE_COUNT; i++) { + /* Create pipe placeholder for this module slot */ + pipe_placeholders[i] = lv_image_create(schema_panel); + lv_image_set_src(pipe_placeholders[i], &img_pipe); + lv_image_set_scale(pipe_placeholders[i], MODULE_SCALE); + /* Will be positioned by update_module_positions */ + int x_pos, y_pos; if (modules[i].enabled) { x_pos = active_x; y_pos = MODULES_ACTIVE_Y; + lv_obj_add_flag(pipe_placeholders[i], LV_OBJ_FLAG_HIDDEN); active_x += MODULE_WIDTH + MODULE_SPACING; } else { + /* Module inactive - show pipe placeholder on active line */ + lv_obj_set_pos(pipe_placeholders[i], active_x, MODULES_ACTIVE_Y); + active_x += MODULE_WIDTH + MODULE_SPACING; + x_pos = inactive_x; y_pos = MODULES_INACTIVE_Y; inactive_x += MODULE_WIDTH + MODULE_SPACING; } create_module_widget(schema_panel, i, x_pos, y_pos); - - /* No more individual pipe placeholders needed - continuous pipe line handles it */ - pipe_placeholders[i] = NULL; } - + /* Update all module displays with current values */ for (int i = 0; i < MODULE_COUNT; i++) { update_module_display(i); } + + /* Update mode button colors to reflect initial state */ + update_mode_button_colors(); } static void create_screen_screen1(void) { @@ -1777,15 +1992,15 @@ static void create_screen_screen1(void) { static void create_screen_screen2(void) { lv_obj_t *scr = lv_obj_create(NULL); scr_screen2 = scr; - lv_obj_set_style_bg_color(scr, lv_color_hex(0x2C3E50), 0); + lv_obj_set_style_bg_color(scr, lv_color_hex(COLOR_BG_DARK), 0); lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0); lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE); /* Title */ lv_obj_t *lbl = lv_label_create(scr); lv_label_set_text(lbl, "ЖУРНАЛ АВАРИЙ"); - lv_obj_set_pos(lbl, 300, 20); - lv_obj_set_style_text_color(lbl, lv_color_hex(0xECF0F1), 0); + lv_obj_set_pos(lbl, 300, 15); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); /* Date/Time display */ @@ -1794,53 +2009,142 @@ static void create_screen_screen2(void) { state.day, state.month, state.year, state.hour, state.minute); lbl = lv_label_create(scr); lv_label_set_text(lbl, datetime_buf); - lv_obj_set_pos(lbl, 620, 20); - lv_obj_set_style_text_color(lbl, lv_color_hex(0xBDC3C7), 0); + lv_obj_set_pos(lbl, 620, 15); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); /* Log panel */ lv_obj_t *log_panel = lv_obj_create(scr); - lv_obj_set_pos(log_panel, 20, 60); - lv_obj_set_size(log_panel, 760, 300); - lv_obj_set_style_bg_color(log_panel, lv_color_hex(0x34495E), 0); + lv_obj_set_pos(log_panel, 20, 50); + lv_obj_set_size(log_panel, 760, 310); + lv_obj_set_style_bg_color(log_panel, lv_color_hex(COLOR_BG_PANEL), 0); lv_obj_set_style_radius(log_panel, 8, 0); - lv_obj_set_style_border_width(log_panel, 2, 0); - lv_obj_set_style_border_color(log_panel, lv_color_hex(0x7F8C8D), 0); + lv_obj_set_style_border_width(log_panel, 1, 0); + lv_obj_set_style_border_color(log_panel, lv_color_hex(COLOR_BORDER), 0); + lv_obj_clear_flag(log_panel, LV_OBJ_FLAG_SCROLLABLE); - /* Display log entries */ + /* Calculate pagination */ + int total_pages = (alarm_count + ALARMS_PER_PAGE - 1) / ALARMS_PER_PAGE; + if (total_pages == 0) total_pages = 1; + if (alarm_page >= total_pages) alarm_page = total_pages - 1; + if (alarm_page < 0) alarm_page = 0; + + int start_idx = alarm_page * ALARMS_PER_PAGE; + int end_idx = start_idx + ALARMS_PER_PAGE; + if (end_idx > alarm_count) end_idx = alarm_count; + + /* Display log entries for current page */ int y = 10; if (alarm_count == 0) { lbl = lv_label_create(log_panel); lv_label_set_text(lbl, "Аварий нет"); - lv_obj_set_pos(lbl, 320, 130); + lv_obj_set_pos(lbl, 320, 150); lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); } else { - for (int i = 0; i < alarm_count && i < 8; i++) { - char buf[150]; - snprintf(buf, sizeof(buf), "%s - %s", - alarm_log[i].message, alarm_log[i].timestamp); + for (int i = start_idx; i < end_idx; i++) { + /* Alarm entry container */ + lv_obj_t *entry_cont = lv_obj_create(log_panel); + lv_obj_set_pos(entry_cont, 5, y); + lv_obj_set_size(entry_cont, 740, 75); + lv_obj_set_style_bg_color(entry_cont, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(entry_cont, 6, 0); + lv_obj_set_style_border_width(entry_cont, 1, 0); + lv_obj_set_style_border_color(entry_cont, alarm_log[i].active ? lv_color_hex(COLOR_DANGER) : lv_color_hex(COLOR_BORDER), 0); + lv_obj_clear_flag(entry_cont, LV_OBJ_FLAG_SCROLLABLE); - lbl = lv_label_create(log_panel); + /* Alarm message */ + char buf[120]; + snprintf(buf, sizeof(buf), "%s %s", alarm_log[i].message, alarm_log[i].timestamp); + lbl = lv_label_create(entry_cont); lv_label_set_text(lbl, buf); - lv_obj_set_pos(lbl, 10, y); - lv_obj_set_width(lbl, 730); + lv_obj_set_pos(lbl, 10, 8); + lv_obj_set_width(lbl, 550); + lv_label_set_long_mode(lbl, LV_LABEL_LONG_CLIP); if (alarm_log[i].active) { lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0); } else { - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); } lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - y += 35; + + /* Confirm button or confirmed status */ + if (alarm_log[i].confirmed) { + /* Show confirmed status */ + lbl = lv_label_create(entry_cont); + lv_label_set_text(lbl, "Подтверждено"); + lv_obj_set_pos(lbl, 580, 10); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + lbl = lv_label_create(entry_cont); + lv_label_set_text(lbl, alarm_log[i].confirm_timestamp); + lv_obj_set_pos(lbl, 580, 35); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + } else { + /* Confirm button - centered vertically */ + lv_obj_t *btn_confirm = lv_btn_create(entry_cont); + lv_obj_set_pos(btn_confirm, 580, 17); + lv_obj_set_size(btn_confirm, 130, 40); + lv_obj_set_style_bg_color(btn_confirm, lv_color_hex(COLOR_BG_MODULE), 0); + lv_obj_set_style_radius(btn_confirm, 4, 0); + lbl = lv_label_create(btn_confirm); + lv_label_set_text(lbl, "Подтвердить"); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn_confirm, btn_confirm_alarm_cb, LV_EVENT_CLICKED, (void*)(intptr_t)i); + } + + y += 80; } } - /* Buttons */ - int btn_y = 380; + /* Buttons row */ + int btn_y = 370; + + /* Left arrow button */ + lv_obj_t *btn = lv_btn_create(scr); + lv_obj_set_pos(btn, 300, btn_y); + lv_obj_set_size(btn, 60, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 6, 0); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, "<"); + lv_obj_set_style_text_color(lbl, alarm_page > 0 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_alarm_page_prev_cb, LV_EVENT_CLICKED, NULL); + + /* Page indicator */ + char page_buf[16]; + snprintf(page_buf, sizeof(page_buf), "%d / %d", alarm_page + 1, total_pages); + lbl = lv_label_create(scr); + lv_label_set_text(lbl, page_buf); + lv_obj_set_pos(lbl, 380, btn_y + 10); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + /* Right arrow button */ + btn = lv_btn_create(scr); + lv_obj_set_pos(btn, 440, btn_y); + lv_obj_set_size(btn, 60, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 6, 0); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, ">"); + lv_obj_set_style_text_color(lbl, alarm_page < total_pages - 1 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_alarm_page_next_cb, LV_EVENT_CLICKED, NULL); + + /* Bottom buttons row */ + btn_y = 420; /* Clear Log button */ - lv_obj_t *btn = lv_btn_create(scr); - lv_obj_set_pos(btn, 50, btn_y); + btn = lv_btn_create(scr); + lv_obj_set_pos(btn, 250, btn_y); lv_obj_set_size(btn, 160, 40); lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); lv_obj_set_style_radius(btn, 6, 0); @@ -1851,28 +2155,15 @@ static void create_screen_screen2(void) { lv_obj_center(lbl); lv_obj_add_event_cb(btn, btn_clear_log_cb, LV_EVENT_CLICKED, NULL); - /* Reset Alarm button */ - btn = lv_btn_create(scr); - lv_obj_set_pos(btn, 230, btn_y); - lv_obj_set_size(btn, 160, 40); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 6, 0); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "Сбросить аварию"); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_center(lbl); - lv_obj_add_event_cb(btn, btn_reset_alarm_cb, LV_EVENT_CLICKED, NULL); - /* Back to Menu button */ btn = lv_btn_create(scr); - lv_obj_set_pos(btn, 600, btn_y); + lv_obj_set_pos(btn, 430, btn_y); lv_obj_set_size(btn, 120, 40); lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); lv_obj_set_style_radius(btn, 6, 0); lbl = lv_label_create(btn); lv_label_set_text(lbl, "Меню"); - lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); lv_obj_center(lbl); lv_obj_add_event_cb(btn, btn_menu_cb, LV_EVENT_CLICKED, NULL); @@ -1893,310 +2184,400 @@ static void create_screen_screen3(void) { lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); char buf[64]; - int row_h = 34; + int row_h = 38; + const char *heater_modes[] = {"ВЫКЛ", "ВКЛ", "АВТО"}; - /* Left panel - Work mode - SCROLLABLE */ + /* Left panel - Work mode - NO SCROLL, with pagination */ lv_obj_t *panel_work = lv_obj_create(scr); lv_obj_set_pos(panel_work, 15, 40); - lv_obj_set_size(panel_work, 380, 310); + lv_obj_set_size(panel_work, 380, 270); lv_obj_set_style_bg_color(panel_work, lv_color_hex(COLOR_BG_PANEL), 0); lv_obj_set_style_radius(panel_work, 6, 0); lv_obj_set_style_border_width(panel_work, 0, 0); - lv_obj_set_scroll_dir(panel_work, LV_DIR_VER); - lv_obj_set_scrollbar_mode(panel_work, LV_SCROLLBAR_MODE_AUTO); + lv_obj_clear_flag(panel_work, LV_OBJ_FLAG_SCROLLABLE); lbl = lv_label_create(panel_work); lv_label_set_text(lbl, "РАБОЧИЙ"); - lv_obj_set_pos(lbl, 10, 8); + lv_obj_set_pos(lbl, 10, 5); lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - int y = 38; - - /* Temperature */ - lv_obj_t *btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Температура: %.1f°C", setpoint_work.temp); - lbl_work_temp = lv_label_create(btn); - lv_label_set_text(lbl_work_temp, buf); - lv_obj_center(lbl_work_temp); - lv_obj_set_style_text_color(lbl_work_temp, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl_work_temp, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_temp_cb, LV_EVENT_CLICKED, NULL); - - y += row_h + 6; - /* Humidity */ - btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Влажность: %.1f%%", setpoint_work.hum); - lbl_work_hum = lv_label_create(btn); - lv_label_set_text(lbl_work_hum, buf); - lv_obj_center(lbl_work_hum); - lv_obj_set_style_text_color(lbl_work_hum, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl_work_hum, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_hum_cb, LV_EVENT_CLICKED, NULL); - - y += row_h + 6; - /* Valve inlet */ - btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Клапан притока: %.1f%%", setpoint_work.valve_inlet); - lbl = lv_label_create(btn); + /* Page indicator for Work mode */ + snprintf(buf, sizeof(buf), "%d/2", setpoint_work_page + 1); + lbl = lv_label_create(panel_work); lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_pos(lbl, 330, 5); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_valve_inlet_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* Valve recirc */ - btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Клапан рецирк: %.1f%%", setpoint_work.valve_recirc); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_valve_recirc_cb, LV_EVENT_CLICKED, NULL); + int y = 32; + lv_obj_t *btn; - y += row_h + 6; - /* Heater mode */ - btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - const char *heater_modes[] = {"ВЫКЛ", "ВКЛ", "АВТО"}; - snprintf(buf, sizeof(buf), "Электронагрев: %s", heater_modes[setpoint_work.heater]); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_heater_cb, LV_EVENT_CLICKED, NULL); + /* Work mode parameters - page 0: Temp, Hum, Valve inlet, Valve recirc */ + /* Work mode parameters - page 1: Heater, Fan, KWS, PWW */ + if (setpoint_work_page == 0) { + /* Temperature */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Температура: %.1f°C", setpoint_work.temp); + lbl_work_temp = lv_label_create(btn); + lv_label_set_text(lbl_work_temp, buf); + lv_obj_center(lbl_work_temp); + lv_obj_set_style_text_color(lbl_work_temp, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl_work_temp, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_temp_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* Fan toggle */ - btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Вентилятор: %s", setpoint_work.fan ? "ВКЛ" : "ВЫКЛ"); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, setpoint_work.fan ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_fan_cb, LV_EVENT_CLICKED, NULL); + y += row_h + 6; + /* Humidity */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Влажность: %.1f%%", setpoint_work.hum); + lbl_work_hum = lv_label_create(btn); + lv_label_set_text(lbl_work_hum, buf); + lv_obj_center(lbl_work_hum); + lv_obj_set_style_text_color(lbl_work_hum, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl_work_hum, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_hum_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* KWS mode */ - btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - if (setpoint_work.kws_auto) { - snprintf(buf, sizeof(buf), "KWS: АВТО"); + y += row_h + 6; + /* Valve inlet */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Клапан притока: %.1f%%", setpoint_work.valve_inlet); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_valve_inlet_cb, LV_EVENT_CLICKED, NULL); + + y += row_h + 6; + /* Valve recirc */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Клапан рецирк: %.1f%%", setpoint_work.valve_recirc); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_valve_recirc_cb, LV_EVENT_CLICKED, NULL); } else { - snprintf(buf, sizeof(buf), "KWS: %.1f%%", setpoint_work.kws_manual); - } - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_kws_cb, LV_EVENT_CLICKED, NULL); + /* Page 1: Heater, Fan, KWS, PWW */ + /* Heater mode */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Электронагрев: %s", heater_modes[setpoint_work.heater]); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_heater_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* PWW mode */ + y += row_h + 6; + /* Fan toggle */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Вентилятор: %s", setpoint_work.fan ? "ВКЛ" : "ВЫКЛ"); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, setpoint_work.fan ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_fan_cb, LV_EVENT_CLICKED, NULL); + + y += row_h + 6; + /* KWS mode */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + if (setpoint_work.kws_auto) { + snprintf(buf, sizeof(buf), "KWS: АВТО"); + } else { + snprintf(buf, sizeof(buf), "KWS: %.1f%%", setpoint_work.kws_manual); + } + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_kws_cb, LV_EVENT_CLICKED, NULL); + + y += row_h + 6; + /* PWW mode */ + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + if (setpoint_work.pww_auto) { + snprintf(buf, sizeof(buf), "PWW: АВТО"); + } else { + snprintf(buf, sizeof(buf), "PWW: %.1f%%", setpoint_work.pww_manual); + } + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_work_pww_cb, LV_EVENT_CLICKED, NULL); + } + + /* Pagination buttons for Work panel */ btn = lv_btn_create(panel_work); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); + lv_obj_set_pos(btn, 80, 216); + lv_obj_set_size(btn, 80, 38); lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); lv_obj_set_style_radius(btn, 4, 0); - if (setpoint_work.pww_auto) { - snprintf(buf, sizeof(buf), "PWW: АВТО"); - } else { - snprintf(buf, sizeof(buf), "PWW: %.1f%%", setpoint_work.pww_manual); - } lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_label_set_text(lbl, "<"); + lv_obj_set_style_text_color(lbl, setpoint_work_page > 0 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_work_pww_cb, LV_EVENT_CLICKED, NULL); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_setpoint_work_prev_cb, LV_EVENT_CLICKED, NULL); - /* Right panel - Standby mode - SCROLLABLE */ + /* Page indicator */ + snprintf(buf, sizeof(buf), "%d/2", setpoint_work_page + 1); + lbl = lv_label_create(panel_work); + lv_label_set_text(lbl, buf); + lv_obj_set_pos(lbl, 180, 226); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + btn = lv_btn_create(panel_work); + lv_obj_set_pos(btn, 210, 216); + lv_obj_set_size(btn, 80, 38); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, ">"); + lv_obj_set_style_text_color(lbl, setpoint_work_page < 1 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_setpoint_work_next_cb, LV_EVENT_CLICKED, NULL); + + /* Right panel - Standby mode - NO SCROLL, with pagination */ lv_obj_t *panel_standby = lv_obj_create(scr); lv_obj_set_pos(panel_standby, 405, 40); - lv_obj_set_size(panel_standby, 380, 310); + lv_obj_set_size(panel_standby, 380, 270); lv_obj_set_style_bg_color(panel_standby, lv_color_hex(COLOR_BG_PANEL), 0); lv_obj_set_style_radius(panel_standby, 6, 0); lv_obj_set_style_border_width(panel_standby, 0, 0); - lv_obj_set_scroll_dir(panel_standby, LV_DIR_VER); - lv_obj_set_scrollbar_mode(panel_standby, LV_SCROLLBAR_MODE_AUTO); + lv_obj_clear_flag(panel_standby, LV_OBJ_FLAG_SCROLLABLE); lbl = lv_label_create(panel_standby); lv_label_set_text(lbl, "ДЕЖУРНЫЙ"); - lv_obj_set_pos(lbl, 10, 8); + lv_obj_set_pos(lbl, 10, 5); lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - y = 38; - /* Standby Temperature */ - btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Температура: %.1f°C", setpoint_standby.temp); - lbl_standby_temp = lv_label_create(btn); - lv_label_set_text(lbl_standby_temp, buf); - lv_obj_center(lbl_standby_temp); - lv_obj_set_style_text_color(lbl_standby_temp, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl_standby_temp, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_temp_cb, LV_EVENT_CLICKED, NULL); - - y += row_h + 6; - /* Standby Humidity */ - btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Влажность: %.1f%%", setpoint_standby.hum); - lbl_standby_hum = lv_label_create(btn); - lv_label_set_text(lbl_standby_hum, buf); - lv_obj_center(lbl_standby_hum); - lv_obj_set_style_text_color(lbl_standby_hum, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl_standby_hum, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_hum_cb, LV_EVENT_CLICKED, NULL); - - y += row_h + 6; - /* Standby Valve inlet */ - btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Клапан притока: %.1f%%", setpoint_standby.valve_inlet); - lbl = lv_label_create(btn); + /* Page indicator for Standby mode */ + snprintf(buf, sizeof(buf), "%d/2", setpoint_standby_page + 1); + lbl = lv_label_create(panel_standby); lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_pos(lbl, 330, 5); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_valve_inlet_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* Standby Valve recirc */ - btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Клапан рецирк: %.1f%%", setpoint_standby.valve_recirc); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_valve_recirc_cb, LV_EVENT_CLICKED, NULL); + y = 32; - y += row_h + 6; - /* Heater mode */ - btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Электронагрев: %s", heater_modes[setpoint_standby.heater]); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_heater_cb, LV_EVENT_CLICKED, NULL); + /* Standby mode parameters - page 0: Temp, Hum, Valve inlet, Valve recirc */ + /* Standby mode parameters - page 1: Heater, Fan, KWS, PWW */ + if (setpoint_standby_page == 0) { + /* Standby Temperature */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Температура: %.1f°C", setpoint_standby.temp); + lbl_standby_temp = lv_label_create(btn); + lv_label_set_text(lbl_standby_temp, buf); + lv_obj_center(lbl_standby_temp); + lv_obj_set_style_text_color(lbl_standby_temp, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl_standby_temp, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_temp_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* Fan toggle */ - btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - snprintf(buf, sizeof(buf), "Вентилятор: %s", setpoint_standby.fan ? "ВКЛ" : "ВЫКЛ"); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, setpoint_standby.fan ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_fan_cb, LV_EVENT_CLICKED, NULL); + y += row_h + 6; + /* Standby Humidity */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Влажность: %.1f%%", setpoint_standby.hum); + lbl_standby_hum = lv_label_create(btn); + lv_label_set_text(lbl_standby_hum, buf); + lv_obj_center(lbl_standby_hum); + lv_obj_set_style_text_color(lbl_standby_hum, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl_standby_hum, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_hum_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* KWS mode */ - btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - if (setpoint_standby.kws_auto) { - snprintf(buf, sizeof(buf), "KWS: АВТО"); + y += row_h + 6; + /* Standby Valve inlet */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Клапан притока: %.1f%%", setpoint_standby.valve_inlet); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_valve_inlet_cb, LV_EVENT_CLICKED, NULL); + + y += row_h + 6; + /* Standby Valve recirc */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Клапан рецирк: %.1f%%", setpoint_standby.valve_recirc); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_valve_recirc_cb, LV_EVENT_CLICKED, NULL); } else { - snprintf(buf, sizeof(buf), "KWS: %.1f%%", setpoint_standby.kws_manual); - } - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_kws_cb, LV_EVENT_CLICKED, NULL); + /* Page 1: Heater, Fan, KWS, PWW */ + /* Heater mode */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Электронагрев: %s", heater_modes[setpoint_standby.heater]); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_heater_cb, LV_EVENT_CLICKED, NULL); - y += row_h + 6; - /* PWW mode */ + y += row_h + 6; + /* Fan toggle */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Вентилятор: %s", setpoint_standby.fan ? "ВКЛ" : "ВЫКЛ"); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, setpoint_standby.fan ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_fan_cb, LV_EVENT_CLICKED, NULL); + + y += row_h + 6; + /* KWS mode */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + if (setpoint_standby.kws_auto) { + snprintf(buf, sizeof(buf), "KWS: АВТО"); + } else { + snprintf(buf, sizeof(buf), "KWS: %.1f%%", setpoint_standby.kws_manual); + } + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_kws_cb, LV_EVENT_CLICKED, NULL); + + y += row_h + 6; + /* PWW mode */ + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 5, y); + lv_obj_set_size(btn, 350, row_h); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + if (setpoint_standby.pww_auto) { + snprintf(buf, sizeof(buf), "PWW: АВТО"); + } else { + snprintf(buf, sizeof(buf), "PWW: %.1f%%", setpoint_standby.pww_manual); + } + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_standby_pww_cb, LV_EVENT_CLICKED, NULL); + } + + /* Pagination buttons for Standby panel */ btn = lv_btn_create(panel_standby); - lv_obj_set_pos(btn, 5, y); - lv_obj_set_size(btn, 350, row_h); + lv_obj_set_pos(btn, 80, 216); + lv_obj_set_size(btn, 80, 38); lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); lv_obj_set_style_radius(btn, 4, 0); - if (setpoint_standby.pww_auto) { - snprintf(buf, sizeof(buf), "PWW: АВТО"); - } else { - snprintf(buf, sizeof(buf), "PWW: %.1f%%", setpoint_standby.pww_manual); - } lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_label_set_text(lbl, "<"); + lv_obj_set_style_text_color(lbl, setpoint_standby_page > 0 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_standby_pww_cb, LV_EVENT_CLICKED, NULL); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_setpoint_standby_prev_cb, LV_EVENT_CLICKED, NULL); + + /* Page indicator */ + snprintf(buf, sizeof(buf), "%d/2", setpoint_standby_page + 1); + lbl = lv_label_create(panel_standby); + lv_label_set_text(lbl, buf); + lv_obj_set_pos(lbl, 180, 226); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + btn = lv_btn_create(panel_standby); + lv_obj_set_pos(btn, 210, 216); + lv_obj_set_size(btn, 80, 38); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, ">"); + lv_obj_set_style_text_color(lbl, setpoint_standby_page < 1 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_setpoint_standby_next_cb, LV_EVENT_CLICKED, NULL); /* Common parameters section */ lv_obj_t *panel_common = lv_obj_create(scr); - lv_obj_set_pos(panel_common, 15, 355); - lv_obj_set_size(panel_common, 770, 70); + lv_obj_set_pos(panel_common, 15, 320); + lv_obj_set_size(panel_common, 770, 60); lv_obj_set_style_bg_color(panel_common, lv_color_hex(COLOR_BG_PANEL), 0); lv_obj_set_style_radius(panel_common, 6, 0); lv_obj_set_style_border_width(panel_common, 0, 0); lv_obj_clear_flag(panel_common, LV_OBJ_FLAG_SCROLLABLE); lbl = lv_label_create(panel_common); - lv_label_set_text(lbl, "Общие параметры:"); - lv_obj_set_pos(lbl, 10, 5); + lv_label_set_text(lbl, "Общие:"); + lv_obj_set_pos(lbl, 10, 3); lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); @@ -2214,21 +2595,8 @@ static void create_screen_screen3(void) { lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - snprintf(buf, sizeof(buf), "%02d:%02d %02d.%02d.%d", state.hour, state.minute, state.day, state.month, state.year); - lbl = lv_label_create(panel_common); - lv_label_set_text(lbl, buf); - lv_obj_set_pos(lbl, 510, 28); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - lbl = lv_label_create(panel_common); - lv_label_set_text(lbl, "(для ввода даты замены)"); - lv_obj_set_pos(lbl, 10, 48); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - /* Buttons row */ - int btn_y = 435; + int btn_y = 395; btn = lv_btn_create(scr); lv_obj_set_pos(btn, 200, btn_y); @@ -2282,340 +2650,422 @@ static void create_screen_config(void) { lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - /* Left panel - Sensor corrections - SCROLLABLE */ - lv_obj_t *panel_left = lv_obj_create(scr); - lv_obj_set_pos(panel_left, 10, 45); - lv_obj_set_size(panel_left, 385, 340); - lv_obj_set_style_bg_color(panel_left, lv_color_hex(COLOR_BG_PANEL), 0); - lv_obj_set_style_radius(panel_left, 8, 0); - lv_obj_set_style_border_width(panel_left, 0, 0); - lv_obj_set_style_pad_all(panel_left, 8, 0); - lv_obj_set_scroll_dir(panel_left, LV_DIR_VER); - lv_obj_set_scrollbar_mode(panel_left, LV_SCROLLBAR_MODE_AUTO); + /* Single unified panel - NO SCROLL, with pagination */ + lv_obj_t *panel_main = lv_obj_create(scr); + lv_obj_set_pos(panel_main, 15, 40); + lv_obj_set_size(panel_main, 770, 310); + lv_obj_set_style_bg_color(panel_main, lv_color_hex(COLOR_BG_PANEL), 0); + lv_obj_set_style_radius(panel_main, 6, 0); + lv_obj_set_style_border_width(panel_main, 0, 0); + lv_obj_clear_flag(panel_main, LV_OBJ_FLAG_SCROLLABLE); - lbl = lv_label_create(panel_left); - lv_label_set_text(lbl, "Коррекция датчиков"); - lv_obj_set_pos(lbl, 10, 5); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); + /* Page indicator */ + snprintf(buf, sizeof(buf), "%d/3", config_page + 1); + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, buf); + lv_obj_set_pos(lbl, 720, 5); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); lv_obj_t *btn; int y = 35; - const char *labels[] = { - "Темп. помещения:", - "Влажн. помещения:", - "Темп. в канале:", - "Влажн. в канале:", - "Клапан притока:", - "Клапан рецирк.:" - }; - float *offsets[] = { - &config.temp_room_offset, - &config.hum_room_offset, - &config.temp_channel_offset, - &config.hum_channel_offset, - &config.valve_inlet_offset, - &config.valve_recirc_offset - }; - for (int i = 0; i < 6; i++) { - btn = lv_btn_create(panel_left); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 350, 36); + /* PAGE 0: Sensor corrections (4 параметра чтобы не налазить на кнопки) */ + if (config_page == 0) { + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "Коррекция датчиков"); + lv_obj_set_pos(lbl, 10, 5); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + const char *labels[] = { + "Темп. помещения:", + "Влажн. помещения:", + "Темп. в канале:", + "Влажн. в канале:" + }; + float *offsets[] = { + &config.temp_room_offset, + &config.hum_room_offset, + &config.temp_channel_offset, + &config.hum_channel_offset + }; + + for (int i = 0; i < 4; i++) { + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 740, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + + lv_obj_t *lbl_name = lv_label_create(btn); + lv_label_set_text(lbl_name, labels[i]); + lv_obj_align(lbl_name, LV_ALIGN_LEFT_MID, 15, 0); + lv_obj_set_style_text_color(lbl_name, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl_name, &montserrat_16_ru_en, 0); + + snprintf(buf, sizeof(buf), "%+.1f", *offsets[i]); + lv_obj_t *lbl_val = lv_label_create(btn); + lv_label_set_text(lbl_val, buf); + lv_obj_align(lbl_val, LV_ALIGN_RIGHT_MID, -15, 0); + lv_obj_set_style_text_color(lbl_val, lv_color_hex(COLOR_ACCENT), 0); + lv_obj_set_style_text_font(lbl_val, &montserrat_16_ru_en, 0); + + lv_obj_add_event_cb(btn, edit_config_offset_cb, LV_EVENT_CLICKED, offsets[i]); + + y += 50; + } + } + /* PAGE 1: Remaining sensor corrections + Equipment and PID regulators */ + else if (config_page == 1) { + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "Коррекция датчиков (продолжение)"); + lv_obj_set_pos(lbl, 10, 5); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + /* Клапан притока */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 360, 40); lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); lv_obj_t *lbl_name = lv_label_create(btn); - lv_label_set_text(lbl_name, labels[i]); - lv_obj_align(lbl_name, LV_ALIGN_LEFT_MID, 10, 0); + lv_label_set_text(lbl_name, "Клапан притока:"); + lv_obj_align(lbl_name, LV_ALIGN_LEFT_MID, 15, 0); lv_obj_set_style_text_color(lbl_name, lv_color_hex(COLOR_TEXT), 0); lv_obj_set_style_text_font(lbl_name, &montserrat_16_ru_en, 0); - snprintf(buf, sizeof(buf), "%+.1f", *offsets[i]); + snprintf(buf, sizeof(buf), "%+.1f", config.valve_inlet_offset); lv_obj_t *lbl_val = lv_label_create(btn); lv_label_set_text(lbl_val, buf); - lv_obj_align(lbl_val, LV_ALIGN_RIGHT_MID, -10, 0); + lv_obj_align(lbl_val, LV_ALIGN_RIGHT_MID, -15, 0); lv_obj_set_style_text_color(lbl_val, lv_color_hex(COLOR_ACCENT), 0); lv_obj_set_style_text_font(lbl_val, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_config_offset_cb, LV_EVENT_CLICKED, offsets[i]); + lv_obj_add_event_cb(btn, edit_config_offset_cb, LV_EVENT_CLICKED, &config.valve_inlet_offset); - y += 40; + /* Клапан рециркуляции */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 390, y); + lv_obj_set_size(btn, 360, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + + lbl_name = lv_label_create(btn); + lv_label_set_text(lbl_name, "Клапан рецирк.:"); + lv_obj_align(lbl_name, LV_ALIGN_LEFT_MID, 15, 0); + lv_obj_set_style_text_color(lbl_name, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl_name, &montserrat_16_ru_en, 0); + + snprintf(buf, sizeof(buf), "%+.1f", config.valve_recirc_offset); + lbl_val = lv_label_create(btn); + lv_label_set_text(lbl_val, buf); + lv_obj_align(lbl_val, LV_ALIGN_RIGHT_MID, -15, 0); + lv_obj_set_style_text_color(lbl_val, lv_color_hex(COLOR_ACCENT), 0); + lv_obj_set_style_text_font(lbl_val, &montserrat_16_ru_en, 0); + + lv_obj_add_event_cb(btn, edit_config_offset_cb, LV_EVENT_CLICKED, &config.valve_recirc_offset); + + y += 55; + + /* Оборудование */ + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "Оборудование"); + lv_obj_set_pos(lbl, 10, y); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + y += 25; + + /* Toggles for equipment presence */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 360, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, "Клапан рецирк.:"); + lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 15, 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, config.has_recirc_valve ? "ЕСТЬ" : "НЕТ"); + lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -15, 0); + lv_obj_set_style_text_color(lbl, config.has_recirc_valve ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, toggle_recirc_valve_cb, LV_EVENT_CLICKED, NULL); + + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 390, y); + lv_obj_set_size(btn, 360, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, "Электронагрев.:"); + lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 15, 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, config.has_heater ? "ЕСТЬ" : "НЕТ"); + lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -15, 0); + lv_obj_set_style_text_color(lbl, config.has_heater ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, toggle_heater_cb, LV_EVENT_CLICKED, NULL); + } + /* PAGE 2: PID regulators, Mode settings and Date/Time */ + else { + /* PID regulators */ + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "ПИД регуляторы"); + lv_obj_set_pos(lbl, 10, 5); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + /* PWW PID */ + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "PWW:"); + lv_obj_set_pos(lbl, 10, y); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + y += 25; + /* PWW Kp */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 120, 36); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Kp=%.2f", config.pid_pww_kp); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_pid_pww_kp_cb, LV_EVENT_CLICKED, NULL); + + /* PWW Ti */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 140, y); + lv_obj_set_size(btn, 120, 36); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Ti=%.2f", config.pid_pww_ti); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_pid_pww_ti_cb, LV_EVENT_CLICKED, NULL); + + /* PWW D */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 270, y); + lv_obj_set_size(btn, 120, 36); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "D=%.2f", config.pid_pww_d); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_pid_pww_d_cb, LV_EVENT_CLICKED, NULL); + + y += 46; + + /* KWS PID */ + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "KWS:"); + lv_obj_set_pos(lbl, 10, y); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + y += 25; + /* KWS Kp */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 120, 36); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Kp=%.2f", config.pid_kws_kp); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_pid_kws_kp_cb, LV_EVENT_CLICKED, NULL); + + /* KWS Ti */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 140, y); + lv_obj_set_size(btn, 120, 36); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "Ti=%.2f", config.pid_kws_ti); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_pid_kws_ti_cb, LV_EVENT_CLICKED, NULL); + + /* KWS D */ + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 270, y); + lv_obj_set_size(btn, 120, 36); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + snprintf(buf, sizeof(buf), "D=%.2f", config.pid_kws_d); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_pid_kws_d_cb, LV_EVENT_CLICKED, NULL); + + y += 55; + + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "Режим работы"); + lv_obj_set_pos(lbl, 10, y); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + y += 25; + + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 740, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, "Принуд. режим:"); + lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 15, 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, config.force_mode_enabled ? "ВКЛ" : "ВЫКЛ"); + lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -15, 0); + lv_obj_set_style_text_color(lbl, config.force_mode_enabled ? lv_color_hex(COLOR_WARNING) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, toggle_force_mode_cb, LV_EVENT_CLICKED, NULL); + + y += 45; + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 740, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, "Перемена ключа:"); + lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 15, 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + lbl = lv_label_create(btn); + lv_label_set_text(lbl, config.key_swap_enabled ? "ВКЛ" : "ВЫКЛ"); + lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -15, 0); + lv_obj_set_style_text_color(lbl, config.key_swap_enabled ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, toggle_key_swap_cb, LV_EVENT_CLICKED, NULL); + + y += 55; + lbl = lv_label_create(panel_main); + lv_label_set_text(lbl, "Дата и время"); + lv_obj_set_pos(lbl, 10, y); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + y += 30; + btn = lv_btn_create(panel_main); + lv_obj_set_pos(btn, 10, y); + lv_obj_set_size(btn, 740, 40); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + + snprintf(buf, sizeof(buf), "%02d.%02d.%04d %02d:%02d", + state.day, state.month, state.year, state.hour, state.minute); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, buf); + lv_obj_center(lbl); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_add_event_cb(btn, edit_datetime_cb, LV_EVENT_CLICKED, NULL); } - /* Toggles for equipment presence */ - y += 10; - btn = lv_btn_create(panel_left); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 350, 36); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "Клапан рецирк.:"); - lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, config.has_recirc_valve ? "ЕСТЬ" : "НЕТ"); - lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0); - lv_obj_set_style_text_color(lbl, config.has_recirc_valve ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, toggle_recirc_valve_cb, LV_EVENT_CLICKED, NULL); - - y += 40; - btn = lv_btn_create(panel_left); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 350, 36); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "Электронагрев.:"); - lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, config.has_heater ? "ЕСТЬ" : "НЕТ"); - lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0); - lv_obj_set_style_text_color(lbl, config.has_heater ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, toggle_heater_cb, LV_EVENT_CLICKED, NULL); - - /* Right panel - PID and mode settings - SCROLLABLE */ - lv_obj_t *panel_right = lv_obj_create(scr); - lv_obj_set_pos(panel_right, 405, 45); - lv_obj_set_size(panel_right, 385, 340); - lv_obj_set_style_bg_color(panel_right, lv_color_hex(COLOR_BG_PANEL), 0); - lv_obj_set_style_radius(panel_right, 8, 0); - lv_obj_set_style_border_width(panel_right, 0, 0); - lv_obj_set_style_pad_all(panel_right, 8, 0); - lv_obj_set_scroll_dir(panel_right, LV_DIR_VER); - lv_obj_set_scrollbar_mode(panel_right, LV_SCROLLBAR_MODE_AUTO); - - lbl = lv_label_create(panel_right); - lv_label_set_text(lbl, "ПИД регуляторы"); - lv_obj_set_pos(lbl, 10, 5); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - y = 35; - /* PWW PID - separate buttons for each parameter */ - lbl = lv_label_create(panel_right); - lv_label_set_text(lbl, "PWW:"); - lv_obj_set_pos(lbl, 10, y); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - y += 25; - /* PWW Kp */ - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 110, 32); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - snprintf(buf, sizeof(buf), "Kp=%.2f", config.pid_pww_kp); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_pid_pww_kp_cb, LV_EVENT_CLICKED, NULL); - - /* PWW Ti */ - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 115, y); - lv_obj_set_size(btn, 110, 32); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - snprintf(buf, sizeof(buf), "Ti=%.2f", config.pid_pww_ti); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_pid_pww_ti_cb, LV_EVENT_CLICKED, NULL); - - /* PWW D */ - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 230, y); - lv_obj_set_size(btn, 110, 32); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - snprintf(buf, sizeof(buf), "D=%.2f", config.pid_pww_d); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_pid_pww_d_cb, LV_EVENT_CLICKED, NULL); - - y += 42; - /* KWS PID - separate buttons for each parameter */ - lbl = lv_label_create(panel_right); - lv_label_set_text(lbl, "KWS:"); - lv_obj_set_pos(lbl, 10, y); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - y += 25; - /* KWS Kp */ - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 110, 32); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - snprintf(buf, sizeof(buf), "Kp=%.2f", config.pid_kws_kp); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_pid_kws_kp_cb, LV_EVENT_CLICKED, NULL); - - /* KWS Ti */ - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 115, y); - lv_obj_set_size(btn, 110, 32); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - snprintf(buf, sizeof(buf), "Ti=%.2f", config.pid_kws_ti); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_pid_kws_ti_cb, LV_EVENT_CLICKED, NULL); - - /* KWS D */ - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 230, y); - lv_obj_set_size(btn, 110, 32); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - snprintf(buf, sizeof(buf), "D=%.2f", config.pid_kws_d); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_pid_kws_d_cb, LV_EVENT_CLICKED, NULL); - - y += 42; - lbl = lv_label_create(panel_right); - lv_label_set_text(lbl, "Режим работы"); - lv_obj_set_pos(lbl, 10, y); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - y += 30; - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 350, 36); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "Принуд. режим:"); - lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, config.force_mode_enabled ? "ВКЛ" : "ВЫКЛ"); - lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0); - lv_obj_set_style_text_color(lbl, config.force_mode_enabled ? lv_color_hex(COLOR_WARNING) : lv_color_hex(COLOR_TEXT_DIM), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, toggle_force_mode_cb, LV_EVENT_CLICKED, NULL); - - y += 40; - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 350, 36); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, "Перемена ключа:"); - lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - lbl = lv_label_create(btn); - lv_label_set_text(lbl, config.key_swap_enabled ? "ВКЛ" : "ВЫКЛ"); - lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0); - lv_obj_set_style_text_color(lbl, config.key_swap_enabled ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, toggle_key_swap_cb, LV_EVENT_CLICKED, NULL); - - y += 45; - lbl = lv_label_create(panel_right); - lv_label_set_text(lbl, "Дата и время"); - lv_obj_set_pos(lbl, 10, y); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - - y += 30; - btn = lv_btn_create(panel_right); - lv_obj_set_pos(btn, 0, y); - lv_obj_set_size(btn, 350, 36); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); - lv_obj_set_style_radius(btn, 4, 0); - lv_obj_set_style_pad_all(btn, 0, 0); - - snprintf(buf, sizeof(buf), "%02d.%02d.%04d %02d:%02d", - state.day, state.month, state.year, state.hour, state.minute); - lbl = lv_label_create(btn); - lv_label_set_text(lbl, buf); - lv_obj_center(lbl); - lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0); - lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); - lv_obj_add_event_cb(btn, edit_datetime_cb, LV_EVENT_CLICKED, NULL); - - /* Buttons */ + /* Pagination buttons - below content */ btn = lv_btn_create(scr); - lv_obj_set_pos(btn, 200, 410); - lv_obj_set_size(btn, 120, 40); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_ACCENT), 0); - lv_obj_set_style_radius(btn, 8, 0); + lv_obj_set_pos(btn, 240, 365); + lv_obj_set_size(btn, 100, 38); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, "<"); + lv_obj_set_style_text_color(lbl, config_page > 0 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_config_page_prev_cb, LV_EVENT_CLICKED, NULL); + + /* Page indicator */ + lbl = lv_label_create(scr); + snprintf(buf, sizeof(buf), "%d/3", config_page + 1); + lv_label_set_text(lbl, buf); + lv_obj_set_pos(lbl, 365, 375); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + + btn = lv_btn_create(scr); + lv_obj_set_pos(btn, 430, 365); + lv_obj_set_size(btn, 100, 38); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); + lbl = lv_label_create(btn); + lv_label_set_text(lbl, ">"); + lv_obj_set_style_text_color(lbl, config_page < 2 ? lv_color_hex(COLOR_TEXT) : lv_color_hex(COLOR_TEXT_DIM), 0); + lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, btn_config_page_next_cb, LV_EVENT_CLICKED, NULL); + + /* Bottom buttons - using screen3 style colors */ + btn = lv_btn_create(scr); + lv_obj_set_pos(btn, 200, 420); + lv_obj_set_size(btn, 110, 38); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); lbl = lv_label_create(btn); lv_label_set_text(lbl, "Сохранить"); - lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); lv_obj_center(lbl); btn = lv_btn_create(scr); - lv_obj_set_pos(btn, 340, 410); - lv_obj_set_size(btn, 140, 40); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_WARNING), 0); - lv_obj_set_style_radius(btn, 8, 0); + lv_obj_set_pos(btn, 330, 420); + lv_obj_set_size(btn, 140, 38); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); lbl = lv_label_create(btn); lv_label_set_text(lbl, "По умолчанию"); - lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); lv_obj_center(lbl); btn = lv_btn_create(scr); - lv_obj_set_pos(btn, 500, 410); - lv_obj_set_size(btn, 100, 40); - lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_TEXT_ACCENT), 0); - lv_obj_set_style_radius(btn, 8, 0); + lv_obj_set_pos(btn, 490, 420); + lv_obj_set_size(btn, 100, 38); + lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0); + lv_obj_set_style_radius(btn, 4, 0); lbl = lv_label_create(btn); lv_label_set_text(lbl, "Меню"); - lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0); lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0); lv_obj_center(lbl); lv_obj_add_event_cb(btn, btn_menu_cb, LV_EVENT_CLICKED, NULL); @@ -2754,21 +3204,21 @@ static void refresh_setpoints_display(void) { lv_obj_t *current_scr = lv_screen_active(); int was_on_screen3 = (current_scr == scr_screen3); int was_on_screen4 = (current_scr == scr_screen4); - + /* Recreate screen 3 to show updated values */ if (scr_screen3) { lv_obj_del(scr_screen3); scr_screen3 = NULL; } create_screen_screen3(); - + /* Recreate screen 4 to show updated values */ if (scr_screen4) { lv_obj_del(scr_screen4); scr_screen4 = NULL; } create_screen_config(); - + /* Load appropriate screen */ if (was_on_screen3) { lv_scr_load(scr_screen3); @@ -2778,26 +3228,35 @@ static void refresh_setpoints_display(void) { } void gui_init(void) { - /* Add some example alarms to the log */ - add_alarm_to_log("Система запущена", 0); - add_alarm_to_log("Фильтр G4 заменен", 0); + /* Журнал начинается пустым - аварии добавляются при необходимости */ create_screen_main(); create_screen_screen1(); - create_screen_screen2(); create_screen_screen3(); create_screen_config(); lv_scr_load(scr_main); - + /* Проверка аварийных ситуаций после загрузки главного экрана */ if (!state.filter_g4_clean) { - create_popup_alarm("ФИЛЬТР G4 ЗАСОРИЛСЯ\n\nЗамените фильтр немедленно.\nСистема работает в аварийном режиме."); + add_alarm_to_log("ФИЛЬТР G4 ЗАСОРИЛСЯ - Замените фильтр", 1); state.mode = 0; + update_mode_button_colors(); } - + if (state.temp_channel < 50) { - create_popup_alarm("УГРОЗА ЗАМОРОЗКИ\n\nУстановка остановлена.\nПроверьте журнал и примите меры."); + add_alarm_to_log("УГРОЗА ЗАМОРОЗКИ - Установка остановлена", 1); state.mode = 0; + update_mode_button_colors(); + } + + /* Create screen2 after alarms are added */ + create_screen_screen2(); + + /* Show alarm popup if needed */ + if (!state.filter_g4_clean) { + create_popup_alarm("ФИЛЬТР G4 ЗАСОРИЛСЯ - Замените фильтр"); + } else if (state.temp_channel < 50) { + create_popup_alarm("УГРОЗА ЗАМОРОЗКИ - Установка остановлена"); } }