mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-28 05:06:32 +00:00
Merge branch 'development' into pre-release-12.3
This commit is contained in:
commit
3919668fc5
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,6 +25,7 @@ firmware.asm
|
|||||||
tasmota/tasmota.ino.cpp
|
tasmota/tasmota.ino.cpp
|
||||||
platformio_override.ini
|
platformio_override.ini
|
||||||
platformio_tasmota_cenv.ini
|
platformio_tasmota_cenv.ini
|
||||||
|
platformio_tasmota_user_env.ini
|
||||||
lib/libesp32/berry/generate/*
|
lib/libesp32/berry/generate/*
|
||||||
lib/libesp32/berry/berry
|
lib/libesp32/berry/berry
|
||||||
|
|
||||||
|
54
api/upload-tasmota.php
Normal file
54
api/upload-tasmota.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
// mkdir and chmod arduino folder to 777
|
||||||
|
//
|
||||||
|
//var_dump($_FILES);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GZIPs a file on disk (appending .gz to the name)
|
||||||
|
*
|
||||||
|
* From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
|
||||||
|
* Based on function by Kioob at:
|
||||||
|
* http://www.php.net/manual/en/function.gzwrite.php#34955
|
||||||
|
*
|
||||||
|
* @param string $source Path to file that should be compressed
|
||||||
|
* @param integer $level GZIP compression level (default: 9)
|
||||||
|
* @return string New filename (with .gz appended) if success, or false if operation fails
|
||||||
|
*/
|
||||||
|
function gzCompressFile($source, $level = 9){
|
||||||
|
$dest = $source . '.gz';
|
||||||
|
$mode = 'wb' . $level;
|
||||||
|
$error = false;
|
||||||
|
if ($fp_out = gzopen($dest, $mode)) {
|
||||||
|
if ($fp_in = fopen($source,'rb')) {
|
||||||
|
while (!feof($fp_in))
|
||||||
|
gzwrite($fp_out, fread($fp_in, 1024 * 512));
|
||||||
|
fclose($fp_in);
|
||||||
|
} else {
|
||||||
|
$error = true;
|
||||||
|
}
|
||||||
|
gzclose($fp_out);
|
||||||
|
} else {
|
||||||
|
$error = true;
|
||||||
|
}
|
||||||
|
if ($error)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return $dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
$image = basename($_FILES["file"]["name"]);
|
||||||
|
//$image = $_FILES["file"]["name"]; // Solves an issue where basename returns Array
|
||||||
|
$target_file = "tasmota/".$image;
|
||||||
|
$hostname = $_SERVER['SERVER_NAME'];
|
||||||
|
|
||||||
|
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
|
||||||
|
if (strpos($target_file, "tasmota32")) {
|
||||||
|
echo "The file $image has been uploaded to OTA server $hostname. \n";
|
||||||
|
} else {
|
||||||
|
gzCompressFile($target_file);
|
||||||
|
echo "The files $image and $image.gz have been uploaded to OTA server $hostname. \n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Sorry, there was an error uploading your file $image to OTA server $hostname. \n";
|
||||||
|
}
|
||||||
|
?>
|
@ -1,108 +1,75 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
#
|
|
||||||
# espupload by Theo Arends - 20170930
|
"""
|
||||||
#
|
espupload.py - for Tasmota
|
||||||
# Uploads binary file to OTA server
|
|
||||||
#
|
Copyright (C) 2022 Theo Arends
|
||||||
# Execute: espupload -u <Host_IP_address>:<Host_port>/<Host_path> -f <sketch.bin>
|
|
||||||
#
|
This program is free software: you can redistribute it and/or modify
|
||||||
# Needs pycurl
|
it under the terms of the GNU General Public License as published by
|
||||||
# - pip install pycurl
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Provides:
|
||||||
|
Uploads binary file to OTA server.
|
||||||
|
Usually initated from http-uploader.py
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
- Python
|
||||||
|
- pip install requests
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
./espupload -u <Host_IP_address>:<Host_port>/<Host_path> -f <sketch.bin>
|
||||||
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import optparse
|
import shutil
|
||||||
import logging
|
import argparse
|
||||||
import pycurl
|
import requests
|
||||||
|
|
||||||
HOST_URL = "domus1:80/api/upload-arduino.php"
|
#HOST_URL = "domus1:80/api/upload-arduino.php"
|
||||||
|
HOST_URL = "otaserver/ota/upload-tasmota.php"
|
||||||
def upload(hostUrl, filename):
|
|
||||||
tname = os.path.normpath(os.path.dirname(filename))
|
|
||||||
new_filename = tname + os.sep + os.path.basename(tname) + '.bin'
|
|
||||||
if os.path.exists(new_filename):
|
|
||||||
os.remove(new_filename)
|
|
||||||
os.rename(filename, new_filename)
|
|
||||||
|
|
||||||
url = 'http://%s' % (hostUrl)
|
|
||||||
c = pycurl.Curl()
|
|
||||||
c.setopt(c.URL, url)
|
|
||||||
# The "Expect:" is there to suppress "Expect: 100-continue" behaviour that is
|
|
||||||
# the default in libcurl when posting large bodies (and fails on lighttpd).
|
|
||||||
c.setopt(c.HTTPHEADER, ["Expect:"])
|
|
||||||
c.setopt(c.HTTPPOST, [('file', (c.FORM_FILE, new_filename, )), ])
|
|
||||||
c.perform()
|
|
||||||
c.close()
|
|
||||||
|
|
||||||
def parser():
|
|
||||||
parser = optparse.OptionParser(
|
|
||||||
usage = "%prog [options]",
|
|
||||||
description = "Upload image to over the air Host server for the esp8266 module with OTA support."
|
|
||||||
)
|
|
||||||
|
|
||||||
# destination ip and port
|
|
||||||
group = optparse.OptionGroup(parser, "Destination")
|
|
||||||
group.add_option("-u", "--host_url",
|
|
||||||
dest = "host_url",
|
|
||||||
action = "store",
|
|
||||||
help = "Host url",
|
|
||||||
default = HOST_URL
|
|
||||||
)
|
|
||||||
parser.add_option_group(group)
|
|
||||||
|
|
||||||
# image
|
|
||||||
group = optparse.OptionGroup(parser, "Image")
|
|
||||||
group.add_option("-f", "--file",
|
|
||||||
dest = "image",
|
|
||||||
help = "Image file.",
|
|
||||||
metavar = "FILE",
|
|
||||||
default = None
|
|
||||||
)
|
|
||||||
parser.add_option_group(group)
|
|
||||||
|
|
||||||
# output group
|
|
||||||
group = optparse.OptionGroup(parser, "Output")
|
|
||||||
group.add_option("-d", "--debug",
|
|
||||||
dest = "debug",
|
|
||||||
help = "Show debug output. And override loglevel with debug.",
|
|
||||||
action = "store_true",
|
|
||||||
default = False
|
|
||||||
)
|
|
||||||
parser.add_option_group(group)
|
|
||||||
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
|
|
||||||
return options
|
|
||||||
# end parser
|
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
# get options
|
# print(sys.argv[0:])
|
||||||
options = parser()
|
|
||||||
|
|
||||||
# adapt log level
|
# get arguments
|
||||||
loglevel = logging.WARNING
|
parser = argparse.ArgumentParser(
|
||||||
if (options.debug):
|
usage = "%prog [arguments]",
|
||||||
loglevel = logging.DEBUG
|
description = "Upload image to over the air Host server for the esp8266 or esp32 module with OTA support."
|
||||||
# end if
|
)
|
||||||
|
parser.add_argument("-u", "--host_url", dest = "host_url", action = "store", help = "Host url", default = HOST_URL)
|
||||||
# logging
|
parser.add_argument("-f", "--file", dest = "image", help = "Image file.", metavar = "FILE", default = None)
|
||||||
logging.basicConfig(level = loglevel, format = '%(asctime)-8s [%(levelname)s]: %(message)s', datefmt = '%H:%M:%S')
|
args = parser.parse_args()
|
||||||
|
|
||||||
logging.debug("Options: %s", str(options))
|
|
||||||
|
|
||||||
if (not options.host_url or not options.image):
|
|
||||||
logging.critical("Not enough arguments.")
|
|
||||||
|
|
||||||
|
if (not args.host_url or not args.image):
|
||||||
|
print("Not enough arguments.")
|
||||||
return 1
|
return 1
|
||||||
# end if
|
# end if
|
||||||
|
|
||||||
if not os.path.exists(options.image):
|
if not os.path.exists(args.image):
|
||||||
logging.critical('Sorry: the file %s does not exist', options.image)
|
print('Sorry: the file %s does not exist', args.image)
|
||||||
|
return 2
|
||||||
return 1
|
|
||||||
# end if
|
# end if
|
||||||
|
|
||||||
upload(options.host_url, options.image)
|
# copy firmware.bin to tasmota.bin or tasmota32.bin
|
||||||
|
tname = os.path.normpath(os.path.dirname(args.image))
|
||||||
|
new_filename = tname + os.sep + os.path.basename(tname) + '.bin'
|
||||||
|
shutil.copy2(args.image, new_filename)
|
||||||
|
|
||||||
|
url = 'http://%s' % (args.host_url)
|
||||||
|
files = {'file': open(new_filename, 'rb')}
|
||||||
|
req = requests.post(url, files=files)
|
||||||
|
print(req.text)
|
||||||
# end main
|
# end main
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -10,4 +10,4 @@ import os
|
|||||||
# pio >= 4.0.0
|
# pio >= 4.0.0
|
||||||
env.Replace(UPLOADER=os.path.join("pio-tools", "espupload.py"))
|
env.Replace(UPLOADER=os.path.join("pio-tools", "espupload.py"))
|
||||||
env.Replace(UPLOADERFLAGS="")
|
env.Replace(UPLOADERFLAGS="")
|
||||||
env.Replace(UPLOADCMD="$UPLOADER -u $UPLOAD_PORT -f $SOURCES")
|
env.Replace(UPLOADCMD="$PYTHONEXE $UPLOADER -u $UPLOAD_PORT -f $SOURCES")
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
;core_dir = .platformio
|
;core_dir = .platformio
|
||||||
; For unrelated compile errors with Windows it can help to shorten Platformio project path
|
; For unrelated compile errors with Windows it can help to shorten Platformio project path
|
||||||
;workspace_dir = c:\.pio
|
;workspace_dir = c:\.pio
|
||||||
|
;extra_configs = platformio_tasmota_user_env.ini
|
||||||
|
|
||||||
; *** Build/upload environment
|
; *** Build/upload environment
|
||||||
default_envs =
|
default_envs =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user