Merge pull request #2049 from proddy/dev

package updates, python formatting
This commit is contained in:
Proddy
2024-09-25 17:33:36 +02:00
committed by GitHub
16 changed files with 208 additions and 108 deletions

View File

@@ -31,7 +31,7 @@
"async-validator": "^4.2.5",
"jwt-decode": "^4.0.0",
"mime-types": "^2.1.35",
"preact": "^10.24.0",
"preact": "^10.24.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
@@ -47,8 +47,8 @@
"@preact/preset-vite": "^2.9.1",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/formidable": "^3",
"@types/node": "^22.6.1",
"@types/react": "^18.3.8",
"@types/node": "^22.7.0",
"@types/react": "^18.3.9",
"@types/react-dom": "^18.3.0",
"@types/react-router-dom": "^5.3.3",
"concurrently": "^9.0.1",
@@ -59,7 +59,7 @@
"rollup-plugin-visualizer": "^5.12.0",
"terser": "^5.33.0",
"typescript-eslint": "8.7.0",
"vite": "^5.4.7",
"vite": "^5.4.8",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.0.1"
},

View File

@@ -1437,7 +1437,7 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:*, @types/node@npm:^22.6.1":
"@types/node@npm:*":
version: 22.6.1
resolution: "@types/node@npm:22.6.1"
dependencies:
@@ -1446,6 +1446,15 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^22.7.0":
version: 22.7.0
resolution: "@types/node@npm:22.7.0"
dependencies:
undici-types: "npm:~6.19.2"
checksum: 10c0/127b1ac3eebe8c2b09e3d2de277ee906710c4908b4573cde23b9c7cec1cb1aaf1af8bdabbccdac08d005f820b770e7447b22c8eb56ca63344f4d2e26bcdc29fb
languageName: node
linkType: hard
"@types/parse-json@npm:^4.0.0":
version: 4.0.2
resolution: "@types/parse-json@npm:4.0.2"
@@ -1499,7 +1508,7 @@ __metadata:
languageName: node
linkType: hard
"@types/react@npm:*, @types/react@npm:^18.3.8":
"@types/react@npm:*":
version: 18.3.8
resolution: "@types/react@npm:18.3.8"
dependencies:
@@ -1509,6 +1518,16 @@ __metadata:
languageName: node
linkType: hard
"@types/react@npm:^18.3.9":
version: 18.3.9
resolution: "@types/react@npm:18.3.9"
dependencies:
"@types/prop-types": "npm:*"
csstype: "npm:^3.0.2"
checksum: 10c0/a92b8e061d0c833e096254782c56a802316593f4a907fb834b557cabe848a0829b9eb6056404ea239eb4d5ec5ac7b7724309761516c0a7a277916fa04dd4f805
languageName: node
linkType: hard
"@types/responselike@npm:^1.0.0":
version: 1.0.3
resolution: "@types/responselike@npm:1.0.3"
@@ -1659,8 +1678,8 @@ __metadata:
"@table-library/react-table-library": "npm:4.1.7"
"@trivago/prettier-plugin-sort-imports": "npm:^4.3.0"
"@types/formidable": "npm:^3"
"@types/node": "npm:^22.6.1"
"@types/react": "npm:^18.3.8"
"@types/node": "npm:^22.7.0"
"@types/react": "npm:^18.3.9"
"@types/react-dom": "npm:^18.3.0"
"@types/react-router-dom": "npm:^5.3.3"
alova: "npm:3.0.16"
@@ -1671,7 +1690,7 @@ __metadata:
formidable: "npm:^3.5.1"
jwt-decode: "npm:^4.0.0"
mime-types: "npm:^2.1.35"
preact: "npm:^10.24.0"
preact: "npm:^10.24.1"
prettier: "npm:^3.3.3"
react: "npm:^18.3.1"
react-dom: "npm:^18.3.1"
@@ -1683,7 +1702,7 @@ __metadata:
typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.6.2"
typescript-eslint: "npm:8.7.0"
vite: "npm:^5.4.7"
vite: "npm:^5.4.8"
vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^5.0.1"
languageName: unknown
@@ -5591,10 +5610,10 @@ __metadata:
languageName: node
linkType: hard
"preact@npm:^10.24.0":
version: 10.24.0
resolution: "preact@npm:10.24.0"
checksum: 10c0/09d490d2326c511e205a96f81db0adf05f1b42dbe2a39be6fc494662c7476575494e96140252f351a0e3b3d15aee5b079bf963865bb01287f69c45c6755ed22e
"preact@npm:^10.24.1":
version: 10.24.1
resolution: "preact@npm:10.24.1"
checksum: 10c0/f9bc8b2f88d340f1b8f854208889244059c46916449b8f8f2174fcacbc0904c445c5870896fb0cfeaf442eeade975857e8e03f0785135c41d63cd32d9414c9c6
languageName: node
linkType: hard
@@ -6983,9 +7002,9 @@ __metadata:
languageName: node
linkType: hard
"vite@npm:^5.4.7":
version: 5.4.7
resolution: "vite@npm:5.4.7"
"vite@npm:^5.4.8":
version: 5.4.8
resolution: "vite@npm:5.4.8"
dependencies:
esbuild: "npm:^0.21.3"
fsevents: "npm:~2.3.3"
@@ -7022,7 +7041,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 10c0/0ca7ca60f71c61f3855bbabf7e33909bec32933b35914d4d281813c728183e78e7ce5be05735a7671df3a994613d3881f520a32a80715faa92effb28deee9320
checksum: 10c0/af70af6d6316a3af71f44ebe3ab343bd66450d4157af73af3b32239e1b6ec43ff6f651d7cc4193b21ed3bff2e9356a3de9e96aee53857f39922e4a2d9fad75a1
languageName: node
linkType: hard

