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
3 changes: 2 additions & 1 deletion components/nspanel_easy/pages.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ constexpr const char *const page_names[] = {
"climate", "settings", "screensaver", "light", "cover", "buttonpage01", "buttonpage02",
"buttonpage03", "buttonpage04", "notification", "qrcode", "entitypage01", "entitypage02", "entitypage03",
"entitypage04", "fan", "alarm", "keyb_num", "media_player", "confirm", "utilities",
"home_smpl", "debug", "water_heater", "theme_apply", "switch"};
"home_smpl", "debug", "water_heater", "theme_apply", "switch", "button"};

constexpr size_t PAGE_COUNT = sizeof(page_names) / sizeof(page_names[0]);
static_assert(PAGE_COUNT <= UINT8_MAX, "PAGE_COUNT exceeds uint8_t range");
Expand Down Expand Up @@ -94,6 +94,7 @@ inline uint8_t get_page_id(const esphome::StringRef &page_name) {
// Ensures no entry is accidentally removed or misspelled in page_names[].
static_assert(get_page_id("alarm") != UINT8_MAX, "Missing required page: alarm");
static_assert(get_page_id("boot") != UINT8_MAX, "Missing required page: boot");
static_assert(get_page_id("button") != UINT8_MAX, "Missing required page: button");
static_assert(get_page_id("buttonpage01") != UINT8_MAX, "Missing required page: buttonpage01");
static_assert(get_page_id("buttonpage02") != UINT8_MAX, "Missing required page: buttonpage02");
static_assert(get_page_id("buttonpage03") != UINT8_MAX, "Missing required page: buttonpage03");
Expand Down
2 changes: 2 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,12 @@ ensuring they can easily access detailed information and return to their initial
The domain is used to select the corresponding detail page.
Supported domains are:
- `alarm_control_panel`
- `button`
- `climate`
- `cover`
- `fan`
- `input_boolean`
- `input_button`
- `light`
- `media_player`
- `switch`
Expand Down
1 change: 1 addition & 0 deletions esphome/nspanel_esphome_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ api:
if (entity == "embedded_climate") entity_id.domain = "climate";
else if (entity_id.domain == "alarm_control_panel") entity_id.domain = "alarm";
else if (entity_id.domain == "input_boolean") entity_id.domain = "switch";
else if (entity_id.domain == "input_button") entity_id.domain = "button";
if (entity_id.domain != "invalid" or entity == "embedded_climate") {
detailed_entity->publish_state(entity);
delay(${DELAY_DEFAULT});
Expand Down
6 changes: 5 additions & 1 deletion esphome/nspanel_esphome_hw_display.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,10 @@ script:
{"component", params[2].c_str()}
});
ESP_LOGV("${TAG_HW_DISPLAY}", "Event sent");
} else if (page != "home" and page != "light" and page != "switch") {
} else if (page != "button" and
page != "home" and
page != "light" and
page != "switch") {
// Generic event
ESP_LOGD("${TAG_HW_DISPLAY}", "Send generic event to Home Assistant");
fire_ha_event("button_click", {
Expand Down Expand Up @@ -300,6 +303,7 @@ script:
// Reset globals
ESP_LOGV("${TAG_HW_DISPLAY}", "Reset globals");
if (new_page_id != get_page_id("alarm") &&
new_page_id != get_page_id("button") &&
new_page_id != get_page_id("climate") &&
new_page_id != get_page_id("cover") &&
new_page_id != get_page_id("fan") &&
Expand Down
81 changes: 81 additions & 0 deletions esphome/nspanel_esphome_page_button.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#####################################################################################################
##### NSPanel Easy - https://github.com/edwardtfn/NSPanel-Easy #####
#####################################################################################################
##### ESPHOME Page button #####
##### PLEASE only make changes if it is necessary and also the required knowledge is available. #####
##### For normal use with the Blueprint, no changes are necessary. #####
#####################################################################################################
---
substitutions:
PAGE_BUTTON_ID: 33
page_button_color_idle: 16904
page_button_color_pressed: 15483
page_button_color_unavail: 10565
page_button_color_ring: 21162
TAG_PAGE_BUTTON: nspanel.page.button

esphome:
platformio_options:
build_flags:
- -D NSPANEL_EASY_PAGE_BUTTON

script:
- id: !extend event_from_display # Defined by hw_display
then:
- lambda: |-
if (params_count == 0 || params[0] != "button") return;

// CSV Format: button,<action>
// params[0]=page, params[1]=action (action to perform)
if (params_count != 2) {
ESP_LOGW("${TAG_PAGE_BUTTON}", "Bad params");
return;
}

if (detailed_entity == nullptr or detailed_entity->state.empty()) {
ESP_LOGW("${TAG_PAGE_BUTTON}", "No detailed entity");
return;
}

const std::string& action = params[1];
ESP_LOGV("${TAG_PAGE_BUTTON}", "Button action: %s", action.c_str());
if (action != "press") {
ESP_LOGW("${TAG_PAGE_BUTTON}", "Unsupported action: %s", action.c_str());
return;
}

const HomeAssistantEntity entity = extractHomeAssistantEntity(detailed_entity->state);
if (entity.domain == "invalid") {
ESP_LOGW("${TAG_PAGE_BUTTON}", "Invalid entity: %s", detailed_entity->state.c_str());
return;
}
if (entity.domain != "button" && entity.domain != "input_button") {
ESP_LOGW("${TAG_PAGE_BUTTON}", "Unsupported entity domain for button page: %s", entity.domain.c_str());
return;
}

const std::string service = entity.domain + "." + action;
fire_ha_event("action_call", {
{"action", service.c_str()},
{"entity", detailed_entity->state.c_str()}
});

- id: !extend page_change
then:
- lambda: |-
if (new_page_id == get_page_id("button"))
page_button->execute();

- id: page_button
mode: single
then:
- lambda: |-
disp1->set_component_value("color_idle", ${page_button_color_idle});
disp1->set_component_value("color_pressed", ${page_button_color_pressed});
disp1->set_component_value("color_unavail", ${page_button_color_unavail});
disp1->set_component_value("color_ring", ${page_button_color_ring});

- id: !extend stop_page_constructors
then:
- lambda: page_button->stop();
...
1 change: 1 addition & 0 deletions esphome/nspanel_esphome_standard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ packages:
hw_relays: !include nspanel_esphome_hw_relays.yaml
hw_temperature: !include nspanel_esphome_hw_temperature.yaml
page_alarm: !include nspanel_esphome_page_alarm.yaml
page_button: !include nspanel_esphome_page_button.yaml
page_buttons: !include nspanel_esphome_page_buttons.yaml
page_climate: !include nspanel_esphome_page_climate.yaml
page_confirm: !include nspanel_esphome_page_confirm.yaml
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: 11
min_tft_version: 12
min_blueprint_version: 12
min_tft_version: 13
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 : 12
Text : 13
Max. Text Size: 3

Variable (int32) log_len
Expand Down
Loading
Loading