Files
NSPanel_HA_Blueprint/nspanel_esphome.yaml
Edward Firmo 81d16343a7 Media Player control
You will be able to add a Media Player entity to any of the buttons pages and with a long press you will see the media player page.
2023-09-12 20:06:58 +02:00

2347 lines
101 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#####################################################################################################
##### NSPANEL ESPHOME created by Blackymas - https://github.com/Blackymas/NSPanel_HA_Blueprint #####
##### ADVANCED CONFIG + FULL ESPHOME CODE! #####
##### 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:
##### DON'T CHANGE THIS #####
version: "4.0"
#############################
##### WIFI SETUP #####
wifi:
networks:
- id: wifi_default
ssid: ${wifi_ssid}
password: ${wifi_password}
power_save_mode: none
ap:
ssid: "${device_name}"
password: ${wifi_password}
##### ESPHOME CONFIGURATION #####
esphome:
name: ${device_name}
min_version: 2023.5.0
##### TYPE OF ESP BOARD #####
esp32:
board: esp32dev
captive_portal:
web_server:
id: web_server_std
port: 80
auth:
username: admin
password: ${wifi_password}
##### OTA PASSWORD #####
ota:
id: ota_std
password: ${wifi_password}
safe_mode: true
reboot_timeout: 3min
num_attempts: 3
##### LOGGER #####
logger:
id: logger_std
##### ENABLE RINGTONE MUSIC SUPPORT #####
rtttl:
id: buzzer
output: buzzer_out
##### CONFIGURE INTERNAL BUZZER #####
output:
##### BUZZER FOR PLAYING RINGTONES #####
- platform: ledc
id: buzzer_out
pin:
number: 21
##### UART FOR NEXTION DISPLAY #####
uart:
id: tf_uart
tx_pin: 16
rx_pin: 17
baud_rate: 115200
##### Keeps time display updated #####
time:
- id: time_provider
platform: homeassistant
on_time:
- seconds: 0
then:
- script.execute:
id: refresh_datetime
on_time_sync:
then:
- component.update: api_timestamp
- component.update: device_timestamp
- logger.log: "System clock synchronized"
- script.execute:
id: refresh_datetime
##### START - BUTTON CONFIGURATION #####
button:
###### REBOOT BUTTON #####
- name: ${device_name} Restart
platform: restart
id: restart_nspanel
##### UPDATE TFT DISPLAY #####
- name: ${device_name} Update TFT display
platform: template
icon: mdi:file-sync
id: tft_update
entity_category: config
on_press:
- logger.log: "Button pressed: Update TFT display"
- binary_sensor.template.publish:
id: nextion_init
state: false
- delay: 16ms
- lambda: id(disp1).upload_tft();
##### EXIT REPARSE TFT DISPLAY #####
- name: ${device_name} Exit reparse
platform: template
icon: mdi:file-sync
id: tft_reparse_off
entity_category: config
on_press:
- logger.log: "Button pressed: Exit reparse"
- uart.write:
id: tf_uart
data: "DRAKJHSUYDGBNCJHGJKSHBDN"
- uart.write:
id: tf_uart
data: [0xFF, 0xFF, 0xFF]
##### START - API CONFIGURATION #####
api:
id: api_server
reboot_timeout: 0s
services:
##### SERVICE TO UPDATE THE HMI FILE ##############
- service: upload_tft
then:
- logger.log: "Service: upload_tft"
- binary_sensor.template.publish:
id: nextion_init
state: false
- lambda: 'id(disp1)->upload_tft();'
##### SERVICE TO UPDATE THE TFT FILE from URL #####
- service: upload_tft_url
variables:
url: string
then:
- logger.log: "Service: upload_tft_url"
- binary_sensor.template.publish:
id: nextion_init
state: false
- lambda: 'id(disp1)->set_tft_url(url.c_str());'
- lambda: 'id(disp1)->upload_tft();'
##### Service to send a command "printf" directly to the display #####
- service: send_command_printf
variables:
cmd: string
then:
- lambda: 'id(disp1).send_command_printf("%s", cmd.c_str());'
##### Service to send a command "text_printf" directly to the display #####
- service: send_command_text_printf
variables:
component: string
message: string
then:
- lambda: 'id(disp1).set_component_text_printf(component.c_str(), "%s", message.c_str());'
##### Service to send a command "component_value (Dualstate Button)" directly to the display #####
- service: send_command_value
variables:
component: string
message: int
then:
- lambda: 'id(disp1).set_component_value(component.c_str(), message);'
##### Service to send a command "hide componente" directly to the display #####
- service: send_command_hide ### unused ###
variables:
component: string
then:
- lambda: 'id(disp1).hide_component(component.c_str());'
##### Service to send a command "show componente" directly to the display #####
- service: send_command_show ### unused ###
variables:
component: string
then:
- lambda: 'id(disp1).show_component(component.c_str());'
##### Service to send a command "show ALL componente" directly to the display #####
- service: send_command_show_all ### unused ###
then:
- lambda: id(disp1).show_component("255");
##### Service to send a command "font color" directly to the display #####
- service: set_component_color
variables:
component: string
foreground: int[]
background: int[]
then:
- lambda: id(set_component_color).execute(component, foreground, background);
##### Service to show a notification-message on the screen #####
- service: notification_show
variables:
label: string
text: string
then:
- lambda: |-
ESP_LOGV("service.notification_show", "Starting");
ESP_LOGV("service.notification_show", "label: %s", label.c_str());
ESP_LOGV("service.notification_show", "text: %s", text.c_str());
ESP_LOGV("service.notification_show", "text length: %i", text.length());
id(disp1).send_command_printf("is_notification=1");
id(disp1).send_command_printf("page notification");
id(disp1).set_component_text_printf("notification.notifi_label", "%s", label.c_str());
id(display_wrapped_text).execute("notification.notifi_text01", text.c_str(), id(display_mode) == 2 ? 23 : 32);
id(notification_label).publish_state(label.c_str());
id(notification_text).publish_state(text.c_str());
- switch.turn_on: notification_unread
- if:
condition:
- switch.is_on: notification_sound
then:
- rtttl.play: "two short:d=4,o=5,b=100:16e6,16e6"
##### Service to clear the notification #####
- service: notification_clear
then:
- logger.log: "Service: notification_clear"
- &notification_clear
lambda: |-
id(disp1).send_command_printf("is_notification=0");
id(notification_label).publish_state("");
id(notification_text).publish_state("");
- switch.turn_off: notification_unread
##### Service to open information for settings-page(s)
- service: open_entity_settings_page
variables:
page: string
page_label: string
page_icon: string
page_icon_color: int[]
entity: string
back_page: string
then:
- lambda: |-
ESP_LOGV("api.service.open_entity_settings_page", "Starting");
ESP_LOGV("api.service.open_entity_settings_page", "page: %s", page.c_str());
ESP_LOGV("api.service.open_entity_settings_page", "page_label: %s", page_label.c_str());
ESP_LOGV("api.service.open_entity_settings_page", "page_icon: %s", page_icon.c_str());
ESP_LOGV("api.service.open_entity_settings_page", "page_icon_color: %i, %i, %i", page_icon_color[0], page_icon_color[1], page_icon_color[2] );
ESP_LOGV("api.service.open_entity_settings_page", "entity: %s", entity.c_str());
ESP_LOGV("api.service.open_entity_settings_page", "back_page: %s", back_page.c_str());
std::string cmp_entity = page.c_str() + std::string(".entity");
ESP_LOGV("api.service.open_entity_settings_page", "cmp_entity: %s", cmp_entity.c_str());
id(disp1).set_component_text_printf(cmp_entity.c_str(), "%s", entity.c_str());
std::string cmd_page = std::string("page ") + page.c_str();
id(disp1).send_command_printf(cmd_page.c_str());
id(disp1).set_component_text_printf("page_label", "%s", page_label.c_str());
id(disp1).set_component_text_printf("back_page", "%s", back_page.c_str());
if ((page_icon.c_str() != std::string()) and (page_icon.c_str() != "") and (page != "climate"))
{
id(disp1).set_component_text_printf("icon_state", "%s", page_icon.c_str());
}
if (page != "climate")
{
id(set_component_color).execute("icon_state", page_icon_color, {});
//id(disp1).set_component_font_color("icon_state", page_icon_color);
}
if (page == "climate" and entity == "embedded_climate") id(addon_climate_set_climate_friendly_name).execute(page_label.c_str());
ESP_LOGV("api.service.open_entity_settings_page", "Finished");
##### Service to play a rtttl tones #####
# Example tones : https://codebender.cc/sketch:109888#RTTTL%20Songs.ino
- service: play_rtttl
variables:
song_str: string
then:
- rtttl.play:
rtttl: !lambda 'return song_str;'
# Service to show a QR code on the display (ex. for WiFi password)
- service: qrcode
variables:
title: string
qrcode: string
show: bool
then:
- lambda: |-
id(disp1).set_component_text_printf("qrcode.qrcode_label", "%s", title.c_str());
id(disp1).set_component_text_printf("qrcode.qrcode_value", "%s", qrcode.c_str());
if (show) id(disp1).send_command_printf("page qrcode");
#### Service to set climate state ####
- service: set_climate
variables:
current_temp: float
target_temp: float
temp_step: int
total_steps: int
temp_offset: int
climate_icon: string
embedded_climate: bool
then:
- lambda: |-
ESP_LOGV("api.service.set_climate", "climateslider.maxval=%i", total_steps);
ESP_LOGV("api.service.set_climate", "temp_offset=%f", temp_offset);
ESP_LOGV("api.service.set_climate", "temp_step=%f", temp_step);
ESP_LOGV("api.service.set_climate", "current_temp=%f", current_temp);
ESP_LOGV("api.service.set_climate", "target_temp=%f", target_temp);
ESP_LOGV("api.service.set_climate", "target_icon=%s", climate_icon.c_str());
ESP_LOGV("api.service.set_climate", "embedded=%i", (embedded_climate) ? 1 : 0);
- script.execute:
id: set_climate
current_temp: !lambda "return current_temp;"
target_temp: !lambda "return target_temp;"
temp_step: !lambda "return temp_step;"
total_steps: !lambda "return total_steps;"
temp_offset: !lambda "return temp_offset;"
climate_icon: !lambda "return climate_icon;"
embedded_climate: !lambda "return embedded_climate;"
#### Service to set the buttons ####
- service: set_button
variables:
btn_id: string
btn_pic: int
btn_bg: int[]
btn_icon_font: int[]
btn_txt_font: int[]
btn_bri_font: int[]
btn_icon: string
btn_label: string
btn_bri_txt: string
btn_confirm: bool
#entity: string
then:
- lambda: |-
// ESP_LOGV("nextion", "set button %s", btn_id.c_str());
std::string btnicon = btn_id.c_str() + std::string("icon");
std::string btntext = btn_id.c_str() + std::string("text");
std::string btnbri = btn_id.c_str() + std::string("bri");
std::string btnconf = btn_id.c_str() + std::string("conf");
//std::string btnentity = btn_id.c_str() + std::string("entity");
id(disp1).send_command_printf("%spic.pic=%i", btn_id.c_str(), btn_pic);
id(set_component_color).execute(btnicon.c_str(), btn_icon_font, btn_bg);
id(set_component_color).execute(btntext.c_str(), btn_txt_font, btn_bg);
id(set_component_color).execute(btnbri.c_str(), btn_bri_font, btn_bg);
id(disp1).set_component_text_printf(btnicon.c_str(), "%s", btn_icon.c_str());
id(display_wrapped_text).execute(btntext.c_str(), btn_label.c_str(), 10);
if (strcmp(btn_bri_txt.c_str(), "0") != 0)
id(disp1).set_component_text_printf(btnbri.c_str(), "%s", btn_bri_txt.c_str());
else
id(disp1).set_component_text_printf(btnbri.c_str(), " ");
id(disp1).set_component_value(btnconf.c_str(), (btn_confirm) ? 1 : 0);
//id(disp1).set_component_text_printf(btnentity.c_str(), "%s", entity.c_str());
##### SERVICE TO WAKE UP THE DISPLAY #####
- service: wake_up
variables:
reset_timer: bool
then:
- lambda: |-
if (id(current_page).state == "home")
{
id(disp1).send_command_printf("home.dimtimer.en=1");
id(disp1).send_command_printf("home.sleeptimer.en=1");
}
else if (id(current_page).state == "screensaver") id(disp1).send_command_printf("page %s", id(wakeup_page_name).state.c_str());
id(disp1).send_command_printf("dim=brightness");
if (reset_timer) id(page_timer)->execute();
#### Service to set the entities ####
- service: set_entity
variables:
ent_id: string
ent_icon: string
ent_label: string
ent_value: string
ent_value_xcen: string
then:
- lambda: |-
ESP_LOGV("service.set_entity", "entity: %s", ent_id.c_str());
std::string enticon = ent_id.c_str() + std::string("_pic");
std::string entlabel = ent_id.c_str() + std::string("_label");
std::string entxcen = ent_id.c_str() + std::string(".xcen=") + ent_value_xcen.c_str();
id(disp1).set_component_text_printf(enticon.c_str(), "%s", ent_icon.c_str());
if (strcmp(ent_icon.c_str(), "0") != 0) id(disp1).set_component_text_printf(enticon.c_str(), "%s", ent_icon.c_str());
id(disp1).set_component_text_printf(entlabel.c_str(), "%s", ent_label.c_str());
//id(display_wrapped_text).execute(entlabel.c_str(), ent_label.c_str(), id(display_mode) == 2 ? 16 : 20);
id(disp1).set_component_text_printf(ent_id.c_str(), "%s", ent_value.c_str());
if (strcmp(ent_value_xcen.c_str(), "0") != 0) id(disp1).send_command_printf("%s", entxcen.c_str());
##### Service for transferring global settings from the blueprint to ESPHome #####
- service: global_settings
variables:
blueprint_version: string
relay1_local_control: bool
relay1_icon: string
relay1_icon_color: int
relay2_local_control: bool
relay2_icon: string
relay2_icon_color: int
date_color: int
time_format: string
time_color: int
embedded_climate: bool
embedded_indoor_temperature: bool
temperature_unit_is_fahrenheit: bool
mui_please_confirm: string
then:
- lambda: |-
// Logs - Begin
ESP_LOGV("service.global_settings", "Starting");
ESP_LOGD("service.global_settings", "Blueprint version: %s", blueprint_version.c_str());
ESP_LOGV("service.global_settings", "relay1_local_control: %i", (relay1_local_control) ? 1 : 0);
ESP_LOGV("service.global_settings", "relay1_icon: %s", relay1_icon.c_str());
ESP_LOGV("service.global_settings", "relay1_icon_color: %i", relay1_icon_color);
ESP_LOGV("service.global_settings", "relay2_local_control: %i", (relay2_local_control) ? 1 : 0);
ESP_LOGV("service.global_settings", "relay2_icon: %s", relay2_icon.c_str());
ESP_LOGV("service.global_settings", "relay2_icon_color: %i", relay2_icon_color);
ESP_LOGV("service.global_settings", "date_color: %i", date_color);
ESP_LOGV("service.global_settings", "time_format: %s", time_format.c_str());
ESP_LOGV("service.global_settings", "time_color: %i", time_color);
ESP_LOGV("service.global_settings", "embedded_climate: %i", (embedded_climate) ? 1 : 0);
ESP_LOGV("service.global_settings", "embedded_indoor_temperature: %i", (embedded_indoor_temperature) ? 1 : 0);
ESP_LOGV("service.global_settings", "temperature_unit_is_fahrenheit: %i", (temperature_unit_is_fahrenheit) ? 1 : 0);
ESP_LOGV("service.global_settings", "mui_please_confirm: %s", mui_please_confirm.c_str());
// Blueprint version
id(version_blueprint) = blueprint_version;
id(check_versions).execute();
// Relays
id(relay1_local).publish_state(relay1_local_control);
id(relay2_local).publish_state(relay2_local_control);
id(home_relay1_icon) = relay1_icon.c_str();
id(home_relay2_icon) = relay2_icon.c_str();
id(home_relay1_icon_color) = relay1_icon_color;
id(home_relay2_icon_color) = relay2_icon_color;
// Localization
id(mui_time_format) = time_format;
// Date/Time colors
id(home_date_color) = date_color;
id(home_time_color) = time_color;
// Embedded thermostat
id(is_embedded_thermostat) = embedded_climate;
// Indoor temperature
id(embedded_indoor_temp) = embedded_indoor_temperature;
id(temp_unit_fahrenheit) = temperature_unit_is_fahrenheit;
id(display_embedded_temp)->execute();
// Confirm page
ESP_LOGV("service.global_settings", "Confirm page - Start");
id(display_wrapped_text).execute("confirm.title", mui_please_confirm.c_str(), 15);
// Refresh colors of global components
ESP_LOGV("service.global_settings", "Refresh colors of global components");
id(disp1).set_component_font_color("home.date", id(home_date_color));
id(disp1).set_component_font_color("home.time", id(home_time_color));
id(disp1).set_component_font_color("home.icon_top_01", id(home_relay1_icon_color));
id(disp1).set_component_font_color("home.icon_top_02", id(home_relay2_icon_color));
// Update home page
ESP_LOGV("service.global_settings", "Update home page");
id(update_page_home).execute();
- if:
condition:
- text_sensor.state: # Is boot page visible?
id: current_page
state: 'boot'
then:
- lambda: |-
ESP_LOGV("service.global_settings", "Boot page is visible");
id(disp1).set_component_text_printf("boot.bluep_version", "%s", blueprint_version.c_str());
ESP_LOGV("service.global_settings", "Wait a bit");
- wait_until:
condition:
- not:
- text_sensor.state: # Is boot page visible?
id: current_page
state: 'boot'
timeout: 2s
- if:
condition:
- text_sensor.state: # Avoid this being called twice by multiple boot triggers
id: current_page
state: 'boot'
then:
- if:
condition:
switch.is_on: notification_sound
then:
- lambda: ESP_LOGV("service.global_settings", "Play boot sound");
- rtttl.play:
rtttl: 'two short:d=4,o=5,b=100:16e6,16e6'
- lambda: |-
ESP_LOGV("service.global_settings", "Jump to wake-up page: %s", id(wakeup_page_name).state.c_str());
id(disp1).send_command_printf("page %s", id(wakeup_page_name).state.c_str());
- lambda: ESP_LOGV("service.global_settings", "Finished");
#### Service to populate the page Home #####
- service: page_home
variables:
notification_icon: string
notification_icon_color_normal: int[]
notification_icon_color_unread: int[]
qrcode: bool
qrcode_icon: string
qrcode_icon_color: int[]
entities_pages: bool
entities_pages_icon: string
entities_pages_icon_color: int[]
alarm_state: string
then:
- lambda: |-
// Logs - Begin
ESP_LOGV("service.page_home_settings", "Starting");
ESP_LOGV("service.page_home_settings", "notification_icon: %s", notification_icon.c_str());
ESP_LOGV("service.page_home_settings", "qrcode: %i", (qrcode) ? 1 : 0);
ESP_LOGV("service.page_home_settings", "qrcode_icon: %s", qrcode_icon.c_str());
ESP_LOGV("service.page_home_settings", "entities_pages: %i", (entities_pages) ? 1 : 0);
ESP_LOGV("service.page_home_settings", "entities_pages_icon: %s", entities_pages_icon.c_str());
ESP_LOGV("service.page_home_settings", "alarm_state: %s", alarm_state.c_str());
// Notification button
ESP_LOGV("service.page_home_settings", "Notification button - Start");
id(disp1).send_command_printf("is_notification=%i", (id(notification_text).state.empty() and id(notification_label).state.empty()) ? 0 : 1);
id(disp1).set_component_text_printf("home.bt_notific", "%s", notification_icon.c_str());
id(set_component_color).execute("home.bt_notific", id(notification_unread).state ? notification_icon_color_unread : notification_icon_color_normal, {});
id(home_notify_icon_color_normal) = notification_icon_color_normal;
id(home_notify_icon_color_unread) = notification_icon_color_unread;
// QRCode button
ESP_LOGV("service.page_home_settings", "QRcode button - Start");
id(disp1).send_command_printf("is_qrcode=%i", (qrcode) ? 1 : 0);
id(disp1).set_component_text_printf("home.bt_qrcode", "%s", qrcode_icon.c_str());
id(set_component_color).execute("home.bt_qrcode", qrcode_icon_color, {});
// Entities pages button
ESP_LOGV("service.page_home_settings", "Entities pages button - Start");
id(disp1).send_command_printf("is_entities=%i", (entities_pages) ? 1 : 0);
id(disp1).set_component_text_printf("home.bt_entities", "%s", entities_pages_icon.c_str());
id(set_component_color).execute("home.bt_entities", entities_pages_icon_color, {});
// Alarm button
ESP_LOGV("service.page_home_settings", "Alarm button - Start");
id(disp1).send_command_printf("is_alarm=%i", (alarm_state=="" or alarm_state.empty()) ? 0 : 1);
id(update_alarm_icon)->execute("home.bt_alarm", alarm_state.c_str());
// Logs - End
ESP_LOGV("service.page_home_settings", "Finished");
#### Service to populate the page Settings #####
- service: page_settings
variables:
reboot: string
sleep_mode: string
brightness: string
bright: string
dim: string
then:
- lambda: |-
ESP_LOGV("service.page_settings", "Starting");
ESP_LOGV("service.page_settings", "reboot: %s", reboot.c_str());
ESP_LOGV("service.page_settings", "sleep_mode: %s", sleep_mode.c_str());
ESP_LOGV("service.page_settings", "brightness: %s", brightness.c_str());
ESP_LOGV("service.page_settings", "bright: %s", bright.c_str());
ESP_LOGV("service.page_settings", "dim: %s", dim.c_str());
if (not reboot.empty()) id(disp1).set_component_text_printf("settings.lbl_reboot", " %s", reboot.c_str());
if (not sleep_mode.empty()) id(disp1).set_component_text_printf("settings.lbl_sleep", " %s", sleep_mode.c_str());
id(display_wrapped_text).execute("settings.lbl_brightness", brightness.c_str(), id(display_mode) == 2 ? 25 : 10);
id(display_wrapped_text).execute("settings.lbl_bright", bright.c_str(), id(display_mode) == 2 ? 25 : 10);
id(display_wrapped_text).execute("settings.lbl_dim", dim.c_str(), id(display_mode) == 2 ? 25 : 10);
#### Service to populate the alarm settings page #####
- service: alarm_settings
variables:
page_title: string
state: string
supported_features: int
code_format: string
code_arm_required: bool
entity: string
mui_alarm: string[] #std::vector<std::string> #std::map
then:
- lambda: |-
// Logs - Begin
ESP_LOGV("service.alarm_settings", "Starting");
ESP_LOGV("service.alarm_settings", "page_title: %s", page_title.c_str());
ESP_LOGV("service.alarm_settings", "state: %s", state.c_str());
ESP_LOGV("service.alarm_settings", "supported_features: %i", supported_features);
ESP_LOGV("service.alarm_settings", "code_format: %s", code_format.c_str());
ESP_LOGV("service.alarm_settings", "code_arm_required: %i", (code_arm_required) ? 1 : 0);
ESP_LOGV("service.alarm_settings", "entity: %s", entity.c_str());
// set alarm icon on home page
ESP_LOGV("service.alarm_settings", "Updating home page icon");
id(disp1).send_command_printf("is_alarm=%i", (state=="" or state.empty()) ? 0 : 1);
id(update_alarm_icon)->execute("home.bt_alarm", state.c_str());
// Is page Alarm visible?
if (id(current_page).state=="alarm")
{ // Update alarm page
ESP_LOGV("service.alarm_settings", "Updating alarm page");
// Alarm page - Header
id(update_alarm_icon)->execute("icon_state", state.c_str());
id(disp1).set_component_text_printf("page_label", "%s", page_title.c_str());
id(disp1).set_component_text_printf("code_format", "%s", code_format.c_str());
if (code_arm_required) id(disp1).set_component_text_printf("code_arm_req", "1"); else id(disp1).set_component_text_printf("code_arm_req", "0");
id(disp1).set_component_text_printf("entity", "%s", entity.c_str());
// Alarm page - Button's icons
id(disp1).set_component_text_printf("bt_home_icon", "\uE689"); //mdi:shield-home
id(disp1).set_component_text_printf("bt_away_icon", "\uE99C"); //mdi:shield-lock
id(disp1).set_component_text_printf("bt_night_icon", "\uF827"); //mdi:shield-moon
id(disp1).set_component_text_printf("bt_vacat_icon", "\uE6BA"); //mdi:shield-airplane
id(disp1).set_component_text_printf("bt_bypass_icon", "\uE77F"); //mdi:shield-half-full
id(disp1).set_component_text_printf("bt_disarm_icon", "\uE99D"); //mdi:shield-off
// Alarm page - Button's text
id(display_wrapped_text).execute("bt_home_text", mui_alarm[0].c_str(), 10);
id(display_wrapped_text).execute("bt_away_text", mui_alarm[1].c_str(), 10);
id(display_wrapped_text).execute("bt_night_text", mui_alarm[2].c_str(), 10);
id(display_wrapped_text).execute("bt_vacat_text", mui_alarm[3].c_str(), 10);
id(display_wrapped_text).execute("bt_bypass_text", mui_alarm[4].c_str(), 10);
id(display_wrapped_text).execute("bt_disarm_text", mui_alarm[5].c_str(), 10);
// Alarm page - Buttons
if (supported_features & 1) // Alarm - Button - Home
{
id(disp1).send_command_printf("bt_home_pic.pic=%i", (state=="armed_home") ? 43 : 42);
id(disp1).set_component_background_color("bt_home_text", (state=="armed_home") ? 19818 : 52857);
id(disp1).set_component_background_color("bt_home_icon", (state=="armed_home") ? 19818 : 52857);
id(disp1).set_component_font_color("bt_home_text", (state=="armed_home") ? 65535 : 0);
id(disp1).set_component_font_color("bt_home_icon", (state=="armed_home") ? 65535 : 0);
if (state=="armed_home") id(disp1).hide_component("bt_home"); else id(disp1).show_component("bt_home");
}
if (supported_features & 2) // Alarm - Button - Away
{
id(disp1).send_command_printf("bt_away_pic.pic=%i", (state=="armed_away") ? 43 : 42);
id(disp1).set_component_background_color("bt_away_text", (state=="armed_away") ? 19818 : 52857);
id(disp1).set_component_background_color("bt_away_icon", (state=="armed_away") ? 19818 : 52857);
id(disp1).set_component_font_color("bt_away_text", (state=="armed_away") ? 65535 : 0);
id(disp1).set_component_font_color("bt_away_icon", (state=="armed_away") ? 65535 : 0);
if (state=="armed_away") id(disp1).hide_component("bt_away"); else id(disp1).show_component("bt_away");
}
if (supported_features & 4) // Alarm - Button - Night
{
id(disp1).send_command_printf("bt_night_pic.pic=%i", (state=="armed_night") ? 43 : 42);
id(disp1).set_component_background_color("bt_night_text", (state=="armed_night") ? 19818 : 52857);
id(disp1).set_component_background_color("bt_night_icon", (state=="armed_night") ? 19818 : 52857);
id(disp1).set_component_font_color("bt_night_text", (state=="armed_night") ? 65535 : 0);
id(disp1).set_component_font_color("bt_night_icon", (state=="armed_night") ? 65535 : 0);
if (state=="armed_night") id(disp1).hide_component("bt_night"); else id(disp1).show_component("bt_night");
}
if (supported_features & 32) // Alarm - Button - Vacation
{
id(disp1).send_command_printf("bt_vacat_pic.pic=%i", (state=="armed_vacation") ? 43 : 42);
id(disp1).set_component_background_color("bt_vacat_text", (state=="armed_vacation") ? 19818 : 52857);
id(disp1).set_component_background_color("bt_vacat_icon", (state=="armed_vacation") ? 19818 : 52857);
id(disp1).set_component_font_color("bt_vacat_text", (state=="armed_vacation") ? 65535 : 0);
id(disp1).set_component_font_color("bt_vacat_icon", (state=="armed_vacation") ? 65535 : 0);
if (state=="armed_vacation") id(disp1).hide_component("bt_vacat"); else id(disp1).show_component("bt_vacat");
}
if (supported_features & 16) // Alarm - Button - Custom bypass
{
id(disp1).send_command_printf("bt_bypass_pic.pic=%i", (state=="armed_bypass") ? 43 : 42);
id(disp1).set_component_background_color("bt_bypass_text", (state=="armed_bypass") ? 19818 : 52857);
id(disp1).set_component_background_color("bt_bypass_icon", (state=="armed_bypass") ? 19818 : 52857);
id(disp1).set_component_font_color("bt_bypass_text", (state=="armed_bypass") ? 65535 : 0);
id(disp1).set_component_font_color("bt_bypass_icon", (state=="armed_bypass") ? 65535 : 0);
if (state=="armed_bypass") id(disp1).hide_component("bt_bypass"); else id(disp1).show_component("bt_bypass");
}
if ( true ) // Alarm - Button - Disarm
{
id(disp1).send_command_printf("bt_disarm_pic.pic=%i", (state=="disarmed") ? 43 : 42);
id(disp1).set_component_background_color("bt_disarm_text", (state=="disarmed") ? 19818 : 52857);
id(disp1).set_component_background_color("bt_disarm_icon", (state=="disarmed") ? 19818 : 52857);
id(disp1).set_component_font_color("bt_disarm_text", (state=="disarmed") ? 65535 : 0);
id(disp1).set_component_font_color("bt_disarm_icon", (state=="disarmed") ? 65535 : 0);
if (state=="disarmed") id(disp1).hide_component("bt_disarm"); else id(disp1).show_component("bt_disarm");
}
}
// Logs - End
ESP_LOGV("service.alarm_settings", "Finished");
#### Service to populate the media player page #####
- service: media_player
variables:
entity: string
state: string
is_volume_muted: bool
friendly_name: string
volume_level: int
media_title: string
media_artist: string
media_duration: int
media_position: int
supported_features: int
then:
- lambda: |-
ESP_LOGV("service.media_player", "Starting");
if (id(current_page).state == "media_player")
{
id(disp1).set_component_text_printf("entity", "%s", entity.c_str());
id(disp1).set_component_text_printf("page_label", "%s", friendly_name.c_str());
id(display_wrapped_text).execute("track", media_title.c_str(), id(display_mode) == 2 ? 15 : 27);
id(display_wrapped_text).execute("artist", media_artist.c_str(), id(display_mode) == 2 ? 26 : 40);
// states:
// OFF: Entity is turned off and is not accepting commands until turned on.
// ON: Entity is turned on, but no details on its state is currently known.
// IDLE: Entity is turned on and accepting commands, but currently not playing any media. Possibly at some idle home screen.
// PLAYING: Entity is currently playing media.
// PAUSED: Entity has an active media and is currently paused
// STANDBY: Entity is in a low power state, accepting commands.
// BUFFERING: Entity is preparing to start playback of some media
// feature:
// PAUSE: 1
// SEEK: 2
// VOLUME_SET: 4
// VOLUME_MUTE: 8
// PREVIOUS_TRACK: 16
// NEXT_TRACK: 32
// reserved: 64
// TURN_ON: 128
// TURN_OFF: 256
// PLAY_MEDIA: 512
// VOLUME_STEP: 1024
// SELECT_SOURCE: 2048
// STOP: 4096
// CLEAR_PLAYLIST: 8192
// PLAY: 16384
// SHUFFLE_SET: 32768
// SELECT_SOUND_MODE: 65536
// BROWSE_MEDIA: 131072
// REPEAT_SET: 262144
// GROUPING: 524288
// MEDIA_ANNOUNCE: 1048576
// MEDIA_ENQUEUE: 2097152
// on/off button
if (supported_features & 128 and state == "off") //TURN_ON
{
id(set_component_color).execute("bt_on_off", { 65535 }, {} );
id(disp1).show_component("bt_on_off");
}
else if (supported_features & 256 and state != "off") //TURN_OFF
{
id(set_component_color).execute("bt_on_off", { 10597 }, {} );
id(disp1).show_component("bt_on_off");
}
else id(disp1).hide_component("bt_on_off");
// play/pause button
if ((supported_features & 512 or supported_features & 16384) and state != "playing" and state != "off") //PLAY_MEDIA+PLAY
{
id(disp1).set_component_text_printf("bt_play_pause", "%s", "\uE409"); // mdi:play
id(disp1).show_component("bt_play_pause");
}
else if (supported_features & 1 and state == "playing" ) //PAUSE
{
id(disp1).set_component_text_printf("bt_play_pause", "%s", "\uE3E3"); // mdi:pause
id(disp1).show_component("bt_play_pause");
}
else id(disp1).hide_component("bt_play_pause");
// bt_prev button - PREVIOUS_TRACK
if (supported_features & 16 and state != "off") id(disp1).show_component("bt_prev"); else id(disp1).hide_component("bt_prev");
// bt_next button - NEXT_TRACK
if (supported_features & 32 and state != "off") id(disp1).show_component("bt_next"); else id(disp1).hide_component("bt_next");
// Stop button - STOP
if (supported_features & 4096 and (state == "playing" or state == "paused")) id(disp1).show_component("bt_stop"); else id(disp1).hide_component("bt_stop");
// mute/unmute button - VOLUME_MUTE
id(disp1).set_component_value("is_muted", (is_volume_muted) ? 1 : 0);
if (supported_features & 8 and is_volume_muted) // unmute
{
id(disp1).set_component_text_printf("bt_mute", "%s", "\uE57E"); // mdi:volume-low
id(disp1).show_component("bt_mute");
}
else if (supported_features & 8) // mute
{
id(disp1).set_component_text_printf("bt_mute", "%s", "\uEE07"); // mdi:volume-variant-off
id(disp1).show_component("bt_mute");
}
else id(disp1).hide_component("bt_mute");
// VOLUME_SET
if (supported_features & 4)
{
id(disp1).set_component_text_printf("vol_text", "%i%%", volume_level);
id(disp1).set_component_value("vol_slider", volume_level);
id(disp1).show_component("vol_slider");
id(disp1).show_component("bt_vol_down");
id(disp1).show_component("bt_vol_up");
id(disp1).show_component("vol_text");
}
else
{
id(disp1).hide_component("vol_slider");
id(disp1).hide_component("bt_vol_down");
id(disp1).hide_component("bt_vol_up");
id(disp1).hide_component("vol_text");
}
if (media_duration > 0)
{
id(disp1).set_component_text_printf("time_current", "%i", media_position);
id(disp1).set_component_text_printf("time_total", "%i", media_duration);
id(disp1).set_component_value("prg_current", media_position);
id(disp1).set_component_value("prg_total", media_duration);
id(disp1).send_command_printf("prg_timer.en=%i", (state == "playing") ? 1 : 0);
id(disp1).show_component("time_current");
id(disp1).show_component("time_total");
id(disp1).show_component("time_progress");
}
else
{
id(disp1).send_command_printf("prg_timer.en=0");
id(disp1).hide_component("time_current");
id(disp1).hide_component("time_total");
id(disp1).hide_component("time_progress");
}
}
##### START - GLOBALS CONFIGURATION #####
globals:
##### Display mode (1 = EU, 2 = US, 3 = US Landscape)
- id: display_mode
type: int
restore_value: true
initial_value: '0'
##### Entity Id of the entity displayed on the detailed pages
- id: entity_id
type: std::string
restore_value: no
initial_value: ''
##### Is embedded thermostat set as main climate entity? #####
- id: is_embedded_thermostat
type: bool
restore_value: true
initial_value: 'false'
##### Save Display Brightness for NSPanel reboot #####
- id: display_brightness_global
type: int
restore_value: true
initial_value: '100'
##### Save Display DIM Brightness for NSPanel reboot
- id: display_dim_brightness_global
type: int
restore_value: true
initial_value: '10'
##### Temperature unit #####
##### Is embedded sensor used for indoor temperature? #####
- id: embedded_indoor_temp
type: bool
restore_value: true
initial_value: 'true'
- id: temp_unit_fahrenheit
type: bool
restore_value: true
initial_value: 'false'
##### Date/time formats #####
#- id: mui_date_format
# type: std::string
# restore_value: no
# initial_value: '"%A, %d.%m"'
- id: home_date_color
type: int
restore_value: true
initial_value: '65535'
- id: mui_time_format
type: std::string
restore_value: no
initial_value: '"%H:%M"'
- id: home_time_color
type: int
restore_value: true
initial_value: '65535'
##### Relay icons #####
- id: home_relay1_icon
type: std::string
restore_value: false
initial_value: ''
- id: home_relay1_icon_color
type: int
restore_value: true
initial_value: '65535'
- id: home_relay2_icon
type: std::string
restore_value: false
initial_value: ''
- id: home_relay2_icon_color
type: int
restore_value: true
initial_value: '65535'
- id: home_notify_icon_color_normal
type: std::vector<int>
restore_value: false
#initial_value: '52857'
- id: home_notify_icon_color_unread
type: std::vector<int>
restore_value: false
#initial_value: '63488'
##### Versions #####
- id: version_blueprint
type: std::string
restore_value: false
initial_value: ''
- id: version_tft
type: std::string
restore_value: false
initial_value: ''
##### START - BINARY SENSOR CONFIGURATION #####
binary_sensor:
###### LEFT BUTTON BELOW DISPLAY TO TOGGLE RELAY#####
- name: ${device_name} Left Button
platform: gpio
id: left_button
pin:
number: 14
inverted: true
on_multi_click:
- timing: &long_click-timing
- ON for at least 0.8s
then:
- logger.log: "Left button - Long click"
- script.execute:
id: ha_button
page: !lambda return id(current_page).state;
component: "hw_bt_left"
command: "long_click"
- timing: &short_click-timing
- ON for at most 0.8s
then:
- logger.log: "Left button - Short click"
- if:
condition:
- switch.is_on: relay1_local
then:
- switch.toggle: relay_1
- script.execute: refresh_relays
- script.execute:
id: ha_button
page: !lambda return id(current_page).state;
component: "hw_bt_left"
command: "short_click"
##### RIGHT BUTTON BELOW DISPLAY TO TOGGLE RELAY #####
- name: ${device_name} Right Button
platform: gpio
id: right_button
pin:
number: 27
inverted: true
on_multi_click:
- timing: *long_click-timing
then:
- logger.log: "Right button - Long click"
- script.execute:
id: ha_button
page: !lambda return id(current_page).state;
component: "hw_bt_right"
command: "long_click"
- timing: *short_click-timing
then:
- logger.log: "Right button - Short click"
- if:
condition:
- switch.is_on: relay2_local
then:
- switch.toggle: relay_2
- script.execute: refresh_relays
- script.execute:
id: ha_button
page: !lambda return id(current_page).state;
component: "hw_bt_right"
command: "short_click"
##### Restart NSPanel Button - Setting Page #####
- name: ${device_name} Restart
platform: nextion
page_id: 7
component_id: 9
internal: true
on_click:
- button.press: restart_nspanel
##### Restart NSPanel Button - Boot Page #####
- name: ${device_name} Restart
platform: nextion
page_id: 8
component_id: 4
internal: true
on_click:
- button.press: restart_nspanel
##### Sleep mode NSPanel Button #####
- name: ${device_name} Sleep mode
platform: nextion
page_id: 7
component_id: 10
internal: true
on_click:
- logger.log: "Sleep mode - Nextion toggle"
- switch.toggle: sleep_mode
##### global variable to keep track on whether the Nextion display is ready or not.
## Delays initial info from HA to the display #####
- name: ${device_name} Nextion display
id: nextion_init
platform: template
device_class: connectivity
publish_initial_state: true
entity_category: diagnostic
icon: mdi:tablet-dashboard
##### API connection status
- name: ${device_name} Status
platform: status
id: api_status
on_state:
then:
- script.execute:
id: refresh_wifi_icon
##### START - SENSOR CONFIGURATION #####
sensor:
##### touchevent sensor, Reset the page timeout #####
- id: touchevent
platform: nextion
nextion_id: disp1
component_name: touchevent
internal: true
on_value:
then:
- lambda: |-
id(page_timer)->execute();
##### Send current brightness info to Home Assistant
- name: ${device_name} Brightness
id: brightness
platform: nextion
variable_name: dim
#update_interval: 1s
internal: false
precision: 0
##### Uptime Sensors #####
- name: ${device_name} Uptime seconds
id: uptime_sec
platform: uptime
internal: true
- name: ${device_name} API uptime
id: api_timestamp
platform: template
lambda: 'return id(time_provider).now().timestamp;'
internal: false
device_class: timestamp
entity_category: diagnostic
accuracy_decimals: 0
update_interval: never
- name: ${device_name} Device uptime
id: device_timestamp
platform: template
lambda: 'return (id(time_provider).now().timestamp - id(uptime_sec).state);'
internal: false
device_class: timestamp
entity_category: diagnostic
accuracy_decimals: 0
update_interval: never
##### WIFI Signal stregth
- name: ${device_name} RSSI
platform: wifi_signal
update_interval: 60s
on_value:
- script.execute:
id: refresh_wifi_icon
##### INTERNAL TEMPERATURE SENSOR, ADC VALUE #####
- id: ntc_source
platform: adc
pin: 38
update_interval: 60s
attenuation: 11db
##### INTERNAL TEMPERATURE SENSOR, adc reading converted to resistance (calculation)#####
- id: resistance_sensor
platform: resistance
sensor: ntc_source
configuration: DOWNSTREAM
resistor: 11.2kOhm
##### INTERNAL TEMPERATURE SENSOR, resistance to temperature (calculation) #####
- name: ${device_name} Temperature
platform: ntc
id: temp_nspanel
sensor: resistance_sensor
calibration:
b_constant: 3950
reference_temperature: 25°C
reference_resistance: 10kOhm
filters:
- lambda: return x + id(temperature_correction).state;
on_value:
then:
# Show panel's temperature if API or Wi-Fi are out
- lambda: id(display_embedded_temp)->execute();
###### Display Brightness GET VALUE FROM NSPanel SLIDER #####
- name: ${device_name} brightness Slider
platform: nextion
id: brightslider
variable_name: brightslider
internal: true
on_value:
then:
- number.set:
id: display_brightness
value: !lambda 'return int(x);'
###### Display DIM Brightness GET VALUE FROM NSPanel SLIDER #####
- name: ${device_name} dim brightness slider
platform: nextion
id: dimslider
variable_name: dimslider
internal: true
on_value:
then:
- number.set:
id: display_dim_brightness
value: !lambda 'return int(x);'
##### START - TEXT SENSOR CONFIGURATION #####
text_sensor:
##### Current page name #####
- name: ${device_name} current page
platform: template
id: current_page
internal: false
disabled_by_default: false
##### ESPhome version used to compile the app #####
- name: ${device_name} ESPhome Version
platform: version
disabled_by_default: true
- platform: wifi_info
ip_address:
name: ${device_name} IP
disabled_by_default: true
id: ip_address
ssid:
name: ${device_name} SSID
disabled_by_default: true
bssid:
name: ${device_name} BSSID
disabled_by_default: true
- name: ${device_name} Notification Label
platform: template
id: notification_label
- name: ${device_name} Notification Text
platform: template
id: notification_text
##### NSPanel event sensor, the main action sensor - push to HA #####
- name: ${device_name} NSPanel event
platform: nextion
nextion_id: disp1
id: disp1_nspanel_event
component_name: nspanelevent
internal: true
filters:
- lambda: |-
x = x.c_str();
x.shrink_to_fit();
return x;
on_value:
then:
- lambda: |-
ESP_LOGV("text_sensor.nspanelevent", "Starting");
id(page_timer)->execute();
DynamicJsonDocument doc(1024);
deserializeJson(doc, x);
std::string page = doc["page"];
std::string component = doc["component"];
std::string value = doc["value"];
std::string entity = doc["entity"];
ESP_LOGV("text_sensor.nspanelevent", "page: %s", page.c_str());
ESP_LOGV("text_sensor.nspanelevent", "component: %s", component.c_str());
ESP_LOGV("text_sensor.nspanelevent", "value: %s", value.c_str());
ESP_LOGV("text_sensor.nspanelevent", "entity: %s", entity.c_str());
auto ha_event = new esphome::api::CustomAPIDevice();
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "generic"},
{"page", page},
{"component", component},
{"value", value},
{"entity", entity}
});
if (component=="currentpage")
{
ESP_LOGD("text_sensor.nspanelevent", "New page: %s", page.c_str());
ESP_LOGV("text_sensor.nspanelevent", "Trigger HA event");
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "page_changed"},
{"page", page},
{"entity", entity}
});
ESP_LOGV("text_sensor.nspanelevent", "Call add-ons scripts for new page");
id(addon_climate_set_climate).execute(page=="climate" and entity=="embedded_climate");
ESP_LOGV("text_sensor.nspanelevent", "Publish current_page sensor");
id(current_page).publish_state(page);
ESP_LOGV("text_sensor.nspanelevent", "Construct new page");
if (page=="home")
{
ESP_LOGV("text_sensor.nspanelevent", "Construct home page");
id(update_page_home).execute();
}
else if (page=="screensaver")
{
ESP_LOGV("text_sensor.nspanelevent", "Construct screensaver page");
int wakeup_page_id = 0;
if (id(wakeup_page_name).state == "buttonpage01") wakeup_page_id = 12;
else if (id(wakeup_page_name).state == "buttonpage02") wakeup_page_id = 13;
else if (id(wakeup_page_name).state == "buttonpage03") wakeup_page_id = 14;
else if (id(wakeup_page_name).state == "buttonpage04") wakeup_page_id = 15;
else if (id(wakeup_page_name).state == "entitypage01") wakeup_page_id = 18;
else if (id(wakeup_page_name).state == "entitypage02") wakeup_page_id = 19;
else if (id(wakeup_page_name).state == "entitypage03") wakeup_page_id = 20;
else if (id(wakeup_page_name).state == "entitypage04") wakeup_page_id = 21;
else if (id(wakeup_page_name).state == "qrcode") wakeup_page_id = 17;
else if (id(wakeup_page_name).state == "alarm") wakeup_page_id = 23;
ESP_LOGV("text_sensor.nspanelevent", "Wake-up page id: %i", wakeup_page_id);
id(disp1).set_component_value("orign", wakeup_page_id);
}
else if (page=="climate")
{
ESP_LOGV("text_sensor.nspanelevent", "Construct climate page");
id(disp1).set_component_text_printf("climate.button01_icon", "%s", "\uEE8D"); //mdi:calendar-sync
id(disp1).set_component_text_printf("climate.button02_icon", "%s", "\uE069"); //mdi:autorenew
id(disp1).set_component_text_printf("climate.button03_icon", "%s", "\uE237"); //mdi:fire
id(disp1).set_component_text_printf("climate.button04_icon", "%s", "\uE716"); //mdi:snowflake
id(disp1).set_component_text_printf("climate.button05_icon", "%s", "\uE58D"); //mdi:water-percent
id(disp1).set_component_text_printf("climate.button06_icon", "%s", "\uE20F"); //mdi:fan
id(disp1).set_component_text_printf("climate.button07_icon", "%s", "\uE424"); //mdi:power
id(addon_climate_update_page_climate)->execute();
}
else if (page=="cover")
{
ESP_LOGV("text_sensor.nspanelevent", "Construct cover page");
id(disp1).set_component_text_printf("cover.cover_stop", "%s", "\uE666"); //mdi:stop-circle-outline
// In the future this will be dynamically contructed based on the device_class
id(disp1).set_component_text_printf("cover.cover_open", "%s", "\uF11D"); //mdi:window-shutter-open
id(disp1).set_component_text_printf("cover.cover_close", "%s", "\uF11B"); //mdi:window-shutter
}
else if (page=="fan")
{
ESP_LOGV("text_sensor.nspanelevent", "Construct fan page");
id(disp1).set_component_text_printf("fan.button_on", "%s", "\uE20F"); //mdi:fan
id(disp1).set_component_text_printf("fan.button_off", "%s", "\uE81C"); //mdi:fan-off
id(disp1).set_component_text_printf("fan.button_up", "%s", "\uF46D"); //mdi:fan-chevron-up
id(disp1).set_component_text_printf("fan.button_down", "%s", "\uF46C"); //mdi:fan-chevron-down
}
else if (page=="keyb_num")
{
ESP_LOGV("text_sensor.nspanelevent", "Construct keyb_num page");
id(disp1).set_component_text_printf("keyb_num.bview", "%s", "\uE207"); //mdi:eye
id(disp1).set_component_text_printf("keyb_num.bclose", "%s", "\uE158"); //mdi:close-circle
id(disp1).set_component_text_printf("keyb_num.bclear", "%s", "\uE641"); //mdi:eraser-variant
id(disp1).set_component_text_printf("keyb_num.benter", "%s", "\uE12B"); //mdi:check
}
else if (page=="weather01") id(disp1).set_component_text_printf("page_index", "%s", "\uE764\uE765\uE765\uE765\uE765"); // 1/5
else if (page=="weather02") id(disp1).set_component_text_printf("page_index", "%s", "\uE765\uE764\uE765\uE765\uE765"); // 2/5
else if (page=="weather03") id(disp1).set_component_text_printf("page_index", "%s", "\uE765\uE765\uE764\uE765\uE765"); // 3/5
else if (page=="weather04") id(disp1).set_component_text_printf("page_index", "%s", "\uE765\uE765\uE765\uE764\uE765"); // 4/5
else if (page=="weather05") id(disp1).set_component_text_printf("page_index", "%s", "\uE765\uE765\uE765\uE765\uE764"); // 5/5
else if (page=="buttonpage01" or page=="entitypage01") id(disp1).set_component_text_printf("page_index", "%s", "\uE764\uE765\uE765\uE765"); // 1/4
else if (page=="buttonpage02" or page=="entitypage02") id(disp1).set_component_text_printf("page_index", "%s", "\uE765\uE764\uE765\uE765"); // 2/4
else if (page=="buttonpage03" or page=="entitypage03") id(disp1).set_component_text_printf("page_index", "%s", "\uE765\uE765\uE764\uE765"); // 3/4
else if (page=="buttonpage04" or page=="entitypage04") id(disp1).set_component_text_printf("page_index", "%s", "\uE765\uE765\uE765\uE764"); // 4/4
else if (page=="settings") id(disp1).set_component_text_printf("bt_sleep", "%s", (id(sleep_mode).state) ? "\uEA19" : "\uEA18"); //mdi:toggle-switch-outline or mdi:toggle-switch-off-outline
else if (page=="notification")
{
id(disp1).set_component_text_printf("notification.notifi_label", "%s", id(notification_label).state.c_str());
id(display_wrapped_text).execute("notification.notifi_text01", id(notification_text).state.c_str(), id(display_mode) == 2 ? 23 : 32);
}
else if (page=="media_player")
{
ESP_LOGV("text_sensor.nspanelevent", "Construct media_player page");
id(disp1).set_component_text_printf("bt_on_off", "%s", "\uE424"); //mdi:power
id(disp1).set_component_text_printf("bt_prev", "%s", "\uE4AD"); //mdi:skip-previous
id(disp1).set_component_text_printf("bt_next", "%s", "\uE4AC"); //mdi:skip-next
id(disp1).set_component_text_printf("bt_play_pause", "%s", "\uE40D"); //mdi:play-pause
id(disp1).set_component_text_printf("bt_stop", "%s", "\uE4DA"); //mdi:stop
id(disp1).set_component_text_printf("bt_mute", "%s", "\uE75E"); //mdi:volume-mute
id(disp1).set_component_text_printf("bt_vol_down", "%s", "\uE75D"); //mdi:volume-minus
id(disp1).set_component_text_printf("bt_vol_up", "%s", "\uE75C"); //mdi:volume-plus
}
}
##### NSPanel event - Execute actions from ESPHome - NO push to HA #####
- name: ${device_name} NSPanel local event
platform: nextion
nextion_id: disp1
id: disp1_local_event
component_name: localevent
internal: true
filters:
- lambda: |-
x = x.c_str();
x.shrink_to_fit();
return x;
on_value:
then:
- lambda: |-
ESP_LOGV("text_sensor.localevent", "Starting");
id(page_timer)->execute();
DynamicJsonDocument doc(1024);
deserializeJson(doc, x);
std::string page = doc["page"];
ESP_LOGV("text_sensor.localevent", "page: %s", page.c_str());
std::string event = doc["event"];
ESP_LOGV("text_sensor.localevent", "event: %s", event.c_str());
std::string component = doc["component"];
ESP_LOGV("text_sensor.localevent", "component: %s", component.c_str());
std::string key = doc["key"];
ESP_LOGV("text_sensor.localevent", "key: %s", key.c_str());
std::string value = doc["value"];
ESP_LOGV("text_sensor.localevent", "value: %s", value.c_str());
std::string entity = doc["entity"];
ESP_LOGV("text_sensor.localevent", "entity: %s", entity.c_str());
int embedded = doc["embedded"];
ESP_LOGV("text_sensor.localevent", "embedded: %i", embedded);
std::string service = "";
// send event to Home Assistant
auto ha_event = new esphome::api::CustomAPIDevice();
if (event=="pagechanged")
{
ESP_LOGD("text_sensor.localevent", "New page: %s", page.c_str());
ESP_LOGV("text_sensor.localevent", "Trigger HA event");
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "page_changed"},
{"page", page},
{"entity", entity}
});
ESP_LOGV("text_sensor.localevent", "Call add-ons scripts for new page");
id(addon_climate_set_climate).execute(page=="climate" and id(entity_id) == "embedded_climate");
ESP_LOGV("text_sensor.localevent", "Publish current_page sensor");
id(current_page).publish_state(page);
ESP_LOGV("text_sensor.localevent", "Construct new page");
}
else if (event=="short_click" or event=="long_click") id(ha_button)->execute(page.c_str(), component.c_str(), event.c_str());
else if (page == "light" or page == "climate" or page == "notification" or page == "media_player")// Generic event
{
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "generic"},
{"page", page},
{"event", event},
{"value", value},
{"entity", entity}
});
}
// page based actions
if (page == "alarm")
{
std::string code_format = doc["code_format"];
std::string code_arm_req = doc["code_arm_req"];
std::string title = doc["mui"];
if (code_format=="number" and (key=="disarm" or code_arm_req=="1"))
{
id(disp1).send_command_printf("page keyb_num");
id(disp1).set_component_value("keyb_num.page_id", 23); //Calling from Alarm page
id(disp1).set_component_text_printf("keyb_num.domain", "%s", page.c_str());
id(disp1).set_component_text_printf("keyb_num.key", "%s", key.c_str());
id(disp1).set_component_text_printf("keyb_num.value", "%s", value.c_str());
id(disp1).set_component_text_printf("keyb_num.entity", "%s", entity.c_str());
id(disp1).set_component_text_printf("keyb_num.title", "%s", title.c_str());
}
else id(service_call_alarm_control_panel)->execute(entity.c_str(), key.c_str(), code_format.c_str(), "");
}
else if (page=="boot")
{
// Detect display mode - Need review
if (doc.containsKey("display_mode"))
{
std::string display_mode_str = doc["display_mode"];
ESP_LOGV("text_sensor.localevent", "display_mode: %s", display_mode_str.c_str());
float display_mode_float = stof(display_mode_str);
if (display_mode_float > 0) id(display_mode) = int(display_mode_float);
}
// Detect TFT version
if (doc.containsKey("version"))
{
std::string version_tmp = doc["version"];
id(version_tft) = version_tmp;
}
id(check_versions).execute();
// Detect timeout
if (event=="timeout")
{
ESP_LOGV("text_sensor.localevent", "Trigger boot timeout event");
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "boot"},
{"step", "timeout"},
{"value", value}
});
if (stof(value) >= 5)
{
ESP_LOGV("text_sensor.localevent", "Jump to wakeup page: %s", id(wakeup_page_name).state.c_str());
id(disp1).send_command_printf("page %s", id(wakeup_page_name).state.c_str());
}
}
}
else if (page == "climate") id(service_call_climate)->execute(entity.c_str(), key.c_str(), value.c_str(), (embedded==1));
else if (page == "cover")
{
if (key == "position") id(ha_call_service)->execute("cover.set_cover_position", key.c_str(), value.c_str(), entity.c_str());
else id(ha_call_service)->execute((std::string("cover.") + key.c_str()), "", "", entity.c_str());
}
else if (page == "fan")
{
if (key == "stop" or value == "0") id(ha_call_service)->execute("fan.turn_off", "", "", entity.c_str());
else id(ha_call_service)->execute("fan.turn_on", key.c_str(), value.c_str(), entity.c_str());
}
else if (page == "keyb_num")
{
std::string base_domain = doc["base_domain"];
if (base_domain == "alarm")
{
std::string code_format = doc["code_format"];
std::string pin = doc["pin"];
id(service_call_alarm_control_panel)->execute(entity.c_str(), key.c_str(), code_format.c_str(), pin.c_str());
}
else if (base_domain == "" or base_domain.empty()) base_domain = "home";
id(disp1).send_command_printf("page %s", base_domain.c_str());
}
else if (page == "light") id(ha_call_service)->execute("light.turn_on", key.c_str(), value.c_str(), entity.c_str());
else if (page == "media_player")
{
if (key == "volume_mute") id(ha_call_service)->execute("media_player.volume_mute", "is_volume_muted", value.c_str(), entity.c_str());
else if (key == "volume_set") id(ha_call_service)->execute("media_player.volume_set", "volume_level", to_string(stof(value) / 100), entity.c_str());
else if (not key.empty()) id(ha_call_service)->execute((std::string("media_player.") + key.c_str()), "", "", entity.c_str());
}
ESP_LOGV("text_sensor.localevent", "Finished");
##### START - SWITCH CONFIGURATION #####
switch:
##### Notification unread #####
- name: ${device_name} Notification unread
platform: template
id: notification_unread
entity_category: config
optimistic: true
restore_mode: ALWAYS_OFF
on_turn_on:
- lambda: id(set_component_color).execute("home.bt_notific", id(home_notify_icon_color_unread), {});
on_turn_off:
- lambda: id(set_component_color).execute("home.bt_notific", id(home_notify_icon_color_normal), {});
##### Notification sound #####
- name: ${device_name} Notification sound
platform: template
id: notification_sound
entity_category: config
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
##### PHYSICAL SWITCH 1 #####
- name: ${device_name} Relay 1
platform: gpio
id: relay_1
pin:
number: 22
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute:
id: refresh_relays
on_turn_off:
then:
- script.execute:
id: refresh_relays
##### PHYSICAL SWITCH 2 ######
- name: ${device_name} Relay 2
platform: gpio
id: relay_2
pin:
number: 19
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute:
id: refresh_relays
on_turn_off:
then:
- script.execute:
id: refresh_relays
##### DISPLAY ALWAYS ON #####
- name: ${device_name} Screen Power
platform: gpio
id: screen_power
entity_category: config
pin:
number: 4
inverted: true
restore_mode: ALWAYS_ON
internal: true
##### Switch Display Sleep mode #####
- name: ${device_name} Sleep mode
platform: template
device_class: switch
id: sleep_mode
entity_category: config
restore_mode: RESTORE_DEFAULT_OFF
optimistic: false
turn_on_action: &sleep_mode-turn_on
- lambda: |-
ESP_LOGV("switch.sleep_mode", "Turn on");
id(disp1).send_command_printf("sleep_mode=1");
id(disp1).set_component_value("settings.bt_sleep",1);
id(disp1).set_component_text_printf("settings.bt_sleep", "%s", "\uEA19");
id(sleep_mode).publish_state(true);
turn_off_action: &sleep_mode-turn_off
- lambda: |-
ESP_LOGV("switch.sleep_mode", "Turn off");
id(disp1).send_command_printf("sleep_mode=0");
id(disp1).set_component_value("settings.bt_sleep",0);
id(disp1).set_component_text_printf("settings.bt_sleep", "%s", "\uEA18");
id(sleep_mode).publish_state(false);
##### Relay Local control #####
- name: ${device_name} Relay 1 Local
platform: template
id: relay1_local
entity_category: config
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
internal: true
on_turn_on:
- logger.log: "Relay 1 Local turned On!"
on_turn_off:
- logger.log: "Relay 1 Local turned Off!"
- name: ${device_name} Relay 2 Local
platform: template
id: relay2_local
entity_category: config
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
internal: true
on_turn_on:
- logger.log: "Relay 2 Local turned On!"
on_turn_off:
- logger.log: "Relay 2 Local turned Off!"
##### START - NUMBER CONFIGURATION #####
number:
##### SCREEN BRIGHTNESS #####
- platform: template
name: ${device_name} Display Brightness
id: display_brightness
entity_category: config
unit_of_measurement: '%'
min_value: 1
max_value: 100
step: 1
restore_value: true
optimistic: true
set_action:
then:
- lambda: |-
id(display_brightness_global) = int(x);
id(disp1).send_command_printf("brightness=%i", int(x));
id(disp1).send_command_printf("settings.brightslider.val=%i", int(x));
if (id(current_page).state != "screensaver")
{
id(disp1).set_backlight_brightness(x/100);
id(disp1).send_command_printf("home.dimtimer.en=1");
}
if (id(current_page).state == "settings")
{
id(disp1).set_component_text_printf("bright_text", "%i%%", int(x));
}
##### SCREEN BRIGHTNESS DIMMED DOWN #####
- platform: template
name: ${device_name} Display Brightness Dimdown
id: display_dim_brightness
entity_category: config
unit_of_measurement: '%'
min_value: 1
max_value: 100
step: 1
restore_value: true
optimistic: true
set_action:
then:
- lambda: |-
id(display_dim_brightness_global) = int(x);
id(disp1).send_command_printf("brightness_dim=%i", int(x));
id(disp1).send_command_printf("settings.dimslider.val=%i", int(x));
if (id(current_page).state == "settings") id(disp1).set_component_text_printf("dim_text", "%i%%", int(x));
##### Temperature Correction #####
- name: ${device_name} Temperature Correction
platform: template
id: temperature_correction
entity_category: config
unit_of_measurement: '°C'
initial_value: 0
min_value: -10
max_value: 10
step: 0.1
restore_value: true
internal: false
optimistic: true
set_action:
- logger.log: Temperature correction changed.
- delay: 1s
- lambda: id(temp_nspanel).publish_state(id(temp_nspanel).raw_state);
##### page-timeout #####
- platform: template
name: ${device_name} Page timeout
id: page_timeout
entity_category: config
min_value: 0
max_value: 60
initial_value: 5
step: 1
restore_value: true
optimistic: true
##### dimming-timeout #####
- platform: template
name: ${device_name} Dimming timeout
id: dimming_timeout
entity_category: config
min_value: 0
max_value: 60
initial_value: 15
step: 1
restore_value: true
optimistic: true
select:
- id: wakeup_page_name
name: ${device_name} Wake-up page
platform: template
options:
- home
- buttonpage01
- buttonpage02
- buttonpage03
- buttonpage04
- entitypage01
- entitypage02
- entitypage03
- entitypage04
- qrcode
- alarm
initial_option: home
optimistic: true
restore_value: true
internal: false
entity_category: config
icon: mdi:page-next-outline
#set_action:
# - logger.log:
# format: "Wake-up page set: %s"
# args: ["x.c_str()"]
##### START - DISPLAY START CONFIGURATION #####
display:
- id: disp1
platform: nextion
uart_id: tf_uart
tft_url: ${nextion_update_url}
on_page: # I couldn't make this trigger to work, so used text_sensor nspanelevent and localevent instead
- lambda: ESP_LOGW("display.disp1", "NEXTION PAGE CHANGED");
on_setup:
then:
- lambda: |-
ESP_LOGV("display.disp1", "Starting");
id(disp1).send_command_printf("page 8");
id(disp1).set_component_text_printf("boot.esph_version", "%s", "${version}"); // ### esphome-version ###
id(disp1).show_component("bt_reboot");
- wait_until:
api.connected
- lambda: |-
id(disp1).set_component_text_printf("boot.ip_addr", "%s", id(ip_address).state.c_str());
auto ha_event = new esphome::api::CustomAPIDevice();
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "boot"},
{"step", "start"}
});
- delay: 1s
- if:
condition:
switch.is_off: sleep_mode
then: *sleep_mode-turn_off
else: *sleep_mode-turn_on
- lambda: |-
// Set dimming values
id(display_brightness).publish_state(id(display_brightness_global));
id(display_dim_brightness).publish_state(id(display_dim_brightness_global));
id(disp1).send_command_printf("brightness=%i", id(display_brightness_global));
id(disp1).send_command_printf("settings.brightslider.val=%i", id(display_brightness_global));
id(disp1).send_command_printf("brightness_dim=%i", id(display_dim_brightness_global));
id(disp1).send_command_printf("settings.dimslider.val=%i", id(display_dim_brightness_global));
id(nextion_init).publish_state(true);
auto ha_event = new esphome::api::CustomAPIDevice();
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "boot"},
{"step", "nextion_init"}
});
id(home_relay1_icon) = "\uE3A5";
id(home_relay1_icon) = "\uE3A8";
- *notification_clear
- switch.turn_off: notification_unread
- logger.log: "Nextion start - Done!"
### Script for page_timer
script:
- id: page_timer
mode: restart
then:
- lambda: ESP_LOGV("script.page_timer", "start page-timer delay %i", delay);
- delay: !lambda return int(id(page_timeout).state *1000);
- lambda: |-
if (id(current_page).state == "home" or id(current_page).state == "screensaver" or id(current_page).state == "boot" or int(id(page_timeout).state) == 0)
ESP_LOGD("script.page_timer", "no page-jump");
else
{
ESP_LOGD("script.page_timer", "timer->home");
id(disp1).send_command_printf("page 0");
}
- id: set_climate
mode: restart
parameters:
current_temp: float
target_temp: float
temp_step: int
total_steps: int
temp_offset: int
climate_icon: string
embedded_climate: bool
then:
- lambda: ESP_LOGV("script.set_climate", "Starting");
- if:
condition:
- text_sensor.state: # Is climate page visible?
id: current_page
state: 'climate'
then:
- lambda: |-
ESP_LOGV("script.set_climate", "climateslider.maxval=%i", total_steps);
ESP_LOGV("script.set_climate", "temp_offset=%i", temp_offset);
ESP_LOGV("script.set_climate", "temp_step=%i", temp_step);
ESP_LOGV("script.set_climate", "current_temp=%f", current_temp);
ESP_LOGV("script.set_climate", "target_temp=%f", target_temp);
ESP_LOGV("script.set_climate", "target_icon=%s", climate_icon.c_str());
ESP_LOGV("script.set_climate", "embedded=%i", (embedded_climate) ? 1 : 0);
id(addon_climate_set_climate).execute(embedded_climate);
id(disp1).send_command_printf("climateslider.maxval=%i", total_steps);
id(disp1).set_component_value("temp_offset", temp_offset);
id(disp1).set_component_value("temp_step", temp_step);
id(disp1).set_component_text_printf("current_temp", "%.1f°", current_temp);
id(disp1).show_component("current_temp");
id(disp1).show_component("current_icon");
if (target_temp > -999)
{
float slider_val = round(((10*target_temp) - temp_offset) / temp_step);
ESP_LOGV("script.set_climate", "climateslider=%f", slider_val);
id(disp1).set_component_value("climateslider", slider_val);
id(disp1).set_component_text_printf("target_temp", "%.1f°", target_temp);
id(disp1).set_component_text_printf("target_icon", "%s", climate_icon.c_str());
id(disp1).show_component("target_icon");
id(disp1).show_component("target_temp");
id(disp1).show_component("climateslider");
id(disp1).show_component("decrease_temp");
id(disp1).show_component("increase_temp");
}
else
{
id(disp1).hide_component("target_icon");
id(disp1).hide_component("target_temp");
id(disp1).hide_component("climateslider");
id(disp1).hide_component("decrease_temp");
id(disp1).hide_component("increase_temp");
}
id(disp1).set_component_value("embedded", (embedded_climate) ? 1 : 0);
- lambda: ESP_LOGV("script.set_climate", "Finished");
- id: refresh_datetime
mode: restart
then:
- lambda: |-
ESP_LOGV("script.refresh_datetime", "Starting");
std::string time_format_str = id(mui_time_format);
if (time_format_str.find("%p") != std::string::npos)
{
std::string meridiem_text = id(time_provider).now().strftime("%p");
id(disp1).set_component_text_printf("home.meridiem", "%s", meridiem_text.c_str());
}
else { id(disp1).set_component_text_printf("home.meridiem", " "); }
if (time_format_str.find("%-H") != std::string::npos) { time_format_str = time_format_str.replace(time_format_str.find("%-H"), sizeof("%-H")-1, to_string((int)(id(time_provider).now().hour))); }
if (time_format_str.find("%-I") != std::string::npos)
{
if (id(time_provider).now().hour>12)
{
time_format_str = time_format_str.replace(time_format_str.find("%-I"), sizeof("%-I")-1, to_string((int)(id(time_provider).now().hour-12)));
}
else if (id(time_provider).now().hour==0)
{
time_format_str = time_format_str.replace(time_format_str.find("%-I"), sizeof("%-I")-1, "12");
}
else
{
time_format_str = time_format_str.replace(time_format_str.find("%-I"), sizeof("%-I")-1, to_string((int)(id(time_provider).now().hour)));
}
}
std::string time_text = id(time_provider).now().strftime(time_format_str);
id(disp1).set_component_text_printf("home.time", "%s", time_text.c_str());
ESP_LOGV("script.refresh_datetime", "Finished");
- id: refresh_relays
mode: restart
then:
- lambda: |-
ESP_LOGV("script.refresh_relays", "Starting");
// Chips - Relays
if (id(relay_1).state) id(disp1).set_component_text_printf("home.icon_top_01", "%s", id(home_relay1_icon).c_str());
else id(disp1).set_component_text_printf("icon_top_01", "\uFFFF");
if (id(relay_2).state) id(disp1).set_component_text_printf("home.icon_top_02", "%s", id(home_relay2_icon).c_str());
else id(disp1).set_component_text_printf("home.icon_top_02", "\uFFFF");
// Hardware buttons - Fallback mode
if (id(relay_1).state and id(relay1_local).state) id(disp1).send_command_printf("home.left_bt_pic.val=%i", (id(relay_1).state) ? 1 : 0);
if (id(relay_2).state and id(relay2_local).state) id(disp1).send_command_printf("home.right_bt_pic.val=%i", (id(relay_2).state) ? 1 : 0);
ESP_LOGV("script.refresh_relays", "Finished");
- id: refresh_wifi_icon
mode: restart
then:
- lambda: ESP_LOGV("script.refresh_wifi_icon", "Starting");
- if:
condition:
- binary_sensor.is_on: nextion_init
then:
# Update Wi-Fi icon
- if:
condition:
wifi.connected:
then:
- if:
condition:
api.connected:
then:
- lambda: id(disp1).send_command_printf("api=1");
- lambda: id(disp1).set_component_text_printf("home.wifi_icon", "%s", "\uE5A8");
- lambda: id(disp1).set_component_font_color("home.wifi_icon", 33808);
else:
- lambda: id(disp1).send_command_printf("api=0");
- lambda: id(disp1).set_component_text_printf("home.wifi_icon", "%s", "\uF256");
- lambda: id(disp1).set_component_font_color("home.wifi_icon", 63488);
else:
- lambda: id(disp1).send_command_printf("api=0");
- lambda: id(disp1).set_component_text_printf("home.wifi_icon", "%s", "\uE5A9");
- lambda: id(disp1).set_component_font_color("home.wifi_icon", 63488);
- lambda: ESP_LOGV("script.refresh_wifi_icon", "Finished");
- id: update_page_home
mode: restart
then:
- lambda: ESP_LOGV("script.update_page_home", "Starting");
- if:
condition:
- text_sensor.state: # Is home page visible?
id: current_page
state: 'home'
then:
- script.execute: refresh_relays
- script.execute: refresh_wifi_icon
- lambda: |-
ESP_LOGV("script.update_page_home", "is_notification=%i", (id(notification_text).state.empty() and id(notification_label).state.empty()) ? 0 : 1);
id(disp1).send_command_printf("is_notification=%i", (id(notification_text).state.empty() and id(notification_label).state.empty()) ? 0 : 1);
id(set_component_color).execute("home.bt_notific", id(notification_unread).state ? id(home_notify_icon_color_unread) : id(home_notify_icon_color_normal), {});
- script.execute: refresh_datetime
- script.execute: addon_climate_update_page_home
- lambda: ESP_LOGV("script.update_page_home", "Finished");
- id: service_call_alarm_control_panel
mode: restart
parameters:
entity: string
key: string
code_format: string
pin: string
then:
- lambda: |-
ESP_LOGV("service_call_alarm_control_panel", "ESPHome remote service call");
ESP_LOGV("service_call_alarm_control_panel", "entity=%s", entity.c_str());
ESP_LOGV("service_call_alarm_control_panel", "key=%s", key.c_str());
ESP_LOGV("service_call_alarm_control_panel", "code_format=%s", code_format.c_str());
ESP_LOGV("service_call_alarm_control_panel", "pin=%s", entity.c_str());
std::string service = "";
if (key=="home") service = "alarm_control_panel.alarm_arm_home";
else if (key=="away") service = "alarm_control_panel.alarm_arm_away";
else if (key=="night") service = "alarm_control_panel.alarm_arm_night";
else if (key=="vacation") service = "alarm_control_panel.alarm_arm_vacation";
else if (key=="bypass") service = "alarm_control_panel.alarm_arm_custom_bypass";
else if (key=="disarm") service = "alarm_control_panel.alarm_disarm";
ESP_LOGV("service_call_alarm_control_panel", "service=%s", service.c_str());
if (service != "" and not service.empty())
{
ESP_LOGV("service_call_alarm_control_panel", "ESPHome remote service call");
HomeassistantServiceResponse resp;
HomeassistantServiceMap resp_kv;
resp.service = service.c_str();
resp_kv.key = "entity_id";
resp_kv.value = entity.c_str();
resp.data.push_back(resp_kv);
if (pin != "" and not pin.empty())
{
resp_kv.key = "code";
resp_kv.value = pin.c_str();
resp.data.push_back(resp_kv);
}
id(api_server).send_homeassistant_service_call(resp);
}
- id: service_call_climate
mode: restart
parameters:
entity: string
key: string
value: string
embedded: bool
then:
- lambda: |-
if (embedded)
id(addon_climate_service_call)->execute(key.c_str(), value.c_str());
else if (key == "set_temperature")
id(ha_call_service)->execute("climate.set_temperature", "temperature", to_string(stof(value) / 10), entity.c_str());
else if (key == "hvac_mode")
id(ha_call_service)->execute("climate.set_hvac_mode", key.c_str(), value.c_str(), entity.c_str());
- id: ha_call_service
mode: restart
parameters:
service: string
key: string
value: string
entity: string
then:
- lambda: |-
if (service != "" and not service.empty())
{
auto ha_event = new esphome::api::CustomAPIDevice();
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "service_call"},
{"service", service},
{"entity", entity},
{"key", key},
{"value", value}
});
}
- id: ha_button
mode: parallel
parameters:
page: string
component: string
command: string
then:
- lambda: |-
ESP_LOGV("script.ha_button", "Starting");
ESP_LOGV("script.ha_button", "page: %s", page.c_str());
ESP_LOGV("script.ha_button", "component: %s", component.c_str());
ESP_LOGV("script.ha_button", "command: %s", command.c_str());
auto ha_event = new esphome::api::CustomAPIDevice();
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "button_click"},
{"page", page},
{"component", component},
{"command", command}
});
ESP_LOGV("script.ha_button", "Finished");
- id: update_alarm_icon
mode: restart
parameters:
component: string
state: string
then:
- lambda: |-
ESP_LOGV("script.update_alarm_icon", "Starting");
std::string alarm_icon = "\uEECC"; //mdi:shield-alert-outline
int alarm_color = 65535;
// Standard colors:
// blue: '1055' # rgb(0, 128, 248)
// grey_dark: '10597' # rgb(40, 44, 40)
// grey_light: '33808' # rgb(128, 128, 128)
// grey_super_light: '52857' # rgb(200, 204, 200)
// grey_white: '59164' # rgb(225, 225, 225)
// red: '63488' # rgb(248, 0, 0)
// white: '65535' # rgb(255, 255, 255)
// yellow: '65472' # rgb(248, 248, 0)
// #### Colors from HA Style:
// green: '19818' # rgb(76, 175, 80)
// orange: '64704' # rgb(255, 152, 0)
// cyan: '1530' # rgb(0, 188, 212)
// deep-orange: '64164' # rgb(255, 87, 34)
// amber: '65024' # rgb(255, 193, 7)
// "off": '35921' #8a8a8a
// disabled: '48631' # rgb(189, 189, 189)
if (state == "disarmed")
{
alarm_icon = "\uE99B"; //mdi:shield-off-outline
alarm_color = 65535;
}
else if (state == "armed_home")
{
alarm_icon = "\uECCA"; //mdi:shield-home-outline
alarm_color = 19818;
}
else if (state == "armed_away")
{
alarm_icon = "\uECCB"; //mdi:shield-lock-outline
alarm_color = 19818;
}
else if (state == "armed_night")
{
alarm_icon = "\uF828"; //mdi:shield-moon-outline
alarm_color = 19818;
}
else if (state == "armed_vacation")
{
alarm_icon = "\uECC6"; //mdi:shield-airplane-outline
alarm_color = 19818;
}
else if (state == "armed_custom_bypass")
{
alarm_icon = "\uE77F"; //mdi:shield-half-full
alarm_color = 19818;
}
else if (state == "pending" or state == "arming")
{
alarm_icon = "\uE498"; //mdi:shield-outline
alarm_color = 65024;
}
else if (state == "disarming")
{
alarm_icon = "\uE99B"; //mdi:shield-off-outline
alarm_color = 65024;
}
else if (state == "triggered")
{
alarm_icon = "\uEECC"; //mdi:shield-alert-outline
alarm_color = 63488;
}
id(disp1).set_component_text_printf(component.c_str(), alarm_icon.c_str());
id(disp1).set_component_font_color(component.c_str(), alarm_color);
ESP_LOGV("script.update_alarm_icon", "Finished");
- id: update_climate_icon
mode: restart
parameters:
component: string
action: int
mode: int
then:
- lambda: |-
ESP_LOGV("script.update_climate_icon", "Starting");
ESP_LOGV("script.update_climate_icon", "component: %s", component.c_str());
ESP_LOGV("script.update_climate_icon", "action: %i", action);
ESP_LOGV("script.update_climate_icon", "mode: %i", mode);
switch (action) // CLIMATE_ACTION_OFF = 0, CLIMATE_ACTION_COOLING = 2, CLIMATE_ACTION_HEATING = 3, CLIMATE_ACTION_IDLE = 4, CLIMATE_ACTION_DRYING = 5, CLIMATE_ACTION_FAN = 6
{
case 0: //CLIMATE_ACTION_OFF
ESP_LOGV("script.update_climate_icon", "Climate 'action' is off. Using 'mode' instead");
switch (mode) // CLIMATE_MODE_OFF = 0, CLIMATE_MODE_HEAT_COOL = 1, CLIMATE_MODE_COOL = 2, CLIMATE_MODE_HEAT = 3, CLIMATE_MODE_FAN_ONLY = 4, CLIMATE_MODE_DRY = 5, CLIMATE_MODE_AUTO = 6
{
case 0: //CLIMATE_MODE_OFF
ESP_LOGV("script.update_climate_icon", "Icon: none");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uFFFF"); // (E424) Don't show icon when off
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
case 1: //CLIMATE_MODE_HEAT_COOL
ESP_LOGV("script.update_climate_icon", "Icon: autorenew");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE069"); // mdi:autorenew
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
case 2: //CLIMATE_MODE_COOL
ESP_LOGV("script.update_climate_icon", "Icon: snowflake");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE716"); // mdi:snowflake
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
case 3: //CLIMATE_MODE_HEAT
ESP_LOGV("script.update_climate_icon", "Icon: fire");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE237"); // mdi:fire
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
case 4: //CLIMATE_MODE_FAN_ONLY
ESP_LOGV("script.update_climate_icon", "Icon: fan");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE20F"); // mdi:fan
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
case 5: //CLIMATE_MODE_DRY
ESP_LOGV("script.update_climate_icon", "Icon: water-percent");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE58D"); // mdi:water-percent
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
case 6: //CLIMATE_MODE_AUTO
ESP_LOGV("script.update_climate_icon", "Icon: calendar-sync");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uEE8D"); // mdi:calendar-sync
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
}
break;
case 2: //CLIMATE_ACTION_COOLING
ESP_LOGV("script.update_climate_icon", "Icon: snowflake");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE716"); // mdi:snowflake
id(disp1).set_component_font_color(component.c_str(), 1055); // blue
break;
case 3: //CLIMATE_ACTION_HEATING
ESP_LOGV("script.update_climate_icon", "Icon: fire");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE237"); // mdi:fire
id(disp1).set_component_font_color(component.c_str(), 64164); // deep-orange
break;
case 4: //CLIMATE_ACTION_IDLE
ESP_LOGV("script.update_climate_icon", "Icon: thermometer");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE50E"); // mdi:thermometer
id(disp1).set_component_font_color(component.c_str(), 35921); // grey (off)
break;
case 5: //CLIMATE_ACTION_DRYING
ESP_LOGV("script.update_climate_icon", "Icon: water-percent");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE58D"); // mdi:water-percent
id(disp1).set_component_font_color(component.c_str(), 64704); // orange
break;
case 6: //CLIMATE_ACTION_FAN
ESP_LOGV("script.update_climate_icon", "Icon: fan");
id(disp1).set_component_text_printf(component.c_str(), "%s", "\uE20F"); // mdi:fan
id(disp1).set_component_font_color(component.c_str(), 1530); // cyan
break;
}
ESP_LOGV("script.update_climate_icon", "Finished");
- id: set_component_color
mode: queued
parameters:
component: string
foreground: int[]
background: int[]
then:
- lambda: |-
ESP_LOGV("script.set_component_color", "Starting");
ESP_LOGV("script.set_component_color", "Component: %s", component.c_str());
int fg565 = -1;
int bg565 = -1;
// Foreground
if (foreground.size() == 3) fg565 = ((foreground[0] & 0b11111000) << 8) | ((foreground[1] & 0b11111100) << 3) | (foreground[2] >> 3);
else if (foreground.size() == 1) fg565 = foreground[0];
if (fg565 >= 0) id(disp1).set_component_font_color(component.c_str(), fg565);
// Background
if (background.size() == 3) bg565 = ((background[0] & 0b11111000) << 8) | ((background[1] & 0b11111100) << 3) | (background[2] >> 3);
else if (background.size() == 1) bg565 = background[0];
if (bg565 >= 0) id(disp1).set_component_background_color(component.c_str(), bg565);
ESP_LOGV("script.set_component_color", "Finished");
- id: display_wrapped_text
mode: queued
parameters:
component: string
text: string
line_length_limit: int
then:
- lambda: |-
int startPos = 0;
int endPos = 0;
std::string wrappedText = "";
while (startPos < text.length()) {
while (text[startPos] == ' ' and startPos < text.length()) { startPos++; }
int endPos = startPos + line_length_limit;
if (endPos >= text.length()) endPos = text.length();
else
{
while (endPos > startPos && text[endPos] != ' ') { endPos--; }
if (endPos == startPos) endPos = startPos + line_length_limit; // Handle case of long word
}
wrappedText += text.substr(startPos, endPos-startPos);
if (endPos < text.length())
{
while (text[endPos] == ' ') { endPos--; }
if (endPos >= startPos) wrappedText += "\\r";
}
startPos = endPos + 1; // Skip the space
while (text[startPos] == ' ' and startPos < text.length()) { startPos++; }
}
ESP_LOGV("script.display_wrapped_text", "text (new): %s", wrappedText.c_str());
id(disp1).set_component_text_printf(component.c_str(), "%s", wrappedText.c_str());
- id: display_embedded_temp
mode: restart
then:
- if:
condition:
- or:
- lambda: return id(embedded_indoor_temp);
- not:
- api.connected:
- not:
- wifi.connected:
then:
- lambda: |-
if (id(temp_unit_fahrenheit)) id(disp1).set_component_text_printf("home.current_temp", "%.0f°F", ((id(temp_nspanel).state * 9.0 / 5.0) + 32.0)); // °F = (°C × 9/5) + 32
else id(disp1).set_component_text_printf("home.current_temp", "%.1f°C", id(temp_nspanel).state);
- id: check_versions
mode: restart
then:
- delay: 60s
- lambda: |-
ESP_LOGD("script.check_versions", "ESPHome version: ${version}");
ESP_LOGD("script.check_versions", "TFT version: %s", id(version_tft).c_str());
if (id(version_tft) != "${version}") ESP_LOGE("script.check_versions", "TFT version mismatch!");
ESP_LOGD("script.check_versions", "Blueprint version: %s", id(version_blueprint).c_str());
if (id(version_blueprint) != "${version}") ESP_LOGE("script.check_versions", "Blueprint version mismatch!");
auto ha_event = new esphome::api::CustomAPIDevice();
ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint",
{
{"type", "version"},
{"tft", id(version_tft).c_str()},
{"esphome", "${version}"},
{"blueprint", id(version_blueprint).c_str()}
});
##### ADD-ONS ############################################################
##### Add-on - Climate #####
- id: addon_climate_service_call
mode: restart
parameters:
key: string
value: string
then:
# Reserved for Add-on Climate
- lambda: |-
ESP_LOGV("script.addon_climate_service_call", "Check for addon_climate");
- id: addon_climate_update_page_home
mode: restart
then:
# Reserved for Add-on Climate
- lambda: |-
ESP_LOGV("script.addon_climate_update_page_home", "Check for addon_climate");
- id: addon_climate_set_climate
mode: restart
parameters:
embedded_climate: bool
then:
# Reserved for Add-on Climate
- lambda: |-
ESP_LOGV("script.addon_climate_set_climate", "Check for addon_climate");
ESP_LOGV("script.addon_climate_set_climate", "embedded_climate: %i", (embedded_climate) ? 1 : 0);
- id: addon_climate_update_page_climate
mode: restart
then:
# Reserved for Add-on Climate
- lambda: |-
ESP_LOGV("script.addon_climate_update_page_climate", "Check for addon_climate");
- id: addon_climate_set_climate_friendly_name
mode: restart
parameters:
friendly_name: string
then:
# Reserved for Add-on Climate
- lambda: |-
ESP_LOGV("script.addon_climate_set_climate_friendly_name", "Check for addon_climate");
ESP_LOGV("script.addon_climate_set_climate_friendly_name", "friendly_name: %s", friendly_name.c_str());