View File

@@ -3,6 +3,7 @@ import os
Import("env")
def buildWeb():
os.chdir("interface")
print("Building web interface...")

View File

@@ -3,6 +3,7 @@
# copied from esphome
# run from Linux using ./scripts/clang-forrmat.py
from helpers import get_output, src_files, filter_changed
import argparse
import multiprocessing
import os
@@ -14,7 +15,7 @@ import threading
import click
sys.path.append(os.path.dirname(__file__))
from helpers import get_output, src_files, filter_changed
def run_format(args, queue, lock, failed_files):
"""Takes filenames out of queue and runs clang-format on them."""
@@ -27,11 +28,13 @@ def run_format(args, queue, lock, failed_files):
invocation.extend(['--dry-run', '-Werror'])
invocation.append(path)
proc = subprocess.run(invocation, capture_output=True, encoding='utf-8')
proc = subprocess.run(
invocation, capture_output=True, encoding='utf-8')
if proc.returncode != 0:
with lock:
print()
print("\033[0;32m************* File \033[1;32m{}\033[0m".format(path))
print(
"\033[0;32m************* File \033[1;32m{}\033[0m".format(path))
print(proc.stdout)
print(proc.stderr)
print()
@@ -42,6 +45,7 @@ def run_format(args, queue, lock, failed_files):
def progress_bar_show(value):
return value if value is not None else ''
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-j', '--jobs', type=int,

View File

