diff --git a/esphome/__main__.py b/esphome/__main__.py index d0d748a1ec..411108e554 100644 --- a/esphome/__main__.py +++ b/esphome/__main__.py @@ -1078,6 +1078,11 @@ def upload_program( port_type = get_port_type(host) + if port_type != PortType.NETWORK and getattr(args, "partition_table", False): + raise EsphomeError( + f"The option --partition-table can only be used for Over The Air updates." + ) + if port_type == PortType.BOOTSEL: exit_code = upload_using_picotool(config) # Return None for device - BOOTSEL can't be used for logging, @@ -1788,7 +1793,7 @@ def parse_args(argv): ) parser_upload.add_argument( "--partition-table", - help="Upload as partition table", + help="Upload as partition table (OTA).", action="store_true", ) diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index e5db0df462..91aee0cea6 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -230,8 +230,7 @@ void ESPHomeOTAComponent::handle_handshake_() { this->extended_proto_ = this->ota_features_ & CLIENT_FEATURE_SUPPORTS_EXTENDED_PROTOCOL; if (this->extended_proto_) { // If the client supports the extended protocol, send 2 bytes: response type and server feature flags - this->handshake_buf_[0] = - ota::OTA_RESPONSE_FEATURE_FLAGS; // indicates the following byte contains feature flags + this->handshake_buf_[0] = ota::OTA_RESPONSE_FEATURE_FLAGS; this->handshake_buf_[1] = SERVER_FEATURE_SUPPORTS_PARTITION_ACCESS; // supported if USE_OTA_PARTITIONS if (supports_compression) { this->handshake_buf_[1] |= SERVER_FEATURE_SUPPORTS_COMPRESSION; diff --git a/esphome/components/ota/ota_backend_esp_idf.cpp b/esphome/components/ota/ota_backend_esp_idf.cpp index 6a2afac978..2118234ae8 100644 --- a/esphome/components/ota/ota_backend_esp_idf.cpp +++ b/esphome/components/ota/ota_backend_esp_idf.cpp @@ -245,9 +245,10 @@ OTAResponseTypes IDFOTABackend::update_partition_table() { int app_partitions_found = 0; int new_app_part_index = -1; int new_app_part_index_with_copy = -1; - int new_otadata_part_index = -1; - bool otadata_overlap = true; - const esp_partition_t *app_copy_target_part{nullptr}; + const esp_partition_t *app_copy_target_part = nullptr; + bool otadata_partition_found = false; + bool otadata_overlap = false; + bool nvs_partition_found = false; for (int i = 0; i < num_partitions; i++) { // Iterate over new partition table const esp_partition_info_t *new_part = &new_partition_table[i]; if (new_part->type == ESP_PARTITION_TYPE_APP) { @@ -275,18 +276,23 @@ OTAResponseTypes IDFOTABackend::update_partition_table() { esp_partition_iterator_release(it); } } - } else if (new_part->type == ESP_PARTITION_TYPE_DATA && new_part->subtype == ESP_PARTITION_SUBTYPE_DATA_OTA) { - // Found the otadata partition in the new partition table - new_otadata_part_index = i; - otadata_overlap = check_overlap(running_app_offset, running_app_size, new_part->pos.offset, new_part->pos.size); + } else if (new_part->type == ESP_PARTITION_TYPE_DATA) { + if (new_part->subtype == ESP_PARTITION_SUBTYPE_DATA_OTA) { + // Found the otadata partition in the new partition table + otadata_partition_found = true; + otadata_overlap = check_overlap(running_app_offset, running_app_size, new_part->pos.offset, new_part->pos.size); + } else if (new_part->subtype == ESP_PARTITION_SUBTYPE_DATA_NVS && strcmp((char*)new_part->label, "nvs") == 0) { + // Found the nvs partition in the new partition table + nvs_partition_found = true; + } } } if (new_app_part_index == -1 && new_app_part_index_with_copy == -1) { ESP_LOGE(TAG, "No compatible app partition found in the new partition table"); return OTA_RESPONSE_ERROR_PARTITION_TABLE_VERIFY; } - if (app_partitions_found < 2 || new_otadata_part_index == -1) { - ESP_LOGE(TAG, "New partition table is missing the required app or otadata partitions"); + if (app_partitions_found < 2 || !otadata_partition_found || !nvs_partition_found) { + ESP_LOGE(TAG, "New partition table is missing the required app, otadata or nvs partitions"); return OTA_RESPONSE_ERROR_PARTITION_TABLE_VERIFY; } if (otadata_overlap) {