diff --git a/components/nspanel_easy/addon_climate.h b/components/nspanel_easy/addon_climate.h index c5ed985b..343e926c 100644 --- a/components/nspanel_easy/addon_climate.h +++ b/components/nspanel_easy/addon_climate.h @@ -51,6 +51,19 @@ namespace nspanel_easy { CLIMATE_MODE_AUTO = 6 ///< Climate device is set to automatic mode }; + /** + * @enum ClimateChipVisibility + * @brief Controls when the climate chip is shown on the home screen. + * + * Sent by the blueprint on boot via `action_component_val` with `page: "mem"` + * and stored in the `climate_chip_visibility` global. + */ + enum ClimateChipVisibility : uint8_t { + CLIMATE_CHIP_ACTIVE_ONLY = 0, ///< Show chip only when actively heating/cooling/drying/fan + CLIMATE_CHIP_ALWAYS = 1, ///< Always show chip when a climate entity is configured + CLIMATE_CHIP_NEVER = 2 ///< Never show the chip, regardless of climate state + }; + // ============================================================================= // Climate Icon Lookup Tables // ============================================================================= diff --git a/esphome/nspanel_esphome_addon_climate_base.yaml b/esphome/nspanel_esphome_addon_climate_base.yaml index 60c4278d..3e9a7e64 100644 --- a/esphome/nspanel_esphome_addon_climate_base.yaml +++ b/esphome/nspanel_esphome_addon_climate_base.yaml @@ -29,6 +29,7 @@ substitutions: cool_overrun: ${1 if TEMP_UNIT_IS_FAHRENHEIT else 0.5} # Temperature delta before disengaging cooling heat_deadband: ${1 if TEMP_UNIT_IS_FAHRENHEIT else 0.5} # Temperature delta before engaging heat heat_overrun: ${1 if TEMP_UNIT_IS_FAHRENHEIT else 0.5} # Temperature delta before disengaging heat + climate_chip_visibility_default: "0" # CLIMATE_CHIP_ACTIVE_ONLY TAG_ADDON_CLIMATE: nspanel.addon.climate esphome: @@ -67,6 +68,12 @@ climate: ESP_LOGV("${TAG_ADDON_CLIMATE}", "Update page 'home'"); page_home->execute(); +globals: + - id: climate_chip_visibility + type: uint8_t + restore_value: true + initial_value: '${climate_chip_visibility_default}' + switch: ##### PHYSICAL SWITCH 0 (Dummy) - Used when relay is not set ##### - name: Relay 0 (dummy) @@ -80,13 +87,29 @@ script: - id: !extend action_component_text then: - lambda: |- - if (page == "mem") { - if (component == "addon_climate_friendly_name") { - ESP_LOGV("${TAG_ADDON_CLIMATE}", "Set addon_climate_friendly_name:"); - ESP_LOGV("${TAG_ADDON_CLIMATE}", " from: %s", addon_climate_friendly_name.c_str()); - ESP_LOGV("${TAG_ADDON_CLIMATE}", " to: %s", txt.c_str()); - addon_climate_friendly_name = txt; + if (page != "mem") return; + if (component == "addon_climate_friendly_name") { + ESP_LOGV("${TAG_ADDON_CLIMATE}", "Set addon_climate_friendly_name:"); + ESP_LOGV("${TAG_ADDON_CLIMATE}", " from: %s", addon_climate_friendly_name.c_str()); + ESP_LOGV("${TAG_ADDON_CLIMATE}", " to: %s", txt.c_str()); + addon_climate_friendly_name = txt; + return; + } + + - id: !extend action_component_val + then: + - lambda: |- + if (page != "mem") return; + if (component == "climate_chip_visibility") { + const bool valid = (val >= static_cast(nspanel_easy::CLIMATE_CHIP_ACTIVE_ONLY) && + val <= static_cast(nspanel_easy::CLIMATE_CHIP_NEVER)); + id(climate_chip_visibility) = valid + ? static_cast(val) + : static_cast(nspanel_easy::CLIMATE_CHIP_ACTIVE_ONLY); + if (!valid) { + ESP_LOGW("${TAG_ADDON_CLIMATE}", "Invalid climate_chip_visibility: %d. Falling back to ACTIVE_ONLY", val); } + ESP_LOGD("${TAG_ADDON_CLIMATE}", "climate_chip_visibility set to %" PRIu8, id(climate_chip_visibility)); } - id: !extend change_climate_state @@ -373,22 +396,46 @@ script: ESP_LOGV("${TAG_ADDON_CLIMATE}", " component: %s", component.c_str()); ESP_LOGV("${TAG_ADDON_CLIMATE}", " action: %d", action); ESP_LOGV("${TAG_ADDON_CLIMATE}", " mode: %d", mode); + ESP_LOGV("${TAG_ADDON_CLIMATE}", " visibility: %" PRIu8, id(climate_chip_visibility)); + + // Determine visibility based on user preference and current climate state + const auto visibility = static_cast(id(climate_chip_visibility)); + const bool is_active = (action == nspanel_easy::CLIMATE_ACTION_COOLING || + action == nspanel_easy::CLIMATE_ACTION_HEATING || + action == nspanel_easy::CLIMATE_ACTION_DRYING || + action == nspanel_easy::CLIMATE_ACTION_FAN); + + bool visible = false; + if (visibility == nspanel_easy::CLIMATE_CHIP_NEVER) { + visible = false; // Never show + } else if (visibility == nspanel_easy::CLIMATE_CHIP_ALWAYS) { + visible = true; // Always show + } else { + visible = is_active; // Active only (default) + } + + ESP_LOGV("${TAG_ADDON_CLIMATE}", " visible: %s", YESNO(visible)); const char* icon = Icons::NONE; uint16_t color = Colors::BLACK; - if (action == nspanel_easy::CLIMATE_ACTION_OFF) { - // Handle OFF action with different modes - if (mode <= nspanel_easy::CLIMATE_MODE_AUTO) { - icon = climate_off_mode_icons[mode].icon; - color = climate_off_mode_icons[mode].color; + if (visible) { + if (action == nspanel_easy::CLIMATE_ACTION_OFF) { + // Handle OFF action — only reached when visibility != NEVER + if (mode <= nspanel_easy::CLIMATE_MODE_AUTO) { + icon = climate_off_mode_icons[mode].icon; + color = climate_off_mode_icons[mode].color; + } + } else if (is_active) { + // Handle actively running states (heating/cooling/drying/fan) + icon = climate_action_icons[action].icon; + color = climate_action_icons[action].color; + } else if (action == nspanel_easy::CLIMATE_ACTION_IDLE) { + // Handle idle — only reached when visibility == ALWAYS + icon = climate_action_icons[nspanel_easy::CLIMATE_ACTION_IDLE].icon; + color = climate_action_icons[nspanel_easy::CLIMATE_ACTION_IDLE].color; } - } else if (action >= nspanel_easy::CLIMATE_ACTION_COOLING - && action <= nspanel_easy::CLIMATE_ACTION_FAN) { - // Handle active action states - icon = climate_action_icons[action].icon; - color = climate_action_icons[action].color; - } + } // #endif visible — icon/color remain NONE/BLACK when hidden // Extract component information using helper function const NextionComponent comp = extractNextionComponent(component, page_names[current_page_id]); diff --git a/esphome/nspanel_esphome_version.yaml b/esphome/nspanel_esphome_version.yaml index 99882cfe..cd9c3b7a 100644 --- a/esphome/nspanel_esphome_version.yaml +++ b/esphome/nspanel_esphome_version.yaml @@ -11,8 +11,8 @@ substitutions: # Value is imported from versioning/version.yaml <<: !include ../versioning/version.yaml # Minimum required versions for compatibility - min_blueprint_version: 4 - min_tft_version: 4 + min_blueprint_version: 5 + min_tft_version: 5 min_esphome_compiler_version: 2026.1.0 TAG_VERSIONING: nspanel.versioning diff --git a/hmi/dev/nspanel_CJK_eu_code/boot.txt b/hmi/dev/nspanel_CJK_eu_code/boot.txt index e728b8d3..aa494f48 100644 --- a/hmi/dev/nspanel_CJK_eu_code/boot.txt +++ b/hmi/dev/nspanel_CJK_eu_code/boot.txt @@ -60,7 +60,7 @@ Variable (string) version Attributes ID : 6 Scope : global - Text : 4 + Text : 5 Max. Text Size: 7 Variable (int32) log_len diff --git a/hmi/dev/nspanel_CJK_eu_code/light.txt b/hmi/dev/nspanel_CJK_eu_code/light.txt index ee00bccb..e4b36b43 100644 --- a/hmi/dev/nspanel_CJK_eu_code/light.txt +++ b/hmi/dev/nspanel_CJK_eu_code/light.txt @@ -684,8 +684,8 @@ Slider tempslider Back. Picture ID : 21 Slided Back. Picture ID: 21 Position : 0 - Upper range limit : 6535 - Lower range limit : 2000 + Upper range limit : 2000 + Lower range limit : 6535 Events Touch Release Event diff --git a/hmi/dev/nspanel_CJK_us_code/boot.txt b/hmi/dev/nspanel_CJK_us_code/boot.txt index cb1eb4b3..fad9c6d2 100644 --- a/hmi/dev/nspanel_CJK_us_code/boot.txt +++ b/hmi/dev/nspanel_CJK_us_code/boot.txt @@ -60,7 +60,7 @@ Variable (string) version Attributes ID : 6 Scope : global - Text : 4 + Text : 5 Max. Text Size: 7 Variable (int32) log_len diff --git a/hmi/dev/nspanel_CJK_us_code/light.txt b/hmi/dev/nspanel_CJK_us_code/light.txt index 2e6c23c6..e759380f 100644 --- a/hmi/dev/nspanel_CJK_us_code/light.txt +++ b/hmi/dev/nspanel_CJK_us_code/light.txt @@ -684,8 +684,8 @@ Slider tempslider Back. Picture ID : 21 Slided Back. Picture ID: 21 Position : 0 - Upper range limit : 6535 - Lower range limit : 2000 + Upper range limit : 2000 + Lower range limit : 6535 Events Touch Release Event diff --git a/hmi/dev/nspanel_CJK_us_land_code/boot.txt b/hmi/dev/nspanel_CJK_us_land_code/boot.txt index e552c587..a2dd5e13 100644 --- a/hmi/dev/nspanel_CJK_us_land_code/boot.txt +++ b/hmi/dev/nspanel_CJK_us_land_code/boot.txt @@ -60,7 +60,7 @@ Variable (string) version Attributes ID : 6 Scope : global - Text : 4 + Text : 5 Max. Text Size: 7 Variable (int32) log_len diff --git a/hmi/dev/nspanel_CJK_us_land_code/light.txt b/hmi/dev/nspanel_CJK_us_land_code/light.txt index ee00bccb..e4b36b43 100644 --- a/hmi/dev/nspanel_CJK_us_land_code/light.txt +++ b/hmi/dev/nspanel_CJK_us_land_code/light.txt @@ -684,8 +684,8 @@ Slider tempslider Back. Picture ID : 21 Slided Back. Picture ID: 21 Position : 0 - Upper range limit : 6535 - Lower range limit : 2000 + Upper range limit : 2000 + Lower range limit : 6535 Events Touch Release Event diff --git a/hmi/dev/nspanel_eu_code/boot.txt b/hmi/dev/nspanel_eu_code/boot.txt index e728b8d3..aa494f48 100644 --- a/hmi/dev/nspanel_eu_code/boot.txt +++ b/hmi/dev/nspanel_eu_code/boot.txt @@ -60,7 +60,7 @@ Variable (string) version Attributes ID : 6 Scope : global - Text : 4 + Text : 5 Max. Text Size: 7 Variable (int32) log_len diff --git a/hmi/dev/nspanel_eu_code/light.txt b/hmi/dev/nspanel_eu_code/light.txt index ee00bccb..e4b36b43 100644 --- a/hmi/dev/nspanel_eu_code/light.txt +++ b/hmi/dev/nspanel_eu_code/light.txt @@ -684,8 +684,8 @@ Slider tempslider Back. Picture ID : 21 Slided Back. Picture ID: 21 Position : 0 - Upper range limit : 6535 - Lower range limit : 2000 + Upper range limit : 2000 + Lower range limit : 6535 Events Touch Release Event diff --git a/hmi/dev/nspanel_us_code/boot.txt b/hmi/dev/nspanel_us_code/boot.txt index cb1eb4b3..fad9c6d2 100644 --- a/hmi/dev/nspanel_us_code/boot.txt +++ b/hmi/dev/nspanel_us_code/boot.txt @@ -60,7 +60,7 @@ Variable (string) version Attributes ID : 6 Scope : global - Text : 4 + Text : 5 Max. Text Size: 7 Variable (int32) log_len diff --git a/hmi/dev/nspanel_us_code/light.txt b/hmi/dev/nspanel_us_code/light.txt index 2e6c23c6..e759380f 100644 --- a/hmi/dev/nspanel_us_code/light.txt +++ b/hmi/dev/nspanel_us_code/light.txt @@ -684,8 +684,8 @@ Slider tempslider Back. Picture ID : 21 Slided Back. Picture ID: 21 Position : 0 - Upper range limit : 6535 - Lower range limit : 2000 + Upper range limit : 2000 + Lower range limit : 6535 Events Touch Release Event diff --git a/hmi/dev/nspanel_us_land_code/boot.txt b/hmi/dev/nspanel_us_land_code/boot.txt index e552c587..a2dd5e13 100644 --- a/hmi/dev/nspanel_us_land_code/boot.txt +++ b/hmi/dev/nspanel_us_land_code/boot.txt @@ -60,7 +60,7 @@ Variable (string) version Attributes ID : 6 Scope : global - Text : 4 + Text : 5 Max. Text Size: 7 Variable (int32) log_len diff --git a/hmi/dev/nspanel_us_land_code/light.txt b/hmi/dev/nspanel_us_land_code/light.txt index ee00bccb..e4b36b43 100644 --- a/hmi/dev/nspanel_us_land_code/light.txt +++ b/hmi/dev/nspanel_us_land_code/light.txt @@ -684,8 +684,8 @@ Slider tempslider Back. Picture ID : 21 Slided Back. Picture ID: 21 Position : 0 - Upper range limit : 6535 - Lower range limit : 2000 + Upper range limit : 2000 + Lower range limit : 6535 Events Touch Release Event diff --git a/hmi/nspanel_CJK_eu.HMI b/hmi/nspanel_CJK_eu.HMI index af2f04f3..752c9cd2 100644 Binary files a/hmi/nspanel_CJK_eu.HMI and b/hmi/nspanel_CJK_eu.HMI differ diff --git a/hmi/nspanel_CJK_eu.tft b/hmi/nspanel_CJK_eu.tft index a0a4daeb..442761a7 100644 Binary files a/hmi/nspanel_CJK_eu.tft and b/hmi/nspanel_CJK_eu.tft differ diff --git a/hmi/nspanel_CJK_us.HMI b/hmi/nspanel_CJK_us.HMI index 7f95d515..585651cd 100644 Binary files a/hmi/nspanel_CJK_us.HMI and b/hmi/nspanel_CJK_us.HMI differ diff --git a/hmi/nspanel_CJK_us.tft b/hmi/nspanel_CJK_us.tft index e1be0c77..62a0a45f 100644 Binary files a/hmi/nspanel_CJK_us.tft and b/hmi/nspanel_CJK_us.tft differ diff --git a/hmi/nspanel_CJK_us_land.HMI b/hmi/nspanel_CJK_us_land.HMI index d1eb30e1..80a42d0e 100644 Binary files a/hmi/nspanel_CJK_us_land.HMI and b/hmi/nspanel_CJK_us_land.HMI differ diff --git a/hmi/nspanel_CJK_us_land.tft b/hmi/nspanel_CJK_us_land.tft index 59946615..e2544e10 100644 Binary files a/hmi/nspanel_CJK_us_land.tft and b/hmi/nspanel_CJK_us_land.tft differ diff --git a/hmi/nspanel_eu.HMI b/hmi/nspanel_eu.HMI index b991043e..ed91a49d 100644 Binary files a/hmi/nspanel_eu.HMI and b/hmi/nspanel_eu.HMI differ diff --git a/hmi/nspanel_eu.tft b/hmi/nspanel_eu.tft index 640bcaba..82e808fe 100644 Binary files a/hmi/nspanel_eu.tft and b/hmi/nspanel_eu.tft differ diff --git a/hmi/nspanel_us.HMI b/hmi/nspanel_us.HMI index 02ff8ea7..a47cf31c 100644 Binary files a/hmi/nspanel_us.HMI and b/hmi/nspanel_us.HMI differ diff --git a/hmi/nspanel_us.tft b/hmi/nspanel_us.tft index f3522220..f040b220 100644 Binary files a/hmi/nspanel_us.tft and b/hmi/nspanel_us.tft differ diff --git a/hmi/nspanel_us_land.HMI b/hmi/nspanel_us_land.HMI index 2dfa2f48..201e5a12 100644 Binary files a/hmi/nspanel_us_land.HMI and b/hmi/nspanel_us_land.HMI differ diff --git a/hmi/nspanel_us_land.tft b/hmi/nspanel_us_land.tft index fee7b26c..282facba 100644 Binary files a/hmi/nspanel_us_land.tft and b/hmi/nspanel_us_land.tft differ diff --git a/nspanel_easy_blueprint.yaml b/nspanel_easy_blueprint.yaml index aa3bcdd5..8a75b162 100644 --- a/nspanel_easy_blueprint.yaml +++ b/nspanel_easy_blueprint.yaml @@ -11,7 +11,7 @@ blueprint: description: > # NSPanel Easy Configuration via Blueprint - **Blueprint release**: 4 + **Blueprint release**: 5 This project enables comprehensive configuration of your NSPanel through a Blueprint featuring a user interface. @@ -19,7 +19,7 @@ blueprint: source_url: https://github.com/edwardtfn/NSPanel-Easy/blob/main/nspanel_easy_blueprint.yaml domain: automation homeassistant: - min_version: 2025.12.0 + min_version: 2026.1.0 input: nspanel_name: # This key was kept with this name to support inputs from legacy versions where the panel name was used @@ -735,12 +735,25 @@ blueprint: multiple: *selector_entity_single_multiple filter: domain: climate - climate_chip_always_visible: - name: Main Climate - Always Show Chip - description: "Keep the climate chip visible on the interface, even when the climate entity is idle or turned off." - default: false + climate_chip_visibility: + name: Main Climate - Chip Visibility + description: >- + Controls when the climate chip is shown on the home screen. + "Active only" shows the chip only when the climate is actively + heating, cooling, drying, or running the fan. + "Always" keeps the chip visible whenever a climate entity is + configured, even when idle or off. + "Never" hides the chip entirely, regardless of the climate state. + default: active_only selector: - boolean: + select: + options: + - label: "Active only" + value: active_only + - label: "Always" + value: always + - label: "Never" + value: never climate_page_settings: name: Climate page (optional) icon: mdi:thermostat-cog @@ -4010,7 +4023,7 @@ trigger_variables: }} variables: - blueprint_version: 4 + blueprint_version: 5 pages: current: '{{ states(currentpage) }}' home: "home" @@ -8730,6 +8743,19 @@ action: - alias: Home page sequence: + - alias: climate_chip_visibility + sequence: + - variables: + climate_chip_visibility: !input climate_chip_visibility + - *delay_boot + - action: 'esphome.{{ device_name }}_component_val' + data: + page: mem + component: climate_chip_visibility + val: >- + {%- if climate_chip_visibility == 'always' %}1 + {%- elif climate_chip_visibility == 'never' %}2 + {%- else %}0{%- endif %} - *delay_boot - alias: chip_font action: 'esphome.{{ nspanel_name }}_component_val' @@ -9763,12 +9789,13 @@ action: - condition: '{{ entity_id_valid }}' - variables: hvac_action: '{{ state_attr(entity_id, "hvac_action") }}' - climate_chip_always_visible: !input climate_chip_always_visible - climate_chip_visible: > + climate_chip_visibility: !input climate_chip_visibility + climate_chip_visible: >- {{ entity_has_value and + climate_chip_visibility != 'never' and ( - climate_chip_always_visible or + climate_chip_visibility == 'always' or entity_state in ["heating", "cooling", "drying", "fan_only"] or ( entity_state not in ["idle", "off"] and @@ -10170,14 +10197,14 @@ action: data: page: light id: temp_value - txt: '{{ curr_color_temp }}' + txt: '{{ curr_color_temp }}K' continue_on_error: true - *delay_default - action: 'esphome.{{ nspanel_name }}_component_text' data: page: light id: temp_value_2 - txt: '{{ curr_color_temp }}' + txt: '{{ curr_color_temp }}K' continue_on_error: true - *delay_default - action: 'esphome.{{ nspanel_name }}_component_val' @@ -10186,15 +10213,16 @@ action: id: tempslider val: '{{ curr_color_temp }}' continue_on_error: true + # That is right, the Kelvin scale is inverted - *delay_default - action: 'esphome.{{ nspanel_name }}_command' data: - cmd: tempslider.minval={{ min_color_temp_kelvin }} + cmd: tempslider.maxval={{ min_color_temp_kelvin }} continue_on_error: true - *delay_default - action: 'esphome.{{ nspanel_name }}_command' data: - cmd: tempslider.maxval={{ max_color_temp_kelvin }} + cmd: tempslider.minval={{ max_color_temp_kelvin }} continue_on_error: true - *delay_default - action: 'esphome.{{ nspanel_name }}_component_color'