@@ -3,6 +3,8 @@
# copied from esphome
# run from Linux using ./scripts/clang-forrmat.py
from helpers import shlex_quote, get_output, \
build_all_include, temp_header_file, filter_changed, load_idedata, src_files
import argparse
import multiprocessing
import os
@@ -16,8 +18,7 @@ import click
import pexpect
sys.path.append(os.path.dirname(__file__))
from helpers import shlex_quote, get_output, \
build_all_include, temp_header_file, filter_changed, load_idedata, src_files
def clang_options(idedata):
cmd = [
@@ -46,6 +47,7 @@ def clang_options(idedata):
return cmd
def run_tidy(args, options, tmpdir, queue, lock, failed_files):
while True:
path = queue.get()
@@ -73,20 +75,24 @@ def run_tidy(args, options, tmpdir, queue, lock, failed_files):
if rc != 0:
with lock:
print()
print("\033[0;32m************* File \033[1;32m{}\033[0m".format(path))
print(
"\033[0;32m************* File \033[1;32m{}\033[0m".format(path))
print(output)
print()
failed_files.append(path)
queue.task_done()
def progress_bar_show(value):
if value is None:
return ''
def split_list(a, n):
k, m = divmod(len(a), n)
return [a[i * k + min(i, m):(i + 1) * k + min(i + 1, m)] for i in range(n)]
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-j', '--jobs', type=int,

View File

@@ -59,6 +59,7 @@ with fileinput.input() as f_input:
entity[headers[i]] = val
entities.append(entity)
def device_name_key(e): return e["device name"]

View File

@@ -4,7 +4,8 @@ import subprocess
import json
from pathlib import Path
root_path = os.path.abspath(os.path.normpath(os.path.join(__file__, "..", "..")))
root_path = os.path.abspath(os.path.normpath(
os.path.join(__file__, "..", "..")))
basepath = os.path.join(root_path, "src")
temp_folder = os.path.join(root_path, ".temp")
temp_header_file = os.path.join(temp_folder, "all-include.cpp")
@@ -18,6 +19,7 @@ def shlex_quote(s):
return "'" + s.replace("'", "'\"'\"'") + "'"
def build_all_include():
# Build a cpp file that includes all header files in this repo.
# Otherwise header-only integrations would not be tested by clang-tidy
@@ -36,6 +38,7 @@ def build_all_include():
p.parent.mkdir(exist_ok=True)
p.write_text(content)
def src_files(filetypes=None):
file_list = []
for path in walk_files(basepath):
@@ -45,24 +48,31 @@ def src_files(filetypes=None):
file_list.append(path)
return file_list
def walk_files(path):
for root, _, files in os.walk(path):
for name in files:
yield os.path.join(root, name)
def get_output(*args):
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc = subprocess.Popen(
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = proc.communicate()
return output.decode("utf-8")
def get_err(*args):
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc = subprocess.Popen(
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = proc.communicate()
return err.decode("utf-8")
def splitlines_no_ends(string):
return [s.strip() for s in string.splitlines()]
def changed_files():
check_remotes = ["upstream", "origin"]
check_remotes.extend(splitlines_no_ends(get_output("git", "remote")))
@@ -81,6 +91,7 @@ def changed_files():
changed.sort()
return changed
def filter_changed(files):
changed = changed_files()
files = [f for f in files if f in changed]
@@ -91,6 +102,7 @@ def filter_changed(files):
print(f" {c}")
return files
def git_ls_files(patterns=None):
command = ["git", "ls-files", "-s"]
if patterns is not None:
@@ -100,6 +112,7 @@ def git_ls_files(patterns=None):
lines = [x.split() for x in output.decode("utf-8").splitlines()]
return {s[3].strip(): int(s[0]) for s in lines}
def load_idedata(environment):
platformio_ini = Path(root_path) / "platformio.ini"
temp_idedata = Path(temp_folder) / f"idedata-{environment}.json"
@@ -113,7 +126,8 @@ def load_idedata(environment):
if not changed:
return json.loads(temp_idedata.read_text())
stdout = subprocess.check_output(["pio", "run", "-t", "idedata", "-e", environment])
stdout = subprocess.check_output(
["pio", "run", "-t", "idedata", "-e", environment])
match = re.search(r'{\s*".*}', stdout.decode("utf-8"))
data = json.loads(match.group())

View File

@@ -2,10 +2,12 @@ import os
Import("env")
def refresh_module():
print("Fetching latest module for Native target...")
os.system("pio pkg install -f -s -e native -l file://../../modules/EMS-ESP-Modules")
os.system(
"pio pkg install -f -s -e native -l file://../../modules/EMS-ESP-Modules")
if not (env.IsCleanTarget()):
refresh_module()

View File

@@ -1,11 +1,12 @@
import hashlib
import shutil
import re
import os
Import("env")
import hashlib
OUTPUT_DIR = "build{}".format(os.path.sep)
def bin_copy(source, target, env):
# get the application version from version.h
@@ -60,7 +61,9 @@ def bin_copy(source, target, env):
# convert . to _ so Windows doesn't complain
# Format is EMS-ESP-<version>-<mcu>-<flash> with + at the end if it has PSRAM
variant = "EMS-ESP-" + app_version.replace(".", "_") + "-" + mcu + "-" + flash_mem + ("+" if psram else "")
variant = "EMS-ESP-" + \
app_version.replace(".", "_") + "-" + mcu + "-" + \
flash_mem + ("+" if psram else "")
# check if output directories exist and create if necessary
if not os.path.isdir(OUTPUT_DIR):
@@ -89,7 +92,7 @@ def bin_copy(source, target, env):
# copy firmware.bin to firmware/<variant>.bin
shutil.copy(str(target[0]), bin_file)
with open(bin_file,"rb") as f:
with open(bin_file, "rb") as f:
result = hashlib.md5(f.read())
print("MD5: "+result.hexdigest())
file1 = open(md5_file, 'w')
@@ -105,16 +108,19 @@ def bin_copy(source, target, env):
#
extra_variant = ""
if env.get('PIOENV') == "ci_s3_16M_P":
extra_variant = "EMS-ESP-" + app_version.replace(".", "_") + "-ESP32_S3"
extra_variant = "EMS-ESP-" + \
app_version.replace(".", "_") + "-ESP32_S3"
elif env.get('PIOENV') == "ci_s_4M":
extra_variant = "EMS-ESP-" + app_version.replace(".", "_") + "-ESP32"
if extra_variant:
extra_bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, extra_variant)
extra_bin_file = "{}firmware{}{}.bin".format(
OUTPUT_DIR, os.path.sep, extra_variant)
if os.path.isfile(extra_bin_file):
os.remove(extra_bin_file)
extra_md5_file = "{}firmware{}{}.md5".format(OUTPUT_DIR, os.path.sep, extra_variant)
extra_md5_file = "{}firmware{}{}.md5".format(
OUTPUT_DIR, os.path.sep, extra_variant)
if os.path.isfile(extra_md5_file):
os.remove(extra_md5_file)
@@ -124,5 +130,6 @@ def bin_copy(source, target, env):
print("*********************************************")
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_copy])
env.AddPostAction("$BUILD_DIR/${PROGNAME}.md5", [bin_copy])

