substitutions: color_bg: "0x000000" # główne tło - czerń color_topbar: "0x0A0A0A" # pasek górny/dolny color_card: "0x0D0D0D" # tło kafelków color_border: "0x262626" # ramki domyślne color_text: "0xFFFFFF" # tekst główny color_text_dim: "0x9A9A9A" # tekst pomocniczy color_text_subtle: "0x5A5A5A" # tekst bardzo wyciszony color_off: "0x111111" # tło przycisków / kafelków color_off_border: "0x2A2A2A" # ramka kafelków color_battery: "0x32D74B" # bateria - zielony color_pv: "0xFFB020" # PV - bursztyn color_water: "0x4DB8E8" # woda - niebieski color_boiler: "0xFF6B35" # bojler - pomarańcz color_alert: "0xFF3B30" # alarm / czerwony color_wifi_ok: "0x32D74B" # status OK color_home_tab: "0xFF9500" # kolor akcentu color_home_tab_t: "0x000000" # tekst na przycisku głównym panel_sleep_timeout: "1min" esphome: name: bms-display-43 friendly_name: Monitor Domu TEST on_boot: priority: -100 then: - lvgl.page.show: home_page - delay: 2s - script.execute: refresh_clock esp32: board: esp32-s3-devkitc-1 flash_size: 16MB framework: type: esp-idf logger: level: WARN baud_rate: 0 api: reboot_timeout: 0s ota: - platform: esphome # --- DEKLARACJA PLIKÓW GRAFICZNYCH (Z PODFOLDERA images/ NA RASPBERRY PI) --- image: - file: "images/reku_nobypass3.png" id: img_reku_bg type: RGB - file: "images/reku_bypass3.png" id: img_reku_bypass type: RGB transparency: alpha_channel # --- WEB SERVER ORAZ WIFI Z TRYBEM AP --- web_server: port: 80 wifi: ssid: "MichalNET2" password: "wersalka" reboot_timeout: 0s fast_connect: false power_save_mode: none ap: ssid: "BMS-Display Fallback Hotspot" password: "wersalka" psram: mode: octal speed: 80MHz # --- CZCIONKI ORAZ IKONY MATERIAL DESIGN --- font: - file: "gfonts://Roboto" id: font_main size: 16 bpp: 4 glyphs: ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ąćęłńóśźżĄĆĘŁŃÓŚŹŻ°µ' - file: "gfonts://Roboto" id: font_titles size: 22 bpp: 4 glyphs: ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ąćęłńóśźżĄĆĘŁŃÓŚŹŻ°µ' - file: "gfonts://Roboto" id: font_big size: 30 bpp: 4 glyphs: ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ąćęłńóśźżĄĆĘŁŃÓŚŹŻ°µ' - file: "gfonts://Roboto" id: font_large_param size: 32 bpp: 4 glyphs: ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ąćęłńóśźżĄĆĘŁŃÓŚŹŻ°µ' - file: "gfonts://Roboto" id: font_huge_param size: 36 bpp: 4 glyphs: ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ąćęłńóśźżĄĆĘŁŃÓŚŹŻ°µ' - file: "gfonts://Roboto" id: font_sleep_date size: 40 bpp: 4 glyphs: ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ąćęłńóśźżĄĆĘŁŃÓŚŹŻ°µ' - file: "gfonts://Roboto" id: font_weather_temp size: 64 bpp: 4 glyphs: "0123456789:-.°C%µ" - file: "gfonts://Roboto" id: font_sleep_clock_huge size: 175 bpp: 4 glyphs: "0123456789:-" - file: "https://github.com/Templarian/MaterialDesign-Webfont/raw/master/fonts/materialdesignicons-webfont.ttf" id: icon_24 size: 24 bpp: 4 glyphs: &mdi_glyphs - "\U000F02DC" # home - "\U000F0335" # lights - "\U000F0599" # weather / sun cloud - "\U000F033E" # alarm - "\U000F0238" # boiler/fire - "\U000F05A9" # wifi - "\U000F0156" # temp - "\U000F0241" # bolt / power - "\U000F1B29" # pump - "\U000F0425" # power off - "\U000F00A8" # solar panel / sun - "\U000F01E2" # chart / production - "\U000F0510" # thermometer outdoor - "\U000F0E02" # radiator/heating - "\U000F0A31" # air quality index - "\U000F0590" # weather sunny - "\U000F0593" # weather rainy - "\U000F0595" # weather snowy - "\U000F0592" # weather cloudy - "\U000F0594" # weather pouring - "\U000F058A" # water percent - "\U000F0379" # gauge / pressure - "\U000F0134" # alert-decagram / check-circle - "\U000F0210" # fan / rekuperator - "\U000F0D53" # air-filter - "\U000F0071" # arrow-decision - "\U000F0538" # fireplace - file: "https://github.com/Templarian/MaterialDesign-Webfont/raw/master/fonts/materialdesignicons-webfont.ttf" id: icon_30 size: 30 bpp: 4 glyphs: *mdi_glyphs - file: "https://github.com/Templarian/MaterialDesign-Webfont/raw/master/fonts/materialdesignicons-webfont.ttf" id: icon_huge_weather size: 80 bpp: 4 glyphs: *mdi_glyphs globals: - id: screen_dimmed type: bool restore_value: no initial_value: 'false' - id: global_pm25 type: float restore_value: no initial_value: '0.0' time: - platform: homeassistant id: ha_time on_time_sync: then: - script.execute: refresh_clock on_time: - seconds: 0 minutes: '*' then: - script.execute: refresh_clock script: - id: refresh_clock then: - lvgl.label.update: id: lbl_time text: !lambda |- auto now = id(ha_time).now(); if (!now.is_valid()) return std::string("--:--"); char b[8]; snprintf(b, sizeof(b), "%02d:%02d", now.hour, now.minute); return std::string(b); - lvgl.label.update: id: lbl_sleep_time text: !lambda |- auto now = id(ha_time).now(); if (!now.is_valid()) return std::string("--:--"); char b[8]; snprintf(b, sizeof(b), "%02d:%02d", now.hour, now.minute); return std::string(b); - lvgl.label.update: id: lbl_date text: !lambda |- auto now = id(ha_time).now(); if (!now.is_valid()) return std::string("--.--.----"); char b[16]; snprintf(b, sizeof(b), "%02d.%02d.%04d", now.day_of_month, now.month, now.year); return std::string(b); - lvgl.label.update: id: lbl_sleep_date text: !lambda |- auto now = id(ha_time).now(); if (!now.is_valid()) return std::string("--.--.----"); const char* dni[] = {"Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"}; int dow = now.day_of_week; if (dow < 1 || dow > 7) dow = 1; char b[64]; snprintf(b, sizeof(b), "%s, %02d.%02d.%04d", dni[dow - 1], now.day_of_month, now.month, now.year); return std::string(b); - id: update_air_quality_ui then: - lvgl.label.update: id: lbl_air_status text: !lambda |- float pm = id(global_pm25); char b[32]; if (pm > 25.0f) { snprintf(b, sizeof(b), "ZŁA: %.1f", id(ha_air_index).state); } else if (pm > 15.0f) { snprintf(b, sizeof(b), "ŚREDNIA: %.1f", id(ha_air_index).state); } else { snprintf(b, sizeof(b), "DOBRA: %.1f", id(ha_air_index).state); } return std::string(b); text_color: !lambda |- float pm = id(global_pm25); if (pm > 25.0f) return lv_color_hex(${color_alert}); if (pm > 15.0f) return lv_color_hex(${color_pv}); return lv_color_hex(${color_battery}); # --- KONFIGURACJA SPRZĘTOWA EKRANU WAVESHARE 4.3" --- i2c: sda: GPIO8 scl: GPIO9 scan: true touchscreen: platform: gt911 id: touch interrupt_pin: GPIO4 on_touch: - if: condition: lambda: 'return id(screen_dimmed);' then: - lvgl.page.show: home_page - lambda: 'id(screen_dimmed) = false;' display: - platform: rpi_dpi_rgb id: main_display color_order: RGB auto_clear_enabled: false update_interval: never dimensions: width: 800 height: 480 de_pin: GPIO5 hsync_pin: GPIO46 vsync_pin: GPIO3 pclk_pin: GPIO7 pclk_frequency: 16MHz pclk_inverted: true hsync_back_porch: 30 hsync_front_porch: 210 hsync_pulse_width: 30 vsync_back_porch: 4 vsync_front_porch: 4 vsync_pulse_width: 4 data_pins: red: [GPIO1, GPIO2, GPIO42, GPIO41, GPIO40] green: [GPIO39, GPIO0, GPIO45, GPIO48, GPIO47, GPIO21] blue: [GPIO14, GPIO38, GPIO18, GPIO17, GPIO10] # --- SENSORY Z HOME ASSISTANT --- sensor: - platform: homeassistant id: ha_soc entity_id: sensor.jk_bms_nx_jk_bms_1_state_of_charge name: "BMS Stan Naładowania" internal: false on_value: - lvgl.label.update: id: lbl_soc text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f%%", x); return std::string(b);' - lvgl.label.update: id: lbl_page_soc text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f%%", x); return std::string(b);' - lvgl.widget.update: id: batt_fill height: !lambda 'return (int)((x / 100.0f) * 126.0f);' bg_color: !lambda 'return (x < 15.0f) ? lv_color_hex(${color_alert}) : lv_color_hex(${color_battery});' - lvgl.widget.update: id: page_batt_fill width: !lambda 'return (int)((x / 100.0f) * 236.0f);' bg_color: !lambda 'return (x < 15.0f) ? lv_color_hex(${color_alert}) : lv_color_hex(${color_battery});' - platform: homeassistant id: ha_bus_voltage entity_id: sensor.jk_bms_nx_jk_bms_1_total_voltage name: "BMS Napięcie" internal: false on_value: - lvgl.label.update: id: lbl_volts text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.2f V", x); return std::string(b);' - lvgl.label.update: id: lbl_page_volts text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.2f V", x); return std::string(b);' - platform: homeassistant id: ha_current entity_id: sensor.magazyny_prad_suma name: "BMS Prąd" internal: false on_value: - lvgl.label.update: id: lbl_amps text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f A", x); return std::string(b);' - lvgl.label.update: id: lbl_page_amps text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f A", x); return std::string(b);' - platform: homeassistant id: ha_bms_tube_temp entity_id: sensor.jk_bms_nx_jk_bms_1_power_tube_temperature name: "Temperatura BMS Tube" internal: false on_value: - lvgl.label.update: id: lbl_page_bms_temp text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f °C", x); return std::string(b);' # --- TEMPERATURY ORAZ KOTŁOWNIA --- - platform: homeassistant id: ha_cwu_temp entity_id: sensor.152832117107914_current_temperature name: "Temperatura CWU" internal: false on_value: - lvgl.label.update: id: lbl_cwu text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f °C", x); return std::string(b);' - platform: homeassistant id: ha_kotlownia_temp entity_id: sensor.temperatura_kotlownia_temperatura_2 name: "Temperatura Kotłownia" internal: false on_value: - lvgl.label.update: id: lbl_kotlownia text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f °C", x); return std::string(b);' - platform: homeassistant id: ha_outdoor_temp entity_id: sensor.termometr_temperatura name: "Temperatura Na zewnątrz" internal: false on_value: - lvgl.label.update: id: lbl_outdoor text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f °C", x); return std::string(b);' - platform: homeassistant id: ha_salon_temp entity_id: sensor.czujnik_salon_wysw_temperatura name: "Temperatura Salon" internal: false on_value: - lvgl.label.update: id: lbl_salon text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f °C", x); return std::string(b);' - platform: homeassistant id: ha_boiler_power entity_id: sensor.boiler_burner_current_power name: "Moc Palnika Pieca" internal: false on_value: - lvgl.label.update: id: lbl_boiler_power text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f%%", x); return std::string(b);' # --- SENSORY ENERGETYCZNE --- - platform: homeassistant id: ha_home_power entity_id: sensor.11kwh_output_active_power name: "Moc na dom" internal: false on_value: - lvgl.label.update: id: lbl_home_power text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f W", x); return std::string(b);' - platform: homeassistant id: ha_pv_power entity_id: sensor.suma_pv name: "Moc PV" internal: false on_value: - lvgl.label.update: id: lbl_pv text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f W", x); return std::string(b);' - platform: homeassistant id: ha_pv_today entity_id: sensor.suma_produkcji_dzisiaj name: "Produkcja PV Dziś" internal: false on_value: - lvgl.label.update: id: lbl_pv_today text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.2f kWh", x); return std::string(b);' - lvgl.label.update: id: lbl_page_pv_today text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.2f kWh", x); return std::string(b);' # --- SENSORY POGODOWE ORAZ JAKOŚCI POWIETRZA --- - platform: homeassistant id: pogoda_temp entity_id: weather.pirateweather attribute: temperature name: "Pogoda Temperatura" internal: false on_value: - lvgl.label.update: id: lbl_weather_temp text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f°C", x); return std::string(b);' - lvgl.label.update: id: lbl_bottom_weather_temp text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f°C", x); return std::string(b);' - platform: homeassistant id: ha_air_index entity_id: sensor.dom_ogolny_indeks_jakosci_powietrza name: "Indeks Jakości Powietrza" internal: false on_value: - script.execute: update_air_quality_ui - platform: homeassistant id: ha_pm25 entity_id: sensor.dom_pm2_5 name: "Pył PM2.5" internal: false on_value: - lambda: 'id(global_pm25) = x;' - lvgl.label.update: id: lbl_pm25 text: !lambda 'char b[32]; snprintf(b, sizeof(b), "PM2.5: %.1f µg/m³", x); return std::string(b);' - script.execute: update_air_quality_ui - platform: homeassistant id: ha_pm10 entity_id: sensor.dom_pm10 name: "Pył PM10" internal: false on_value: - lvgl.label.update: id: lbl_pm10 text: !lambda 'char b[32]; snprintf(b, sizeof(b), "PM10: %.1f µg/m³", x); return std::string(b);' - platform: homeassistant id: ha_humidity entity_id: sensor.dom_wilgotnosc name: "Wilgotność" internal: false on_value: - lvgl.label.update: id: lbl_humidity text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f%%", x); return std::string(b);' - platform: homeassistant id: ha_pressure entity_id: sensor.dom_cisnienie name: "Ciśnienie" internal: false on_value: - lvgl.label.update: id: lbl_pressure text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f hPa", x); return std::string(b);' - lvgl.label.update: id: lbl_bottom_weather_press text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f hPa", x); return std::string(b);' # --- SENSORY DLA REKUPERATORA --- - platform: homeassistant id: reku_czerpnia entity_id: sensor.rekuperator_temperatura_czerpnia on_value: - lvgl.label.update: id: lbl_reku_czerpnia text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f°C", x); return std::string(b);' - platform: homeassistant id: reku_nawiew entity_id: sensor.rekuperator_temperatura_nawiew on_value: - lvgl.label.update: id: lbl_reku_nawiew text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f°C", x); return std::string(b);' - platform: homeassistant id: reku_wywiew entity_id: sensor.rekuperator_temperatura_wywiew on_value: - lvgl.label.update: id: lbl_reku_wywiew text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.1f°C", x); return std::string(b);' - platform: homeassistant id: reku_sprawnosc entity_id: sensor.rekuperator_sprawnosc on_value: - lvgl.label.update: id: lbl_reku_sprawnosc text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f%%", x); return std::string(b);' - platform: homeassistant id: reku_moc entity_id: sensor.rekuperator_odzyskana_moc on_value: - lvgl.label.update: id: lbl_reku_moc text: !lambda 'char b[16]; snprintf(b, sizeof(b), "%.0f W", x); return std::string(b);' # --- BINARY SENSORY (BYPASS I STANY WARUNKOWE) --- binary_sensor: - platform: status name: "Status WiFi" id: panel_status on_state: then: - lvgl.label.update: id: lbl_wifi text_color: !lambda 'return id(panel_status).state ? lv_color_hex(${color_wifi_ok}) : lv_color_hex(${color_alert});' # Siłownik Bypassu w Rekuperatorze - platform: homeassistant id: reku_bypass_state entity_id: binary_sensor.rekuperator_silownik_bypassu on_state: then: - if: condition: binary_sensor.is_on: reku_bypass_state then: - lvgl.widget.show: overlay_bypass else: - lvgl.widget.hide: overlay_bypass # --- SENSORY TEKSTOWE --- text_sensor: - platform: homeassistant id: pogoda_stan entity_id: weather.pirateweather name: "Stan Pogody" internal: false on_value: - lvgl.label.update: id: lbl_weather_status_pl text: !lambda |- if (x == "sunny") return std::string("Słonecznie"); else if (x == "rainy") return std::string("Opady deszczu"); else if (x == "pouring") return std::string("Ulewny deszcz"); else if (x == "cloudy") return std::string("Pochmurno"); else if (x == "partlycloudy") return std::string("Częściowe zachm."); else if (x == "snowy") return std::string("Opady śniegu"); return std::string("Umiarkowanie"); - lvgl.label.update: id: lbl_bottom_weather_status text: !lambda |- if (x == "sunny") return std::string("Słonecznie"); else if (x == "rainy") return std::string("Opady deszczu"); else if (x == "pouring") return std::string("Ulewny deszcz"); else if (x == "cloudy") return std::string("Pochmurno"); else if (x == "partlycloudy") return std::string("Częściowe zachm."); else if (x == "snowy") return std::string("Opady śniegu"); return std::string("Umiarkowanie"); - lvgl.label.update: id: lbl_weather_icon text: !lambda |- if (x == "sunny") return std::string("\U000F0590"); else if (x == "rainy") return std::string("\U000F0593"); else if (x == "pouring") return std::string("\U000F0594"); else if (x == "snowy") return std::string("\U000F0595"); return std::string("\U000F0592"); - lvgl.label.update: id: lbl_bottom_weather_icon text: !lambda |- if (x == "sunny") return std::string("\U000F0590"); else if (x == "rainy") return std::string("\U000F0593"); else if (x == "pouring") return std::string("\U000F0594"); else if (x == "snowy") return std::string("\U000F0595"); return std::string("\U000F0592"); # --- RYSOWANIE INTERFEJSU LVGL --- lvgl: displays: - main_display touchscreens: - touchscreen_id: touch buffer_size: 10% update_interval: 33ms on_idle: timeout: ${panel_sleep_timeout} then: - lvgl.page.show: screen_off_page - lambda: 'id(screen_dimmed) = true;' pages: # EKRAN GŁÓWNY (HOME) - id: home_page bg_color: ${color_bg} scrollable: false widgets: # Górny Pasek Statusu - obj: x: 0 y: 0 width: 800 height: 50 bg_color: ${color_topbar} border_width: 0 pad_all: 0 scrollable: false widgets: - label: align: LEFT_MID x: 15 text: "MONITOR DOMU" text_font: font_titles text_color: ${color_text} - label: id: lbl_time align: CENTER text: "--:--" text_font: font_titles text_color: ${color_text} - label: id: lbl_date align: RIGHT_MID x: -50 text: "--.--.----" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_wifi align: RIGHT_MID x: -15 text: "\U000F05A9" text_font: icon_24 text_color: ${color_alert} # KAFEL 1: BATERIA / BMS - obj: x: 15 y: 65 width: 240 height: 220 radius: 14 bg_color: ${color_card} border_width: 1 border_color: ${color_border} pad_all: 0 scrollable: false on_click: - lvgl.page.show: battery_page widgets: - label: align: TOP_LEFT x: 10 y: 10 text: "BMS / BATERIA" text_font: font_main text_color: ${color_text_dim} - obj: x: 23 y: 42 width: 24 height: 6 radius: 2 bg_color: 0x404040 border_width: 0 - obj: x: 10 y: 48 width: 50 height: 130 radius: 8 bg_color: 0x111111 border_width: 2 border_color: 0x404040 pad_all: 0 scrollable: false widgets: - obj: id: batt_fill align: BOTTOM_MID x: 0 y: -1 width: 46 height: 0 radius: 5 bg_color: ${color_battery} border_width: 0 - label: id: lbl_soc x: 70 y: 45 text: "--%" text_font: font_huge_param text_color: ${color_text} - label: x: 70 y: 92 text: "NAPIĘCIE:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_volts x: 70 y: 110 text: "-- V" text_font: font_large_param text_color: ${color_text} - label: x: 70 y: 148 text: "PRĄD:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_amps x: 70 y: 166 text: "-- A" text_font: font_large_param text_color: ${color_water} # KAFEL 2: KOTŁOWNIA I TEMPERATURY - obj: x: 265 y: 65 width: 520 height: 220 radius: 14 bg_color: ${color_card} border_width: 1 border_color: ${color_border} pad_all: 0 scrollable: false widgets: - label: align: TOP_LEFT x: 15 y: 8 text: "KOTŁOWNIA I TEMPERATURY" text_font: font_main text_color: ${color_text_dim} # 1. Ciepła woda - label: x: 15 y: 35 text: "\U000F0238" text_font: icon_24 text_color: ${color_boiler} - label: x: 45 y: 30 text: "Ciepła woda:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_cwu x: 45 y: 48 text: "--.- °C" text_font: font_huge_param text_color: ${color_boiler} # 2. Kotłownia Temp - label: x: 265 y: 35 text: "\U000F0E02" text_font: icon_24 text_color: ${color_pv} - label: x: 295 y: 30 text: "Kotłownia:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_kotlownia x: 295 y: 48 text: "--.- °C" text_font: font_huge_param text_color: ${color_pv} # 3. Na zewnątrz - label: x: 15 y: 95 text: "\U000F0510" text_font: icon_24 text_color: ${color_water} - label: x: 45 y: 90 text: "Na zewnątrz:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_outdoor x: 45 y: 108 text: "--.- °C" text_font: font_huge_param text_color: ${color_water} # 4. Salon - label: x: 265 y: 95 text: "\U000F02DC" text_font: icon_24 text_color: ${color_battery} - label: x: 295 y: 90 text: "Salon:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_salon x: 295 y: 108 text: "--.- °C" text_font: font_huge_param text_color: ${color_battery} # MOC PALNIKA PIECA - obj: align: BOTTOM_RIGHT x: -12 y: -10 width: 250 height: 45 radius: 10 bg_color: 0x141414 border_width: 1 border_color: 0x303030 pad_all: 0 scrollable: false widgets: - label: align: LEFT_MID x: 10 text: "MOC PALNIKA:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_boiler_power align: RIGHT_MID x: -10 text: "--%" text_font: font_large_param text_color: ${color_boiler} # --- 3 KAFELKI INFORMACYJNE O ENERGII --- - obj: x: 15 y: 300 width: 240 height: 100 radius: 14 bg_color: ${color_off} border_width: 1 border_color: ${color_off_border} pad_all: 0 scrollable: false widgets: - label: align: TOP_LEFT x: 12 y: 8 text: "\U000F0241" text_font: icon_24 text_color: ${color_water} - label: x: 42 y: 10 text: "MOC NA DOM" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_home_power align: BOTTOM_LEFT x: 12 y: -12 text: "-- W" text_font: font_huge_param text_color: ${color_water} # KAFEL PV - obj: x: 280 y: 300 width: 240 height: 100 radius: 14 bg_color: ${color_off} border_width: 1 border_color: ${color_off_border} pad_all: 0 scrollable: false widgets: - label: align: TOP_LEFT x: 12 y: 8 text: "\U000F00A8" text_font: icon_24 text_color: ${color_pv} - label: x: 42 y: 10 text: "MOC PANELI PV" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_pv align: BOTTOM_LEFT x: 12 y: -12 text: "-- W" text_font: font_huge_param text_color: ${color_pv} # KAFEL PRODUKCJA DZIŚ - obj: x: 545 y: 300 width: 240 height: 100 radius: 14 bg_color: ${color_off} border_width: 1 border_color: ${color_off_border} pad_all: 0 scrollable: false widgets: - label: align: TOP_LEFT x: 12 y: 8 text: "\U000F01E2" text_font: icon_24 text_color: ${color_battery} - label: x: 42 y: 10 text: "PRODUKCJA DZIŚ" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_pv_today align: BOTTOM_LEFT x: 12 y: -12 text: "-- kWh" text_font: font_huge_param text_color: ${color_battery} # DOLNY DYNAMICZNY PASEK POGODOWY Z PRZYCISKIEM WENTYLATORA - button: x: 0 y: 420 width: 800 height: 60 bg_color: ${color_topbar} border_width: 0 pad_all: 0 scrollable: false on_click: - lvgl.page.show: weather_page widgets: - label: id: lbl_bottom_weather_icon align: LEFT_MID x: 20 text: "\U000F0592" text_font: icon_30 text_color: ${color_pv} - label: id: lbl_bottom_weather_status align: LEFT_MID x: 65 text: "Ładowanie..." text_font: font_titles text_color: ${color_text} - label: id: lbl_bottom_weather_temp align: CENTER x: -30 text: "--.-°C" text_font: font_big text_color: ${color_water} - label: id: lbl_bottom_weather_press align: RIGHT_MID x: -90 text: "-- hPa" text_font: font_titles text_color: ${color_battery} # IKONA WENTYLATORA (PRZYCISK PRZENOSZĄCY DO REKUPERACJI) - button: x: 735 y: 425 width: 50 height: 50 radius: 12 bg_color: ${color_off} border_width: 1 border_color: ${color_water} pad_all: 0 on_click: - lvgl.page.show: reku_page widgets: - label: align: CENTER text: "\U000F0210" # mdi-fan text_font: icon_30 text_color: ${color_water} # EKRAN 2: DEDYKOWANA STRONA BATERII (LIFEPO4) - id: battery_page bg_color: ${color_bg} scrollable: false widgets: - obj: x: 0 y: 0 width: 800 height: 50 bg_color: ${color_topbar} border_width: 0 pad_all: 0 scrollable: false widgets: - label: align: LEFT_MID x: 15 text: "AKUMULATOR LIFEPO4 (BMS)" text_font: font_titles text_color: ${color_battery} - obj: x: 30 y: 65 width: 740 height: 150 radius: 18 bg_color: ${color_card} border_width: 1 border_color: ${color_border} pad_all: 0 scrollable: false widgets: - label: align: TOP_LEFT x: 20 y: 12 text: "LIFEPO4" text_font: font_titles text_color: ${color_text_dim} - obj: x: 20 y: 50 width: 250 height: 80 radius: 10 bg_color: 0x111111 border_width: 3 border_color: 0x404040 pad_all: 0 scrollable: false widgets: - obj: id: page_batt_fill align: LEFT_MID x: 2 width: 0 height: 72 radius: 6 bg_color: ${color_battery} border_width: 0 - obj: x: 271 y: 72 width: 10 height: 36 radius: 3 bg_color: 0x404040 border_width: 0 - label: id: lbl_page_soc x: 310 y: 50 text: "--%" text_font: font_weather_temp text_color: ${color_text} - obj: x: 30 y: 230 width: 740 height: 180 radius: 18 bg_color: ${color_card} border_width: 1 border_color: ${color_border} pad_all: 0 scrollable: false widgets: - label: x: 30 y: 20 text: "NAPIĘCIE CAŁKOWITE:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_page_volts x: 30 y: 45 text: "-- V" text_font: font_huge_param text_color: ${color_text} - label: x: 400 y: 20 text: "PRĄD ŁADOWANIA / ROZŁ.:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_page_amps x: 400 y: 45 text: "-- A" text_font: font_huge_param text_color: ${color_water} - label: x: 30 y: 100 text: "PRODUKCJA PV DZIŚ:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_page_pv_today x: 30 y: 125 text: "-- kWh" text_font: font_huge_param text_color: ${color_pv} - label: x: 400 y: 100 text: "TEMPERATURA BMS / TUBE:" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_page_bms_temp x: 400 y: 125 text: "--.- °C" text_font: font_huge_param text_color: ${color_boiler} - button: x: 0 y: 425 width: 800 height: 55 bg_color: ${color_home_tab} pad_all: 0 scrollable: false on_click: - lvgl.page.show: home_page widgets: - label: align: CENTER text: "GŁÓWNA" text_font: font_titles text_color: ${color_home_tab_t} # EKRAN 3: POGODA ORAZ JAKOŚĆ POWIETRZA - id: weather_page bg_color: ${color_bg} scrollable: false widgets: - obj: x: 0 y: 0 width: 800 height: 50 bg_color: ${color_topbar} border_width: 0 pad_all: 0 scrollable: false widgets: - label: align: CENTER text: "POGODA I JAKOŚĆ POWIETRZA" text_font: font_titles text_color: ${color_text} - obj: x: 20 y: 60 width: 760 height: 155 radius: 16 bg_color: ${color_card} border_width: 1 border_color: ${color_border} pad_all: 0 scrollable: false widgets: - label: id: lbl_weather_icon x: 25 y: 35 text: "\U000F0592" text_font: icon_huge_weather text_color: ${color_pv} - label: id: lbl_weather_temp x: 130 y: 25 text: "--.-°C" text_font: font_weather_temp text_color: ${color_text} - label: id: lbl_weather_status_pl x: 135 y: 100 text: "Ładowanie..." text_font: font_titles text_color: ${color_water} - obj: x: 20 y: 225 width: 760 height: 180 radius: 18 bg_color: ${color_card} border_width: 1 border_color: ${color_border} pad_all: 0 scrollable: false widgets: - label: align: TOP_MID y: 10 text: "JAKOŚĆ POWIETRZA" text_font: font_main text_color: ${color_text_dim} - label: id: lbl_air_status align: TOP_MID y: 32 text: "Ładowanie..." text_font: font_big text_color: ${color_battery} - obj: x: 20 y: 80 width: 720 height: 1 bg_color: 0x2A2A2A border_width: 0 - label: id: lbl_pm25 x: 40 y: 95 text: "PM2.5: -- µg/m³" text_font: font_main text_color: ${color_text} - label: id: lbl_pm10 x: 430 y: 95 text: "PM10: -- µg/m³" text_font: font_main text_color: ${color_text} - obj: x: 20 y: 125 width: 720 height: 1 bg_color: 0x2A2A2A border_width: 0 - label: x: 40 y: 140 text: "\U000F058A" text_font: icon_24 text_color: ${color_water} - label: id: lbl_humidity x: 75 y: 142 text: "--%" text_font: font_titles text_color: ${color_water} - label: x: 430 y: 140 text: "\U000F0379" text_font: icon_24 text_color: ${color_battery} - label: id: lbl_pressure x: 465 y: 142 text: "-- hPa" text_font: font_titles text_color: ${color_battery} - button: x: 0 y: 425 width: 800 height: 55 bg_color: ${color_home_tab} pad_all: 0 scrollable: false on_click: - lvgl.page.show: home_page widgets: - label: align: CENTER text: "GŁÓWNA" text_font: font_titles text_color: ${color_home_tab_t} # EKRAN 4: STRONA REKUPERATORA Z PEŁNOWYMIAROWYM SCHEMATEM - id: reku_page bg_color: ${color_bg} scrollable: false widgets: # Górny Pasek - obj: x: 0 y: 0 width: 800 height: 45 bg_color: ${color_topbar} border_width: 0 pad_all: 0 scrollable: false widgets: - label: align: LEFT_MID x: 15 text: "REKUPERACJA - SCHEMAT PRACY" text_font: font_titles text_color: ${color_water} # SEKCJA WIZUALNA: PEŁNY SCHEMAT Z TEMPERATURAMI - obj: x: 10 y: 50 width: 780 height: 365 radius: 14 bg_color: ${color_card} border_width: 1 border_color: ${color_border} pad_all: 0 scrollable: false widgets: # Grafika podkładu rekuperatora (wyśrodkowana w pionie i poziomie) - image: src: img_reku_bg align: CENTER x: 0 y: -10 # Nakładka siłownika bypassu - image: id: overlay_bypass src: img_reku_bypass align: CENTER x: 0 y: -10 hidden: true # NAKŁADANE ETYKIETY TEMPERATUR NA SCHEMAT # 1. Czerpnia (lewy górny róg) - label: id: lbl_reku_czerpnia x: 40 y: 35 text: "--.-°C" text_font: font_titles text_color: ${color_water} # 2. Wywiew (prawy górny róg) - label: id: lbl_reku_wywiew x: 630 y: 35 text: "--.-°C" text_font: font_titles text_color: ${color_pv} # 3. Nawiew (prawy dolny róg) - label: id: lbl_reku_nawiew x: 630 y: 285 text: "--.-°C" text_font: font_titles text_color: ${color_battery} # 4. Sprawność (na środku u dołu wymiennika) - label: id: lbl_reku_sprawnosc align: BOTTOM_MID x: -60 y: -25 text: "--%" text_font: font_titles text_color: ${color_text} # 5. Odzyskana moc - label: id: lbl_reku_moc align: BOTTOM_MID x: 60 y: -25 text: "-- W" text_font: font_titles text_color: ${color_pv} # PASEK NAWIGACJI POWROTNEJ (DOLNY) - button: x: 0 y: 425 width: 800 height: 55 bg_color: ${color_home_tab} pad_all: 0 scrollable: false on_click: - lvgl.page.show: home_page widgets: - label: align: CENTER text: "GŁÓWNA" text_font: font_titles text_color: ${color_home_tab_t} # EKRAN WYGASZACZA (SLEEP) - id: screen_off_page bg_color: ${color_bg} scrollable: false on_click: - lvgl.page.show: home_page - lambda: 'id(screen_dimmed) = false;' widgets: - label: id: lbl_sleep_time align: CENTER y: -80 text: "--:--" text_font: font_sleep_clock_huge text_color: ${color_text} - label: id: lbl_sleep_date align: CENTER y: 65 text: "--, --.--.----" text_font: font_sleep_date text_color: ${color_text_dim} - label: align: CENTER y: 165 text: "DOTKNIJ ABY WYBUDZIĆ" text_font: font_titles text_color: ${color_text_subtle}