We are trying to make your panel as autonomous as possible by moving some of the controls from the Blueprint to ESPHome. This will reduce the load in your network and Home Assistant, but also will make a more reliable system capable to do it's core functionality even when the network is unavailable or Home Assistant is restarting. With this version, the following engines have been moved to your panel (local control): - Physical relay control (when hardware left button is connected to relay 1 or right button to relay 2) Solves #910
1082 lines
36 KiB
YAML
1082 lines
36 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. #####
|
|
#####################################################################################################
|
|
|
|
|
|
##### ADVANCED CONFIGURATION - activate only when you know what you do ##############################
|
|
substitutions:
|
|
baud_rate: "115200" # requires 115200 if tft is installed but can be changed to 9600 if tft upload fails and nextion switches to 9600
|
|
# ## usage of secrets-file ## -> comment in ###### Change ME ######
|
|
# device_name: "nspanel-name" # Wird im Blueprint benötigt!
|
|
# wifi_ssid: !secret nspanel_wifi_ssid # add in your esphome secrets file.
|
|
# wifi_password: !secret nspanel_wifi_password # add in your esphome secrets file. -> per default this is also used for ota_password and web_password
|
|
# ota_password: !secret nspanel_ota_password # add in your esphome secrets file. - manual change in code required to activate
|
|
# web_password: !secret nspanel_web_password # add in your esphome secrets file. - manual change in code required to activate
|
|
# api_password: !secret nspanel_api_password # add in your esphome secrets file. - manual change in code required to activate
|
|
# nextion_update_url: !secret nspanel_update_url # add in your esphome secrets file. Example: "http://"HOME ASSISTANT IP":8123/local/nspanel/nspanel.tft"
|
|
|
|
# ## static ip config ##
|
|
# ip: "10.0.0.7"
|
|
# gw: "10.0.0.138"
|
|
# subnet: "255.255.255.0"
|
|
# dns: "10.0.0.138"
|
|
# domain: ".local"
|
|
|
|
time_source: "homeassistant" # Either "homeassistant" or "sntp" are supported
|
|
|
|
###### USE THIS ONLY FOR YOUR FIRST TFT UPLOAD
|
|
###### AND IF EXIT-REPARSE BUTTON FAILS
|
|
###### ONCE IT WORKED, REMOVE THESE LINES
|
|
###### https://github.com/esphome/esphome/pull/2956
|
|
# external_components:
|
|
# - source: github://pr#2956
|
|
# components: [nextion]
|
|
# refresh: 1h
|
|
##################################################
|
|
|
|
##### if you rename this file to .nspanel_esphome.yaml then you can activate nested config
|
|
##### use the ADVANCED CONFIG-Section as device configuration
|
|
##### https://esphome.io/guides/configuration-types.html#yaml-insertion-operator
|
|
# <<: !include .nspanel_esphome.yaml
|
|
|
|
##### END OF ADVANCED CONFIGURATION ##############################################################
|
|
|
|
##### WIFI SETUP #####
|
|
wifi:
|
|
ssid: ${wifi_ssid}
|
|
password: ${wifi_password}
|
|
power_save_mode: none
|
|
##### advanced config - uncomment to use static IP-Config #####
|
|
# manual_ip:
|
|
# static_ip: ${ip}
|
|
# gateway: ${gw}
|
|
# subnet: ${subnet}
|
|
# dns1: ${dns}
|
|
# domain: ${domain}
|
|
##### Enable fallback hotspot (captive portal) in case wifi connection fails
|
|
ap:
|
|
ssid: "${device_name}"
|
|
password: ${wifi_password}
|
|
|
|
##### ESPHOME CONFIGURATION #####
|
|
esphome:
|
|
name: ${device_name}
|
|
min_version: 2022.10.2
|
|
|
|
##### TYPE OF ESP BOARD #####
|
|
esp32:
|
|
board: esp32dev
|
|
|
|
captive_portal:
|
|
|
|
web_server:
|
|
port: 80
|
|
auth:
|
|
username: admin
|
|
password: ${wifi_password}
|
|
##### advanced config - change to use web_password #####
|
|
# password: ${web_password}
|
|
|
|
##### OTA PASSWORD #####
|
|
ota:
|
|
password: ${wifi_password}
|
|
##### advanced config - change to use ota_password #####
|
|
# password: ${ota_password}
|
|
safe_mode: true
|
|
reboot_timeout: 3min
|
|
num_attempts: 3
|
|
|
|
##### LOGGER #####
|
|
logger:
|
|
baud_rate: 0
|
|
# level: WARN
|
|
|
|
##### CONFIGURE INTERNAL BUZZER #####
|
|
output:
|
|
##### BUZZER FOR PLAYING RINGTONES #####
|
|
- platform: ledc
|
|
id: buzzer_out
|
|
pin:
|
|
number: 21
|
|
|
|
##### ENABLE RINGTONE MUSIC SUPPORT #####
|
|
rtttl:
|
|
id: buzzer
|
|
output: buzzer_out
|
|
|
|
##### UART FOR NEXTION DISPLAY #####
|
|
uart:
|
|
tx_pin: 16
|
|
rx_pin: 17
|
|
baud_rate: ${baud_rate}
|
|
id: tf_uart
|
|
# debug:
|
|
# direction: BOTH
|
|
# dummy_receiver: false
|
|
# after:
|
|
# delimiter: "\n"
|
|
# sequence:
|
|
# - lambda: UARTDebug::log_string(direction, bytes);
|
|
|
|
### Keeps time display updated
|
|
time:
|
|
- platform: ${time_source}
|
|
id: time_provider
|
|
on_time:
|
|
- seconds: 0
|
|
then:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- &refresh_datetime
|
|
lambda: |-
|
|
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());
|
|
on_time_sync:
|
|
then:
|
|
- logger.log: "Synchronized system clock"
|
|
- *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:
|
|
##### advanced config - activate to use api_password #####
|
|
# password: ${api_password}
|
|
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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- 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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- 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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- 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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- 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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: 'id(disp1).show_component("255");'
|
|
|
|
##### Service to send a command "font color" directly to the display #####
|
|
- service: send_command_font_color
|
|
variables:
|
|
component: string
|
|
message: int
|
|
then:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: 'id(disp1).set_component_font_color(component.c_str(), message);'
|
|
|
|
##### Service to send a command "background color" directly to the display #####
|
|
- service: send_command_background_color
|
|
variables:
|
|
component: string
|
|
message: int
|
|
then:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: 'id(disp1).set_component_background_color(component.c_str(), message);'
|
|
|
|
##### Service to show a notification-message on the screen #####
|
|
- service: notification_show
|
|
variables:
|
|
label: string
|
|
text: string
|
|
then:
|
|
- logger.log: "Service: notification_show"
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: |-
|
|
id(disp1).send_command_printf("page notification");
|
|
id(disp1).set_component_text_printf("notification.notifi_label", "%s", label.c_str());
|
|
id(disp1).set_component_text_printf("notification.notifi_text01", "%s", text.c_str());
|
|
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"
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: |-
|
|
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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: |-
|
|
id(disp1).set_component_text_printf("home.entity", "%s", entity.c_str());
|
|
std::string cmd_page = std::string("page ") + page.c_str();
|
|
id(disp1).send_command_printf(cmd_page.c_str());
|
|
id(disp1).set_component_text_printf("page_label", "%s", page_label.c_str());
|
|
id(disp1).set_component_text_printf("back_page", "%s", back_page.c_str());
|
|
if ((page_icon.c_str() != std::string()) and (page_icon.c_str() != "") and (page != "climate"))
|
|
{
|
|
id(disp1).set_component_text_printf("icon_state", "%s", page_icon.c_str());
|
|
}
|
|
if (page_icon_color >= 0 and page != "climate")
|
|
{
|
|
id(disp1).set_component_font_color("icon_state", page_icon_color);
|
|
}
|
|
|
|
##### 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: qr_code
|
|
variables:
|
|
qrdata: string
|
|
then:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: |-
|
|
id(disp1).send_command_printf("page qrcode");
|
|
id(disp1).set_component_text_printf("qrcode.qrcode_value", "%s", qrdata.c_str());
|
|
|
|
#### Service to set climate state ####
|
|
- service: set_climate
|
|
variables:
|
|
current_temp: float
|
|
target_temp: float
|
|
temp_step: int
|
|
total_steps: int
|
|
slider_val: int
|
|
temp_offset: int
|
|
climate_icon: string
|
|
then:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: |-
|
|
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)
|
|
{
|
|
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");
|
|
}
|
|
|
|
#### 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
|
|
then:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: |-
|
|
// ESP_LOGD("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");
|
|
id(disp1).send_command_printf("%spic.pic=%i", btn_id.c_str(), btn_pic);
|
|
id(disp1).set_component_background_color(btnicon.c_str(), btn_bg);
|
|
id(disp1).set_component_background_color(btntext.c_str(), btn_bg);
|
|
id(disp1).set_component_background_color(btnbri.c_str(), btn_bg);
|
|
id(disp1).set_component_font_color(btnicon.c_str(), btn_icon_font);
|
|
id(disp1).set_component_font_color(btntext.c_str(), btn_txt_font);
|
|
id(disp1).set_component_font_color(btnbri.c_str(), btn_bri_font);
|
|
id(disp1).set_component_text_printf(btnicon.c_str(), "%s", btn_icon.c_str());
|
|
id(disp1).set_component_text_printf(btntext.c_str(), "%s", btn_label.c_str());
|
|
// id(disp1).set_component_text_printf(btnbri.c_str(), "%s", btn_bri_txt.c_str());
|
|
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(), " ");
|
|
}
|
|
|
|
##### SERVICE TO WAKE UP THE DISPLAY #####
|
|
- service: wake_up_display
|
|
variables:
|
|
option: string
|
|
then:
|
|
- lambda: |-
|
|
DynamicJsonDocument doc(1024);
|
|
deserializeJson(doc, id(disp1_nspanel_event).state);
|
|
std::string page = doc["page"];
|
|
if (page == "screensaver") {
|
|
id(disp1).send_command_printf("page home");
|
|
} else {
|
|
if (page == "home"){
|
|
id(disp1).send_command_printf("dim=brightness.val");
|
|
}
|
|
}
|
|
- if:
|
|
condition:
|
|
- lambda: 'return option == "keep_wake";'
|
|
then:
|
|
- lambda: id(disp1).send_command_printf("home.dimtimer.en=1");
|
|
- lambda: id(disp1).send_command_printf("home.sleeptimer.en=1");
|
|
- if:
|
|
condition:
|
|
- lambda: 'return option == "keep_page";'
|
|
then:
|
|
- lambda: id(disp1).send_command_printf("home.dimtimer.en=1");
|
|
- lambda: id(disp1).send_command_printf("home.sleeptimer.en=1");
|
|
- lambda: |-
|
|
id(page_timer)->execute(int(id(page_timeout).state));
|
|
|
|
#### 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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- lambda: |-
|
|
// ESP_LOGD("nextion", "set 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(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 localization of global vars #####
|
|
- service: set_localization
|
|
variables:
|
|
time_format: string
|
|
then:
|
|
- lambda: |-
|
|
ESP_LOGD("set_localization", "time_format: %s", time_format.c_str());
|
|
id(mui_time_format) = time_format;
|
|
- *refresh_datetime
|
|
|
|
##### Service for setting relays as locally controlled #####
|
|
- service: set_relay_local
|
|
variables:
|
|
relay1: bool
|
|
relay2: bool
|
|
then:
|
|
- lambda: |-
|
|
id(relay1_local).publish_state(relay1);
|
|
id(relay2_local).publish_state(relay2);
|
|
|
|
##### START - GLOBALS CONFIGURATION #####
|
|
globals:
|
|
|
|
##### 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 Correction #####
|
|
- id: temperature_correction_global
|
|
type: float
|
|
restore_value: true
|
|
initial_value: '0.0'
|
|
|
|
##### Date/time formats #####
|
|
#- id: mui_date_format
|
|
# type: std::string
|
|
# restore_value: no
|
|
# initial_value: '"%A, %d.%m"'
|
|
- id: mui_time_format
|
|
type: std::string
|
|
restore_value: no
|
|
initial_value: '"%H:%M"'
|
|
|
|
##### 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_click:
|
|
then:
|
|
- if:
|
|
condition:
|
|
or:
|
|
- switch.is_on: relay1_local
|
|
- and:
|
|
- switch.is_on: relay1_fallback
|
|
- not:
|
|
api.connected:
|
|
then:
|
|
- switch.toggle: relay_1
|
|
- if:
|
|
condition:
|
|
switch.is_on: relay_1
|
|
then:
|
|
- lambda: id(disp1).send_command_printf("home.left_bt_pic.pic=78");
|
|
- lambda: id(disp1).send_command_printf("home.icon_top_01","\U0000E3A5");
|
|
else:
|
|
- lambda: id(disp1).send_command_printf("home.left_bt_pic.pic=77");
|
|
- lambda: id(disp1).send_command_printf("home.icon_top_01","\U0000FFFF");
|
|
|
|
##### RIGHT BUTTON BELOW DISPLAY TO TOGGLE RELAY #####
|
|
- name: ${device_name} Right Button
|
|
platform: gpio
|
|
id: right_button
|
|
pin:
|
|
number: 27
|
|
inverted: true
|
|
on_click:
|
|
then:
|
|
- if:
|
|
condition:
|
|
or:
|
|
- switch.is_on: relay2_local
|
|
- and:
|
|
- switch.is_on: relay2_fallback
|
|
- not:
|
|
api.connected:
|
|
then:
|
|
- switch.toggle: relay_2
|
|
- if:
|
|
condition:
|
|
switch.is_on: relay_2
|
|
then:
|
|
- lambda: id(disp1).send_command_printf("home.right_bt_pic.pic=78");
|
|
- lambda: id(disp1).send_command_printf("home.icon_top_02","\U0000E3A8");
|
|
else:
|
|
- lambda: id(disp1).send_command_printf("home.right_bt_pic.pic=77");
|
|
- lambda: id(disp1).send_command_printf("home.icon_top_02","\U0000FFFF");
|
|
|
|
##### Restart NSPanel Button - Setting Page #####
|
|
- name: ${device_name} Restart
|
|
platform: nextion
|
|
page_id: 7
|
|
component_id: 13
|
|
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: 14
|
|
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
|
|
- platform: status
|
|
name: ${device_name} Status
|
|
on_state:
|
|
then:
|
|
- &update_wifi_icon
|
|
if:
|
|
condition:
|
|
wifi.connected:
|
|
then:
|
|
- if:
|
|
condition:
|
|
api.connected:
|
|
then:
|
|
- lambda: id(disp1).set_component_value("home.api",1);
|
|
- lambda: id(disp1).set_component_text_printf("home.wifi_icon", "%s", "\U0000E5A8");
|
|
- lambda: id(disp1).set_component_font_color("home.wifi_icon", 33808);
|
|
else:
|
|
- lambda: id(disp1).set_component_value("home.api",0);
|
|
- lambda: id(disp1).set_component_text_printf("home.wifi_icon", "%s", "\U0000F256");
|
|
- lambda: id(disp1).set_component_font_color("home.wifi_icon", 63488);
|
|
else:
|
|
- lambda: id(disp1).set_component_value("home.api",0);
|
|
- lambda: id(disp1).set_component_text_printf("home.wifi_icon", "%s", "\U0000E5A9");
|
|
- lambda: id(disp1).set_component_font_color("home.wifi_icon", 63488);
|
|
|
|
##### START - SENSOR CONFIGURATION #####
|
|
sensor:
|
|
|
|
##### Uptime #####
|
|
- name: ${device_name} uptime
|
|
platform: uptime
|
|
disabled_by_default: true
|
|
|
|
##### WIFI Signal stregth
|
|
- name: ${device_name} RSSI
|
|
platform: wifi_signal
|
|
update_interval: 60s
|
|
on_value:
|
|
- *update_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_global);
|
|
#on_value:
|
|
# then:
|
|
# - wait_until:
|
|
# binary_sensor.is_on: nextion_init
|
|
# - lambda: id(disp1).set_component_text_printf("home.current_temp", "%.1f°", id(temp_nspanel).state); # onboard temp (thermostat temp) to home page.
|
|
# - lambda: id(disp1).set_component_text_printf("climate.current_temp", "%.1f", id(temp_nspanel).state);
|
|
|
|
###### Display Brightness GET VALUE FROM NSPanel SLIDER #####
|
|
- name: ${device_name} brightness Slider
|
|
platform: nextion
|
|
id: brightslider
|
|
variable_name: brightslider
|
|
internal: true
|
|
on_value:
|
|
then:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- number.set:
|
|
id: display_brightness
|
|
value: !lambda 'return int(x);'
|
|
# send text field percentage of current_lightslider_val
|
|
- lambda: id(disp1).set_component_text_printf("settings.a03", "%i", id(display_brightness_global));
|
|
|
|
###### 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:
|
|
- wait_until:
|
|
binary_sensor.is_on: nextion_init
|
|
- number.set:
|
|
id: display_dim_brightness
|
|
value: !lambda 'return int(x);'
|
|
# send text field percentage of current_lightslider_val
|
|
- lambda: id(disp1).set_component_text_printf("settings.a04", "%i", id(display_dim_brightness_global));
|
|
|
|
##### START - TEXT SENSOR CONFIGURATION #####
|
|
text_sensor:
|
|
|
|
##### ESPhome version used to compile the app #####
|
|
- platform: version
|
|
name: ${device_name} ESPhome 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: false
|
|
filters:
|
|
- lambda: |-
|
|
x = x.c_str();
|
|
x.shrink_to_fit();
|
|
return x;
|
|
on_value:
|
|
then:
|
|
- lambda: |-
|
|
id(page_timer)->execute(int(id(page_timeout).state));
|
|
|
|
##### touchevent sensor, Reset the page timeout #####
|
|
- id: disp1_touchevent
|
|
platform: nextion
|
|
nextion_id: disp1
|
|
#name: ${device_name} touchevent
|
|
component_name: touchevent
|
|
internal: true
|
|
filters:
|
|
- lambda: |-
|
|
x = x.c_str();
|
|
x.shrink_to_fit();
|
|
return x;
|
|
on_value:
|
|
then:
|
|
- lambda: |-
|
|
id(page_timer)->execute(int(id(page_timeout).state));
|
|
|
|
##### START - SWITCH CONFIGURATION #####
|
|
switch:
|
|
|
|
##### Notification unread #####
|
|
- name: ${device_name} Notification unread
|
|
platform: template
|
|
id: notification_unread
|
|
entity_category: config
|
|
restore_state: true
|
|
optimistic: true
|
|
|
|
##### Notification sound #####
|
|
- name: ${device_name} Notification sound
|
|
platform: template
|
|
id: notification_sound
|
|
entity_category: config
|
|
restore_state: true
|
|
optimistic: true
|
|
restore_mode: RESTORE_DEFAULT_OFF
|
|
|
|
##### Confirmation Message #####
|
|
- name: ${device_name} Confirmation Message
|
|
platform: template
|
|
id: confirmation_message
|
|
entity_category: config
|
|
restore_state: false
|
|
optimistic: true
|
|
|
|
##### PHYSICAL SWITCH 1 #####
|
|
- name: ${device_name} Relay 1
|
|
platform: gpio
|
|
id: relay_1
|
|
pin:
|
|
number: 22
|
|
restore_mode: RESTORE_DEFAULT_OFF
|
|
|
|
##### PHYSICAL SWITCH 2 ######
|
|
- name: ${device_name} Relay 2
|
|
platform: gpio
|
|
id: relay_2
|
|
pin:
|
|
number: 19
|
|
restore_mode: RESTORE_DEFAULT_OFF
|
|
|
|
##### 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
|
|
restore_state: true
|
|
optimistic: false
|
|
turn_on_action: &sleep_mode-turn_on
|
|
- logger.log: "Sleep mode - Turn on"
|
|
- lambda: id(disp1).send_command_printf("home.sleepmodus.val=1");
|
|
- lambda: id(disp1).set_component_value("settings.bt1",1);
|
|
- switch.template.publish:
|
|
id: sleep_mode
|
|
state: ON
|
|
turn_off_action: &sleep_mode-turn_off
|
|
- logger.log: "Sleep mode - Turn off"
|
|
- lambda: id(disp1).send_command_printf("home.sleepmodus.val=0");
|
|
- lambda: id(disp1).set_component_value("settings.bt1",0);
|
|
- switch.template.publish:
|
|
id: sleep_mode
|
|
state: OFF
|
|
|
|
##### Relay Local control #####
|
|
- name: ${device_name} Relay 1 Local
|
|
platform: template
|
|
id: relay1_local
|
|
entity_category: config
|
|
restore_state: true
|
|
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
|
|
restore_state: true
|
|
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!"
|
|
|
|
##### Relay Local control Fallback #####
|
|
- name: ${device_name} Relay 1 Local Fallback
|
|
platform: template
|
|
id: relay1_fallback
|
|
entity_category: config
|
|
restore_state: true
|
|
optimistic: true
|
|
restore_mode: RESTORE_DEFAULT_OFF
|
|
- name: ${device_name} Relay 2 Local Fallback
|
|
platform: template
|
|
id: relay2_fallback
|
|
entity_category: config
|
|
restore_state: true
|
|
optimistic: true
|
|
restore_mode: RESTORE_DEFAULT_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(disp1).set_backlight_brightness(x/100);'
|
|
- lambda: 'id(disp1).send_command_printf("home.brightness.val=%i", int(x));'
|
|
- globals.set:
|
|
id: display_brightness_global
|
|
value: !lambda 'return 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(disp1).send_command_printf("home.brightdd.val=%i", int(x));'
|
|
- globals.set:
|
|
id: display_dim_brightness_global
|
|
value: !lambda 'return int(x);'
|
|
|
|
##### Temperature Correction #####
|
|
- platform: template
|
|
name: ${device_name} Temperature Correction
|
|
id: temperature_correction
|
|
entity_category: config
|
|
unit_of_measurement: '°C'
|
|
min_value: -10
|
|
max_value: 10
|
|
step: 0.5
|
|
restore_value: true
|
|
optimistic: true
|
|
set_action:
|
|
then:
|
|
- globals.set:
|
|
id: temperature_correction_global
|
|
value: !lambda 'return x;'
|
|
|
|
##### page-timeout #####
|
|
- platform: template
|
|
name: ${device_name} Page Timeout
|
|
id: page_timeout
|
|
entity_category: config
|
|
min_value: 0
|
|
max_value: 60
|
|
initial_value: 10
|
|
step: 1
|
|
restore_value: true
|
|
optimistic: true
|
|
|
|
##### START - DISPLAY START CONFIGURATION #####
|
|
display:
|
|
- id: disp1
|
|
platform: nextion
|
|
uart_id: tf_uart
|
|
tft_url: ${nextion_update_url}
|
|
on_setup:
|
|
then:
|
|
- logger.log: "Nextion start - Jump to page 8"
|
|
- lambda: id(disp1).send_command_printf("page 8");
|
|
- logger.log: "Nextion start - Publish ESPHome version"
|
|
- lambda: id(disp1).set_component_text_printf("boot.esph_version", "%s", "3.5_dev"); ### esphome-version ###
|
|
- logger.log: "Nextion start - Wait for Home Assistant API"
|
|
- wait_until:
|
|
api.connected
|
|
- logger.log: "Nextion start - Publish IP address"
|
|
- lambda: id(disp1).set_component_text_printf("boot.ip_addr", "%s", id(ip_address).state.c_str());
|
|
- delay: 1s
|
|
- logger.log: "Nextion start - Set display brigntess"
|
|
- number.set:
|
|
id: display_brightness
|
|
value: !lambda 'return id(display_brightness_global);'
|
|
- logger.log: "Nextion start - Set display dim brightness"
|
|
- number.set:
|
|
id: display_dim_brightness
|
|
value: !lambda 'return id(display_dim_brightness_global);'
|
|
- logger.log: "Nextion start - Update settings page"
|
|
- lambda: id(disp1).set_component_text_printf("settings.a03", "%i", id(display_brightness_global));
|
|
- lambda: id(disp1).set_component_text_printf("settings.a04", "%i", id(display_dim_brightness_global));
|
|
- lambda: id(disp1).send_command_printf("settings.brightslider.val=%i", id(display_brightness_global));
|
|
- lambda: id(disp1).send_command_printf("settings.dimslider.val=%i", id(display_dim_brightness_global));
|
|
- if:
|
|
condition:
|
|
switch.is_off: sleep_mode
|
|
then: *sleep_mode-turn_off
|
|
else: *sleep_mode-turn_on
|
|
- delay: 1s
|
|
- logger.log: "Nextion start - Inform Home Assistant display is ready"
|
|
- binary_sensor.template.publish:
|
|
id: nextion_init
|
|
state: true
|
|
- logger.log: "Nextion start - Done!"
|
|
|
|
### Script for page_timer
|
|
script:
|
|
- id: page_timer
|
|
mode: restart
|
|
parameters:
|
|
delay: int
|
|
then:
|
|
- lambda: ESP_LOGD("nspanel", "start page-timer delay %i", int(id(page_timeout).state));
|
|
- delay: !lambda return delay *1000;
|
|
- lambda: |-
|
|
DynamicJsonDocument doc(1024);
|
|
deserializeJson(doc, id(disp1_nspanel_event).state);
|
|
std::string page = doc["page"];
|
|
if (page == "home" or page == "screensaver" or page == "boot" or int(id(page_timeout).state) == 0) {
|
|
ESP_LOGD("nspanel", "no page-jump");
|
|
} else {
|
|
ESP_LOGD("nspanel", "timer->home");
|
|
id(disp1).send_command_printf("page 0");
|
|
}
|