View File

@@ -14,13 +14,15 @@ import platform # For getting the operating system type
import subprocess # For executing a shell command
from termcolor import cprint
def print_success(x): return cprint(x, 'green')
def print_fail(x): return cprint(x, 'red')
def ping_until_up(ip, text):
print(text + "...", flush=True, end="")
time.sleep(1)
param = '-n' if platform.system().lower()=='windows' else '-c'
param = '-n' if platform.system().lower() == 'windows' else '-c'
command = ["ping", param, "2", ip]
while True:
if (subprocess.run(args=command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0):
@@ -30,13 +32,15 @@ def ping_until_up(ip, text):
print(".", flush=True, end="")
time.sleep(1)
def run_test(ip, wait, name, token):
BASE_URL = "http://" + str(ip)
INFO_URL = BASE_URL + "/api/system/info"
RESTART_URL = BASE_URL + "/api/system/restart"
TEST_URL = BASE_URL + "/api?device=system&cmd=test&data=" + name
GET_HEADERS = { 'Content-Type': 'application/json'}
GET_HEADERS_SECURE = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + str(token) }
GET_HEADERS = {'Content-Type': 'application/json'}
GET_HEADERS_SECURE = {'Content-Type': 'application/json',
'Authorization': 'Bearer ' + str(token)}
# BODY = json.dumps({ "value": 22.5 })
start = timer()
@@ -51,12 +55,15 @@ def run_test(ip, wait, name, token):
end = timer()
# check if IP exists
ping_until_up(ip, "(" + str(round(end - start, 1)) + ")\t1. Checking if EMS-ESP is reachable")
ping_until_up(ip, "(" + str(round(end - start, 1)) +
")\t1. Checking if EMS-ESP is reachable")
end = timer()
# Restart EMS-ESP
print("(" + str(round(end - start, 1)) + ")\t2. Doing a cold restart...", end="")
response = requests.get(RESTART_URL, headers=GET_HEADERS_SECURE, verify=False)
print("(" + str(round(end - start, 1)) +
")\t2. Doing a cold restart...", end="")
response = requests.get(
RESTART_URL, headers=GET_HEADERS_SECURE, verify=False)
if (response.status_code != 200):
print_fail("Failed")
return
@@ -64,20 +71,24 @@ def run_test(ip, wait, name, token):
end = timer()
# Wait for EMS-ESP to come back up and reconnect to WiFi
ping_until_up(ip, "(" + str(round(end - start, 1)) + ")\t3. Waiting for EMS-ESP to come back online")
ping_until_up(ip, "(" + str(round(end - start, 1)) +
")\t3. Waiting for EMS-ESP to come back online")
end = timer()
print("(" + str(round(end - start, 1)) + ")\t4. Getting initial memory stats...", flush=True, end="")
print("(" + str(round(end - start, 1)) +
")\t4. Getting initial memory stats...", flush=True, end="")
time.sleep(1)
response = requests.get(INFO_URL, headers=GET_HEADERS, verify=False)
uptime_a = response.json()['System Info']['uptime (seconds)']
freemem_a = response.json()['System Info']['free mem']
maxalloc_a = response.json()['System Info']['max alloc']
print_success("Uptime is " + str(uptime_a) + " secs, Free mem/Max alloc before=" + str(freemem_a) + "/" + str(maxalloc_a) )
print_success("Uptime is " + str(uptime_a) +
" secs, Free mem/Max alloc before=" + str(freemem_a) + "/" + str(maxalloc_a))
end = timer()
# run test
print("(" + str(round(end - start, 1)) + ")\t5. Running test called '" + name + "'...", end="")
print("(" + str(round(end - start, 1)) +
")\t5. Running test called '" + name + "'...", end="")
response = requests.get(TEST_URL, headers=GET_HEADERS, verify=False)
test_output = response.json()['message']
if (test_output != 'OK'):
@@ -87,25 +98,29 @@ def run_test(ip, wait, name, token):
end = timer()
# wait n seconds
print("(" + str(round(end - start, 1)) + ")\t6. Waiting for " + str(wait) + " seconds...", flush=True, end="")
print("(" + str(round(end - start, 1)) + ")\t6. Waiting for " +
str(wait) + " seconds...", flush=True, end="")
time.sleep(wait)
print_success("Done")
end = timer()
# get latest stats
print("(" + str(round(end - start, 1)) + ")\t7. Getting latest memory stats...", end="")
print("(" + str(round(end - start, 1)) +
")\t7. Getting latest memory stats...", end="")
response = requests.get(INFO_URL, headers=GET_HEADERS, verify=False)
uptime_b = response.json()['System Info']['uptime (seconds)']
freemem_b = response.json()['System Info']['free mem']
maxalloc_b = response.json()['System Info']['max alloc']
print_success("Uptime is " + str(uptime_b) + " secs, Free mem/Max alloc after=" + str(freemem_b) + "/" + str(maxalloc_b) )
print_success("Uptime is " + str(uptime_b) +
" secs, Free mem/Max alloc after=" + str(freemem_b) + "/" + str(maxalloc_b))
print()
# check if it worked and report back
if (uptime_b <= uptime_a):
print(" Error! EMS-ESP crashed and restarted :-(")
else:
print("In the " + str(uptime_b - uptime_a) + " seconds elapsed, we have Free mem/Max alloc: ", end="")
print("In the " + str(uptime_b - uptime_a) +
" seconds elapsed, we have Free mem/Max alloc: ", end="")
cprint("before=" + str(freemem_a) + "/" + str(maxalloc_a) +
" after=" + str(freemem_b) + "/" + str(maxalloc_b) +
" diff=" + str(freemem_a - freemem_b) + "/" + str(maxalloc_a - maxalloc_b), "cyan", attrs=["bold"])
@@ -113,11 +128,17 @@ def run_test(ip, wait, name, token):
# finish
print()
# main
parser = argparse.ArgumentParser(description="Benchmark EMS-ESP, memory profiler")
parser.add_argument("-i", "--ip", metavar="IP", type=str, default="ems-esp.local", help="IP address of EMS-ESP")
parser.add_argument("-w", "--wait", metavar="WAIT", type=int, default="10", help="time to wait between test")
parser.add_argument("-n", "--name", metavar="NAME", type=str, default="memory", help="Name of test to run")
parser.add_argument("-t", "--token", metavar="TOKEN", type=str, help="Bearer Token")
parser = argparse.ArgumentParser(
description="Benchmark EMS-ESP, memory profiler")
parser.add_argument("-i", "--ip", metavar="IP", type=str,
default="ems-esp.local", help="IP address of EMS-ESP")
parser.add_argument("-w", "--wait", metavar="WAIT", type=int,
default="10", help="time to wait between test")
parser.add_argument("-n", "--name", metavar="NAME", type=str,
default="memory", help="Name of test to run")
parser.add_argument("-t", "--token", metavar="TOKEN",
type=str, help="Bearer Token")
args = parser.parse_args()
run_test(**vars(args))

