diff --git a/esphome/esp-bedside-panel.yaml b/esphome/esp-bedside-panel.yaml index 69f0943..ec06ab8 100644 --- a/esphome/esp-bedside-panel.yaml +++ b/esphome/esp-bedside-panel.yaml @@ -6,29 +6,32 @@ # https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml #:########################################################################################:# # VERSIONS: -# V0.8p 2026-07-16 Changed the Heat Pump high-output profile name from Boost to Boost -# V0.8o 2026-07-16 Added reliable MDI setpoint arrows and optimistic mutually-exclusive Heat Pump profiles -# V0.8n 2026-07-16 Fixed setpoint arrow icons using LVGL built-in FontAwesome symbols -# V0.8m 2026-07-16 Added Quiet / Boost profiles, Night Power toggle and improved Climate state highlighting +# V0.8s 2026-07-16 Added direct Panasonic preset control and optimistic Nano-X +# V0.8r 2026-07-16 Added LVGL startup guards and reduced draw buffer to 6% +# V0.8q 2026-07-16 Added direct profile helper selection, Nano-X and aligned Climate layout +# V0.8p 2026-07-16 Renamed the Heat Pump high-output profile from Powerful to Boost +# V0.8o 2026-07-16 Added reliable MDI setpoint arrows and optimistic profile controls +# V0.8n 2026-07-16 Fixed setpoint arrow icons using LVGL built-in symbols +# V0.8m 2026-07-16 Added Quiet / Boost profiles, Night Power toggle and improved highlighting # V0.8l 2026-07-16 Completed primary Climate controls, ceiling fan cycle and Air Filter Low # V0.8k 2026-07-16 Revised Bedroom header and added five-button navigation row -# V0.8j 2026-07-16 Added delayed Home Assistant state synchronisation for button highlighting at startup -# V0.8i 2026-07-16 Moved Clock date upward, added missing value glyphs and increased Clock to 190px +# V0.8j 2026-07-16 Added delayed Home Assistant state synchronisation at startup +# V0.8i 2026-07-16 Moved Clock date upward, added glyphs and increased Clock to 190px # V0.8h 2026-07-16 Updated local environment entities and added Moon / Outdoor readings -# V0.8g 2026-07-16 Added working Climate mode buttons and retained lightweight placeholders +# V0.8g 2026-07-16 Added working Climate mode buttons and retained placeholders # V0.8f 2026-07-15 Added minimal Climate page with two placeholders and Back button # V0.8e 2026-07-15 Centred Bedroom button captions only; no additional pages # V0.8b 2026-07-15 Changed proven V0.8a clock to 24-hour format and removed AM/PM # V0.8a 2026-07-14 Reduced LVGL memory load after V0.8 OTA rollback # Added lean large-clock idle page and Bedroom controls -# V0.8 2026-07-14 Added large bedside clock, idle dimming and first bedroom control page +# V0.8 2026-07-14 Added large bedside clock, idle dimming and first Bedroom page # V0.7 2026-07-14 Added first landscape LVGL page and Home Assistant test button # V0.6 2026-07-14 Added GT911 touchscreen and touch-coordinate logging # V0.5 2026-07-14 Added corrected JC1060P470 MIPI display configuration and text test -# V0.4 2026-07-14 Removed MIPI display test after setup watchdog boot loop; retained backlight-only test +# V0.4 2026-07-14 Removed MIPI display test after setup watchdog boot loop # V0.3 2026-07-14 Added backlight control and first MIPI display text test # V0.2 2026-07-14 Added ESP32 hosted WiFi via ESP32-C6 co-processor -# V0.1 2026-07-14 Initial ESPHome bring-up for Guition JC1060P470C_I_W_Y ESP32-P4 panel +# V0.1 2026-07-14 Initial ESPHome bring-up for Guition JC1060P470C_I_W_Y #:########################################################################################:# # HARDWARE: # - Guition JC1060P470C_I_W_Y @@ -84,12 +87,12 @@ substitutions: # Device Naming device_name: "esp-bedside-panel" friendly_name: "ESP Bedside Panel" - description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Climate layout with guarded LVGL startup and additional memory headroom. (Layout V1.1)" + description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Direct Panasonic Eco/Boost/None presets with optimistic Nano-X. (Layout V1.1)" device_area: "Bedroom" # Project Naming project_name: "Guition.JC1060P470C_I_W_Y" - project_version: "v0.8r" + project_version: "v0.8s" # Passwords & Secrets api_key: !secret esp-api_key @@ -720,6 +723,9 @@ binary_sensor: internal: true on_state: then: + - lambda: |- + id(nanoe_optimistic) = -1; + - script.execute: refresh_climate_controls - platform: homeassistant @@ -753,11 +759,17 @@ globals: restore_value: false initial_value: "false" - # 0 = Normal, 1 = Quiet, 2 = Boost. + # -1 = follow HA, 0 = Normal, 1 = Quiet, 2 = Boost. - id: climate_profile_optimistic type: int restore_value: false - initial_value: "0" + initial_value: "-1" + + # -1 = follow HA, 0 = off, 1 = on. + - id: nanoe_optimistic + type: int + restore_value: false + initial_value: "-1" #:########################################################################################:# # SCRIPTS: @@ -1004,25 +1016,84 @@ script: ? lv_color_hex(0x32677F) : lv_color_hex(0x28313D); - # Quiet / Boost are mutually exclusive. Normal means neither is lit. + # Quiet / Boost are mutually exclusive. Optimistic state wins + # immediately; actual Panasonic preset is authoritative afterwards. - lvgl.widget.update: id: climate_quiet_button bg_color: !lambda |- - return id(climate_profile_optimistic) == 1 + int selected = id(climate_profile_optimistic); + + if (selected < 0) { + const auto preset = id(ha_climate_preset_mode).state; + const auto helper = id(ha_climate_profile).state; + + if ( + preset == "eco" || + preset == "quiet" || + preset == "Quiet" || + helper == "Quiet" || + helper == "quiet" + ) { + selected = 1; + } else if ( + preset == "boost" || + preset == "Boost" || + helper == "Boost" || + helper == "boost" + ) { + selected = 2; + } else { + selected = 0; + } + } + + return selected == 1 ? lv_color_hex(0x315843) : lv_color_hex(0x28313D); - lvgl.widget.update: id: climate_boost_button bg_color: !lambda |- - return id(climate_profile_optimistic) == 2 + int selected = id(climate_profile_optimistic); + + if (selected < 0) { + const auto preset = id(ha_climate_preset_mode).state; + const auto helper = id(ha_climate_profile).state; + + if ( + preset == "eco" || + preset == "quiet" || + preset == "Quiet" || + helper == "Quiet" || + helper == "quiet" + ) { + selected = 1; + } else if ( + preset == "boost" || + preset == "Boost" || + helper == "Boost" || + helper == "boost" + ) { + selected = 2; + } else { + selected = 0; + } + } + + return selected == 2 ? lv_color_hex(0x6B4A86) : lv_color_hex(0x28313D); - lvgl.widget.update: id: climate_nanoe_button bg_color: !lambda |- - return id(ha_nanoe).state + bool active = id(ha_nanoe).state; + + if (id(nanoe_optimistic) >= 0) { + active = id(nanoe_optimistic) == 1; + } + + return active ? lv_color_hex(0x315E82) : lv_color_hex(0x28313D); @@ -1089,6 +1160,26 @@ script: ? lv_color_hex(0x5A4778) : lv_color_hex(0x28313D); + - id: release_climate_profile_optimistic + mode: restart + then: + - delay: 5s + + - lambda: |- + id(climate_profile_optimistic) = -1; + + - script.execute: refresh_climate_controls + + - id: release_nanoe_optimistic + mode: restart + then: + - delay: 5s + + - lambda: |- + id(nanoe_optimistic) = -1; + + - script.execute: refresh_climate_controls + # Two passes allow time for LVGL creation and Home Assistant state delivery. - id: startup_button_state_sync mode: restart @@ -1168,22 +1259,24 @@ text_sensor: then: - script.execute: refresh_climate_controls - # Authoritative Heat Pump profile helper: Boost / Quiet / Normal. + # User-facing profile helper: Boost / Quiet / Normal. - platform: homeassistant id: ha_climate_profile entity_id: "${climate_profile_entity}" internal: true on_value: then: - - lambda: |- - if (x == "Quiet" || x == "quiet") { - id(climate_profile_optimistic) = 1; - } else if (x == "Boost" || x == "boost") { - id(climate_profile_optimistic) = 2; - } else { - id(climate_profile_optimistic) = 0; - } + - script.execute: refresh_climate_controls + # Actual Panasonic Comfort Cloud preset for this installation: + # eco = Quiet, boost = Boost, none = Normal. + - platform: homeassistant + id: ha_climate_preset_mode + entity_id: "${climate_entity}" + attribute: preset_mode + internal: true + on_value: + then: - script.execute: refresh_climate_controls - platform: version @@ -1878,8 +1971,34 @@ lvgl: on_click: # Quiet toggles between Quiet and Normal. - lambda: |- + int selected = id(climate_profile_optimistic); + + if (selected < 0) { + const auto preset = id(ha_climate_preset_mode).state; + const auto helper = id(ha_climate_profile).state; + + if ( + preset == "eco" || + preset == "quiet" || + preset == "Quiet" || + helper == "Quiet" || + helper == "quiet" + ) { + selected = 1; + } else if ( + preset == "boost" || + preset == "Boost" || + helper == "Boost" || + helper == "boost" + ) { + selected = 2; + } else { + selected = 0; + } + } + id(climate_profile_optimistic) = - id(climate_profile_optimistic) == 1 ? 0 : 1; + selected == 1 ? 0 : 1; - script.execute: refresh_climate_controls @@ -1895,6 +2014,12 @@ lvgl: entity_id: "${climate_profile_entity}" option: "Quiet" + - homeassistant.action: + action: climate.set_preset_mode + data: + entity_id: "${climate_entity}" + preset_mode: "eco" + else: - homeassistant.action: action: input_select.select_option @@ -1902,6 +2027,14 @@ lvgl: entity_id: "${climate_profile_entity}" option: "Normal" + - homeassistant.action: + action: climate.set_preset_mode + data: + entity_id: "${climate_entity}" + preset_mode: "none" + + - script.execute: release_climate_profile_optimistic + - button: id: climate_boost_button x: 180 @@ -1924,8 +2057,34 @@ lvgl: on_click: # Boost toggles between Boost and Normal. - lambda: |- + int selected = id(climate_profile_optimistic); + + if (selected < 0) { + const auto preset = id(ha_climate_preset_mode).state; + const auto helper = id(ha_climate_profile).state; + + if ( + preset == "eco" || + preset == "quiet" || + preset == "Quiet" || + helper == "Quiet" || + helper == "quiet" + ) { + selected = 1; + } else if ( + preset == "boost" || + preset == "Boost" || + helper == "Boost" || + helper == "boost" + ) { + selected = 2; + } else { + selected = 0; + } + } + id(climate_profile_optimistic) = - id(climate_profile_optimistic) == 2 ? 0 : 2; + selected == 2 ? 0 : 2; - script.execute: refresh_climate_controls @@ -1941,6 +2100,12 @@ lvgl: entity_id: "${climate_profile_entity}" option: "Boost" + - homeassistant.action: + action: climate.set_preset_mode + data: + entity_id: "${climate_entity}" + preset_mode: "boost" + else: - homeassistant.action: action: input_select.select_option @@ -1948,6 +2113,14 @@ lvgl: entity_id: "${climate_profile_entity}" option: "Normal" + - homeassistant.action: + action: climate.set_preset_mode + data: + entity_id: "${climate_entity}" + preset_mode: "none" + + - script.execute: release_climate_profile_optimistic + - button: id: climate_nanoe_button x: 335 @@ -1968,10 +2141,35 @@ lvgl: text_font: font_button text_color: 0xFFFFFF on_click: - - homeassistant.action: - action: switch.toggle - data: - entity_id: "${nanoe_entity}" + - lambda: |- + bool active = id(ha_nanoe).state; + + if (id(nanoe_optimistic) >= 0) { + active = id(nanoe_optimistic) == 1; + } + + id(nanoe_optimistic) = active ? 0 : 1; + + - script.execute: refresh_climate_controls + + - if: + condition: + lambda: |- + return id(nanoe_optimistic) == 1; + + then: + - homeassistant.action: + action: switch.turn_on + data: + entity_id: "${nanoe_entity}" + + else: + - homeassistant.action: + action: switch.turn_off + data: + entity_id: "${nanoe_entity}" + + - script.execute: release_nanoe_optimistic - button: id: climate_setpoint_down_button