Comments (19)
I would also like to have this feature implemented... It was sooo easy to use it before Asynwebserver...
from elegantota.
For me it works like this with the extra script, note the URL:
extra_scripts = platformio_upload.py
upload_protocol = custom
upload_url = http://192.168.123.123/ota/upload
Edit: Wait, no. It just gives an "OK" but the firmware isn't written 😕
from elegantota.
ive had the same problem. For me it helped to use these platformio.ini configurations
extra_scripts = platformio_upload.py
upload_protocol = custom
upload_url = http://[IP or hostname] ; eg http://192.168.178.20
and i had to modify the platformio_upload.py file, and excuse me, i haven't been programming very long. It's not pretty but it works for me.
It looks like something was changed in the ElegantOTA library because of the GET and POST requests, so the script encounters problems. So I didn't do more than mimic the behavior of the browser. And thats it:
# Allows PlatformIO to upload directly to ElegantOTA
#
# To use:
# - copy this script into the same folder as your platformio.ini
# - set the following for your project in platformio.ini:
#
# extra_scripts = platformio_upload.py
# upload_protocol = custom
# upload_url = <your upload URL>
#
# An example of an upload URL:
# upload_URL = http://192.168.1.123
import requests
import hashlib
from urllib.parse import urlparse
Import("env")
try:
from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
from tqdm import tqdm
except ImportError:
env.Execute("$PYTHONEXE -m pip install requests_toolbelt")
env.Execute("$PYTHONEXE -m pip install tqdm")
from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
from tqdm import tqdm
def on_upload(source, target, env):
firmware_path = str(source[0])
upload_url = env.GetProjectOption('upload_url')
with open(firmware_path, 'rb') as firmware:
md5 = hashlib.md5(firmware.read()).hexdigest()
parsed_url = urlparse(upload_url)
host_ip = parsed_url.netloc
# Führe die GET-Anfrage aus
start_url = f"{upload_url}/ota/start?mode=fr&hash={md5}"
# start_response = requests.get(start_url)
start_headers = {
'Host': host_ip,
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0',
'Accept': '*/*',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Referer': f'{upload_url}/update',
'Connection': 'keep-alive'
}
start_response = requests.get(start_url, headers=start_headers)
# Drucke Anfrage- und Antwortkopfzeilen für die GET-Anfrage
# print("GET Anfragekopfzeilen:", start_response.request.headers)
# print("GET Antwortkopfzeilen:", start_response.headers)
if start_response.status_code != 200:
print("Start-Request fehlgeschlagen " + str(start_response.status_code))
return
firmware.seek(0)
encoder = MultipartEncoder(fields={
'MD5': md5,
'firmware': ('firmware', firmware, 'application/octet-stream')}
)
bar = tqdm(desc='Upload Progress',
total=encoder.len,
dynamic_ncols=True,
unit='B',
unit_scale=True,
unit_divisor=1024
)
monitor = MultipartEncoderMonitor(encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n))
post_headers = {
'Host': host_ip,
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0',
'Accept': '*/*',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Referer': f'{upload_url}/update',
'Connection': 'keep-alive',
'Content-Type': monitor.content_type,
'Content-Length': str(monitor.len),
'Origin': f'{upload_url}'
}
response = requests.post(f"{upload_url}/ota/upload", data=monitor, headers=post_headers)
# Drucke Anfrage- und Antwortkopfzeilen für die POST-Anfrage
# print("POST Anfragekopfzeilen:", response.request.headers)
# print("POST Antwortkopfzeilen:", response.headers)
bar.close()
if response.status_code != 200:
print("Upload fehlgeschlagen")
else:
print("Upload erfolgreich", response.text)
env.Replace(UPLOADCMD=on_upload)
from elegantota.
@mindsuru The internal API of ElegantOTA indeed got changed to provide a much better & stable experience. Your fix looks promising! It was a community PR that added it in past that's why it wasn't updated with V3.
If you don't mind, can you open a PR that fixes the platformio_upload.py
script?
from elegantota.
Thanks,
and okay, I'll give it a try. I'm not that familiar with GitHub yet, but it should work out somehow. I'll read up on it.
I changed the python file slightly. Now you can use it with the old configuration in your platformio.ini
from elegantota.
@mindsuru For me the version you have here does not work. It gives the following error, then quits:
....
Uploading .pio\build\esp32\firmware.bin
Start-Request fehlgeschlagen 401
Seems to me that it cannot find the OTA page... This is the relevant part of my platformio.ini
:
extra_scripts =
pre:../../scripts/preIncrementBuildNumber.py
platformio_upload.py
upload_protocol = custom
upload_url = http://192.168.123.137
As you can see I have an extra script running, but I don't suppose that would be an issue as the behavior is that same when I remove it.
If I can help testing any new version of your script, don't hold back :)
from elegantota.
@mindsuru @ayushsharma82 When can we expect PR and merge?
from elegantota.
@viktak is your device reachable with this ip you‘ve choosen in your platformio.ini file?
from elegantota.
@mindsuru @ayushsharma82 When can we expect PR and merge?
It has been merged but yet to be released.
from elegantota.
@viktak is your device reachable with this ip you‘ve choosen in your platformio.ini file?
I guess he's using authentication that's why response code was '401' which means 'Unauthorized'. The script might need adjustments to work with authentication enabled.
from elegantota.
Yes, the device is reachable, all other functions of the asyncwebserver and elegantota are all working.
from elegantota.
@viktak is your device reachable with this ip you‘ve choosen in your platformio.ini file?
I guess he's using authentication that's why response code was '401' which means 'Unauthorized'. The script might need adjustments to work with authentication enabled.
Yessss, I definitely use authentication.
But the authentication is added on a per page basis, i.e. for each of the protected pages (not all of them are) I add this line:
if(!request->authenticate(ADMIN_USERNAME, appSettings.adminPassword))
return request->requestAuthentication();
So the pages that don't use authentication should work just fine. In fact, those pages of mine that do not require authentication work fine.
from elegantota.
Okay good to know. I will have a look on it. But unfortunatly i‘m ill right now. It may take a bit.
from elegantota.
Okay good to know. I will have a look on it. But unfortunatly i‘m ill right now. It may take a bit.
Get well soon, that's the priority!
from elegantota.
i think thats it. now both upload methods should work. regardless of whether you use the encrypted or non-encrypted method.
i opened a pull request for that change
from elegantota.
@mindsuru Yes, it is now working.
I just checked the version in the pull request, and at first it failed with a message that there was no username defined, but once I defined all the credentials the upload worked flawlessly.
Here are all the relevant additions in platformio.ini
I had to make it work:
extra_scripts =
platformio_upload.py
build_flags =
'-DELEGANTOTA_USE_ASYNC_WEBSERVER = 1'
lib_deps =
ottowinter/ESPAsyncWebServer-esphome @ ^3.1.0
esphome/AsyncTCP-esphome @ ^2.0.1
ayushsharma82/ElegantOTA @ ^3.1.0
upload_protocol = custom
upload_url = http://w.x.y.z
username = username
password = password
from elegantota.
One more request, perhaps it is possible to rename the expected variables from this:
upload_url = http://w.x.y.z
username = username
password = password
to this:
custom_upload_url = http://w.x.y.z
custom_username = username
custom_password = password
This is to get rid of those pesky PlatformIO warning:
Warning! Ignore unknown configuration option `upload_url` in section [env:esp32]
Warning! Ignore unknown configuration option `username` in section [env:esp32]
Warning! Ignore unknown configuration option `password` in section [env:esp32]
from elegantota.
sure and thanks for this information
from elegantota.
I have been using the updated script for a couple of months now on various projects. Here are my observations:
- Doing an update from the /update page works all the time, every time, be it the firmware or the spiffs.
- From PlatformIO, uploading the code works perfectly all the time, every time.
- However, uploading the spiffs from PlatformIO is a hit and miss for me, and I haven't figured out what the problem might be. I haven't even noticed a pattern, to be honest. Sometimes it works, sometimes it fails during upload, sometimes it goes fine to 100%, then it says:
Upload Progress: 100%|██████████| 1.50M/1.50M [00:07<00:00, 205kB/s]
Upload faild.
Server response: Failed to write chunked data to free space
or it complains about the magic byte (I can't remember the exact message...)
4. Some typos in the console: "faild" *3 and "successfull" *1
from elegantota.
Related Issues (20)
- PLEASE RELEASE AND PUBLISH 3.1.1 😄 HOT 2
- ElegantOTA over ethernet on ESP32 HOT 1
- Save / load settings variables using LITTLEFS HOT 1
- firmware update protection? HOT 1
- no matching function for call to 'ElegantOTAClass::begin(AsyncWebServer*)' HOT 3
- Update successful, but no reboot HOT 1
- Error in platformio_upload.py instructions
- No ELEGANT OTA lite web interface appears HOT 1
- ElegantOTA crashed on ESP32 NINA-W102 EVK
- Documentation fails to mention how to access portal HOT 2
- platformio_upload.py with authentication not working HOT 2
- no <wifi.h> & <update.h> files found. HOT 3
- I want to purchase The Elegant ETA Pro but I have Questions. HOT 1
- adding a check for flash-organisation / flash-sizes
- Async Demo will not compile HOT 2
- possible to use OTA via PlattformAIO? HOT 2
- OTA crash when trying to upload HOT 2
- ElegantOTA and WebThings (Arduino) + ESP32-S3
- Brakes at ElegantOTA.cpp -> Line 141
- Smartphone browser crash when selecting a path containing a data type.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from elegantota.