View File

@@ -5,6 +5,7 @@ Import("env")
OUTPUT_DIR = "build{}".format(os.path.sep)
def move_file(source, target, env):
# get the build info
@@ -57,4 +58,5 @@ def move_file(source, target, env):
print("Executing file")
os.system(bin_file)
env.AddPostAction("$BUILD_DIR/${PROGNAME}", [move_file])

View File

@@ -192,10 +192,12 @@ for entity in entities:
# set size for string entities
if entity["modbus count"] == "0" and entity_dev_name in string_sizes:
entity["modbus count"] = -(-string_sizes[entity_dev_name] // 2) # divide and round up
entity["modbus count"] = - \
(-string_sizes[entity_dev_name] // 2) # divide and round up
if int(entity["modbus count"]) <= 0:
raise Exception('Entity "' + entity_shortname + '" does not have a size - string sizes need to be added manually to update_modbus_registers.py')
raise Exception('Entity "' + entity_shortname +
'" does not have a size - string sizes need to be added manually to update_modbus_registers.py')
# if entity["modbus count"] == "0":
# print("ignoring " + entity_dev_name + " - it has a register length of zero")
@@ -254,7 +256,8 @@ for device_type_name in device_type_names:
for entity_name, modbus_info in sorted(entities.items(), key=lambda x: int(x[1]["modbus offset"])):
params = {
'devtype': "dt::" + device_type_name,
"tagtype": tag_to_tagtype[int(tag)], # re.sub(r"[0-9]+", "*", tag),
# re.sub(r"[0-9]+", "*", tag),
"tagtype": tag_to_tagtype[int(tag)],
"shortname": 'FL_(' + listNames[entity_name] + ")",
"entity_name": entity_name,
'registeroffset': modbus_info["modbus offset"],

View File

@@ -33,14 +33,17 @@ except ImportError:
from tqdm import tqdm
from termcolor import cprint
def print_success(x): return cprint(x, 'green')
def print_fail(x): return cprint('Error: '+x, 'red')
def on_upload(source, target, env):
# make sure we have set the upload_protocol to custom
if env.get('UPLOAD_PROTOCOL') != 'custom':
print_fail("Please set upload_protocol = custom in your pio_local.ini file when using upload.py")
print_fail(
"Please set upload_protocol = custom in your pio_local.ini file when using upload.py")
return
# first check authentication
@@ -52,7 +55,6 @@ def on_upload(source, target, env):
print_fail('Missing settings. Add these to your pio_local.ini file: \n\ncustom_username=username\ncustom_password=password\ncustom_emsesp_ip=ems-esp.local\n')
return
emsesp_url = "http://" + env.GetProjectOption('custom_emsesp_ip')
parsed_url = urlparse(emsesp_url)
host_ip = parsed_url.netloc
@@ -75,10 +77,12 @@ def on_upload(source, target, env):
"password": password
}
response = requests.post(signon_url, json=username_password, headers=signon_headers)
response = requests.post(
signon_url, json=username_password, headers=signon_headers)
if response.status_code != 200:
print_fail("Authentication with EMS-ESP failed (code " + str(response.status_code) + ")")
print_fail("Authentication with EMS-ESP failed (code " +
str(response.status_code) + ")")
return
print_success("Authentication with EMS-ESP successful")
@@ -105,7 +109,8 @@ def on_upload(source, target, env):
unit_divisor=1024
)
monitor = MultipartEncoderMonitor(encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n))
monitor = MultipartEncoderMonitor(
encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n))
post_headers = {
'Host': host_ip,
@@ -123,7 +128,8 @@ def on_upload(source, target, env):
upload_url = f"{emsesp_url}/rest/uploadFile"
response = requests.post(upload_url, data=monitor, headers=post_headers)
response = requests.post(
upload_url, data=monitor, headers=post_headers)
bar.close()
time.sleep(0.1)
@@ -148,8 +154,10 @@ def on_upload(source, target, env):
restart_url = f"{emsesp_url}/api/system/restart"
response = requests.get(restart_url, headers=restart_headers)
if response.status_code != 200:
print_fail("Restart failed (code " + str(response.status_code) + ")")
print_fail("Restart failed (code " +
str(response.status_code) + ")")
print()
env.Replace(UPLOADCMD=on_upload)

View File

@@ -19,9 +19,11 @@ from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
from tqdm import tqdm
from termcolor import cprint
def print_success(x): return cprint(x, 'green')
def print_fail(x): return cprint(x, 'red')
def upload(file, ip, username, password):
# Print welcome message
@@ -51,10 +53,12 @@ def upload(file, ip, username, password):
"password": password
}
response = requests.post(signon_url, json=username_password, headers=signon_headers, auth=None)
response = requests.post(
signon_url, json=username_password, headers=signon_headers, auth=None)
if response.status_code != 200:
print_fail("Authentication failed (code " + str(response.status_code) + ")")
print_fail("Authentication failed (code " +
str(response.status_code) + ")")
return
print_success("Authentication successful")
@@ -79,7 +83,8 @@ def upload(file, ip, username, password):
unit_divisor=1024
)
monitor = MultipartEncoderMonitor(encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n))
monitor = MultipartEncoderMonitor(
encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n))
post_headers = {
'Host': host_ip,
@@ -97,7 +102,8 @@ def upload(file, ip, username, password):
upload_url = f"{emsesp_url}/rest/uploadFile"
response = requests.post(upload_url, data=monitor, headers=post_headers, auth=None)
response = requests.post(
upload_url, data=monitor, headers=post_headers, auth=None)
bar.close()
time.sleep(0.1)
@@ -120,16 +126,21 @@ def upload(file, ip, username, password):
restart_url = f"{emsesp_url}/api/system/restart"
response = requests.get(restart_url, headers=restart_headers)
if response.status_code != 200:
print_fail("Restart failed (code " + str(response.status_code) + ")")
print_fail("Restart failed (code " +
str(response.status_code) + ")")
print()
# main
parser = argparse.ArgumentParser(description="EMS-ESP Firmware Upload")
parser.add_argument("-f", "--file", metavar="FILE", required=True, type=str, help="firmware file")
parser.add_argument("-i", "--ip", metavar="IP", type=str, default="ems-esp.local", help="IP address of EMS-ESP")
parser.add_argument("-u", "--username", metavar="USERNAME", type=str, default="admin", help="admin user")
parser.add_argument("-p", "--password", metavar="PASSWORD", type=str, default="admin", help="admin password")
parser.add_argument("-f", "--file", metavar="FILE",
required=True, type=str, help="firmware file")
parser.add_argument("-i", "--ip", metavar="IP", type=str,
default="ems-esp.local", help="IP address of EMS-ESP")
parser.add_argument("-u", "--username", metavar="USERNAME",
type=str, default="admin", help="admin user")
parser.add_argument("-p", "--password", metavar="PASSWORD",
type=str, default="admin", help="admin password")
args = parser.parse_args()
upload(**vars(args))

View File

@@ -1731,7 +1731,8 @@ void EMSESP::start_serial_console() {
void EMSESP::shell_prompt() {
#ifndef EMSESP_STANDALONE
serial_console_.println();
serial_console_.println("Press CTRL-C to activate this serial console");
serial_console_.printf("EMS-ESP %s: press CTRL-C to activate this serial console", EMSESP_APP_VERSION);
serial_console_.println();
#endif
}