Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions components/nspanel_easy/addon_climate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
// =============================================================================
Expand Down
81 changes: 64 additions & 17 deletions esphome/nspanel_esphome_addon_climate_base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand All @@ -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<int>(nspanel_easy::CLIMATE_CHIP_ACTIVE_ONLY) &&
val <= static_cast<int>(nspanel_easy::CLIMATE_CHIP_NEVER));
id(climate_chip_visibility) = valid
? static_cast<uint8_t>(val)
: static_cast<uint8_t>(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
Expand Down Expand Up @@ -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<nspanel_easy::ClimateChipVisibility>(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]);
Expand Down
4 changes: 2 additions & 2 deletions esphome/nspanel_esphome_version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion hmi/dev/nspanel_CJK_eu_code/boot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Variable (string) version
Attributes
ID : 6
Scope : global
Text : 4
Text : 5
Max. Text Size: 7

Variable (int32) log_len
Expand Down
4 changes: 2 additions & 2 deletions hmi/dev/nspanel_CJK_eu_code/light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion hmi/dev/nspanel_CJK_us_code/boot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Variable (string) version
Attributes
ID : 6
Scope : global
Text : 4
Text : 5
Max. Text Size: 7

Variable (int32) log_len
Expand Down
4 changes: 2 additions & 2 deletions hmi/dev/nspanel_CJK_us_code/light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion hmi/dev/nspanel_CJK_us_land_code/boot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Variable (string) version
Attributes
ID : 6
Scope : global
Text : 4
Text : 5
Max. Text Size: 7

Variable (int32) log_len
Expand Down
4 changes: 2 additions & 2 deletions hmi/dev/nspanel_CJK_us_land_code/light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion hmi/dev/nspanel_eu_code/boot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Variable (string) version
Attributes
ID : 6
Scope : global
Text : 4
Text : 5
Max. Text Size: 7

Variable (int32) log_len
Expand Down
4 changes: 2 additions & 2 deletions hmi/dev/nspanel_eu_code/light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion hmi/dev/nspanel_us_code/boot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Variable (string) version
Attributes
ID : 6
Scope : global
Text : 4
Text : 5
Max. Text Size: 7

Variable (int32) log_len
Expand Down
4 changes: 2 additions & 2 deletions hmi/dev/nspanel_us_code/light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion hmi/dev/nspanel_us_land_code/boot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Variable (string) version
Attributes
ID : 6
Scope : global
Text : 4
Text : 5
Max. Text Size: 7

Variable (int32) log_len
Expand Down
4 changes: 2 additions & 2 deletions hmi/dev/nspanel_us_land_code/light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Binary file modified hmi/nspanel_CJK_eu.HMI
Binary file not shown.
Binary file modified hmi/nspanel_CJK_eu.tft
Binary file not shown.
Binary file modified hmi/nspanel_CJK_us.HMI
Binary file not shown.
Binary file modified hmi/nspanel_CJK_us.tft
Binary file not shown.
Binary file modified hmi/nspanel_CJK_us_land.HMI
Binary file not shown.
Binary file modified hmi/nspanel_CJK_us_land.tft
Binary file not shown.
Binary file modified hmi/nspanel_eu.HMI
Binary file not shown.
Binary file modified hmi/nspanel_eu.tft
Binary file not shown.
Binary file modified hmi/nspanel_us.HMI
Binary file not shown.
Binary file modified hmi/nspanel_us.tft
Binary file not shown.
Binary file modified hmi/nspanel_us_land.HMI
Binary file not shown.
Binary file modified hmi/nspanel_us_land.tft
Binary file not shown.
58 changes: 43 additions & 15 deletions nspanel_easy_blueprint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ 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.

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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -4010,7 +4023,7 @@ trigger_variables:
}}

variables:
blueprint_version: 4
blueprint_version: 5
pages:
current: '{{ states(currentpage) }}'
home: "home"
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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'
Expand All @@ -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'
Expand Down