Enable nodelay for phase 1 of OTAv2

This commit is contained in:
Otto Winter 2018-11-13 15:31:14 +01:00
parent 01aaf14078
commit 39457f7b8c
No known key found for this signature in database
GPG key ID: DB66C0BE6013F97E
2 changed files with 15 additions and 10 deletions

View file

@ -16,11 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
platformio settings set check_platforms_interval 1000000 platformio settings set check_platforms_interval 1000000
COPY docker/platformio.ini /pio/platformio.ini COPY docker/platformio.ini /pio/platformio.ini
ARG ESPHOMELIB_VERSION="" RUN platformio run -d /pio; rm -rf /pio
RUN platformio run -d /pio; rm -rf /pio && \
/bin/bash -c "if [ ! -z '$ESPHOMELIB_VERSION']; then \
platformio lib -g install '${ESPHOMELIB_VERSION}'; \
fi"
COPY . . COPY . .

View file

@ -3,7 +3,6 @@ import logging
import random import random
import socket import socket
import sys import sys
import time
from esphomeyaml.core import ESPHomeYAMLError from esphomeyaml.core import ESPHomeYAMLError
@ -95,7 +94,8 @@ def check_error(data, expect):
if dat == RESPONSE_ERROR_MAGIC: if dat == RESPONSE_ERROR_MAGIC:
raise OTAError("Error: Invalid magic byte") raise OTAError("Error: Invalid magic byte")
if dat == RESPONSE_ERROR_UPDATE_PREPARE: if dat == RESPONSE_ERROR_UPDATE_PREPARE:
raise OTAError("Error: Couldn't prepare flash memory for update. Is the binary too big?") raise OTAError("Error: Couldn't prepare flash memory for update. Is the binary too big? "
"Please try restarting the ESP.")
if dat == RESPONSE_ERROR_AUTH_INVALID: if dat == RESPONSE_ERROR_AUTH_INVALID:
raise OTAError("Error: Authentication invalid. Is the password correct?") raise OTAError("Error: Authentication invalid. Is the password correct?")
if dat == RESPONSE_ERROR_WRITING_FLASH: if dat == RESPONSE_ERROR_WRITING_FLASH:
@ -121,7 +121,7 @@ def send_check(sock, data, msg):
data = ''.join([chr(x) for x in data]) data = ''.join([chr(x) for x in data])
elif isinstance(data, int): elif isinstance(data, int):
data = chr(data) data = chr(data)
sock.send(data) sock.sendall(data)
except socket.error as err: except socket.error as err:
raise OTAError("Error sending {}: {}".format(msg, err)) raise OTAError("Error sending {}: {}".format(msg, err))
@ -133,6 +133,8 @@ def perform_ota(sock, password, file_handle, filename):
file_handle.seek(0) file_handle.seek(0)
_LOGGER.debug("MD5 of binary is %s", file_md5) _LOGGER.debug("MD5 of binary is %s", file_md5)
# Enable nodelay, we need it for phase 1
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
send_check(sock, MAGIC_BYTES, 'magic bytes') send_check(sock, MAGIC_BYTES, 'magic bytes')
_, version = receive_exactly(sock, 2, 'version', RESPONSE_OK) _, version = receive_exactly(sock, 2, 'version', RESPONSE_OK)
@ -179,7 +181,12 @@ def perform_ota(sock, password, file_handle, filename):
send_check(sock, file_md5, 'file checksum') send_check(sock, file_md5, 'file checksum')
receive_exactly(sock, 1, 'file checksum', RESPONSE_BIN_MD5_OK) receive_exactly(sock, 1, 'file checksum', RESPONSE_BIN_MD5_OK)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 4096) # Disable nodelay for transfer
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 0)
# Limit send buffer (usually around 100kB) in order to have progress bar
# show the actual progress
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 8192)
offset = 0 offset = 0
update_progress(0.0) update_progress(0.0)
while True: while True:
@ -196,13 +203,15 @@ def perform_ota(sock, password, file_handle, filename):
update_progress(offset / float(file_size)) update_progress(offset / float(file_size))
# Enable nodelay for last checks
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
sys.stderr.write('\n') sys.stderr.write('\n')
_LOGGER.info("Waiting for result...") _LOGGER.info("Waiting for result...")
receive_exactly(sock, 1, 'receive OK', RESPONSE_RECEIVE_OK) receive_exactly(sock, 1, 'receive OK', RESPONSE_RECEIVE_OK)
receive_exactly(sock, 1, 'Update end', RESPONSE_UPDATE_END_OK) receive_exactly(sock, 1, 'Update end', RESPONSE_UPDATE_END_OK)
send_check(sock, RESPONSE_OK, 'end acknowledgement') send_check(sock, RESPONSE_OK, 'end acknowledgement')
time.sleep(0.25)
_LOGGER.info("OTA successful") _LOGGER.info("OTA successful")