Files
NSPanel_HA_Blueprint/advanced/esphome/nspanel_esphome_addon_upload_tft.yaml
Edward Firmo e02ee95198 Rebuilt Upload TFT
Rebuilt again, now based on the ESPHome's Nextion component instead of local code.
Still not there yet, specially when Lovelace UI tft is installed, but hopefully this solves #1383 and solves #1491.
2023-12-30 01:59:51 +01:00

449 lines
15 KiB
YAML

#####################################################################################################
##### NSPANEL ESPHOME created by Blackymas - https://github.com/Blackymas/NSPanel_HA_Blueprint #####
##### TFT Upload engine #####
##### 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. #####
#####################################################################################################
##### ATTENTION: This will add advanced elements to the core system and requires the core part. #####
#####################################################################################################
---
substitutions:
################## Defaults ##################
# Just in case user forgets to set something #
nextion_update_url: "http://github.com/Blackymas/NSPanel_HA_Blueprint/raw/main/custom_configuration/nspanel_eu.tft"
nextion_blank_url: "http://github.com/Blackymas/NSPanel_HA_Blueprint/raw/main/custom_configuration/nspanel_blank.tft"
##############################################
##### DON'T CHANGE THIS #####
upload_tft_chunk_size_max: "32768"
upload_tft_baud_rate: "0"
#############################
api:
services:
##### SERVICE TO UPDATE THE TFT FILE from URL #####
##### It will use the default url if url is empty or "default"
- service: upload_tft_url
variables:
url: string
then:
- lambda: |-
static const char *const TAG = "service.upload_tft_url";
ESP_LOGVV(TAG, "Starting...");
std::string clean_url = url;
// Convert to lowercase
std::transform(clean_url.begin(), clean_url.end(), clean_url.begin(),
[](unsigned char c){ return std::tolower(c); });
// Trim trailing spaces
auto endPos = clean_url.find_last_not_of(" \t");
if (std::string::npos != endPos) {
clean_url = clean_url.substr(0, endPos + 1);
}
if (clean_url.empty() or clean_url == "default") url = "${nextion_update_url}";
upload_tft->execute(url.c_str());
button:
##### UPDATE TFT DISPLAY #####
- id: tft_update
name: ${device_name} Update TFT display
platform: template
icon: mdi:file-sync
entity_category: config
on_press:
- lambda: |-
static const char *const TAG = "button.tft_update.on_press";
ESP_LOGD(TAG, "Update TFT display button pressed");
upload_tft->execute("${nextion_update_url}");
display:
- id: !extend disp1
tft_url: ${nextion_update_url}
exit_reparse_on_start: true
globals:
- id: baud_rate_original
type: uint
restore_value: false
initial_value: '115200'
- id: baud_rate_target
type: uint
restore_value: false
initial_value: ${upload_tft_baud_rate}
- id: tft_is_valid
type: bool
restore_value: false
initial_value: 'false'
- id: tft_upload_try
type: uint
restore_value: false
initial_value: '0'
script:
- id: nextion_uart_command
mode: queued
parameters:
command: string
then:
- lambda: |-
static const char *const TAG = "script.nextion_uart_command";
if (disp1->is_setup()) {
ESP_LOGD(TAG, "Sending `%s` directly to Nextion", command.c_str());
disp1->send_command_printf(command.c_str());
} else {
ESP_LOGD(TAG, "Sending `%s` directly to UART", command.c_str());
tf_uart->write_str(command.c_str());
const uint8_t to_send[3] = {0xFF, 0xFF, 0xFF};
tf_uart->write_array(to_send, sizeof(to_send));
}
App.feed_wdt();
- id: report_upload_progress
mode: restart
parameters:
message: string
then:
- lambda: |-
static const char *const TAG = "script.report_upload_progress";
ESP_LOGD(TAG, "%s", message.c_str());
if (id(tft_is_valid)) {
if (page_id->state != 26) {
open_upload_dialog->execute();
}
display_wrapped_text->execute("confirm.body", message.c_str(), 18);
disp1->set_backlight_brightness(1);
App.feed_wdt();
}
- id: nextion_upload
mode: single
then:
- lambda: |-
static const char *const TAG = "script.nextion_upload";
ESP_LOGD(TAG, "Waiting for empty UART and Nextion queues");
- wait_until:
condition:
- lambda: !lambda return (disp1->queue_size()<=0);
- lambda: !lambda return (tf_uart->available()<=0);
timeout: 10s
- delay: 2s
- lambda: |-
static const char *const TAG = "script.nextion_upload";
ESP_LOGD(TAG, "Starting TFT upload...");
if (disp1->upload_tft()) App.safe_reboot();
- id: open_upload_dialog
mode: restart
then:
- lambda: |-
static const char *const TAG = "script.open_upload_dialog";
ESP_LOGD(TAG, "Showing upload dialog page");
disp1->goto_page("confirm");
disp1->hide_component("bt_close");
disp1->hide_component("bt_accept");
disp1->hide_component("bt_clear");
disp1->hide_component("bt_close");
#ifdef ARDUINO
disp1->set_component_text_printf("confirm.title", "Upload TFT\\rArduino");
#elif defined(ESP_PLATFORM)
disp1->set_component_text_printf("confirm.title", "Upload TFT\\rESP-IDF");
#endif
page_id->update();
- id: upload_tft # I've changed this to use ESPHome commands to avoid the parallelism from lambdas
mode: single
parameters:
url: string
then:
# Make sure the screen is ON
- if:
condition:
- switch.is_off: screen_power
then:
- switch.turn_on: screen_power
- delay: 5s
# Then start the upload
- lambda: |-
static const char *const TAG = "script.upload_tft";
ESP_LOGD(TAG, "Starting...");
id(is_uploading_tft) = true;
nextion_status->execute();
uint32_t supported_baud_rates[] = {2400, 4800, 9600, 19200, 31250, 38400, 57600, 115200, 230400, 250000, 256000, 512000, 921600};
auto is_baud_rate_supported = [supported_baud_rates](uint32_t baud_rate_requested) -> bool {
size_t size = sizeof(supported_baud_rates) / sizeof(supported_baud_rates[0]);
for (size_t i = 0; i < size; ++i) {
if (supported_baud_rates[i] == baud_rate_requested) {
return true;
}
}
return false; // Return false if not found
};
// The upload process starts here
ESP_LOGD(TAG, "Starting the upload script");
// Detect baud rates to be used
id(baud_rate_original) = tf_uart->get_baud_rate();
if (!is_baud_rate_supported(id(baud_rate_original))) id(baud_rate_original) = 115200;
std::string upload_tft_baud_rate_string = "${upload_tft_baud_rate}";
id(baud_rate_target) = stoi(upload_tft_baud_rate_string);
if (!is_baud_rate_supported(id(baud_rate_target))) id(baud_rate_target) = id(baud_rate_original);
ESP_LOGD(TAG, " Target upload baud rate: %d bps", id(baud_rate_target));
ESP_LOGD(TAG, " Current baud rate: %d bps", tf_uart->get_baud_rate());
// Upload URL
ESP_LOGD(TAG, " Upload URL: %s", url.c_str());
disp1->set_tft_url(url.c_str());
nextion_uart_command->execute("bkcmd=3");
- lambda: if (id(tft_is_valid)) disp1->goto_page("home");
- delay: 2s
- script.execute: open_upload_dialog
- script.wait: open_upload_dialog
- lambda: page_id->update();
- wait_until:
condition:
- lambda: !lambda return (page_id->state == 26);
timeout: 2s
- script.execute:
id: report_upload_progress
message: "Set Nextion unavailable for blueprint calls"
- script.wait: report_upload_progress
- binary_sensor.template.publish:
id: nextion_init
state: false
- script.execute:
id: report_upload_progress
message: "Stopping other scripts"
- script.wait: report_upload_progress
- script.execute: stop_all
- script.wait: stop_all
- wait_until:
condition:
- lambda: !lambda return (!id(tft_is_valid));
timeout: 1s
### Try twice at the target baud rate
- script.execute: nextion_status
- script.wait: nextion_status
- script.execute:
id: report_upload_progress
message: "Setting baud rate"
- script.wait: report_upload_progress
- script.execute:
id: set_baud_rate
baud_rate: !lambda return id(baud_rate_target);
definitive: false
- script.wait: set_baud_rate
- delay: 2s
# Try #1
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
# Try #2
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
### Try twice at the original baud rate
- script.execute: nextion_status
- script.wait: nextion_status
- script.execute:
id: report_upload_progress
message: "Setting baud rate"
- script.wait: report_upload_progress
- script.execute:
id: set_baud_rate
baud_rate: !lambda return id(baud_rate_original);
definitive: false
- script.wait: set_baud_rate
- delay: 2s
# Try #3
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
# Try #4
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
### Try twice at the Nextion's default baud rate (115200bps)
- script.execute: nextion_status
- script.wait: nextion_status
- script.execute:
id: report_upload_progress
message: "Setting baud rate"
- script.wait: report_upload_progress
- script.execute:
id: set_baud_rate
baud_rate: 115200
definitive: false
- script.wait: set_baud_rate
- delay: 2s
# Try #5
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
# Try #6
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
### Exit reparse and try twice again
- script.execute: nextion_status
- script.wait: nextion_status
- script.execute:
id: report_upload_progress
message: "Exiting reparse mode"
- script.wait: report_upload_progress
- script.execute: exit_reparse
- script.wait: exit_reparse
- delay: 5s
- script.execute: nextion_status
- script.wait: nextion_status
- script.execute:
id: report_upload_progress
message: "Setting baud rate"
- script.wait: report_upload_progress
- script.execute:
id: set_baud_rate
baud_rate: 115200
definitive: false
- script.wait: set_baud_rate
- delay: 2s
# Try #7
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
# Try #8
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
### Then try twice again at 9600bps
- script.execute: nextion_status
- script.wait: nextion_status
- script.execute:
id: report_upload_progress
message: "Setting baud rate"
- script.wait: report_upload_progress
- script.execute:
id: set_baud_rate
baud_rate: 9600
definitive: false
- script.wait: set_baud_rate
- delay: 2s
# Try #9
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
# Try #10
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
### Restart Nextion and try twice again at default baud rate (115200bps)
- script.execute:
id: report_upload_progress
message: "Restarting Nextion display"
- script.wait: report_upload_progress
- wait_until:
condition:
- lambda: !lambda return (!id(tft_is_valid));
timeout: 3s
- switch.turn_off: screen_power
- delay: 2s
- switch.turn_on: screen_power
- delay: 5s
- script.execute: nextion_status
- script.wait: nextion_status
- script.execute:
id: report_upload_progress
message: "Setting baud rate"
- script.wait: report_upload_progress
- script.execute:
id: set_baud_rate
baud_rate: 115200
definitive: false
- script.wait: set_baud_rate
- delay: 2s
# Try #11
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
# Try #12
- script.execute: upload_tft_try
- script.wait: upload_tft_try
- delay: 5s
### All tries failed ###
- script.execute:
id: report_upload_progress
message: "TFT upload failed"
- script.wait: report_upload_progress
- wait_until:
condition:
- lambda: !lambda return (!id(tft_is_valid));
timeout: 5s
- script.execute:
id: report_upload_progress
message: "Turn off Nextion and restart ESPHome"
- script.wait: report_upload_progress
- wait_until:
condition:
- lambda: !lambda return (!id(tft_is_valid));
timeout: 5s
- switch.turn_off: screen_power
- delay: 2s
# Restart ESPHome
- lambda: !lambda App.safe_reboot();
### This code should never run
- delay: 2s
- lambda: |-
static const char *const TAG = "script.upload_tft";
ESP_LOGD(TAG, "Finishing...");
id(is_uploading_tft) = false;
screen_power->publish_state(true);
ESP_LOGE(TAG, "TFT upload finished unsuccessfully!");
- id: upload_tft_try
mode: single
then:
- logger.log: "Trying to upload TFT"
- lambda: !lambda id(tft_upload_try)++;
- lambda: |-
char update_msg[128];
sprintf(update_msg, "Try #%d at %d bps", id(tft_upload_try), tf_uart->get_baud_rate());
report_upload_progress->execute(update_msg);
- script.wait: report_upload_progress
- wait_until:
condition:
- lambda: !lambda return (!id(tft_is_valid));
timeout: 1s
- script.execute: nextion_upload
- script.wait: nextion_upload
- lambda: |-
char update_msg[128];
sprintf(update_msg, "Try #%d at %d bps failed!", id(tft_upload_try), tf_uart->get_baud_rate());
report_upload_progress->execute(update_msg);
- script.wait: report_upload_progress
sensor:
- id: !extend display_mode
on_value:
then:
lambda: |-
id(tft_is_valid) = (display_mode->state > 0 and display_mode->state < 4);