3 #ifdef USE_NEXTION_TFT_UPLOAD 12 #include <esp_heap_caps.h> 17 static const char *
const TAG =
"nextion_upload";
26 range_end = 16384 - 1;
35 #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0) 36 http->setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
37 #elif USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0) 38 http->setFollowRedirects(
true);
40 #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0) 41 http->setRedirectLimit(3);
45 char range_header[64];
46 sprintf(range_header,
"bytes=%d-%d", range_start, range_end);
48 ESP_LOGD(TAG,
"Requesting range: %s", range_header);
52 bool begin_status =
false;
55 begin_status = http->begin(this->
tft_url_.c_str());
63 ESP_LOGD(TAG,
"upload_by_chunks_: connection failed");
67 http->addHeader(
"Range", range_header);
70 if (code == 200 || code == 206) {
73 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s; Error: %s, retries(%d/5)", this->
tft_url_.c_str(),
74 HTTPClient::errorToString(code).c_str(), tries);
84 std::string recv_string;
87 int range = range_end - range_start;
89 while (sent < range) {
90 size = http->getStreamPtr()->available();
96 int c = http->getStreamPtr()->readBytes(
101 ESP_LOGN(TAG,
"this->content_length_ %d sent %d", this->
content_length_, sent);
102 for (
int i = 0; i < range; i += 4096) {
105 ESP_LOGN(TAG,
"this->content_length_ %d range %d range_end %d range_start %d", this->
content_length_, range,
106 range_end, range_start);
115 if (recv_string[0] == 0x08) {
117 for (
int i = 0; i < 4; ++i) {
118 result +=
static_cast<uint8_t
>(recv_string[i + 1]) << (8 * i);
121 ESP_LOGD(TAG,
"Nextion reported new range %d", result);
128 return range_end + 1;
133 ESP_LOGD(TAG,
"Currently updating");
138 ESP_LOGD(TAG,
"network is not connected");
145 http.setTimeout(15000);
146 bool begin_status =
false;
148 begin_status = http.begin(this->
tft_url_.c_str());
151 #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0) 152 http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
153 #elif USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0) 154 http.setFollowRedirects(
true);
156 #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 6, 0) 157 http.setRedirectLimit(3);
164 ESP_LOGD(TAG,
"connection failed");
169 ESP_LOGD(TAG,
"Connected");
172 http.addHeader(
"Range",
"bytes=0-255");
173 const char *header_names[] = {
"Content-Range"};
174 http.collectHeaders(header_names, 1);
175 ESP_LOGD(TAG,
"Requesting URL: %s", this->
tft_url_.c_str());
180 int code = http.GET();
184 while (code != 200 && code != 206 && tries <= 5) {
185 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s; Error: %s, retrying (%d/5)", this->
tft_url_.c_str(),
186 HTTPClient::errorToString(code).c_str(), tries);
194 if ((code != 200 && code != 206) || tries > 5) {
198 String content_range_string = http.header(
"Content-Range");
199 content_range_string.remove(0, 12);
205 ESP_LOGE(TAG,
"Failed to get file size");
209 ESP_LOGD(TAG,
"Updating Nextion %s...", this->
device_model_.c_str());
234 std::string response;
235 ESP_LOGD(TAG,
"Waiting for upgrade response");
239 ESP_LOGD(TAG,
"Upgrade response is %s %zu", response.c_str(), response.length());
241 for (
size_t i = 0; i < response.length(); i++) {
242 ESP_LOGD(TAG,
"Available %d : 0x%02X", i, response[i]);
245 if (response.find(0x05) != std::string::npos) {
246 ESP_LOGD(TAG,
"preparation for tft update done");
248 ESP_LOGD(TAG,
"preparation for tft update failed %d \"%s\"", response[0], response.c_str());
254 uint32_t chunk_size = 8192;
255 if (heap_caps_get_free_size(MALLOC_CAP_SPIRAM) > 0) {
258 if (ESP.getFreeHeap() > 40960) {
259 int chunk = int((ESP.getFreeHeap() - 32768) / 4096);
260 chunk_size = chunk * 4096;
261 chunk_size = chunk_size > 65536 ? 65536 : chunk_size;
262 }
else if (ESP.getFreeHeap() < 10240) {
268 uint32_t chunk_size = ESP.getFreeHeap() < 10240 ? 4096 : 8192;
274 ESP_LOGD(TAG,
"Allocating buffer size %d, Heap size is %u", chunk_size, ESP.getFreeHeap());
276 if (this->transfer_buffer_ ==
nullptr) {
277 ESP_LOGD(TAG,
"Could not allocate buffer size: %d trying 4096 instead", chunk_size);
279 ESP_LOGD(TAG,
"Allocating %d buffer", chunk_size);
280 this->transfer_buffer_ = allocator.
allocate(chunk_size);
282 if (!this->transfer_buffer_)
290 ESP_LOGD(TAG,
"Updating tft from \"%s\" with a file size of %d using %zu chunksize, Heap Size %d",
297 ESP_LOGD(TAG,
"Error updating Nextion!");
302 ESP_LOGD(TAG,
"Heap Size %d, Bytes left %d", ESP.getFreeHeap(), this->
content_length_);
304 ESP_LOGD(TAG,
"Successfully updated Nextion!");
310 ESP_LOGD(TAG,
"Restarting Nextion");
313 ESP_LOGD(TAG,
"Restarting esphome");
319 if (this->
tft_url_.compare(0, 6,
"https:") == 0) {
339 #endif // USE_NEXTION_TFT_UPLOAD uint32_t get_baud_rate() const
void write_array(const uint8_t *data, size_t len)
void upload_tft()
Upload the tft file and softreset the Nextion.
WiFiClient * get_wifi_client_()
An STL allocator that uses SPI RAM.
void deallocate(T *p, size_t n)
int upload_by_chunks_(HTTPClient *http, int range_start)
bool send_command_(const std::string &command)
Manually send a raw command to the display and don't wait for an acknowledgement packet.
BearSSL::WiFiClientSecure * wifi_client_secure_
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
bool read_byte(uint8_t *data)
Application App
Global storage of Application pointer - only one Application can exist.
uint8_t * transfer_buffer_
void set_backlight_brightness(float brightness)
Set the brightness of the backlight.
std::string device_model_
void soft_reset()
Softreset the Nextion.
bool upload_first_chunk_sent_
WiFiClient * wifi_client_
Implementation of SPI Controller mode.
size_t transfer_buffer_size_
uint16_t recv_ret_string_(std::string &response, uint32_t timeout, bool recv_flag)
int content_length_
will request chunk_size chunks from the web server and send each to the nextion
void IRAM_ATTR HOT delay(uint32_t ms)