mirror of
https://github.com/esphome/esphome.git
synced 2026-09-21 03:58:41 +00:00
[esphome.ota] Compress OTA uploads with deflate on platforms without gzip support
ESP32, RP2040, LibreTiny and host could not receive a compressed image; only the ESP8266 can, because its bootloader inflates a gzip file at reboot. This inflates a raw deflate stream on the fly through a 4 KB ring window that also serves as the output buffer, so the device never holds the whole image. The CLI offers a new client feature bit; a device whose backend has no gzip support and has the inflater compiled answers with a new server bit once the session memory is in hand, then the CLI sends a 4 KB window deflate stream and the MD5 of the inflated image. On allocation failure the device declines the bit and the upload stays uncompressed. Old CLIs and old devices never set the bits, so both directions stay compatible; the ESP8266 keeps its gzip path and the CLI prefers gzip when a device offers both. The decoder is uzlib's tinflate.c (zlib licence) trimmed to raw deflate.
This commit is contained in:
@@ -180,10 +180,14 @@ async def test_host_ota_self_update(
|
||||
)
|
||||
)
|
||||
staged = asyncio.Event()
|
||||
inflated = asyncio.Event()
|
||||
|
||||
def on_log(line: str) -> None:
|
||||
if "OTA staged at" in line:
|
||||
staged.set()
|
||||
# The host backend has no gzip support, so the upload negotiates deflate
|
||||
if "Inflated " in line:
|
||||
inflated.set()
|
||||
dev.on_log(line)
|
||||
|
||||
async with run_binary(dev.binary_path, line_callback=on_log) as (proc, _lines):
|
||||
@@ -195,6 +199,7 @@ async def test_host_ota_self_update(
|
||||
|
||||
await dev.ota(None, None, "espota2 reported failure")
|
||||
assert staged.is_set()
|
||||
assert inflated.is_set(), "upload was not deflate compressed"
|
||||
|
||||
async with wait_and_connect_api_client(port=dev.api_port) as client:
|
||||
info_after = await client.device_info()
|
||||
|
||||
Reference in New Issue
Block a user