Since v3.4, the info about entity_id shown was going all the way to Nextion and then sent back in the json return, however this requires a long (100-char) global var and the way it was implemented, it was one of those per settings page, as climate should be also recorded at the same time in case the embedded climate was installed. This was taking too much memory, so I've moved this info to a global variable (string) in ESPHome. There is now lots of space for code cleaning (and still pending to do the same with climate entity, as it could be only a bool to inform if embedded), but this brings the functionality. This enabled the return to global for some components, so it probably solves #1031
2352 lines
100 KiB
YAML
2352 lines
100 KiB
YAML
#####################################################################################################
|
||
##### 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"
|
||
- ¬ification_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());
|
||
id(entity_id) = entity;
|
||
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 == "climate")
|
||
{
|
||
if (entity == "embedded_climate") id(addon_climate_set_climate_friendly_name).execute(page_label.c_str());
|
||
id(disp1).set_component_value("embedded", (entity == "embedded_climate") ? 1 : 0);
|
||
}
|
||
else
|
||
{
|
||
if ((page_icon.c_str() != std::string()) and (page_icon.c_str() != ""))
|
||
id(disp1).set_component_text_printf("icon_state", "%s", page_icon.c_str());
|
||
id(set_component_color).execute("icon_state", page_icon_color, {});
|
||
}
|
||
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");
|
||
id(entity_id) = entity;
|
||
|
||
// 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");
|
||
|
||
// 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(entity_id) = entity;
|
||
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 ? 16 : 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_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
|
||
on_value:
|
||
then:
|
||
- lambda: |-
|
||
if (x != "climate" and x != "cover" and x != "fan" and x != "light" and x != "media_player" ) id(entity_id) = "";
|
||
ESP_LOGD("text_sensor.current_page", "New page: %s", x.c_str());
|
||
if (!id(entity_id).empty()) ESP_LOGD("text_sensor.current_page", "Entity shown: %s", id(entity_id).c_str());
|
||
|
||
##### 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 = id(entity_id); //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_LOGV("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 = id(entity_id); //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_LOGV("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")// 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());
|