mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-10-28 11:14:58 +00:00
add factory reset to Recovery
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
"@table-library/react-table-library": "4.1.15",
|
"@table-library/react-table-library": "4.1.15",
|
||||||
"alova": "^3.5.5",
|
"alova": "^3.5.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"preact": "^11.0.0",
|
"preact": "^11.0.1",
|
||||||
"react": "^19.3.0",
|
"react": "^19.3.0",
|
||||||
"react-dom": "^19.3.0",
|
"react-dom": "^19.3.0",
|
||||||
"react-icons": "^5.7.0",
|
"react-icons": "^5.7.0",
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
"@types/node": "^26.6.4",
|
"@types/node": "^26.6.4",
|
||||||
"@types/react": "^19.3.0",
|
"@types/react": "^19.3.0",
|
||||||
"@types/react-dom": "^19.3.0",
|
"@types/react-dom": "^19.3.0",
|
||||||
"concurrently": "^10.0.5",
|
"concurrently": "^10.0.6",
|
||||||
"eslint": "^10.12.0",
|
"eslint": "^10.12.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"etag": "^1.8.1",
|
"etag": "^1.8.1",
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"terser": "^5.51.2",
|
"terser": "^5.51.2",
|
||||||
"typescript": "^6.0.3",
|
"typescript": "^6.0.3",
|
||||||
"typescript-eslint": "^8.71.1",
|
"typescript-eslint": "^8.71.1",
|
||||||
"vite": "^8.3.3",
|
"vite": "^8.3.4",
|
||||||
"vite-plugin-imagemin": "^0.6.1"
|
"vite-plugin-imagemin": "^0.6.1"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@12.10.1"
|
"packageManager": "pnpm@12.10.1"
|
||||||
|
|||||||
Generated
+51
-51
@@ -191,8 +191,8 @@ importers:
|
|||||||
specifier: ^4.0.0
|
specifier: ^4.0.0
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
preact:
|
preact:
|
||||||
specifier: ^11.0.0
|
specifier: ^11.0.1
|
||||||
version: 11.0.0
|
version: 11.0.1
|
||||||
react:
|
react:
|
||||||
specifier: ^19.3.0
|
specifier: ^19.3.0
|
||||||
version: 19.3.0
|
version: 19.3.0
|
||||||
@@ -214,7 +214,7 @@ importers:
|
|||||||
version: 10.0.1(eslint@10.12.0(supports-color@10.2.2))
|
version: 10.0.1(eslint@10.12.0(supports-color@10.2.2))
|
||||||
'@preact/preset-vite':
|
'@preact/preset-vite':
|
||||||
specifier: ^2.10.6
|
specifier: ^2.10.6
|
||||||
version: 2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
|
version: 2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@11.0.1)(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2))
|
||||||
'@trivago/prettier-plugin-sort-imports':
|
'@trivago/prettier-plugin-sort-imports':
|
||||||
specifier: ^6.0.2
|
specifier: ^6.0.2
|
||||||
version: 6.0.2(prettier@3.9.9)(supports-color@10.2.2)
|
version: 6.0.2(prettier@3.9.9)(supports-color@10.2.2)
|
||||||
@@ -228,8 +228,8 @@ importers:
|
|||||||
specifier: ^19.3.0
|
specifier: ^19.3.0
|
||||||
version: 19.3.0(@types/react@19.3.0)
|
version: 19.3.0(@types/react@19.3.0)
|
||||||
concurrently:
|
concurrently:
|
||||||
specifier: ^10.0.5
|
specifier: ^10.0.6
|
||||||
version: 10.0.5
|
version: 10.0.6
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^10.12.0
|
specifier: ^10.12.0
|
||||||
version: 10.12.0(supports-color@10.2.2)
|
version: 10.12.0(supports-color@10.2.2)
|
||||||
@@ -258,11 +258,11 @@ importers:
|
|||||||
specifier: ^8.71.1
|
specifier: ^8.71.1
|
||||||
version: 8.71.1(eslint@10.12.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)
|
version: 8.71.1(eslint@10.12.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)
|
||||||
vite:
|
vite:
|
||||||
specifier: ^8.3.3
|
specifier: ^8.3.4
|
||||||
version: 8.3.3(@types/node@26.6.4)(terser@5.51.2)
|
version: 8.3.4(@types/node@26.6.4)(terser@5.51.2)
|
||||||
vite-plugin-imagemin:
|
vite-plugin-imagemin:
|
||||||
specifier: ^0.6.1
|
specifier: ^0.6.1
|
||||||
version: 0.6.1(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
|
version: 0.6.1(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2))
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@@ -1004,8 +1004,8 @@ packages:
|
|||||||
base64-js@1.5.1:
|
base64-js@1.5.1:
|
||||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||||
|
|
||||||
baseline-browser-mapping@2.11.27:
|
baseline-browser-mapping@2.11.28:
|
||||||
resolution: {integrity: sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==}
|
resolution: {integrity: sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -1157,8 +1157,8 @@ packages:
|
|||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||||
|
|
||||||
concurrently@10.0.5:
|
concurrently@10.0.6:
|
||||||
resolution: {integrity: sha512-JaP/CoftUrCcAFW/g//RbgEGwlelnEae6cfBLgH6ZdO6s8jPkn6p9SB9u6pdVxYXoiSnFqseOlHfrEfF82TVOg==}
|
resolution: {integrity: sha512-qgICXXFp2/3nAebRLmxcINKEXM1mLK3ij/y31P02VTs/KIkddIeC05n73DxOXsXMB9LFSqNU1/na3lDlOhcbIw==}
|
||||||
engines: {node: '>=22'}
|
engines: {node: '>=22'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -1338,8 +1338,8 @@ packages:
|
|||||||
duplexer3@0.1.5:
|
duplexer3@0.1.5:
|
||||||
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
|
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
|
||||||
|
|
||||||
electron-to-chromium@1.5.449:
|
electron-to-chromium@1.5.452:
|
||||||
resolution: {integrity: sha512-dKeYk/3SFQz+nXi5whp3OuJzeWABEG4zCtkWJ9+Vby1E1iFM2y0gElRtQvNXRPJTsj8WAF4HMP7hvP790QtJ9g==}
|
resolution: {integrity: sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==}
|
||||||
|
|
||||||
emoji-regex@10.6.0:
|
emoji-regex@10.6.0:
|
||||||
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
|
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
|
||||||
@@ -2318,8 +2318,8 @@ packages:
|
|||||||
node-html-parser@6.1.13:
|
node-html-parser@6.1.13:
|
||||||
resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==}
|
resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==}
|
||||||
|
|
||||||
node-releases@2.0.57:
|
node-releases@2.0.58:
|
||||||
resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==}
|
resolution: {integrity: sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
normalize-package-data@2.5.0:
|
normalize-package-data@2.5.0:
|
||||||
@@ -2531,8 +2531,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==}
|
resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==}
|
||||||
engines: {node: '>=20'}
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
preact@11.0.0:
|
preact@11.0.1:
|
||||||
resolution: {integrity: sha512-LRTLKuSe6VYPhvBDjwFaX+nuZnpsw6IN2GSboisAvhGsncylBmrbDCERhgKDn6yP2mAwbGvsB5OVyTe33M8gBg==}
|
resolution: {integrity: sha512-TNNwEq++jYNHy747LziCjPRVgEwnLSOIOAw/oYcjI3Tdnubx2EXtt76I0an8PATvUWtx/DX1kFIg1eFN+O/fkw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
preact-render-to-string: '>=6.7.0'
|
preact-render-to-string: '>=6.7.0'
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
@@ -2768,8 +2768,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
shell-quote@1.9.0:
|
shell-quote@1.12.0:
|
||||||
resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==}
|
resolution: {integrity: sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
signal-exit@3.0.7:
|
signal-exit@3.0.7:
|
||||||
@@ -3015,8 +3015,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
|
|
||||||
update-browserslist-db@1.3.3:
|
update-browserslist-db@1.3.4:
|
||||||
resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==}
|
resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
browserslist: '>= 4.21.0'
|
browserslist: '>= 4.21.0'
|
||||||
@@ -3057,8 +3057,8 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: 5.x || 6.x || 7.x || 8.x
|
vite: 5.x || 6.x || 7.x || 8.x
|
||||||
|
|
||||||
vite@8.3.3:
|
vite@8.3.4:
|
||||||
resolution: {integrity: sha512-cTAldKPImjg6c+gk48U19POPn3GCBzZwpdsN8ZMEEcbpes+6/wvfqUd0C2y3qYY4wsj8PwgFwrZ/1jBPVttMSg==}
|
resolution: {integrity: sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -3591,19 +3591,19 @@ snapshots:
|
|||||||
|
|
||||||
'@popperjs/core@2.11.8': {}
|
'@popperjs/core@2.11.8': {}
|
||||||
|
|
||||||
'@preact/preset-vite@2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))':
|
'@preact/preset-vite@2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@11.0.1)(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.29.7(supports-color@10.2.2)
|
'@babel/core': 7.29.7(supports-color@10.2.2)
|
||||||
'@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)
|
'@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)
|
||||||
'@babel/plugin-transform-react-jsx-development': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)
|
'@babel/plugin-transform-react-jsx-development': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)
|
||||||
'@prefresh/vite': 2.4.12(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
|
'@prefresh/vite': 2.4.12(preact@11.0.1)(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2))
|
||||||
'@rollup/pluginutils': 5.4.0
|
'@rollup/pluginutils': 5.4.0
|
||||||
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.29.7(supports-color@10.2.2))
|
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.29.7(supports-color@10.2.2))
|
||||||
debug: 4.4.3(supports-color@10.2.2)
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
magic-string: 0.30.21
|
magic-string: 0.30.21
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
vite: 8.3.3(@types/node@26.6.4)(terser@5.51.2)
|
vite: 8.3.4(@types/node@26.6.4)(terser@5.51.2)
|
||||||
vite-prerender-plugin: 0.5.14(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
|
vite-prerender-plugin: 0.5.14(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2))
|
||||||
zimmerframe: 1.1.5
|
zimmerframe: 1.1.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- preact
|
- preact
|
||||||
@@ -3614,21 +3614,21 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.29.7(supports-color@10.2.2)
|
'@babel/core': 7.29.7(supports-color@10.2.2)
|
||||||
|
|
||||||
'@prefresh/core@1.5.11(preact@11.0.0)':
|
'@prefresh/core@1.5.11(preact@11.0.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
preact: 11.0.0
|
preact: 11.0.1
|
||||||
|
|
||||||
'@prefresh/utils@1.2.1': {}
|
'@prefresh/utils@1.2.1': {}
|
||||||
|
|
||||||
'@prefresh/vite@2.4.12(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))':
|
'@prefresh/vite@2.4.12(preact@11.0.1)(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.29.7(supports-color@10.2.2)
|
'@babel/core': 7.29.7(supports-color@10.2.2)
|
||||||
'@prefresh/babel-plugin': 0.5.4(@babel/core@7.29.7(supports-color@10.2.2))
|
'@prefresh/babel-plugin': 0.5.4(@babel/core@7.29.7(supports-color@10.2.2))
|
||||||
'@prefresh/core': 1.5.11(preact@11.0.0)
|
'@prefresh/core': 1.5.11(preact@11.0.1)
|
||||||
'@prefresh/utils': 1.2.1
|
'@prefresh/utils': 1.2.1
|
||||||
'@rollup/pluginutils': 4.2.1
|
'@rollup/pluginutils': 4.2.1
|
||||||
preact: 11.0.0
|
preact: 11.0.1
|
||||||
vite: 8.3.3(@types/node@26.6.4)(terser@5.51.2)
|
vite: 8.3.4(@types/node@26.6.4)(terser@5.51.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -3942,7 +3942,7 @@ snapshots:
|
|||||||
|
|
||||||
base64-js@1.5.1: {}
|
base64-js@1.5.1: {}
|
||||||
|
|
||||||
baseline-browser-mapping@2.11.27: {}
|
baseline-browser-mapping@2.11.28: {}
|
||||||
|
|
||||||
bin-build@3.0.0:
|
bin-build@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4003,11 +4003,11 @@ snapshots:
|
|||||||
|
|
||||||
browserslist@4.29.3:
|
browserslist@4.29.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
baseline-browser-mapping: 2.11.27
|
baseline-browser-mapping: 2.11.28
|
||||||
caniuse-lite: 1.0.30001815
|
caniuse-lite: 1.0.30001815
|
||||||
electron-to-chromium: 1.5.449
|
electron-to-chromium: 1.5.452
|
||||||
node-releases: 2.0.57
|
node-releases: 2.0.58
|
||||||
update-browserslist-db: 1.3.3(browserslist@4.29.3)
|
update-browserslist-db: 1.3.4(browserslist@4.29.3)
|
||||||
|
|
||||||
buffer-alloc-unsafe@1.1.0: {}
|
buffer-alloc-unsafe@1.1.0: {}
|
||||||
|
|
||||||
@@ -4125,11 +4125,11 @@ snapshots:
|
|||||||
|
|
||||||
concat-map@0.0.1: {}
|
concat-map@0.0.1: {}
|
||||||
|
|
||||||
concurrently@10.0.5:
|
concurrently@10.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk: 5.6.2
|
chalk: 5.6.2
|
||||||
rxjs: 7.8.2
|
rxjs: 7.8.2
|
||||||
shell-quote: 1.9.0
|
shell-quote: 1.12.0
|
||||||
supports-color: 10.2.2
|
supports-color: 10.2.2
|
||||||
tree-kill: 1.2.2
|
tree-kill: 1.2.2
|
||||||
yargs: 18.0.0
|
yargs: 18.0.0
|
||||||
@@ -4370,7 +4370,7 @@ snapshots:
|
|||||||
|
|
||||||
duplexer3@0.1.5: {}
|
duplexer3@0.1.5: {}
|
||||||
|
|
||||||
electron-to-chromium@1.5.449: {}
|
electron-to-chromium@1.5.452: {}
|
||||||
|
|
||||||
emoji-regex@10.6.0: {}
|
emoji-regex@10.6.0: {}
|
||||||
|
|
||||||
@@ -5307,7 +5307,7 @@ snapshots:
|
|||||||
css-select: 5.2.2
|
css-select: 5.2.2
|
||||||
he: 1.2.0
|
he: 1.2.0
|
||||||
|
|
||||||
node-releases@2.0.57: {}
|
node-releases@2.0.58: {}
|
||||||
|
|
||||||
normalize-package-data@2.5.0:
|
normalize-package-data@2.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5501,7 +5501,7 @@ snapshots:
|
|||||||
|
|
||||||
powershell-utils@0.2.1: {}
|
powershell-utils@0.2.1: {}
|
||||||
|
|
||||||
preact@11.0.0: {}
|
preact@11.0.1: {}
|
||||||
|
|
||||||
prelude-ls@1.2.1: {}
|
prelude-ls@1.2.1: {}
|
||||||
|
|
||||||
@@ -5724,7 +5724,7 @@ snapshots:
|
|||||||
|
|
||||||
shebang-regex@3.0.0: {}
|
shebang-regex@3.0.0: {}
|
||||||
|
|
||||||
shell-quote@1.9.0: {}
|
shell-quote@1.12.0: {}
|
||||||
|
|
||||||
signal-exit@3.0.7: {}
|
signal-exit@3.0.7: {}
|
||||||
|
|
||||||
@@ -5953,7 +5953,7 @@ snapshots:
|
|||||||
|
|
||||||
universalify@2.0.1: {}
|
universalify@2.0.1: {}
|
||||||
|
|
||||||
update-browserslist-db@1.3.3(browserslist@4.29.3):
|
update-browserslist-db@1.3.4(browserslist@4.29.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.29.3
|
browserslist: 4.29.3
|
||||||
escalade: 3.2.0
|
escalade: 3.2.0
|
||||||
@@ -5982,7 +5982,7 @@ snapshots:
|
|||||||
spdx-correct: 3.2.0
|
spdx-correct: 3.2.0
|
||||||
spdx-expression-parse: 3.0.1
|
spdx-expression-parse: 3.0.1
|
||||||
|
|
||||||
vite-plugin-imagemin@0.6.1(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2)):
|
vite-plugin-imagemin@0.6.1(supports-color@10.2.2)(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/imagemin': 7.0.1
|
'@types/imagemin': 7.0.1
|
||||||
'@types/imagemin-gifsicle': 7.0.4
|
'@types/imagemin-gifsicle': 7.0.4
|
||||||
@@ -6007,11 +6007,11 @@ snapshots:
|
|||||||
imagemin-webp: 6.1.0
|
imagemin-webp: 6.1.0
|
||||||
jpegtran-bin: 6.0.1
|
jpegtran-bin: 6.0.1
|
||||||
pathe: 0.2.0
|
pathe: 0.2.0
|
||||||
vite: 8.3.3(@types/node@26.6.4)(terser@5.51.2)
|
vite: 8.3.4(@types/node@26.6.4)(terser@5.51.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
vite-prerender-plugin@0.5.14(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2)):
|
vite-prerender-plugin@0.5.14(vite@8.3.4(@types/node@26.6.4)(terser@5.51.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
kolorist: 1.8.0
|
kolorist: 1.8.0
|
||||||
magic-string: 0.30.21
|
magic-string: 0.30.21
|
||||||
@@ -6019,9 +6019,9 @@ snapshots:
|
|||||||
simple-code-frame: 1.3.0
|
simple-code-frame: 1.3.0
|
||||||
source-map: 0.7.6
|
source-map: 0.7.6
|
||||||
stack-trace: 1.0.0
|
stack-trace: 1.0.0
|
||||||
vite: 8.3.3(@types/node@26.6.4)(terser@5.51.2)
|
vite: 8.3.4(@types/node@26.6.4)(terser@5.51.2)
|
||||||
|
|
||||||
vite@8.3.3(@types/node@26.6.4)(terser@5.51.2):
|
vite@8.3.4(@types/node@26.6.4)(terser@5.51.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
lightningcss: 1.33.0
|
lightningcss: 1.33.0
|
||||||
picomatch: 4.0.7
|
picomatch: 4.0.7
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import LogoutIcon from '@mui/icons-material/Logout';
|
|||||||
import MemoryIcon from '@mui/icons-material/Memory';
|
import MemoryIcon from '@mui/icons-material/Memory';
|
||||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||||
import RestartAltIcon from '@mui/icons-material/RestartAlt';
|
import RestartAltIcon from '@mui/icons-material/RestartAlt';
|
||||||
|
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
@@ -32,7 +33,7 @@ import SectionContent from 'components/SectionContent';
|
|||||||
import { toast } from 'components/toast';
|
import { toast } from 'components/toast';
|
||||||
|
|
||||||
import FirmwareUpload from './FirmwareUpload';
|
import FirmwareUpload from './FirmwareUpload';
|
||||||
import { HttpError, restart, setBootPartition } from './api';
|
import { HttpError, factoryReset, restart, setBootPartition } from './api';
|
||||||
import type { RecoveryPartition, RecoveryStatus } from './types';
|
import type { RecoveryPartition, RecoveryStatus } from './types';
|
||||||
|
|
||||||
const formatMB = (bytes: number) => `${(bytes / 1048576).toFixed(2)} MB`;
|
const formatMB = (bytes: number) => `${(bytes / 1048576).toFixed(2)} MB`;
|
||||||
@@ -97,6 +98,7 @@ interface DashboardProps {
|
|||||||
|
|
||||||
const Dashboard = ({ status, onRestarting, onSignOut }: DashboardProps) => {
|
const Dashboard = ({ status, onRestarting, onSignOut }: DashboardProps) => {
|
||||||
const [confirmBoot, setConfirmBoot] = useState<RecoveryPartition>();
|
const [confirmBoot, setConfirmBoot] = useState<RecoveryPartition>();
|
||||||
|
const [confirmFactoryReset, setConfirmFactoryReset] = useState(false);
|
||||||
const [pickedTarget, setPickedTarget] = useState<string>();
|
const [pickedTarget, setPickedTarget] = useState<string>();
|
||||||
const uploadTarget = pickedTarget ?? status.upload_target;
|
const uploadTarget = pickedTarget ?? status.upload_target;
|
||||||
|
|
||||||
@@ -132,6 +134,16 @@ const Dashboard = ({ status, onRestarting, onSignOut }: DashboardProps) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const doFactoryReset = async () => {
|
||||||
|
setConfirmFactoryReset(false);
|
||||||
|
try {
|
||||||
|
await factoryReset();
|
||||||
|
onRestarting(status.boot);
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const otaPartitions = status.partitions.filter((p) => !p.factory);
|
const otaPartitions = status.partitions.filter((p) => !p.factory);
|
||||||
const hasFirmware = otaPartitions.some((p) => p.valid);
|
const hasFirmware = otaPartitions.some((p) => p.valid);
|
||||||
const reason = recoveryReason(
|
const reason = recoveryReason(
|
||||||
@@ -317,6 +329,16 @@ const Dashboard = ({ status, onRestarting, onSignOut }: DashboardProps) => {
|
|||||||
<InfoRow label="Hostname" value={status.hostname} />
|
<InfoRow label="Hostname" value={status.hostname} />
|
||||||
|
|
||||||
<ButtonRow>
|
<ButtonRow>
|
||||||
|
{!status.disable_reset && (
|
||||||
|
<Button
|
||||||
|
startIcon={<SettingsBackupRestoreIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
color="error"
|
||||||
|
onClick={() => setConfirmFactoryReset(true)}
|
||||||
|
>
|
||||||
|
Factory Reset
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
startIcon={<RestartAltIcon />}
|
startIcon={<RestartAltIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
@@ -336,6 +358,35 @@ const Dashboard = ({ status, onRestarting, onSignOut }: DashboardProps) => {
|
|||||||
</ButtonRow>
|
</ButtonRow>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
sx={dialogStyle}
|
||||||
|
open={confirmFactoryReset}
|
||||||
|
onClose={() => setConfirmFactoryReset(false)}
|
||||||
|
>
|
||||||
|
<DialogTitle>Factory Reset</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
Are you sure you want to reset EMS-ESP to its factory defaults?
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
startIcon={<CancelIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
color="secondary"
|
||||||
|
onClick={() => setConfirmFactoryReset(false)}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
startIcon={<SettingsBackupRestoreIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
color="error"
|
||||||
|
onClick={() => void doFactoryReset()}
|
||||||
|
>
|
||||||
|
Factory Reset
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
sx={dialogStyle}
|
sx={dialogStyle}
|
||||||
open={!!confirmBoot}
|
open={!!confirmBoot}
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ export const setBootPartition = (partition: string) =>
|
|||||||
|
|
||||||
export const restart = () => request<void>('POST', '/rest/recovery/restart');
|
export const restart = () => request<void>('POST', '/rest/recovery/restart');
|
||||||
|
|
||||||
|
export const factoryReset = () => request<void>('POST', '/rest/recovery/format');
|
||||||
|
|
||||||
export interface UploadHandle {
|
export interface UploadHandle {
|
||||||
promise: Promise<UploadResult>;
|
promise: Promise<UploadResult>;
|
||||||
abort: () => void;
|
abort: () => void;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export interface RecoveryStatus {
|
|||||||
wifi_ip?: string;
|
wifi_ip?: string;
|
||||||
wifi_rssi?: number;
|
wifi_rssi?: number;
|
||||||
static_ip: boolean;
|
static_ip: boolean;
|
||||||
|
disable_reset: boolean; // factory reset is disabled in the EMS-ESP settings
|
||||||
// only on boards with Ethernet configured
|
// only on boards with Ethernet configured
|
||||||
eth_state?: 'disabled' | 'failed' | 'no_link' | 'connecting' | 'connected';
|
eth_state?: 'disabled' | 'failed' | 'no_link' | 'connecting' | 'connected';
|
||||||
eth_ip?: string;
|
eth_ip?: string;
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ const status = (authenticated) => ({
|
|||||||
wifi_started: false,
|
wifi_started: false,
|
||||||
wifi_connected: false,
|
wifi_connected: false,
|
||||||
static_ip: true,
|
static_ip: true,
|
||||||
|
disable_reset: false, // set to true to test with the factory reset disabled
|
||||||
eth_state: 'connected',
|
eth_state: 'connected',
|
||||||
eth_ip: '192.168.1.50',
|
eth_ip: '192.168.1.50',
|
||||||
running: 'boot',
|
running: 'boot',
|
||||||
@@ -162,6 +163,12 @@ export default function recoveryMock() {
|
|||||||
return restart();
|
return restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (url === '/rest/recovery/format' && req.method === 'POST') {
|
||||||
|
if (status(true).disable_reset) return send(res, 403);
|
||||||
|
send(res, 200);
|
||||||
|
return restart();
|
||||||
|
}
|
||||||
|
|
||||||
if (url === '/rest/recovery/boot' && req.method === 'POST') {
|
if (url === '/rest/recovery/boot' && req.method === 'POST') {
|
||||||
const { partition } = JSON.parse((await readBody(req)).toString() || '{}');
|
const { partition } = JSON.parse((await readBody(req)).toString() || '{}');
|
||||||
const p = state.partitions.find((x) => x.label === partition);
|
const p = state.partitions.find((x) => x.label === partition);
|
||||||
|
|||||||
@@ -60,8 +60,6 @@ unbuild_flags =
|
|||||||
[espressif32_base_4M]
|
[espressif32_base_4M]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.partitions = partitions/esp32_partition_4M.csv
|
board_build.partitions = partitions/esp32_partition_4M.csv
|
||||||
board_upload.flash_size = 4MB
|
|
||||||
board_build.app_partition_name = app0
|
|
||||||
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.05.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.8 based on IDF 5.5.4.260407
|
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.05.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.8 based on IDF 5.5.4.260407
|
||||||
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.09.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.12 based on IDF 5.5.5
|
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.09.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.12 based on IDF 5.5.5
|
||||||
|
|
||||||
@@ -69,8 +67,6 @@ platform = https://github.com/tasmota/platform-espressif32/releases/download/202
|
|||||||
[espressif32_base_16M]
|
[espressif32_base_16M]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.partitions = partitions/esp32_partition_16M.csv
|
board_build.partitions = partitions/esp32_partition_16M.csv
|
||||||
board_upload.flash_size = 16MB
|
|
||||||
board_build.app_partition_name = app0
|
|
||||||
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.05.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.8 based on IDF 5.5.4.260407
|
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.05.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.8 based on IDF 5.5.4.260407
|
||||||
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.09.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.12 based on IDF 5.5.5
|
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.09.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.12 based on IDF 5.5.5
|
||||||
build_flags =
|
build_flags =
|
||||||
@@ -82,8 +78,6 @@ build_flags =
|
|||||||
[espressif32_base_32M]
|
[espressif32_base_32M]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.partitions = partitions/esp32_partition_32M.csv
|
board_build.partitions = partitions/esp32_partition_32M.csv
|
||||||
board_upload.flash_size = 32MB
|
|
||||||
board_build.app_partition_name = app0
|
|
||||||
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.05.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.8 based on IDF 5.5.4.260407
|
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.05.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.8 based on IDF 5.5.4.260407
|
||||||
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.09.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.12 based on IDF 5.5.5
|
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.09.50/platform-espressif32.zip ; Tasmota Arduino Core 3.3.12 based on IDF 5.5.5
|
||||||
|
|
||||||
|
|||||||
+34
-3
@@ -5,7 +5,8 @@
|
|||||||
// if one is set), and serves a cut-down WebUI to upload a new EMS-ESP firmware into the OTA partitions
|
// if one is set), and serves a cut-down WebUI to upload a new EMS-ESP firmware into the OTA partitions
|
||||||
// or select which OTA partition to boot.
|
// or select which OTA partition to boot.
|
||||||
//
|
//
|
||||||
// The EMS-ESP settings in LittleFS are only ever read, never written.
|
// The EMS-ESP settings in LittleFS are only ever read, never written, except for a factory reset
|
||||||
|
// which erases them.
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
@@ -76,6 +77,7 @@ struct Settings {
|
|||||||
int8_t eth_power = -1;
|
int8_t eth_power = -1;
|
||||||
uint8_t eth_phy_addr = 0;
|
uint8_t eth_phy_addr = 0;
|
||||||
uint8_t eth_clock_mode = 0;
|
uint8_t eth_clock_mode = 0;
|
||||||
|
bool disable_reset = false; // factory reset is disabled in the EMS-ESP settings
|
||||||
std::vector<AdminUser> admins;
|
std::vector<AdminUser> admins;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,6 +176,7 @@ static void loadSettings() {
|
|||||||
settings.eth_power = doc["eth_power"] | -1;
|
settings.eth_power = doc["eth_power"] | -1;
|
||||||
settings.eth_phy_addr = doc["eth_phy_addr"] | 0;
|
settings.eth_phy_addr = doc["eth_phy_addr"] | 0;
|
||||||
settings.eth_clock_mode = doc["eth_clock_mode"] | 0;
|
settings.eth_clock_mode = doc["eth_clock_mode"] | 0;
|
||||||
|
settings.disable_reset = doc["disable_reset"] | false;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.clear();
|
doc.clear();
|
||||||
@@ -185,6 +188,8 @@ static void loadSettings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (settings.admins.empty()) {
|
if (settings.admins.empty()) {
|
||||||
|
// the admin user couldn't be read, so sign in with the factory login but never allow a factory reset
|
||||||
|
settings.disable_reset = true;
|
||||||
settings.admins.push_back({FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD});
|
settings.admins.push_back({FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,8 +454,9 @@ static void handleStatus(AsyncWebServerRequest * request) {
|
|||||||
root["wifi_ip"] = WiFi.localIP().toString();
|
root["wifi_ip"] = WiFi.localIP().toString();
|
||||||
root["wifi_rssi"] = WiFi.RSSI();
|
root["wifi_rssi"] = WiFi.RSSI();
|
||||||
}
|
}
|
||||||
root["wifi_started"] = wifi_started;
|
root["wifi_started"] = wifi_started;
|
||||||
root["static_ip"] = settings.static_ip;
|
root["static_ip"] = settings.static_ip;
|
||||||
|
root["disable_reset"] = settings.disable_reset;
|
||||||
|
|
||||||
// only on boards with Ethernet configured
|
// only on boards with Ethernet configured
|
||||||
if (eth_state[0] != '\0') {
|
if (eth_state[0] != '\0') {
|
||||||
@@ -550,6 +556,30 @@ static void handleRestart(AsyncWebServerRequest * request) {
|
|||||||
restart_at = millis() + RESTART_DELAY_MS;
|
restart_at = millis() + RESTART_DELAY_MS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// factory reset, erases all EMS-ESP settings and restarts
|
||||||
|
// only signed in admins are authorized (the recovery only accepts admin users), and only if not disabled in the settings
|
||||||
|
static void handleFactoryReset(AsyncWebServerRequest * request) {
|
||||||
|
if (!isAuthorized(request)) {
|
||||||
|
request->send(401);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (settings.disable_reset) {
|
||||||
|
LOG("Factory reset disabled");
|
||||||
|
request->send(403);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool ok = LittleFS.format(); // the only place the recovery writes to the filesystem
|
||||||
|
LOG("Factory reset %s", ok ? "done" : "failed");
|
||||||
|
if (!ok) {
|
||||||
|
request->send(500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->send(200);
|
||||||
|
restart_at = millis() + RESTART_DELAY_MS;
|
||||||
|
}
|
||||||
|
|
||||||
static void uploadFail(AsyncWebServerRequest * request, int code) {
|
static void uploadFail(AsyncWebServerRequest * request, int code) {
|
||||||
if (upload_error) {
|
if (upload_error) {
|
||||||
return;
|
return;
|
||||||
@@ -784,6 +814,7 @@ static void startNetwork() {
|
|||||||
static void startWebServer() {
|
static void startWebServer() {
|
||||||
server.on("/rest/recovery/status", HTTP_GET, handleStatus);
|
server.on("/rest/recovery/status", HTTP_GET, handleStatus);
|
||||||
server.on("/rest/recovery/restart", HTTP_POST, handleRestart);
|
server.on("/rest/recovery/restart", HTTP_POST, handleRestart);
|
||||||
|
server.on("/rest/recovery/format", HTTP_POST, handleFactoryReset);
|
||||||
server.on("/rest/uploadFile", HTTP_POST, handleUploadComplete, handleUpload);
|
server.on("/rest/uploadFile", HTTP_POST, handleUploadComplete, handleUpload);
|
||||||
server.addHandler(new AsyncCallbackJsonWebHandler("/rest/signIn", handleSignIn));
|
server.addHandler(new AsyncCallbackJsonWebHandler("/rest/signIn", handleSignIn));
|
||||||
server.addHandler(new AsyncCallbackJsonWebHandler("/rest/recovery/boot", handleSetBoot));
|
server.addHandler(new AsyncCallbackJsonWebHandler("/rest/recovery/boot", handleSetBoot));
|
||||||
|
|||||||
+20
-13
@@ -959,23 +959,30 @@ void System::button_OnDblClick(PButton & b) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// button long press
|
// button long press, held for BUTTON_LongPressDelay (3000 ms, 3 seconds)
|
||||||
|
// restart EMS-ESP
|
||||||
void System::button_OnLongPress(PButton & b) {
|
void System::button_OnLongPress(PButton & b) {
|
||||||
LOG_NOTICE("Button pressed - long press - restart EMS-ESP");
|
|
||||||
EMSESP::system_.system_restart("boot");
|
|
||||||
}
|
|
||||||
|
|
||||||
// button indefinite press
|
|
||||||
void System::button_OnVLongPress(PButton & b) {
|
|
||||||
if (EMSESP::system_.disable_reset()) {
|
if (EMSESP::system_.disable_reset()) {
|
||||||
LOG_NOTICE("Factory reset disabled");
|
LOG_NOTICE("reset disabled, can't boot");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_NOTICE("Button pressed - very long press - perform factory reset");
|
LOG_NOTICE("Button pressed - long press - restart EMS-ESP");
|
||||||
EMSESP::led_.start_led_fast_flash(5); // Start LED flash timer for 5 seconds
|
EMSESP::system_.system_restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// push button
|
// button indefinite press, held for BUTTON_VLongPressDelay (6000 ms, 6 seconds)
|
||||||
|
// restart EMS_ESP into the Recovery boot menu, where you can optionally do a factory reset
|
||||||
|
void System::button_OnVLongPress(PButton & b) {
|
||||||
|
if (EMSESP::system_.disable_reset()) {
|
||||||
|
LOG_NOTICE("reset disabled, can't boot");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG_NOTICE("Button pressed - very long press - perform factory reset in Recovery Mode");
|
||||||
|
EMSESP::system_.system_restart("boot");
|
||||||
|
// EMSESP::led_.start_led_fast_flash(5); // Start LED flash timer for 5 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
// push button, held for BUTTON_Debounce (200 ms)
|
||||||
void System::button_init() {
|
void System::button_init() {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
if (!myPButton_.init(pbutton_gpio_, HIGH)) {
|
if (!myPButton_.init(pbutton_gpio_, HIGH)) {
|
||||||
@@ -3934,9 +3941,9 @@ void System::remove_optional_gpio(uint8_t pin) {
|
|||||||
// set unused gpios to default state input high-Z
|
// set unused gpios to default state input high-Z
|
||||||
void System::reset_unused_gpios() {
|
void System::reset_unused_gpios() {
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
constexpr uint8_t tx0 = 1; // don't change tx0 pin
|
constexpr uint8_t tx0 = 1; // don't change tx0 pin
|
||||||
#else
|
#else
|
||||||
constexpr uint8_t tx0 = 255; // no valid pin, chips have native USB, tx0 not connected to transceiver
|
constexpr uint8_t tx0 = 255; // no valid pin, chips have native USB, tx0 not connected to transceiver
|
||||||
#endif
|
#endif
|
||||||
for (const auto & pin : valid_system_gpios_) {
|
for (const auto & pin : valid_system_gpios_) {
|
||||||
auto it = std::find_if(used_gpios_.begin(), used_gpios_.end(), [pin](const GpioUsage & usage) { return usage.pin == pin; });
|
auto it = std::find_if(used_gpios_.begin(), used_gpios_.end(), [pin](const GpioUsage & usage) { return usage.pin == pin; });
|
||||||
|
|||||||
+2
-2
@@ -409,8 +409,8 @@ class System {
|
|||||||
static constexpr uint32_t BUTTON_DblClickDelay = 250; // Max period between clicks for a double click event (in ms)
|
static constexpr uint32_t BUTTON_DblClickDelay = 250; // Max period between clicks for a double click event (in ms)
|
||||||
|
|
||||||
// button press delays
|
// button press delays
|
||||||
static constexpr uint32_t BUTTON_LongPressDelay = 3000; // Hold period for a long press event (in ms) - ~3 seconds
|
static constexpr uint32_t BUTTON_LongPressDelay = 3000; // Hold period for a long press event (in ms) - 3 seconds
|
||||||
static constexpr uint32_t BUTTON_VLongPressDelay = 9500; // Hold period for a very long press event (in ms) - !10 seconds
|
static constexpr uint32_t BUTTON_VLongPressDelay = 9500; // Hold period for a very long press event (in ms) - 9.5 seconds
|
||||||
|
|
||||||
// healthcheck
|
// healthcheck
|
||||||
#ifdef EMSESP_PINGTEST
|
#ifdef EMSESP_PINGTEST
|
||||||
|
|||||||
Reference in New Issue
Block a user