Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosIntel Devs: Smart AI Edge Solutions - 0 Introduction | Intel Software(22.09.2026 um 23:48 Uhr)
Windows Tipps & SecurityGoogles gibt Chrome 154 frei und schließt über 100 Lücken(23.09.2026 um 09:11 Uhr)
Windows Tipps & SecurityKlangerlebnis & Sicherheit im Vonovia Ruhrstadion(23.09.2026 um 08:45 Uhr)
Unix & Linux ServerLocal AI Jargon Quiz: Do You Know All These Buzzwords?(23.09.2026 um 08:38 Uhr)
Sichere ProgrammierungNeu von AWS: Weniger Kontextpflege für selbst gebaute KI-Agenten(23.09.2026 um 09:52 Uhr)
Sichere ProgrammierungLINQ GroupBy: The Operator Everyone Uses Wrong(23.09.2026 um 09:41 Uhr)
Sichere ProgrammierungIT Heard About the Acquisition Nine Days Before It Closed(23.09.2026 um 09:45 Uhr)
YouTube Security VideosIntel Devs: Smart AI Edge Solutions - 0 Introduction | Intel Software(22.09.2026 um 23:48 Uhr)
Windows Tipps & SecurityGoogles gibt Chrome 154 frei und schließt über 100 Lücken(23.09.2026 um 09:11 Uhr)
Windows Tipps & SecurityKlangerlebnis & Sicherheit im Vonovia Ruhrstadion(23.09.2026 um 08:45 Uhr)
Unix & Linux ServerLocal AI Jargon Quiz: Do You Know All These Buzzwords?(23.09.2026 um 08:38 Uhr)
Sichere ProgrammierungNeu von AWS: Weniger Kontextpflege für selbst gebaute KI-Agenten(23.09.2026 um 09:52 Uhr)
Sichere ProgrammierungLINQ GroupBy: The Operator Everyone Uses Wrong(23.09.2026 um 09:41 Uhr)
Sichere ProgrammierungIT Heard About the Acquisition Nine Days Before It Closed(23.09.2026 um 09:45 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

OTA Python updates with ESP-Now

This is the third article in a series about using ESP-Now to implement an ESP32-based master-slave network. Part one describes the main network comms class and part two describes how to follow the system router when it channel-hops. In…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

This is the third article in a series about using ESP-Now to implement an ESP32-based master-slave network. Part one describes the main network comms class and part two describes how to follow the system router when it channel-hops. In this final article I'll describe an implementation of over-the-air (OTA) updates to the Python and other files held on the devices.



In part one of this series, when a message is received it is handed to a message handler, which carries out the needed action(s) and returns a result. The following is that message handler. Most of it is directly applicable to any similar application, since there are only so many things a network slave is able to do.




import asyncio,machine,os
from binascii import unhexlify
from files import readFile,writeFile,renameFile,deleteFile,createDirectory

class Handler():

def __init__(self,config):
self.config=config
config.setHandler(self)
self.relay=config.getRelay()
self.saveError=False

def handleMessage(self,msg):
# print('Handler:',msg)
bleValues=self.config.getBLEValues()
response=f'OK {self.config.getUptime()} :{bleValues}'
if msg=='uptime':
pass
elif msg == 'on':
response=f'{response} ON' if self.relay.on() else 'No relay'
elif msg == 'off':
response=f'{response} OFF' if self.relay.off() else 'No relay'
elif msg == 'relay':
try:
response=f'OK {self.relay.getState()}'
except:
response='No relay'
elif msg=='reset':
self.config.reset()
response='OK'
elif msg == 'ipaddr':
response=f'OK {self.config.getIPAddr()}'
elif msg=='channel':
response=f'OK {self.config.getChannel()}'
elif msg[0:8]=='channel=':
channel=msg[8:]
self.config.setChannel(channel)
response=f'OK {channel}'
elif msg[0:7]=='environ':
environ=msg[8:]
self.config.setEnviron(environ)
response=f'OK {environ}'
elif msg=='temp':
response=f'OK {self.config.getTemperature()}'
elif msg=='pause':
self.config.pause()
response=f'OK paused'
elif msg=='resume':
self.config.resume()
response=f'OK resumed'
elif msg[0:6]=='delete':
file=msg[7:]
response='OK' if deleteFile(file) else 'Fail'
elif msg[0:4]=='part':
# Format is part:{n},text:{text}
part=None
text=None
items=msg.split(',')
for item in items:
item=item.split(':')
label=item[0]
value=item[1]
if label=='part': part=int(value)
elif label=='text': text=value
if part!=None and text!=None:
text=text.encode('utf-8')
text=unhexlify(text)
text=text.decode('utf-8')
if part==0:
self.buffer=[]
self.pp=0
self.saveError=False
else:
if self.saveError:
return 'Save error'
else:
if part==self.pp+1:
self.pp=part
else:
self.saveError=True
return f'Sequence error: {part} {self.pp+1}'
self.buffer.append(text)
response=f'{part} {str(len(text))}'
elif msg[0:4]=='save':
if len(self.buffer[0])>0:
fname=msg[5:]
tname=f't-{fname}'
print(f'Save {tname}')
size=0
f = open(tname,'w')
for n in range(0, len(self.buffer)):
f.write(self.buffer[n])
size+= len(self.buffer[n])
f.close()
# Check the file against the buffer
if self.checkFile(self.buffer, tname):
response=str(size)
print('File saved')
else: response='Bad save'
else: response='No data'
text=None
elif msg=='update':
for tname in os.listdir('.'):
if tname[0:2]=='t-':
fname=tname[2:]
print(f'Update {fname}')
deleteFile(fname)
renameFile(tname,fname)
response='OK'
elif msg[0:5]=='mkdir':
path=msg[6:]
print(f'mkdir {path}')
response='OK' if createDirectory(path) else 'Fail'
else: response=f'Unknown message: {msg}'
# print('Handler response:',response)
return response

def checkFile(self, buf, file):
try:
with open(file, 'r') as f:
i = 0 # index in lst
pos = 0 # position in current list item
while True:
c = f.read(1)
if not c:
# End of file: check if we've also finished the list
while i < len(buf) and pos == len(buf[i]):
i += 1
pos = 0
return i == len(buf)
if i >= len(buf) or pos >= len(buf[i]) or c != buf[i][pos]:
return False
pos += 1
if pos == len(buf[i]):
i += 1
pos = 0
except OSError:
return False









__init__()



The system makes extensive use of a Config class, which holds all the system-specific configuration data such as which I/O pins do what. It also acts as a central message interchange, with functions that either return an object that has the required functionality or call the objects themselves, avoiding the need for every class to know about all the others. So in this Handler class, the relay object supplied by Config is a class that has the ability to turn the relay on and off and to return the current relay state.






handleMessage()



This is where most of the work is done. The function handles a set of commands, most of which should be fairly obvious, though some will be more relevant than others. For example, elsewhere in the code there's a Bluetooth (BLE) module that collects occasional transmissions from specific devices and for some message types appends these values to the string that is returned to the caller. In my system these are temperature values, but not everyone will want this feature.



The most interesting part of this is the OTA file updater, which works like this. The maximum size of an ESP-Now data packet is something over 200 bytes, so few Python scripts can be transferred in a single message. I chose to send 100 bytes at a time, with the text data encoded as hex values. The file is sent as a series of messages, each containing 100 bytes, and the messages are prefixed by the command part and a part number starting with zero. The function splits up the packet to extract the part number and the data itself. If the part number matches what was expected, the text is added to a list, otherwise the function returns an error. For a successfully received part, the function returns the part number and the size of the data, which the sender can use to verify that it has been received successfully.



When all the parts have been sent, the list can be saved to a temporary file. This is done by the save command.






checkFile(()



Now we need to check the data has not been corrupted. This function reads the file back, one character at a time, and compares it with the contents of the list. If no errors are found, the new file can be assumed to be good.



However, a problem comes when several Python files all need to be updated together. In many cases, if only some of the files are updated and then an error occurs or for some other reason the update stops, there will be a mismatch between the various parts and the program will not run after the next reboot. So rather than update files one by one they should instead be done as a batch. Only when all of the files have been saved and checked is it then safe to rename the entire batch. This is done by the update command.



In a practical implementation, when an error is discovered and reported back to the sender, the entire save can be retried. Although for the most part OTA updates proceed without a hitch, in some cases, particularly where the signal strength isn't great or suffers from interference, it can take several attempts to transfer a large file. I allow up to 10 retries before abandoning the save.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten OTA Python updates with ESP-Now

Thematisch verwandte Begriffe: Python, updates, with, ESPNow · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-96258 | A vulnerability has been found in onSite internet GmbH Auktion NG Auktio…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick