As the title says, since the files are replaced as they are downloaded, the software can get into an inconsistent state.
I suggest downloading all the files to a temporary folder and then replacing them once all of them have been downloaded.
This should significantly reduce the risk of corruption if the connection is not reliable enough.
Here is how I implemented it in my version:
# def ota_update(host, project, filenames, use_version_prefix=True, user=None, passwd=None, hard_reset_device=True, soft_reset_device=False, timeout=5) -> None: # REMOVED
def ota_update(host, project, filenames, tempdir, *,use_version_prefix=True, user=None, passwd=None, hard_reset_device=True, soft_reset_device=False, timeout=5) -> None: # ADDED
all_files_found = True
auth = generate_auth(user, passwd)
prefix_or_path_separator = '_' if use_version_prefix else '/'
try:
version_changed, remote_version = check_version(host, project, auth=auth, timeout=timeout)
if version_changed:
try: uos.mkdir(tempdir) # ADDED
except: pass # ADDED
for filename in filenames:
if auth:
response = urequests.get(f'{host}/{project}/{remote_version}{prefix_or_path_separator}{filename}', headers={'Authorization': f'Basic {auth}'}, timeout=timeout)
else:
response = urequests.get(f'{host}/{project}/{remote_version}{prefix_or_path_separator}{filename}', timeout=timeout)
response_status_code = response.status_code
response_text = response.text
response.close()
if response_status_code != 200:
print(f'Remote source file {host}/{project}/{remote_version}{prefix_or_path_separator}{filename} not found')
all_files_found = False
continue
# with open(filename, 'w') as source_file: # REMOVED
with open(f"{tempdir}/{filename}", 'w') as source_file: # ADDED
source_file.write(response_text) # ADDED
if all_files_found:
for filename in filenames: # ADDED
temp_filename = f"{tempdir}/{filename}" # ADDED
with open(temp_filename,"r") as temp, open(filename,"w") as file: # ADDED
file.write(temp.read()) # ADDED
uos.remove(temp_filename) # ADDED
uos.rmdir(tempdir) # ADDED
with open('version', 'w') as current_version_file:
current_version_file.write(remote_version)
if soft_reset_device:
print('Soft-resetting device...')
machine.soft_reset()
if hard_reset_device:
print('Hard-resetting device...')
machine.reset()
except Exception as ex:
print(f'Something went wrong: {ex}')
As the title says, since the files are replaced as they are downloaded, the software can get into an inconsistent state. I suggest downloading all the files to a temporary folder and then replacing them once all of them have been downloaded. This should significantly reduce the risk of corruption if the connection is not reliable enough.
Here is how I implemented it in my version: