From fe50c9f6d0f69ea8375925042db9d26d1104174b Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:51:17 +0200 Subject: [PATCH 01/66] autodetect, download and install firmware upgrades --- CHANGELOG_LATEST.md | 3 +- interface/src/api/system.ts | 3 + interface/src/app/settings/DownloadUpload.tsx | 199 +++++++++++------- interface/src/i18n/de/index.ts | 18 +- interface/src/i18n/en/index.ts | 16 +- interface/src/i18n/fr/index.ts | 16 +- interface/src/i18n/it/index.ts | 16 +- interface/src/i18n/nl/index.ts | 16 +- interface/src/i18n/no/index.ts | 16 +- interface/src/i18n/pl/index.ts | 16 +- interface/src/i18n/sk/index.ts | 16 +- interface/src/i18n/sv/index.ts | 16 +- interface/src/i18n/tr/index.ts | 16 +- interface/src/types/system.ts | 2 +- mock-api/rest_server.ts | 20 +- src/version.h | 2 +- src/web/WebStatusService.cpp | 68 +++--- src/web/WebStatusService.h | 8 +- 18 files changed, 290 insertions(+), 177 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index b43cc5c6b..5a5e0a2bb 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -5,7 +5,7 @@ ## **IMPORTANT! BREAKING CHANGES with 3.6.5** - new device WATER shows dhw entities from MM100 and SM100 in dhw setting -- renamed WWC to DHW, always create DHW nests/topics, remove ww prefix from mqtt names [#1634](https://github.com/emsesp/EMS-ESP32/issues/1634). To preserve current value of dhw energy (nrgww), follow ([#1938]https://github.com/emsesp/EMS-ESP32/issues/1938) +- renamed WWC to DHW, always create DHW nests/topics, remove ww prefix from mqtt names [#1634](https://github.com/emsesp/EMS-ESP32/issues/1634). To preserve current value of dhw energy (nrgww), follow ([#1938]) - change temperaturesensor id to underscore - system/info API command has it's JSON keys and names changed to camelCase @@ -35,6 +35,7 @@ - RC310 cooling parameters [#1857](https://github.com/emsesp/EMS-ESP32/issues/1857) - command `api/device/entities` [#1897](https://github.com/emsesp/EMS-ESP32/issues/1897) - switchprogmode [#1903] +- Autodetect and download firmware upgrades ## Fixed diff --git a/interface/src/api/system.ts b/interface/src/api/system.ts index ce380e8b8..a9749e7e9 100644 --- a/interface/src/api/system.ts +++ b/interface/src/api/system.ts @@ -48,3 +48,6 @@ export const uploadFile = (file: File) => { export const uploadURL = (data: { url: string }) => alovaInstance.Post('/rest/uploadURL', data); + +export const checkUpgrade = (data: { version: string }) => + alovaInstance.Post('/rest/checkUpgrade', data); diff --git a/interface/src/app/settings/DownloadUpload.tsx b/interface/src/app/settings/DownloadUpload.tsx index 058ec7ebc..a195049d2 100644 --- a/interface/src/app/settings/DownloadUpload.tsx +++ b/interface/src/app/settings/DownloadUpload.tsx @@ -1,10 +1,21 @@ import { useState } from 'react'; import { toast } from 'react-toastify'; +import CancelIcon from '@mui/icons-material/Cancel'; import DownloadIcon from '@mui/icons-material/GetApp'; +import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import WarningIcon from '@mui/icons-material/Warning'; -import { Box, Button, Divider, Link, Typography } from '@mui/material'; +import { + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Link, + Typography +} from '@mui/material'; import * as SystemApi from 'api/system'; import { @@ -14,7 +25,7 @@ import { getSchedule, getSettings } from 'api/app'; -import { getDevVersion, getStableVersion } from 'api/system'; +import { checkUpgrade, getDevVersion, getStableVersion } from 'api/system'; import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova/client'; @@ -34,6 +45,9 @@ const DownloadUpload = () => { const [restarting, setRestarting] = useState(false); const [restartNeeded, setRestartNeeded] = useState(false); + const [openDialog, setOpenDialog] = useState(false); + const [useDev, setUseDev] = useState(false); + const [upgradeAvailable, setUpgradeAvailable] = useState(false); const { send: sendSettings } = useRequest(getSettings(), { immediate: false @@ -95,20 +109,24 @@ const DownloadUpload = () => { }); }; + const { send: sendCheckUpgrade } = useRequest(checkUpgrade, { + immediate: false + }).onSuccess((event) => { + setUpgradeAvailable(event.data.upgradeable); + }); + // called immediately to get the latest version, on page load const { data: latestVersion } = useRequest(getStableVersion, { - immediate: true - // uncomment for testing - // https://github.com/emsesp/EMS-ESP32/releases/download/v3.6.5/EMS-ESP-3_6_5-ESP32-16MB+.bin + // uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/v3.6.5/EMS-ESP-3_6_5-ESP32-16MB+.bin // immediate: false, // initialData: '3.6.5' }); const { data: latestDevVersion } = useRequest(getDevVersion, { - immediate: true - // uncomment for testing - // https://github.com/emsesp/EMS-ESP32/releases/download/latest/EMS-ESP-3_7_0-dev_31-ESP32-16MB+.bin + // uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/latest/EMS-ESP-3_7_0-dev_31-ESP32-16MB+.bin // immediate: false, - // initialData: '3.7.0-dev.31' + // initialData: '3.7.0-dev.32' + }).onSuccess((event) => { + void sendCheckUpgrade({ version: event.data }); }); const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/'; @@ -119,8 +137,17 @@ const DownloadUpload = () => { const DEV_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md'; - const getBinURL = (v: string) => - 'EMS-ESP-' + v.replaceAll('.', '_') + '-' + getPlatform() + '.bin'; + const getBinURL = (useDev: boolean) => { + const filename = + 'EMS-ESP-' + + (useDev ? latestDevVersion : latestVersion).replaceAll('.', '_') + + '-' + + getPlatform() + + '.bin'; + return useDev + ? DEV_URL + filename + : STABLE_URL + 'v' + latestVersion + '/' + filename; + }; const getPlatform = () => { return ( @@ -181,11 +208,72 @@ const DownloadUpload = () => { useLayoutTitle(LL.DOWNLOAD_UPLOAD()); + const renderUploadDialog = () => { + if (latestDevVersion === undefined || latestVersion === undefined) { + return null; + } + return ( + setOpenDialog(false)} + > + + {LL.INSTALL('') + + ' ' + + (useDev ? LL.DEVELOPMENT() : LL.STABLE()) + + ' Firmware'} + + + + {LL.INSTALL_VERSION(useDev ? latestDevVersion : latestVersion)} + + + {LL.RELEASE_NOTES()} + +  |  + + {LL.DOWNLOAD(1)} + + + + + + + + ); + }; + + const showFirmwareDialog = (useDev: boolean) => { + setUseDev(useDev); + setOpenDialog(true); + }; + const content = () => { if (!data) { return ; } + const isDev = data.emsesp_version.includes('dev'); + return ( <> @@ -274,76 +362,49 @@ const DownloadUpload = () => { - {LL.VERSION_ON() + ' '} - {data.emsesp_version} ({getPlatform()}) - - {latestVersion && ( - - {LL.THE_LATEST()} {LL.OFFICIAL()} {LL.RELEASE_IS()} -  {latestVersion} -  ( - - {LL.RELEASE_NOTES()} - - ) ( - - {LL.DOWNLOAD(1)} - - ) + + {LL.VERSION() + ':'} {data.emsesp_version} + {data.build_flags && ( + +   ({data.build_flags}) + + )} + + + Platform: {getPlatform()} + + + Release: {isDev ? LL.DEVELOPMENT() : LL.STABLE()} + {!isDev && ( - - )} - {latestDevVersion && ( - - {LL.THE_LATEST()} {LL.DEVELOPMENT()} {LL.RELEASE_IS()} -   - {latestDevVersion} -  ( - - {LL.RELEASE_NOTES()} - - ) ( - - {LL.DOWNLOAD(1)} - - ) + )} + + {upgradeAvailable ? ( + + +   {LL.UPGRADE_AVAILABLE()} - + + ) : ( + {LL.LATEST_VERSION()} )} + {renderUploadDialog()} @@ -374,11 +435,7 @@ const DownloadUpload = () => { return ( - {restarting ? ( - - ) : ( - content() - )} + {restarting ? : content()} ); }; diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index aca27cd43..a71224853 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -145,7 +145,7 @@ const de: Translation = { CUSTOMIZATIONS_HELP_1: 'Wählen Sie ein Gerät aus und passen Sie die Entitäten mithilfe der Optionen an', CUSTOMIZATIONS_HELP_2: 'Als Favorit markieren', CUSTOMIZATIONS_HELP_3: 'Schreibaktion deaktivieren', - CUSTOMIZATIONS_HELP_4: 'von MQTT und API ausschließen', + CUSTOMIZATIONS_HELP_4: 'Von MQTT und API ausschließen', CUSTOMIZATIONS_HELP_5: 'Aus dem Kontrollzentrum ausblenden', CUSTOMIZATIONS_HELP_6: 'Aus dem Speicher löschen', SELECT_DEVICE: 'Wählen Sie ein Gerät aus', @@ -161,7 +161,7 @@ const de: Translation = { HELP_INFORMATION_5: 'EMS-ESP ist ein freies Open-Source Projekt. Bitte unterstützen Sie die zukünftige Entwicklung mit einem "Star" auf GitHub!', UPLOAD: 'Hochladen', DOWNLOAD: '{{H|h|h}}erunterladen', - INSTALL: 'Installieren', + INSTALL: 'Installieren {0}', ABORTED: 'abgebrochen', FAILED: 'gescheitert', SUCCESSFUL: 'erfolgreich', @@ -169,16 +169,13 @@ const de: Translation = { LOG_OF: '{0}protokoll', STATUS_OF: '{0} Status', DOWNLOAD_UPLOAD: 'Herunterladen/Hochladen', - VERSION_ON: 'Sie verwenden derzeit', CLOSE: 'Schließen', USE: 'Verwenden Sie', FACTORY_RESET: 'Werkseinstellung', SYSTEM_FACTORY_TEXT: 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu', SYSTEM_FACTORY_TEXT_DIALOG: 'Sind Sie sicher alle Einstellungen auf Werkseinstellung zu setzen?', - THE_LATEST: 'Die neueste', - OFFICIAL: 'offizielle', + STABLE: 'Stable', // TODO translate DEVELOPMENT: 'Entwicklungs', - RELEASE_IS: 'Release ist', RELEASE_NOTES: 'Versionshinweise', EMS_ESP_VER: 'EMS-ESP Version', UPTIME: 'System Betriebszeit', @@ -333,9 +330,14 @@ const de: Translation = { ENABLE_MODBUS: 'Modbus aktivieren', VIEW_LOG: 'Sehen Sie sich das Protokoll an, um Probleme zu diagnostizieren', UPLOAD_DRAG: 'Ziehen Sie eine Datei hierher oder klicken Sie, um eine auszuwählen', - SERVICES: 'Dienstleistungen', + SERVICES: 'Dienste', ALLVALUES: 'Alle Werte', - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Sonderfunktionen', + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default de; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 196b3da34..ac069aab2 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -161,7 +161,7 @@ const en: Translation = { HELP_INFORMATION_5: 'EMS-ESP is a free and open-source project. Please support its future development by giving it a star on GitHub!', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', - INSTALL: 'Install', + INSTALL: 'Install {0}', ABORTED: 'aborted', FAILED: 'failed', SUCCESSFUL: 'successful', @@ -169,16 +169,13 @@ const en: Translation = { LOG_OF: '{0} Log', STATUS_OF: '{0} Status', DOWNLOAD_UPLOAD: 'Download/Upload', - VERSION_ON: 'You are currently on version', CLOSE: 'Close', USE: 'Use', FACTORY_RESET: 'Factory Reset', SYSTEM_FACTORY_TEXT: 'Device has been factory reset and will now restart', SYSTEM_FACTORY_TEXT_DIALOG: 'Are you sure you want to reset EMS-ESP to its factory defaults?', - THE_LATEST: 'The latest', - OFFICIAL: 'official', - DEVELOPMENT: 'development', - RELEASE_IS: 'release is', + STABLE: 'Stable', + DEVELOPMENT: 'Development', RELEASE_NOTES: 'release notes', EMS_ESP_VER: 'EMS-ESP Version', UPTIME: 'System Uptime', @@ -335,7 +332,12 @@ const en: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', SERVICES: 'Services', ALLVALUES: 'All Values', - SPECIAL_FUNCTIONS: 'Special Functions' + SPECIAL_FUNCTIONS: 'Special Functions', + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default en; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 6fee7f0a5..cd614e02c 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -161,7 +161,7 @@ const fr: Translation = { HELP_INFORMATION_5: 'EMS-ESP est un projet libre et open-source. Merci de soutenir son développement futur en lui donnant une étoile sur GitHub !', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', - INSTALL: 'Installer', + INSTALL: 'Installer {0}', ABORTED: 'annulé', FAILED: 'échoué', SUCCESSFUL: 'réussi', @@ -169,16 +169,13 @@ const fr: Translation = { LOG_OF: '{0} Log', STATUS_OF: 'Statut {0}', DOWNLOAD_UPLOAD: 'Download/Upload', // TODO translate - VERSION_ON: 'You are currently on', // TODO translate CLOSE: 'Fermer', USE: 'Utiliser', FACTORY_RESET: 'Réinitialisation', SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer", SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?", - THE_LATEST: 'La dernière', - OFFICIAL: 'officielle', - DEVELOPMENT: 'développement', - RELEASE_IS: 'release est', // TODO translate + STABLE: 'Stable', // TODO translate + DEVELOPMENT: 'Développement', RELEASE_NOTES: 'notes de version', EMS_ESP_VER: 'Version EMS-ESP', UPTIME: 'Durée de fonctionnement du système', @@ -335,7 +332,12 @@ const fr: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate // TODO translate }; export default fr; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 2b837addb..6dbf4707c 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -161,7 +161,7 @@ const it: Translation = { HELP_INFORMATION_5: 'EMS-ESP è un progetto gratuito e open-source. Supporta il suo sviluppo futuro assegnandogli una stella su GitHub!', UPLOAD: 'Carica', DOWNLOAD: 'Scarica', - INSTALL: 'Installare', + INSTALL: 'Installare {0}', ABORTED: 'Annullato', FAILED: 'Fallito', SUCCESSFUL: 'Riuscito', @@ -169,16 +169,13 @@ const it: Translation = { LOG_OF: 'Registro {0}', STATUS_OF: 'Stato {0}', DOWNLOAD_UPLOAD: 'Scaricamento/Caricamento', - VERSION_ON: 'Attualmente stai eseguendo la versione', CLOSE: 'Chiudere', USE: 'Usa', FACTORY_RESET: 'Impostazioni di fabbrica', SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato', SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??', - THE_LATEST: 'Ultima', - OFFICIAL: 'ufficiale', - DEVELOPMENT: 'sviluppo', - RELEASE_IS: 'rilascio é', + STABLE: 'Stable', // TODO translate + DEVELOPMENT: 'Sviluppo', RELEASE_NOTES: 'note rilascio', EMS_ESP_VER: 'Versione EMS-ESP', UPTIME: 'Tempo di attività del sistema', @@ -335,7 +332,12 @@ const it: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default it; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index a6d93bfe9..bf47983e9 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -161,7 +161,7 @@ const nl: Translation = { HELP_INFORMATION_5: 'EMS-ESP is een gratis en open source project. Steun ons met een Star op GitHub!', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', - INSTALL: 'Installeren', + INSTALL: 'Installeren {0}', ABORTED: 'afgebroken', FAILED: 'mislukt', SUCCESSFUL: 'successvol', @@ -169,16 +169,13 @@ const nl: Translation = { LOG_OF: '{0} Log', STATUS_OF: '{0} Status', DOWNLOAD_UPLOAD: 'Download/Upload', - VERSION_ON: 'U bevindt zich momenteel op versie', CLOSE: 'Sluiten', USE: 'Gebruik', FACTORY_RESET: 'Fabrieksinstellingen', SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen', SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?', - THE_LATEST: 'De laatste', - OFFICIAL: 'official', - DEVELOPMENT: 'development', - RELEASE_IS: 'release is', + STABLE: 'Stable', + DEVELOPMENT: 'Development', RELEASE_NOTES: 'release notes', EMS_ESP_VER: 'EMS-ESP Versie', UPTIME: 'Systeem Uptime', @@ -335,7 +332,12 @@ const nl: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default nl; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 51dacd356..7471b596b 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -161,7 +161,7 @@ const no: Translation = { HELP_INFORMATION_5: 'EMS-ESP er gratis og åpen kildekode. Bidra til utviklingen ved å gi oss en stjerne på GitHub!', UPLOAD: 'Opplasning', DOWNLOAD: '{{N|n|n}}edlasting', - INSTALL: 'Installer', + INSTALL: 'Installer {0}', ABORTED: 'avbrutt', FAILED: 'feilet', SUCCESSFUL: 'vellykket', @@ -169,16 +169,13 @@ const no: Translation = { LOG_OF: '{0} Logg', STATUS_OF: '{0} Status', DOWNLOAD_UPLOAD: 'Nedlasting/Opp', - VERSION_ON: 'You are currently on', // TODO translate CLOSE: 'Steng', USE: 'Bruk', FACTORY_RESET: 'Sett tilbake til fabrikkinstilling', SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte', SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?', - THE_LATEST: 'Den nyeste', - OFFICIAL: 'official', - DEVELOPMENT: 'development', - RELEASE_IS: 'release er', + STABLE: 'Stable', // TODO translate + DEVELOPMENT: 'Development', RELEASE_NOTES: 'release notes', EMS_ESP_VER: 'EMS-ESP Version', UPTIME: 'System Oppetid', @@ -335,7 +332,12 @@ const no: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default no; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index b19451681..48f97782e 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -161,7 +161,7 @@ const pl: BaseTranslation = { HELP_INFORMATION_5: 'EMS-ESP jest darmowym projektem typu open-source. Aby go wesprzeć, rozważ przyznanie nam gwiazdki na GitHub!', UPLOAD: 'Wysyłanie', DOWNLOAD: '{{P|p||P}}obier{{anie|z||z}}', - INSTALL: 'Zainstalować', + INSTALL: 'Zainstalować {0}', ABORTED: 'zostało przerwane!', FAILED: 'nie powiodł{{o|a|}} się!', SUCCESSFUL: 'powiodło się.', @@ -169,16 +169,13 @@ const pl: BaseTranslation = { LOG_OF: 'Log {0}', STATUS_OF: 'Status {0}', DOWNLOAD_UPLOAD: 'Plików przesyłanie', - VERSION_ON: 'Aktualnie używasz', CLOSE: 'Zamknij', USE: 'Aby zaktualizować firmware skorzystaj z funkcji', FACTORY_RESET: 'Ustawienia fabryczne', SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.', SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP? ', - THE_LATEST: 'Najnowsze', - OFFICIAL: 'oficjalne', - DEVELOPMENT: 'testowe', - RELEASE_IS: 'wydanie to', + STABLE: 'Stable', // TODO translate + DEVELOPMENT: 'Testowe', RELEASE_NOTES: 'lista zmian', EMS_ESP_VER: 'Wersja EMS-ESP', UPTIME: 'Czas działania systemu', @@ -335,7 +332,12 @@ const pl: BaseTranslation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index b1d996c48..7360741f7 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -161,7 +161,7 @@ const sk: Translation = { HELP_INFORMATION_5: 'EMS-ESP je bezplatný a open source projekt. Podporte jeho budúci vývoj tým, že mu dáte hviezdičku na GitHub!', UPLOAD: 'Nahrať', DOWNLOAD: '{{S|s|s}}tiahnuť', - INSTALL: 'Inštalovať', + INSTALL: 'Inštalovať {0}', ABORTED: 'zrušené', FAILED: 'chybné', SUCCESSFUL: 'úspešné', @@ -169,16 +169,13 @@ const sk: Translation = { LOG_OF: '{0} Log', STATUS_OF: '{0} Stav', DOWNLOAD_UPLOAD: 'Stiahnuť/Nahrať', - VERSION_ON: 'Momentálne nainštalovaná verzia: ', CLOSE: 'Zatvoriť', USE: 'Použiť', FACTORY_RESET: 'Továrenské nastavenia', SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje', SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?', - THE_LATEST: 'Posledná', - OFFICIAL: 'officiálna', - DEVELOPMENT: 'vývojárska', - RELEASE_IS: 'verzia je', + STABLE: 'Stable', // TODO translate + DEVELOPMENT: 'Vývojárska', RELEASE_NOTES: 'poznámky k verzii', EMS_ESP_VER: 'EMS-ESP verzia', UPTIME: 'Beh systému', @@ -335,7 +332,12 @@ const sk: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default sk; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 68635b772..4b71f483a 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -161,7 +161,7 @@ const sv: Translation = { HELP_INFORMATION_5: 'EMS-ESP är gratis och är öppen källkod. Bidra till utvecklingen genom att ge oss en stjärna på GitHub!', UPLOAD: 'Uppladdning', DOWNLOAD: '{{N|n|n}}edladdning', - INSTALL: 'Installera', + INSTALL: 'Installera {0}', ABORTED: 'Avbruten', FAILED: 'Misslyckades', SUCCESSFUL: 'Lyckades', @@ -169,16 +169,13 @@ const sv: Translation = { LOG_OF: '{0} Logg', STATUS_OF: '{0} Status', DOWNLOAD_UPLOAD: 'Nedladdning/Upp', - VERSION_ON: 'You are currently on', // TODO translate CLOSE: 'Stäng', USE: 'Använd', FACTORY_RESET: 'Fabriksåterställning', SYSTEM_FACTORY_TEXT: 'Enheten har blivit fabriksåterställd och startar nu om', SYSTEM_FACTORY_TEXT_DIALOG: 'Är du säker att du vill fabriksåterställa enheten?', - THE_LATEST: 'Den senaste', - OFFICIAL: 'officiell', - DEVELOPMENT: 'utveckling', - RELEASE_IS: 'release är', + STABLE: 'Stable', // TODO translate + DEVELOPMENT: 'Utveckling', RELEASE_NOTES: 'release-logg', EMS_ESP_VER: 'EMS-ESP Version', UPTIME: 'Systemets Upptid', @@ -335,7 +332,12 @@ const sv: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default sv; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 083074faf..6e2f3e3b8 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -161,7 +161,7 @@ const tr: Translation = { HELP_INFORMATION_5: 'EMS-ESP ücretsiz ve açık kaynaklı bir projedir. Lütfen geliştirmeyi desteklemek için GitHubda projeye yıldız verin!', UPLOAD: 'Yükleme', DOWNLOAD: '{{İ|i|i}}İndirme', - INSTALL: 'Düzenlemek', + INSTALL: 'Düzenlemek {0}', ABORTED: 'iptal edildi', FAILED: 'başarısız', SUCCESSFUL: 'başarılı', @@ -169,16 +169,13 @@ const tr: Translation = { LOG_OF: '{0} Kaydı', STATUS_OF: '{0} Durumu', DOWNLOAD_UPLOAD: 'İndirme/Yükleme', - VERSION_ON: 'You are currently on', // TODO translate CLOSE: 'Kapat', USE: 'KUllan', FACTORY_RESET: 'Fabrika ayarına dönme', SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak', SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?', - THE_LATEST: 'En son', - OFFICIAL: 'resmi', - DEVELOPMENT: 'geliştirme', - RELEASE_IS: 'release is', // TODO translate + STABLE: 'Stable', // TODO translate + DEVELOPMENT: 'Geliştirme', RELEASE_NOTES: 'yayınlanma notları', EMS_ESP_VER: 'EMS-ESP Sürümü', UPTIME: 'Sistem Çalışma Süresi', @@ -335,7 +332,12 @@ const tr: Translation = { UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate SERVICES: 'Services', // TODO translate ALLVALUES: 'All Values', // TODO translate - SPECIAL_FUNCTIONS: 'Special Functions' // TODO translate + SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate + WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate + INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate + SWITCH_DEV: 'Switch to development version', // TODO translate + UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate + LATEST_VERSION: 'You are using the latest version.' // TODO translate }; export default tr; diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index 2d59ca9d4..62b425677 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -4,6 +4,7 @@ import type { NetworkConnectionStatus } from './network'; export interface HardwareStatus { emsesp_version: string; + build_flags: string; esp_platform: string; max_alloc_heap: number; cpu_type: string; @@ -30,7 +31,6 @@ export interface HardwareStatus { export interface SystemStatus { emsesp_version: string; - esp_platform: string; status: busConnectionStatus; uptime: number; bus_uptime: number; diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index 5162afc3c..fa6dd60a3 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -368,8 +368,10 @@ const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn'; const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'; const hardware_status = { - emsesp_version: '3.7-demo', + emsesp_version: '3.7.0-dev.33', + // emsesp_version: '3.6.5', esp_platform: 'ESP32S3', + build_flags: 'DEMO', cpu_type: 'ESP32-S3', cpu_rev: 0, cpu_cores: 2, @@ -395,8 +397,8 @@ const hardware_status = { }; const system_status = { - emsesp_version: '3.7-demo', - esp_platform: 'ESP32', + emsesp_version: '3.7.0-dev.33', + // emsesp_version: '3.6.5', status: 0, // status: 2, uptime: 77186, @@ -452,6 +454,7 @@ const EMSESP_DEVICEDATA_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceData/:id?'; const EMSESP_DEVICEENTITIES_ENDPOINT1 = REST_ENDPOINT_ROOT + 'deviceEntities'; const EMSESP_DEVICEENTITIES_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceEntities/:id?'; +const EMSESP_CHECK_UPGRADE_ENDPOINT = REST_ENDPOINT_ROOT + 'checkUpgrade'; const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'; const EMSESP_WRITE_DEVICEVALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue'; const EMSESP_WRITE_DEVICENAME_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceName'; @@ -4529,6 +4532,17 @@ router return status(200); }) + // check upgrade + .post(EMSESP_CHECK_UPGRADE_ENDPOINT, async (request: any) => { + const content = await request.json(); + console.log('check upgrade', content.version); + const data = { + upgradeable: true + // upgradeable: false + }; + return data; + }) + // Settings - board profile .post(EMSESP_BOARDPROFILE_ENDPOINT, async (request: any) => { const content = await request.json(); diff --git a/src/version.h b/src/version.h index a993524cf..639371d84 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.32" +#define EMSESP_APP_VERSION "3.7.0-dev.33" diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index a9d56cedc..d7037f838 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -24,12 +24,15 @@ namespace emsesp { -// /rest/hardwareStatus WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { - server->on(HARDWARE_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { hardwareStatus(request); }); - server->on(SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { systemStatus(request); }); + // GET + server->on(EMSESP_HARDWARE_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { hardwareStatus(request); }); + server->on(EMSESP_SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { systemStatus(request); }); + // POST + server->on(EMSESP_CHECK_UPGRADE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { checkUpgrade(request, json); }); } +// /rest/systemStatus void WebStatusService::systemStatus(AsyncWebServerRequest * request) { // This is a litle trick for the OTA upload. We don't want the React RestartService to think we're finished // with the upload so we fake it and pretent the /rest/systemStatus is not available. That way the spinner keeps spinning. @@ -42,25 +45,15 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) { auto * response = new AsyncJsonResponse(false); JsonObject root = response->getRoot(); -#ifdef EMSESP_DEBUG - root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (DEBUG)"; -#else -#ifdef EMSESP_TEST - root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (TEST)"; -#else root["emsesp_version"] = EMSESP_APP_VERSION; -#endif -#endif - - root["esp_platform"] = EMSESP_PLATFORM; // from default_settings.h: ESP32, ESP32C3, ESP32S2, ESP32S3 - root["status"] = EMSESP::bus_status(); // 0, 1 or 2 - root["bus_uptime"] = EMSbus::bus_uptime(); - root["num_devices"] = EMSESP::count_devices(); - root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors(); - root["num_analogs"] = EMSESP::analogsensor_.no_sensors(); - root["free_heap"] = EMSESP::system_.getHeapMem(); - root["uptime"] = uuid::get_uptime_sec(); - root["mqtt_status"] = EMSESP::mqtt_.connected(); + root["status"] = EMSESP::bus_status(); // 0, 1 or 2 + root["bus_uptime"] = EMSbus::bus_uptime(); + root["num_devices"] = EMSESP::count_devices(); + root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors(); + root["num_analogs"] = EMSESP::analogsensor_.no_sensors(); + root["free_heap"] = EMSESP::system_.getHeapMem(); + root["uptime"] = uuid::get_uptime_sec(); + root["mqtt_status"] = EMSESP::mqtt_.connected(); #ifndef EMSESP_STANDALONE root["ntp_status"] = [] { @@ -104,21 +97,25 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) { request->send(response); } +// /rest/hardwareStatus void WebStatusService::hardwareStatus(AsyncWebServerRequest * request) { EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap auto * response = new AsyncJsonResponse(false); JsonObject root = response->getRoot(); -#ifdef EMSESP_DEBUG - root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (DEBUG)"; -#else -#ifdef EMSESP_TEST - root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (TEST)"; -#else root["emsesp_version"] = EMSESP_APP_VERSION; + +#ifdef EMSESP_DEBUG +#ifdef EMSESP_TEST + root["build_flags"] = "DEBUG,TEST"; +#else + root["build_flags"] = "DEBUG"; #endif +#elif defined(EMSESP_TEST) + root["build_flags"] = "TEST"; #endif + root["esp_platform"] = EMSESP_PLATFORM; #ifndef EMSESP_STANDALONE @@ -154,4 +151,21 @@ void WebStatusService::hardwareStatus(AsyncWebServerRequest * request) { request->send(response); } +// returns trues if there is an upgrade available +void WebStatusService::checkUpgrade(AsyncWebServerRequest * request, JsonVariant json) { + auto * response = new AsyncJsonResponse(); + JsonObject root = response->getRoot(); + + version::Semver200_version settings_version(EMSESP_APP_VERSION); + std::string latest_version = json["version"] | EMSESP_APP_VERSION; + version::Semver200_version this_version(latest_version); + + emsesp::EMSESP::logger().debug("Checking for upgrade: %s > %s", EMSESP_APP_VERSION, latest_version.c_str()); + + root["upgradeable"] = (this_version > settings_version); + + response->setLength(); + request->send(response); +} + } // namespace emsesp diff --git a/src/web/WebStatusService.h b/src/web/WebStatusService.h index e3fe28083..0eb3cbe2f 100644 --- a/src/web/WebStatusService.h +++ b/src/web/WebStatusService.h @@ -1,8 +1,11 @@ #ifndef WebStatusService_h #define WebStatusService_h -#define HARDWARE_STATUS_SERVICE_PATH "/rest/hardwareStatus" -#define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" +#define EMSESP_HARDWARE_STATUS_SERVICE_PATH "/rest/hardwareStatus" +#define EMSESP_SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" +#define EMSESP_CHECK_UPGRADE_PATH "/rest/checkUpgrade" + +#include namespace emsesp { @@ -13,6 +16,7 @@ class WebStatusService { private: void systemStatus(AsyncWebServerRequest * request); void hardwareStatus(AsyncWebServerRequest * request); + void checkUpgrade(AsyncWebServerRequest * request, JsonVariant json); }; } // namespace emsesp From 1bf4e85fcbeb6b2a0ac0bdff2ee4fac822dabdbc Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:51:35 +0200 Subject: [PATCH 02/66] remove unneeded immediate param --- interface/src/app/status/SystemLog.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/app/status/SystemLog.tsx b/interface/src/app/status/SystemLog.tsx index 32d649e6e..eaa909611 100644 --- a/interface/src/app/status/SystemLog.tsx +++ b/interface/src/app/status/SystemLog.tsx @@ -102,7 +102,6 @@ const SystemLog = () => { // eslint-disable-next-line @typescript-eslint/unbound-method const { onMessage, onError } = useSSE(fetchLogES, { - immediate: true, // withCredentials: true, interceptByGlobalResponded: false }); From cdb8920db60f7ce7d90f01032f16076fdbbaaee3 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:51:58 +0200 Subject: [PATCH 03/66] package update --- interface/package.json | 22 +- interface/yarn.lock | 566 +++++++++++++++++++++-------------------- mock-api/package.json | 2 +- mock-api/yarn.lock | 30 +-- 4 files changed, 324 insertions(+), 296 deletions(-) diff --git a/interface/package.json b/interface/package.json index 3b82bb022..2d019b462 100644 --- a/interface/package.json +++ b/interface/package.json @@ -21,13 +21,13 @@ "lint": "eslint . --fix" }, "dependencies": { - "@alova/adapter-xhr": "2.0.5", - "@emotion/react": "^11.13.0", + "@alova/adapter-xhr": "2.0.6", + "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", - "@mui/icons-material": "^5.16.7", - "@mui/material": "^5.16.7", + "@mui/icons-material": "^6.0.0", + "@mui/material": "^6.0.0", "@table-library/react-table-library": "4.1.7", - "alova": "3.0.9", + "alova": "3.0.14", "async-validator": "^4.2.5", "jwt-decode": "^4.0.0", "mime-types": "^2.1.35", @@ -42,25 +42,25 @@ }, "devDependencies": { "@babel/core": "^7.25.2", - "@eslint/js": "^9.9.0", + "@eslint/js": "^9.9.1", "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.9.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/babel__core": "^7", "@types/formidable": "^3", - "@types/node": "^22.4.0", - "@types/react": "^18.3.3", + "@types/node": "^22.5.1", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", "concurrently": "^8.2.2", - "eslint": "^9.9.0", + "eslint": "^9.9.1", "eslint-config-prettier": "^9.1.0", "formidable": "^3.5.1", "prettier": "^3.3.3", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.31.6", - "typescript-eslint": "8.1.0", - "vite": "^5.4.1", + "typescript-eslint": "8.3.0", + "vite": "^5.4.2", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^5.0.1" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 238314ab4..1d81f413c 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -5,21 +5,21 @@ __metadata: version: 8 cacheKey: 10c0 -"@alova/adapter-xhr@npm:2.0.5": - version: 2.0.5 - resolution: "@alova/adapter-xhr@npm:2.0.5" +"@alova/adapter-xhr@npm:2.0.6": + version: 2.0.6 + resolution: "@alova/adapter-xhr@npm:2.0.6" dependencies: - "@alova/shared": "npm:^1.0.4" + "@alova/shared": "npm:^1.0.5" peerDependencies: - alova: ^3.0.9 - checksum: 10c0/9c48689e7dd081843726c4d8a93abbb7aca8b4654c606e67b81ab23de42542d5c17f2fbff7b65d4b75c7d484b42a74e76ba77e61446021620a256051eb82496c + alova: ^3.0.14 + checksum: 10c0/8a944d582ded17ff74b020a1e5defd98578a65520bde3b8a7e4586d8d0e54e40ddd03f35e1d6f8080ea9a8ac5bcba6933e861a67862278d9bd6aa8b6179f607f languageName: node linkType: hard -"@alova/shared@npm:^1.0.4": - version: 1.0.4 - resolution: "@alova/shared@npm:1.0.4" - checksum: 10c0/308b3163ee81fe98bb8372bd8a7df2a053be508167c86c6cfa2b3610c79389621e9a3466c391210e3f058799733465cf7dd153fcae536b03ea58dabff9d6eab4 +"@alova/shared@npm:^1.0.5": + version: 1.0.5 + resolution: "@alova/shared@npm:1.0.5" + checksum: 10c0/58d99d8b6b026e60c7184c55bdccd43d3b39bec598722135b272fd3c355942facc40f9433dceb6fcabb6631b87766c7227432c2a2bf3ae281d9a26b2eba2a69d languageName: node linkType: hard @@ -287,7 +287,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": version: 7.25.0 resolution: "@babel/runtime@npm:7.25.0" dependencies: @@ -296,6 +296,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.25.0": + version: 7.25.4 + resolution: "@babel/runtime@npm:7.25.4" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: 10c0/33e937e685f0bfc2d40c219261e2e50d0df7381a6e7cbf56b770e0c5d77cb0c21bf4d97da566cf0164317ed7508e992082c7b6cce7aaa3b17da5794f93fbfb46 + languageName: node + linkType: hard + "@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0": version: 7.25.0 resolution: "@babel/template@npm:7.25.0" @@ -380,7 +389,7 @@ __metadata: languageName: node linkType: hard -"@emotion/cache@npm:^11.11.0, @emotion/cache@npm:^11.13.0": +"@emotion/cache@npm:^11.13.0, @emotion/cache@npm:^11.13.1": version: 11.13.1 resolution: "@emotion/cache@npm:11.13.1" dependencies: @@ -416,14 +425,14 @@ __metadata: languageName: node linkType: hard -"@emotion/react@npm:^11.13.0": - version: 11.13.0 - resolution: "@emotion/react@npm:11.13.0" +"@emotion/react@npm:^11.13.3": + version: 11.13.3 + resolution: "@emotion/react@npm:11.13.3" dependencies: "@babel/runtime": "npm:^7.18.3" "@emotion/babel-plugin": "npm:^11.12.0" "@emotion/cache": "npm:^11.13.0" - "@emotion/serialize": "npm:^1.3.0" + "@emotion/serialize": "npm:^1.3.1" "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0" "@emotion/utils": "npm:^1.4.0" "@emotion/weak-memoize": "npm:^0.4.0" @@ -433,7 +442,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/28ee0ba6818ccf2726b31da0ecf3a6ac091983c8e03b3f5d6d2eb02165e3b3d1b95c267fccd08bff2f9769e0ff7361d791810583b858a9dd788de7cf82f6667d + checksum: 10c0/a55e770b9ea35de5d35db05a7ad40a4a3f442809fa8e4fabaf56da63ac9444f09aaf691c4e75a1455dc388991ab0c0ab4e253ce67c5836f27513e45ebd01b673 languageName: node linkType: hard @@ -450,6 +459,19 @@ __metadata: languageName: node linkType: hard +"@emotion/serialize@npm:^1.3.1": + version: 1.3.1 + resolution: "@emotion/serialize@npm:1.3.1" + dependencies: + "@emotion/hash": "npm:^0.9.2" + "@emotion/memoize": "npm:^0.9.0" + "@emotion/unitless": "npm:^0.10.0" + "@emotion/utils": "npm:^1.4.0" + csstype: "npm:^3.0.2" + checksum: 10c0/ac7158e2881b5f3f9ca1e4d865186d38623f997de888675297e0928b202d16273e43b0a19aa021c0b706edefae31118bc97c5fab095820109d09d502dbcf2092 + languageName: node + linkType: hard + "@emotion/sheet@npm:^1.4.0": version: 1.4.0 resolution: "@emotion/sheet@npm:1.4.0" @@ -477,6 +499,13 @@ __metadata: languageName: node linkType: hard +"@emotion/unitless@npm:^0.10.0": + version: 0.10.0 + resolution: "@emotion/unitless@npm:0.10.0" + checksum: 10c0/150943192727b7650eb9a6851a98034ddb58a8b6958b37546080f794696141c3760966ac695ab9af97efe10178690987aee4791f9f0ad1ff76783cdca83c1d49 + languageName: node + linkType: hard + "@emotion/unitless@npm:^0.9.0": version: 0.9.0 resolution: "@emotion/unitless@npm:0.9.0" @@ -693,14 +722,14 @@ __metadata: languageName: node linkType: hard -"@eslint/config-array@npm:^0.17.1": - version: 0.17.1 - resolution: "@eslint/config-array@npm:0.17.1" +"@eslint/config-array@npm:^0.18.0": + version: 0.18.0 + resolution: "@eslint/config-array@npm:0.18.0" dependencies: "@eslint/object-schema": "npm:^2.1.4" debug: "npm:^4.3.1" minimatch: "npm:^3.1.2" - checksum: 10c0/b986a0a96f2b42467578968ce3d4ae3b9284e587f8490f2dcdc44ff1b8d30580c62b221da6e58d07b09e156c3050e2dc38267f9370521d9cafc099c4e30154ef + checksum: 10c0/0234aeb3e6b052ad2402a647d0b4f8a6aa71524bafe1adad0b8db1dfe94d7f5f26d67c80f79bb37ac61361a1d4b14bb8fb475efe501de37263cf55eabb79868f languageName: node linkType: hard @@ -721,10 +750,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.9.0, @eslint/js@npm:^9.9.0": - version: 9.9.0 - resolution: "@eslint/js@npm:9.9.0" - checksum: 10c0/6ec9f1f0d576132444d6a5c66a8a08b0be9444e3ebb563fa6a6bebcf5299df3da7e454dc04c0fa601bb811197f00764b3a04430d8458cdb8e3a4677993d23f30 +"@eslint/js@npm:9.9.1, @eslint/js@npm:^9.9.1": + version: 9.9.1 + resolution: "@eslint/js@npm:9.9.1" + checksum: 10c0/a3a91de2ce78469f7c4eee78c1eba77360706e1d0fa0ace2e19102079bcf237b851217c85ea501dc92c4c3719d60d9df966977abc8554d4c38e3638c1f53dcb2 languageName: node linkType: hard @@ -815,41 +844,41 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.16.7": - version: 5.16.7 - resolution: "@mui/core-downloads-tracker@npm:5.16.7" - checksum: 10c0/4644c850160d01232c1abdbed141e4fa70e155891a9c68f0c2cc3054b4a3cdc1d28cf2d6665366fd8c725b2b091db677e11831552889a4e4e14f1e44450cf654 +"@mui/core-downloads-tracker@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/core-downloads-tracker@npm:6.0.0" + checksum: 10c0/68b7dfe3fbdf7570bb9f04382cd5615adc69007255e87ffa98d97329ccd66159daf33d5293388fa8769de74cae7361c98123f5ca5c98a7fa0597cb49cd43cdac languageName: node linkType: hard -"@mui/icons-material@npm:^5.16.7": - version: 5.16.7 - resolution: "@mui/icons-material@npm:5.16.7" +"@mui/icons-material@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/icons-material@npm:6.0.0" dependencies: - "@babel/runtime": "npm:^7.23.9" + "@babel/runtime": "npm:^7.25.0" peerDependencies: - "@mui/material": ^5.0.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + "@mui/material": ^6.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/49bab1754334798acaf93187d27200cf90d7c50b6a019531594aeac9e5ced9168281fec70bb040792dc86c8bc0d3bf9a876f22cfbf86ad07941ca6bc6c564921 + checksum: 10c0/41dd50ff529228ebc066bdb2a83a85a24efb0adac85f4c30a76f5c8c39f1bf85502d6dfc4af69b616c0ce3283fec58f674b79182c77fcaf470d8daba69c7bbe7 languageName: node linkType: hard -"@mui/material@npm:^5.16.7": - version: 5.16.7 - resolution: "@mui/material@npm:5.16.7" +"@mui/material@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/material@npm:6.0.0" dependencies: - "@babel/runtime": "npm:^7.23.9" - "@mui/core-downloads-tracker": "npm:^5.16.7" - "@mui/system": "npm:^5.16.7" - "@mui/types": "npm:^7.2.15" - "@mui/utils": "npm:^5.16.6" + "@babel/runtime": "npm:^7.25.0" + "@mui/core-downloads-tracker": "npm:^6.0.0" + "@mui/system": "npm:^6.0.0" + "@mui/types": "npm:^7.2.16" + "@mui/utils": "npm:^6.0.0" "@popperjs/core": "npm:^2.11.8" - "@types/react-transition-group": "npm:^4.4.10" - clsx: "npm:^2.1.0" + "@types/react-transition-group": "npm:^4.4.11" + clsx: "npm:^2.1.1" csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" react-is: "npm:^18.3.1" @@ -857,75 +886,78 @@ __metadata: peerDependencies: "@emotion/react": ^11.5.0 "@emotion/styled": ^11.3.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 + "@mui/material-pigment-css": ^6.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@emotion/react": optional: true "@emotion/styled": optional: true + "@mui/material-pigment-css": + optional: true "@types/react": optional: true - checksum: 10c0/b11419c1a77835413471f9352586fed65fb5de19c6737e121669da0484c441c7dd9939aa73fdad779482c30efaa694fb9fdcf18dcf418af07881e60eaff92b4f + checksum: 10c0/975d0457d5307610aa1f21dd69d412f154964fb1661ecd0533961a927205468c69857d4c5dd16a86faf3d9737eb8cc8fa9d5ddfe1d482480d311b93b8f984581 languageName: node linkType: hard -"@mui/private-theming@npm:^5.16.6": - version: 5.16.6 - resolution: "@mui/private-theming@npm:5.16.6" +"@mui/private-theming@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/private-theming@npm:6.0.0" dependencies: - "@babel/runtime": "npm:^7.23.9" - "@mui/utils": "npm:^5.16.6" + "@babel/runtime": "npm:^7.25.0" + "@mui/utils": "npm:^6.0.0" prop-types: "npm:^15.8.1" peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/0a09afd6c2be37197973a856049f97e2f17f3e5e6cf6387af036055342efbfcd7d7066dcad587886f25f491e5940e4e9bb7d732d5099eb85b53b84ef120e9555 + checksum: 10c0/5c4451ded03b0e6f9c8b08fc6ce3e4e3a5ee3e0b50d95fd1eec72db030992c94ab92815ae3462b05c095db72b1b15b7f1cdaf613c4df688e800533d2b98694a1 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.16.6": - version: 5.16.6 - resolution: "@mui/styled-engine@npm:5.16.6" +"@mui/styled-engine@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/styled-engine@npm:6.0.0" dependencies: - "@babel/runtime": "npm:^7.23.9" - "@emotion/cache": "npm:^11.11.0" + "@babel/runtime": "npm:^7.25.0" + "@emotion/cache": "npm:^11.13.1" csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" peerDependencies: "@emotion/react": ^11.4.1 "@emotion/styled": ^11.3.0 - react: ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@emotion/react": optional: true "@emotion/styled": optional: true - checksum: 10c0/b15e653c8756059c8ae2891ca54900573e22f6ed1aaf65a389ec838f2aca3252aeeb9a79aec4a43f080152b161a416e60b31a62595ba86ad5f72eda5642caaf2 + checksum: 10c0/9a2330ed3f4b4e1a2344c44dd6902b4a9bf5578e46dbaf839068ab089af9731e4a1a4a9155965cddb4b6cda8b55aac7d4ca24aa3ae934dee4f90e47be1e50f7a languageName: node linkType: hard -"@mui/system@npm:^5.16.7": - version: 5.16.7 - resolution: "@mui/system@npm:5.16.7" +"@mui/system@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/system@npm:6.0.0" dependencies: - "@babel/runtime": "npm:^7.23.9" - "@mui/private-theming": "npm:^5.16.6" - "@mui/styled-engine": "npm:^5.16.6" - "@mui/types": "npm:^7.2.15" - "@mui/utils": "npm:^5.16.6" - clsx: "npm:^2.1.0" + "@babel/runtime": "npm:^7.25.0" + "@mui/private-theming": "npm:^6.0.0" + "@mui/styled-engine": "npm:^6.0.0" + "@mui/types": "npm:^7.2.16" + "@mui/utils": "npm:^6.0.0" + clsx: "npm:^2.1.1" csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" peerDependencies: "@emotion/react": ^11.5.0 "@emotion/styled": ^11.3.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@emotion/react": optional: true @@ -933,39 +965,39 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10c0/c07479c0728433847c1e3d7f57b96d9e0770cc814dfd1c9e070304955984a0b706832703b22388eb83906d1a01691f37047e2bac6a5e5c083e8c29a54302d476 + checksum: 10c0/b6b50fcbb4383c1e529a3839a07c6e06ee4bf40a655e612b94a2d061a8360216d2145c837da5a17624b684e2753df76bfb3ca80493d668a1eb66aebeb3c10211 languageName: node linkType: hard -"@mui/types@npm:^7.2.15": - version: 7.2.15 - resolution: "@mui/types@npm:7.2.15" +"@mui/types@npm:^7.2.16": + version: 7.2.16 + resolution: "@mui/types@npm:7.2.16" peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/26c39674fe6f653a4c7406890b081b772e62efbd5b2754ab28bb8346819265d7c6496db8a8923230a84252ffd890e3d0b41642c151b78fdf8505336c92d78e14 + checksum: 10c0/e51189d464e4217616a0d2bf45468b949c5b660b154fa03f1153456e4ef1422157454ed442dc9bde6a247166c8db7de6c405c629829525e3ca500ee9cf48f507 languageName: node linkType: hard -"@mui/utils@npm:^5.16.6": - version: 5.16.6 - resolution: "@mui/utils@npm:5.16.6" +"@mui/utils@npm:^6.0.0": + version: 6.0.0 + resolution: "@mui/utils@npm:6.0.0" dependencies: - "@babel/runtime": "npm:^7.23.9" - "@mui/types": "npm:^7.2.15" + "@babel/runtime": "npm:^7.25.0" + "@mui/types": "npm:^7.2.16" "@types/prop-types": "npm:^15.7.12" clsx: "npm:^2.1.1" prop-types: "npm:^15.8.1" react-is: "npm:^18.3.1" peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/2db3d11a83d7216fb8ceb459d4b30c795922c04cd8fabc26c721dd7b4f5ed5c4f3f3ace6ea70227bf3b79361bd58f13b723562cfd40255424d979ab238ab2e91 + checksum: 10c0/605ff8098810025a0a8079d8a8f64cdac6e66bc1d6271348bd5a1819ab8e02046c92422fe42d373cc874fa7b0d059bb34489768ab6b47fc471bc40c27dfa1fb5 languageName: node linkType: hard @@ -1121,114 +1153,114 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.20.0" +"@rollup/rollup-android-arm-eabi@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.21.1" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-android-arm64@npm:4.20.0" +"@rollup/rollup-android-arm64@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-android-arm64@npm:4.21.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-darwin-arm64@npm:4.20.0" +"@rollup/rollup-darwin-arm64@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.21.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-darwin-x64@npm:4.20.0" +"@rollup/rollup-darwin-x64@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.21.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.1" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.20.0" +"@rollup/rollup-linux-arm-musleabihf@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.21.1" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.20.0" +"@rollup/rollup-linux-arm64-gnu@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.21.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.20.0" +"@rollup/rollup-linux-arm64-musl@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.21.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.1" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.20.0" +"@rollup/rollup-linux-riscv64-gnu@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.21.1" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.20.0" +"@rollup/rollup-linux-s390x-gnu@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.1" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.20.0" +"@rollup/rollup-linux-x64-gnu@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.21.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.20.0" +"@rollup/rollup-linux-x64-musl@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.21.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.20.0" +"@rollup/rollup-win32-arm64-msvc@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.21.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.20.0" +"@rollup/rollup-win32-ia32-msvc@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.21.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.20.0": - version: 4.20.0 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.20.0" +"@rollup/rollup-win32-x64-msvc@npm:4.21.1": + version: 4.21.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.21.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1454,12 +1486,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^22.4.0": - version: 22.4.0 - resolution: "@types/node@npm:22.4.0" +"@types/node@npm:^22.5.1": + version: 22.5.1 + resolution: "@types/node@npm:22.5.1" dependencies: undici-types: "npm:~6.19.2" - checksum: 10c0/84cd094b19a27e0db425f1d02614e4f7ac59b5eb3b21e288c8f8d4d0a4c9ad370107bc1a649d4c2b4e810cd133feea26e0bbf7e7c617f93e9e139d6d2568cf50 + checksum: 10c0/35373176d8a1d4e16004a1ed303e68d39e4c6341024dc056f2577982df98c1a045a6b677f12ed557796f09bbf7d621f428f6874cc37ed28f7b336fa604b5f6a6 languageName: node linkType: hard @@ -1507,16 +1539,16 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^4.4.10": - version: 4.4.10 - resolution: "@types/react-transition-group@npm:4.4.10" +"@types/react-transition-group@npm:^4.4.11": + version: 4.4.11 + resolution: "@types/react-transition-group@npm:4.4.11" dependencies: "@types/react": "npm:*" - checksum: 10c0/3eb9bca143abc21eb781aa5cb1bded0c9335689d515bf0513fb8e63217b7a8122c6a323ecd5644a06938727e1f467ee061d8df1c93b68825a80ff1b47ab777a2 + checksum: 10c0/8fbf0dcc1b81985cdcebe3c59d769fe2ea3f4525f12c3a10a7429a59f93e303c82b2abb744d21cb762879f4514969d70a7ab11b9bf486f92213e8fe70e04098d languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^18.3.3": +"@types/react@npm:*": version: 18.3.3 resolution: "@types/react@npm:18.3.3" dependencies: @@ -1526,6 +1558,16 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^18.3.4": + version: 18.3.4 + resolution: "@types/react@npm:18.3.4" + dependencies: + "@types/prop-types": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10c0/5c52e1e6f540cff21e3c2a5212066d02e005f6fb21e4a536a29097fae878db9f407cd7a4b43778f51359349c5f692e08bc77ddb5f5cecbfca9ca4d4e3c91a48e + languageName: node + linkType: hard + "@types/responselike@npm:^1.0.0": version: 1.0.3 resolution: "@types/responselike@npm:1.0.3" @@ -1544,15 +1586,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.1.0" +"@typescript-eslint/eslint-plugin@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.3.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.1.0" - "@typescript-eslint/type-utils": "npm:8.1.0" - "@typescript-eslint/utils": "npm:8.1.0" - "@typescript-eslint/visitor-keys": "npm:8.1.0" + "@typescript-eslint/scope-manager": "npm:8.3.0" + "@typescript-eslint/type-utils": "npm:8.3.0" + "@typescript-eslint/utils": "npm:8.3.0" + "@typescript-eslint/visitor-keys": "npm:8.3.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -1563,68 +1605,68 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/7bbeae588f859b59c34d6a76cac06ef0fa605921b40c5d3b65b94829984280ea84c4dd3f5cb9ce2eb326f5563e9abb4c90ebff05c47f83f4def296c2ea1fa86c + checksum: 10c0/d5242b16b8602ab5817cf04b35ac7208b6bee530730eeed6eab886667d1f2c5fac1537b3e33c453393090a1c6fcd50f727c07f5168985a00e7d23d1f99576988 languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/parser@npm:8.1.0" +"@typescript-eslint/parser@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/parser@npm:8.3.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.1.0" - "@typescript-eslint/types": "npm:8.1.0" - "@typescript-eslint/typescript-estree": "npm:8.1.0" - "@typescript-eslint/visitor-keys": "npm:8.1.0" + "@typescript-eslint/scope-manager": "npm:8.3.0" + "@typescript-eslint/types": "npm:8.3.0" + "@typescript-eslint/typescript-estree": "npm:8.3.0" + "@typescript-eslint/visitor-keys": "npm:8.3.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/b94b2d3ab5ca505484d100701fad6a04a5dc8d595029bac1b9f5b8a4a91d80fd605b0f65d230b36a97ab7e5d55eeb0c28af2ab63929a3e4ab8fdefd2a548c36b + checksum: 10c0/8185e7f1f570cded8719cfb1e8147fcbbc5b8796de628d68024d2929ce6fb02d1f6101b741161229e877be1c30c720701e1e1f7c4313dba33d4bb1190a85f705 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/scope-manager@npm:8.1.0" +"@typescript-eslint/scope-manager@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/scope-manager@npm:8.3.0" dependencies: - "@typescript-eslint/types": "npm:8.1.0" - "@typescript-eslint/visitor-keys": "npm:8.1.0" - checksum: 10c0/2bcf8cd176a1819bddcae16c572e7da8fba821b995a91cd53d64d8d6b85a17f5a895522f281ba57e34929574bddd4d6684ee3e545ec4e8096be4c3198e253a9a + "@typescript-eslint/types": "npm:8.3.0" + "@typescript-eslint/visitor-keys": "npm:8.3.0" + checksum: 10c0/24d093505d444a07db88f9ab44af04eb738ce523ac3f98b0a641cf3a3ee38d18aff9f72bbf2b2e2d9f45e57c973f31016f1e224cd8ab773f6e7c3477c5a09ad3 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/type-utils@npm:8.1.0" +"@typescript-eslint/type-utils@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/type-utils@npm:8.3.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.1.0" - "@typescript-eslint/utils": "npm:8.1.0" + "@typescript-eslint/typescript-estree": "npm:8.3.0" + "@typescript-eslint/utils": "npm:8.3.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/62753941c4136e8d2daa72fe0410dea48e5317a6f12ece6382ca85e29912bd1b3f739b61d1060fc0a1f8c488dfc905beab4c8b8497951a21c3138a659c7271ec + checksum: 10c0/0e4b42ff2bfcd1727893bb7fe5fcf1aa808b45b5f690c249c68ce7aff68ddfba3d8b1565de2f08972915df23fa7ab114c09f507668e9b0b63faf1e34a5091706 languageName: node linkType: hard -"@typescript-eslint/types@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/types@npm:8.1.0" - checksum: 10c0/ceade44455f45974e68956016c4d1c6626580732f7f9675e14ffa63db80b551752b0df596b20473dae9f0dc6ed966e17417dc2cf36e1a82b6ab0edc97c5eaa50 +"@typescript-eslint/types@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/types@npm:8.3.0" + checksum: 10c0/5cd733af7ffa0cdaa5842f6c5e275b3a5c9b98dc49bf1bb9df1f0b51d346bef2a10a827d886f60492d502218a272e935cef50b4f7c69100217d5b10a2499c7b1 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.1.0" +"@typescript-eslint/typescript-estree@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.3.0" dependencies: - "@typescript-eslint/types": "npm:8.1.0" - "@typescript-eslint/visitor-keys": "npm:8.1.0" + "@typescript-eslint/types": "npm:8.3.0" + "@typescript-eslint/visitor-keys": "npm:8.3.0" debug: "npm:^4.3.4" - globby: "npm:^11.1.0" + fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" minimatch: "npm:^9.0.4" semver: "npm:^7.6.0" @@ -1632,31 +1674,31 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/a7bc8275df1c79c4cb14ef086c56674316dd4907efec53eddca35d0b5220428b69c82178ce2d95138da2e398269c8bd0764cae8020a36417e411e35c3c47bc4b + checksum: 10c0/dd73aa1a9d7b5c7e6238e766e6ecdb6d87a9b28a24815258b7bbdc59c49fb525d3fe15d9b7c672e2220678f9d5fabdd9615e4cd5ee97a102fd46023ec0735d50 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/utils@npm:8.1.0" +"@typescript-eslint/utils@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/utils@npm:8.3.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.1.0" - "@typescript-eslint/types": "npm:8.1.0" - "@typescript-eslint/typescript-estree": "npm:8.1.0" + "@typescript-eslint/scope-manager": "npm:8.3.0" + "@typescript-eslint/types": "npm:8.3.0" + "@typescript-eslint/typescript-estree": "npm:8.3.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - checksum: 10c0/c95503a6bdcd98b1ff04d1adbf46377b2036b1c510d90a4a056401f996f775f06c3108c95fb81cd6babc9c97b73b91b8e848f0337bc508de8a49c993582f0e75 + checksum: 10c0/e4e9e820cf4b4775bb66b2293a2a827897edaba88577b63df317b50752a01d542be521cc4842976fbbd93e08b9e273ce9d20e23768d06de68a83d68cc0f68a93 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.1.0": - version: 8.1.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.1.0" +"@typescript-eslint/visitor-keys@npm:8.3.0": + version: 8.3.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.3.0" dependencies: - "@typescript-eslint/types": "npm:8.1.0" + "@typescript-eslint/types": "npm:8.3.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/b7544dbb0eec1ddbfcd95c04b51b9a739c2e768c16d1c88508f976a2b0d1bc02fefb7491930e06e48073a5c07c6f488cd8403bba3a8b918888b93a88d5ac3869 + checksum: 10c0/4c19216636f2cc25026fe20d2832d857f05c262eba78bc4159121c696199e44cac68443565959f9336372f7686a14b452867300cf4deb3c0507b8dbde88ac0e6 languageName: node linkType: hard @@ -1664,27 +1706,27 @@ __metadata: version: 0.0.0-use.local resolution: "EMS-ESP@workspace:." dependencies: - "@alova/adapter-xhr": "npm:2.0.5" + "@alova/adapter-xhr": "npm:2.0.6" "@babel/core": "npm:^7.25.2" - "@emotion/react": "npm:^11.13.0" + "@emotion/react": "npm:^11.13.3" "@emotion/styled": "npm:^11.13.0" - "@eslint/js": "npm:^9.9.0" - "@mui/icons-material": "npm:^5.16.7" - "@mui/material": "npm:^5.16.7" + "@eslint/js": "npm:^9.9.1" + "@mui/icons-material": "npm:^6.0.0" + "@mui/material": "npm:^6.0.0" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.9.0" "@table-library/react-table-library": "npm:4.1.7" "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@types/babel__core": "npm:^7" "@types/formidable": "npm:^3" - "@types/node": "npm:^22.4.0" - "@types/react": "npm:^18.3.3" + "@types/node": "npm:^22.5.1" + "@types/react": "npm:^18.3.4" "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" - alova: "npm:3.0.9" + alova: "npm:3.0.14" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^9.9.0" + eslint: "npm:^9.9.1" eslint-config-prettier: "npm:^9.1.0" formidable: "npm:^3.5.1" jwt-decode: "npm:^4.0.0" @@ -1700,8 +1742,8 @@ __metadata: terser: "npm:^5.31.6" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.5.4" - typescript-eslint: "npm:8.1.0" - vite: "npm:^5.4.1" + typescript-eslint: "npm:8.3.0" + vite: "npm:^5.4.2" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^5.0.1" languageName: unknown @@ -1763,13 +1805,13 @@ __metadata: languageName: node linkType: hard -"alova@npm:3.0.9": - version: 3.0.9 - resolution: "alova@npm:3.0.9" +"alova@npm:3.0.14": + version: 3.0.14 + resolution: "alova@npm:3.0.14" dependencies: - "@alova/shared": "npm:^1.0.4" + "@alova/shared": "npm:^1.0.5" rate-limiter-flexible: "npm:^5.0.3" - checksum: 10c0/df4cf0e513e10cf12d0af37c3b4f04bd81c5f1681073335c23d8d6d32f7d08aaba88822c7ff99f862ef55a959f336c9f26d14bb7dde051b2add813cc9a6ffdad + checksum: 10c0/67e943b7d75ecfb1a3b0d32d0491302ecae317295804300a03d20ac61fcd85de9b442dd4bac7871e555c68db6fb0dd662377b18afdd441adb56972c9d4e2eef6 languageName: node linkType: hard @@ -3182,15 +3224,15 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9.9.0": - version: 9.9.0 - resolution: "eslint@npm:9.9.0" +"eslint@npm:^9.9.1": + version: 9.9.1 + resolution: "eslint@npm:9.9.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.11.0" - "@eslint/config-array": "npm:^0.17.1" + "@eslint/config-array": "npm:^0.18.0" "@eslint/eslintrc": "npm:^3.1.0" - "@eslint/js": "npm:9.9.0" + "@eslint/js": "npm:9.9.1" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.3.0" "@nodelib/fs.walk": "npm:^1.2.8" @@ -3227,7 +3269,7 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/3a22f68c99d75dcbafe6e2fef18d2b5bbcc960c2437f48a414ccf9ca214254733a18e6b79d07bbd374a2369a648413e421aabd07b11be3de5a44d5a4b9997877 + checksum: 10c0/5e71efda7c0a14ee95436d5cdfed04ee61dfb1d89d7a32b50a424de2e680af82849628ea6581950c2e0726491f786a3cfd0032ce013c1c5093786e475cfdfb33 languageName: node linkType: hard @@ -3400,7 +3442,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9": +"fast-glob@npm:^3.0.3, fast-glob@npm:^3.3.2": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -3881,20 +3923,6 @@ __metadata: languageName: node linkType: hard -"globby@npm:^11.1.0": - version: 11.1.0 - resolution: "globby@npm:11.1.0" - dependencies: - array-union: "npm:^2.1.0" - dir-glob: "npm:^3.0.1" - fast-glob: "npm:^3.2.9" - ignore: "npm:^5.2.0" - merge2: "npm:^1.4.1" - slash: "npm:^3.0.0" - checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 - languageName: node - linkType: hard - "globrex@npm:^0.1.2": version: 0.1.2 resolution: "globrex@npm:0.1.2" @@ -4910,7 +4938,7 @@ __metadata: languageName: node linkType: hard -"merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": +"merge2@npm:^1.2.3, merge2@npm:^1.3.0": version: 1.4.1 resolution: "merge2@npm:1.4.1" checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb @@ -6039,26 +6067,26 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.13.0": - version: 4.20.0 - resolution: "rollup@npm:4.20.0" +"rollup@npm:^4.20.0": + version: 4.21.1 + resolution: "rollup@npm:4.21.1" dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.20.0" - "@rollup/rollup-android-arm64": "npm:4.20.0" - "@rollup/rollup-darwin-arm64": "npm:4.20.0" - "@rollup/rollup-darwin-x64": "npm:4.20.0" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.20.0" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.20.0" - "@rollup/rollup-linux-arm64-gnu": "npm:4.20.0" - "@rollup/rollup-linux-arm64-musl": "npm:4.20.0" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.20.0" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.20.0" - "@rollup/rollup-linux-s390x-gnu": "npm:4.20.0" - "@rollup/rollup-linux-x64-gnu": "npm:4.20.0" - "@rollup/rollup-linux-x64-musl": "npm:4.20.0" - "@rollup/rollup-win32-arm64-msvc": "npm:4.20.0" - "@rollup/rollup-win32-ia32-msvc": "npm:4.20.0" - "@rollup/rollup-win32-x64-msvc": "npm:4.20.0" + "@rollup/rollup-android-arm-eabi": "npm:4.21.1" + "@rollup/rollup-android-arm64": "npm:4.21.1" + "@rollup/rollup-darwin-arm64": "npm:4.21.1" + "@rollup/rollup-darwin-x64": "npm:4.21.1" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.21.1" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.21.1" + "@rollup/rollup-linux-arm64-gnu": "npm:4.21.1" + "@rollup/rollup-linux-arm64-musl": "npm:4.21.1" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.21.1" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.21.1" + "@rollup/rollup-linux-s390x-gnu": "npm:4.21.1" + "@rollup/rollup-linux-x64-gnu": "npm:4.21.1" + "@rollup/rollup-linux-x64-musl": "npm:4.21.1" + "@rollup/rollup-win32-arm64-msvc": "npm:4.21.1" + "@rollup/rollup-win32-ia32-msvc": "npm:4.21.1" + "@rollup/rollup-win32-x64-msvc": "npm:4.21.1" "@types/estree": "npm:1.0.5" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -6098,7 +6126,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/9b23bf0e3380e64573a5f68a55274d5c7969036e55c19aab9fb4deea2e938d76769db70f3c95ee3783c24af152bea1772ad73f9e3625b6ffd4e600a788fe97ea + checksum: 10c0/e64b6adabadc3e18544c68e9704744c333b38a68ba803c49b5344a015c5865bf35a72669ba121ba26869fa306f193884e07319ccfc570c08fd8f9e72c9949d4d languageName: node linkType: hard @@ -6831,17 +6859,17 @@ __metadata: languageName: node linkType: hard -"typescript-eslint@npm:8.1.0": - version: 8.1.0 - resolution: "typescript-eslint@npm:8.1.0" +"typescript-eslint@npm:8.3.0": + version: 8.3.0 + resolution: "typescript-eslint@npm:8.3.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.1.0" - "@typescript-eslint/parser": "npm:8.1.0" - "@typescript-eslint/utils": "npm:8.1.0" + "@typescript-eslint/eslint-plugin": "npm:8.3.0" + "@typescript-eslint/parser": "npm:8.3.0" + "@typescript-eslint/utils": "npm:8.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/9b5769b95aeca54ae9fa15cd2f0e5656747f643a7be220513555de143ff19d70c5945eb82259a3fb29ab4d37f4d158f7f088e7b2cf98e2e8253a7429ac19d072 + checksum: 10c0/90134b4b601d6fa582a95c9bee23c254f6ac2ca38aed07986d0a3bb75e1ddfdceeb9650c8647b34148696115d5fe0ce281413e4a8ec001e1e928356242a1756d languageName: node linkType: hard @@ -7037,14 +7065,14 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.4.1": - version: 5.4.1 - resolution: "vite@npm:5.4.1" +"vite@npm:^5.4.2": + version: 5.4.2 + resolution: "vite@npm:5.4.2" dependencies: esbuild: "npm:^0.21.3" fsevents: "npm:~2.3.3" postcss: "npm:^8.4.41" - rollup: "npm:^4.13.0" + rollup: "npm:^4.20.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 less: "*" @@ -7076,7 +7104,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/b9ea824f1a946aa494f756e6d9dd88869baa62ae5ba3071b32b6a20958fd622cb624c860bdd7daee201c83ca029feaf8bbe2d2a6e172a5d49308772f8899d86d + checksum: 10c0/23e347ca8aa6f0a774227e4eb7abae228f12c6806a727b046aa75e7ee37ffc2d68cff74360e12a42c347f79adc294e2363bc723b957bf4b382b5a8fb39e4df9d languageName: node linkType: hard diff --git a/mock-api/package.json b/mock-api/package.json index 97a5e1069..6e499bb75 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -11,7 +11,7 @@ "dependencies": { "@msgpack/msgpack": "^2.8.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0", - "eslint": "^9.9.0", + "eslint": "^9.9.1", "eslint-config-prettier": "^9.1.0", "formidable": "^3.5.1", "itty-router": "^5.0.18", diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index 43ff4ac2f..a308f1b31 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -180,14 +180,14 @@ __metadata: languageName: node linkType: hard -"@eslint/config-array@npm:^0.17.1": - version: 0.17.1 - resolution: "@eslint/config-array@npm:0.17.1" +"@eslint/config-array@npm:^0.18.0": + version: 0.18.0 + resolution: "@eslint/config-array@npm:0.18.0" dependencies: "@eslint/object-schema": "npm:^2.1.4" debug: "npm:^4.3.1" minimatch: "npm:^3.1.2" - checksum: 10c0/b986a0a96f2b42467578968ce3d4ae3b9284e587f8490f2dcdc44ff1b8d30580c62b221da6e58d07b09e156c3050e2dc38267f9370521d9cafc099c4e30154ef + checksum: 10c0/0234aeb3e6b052ad2402a647d0b4f8a6aa71524bafe1adad0b8db1dfe94d7f5f26d67c80f79bb37ac61361a1d4b14bb8fb475efe501de37263cf55eabb79868f languageName: node linkType: hard @@ -208,10 +208,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.9.0": - version: 9.9.0 - resolution: "@eslint/js@npm:9.9.0" - checksum: 10c0/6ec9f1f0d576132444d6a5c66a8a08b0be9444e3ebb563fa6a6bebcf5299df3da7e454dc04c0fa601bb811197f00764b3a04430d8458cdb8e3a4677993d23f30 +"@eslint/js@npm:9.9.1": + version: 9.9.1 + resolution: "@eslint/js@npm:9.9.1" + checksum: 10c0/a3a91de2ce78469f7c4eee78c1eba77360706e1d0fa0ace2e19102079bcf237b851217c85ea501dc92c4c3719d60d9df966977abc8554d4c38e3638c1f53dcb2 languageName: node linkType: hard @@ -574,15 +574,15 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9.9.0": - version: 9.9.0 - resolution: "eslint@npm:9.9.0" +"eslint@npm:^9.9.1": + version: 9.9.1 + resolution: "eslint@npm:9.9.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.11.0" - "@eslint/config-array": "npm:^0.17.1" + "@eslint/config-array": "npm:^0.18.0" "@eslint/eslintrc": "npm:^3.1.0" - "@eslint/js": "npm:9.9.0" + "@eslint/js": "npm:9.9.1" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.3.0" "@nodelib/fs.walk": "npm:^1.2.8" @@ -619,7 +619,7 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/3a22f68c99d75dcbafe6e2fef18d2b5bbcc960c2437f48a414ccf9ca214254733a18e6b79d07bbd374a2369a648413e421aabd07b11be3de5a44d5a4b9997877 + checksum: 10c0/5e71efda7c0a14ee95436d5cdfed04ee61dfb1d89d7a32b50a424de2e680af82849628ea6581950c2e0726491f786a3cfd0032ce013c1c5093786e475cfdfb33 languageName: node linkType: hard @@ -960,7 +960,7 @@ __metadata: dependencies: "@msgpack/msgpack": "npm:^2.8.0" "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" - eslint: "npm:^9.9.0" + eslint: "npm:^9.9.1" eslint-config-prettier: "npm:^9.1.0" formidable: "npm:^3.5.1" itty-router: "npm:^5.0.18" From 4188588ea040210137734e0ec2617801ee124472 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:52:12 +0200 Subject: [PATCH 04/66] remove uploads folder/directory --- mock-api/uploads/README.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 mock-api/uploads/README.md diff --git a/mock-api/uploads/README.md b/mock-api/uploads/README.md deleted file mode 100644 index e00bbed6b..000000000 --- a/mock-api/uploads/README.md +++ /dev/null @@ -1 +0,0 @@ -leave empty From 7aafe1fbbce0b5bf12fb07d803250c016a300671 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:52:20 +0200 Subject: [PATCH 05/66] improve comment --- scripts/run_native.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_native.py b/scripts/run_native.py index fc81a0a03..2dd01ebea 100644 --- a/scripts/run_native.py +++ b/scripts/run_native.py @@ -35,7 +35,7 @@ def move_file(source, target, env): print("app version: " + app_version) print("platform: " + platform) - # TODO do I need .exe for windows? + # TODO do we need to add a .exe extension for windows? - need to test variant = "native" # check if output directories exist and create if necessary From eafd65987059308c5e8f53b9e51a069ef47c1b49 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:52:36 +0200 Subject: [PATCH 06/66] move shunting yard to main code folder --- src/{web => }/shuntingYard.hpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{web => }/shuntingYard.hpp (100%) diff --git a/src/web/shuntingYard.hpp b/src/shuntingYard.hpp similarity index 100% rename from src/web/shuntingYard.hpp rename to src/shuntingYard.hpp From e2aabb1418b70c4975e13274223e4fd5ff6aa5a3 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:52:58 +0200 Subject: [PATCH 07/66] don't show warning when uploading using script --- src/system.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/system.cpp b/src/system.cpp index 55b45ee4d..b0d95ded4 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1851,7 +1851,6 @@ bool System::uploadFirmwareURL(const char * url) { // make sure we have a valid URL if (saved_url.isEmpty()) { - LOG_ERROR("Firmware upload failed - no URL"); return false; } From 19922ca9fbcedfed87f6a0a79f55d6ec19d62d32 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 13:53:27 +0200 Subject: [PATCH 08/66] move the Get* endpoints to their right service classes --- src/web/WebAPIService.cpp | 74 ----------------------------- src/web/WebAPIService.h | 9 ---- src/web/WebCustomEntityService.cpp | 16 +++++++ src/web/WebCustomEntityService.h | 3 ++ src/web/WebCustomizationService.cpp | 30 ++++++++---- src/web/WebCustomizationService.h | 12 +++-- src/web/WebDataService.cpp | 14 +++--- src/web/WebDataService.h | 12 ++--- src/web/WebLogService.cpp | 6 +-- src/web/WebLogService.h | 6 +-- src/web/WebSchedulerService.cpp | 16 +++++++ src/web/WebSchedulerService.h | 3 ++ src/web/WebSettingsService.cpp | 25 ++++++++++ src/web/WebSettingsService.h | 3 ++ 14 files changed, 114 insertions(+), 115 deletions(-) diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index 296f3f4e1..112136dcf 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -25,25 +25,7 @@ uint16_t WebAPIService::api_fails_ = 0; WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * securityManager) : _securityManager(securityManager) { - // API server->on(EMSESP_API_SERVICE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { webAPIService(request, json); }); - - // settings - server->on(GET_SETTINGS_PATH, - HTTP_GET, - securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSettings(request); }, AuthenticationPredicates::IS_ADMIN)); - - server->on(GET_CUSTOMIZATIONS_PATH, - HTTP_GET, - securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getCustomizations(request); }, AuthenticationPredicates::IS_ADMIN)); - - server->on(GET_SCHEDULE_PATH, - HTTP_GET, - securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSchedule(request); }, AuthenticationPredicates::IS_ADMIN)); - - server->on(GET_ENTITIES_PATH, - HTTP_GET, - securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getEntities(request); }, AuthenticationPredicates::IS_ADMIN)); } // POST|GET /{device} @@ -173,62 +155,6 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) { #endif } -void WebAPIService::getSettings(AsyncWebServerRequest * request) { - auto * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - - root["type"] = "settings"; - - JsonObject node = root["System"].to(); - node["version"] = EMSESP_APP_VERSION; - - System::extractSettings(NETWORK_SETTINGS_FILE, "Network", root); - System::extractSettings(AP_SETTINGS_FILE, "AP", root); - System::extractSettings(MQTT_SETTINGS_FILE, "MQTT", root); - System::extractSettings(NTP_SETTINGS_FILE, "NTP", root); - System::extractSettings(SECURITY_SETTINGS_FILE, "Security", root); - System::extractSettings(EMSESP_SETTINGS_FILE, "Settings", root); - - response->setLength(); - request->send(response); -} - -void WebAPIService::getCustomizations(AsyncWebServerRequest * request) { - auto * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - - root["type"] = "customizations"; - - System::extractSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", root); - - response->setLength(); - request->send(response); -} - -void WebAPIService::getSchedule(AsyncWebServerRequest * request) { - auto * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - - root["type"] = "schedule"; - - System::extractSettings(EMSESP_SCHEDULER_FILE, "Schedule", root); - - response->setLength(); - request->send(response); -} - -void WebAPIService::getEntities(AsyncWebServerRequest * request) { - auto * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - - root["type"] = "entities"; - - System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root); - - response->setLength(); - request->send(response); -} - #if defined(EMSESP_UNITY) // store the result so we can test with Unity later static JsonDocument storeResponseDoc_; diff --git a/src/web/WebAPIService.h b/src/web/WebAPIService.h index e47e19232..636c15d6b 100644 --- a/src/web/WebAPIService.h +++ b/src/web/WebAPIService.h @@ -21,11 +21,6 @@ #define EMSESP_API_SERVICE_PATH "/api" -#define GET_SETTINGS_PATH "/rest/getSettings" -#define GET_CUSTOMIZATIONS_PATH "/rest/getCustomizations" -#define GET_SCHEDULE_PATH "/rest/getSchedule" -#define GET_ENTITIES_PATH "/rest/getEntities" - namespace emsesp { class WebAPIService { @@ -56,10 +51,6 @@ class WebAPIService { static uint16_t api_fails_; void parse(AsyncWebServerRequest * request, JsonObject input); - void getSettings(AsyncWebServerRequest * request); - void getCustomizations(AsyncWebServerRequest * request); - void getSchedule(AsyncWebServerRequest * request); - void getEntities(AsyncWebServerRequest * request); }; } // namespace emsesp diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 6e84fea49..5c0a5bc67 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -29,6 +29,9 @@ WebCustomEntityService::WebCustomEntityService(AsyncWebServer * server, FS * fs, securityManager, AuthenticationPredicates::IS_AUTHENTICATED) , _fsPersistence(WebCustomEntity::read, WebCustomEntity::update, this, fs, EMSESP_CUSTOMENTITY_FILE) { + server->on(EMSESP_GET_ENTITIES_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getEntities(request); }, AuthenticationPredicates::IS_ADMIN)); } // load the settings when the service starts @@ -708,4 +711,17 @@ void WebCustomEntityService::test() { } #endif +// return entities as a json object +void WebCustomEntityService::getEntities(AsyncWebServerRequest * request) { + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + + root["type"] = "entities"; + + System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root); + + response->setLength(); + request->send(response); +} + } // namespace emsesp diff --git a/src/web/WebCustomEntityService.h b/src/web/WebCustomEntityService.h index 4f67c2290..088562c5e 100644 --- a/src/web/WebCustomEntityService.h +++ b/src/web/WebCustomEntityService.h @@ -22,6 +22,7 @@ #define EMSESP_CUSTOMENTITY_FILE "/config/emsespEntity.json" #define EMSESP_CUSTOMENTITY_SERVICE_PATH "/rest/customEntities" // GET and POST +#define EMSESP_GET_ENTITIES_PATH "/rest/getEntities" namespace emsesp { @@ -80,6 +81,8 @@ class WebCustomEntityService : public StatefulService { HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; + void getEntities(AsyncWebServerRequest * request); + std::list * customEntityItems_; // pointer to the list of entity items bool ha_registered_ = false; diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index da96e6611..63d415992 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -25,24 +25,25 @@ bool WebCustomization::_start = true; WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE) { // GET - server->on(DEVICE_ENTITIES_PATH, + server->on(EMSESP_DEVICE_ENTITIES_PATH, HTTP_GET, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_entities(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); - - server->on(DEVICES_SERVICE_PATH, + server->on(EMSESP_DEVICES_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { devices(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); + server->on(EMSESP_GET_CUSTOMIZATIONS_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getCustomizations(request); }, AuthenticationPredicates::IS_ADMIN)); + // POST - server->on(RESET_CUSTOMIZATION_SERVICE_PATH, + server->on(EMSESP_RESET_CUSTOMIZATION_SERVICE_PATH, HTTP_POST, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { reset_customization(request); }, AuthenticationPredicates::IS_ADMIN)); - - server->on(WRITE_DEVICE_NAME_PATH, + server->on(EMSESP_WRITE_DEVICE_NAME_PATH, securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { writeDeviceName(request, json); }, AuthenticationPredicates::IS_AUTHENTICATED)); - - server->on(CUSTOMIZATION_ENTITIES_PATH, + server->on(EMSESP_CUSTOMIZATION_ENTITIES_PATH, securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { customization_entities(request, json); }, AuthenticationPredicates::IS_AUTHENTICATED)); } @@ -424,4 +425,17 @@ void WebCustomizationService::test() { } #endif +// return all customizations in a json object +void WebCustomizationService::getCustomizations(AsyncWebServerRequest * request) { + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + + root["type"] = "customizations"; + + System::extractSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", root); + + response->setLength(); + request->send(response); +} + } // namespace emsesp diff --git a/src/web/WebCustomizationService.h b/src/web/WebCustomizationService.h index 98abbbc3b..2f085efe8 100644 --- a/src/web/WebCustomizationService.h +++ b/src/web/WebCustomizationService.h @@ -22,13 +22,14 @@ #define EMSESP_CUSTOMIZATION_FILE "/config/emsespCustomization.json" // GET -#define DEVICES_SERVICE_PATH "/rest/devices" -#define DEVICE_ENTITIES_PATH "/rest/deviceEntities" +#define EMSESP_DEVICES_SERVICE_PATH "/rest/devices" +#define EMSESP_DEVICE_ENTITIES_PATH "/rest/deviceEntities" +#define EMSESP_GET_CUSTOMIZATIONS_PATH "/rest/getCustomizations" // POST -#define CUSTOMIZATION_ENTITIES_PATH "/rest/customizationEntities" -#define RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations" -#define WRITE_DEVICE_NAME_PATH "/rest/writeDeviceName" +#define EMSESP_CUSTOMIZATION_ENTITIES_PATH "/rest/customizationEntities" +#define EMSESP_RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations" +#define EMSESP_WRITE_DEVICE_NAME_PATH "/rest/writeDeviceName" namespace emsesp { @@ -99,6 +100,7 @@ class WebCustomizationService : public StatefulService { // GET void devices(AsyncWebServerRequest * request); void device_entities(AsyncWebServerRequest * request); + void getCustomizations(AsyncWebServerRequest * request); // POST void customization_entities(AsyncWebServerRequest * request, JsonVariant json); diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 346330df4..118c6bf86 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -22,25 +22,25 @@ namespace emsesp { WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securityManager) { // write endpoints - server->on(WRITE_DEVICE_VALUE_SERVICE_PATH, + server->on(EMSESP_WRITE_DEVICE_VALUE_SERVICE_PATH, securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_device_value(request, json); }, AuthenticationPredicates::IS_ADMIN)); - server->on(WRITE_TEMPERATURE_SENSOR_SERVICE_PATH, + server->on(EMSESP_WRITE_TEMPERATURE_SENSOR_SERVICE_PATH, securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_temperature_sensor(request, json); }, AuthenticationPredicates::IS_ADMIN)); - server->on(WRITE_ANALOG_SENSOR_SERVICE_PATH, + server->on(EMSESP_WRITE_ANALOG_SENSOR_SERVICE_PATH, securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_analog_sensor(request, json); }, AuthenticationPredicates::IS_ADMIN)); // GET's - server->on(DEVICE_DATA_SERVICE_PATH, + server->on(EMSESP_DEVICE_DATA_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); - server->on(CORE_DATA_SERVICE_PATH, + server->on(EMSESP_CORE_DATA_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { core_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); - server->on(SENSOR_DATA_SERVICE_PATH, + server->on(EMSESP_SENSOR_DATA_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { sensor_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } @@ -341,7 +341,7 @@ void WebDataService::write_analog_sensor(AsyncWebServerRequest * request, JsonVa ok = EMSESP::analogsensor_.update(gpio, name, offset, factor, uom, type, deleted); } - AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 400); // bad request + AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 400); // ok or bad request request->send(response); } diff --git a/src/web/WebDataService.h b/src/web/WebDataService.h index 390cb80e9..f443eee91 100644 --- a/src/web/WebDataService.h +++ b/src/web/WebDataService.h @@ -20,14 +20,14 @@ #define WebDataService_h // GET -#define CORE_DATA_SERVICE_PATH "/rest/coreData" -#define DEVICE_DATA_SERVICE_PATH "/rest/deviceData" -#define SENSOR_DATA_SERVICE_PATH "/rest/sensorData" +#define EMSESP_CORE_DATA_SERVICE_PATH "/rest/coreData" +#define EMSESP_DEVICE_DATA_SERVICE_PATH "/rest/deviceData" +#define EMSESP_SENSOR_DATA_SERVICE_PATH "/rest/sensorData" // POST -#define WRITE_DEVICE_VALUE_SERVICE_PATH "/rest/writeDeviceValue" -#define WRITE_TEMPERATURE_SENSOR_SERVICE_PATH "/rest/writeTemperatureSensor" -#define WRITE_ANALOG_SENSOR_SERVICE_PATH "/rest/writeAnalogSensor" +#define EMSESP_WRITE_DEVICE_VALUE_SERVICE_PATH "/rest/writeDeviceValue" +#define EMSESP_WRITE_TEMPERATURE_SENSOR_SERVICE_PATH "/rest/writeTemperatureSensor" +#define EMSESP_WRITE_ANALOG_SENSOR_SERVICE_PATH "/rest/writeAnalogSensor" namespace emsesp { diff --git a/src/web/WebLogService.cpp b/src/web/WebLogService.cpp index eee6b85f0..84acf883f 100644 --- a/src/web/WebLogService.cpp +++ b/src/web/WebLogService.cpp @@ -21,12 +21,12 @@ namespace emsesp { WebLogService::WebLogService(AsyncWebServer * server, SecurityManager * securityManager) - : events_(EVENT_SOURCE_LOG_PATH) { + : events_(EMSESP_EVENT_SOURCE_LOG_PATH) { // get & set settings - server->on(LOG_SETTINGS_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { getSetValues(request, json); }); + server->on(EMSESP_LOG_SETTINGS_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { getSetValues(request, json); }); // for bring back the whole log - is a command, hence a POST - server->on(FETCH_LOG_PATH, HTTP_POST, [this](AsyncWebServerRequest * request) { fetchLog(request); }); + server->on(EMSESP_FETCH_LOG_PATH, HTTP_POST, [this](AsyncWebServerRequest * request) { fetchLog(request); }); // events_.setFilter(securityManager->filterRequest(AuthenticationPredicates::IS_ADMIN)); server->addHandler(&events_); diff --git a/src/web/WebLogService.h b/src/web/WebLogService.h index 68f77c3cf..23074ffd9 100644 --- a/src/web/WebLogService.h +++ b/src/web/WebLogService.h @@ -19,9 +19,9 @@ #ifndef WebLogService_h #define WebLogService_h -#define EVENT_SOURCE_LOG_PATH "/es/log" -#define FETCH_LOG_PATH "/rest/fetchLog" -#define LOG_SETTINGS_PATH "/rest/logSettings" +#define EMSESP_EVENT_SOURCE_LOG_PATH "/es/log" +#define EMSESP_FETCH_LOG_PATH "/rest/fetchLog" +#define EMSESP_LOG_SETTINGS_PATH "/rest/logSettings" namespace emsesp { diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index 988b996c9..43116d0cc 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -25,6 +25,9 @@ namespace emsesp { WebSchedulerService::WebSchedulerService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(WebScheduler::read, WebScheduler::update, this, server, EMSESP_SCHEDULER_SERVICE_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED) , _fsPersistence(WebScheduler::read, WebScheduler::update, this, fs, EMSESP_SCHEDULER_FILE) { + server->on(EMSESP_GET_SCHEDULE_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSchedule(request); }, AuthenticationPredicates::IS_ADMIN)); } // load the settings when the service starts @@ -610,4 +613,17 @@ void WebSchedulerService::test() { } #endif +// return schedule entries in a json object +void WebSchedulerService::getSchedule(AsyncWebServerRequest * request) { + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + + root["type"] = "schedule"; + + System::extractSettings(EMSESP_SCHEDULER_FILE, "Schedule", root); + + response->setLength(); + request->send(response); +} + } // namespace emsesp diff --git a/src/web/WebSchedulerService.h b/src/web/WebSchedulerService.h index 30f9406c9..26a87bcfb 100644 --- a/src/web/WebSchedulerService.h +++ b/src/web/WebSchedulerService.h @@ -21,6 +21,7 @@ #define EMSESP_SCHEDULER_FILE "/config/emsespScheduler.json" #define EMSESP_SCHEDULER_SERVICE_PATH "/rest/schedule" // GET and POST +#define EMSESP_GET_SCHEDULE_PATH "/rest/getSchedule" // bit flags for the schedule items. Matches those in interface/src/app/main/SchedulerDialog.tsx // 0-127 (0->0x7F) is day schedule @@ -90,6 +91,8 @@ class WebSchedulerService : public StatefulService { HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; + void getSchedule(AsyncWebServerRequest * request); + std::list * scheduleItems_; // pointer to the list of schedule events bool ha_registered_ = false; std::deque cmd_changed_; diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index a3163bf72..5e27b3b88 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -29,6 +29,10 @@ WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, Securit HTTP_GET, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { board_profile(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); addUpdateHandler([this] { onUpdate(); }, false); + + server->on(EMSESP_GET_SETTINGS_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSettings(request); }, AuthenticationPredicates::IS_ADMIN)); } void WebSettings::read(WebSettings & settings, JsonObject root) { @@ -425,4 +429,25 @@ void WebSettingsService::board_profile(AsyncWebServerRequest * request) { request->send(response); } +// returns json with all system settings +void WebSettingsService::getSettings(AsyncWebServerRequest * request) { + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + + root["type"] = "settings"; + + JsonObject node = root["System"].to(); + node["version"] = EMSESP_APP_VERSION; + + System::extractSettings(NETWORK_SETTINGS_FILE, "Network", root); + System::extractSettings(AP_SETTINGS_FILE, "AP", root); + System::extractSettings(MQTT_SETTINGS_FILE, "MQTT", root); + System::extractSettings(NTP_SETTINGS_FILE, "NTP", root); + System::extractSettings(SECURITY_SETTINGS_FILE, "Security", root); + System::extractSettings(EMSESP_SETTINGS_FILE, "Settings", root); + + response->setLength(); + request->send(response); +} + } // namespace emsesp diff --git a/src/web/WebSettingsService.h b/src/web/WebSettingsService.h index 56830e8a7..7a67bdf94 100644 --- a/src/web/WebSettingsService.h +++ b/src/web/WebSettingsService.h @@ -22,8 +22,10 @@ #include "../default_settings.h" #define EMSESP_SETTINGS_FILE "/config/emsespSettings.json" + #define EMSESP_SETTINGS_SERVICE_PATH "/rest/settings" #define EMSESP_BOARD_PROFILE_SERVICE_PATH "/rest/boardProfile" +#define EMSESP_GET_SETTINGS_PATH "/rest/getSettings" namespace emsesp { @@ -134,6 +136,7 @@ class WebSettingsService : public StatefulService { FSPersistence _fsPersistence; void board_profile(AsyncWebServerRequest * request); + void getSettings(AsyncWebServerRequest * request); void onUpdate(); }; From 908284177fb457aaf47fac5b43c04b1b65eac8b1 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 14:49:09 +0200 Subject: [PATCH 09/66] remove deprecated component --- interface/src/app/settings/network/NetworkSettings.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/app/settings/network/NetworkSettings.tsx b/interface/src/app/settings/network/NetworkSettings.tsx index 4fc22b358..f87c4560d 100644 --- a/interface/src/app/settings/network/NetworkSettings.tsx +++ b/interface/src/app/settings/network/NetworkSettings.tsx @@ -163,11 +163,9 @@ const NetworkSettings = () => { selectedNetwork.bssid } /> - - - - - + + + ) : ( From 41ec9162fda52b033a4202f459a7c3ad75e506f3 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 29 Aug 2024 14:49:21 +0200 Subject: [PATCH 10/66] add partition text --- mock-api/rest_server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index fa6dd60a3..8f40caecb 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -4223,7 +4223,7 @@ router return status(200); }) .post(RESTART_PARTITION_ENDPOINT, () => { - console.log('restarting...'); + console.log('restarting.from partition...'); return status(200); }) .post(FACTORY_RESET_ENDPOINT, () => status(200)) From 2ce728d03f82971adcb69fe4f518687c954423de Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:06:35 +0200 Subject: [PATCH 11/66] comment change --- interface/src/api/network.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/api/network.ts b/interface/src/api/network.ts index 12222129c..7f4ff203d 100644 --- a/interface/src/api/network.ts +++ b/interface/src/api/network.ts @@ -7,7 +7,7 @@ export const readNetworkStatus = () => export const scanNetworks = () => alovaInstance.Get('/rest/scanNetworks'); export const listNetworks = () => alovaInstance.Get('/rest/listNetworks', { - timeout: 20000 // timeout 20 seconds + timeout: 20000 // 20 seconds }); export const readNetworkSettings = () => alovaInstance.Get('/rest/networkSettings'); From 21b75ef392d2dd744e40245e0bed84ab810a3763 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:06:44 +0200 Subject: [PATCH 12/66] remove timeout --- interface/src/api/endpoints.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/api/endpoints.ts b/interface/src/api/endpoints.ts index 3afb960c1..2df9486cd 100644 --- a/interface/src/api/endpoints.ts +++ b/interface/src/api/endpoints.ts @@ -8,7 +8,7 @@ export const ACCESS_TOKEN = 'access_token'; export const alovaInstance = createAlova({ statesHook: ReactHook, - timeout: 3000, // 3 seconds before throwing a timeout error + // timeout: 3000, // 3 seconds before throwing a timeout error, default is 0 = none cacheFor: null, // disable cache // cacheFor: { // GET: { From 666f5626eabf3aeab5f15fa89a10bf5b89eb77bb Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:06:54 +0200 Subject: [PATCH 13/66] smaller spinner --- interface/src/app/main/Devices.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/app/main/Devices.tsx b/interface/src/app/main/Devices.tsx index 20ed79122..5fb305e75 100644 --- a/interface/src/app/main/Devices.tsx +++ b/interface/src/app/main/Devices.tsx @@ -556,7 +556,7 @@ const Devices = () => { {tableList.length === 0 && ( - + )} {tableList.map((device: Device) => ( From 79ae51fbe597fafd4cf2d8bb0dc40190bae8eed6 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:07:44 +0200 Subject: [PATCH 14/66] HELP_OF to HELP --- interface/src/app/main/Help.tsx | 2 +- interface/src/i18n/de/index.ts | 2 +- interface/src/i18n/en/index.ts | 2 +- interface/src/i18n/fr/index.ts | 2 +- interface/src/i18n/it/index.ts | 2 +- interface/src/i18n/nl/index.ts | 2 +- interface/src/i18n/no/index.ts | 2 +- interface/src/i18n/pl/index.ts | 2 +- interface/src/i18n/sk/index.ts | 2 +- interface/src/i18n/sv/index.ts | 2 +- interface/src/i18n/tr/index.ts | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/interface/src/app/main/Help.tsx b/interface/src/app/main/Help.tsx index fa4411e21..fb9c1eaed 100644 --- a/interface/src/app/main/Help.tsx +++ b/interface/src/app/main/Help.tsx @@ -26,7 +26,7 @@ import type { APIcall } from './types'; const Help = () => { const { LL } = useI18nContext(); - useLayoutTitle(LL.HELP_OF('')); + useLayoutTitle(LL.HELP()); const { send: getAPI } = useRequest((data: APIcall) => API(data), { immediate: false diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index a71224853..c5a3bc256 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -11,7 +11,7 @@ const de: Translation = { PASSWORD: 'Passwort', SU_PASSWORD: 'su Passwort', SETTINGS_OF: '{0} Einstellungen', - HELP_OF: '{0} Hilfe', + HELP: 'Hilfe', LOGGED_IN: 'Eingeloggt als {name}', PLEASE_SIGNIN: 'Bitte einloggen, um fortzufahren', UPLOAD_SUCCESSFUL: 'Hochladen erfolgreich', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index ac069aab2..def2fe914 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -11,7 +11,7 @@ const en: Translation = { PASSWORD: 'Password', SU_PASSWORD: 'su Password', SETTINGS_OF: '{0} Settings', - HELP_OF: '{0} Help', + HELP: 'Help', LOGGED_IN: 'Logged in as {name}', PLEASE_SIGNIN: 'Please sign in to continue', UPLOAD_SUCCESSFUL: 'Upload successful', diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index cd614e02c..6eed9291a 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -11,7 +11,7 @@ const fr: Translation = { PASSWORD: 'Mot de passe', SU_PASSWORD: 'Mot de passe su', SETTINGS_OF: 'Paramètres {0}', - HELP_OF: 'Aide {0}', + HELP: 'Aide', LOGGED_IN: 'Connecté en tant que {name}', PLEASE_SIGNIN: 'Veuillez vous connecter pour continuer', UPLOAD_SUCCESSFUL: 'Upload terminée', diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 6dbf4707c..424993e57 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -11,7 +11,7 @@ const it: Translation = { PASSWORD: 'Password', SU_PASSWORD: 'su Password', SETTINGS_OF: 'Impostazioni {0}', - HELP_OF: '{0} Aiuto', + HELP: 'Aiuto', LOGGED_IN: 'Registrato come {name}', PLEASE_SIGNIN: 'Prego registrarsi per continuare', UPLOAD_SUCCESSFUL: 'Caricamento finito', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index bf47983e9..085828ef0 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -11,7 +11,7 @@ const nl: Translation = { PASSWORD: 'Wachtwoord', SU_PASSWORD: 'su Wachtwoord', SETTINGS_OF: '{0} Instellingen', - HELP_OF: '{0} Help', + HELP: 'Help', LOGGED_IN: 'Ingelogd als {name}', PLEASE_SIGNIN: 'Log in om verder te gaan', UPLOAD_SUCCESSFUL: 'Upload successvol', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 7471b596b..6e4658a13 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -11,7 +11,7 @@ const no: Translation = { PASSWORD: 'Passord', SU_PASSWORD: 'su Passord', SETTINGS_OF: '{0} Innstillinger', - HELP_OF: '{0} Hjelp', + HELP: 'Hjelp', LOGGED_IN: 'Logget in som {name}', PLEASE_SIGNIN: 'Venligst logge inn for å fortsetta', UPLOAD_SUCCESSFUL: 'Opplasting lykkes', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 48f97782e..388ddee65 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -11,7 +11,7 @@ const pl: BaseTranslation = { PASSWORD: 'Hasło', SU_PASSWORD: 'Hasło "su"', SETTINGS_OF: 'Ustawienia {0}', - HELP_OF: 'Pomoc {0}', + HELP: 'Pomoc', LOGGED_IN: 'Zalogowano użytkownika {name}.', PLEASE_SIGNIN: 'Zaloguj się aby kontynuować.', UPLOAD_SUCCESSFUL: 'Wysyłanie zakończone.', diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 7360741f7..abc219aff 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -11,7 +11,7 @@ const sk: Translation = { PASSWORD: 'Heslo', SU_PASSWORD: 'su heslo', SETTINGS_OF: '{0} Nastavenia', - HELP_OF: '{0} Pomoc', + HELP: 'Pomoc', LOGGED_IN: 'Prihlásený ako {name}', PLEASE_SIGNIN: 'Ak chcete pokračovať, prihláste sa', UPLOAD_SUCCESSFUL: 'Nahratie úspešné', diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 4b71f483a..6546dc48c 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -11,7 +11,7 @@ const sv: Translation = { PASSWORD: 'Lösenord', SU_PASSWORD: 'su Lösenord', SETTINGS_OF: '{0} Inställningar', - HELP_OF: '{0} Hjälp', + HELP: 'Hjälp', LOGGED_IN: 'Inloggad som {name}', PLEASE_SIGNIN: 'Vänligen logga in för att fortsätta', UPLOAD_SUCCESSFUL: 'Uppladdning lyckades', diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 6e2f3e3b8..ba99e54d8 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -11,7 +11,7 @@ const tr: Translation = { PASSWORD: 'Şifre', SU_PASSWORD: 'SK Şifresi', SETTINGS_OF: '{0} Ayarlar', - HELP_OF: '{0} Yardım', + HELP: 'Yardım', LOGGED_IN: '{name} olarak giriş yapıldı', PLEASE_SIGNIN: 'Lütfen devam etmek için giriş yapın', UPLOAD_SUCCESSFUL: 'Yükleme tamamlandı', From d2f6f8203f0467f09ad15c21d25bacf0eb4f0977 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:08:00 +0200 Subject: [PATCH 15/66] remove deprecated ListItemSecondaryAction --- interface/src/app/settings/network/NetworkSettings.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/app/settings/network/NetworkSettings.tsx b/interface/src/app/settings/network/NetworkSettings.tsx index f87c4560d..68fbb5b10 100644 --- a/interface/src/app/settings/network/NetworkSettings.tsx +++ b/interface/src/app/settings/network/NetworkSettings.tsx @@ -15,7 +15,6 @@ import { List, ListItem, ListItemAvatar, - ListItemSecondaryAction, ListItemText, MenuItem, TextField, From 117b55cc16e4d0ec31efffc1379d461f05249bfb Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:09:05 +0200 Subject: [PATCH 16/66] tidy up restart --- interface/src/app/settings/DownloadUpload.tsx | 61 +++++++---------- interface/src/app/status/RestartMonitor.tsx | 10 +-- interface/src/app/status/Status.tsx | 68 ------------------- interface/src/components/upload/DragNdrop.tsx | 2 +- .../src/components/upload/SingleUpload.tsx | 11 ++- .../upload/{drag-drop.css => dragNdrop.css} | 0 lib/framework/RestartService.cpp | 41 +---------- lib/framework/RestartService.h | 4 -- lib/framework/UploadFileService.cpp | 6 +- src/system.cpp | 55 +++++++++------ 10 files changed, 72 insertions(+), 186 deletions(-) rename interface/src/components/upload/{drag-drop.css => dragNdrop.css} (100%) diff --git a/interface/src/app/settings/DownloadUpload.tsx b/interface/src/app/settings/DownloadUpload.tsx index a195049d2..e955f9280 100644 --- a/interface/src/app/settings/DownloadUpload.tsx +++ b/interface/src/app/settings/DownloadUpload.tsx @@ -4,7 +4,6 @@ import { toast } from 'react-toastify'; import CancelIcon from '@mui/icons-material/Cancel'; import DownloadIcon from '@mui/icons-material/GetApp'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; -import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import WarningIcon from '@mui/icons-material/Warning'; import { Box, @@ -25,7 +24,13 @@ import { getSchedule, getSettings } from 'api/app'; -import { checkUpgrade, getDevVersion, getStableVersion } from 'api/system'; +import { + checkUpgrade, + getDevVersion, + getStableVersion, + restart, + uploadURL +} from 'api/system'; import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova/client'; @@ -33,7 +38,6 @@ import type { APIcall } from 'app/main/types'; import RestartMonitor from 'app/status/RestartMonitor'; import { FormLoader, - MessageBox, SectionContent, SingleUpload, useLayoutTitle @@ -44,7 +48,6 @@ const DownloadUpload = () => { const { LL } = useI18nContext(); const [restarting, setRestarting] = useState(false); - const [restartNeeded, setRestartNeeded] = useState(false); const [openDialog, setOpenDialog] = useState(false); const [useDev, setUseDev] = useState(false); const [upgradeAvailable, setUpgradeAvailable] = useState(false); @@ -89,24 +92,21 @@ const DownloadUpload = () => { } = useRequest(SystemApi.readHardwareStatus); const { send: sendUploadURL } = useRequest( - (data: { url: string }) => SystemApi.uploadURL(data), + (data: { url: string }) => uploadURL(data), { immediate: false } ); - const { send: restartCommand } = useRequest(SystemApi.restart(), { + const { send: restartCommand } = useRequest(restart(), { immediate: false }); - const restart = async () => { - await restartCommand() - .then(() => { - setRestarting(true); - }) - .catch((error: Error) => { - toast.error(error.message); - }); + const callRestart = async () => { + setRestarting(true); + await restartCommand().catch((error: Error) => { + toast.error(error.message); + }); }; const { send: sendCheckUpgrade } = useRequest(checkUpgrade, { @@ -387,10 +387,11 @@ const DownloadUpload = () => { )} - {upgradeAvailable ? ( - - -   {LL.UPGRADE_AVAILABLE()} + + +    + {upgradeAvailable ? LL.UPGRADE_AVAILABLE() : LL.LATEST_VERSION()} + {upgradeAvailable && ( - - ) : ( - {LL.LATEST_VERSION()} - )} + )} + + {renderUploadDialog()} @@ -411,24 +411,11 @@ const DownloadUpload = () => { {LL.UPLOAD()} - + {LL.UPLOAD_TEXT()} - {restartNeeded ? ( - - - - ) : ( - - )} + ); }; diff --git a/interface/src/app/status/RestartMonitor.tsx b/interface/src/app/status/RestartMonitor.tsx index 685cac3e8..4b1f32daf 100644 --- a/interface/src/app/status/RestartMonitor.tsx +++ b/interface/src/app/status/RestartMonitor.tsx @@ -1,13 +1,13 @@ import { type FC, useEffect, useRef, useState } from 'react'; -import * as SystemApi from 'api/system'; +import { readHardwareStatus } from 'api/system'; import { useRequest } from 'alova/client'; import { FormLoader } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; const RESTART_TIMEOUT = 2 * 60 * 1000; // 2 minutes -const POLL_INTERVAL = 1000; // every 1 second +const POLL_INTERVAL = 2000; // every 2 seconds export interface RestartMonitorProps { message?: string; @@ -16,10 +16,12 @@ export interface RestartMonitorProps { const RestartMonitor: FC = ({ message }) => { const [failed, setFailed] = useState(false); const [timeoutId, setTimeoutId] = useState(); + const { LL } = useI18nContext(); + const timeoutAt = useRef(new Date().getTime() + RESTART_TIMEOUT); - const { send } = useRequest(SystemApi.readSystemStatus); + const { send } = useRequest(readHardwareStatus, { immediate: false }); const poll = useRef(async () => { try { @@ -35,7 +37,7 @@ const RestartMonitor: FC = ({ message }) => { }); useEffect(() => { - void poll.current(); + setTimeoutId(setTimeout(poll.current, POLL_INTERVAL)); }, []); useEffect(() => () => timeoutId && clearTimeout(timeoutId), [timeoutId]); diff --git a/interface/src/app/status/Status.tsx b/interface/src/app/status/Status.tsx index cca48dbee..95b880fa0 100644 --- a/interface/src/app/status/Status.tsx +++ b/interface/src/app/status/Status.tsx @@ -52,24 +52,12 @@ const SystemStatus = () => { const { me } = useContext(AuthenticatedContext); const [confirmRestart, setConfirmRestart] = useState(false); - const [processing, setProcessing] = useState(false); const [restarting, setRestarting] = useState(); const { send: restartCommand } = useRequest(SystemApi.restart(), { immediate: false }); - const { send: partitionCommand } = useRequest(SystemApi.partition(), { - immediate: false - }); - - const { send: factoryPartitionCommand } = useRequest( - SystemApi.factoryPartition(), - { - immediate: false - } - ); - const { data: data, send: loadData, @@ -208,7 +196,6 @@ const SystemStatus = () => { value ? theme.palette.success.main : theme.palette.info.main; const restart = async () => { - setProcessing(true); await restartCommand() .then(() => { setRestarting(true); @@ -218,37 +205,6 @@ const SystemStatus = () => { }) .finally(() => { setConfirmRestart(false); - setProcessing(false); - }); - }; - - const partition = async () => { - setProcessing(true); - await partitionCommand() - .then(() => { - setRestarting(true); - }) - .catch((error: Error) => { - toast.error(error.message); - }) - .finally(() => { - setConfirmRestart(false); - setProcessing(false); - }); - }; - - const factoryPartition = async () => { - setProcessing(true); - await factoryPartitionCommand() - .then(() => { - setRestarting(true); - }) - .catch((error: Error) => { - toast.error(error.message); - }) - .finally(() => { - setConfirmRestart(false); - setProcessing(false); }); }; @@ -265,38 +221,14 @@ const SystemStatus = () => { startIcon={} variant="outlined" onClick={() => setConfirmRestart(false)} - disabled={processing} color="secondary" > {LL.CANCEL()} - {data.has_loader && ( - - )} - {data.has_partition && ( - - )} - + - {/* */} - {/* */} From 3f2d5bea677d3bcbb21cd3ce7e288c2a59e98a0e Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:10:50 +0200 Subject: [PATCH 24/66] formatting --- esp32_partition_16M.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp32_partition_16M.csv b/esp32_partition_16M.csv index 578cbfce8..e912ccc98 100644 --- a/esp32_partition_16M.csv +++ b/esp32_partition_16M.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x005000, otadata, data, ota, , 0x002000, -boot, app, factory, , 0x280000, +boot, app, factory, , 0x280000, app0, app, ota_0, , 0x590000, app1, app, ota_1, , 0x590000, nvs1, data, nvs, , 0x040000, From 5635268fd142bdd3ff317da94390439aeea2fc38 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:21:03 +0200 Subject: [PATCH 25/66] fix autoupdate in dialog --- interface/src/app/main/CustomEntities.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/app/main/CustomEntities.tsx b/interface/src/app/main/CustomEntities.tsx index b7b3e0ca6..31a0811d7 100644 --- a/interface/src/app/main/CustomEntities.tsx +++ b/interface/src/app/main/CustomEntities.tsx @@ -54,7 +54,7 @@ const CustomEntities = () => { useEffect(() => { const timer = setInterval(async () => { - if (dialogOpen) { + if (dialogOpen || numChanges > 0) { return; } await fetchEntities(); From 70642de2a6e801b2d8b7f1e820c050d0f3fe1b1d Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:21:11 +0200 Subject: [PATCH 26/66] remove Divider --- interface/src/app/settings/Settings.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/app/settings/Settings.tsx b/interface/src/app/settings/Settings.tsx index fdebb3dc9..06790ada4 100644 --- a/interface/src/app/settings/Settings.tsx +++ b/interface/src/app/settings/Settings.tsx @@ -17,7 +17,6 @@ import { DialogActions, DialogContent, DialogTitle, - Divider, List } from '@mui/material'; @@ -131,8 +130,6 @@ const Settings = () => { to="modules" /> - - Date: Fri, 30 Aug 2024 11:21:26 +0200 Subject: [PATCH 27/66] add back immediate for SSE calls (Alova bug) --- interface/src/app/status/SystemLog.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/app/status/SystemLog.tsx b/interface/src/app/status/SystemLog.tsx index eaa909611..77b48c839 100644 --- a/interface/src/app/status/SystemLog.tsx +++ b/interface/src/app/status/SystemLog.tsx @@ -103,6 +103,7 @@ const SystemLog = () => { // eslint-disable-next-line @typescript-eslint/unbound-method const { onMessage, onError } = useSSE(fetchLogES, { // withCredentials: true, + immediate: true, interceptByGlobalResponded: false }); From c0305ddf3823f8e9df299dc34366c54cdeb9ec81 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 11:21:35 +0200 Subject: [PATCH 28/66] German translations --- interface/src/i18n/de/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index c5a3bc256..64614287d 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -174,7 +174,7 @@ const de: Translation = { FACTORY_RESET: 'Werkseinstellung', SYSTEM_FACTORY_TEXT: 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu', SYSTEM_FACTORY_TEXT_DIALOG: 'Sind Sie sicher alle Einstellungen auf Werkseinstellung zu setzen?', - STABLE: 'Stable', // TODO translate + STABLE: 'Stabil', DEVELOPMENT: 'Entwicklungs', RELEASE_NOTES: 'Versionshinweise', EMS_ESP_VER: 'EMS-ESP Version', @@ -333,11 +333,11 @@ const de: Translation = { SERVICES: 'Dienste', ALLVALUES: 'Alle Werte', SPECIAL_FUNCTIONS: 'Sonderfunktionen', - WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate - INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate - UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate - LATEST_VERSION: 'You are using the latest version.' // TODO translate + WAIT_FIRMWARE: 'Bitte warten Sie, während die Firmware hochgeladen wird. Das Gerät wird automatisch neu gestartet.', + INSTALL_VERSION: 'Dadurch wird die Version installiert {0}. Sind Sie sicher?', + SWITCH_DEV: 'Wechseln Sie zur Entwicklungsversion', + UPGRADE_AVAILABLE: 'Es ist ein Firmware-Upgrade verfügbar!', + LATEST_VERSION: 'Sie verwenden die neueste Version.' }; export default de; From 7c3c5917dbe1917035ea1970c246a4bde5958aa7 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 14:54:30 +0200 Subject: [PATCH 29/66] fixes to install --- interface/src/app/settings/DownloadUpload.tsx | 21 ++++++++++++------- interface/src/i18n/en/index.ts | 2 +- interface/src/i18n/fr/index.ts | 2 +- interface/src/i18n/it/index.ts | 2 +- interface/src/i18n/nl/index.ts | 2 +- interface/src/i18n/no/index.ts | 2 +- interface/src/i18n/pl/index.ts | 2 +- interface/src/i18n/sk/index.ts | 2 +- interface/src/i18n/sv/index.ts | 2 +- interface/src/i18n/tr/index.ts | 2 +- mock-api/rest_server.ts | 10 +++++---- 11 files changed, 28 insertions(+), 21 deletions(-) diff --git a/interface/src/app/settings/DownloadUpload.tsx b/interface/src/app/settings/DownloadUpload.tsx index e955f9280..a8960f9f8 100644 --- a/interface/src/app/settings/DownloadUpload.tsx +++ b/interface/src/app/settings/DownloadUpload.tsx @@ -137,14 +137,14 @@ const DownloadUpload = () => { const DEV_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md'; - const getBinURL = (useDev: boolean) => { + const getBinURL = (useDevVersion: boolean) => { const filename = 'EMS-ESP-' + - (useDev ? latestDevVersion : latestVersion).replaceAll('.', '_') + + (useDevVersion ? latestDevVersion : latestVersion).replaceAll('.', '_') + '-' + getPlatform() + '.bin'; - return useDev + return useDevVersion ? DEV_URL + filename : STABLE_URL + 'v' + latestVersion + '/' + filename; }; @@ -262,8 +262,11 @@ const DownloadUpload = () => { ); }; - const showFirmwareDialog = (useDev: boolean) => { - setUseDev(useDev); + // useDev = true to force using the dev version + const showFirmwareDialog = (useDevVersion: boolean) => { + if (useDevVersion || data.emsesp_version.includes('dev')) { + setUseDev(true); + } setOpenDialog(true); }; @@ -393,13 +396,15 @@ const DownloadUpload = () => { {upgradeAvailable ? LL.UPGRADE_AVAILABLE() : LL.LATEST_VERSION()} {upgradeAvailable && ( )} diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index def2fe914..7b3e6b8d8 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -335,7 +335,7 @@ const en: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 6eed9291a..7a25af0c4 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -335,7 +335,7 @@ const fr: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate // TODO translate }; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 424993e57..906555bdc 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -335,7 +335,7 @@ const it: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 085828ef0..c44f00fc6 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -335,7 +335,7 @@ const nl: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 6e4658a13..c211c7635 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -335,7 +335,7 @@ const no: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 388ddee65..4d6193585 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -335,7 +335,7 @@ const pl: BaseTranslation = { SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index abc219aff..ea73942cc 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -335,7 +335,7 @@ const sk: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 6546dc48c..0da5c760c 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -335,7 +335,7 @@ const sv: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index ba99e54d8..07a3aa1e5 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -335,7 +335,7 @@ const tr: Translation = { SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate WAIT_FIRMWARE: 'Please wait while the firmware is being uploaded. The device will restart automatically.', // TODO translate INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate - SWITCH_DEV: 'Switch to development version', // TODO translate + SWITCH_DEV: 'switch to the development version', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'You are using the latest version.' // TODO translate }; diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index 8f40caecb..3e5b5f105 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -331,6 +331,7 @@ let mqtt_settings = { publish_time_other: 10, publish_time_sensor: 10, publish_time_heartbeat: 60, + publish_time_water: 60, mqtt_qos: 0, rootCA: '', mqtt_retain: false, @@ -367,9 +368,11 @@ const VERIFY_AUTHORIZATION_ENDPOINT = REST_ENDPOINT_ROOT + 'verifyAuthorization' const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn'; const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'; +const VERSION = '3.7.0-dev.0'; +// const VERSION = '3.6.4'; + const hardware_status = { - emsesp_version: '3.7.0-dev.33', - // emsesp_version: '3.6.5', + emsesp_version: VERSION, esp_platform: 'ESP32S3', build_flags: 'DEMO', cpu_type: 'ESP32-S3', @@ -397,8 +400,7 @@ const hardware_status = { }; const system_status = { - emsesp_version: '3.7.0-dev.33', - // emsesp_version: '3.6.5', + emsesp_version: VERSION, status: 0, // status: 2, uptime: 77186, From eff3e3f40434537765eb27b79df30e9e7a1e211b Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 14:55:10 +0200 Subject: [PATCH 30/66] package update --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index ce4aecb9f..90f1db04a 100644 --- a/interface/package.json +++ b/interface/package.json @@ -49,7 +49,7 @@ "@types/babel__core": "^7", "@types/formidable": "^3", "@types/node": "^22.5.1", - "@types/react": "^18.3.4", + "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", "concurrently": "^8.2.2", diff --git a/interface/yarn.lock b/interface/yarn.lock index 2201f41da..5b0c264ca 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1558,13 +1558,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.3.4": - version: 18.3.4 - resolution: "@types/react@npm:18.3.4" +"@types/react@npm:^18.3.5": + version: 18.3.5 + resolution: "@types/react@npm:18.3.5" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10c0/5c52e1e6f540cff21e3c2a5212066d02e005f6fb21e4a536a29097fae878db9f407cd7a4b43778f51359349c5f692e08bc77ddb5f5cecbfca9ca4d4e3c91a48e + checksum: 10c0/548b1d3d7c2f0242fbfdbbd658731b4ce69a134be072fa83e6ab516f2840402a3f20e3e7f72e95133b23d4880ef24a6d864050dc8e1f7c68f39fa87ca8445917 languageName: node linkType: hard @@ -1720,7 +1720,7 @@ __metadata: "@types/babel__core": "npm:^7" "@types/formidable": "npm:^3" "@types/node": "npm:^22.5.1" - "@types/react": "npm:^18.3.4" + "@types/react": "npm:^18.3.5" "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" alova: "npm:3.0.14" From 35cb567b62d499ab54c1a2f5bef959605d476243 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 14:55:24 +0200 Subject: [PATCH 31/66] migrate deprecated Grid v5 to v6 (Grid2) --- interface/src/SignIn.tsx | 8 +- .../src/app/main/CustomEntitiesDialog.tsx | 78 +++--- interface/src/app/main/Customizations.tsx | 26 +- .../src/app/main/CustomizationsDialog.tsx | 11 +- interface/src/app/main/Devices.tsx | 4 +- interface/src/app/main/DevicesDialog.tsx | 30 ++- interface/src/app/main/ModulesDialog.tsx | 2 +- interface/src/app/main/SchedulerDialog.tsx | 2 +- .../src/app/main/SensorsAnalogDialog.tsx | 96 ++++---- .../src/app/main/SensorsTemperatureDialog.tsx | 17 +- interface/src/app/main/types.ts | 3 +- .../src/app/settings/ApplicationSettings.tsx | 224 +++++++----------- interface/src/app/settings/MqttSettings.tsx | 184 +++++--------- interface/src/app/status/NTPStatus.tsx | 6 +- interface/src/app/status/SystemLog.tsx | 61 ++--- .../inputs/ValidatedPasswordField.tsx | 24 +- .../src/components/upload/SingleUpload.tsx | 2 +- 17 files changed, 326 insertions(+), 452 deletions(-) diff --git a/interface/src/SignIn.tsx b/interface/src/SignIn.tsx index 409cb36e2..c547be43d 100644 --- a/interface/src/SignIn.tsx +++ b/interface/src/SignIn.tsx @@ -109,9 +109,11 @@ const SignIn = () => { onChange={updateLoginRequestValue} margin="normal" variant="outlined" - inputProps={{ - autoCapitalize: 'none', - autoCorrect: 'off' + slotProps={{ + input: { + autoCapitalize: 'none', + autoCorrect: 'off' + } }} /> - - + + - + {editItem.ram === 1 && ( - + - + - + 0x - ) + slotProps={{ + input: { + startAdornment: ( + 0x + ) + }, + htmlInput: { style: { textTransform: 'uppercase' } } }} /> - + 0x - ) + slotProps={{ + input: { + startAdornment: ( + 0x + ) + }, + htmlInput: { style: { textTransform: 'uppercase' } } }} /> - + - + @@ -247,26 +251,28 @@ const CustomEntitiesDialog = ({ {editItem.value_type !== DeviceValueType.BOOL && editItem.value_type !== DeviceValueType.STRING && ( <> - + - + @@ -281,20 +287,21 @@ const CustomEntitiesDialog = ({ )} {editItem.value_type === DeviceValueType.STRING && editItem.device_id !== '0' && ( - + @@ -303,7 +310,6 @@ const CustomEntitiesDialog = ({ )} - {!creating && ( diff --git a/interface/src/app/main/Customizations.tsx b/interface/src/app/main/Customizations.tsx index 42de65d53..4f74dd0a9 100644 --- a/interface/src/app/main/Customizations.tsx +++ b/interface/src/app/main/Customizations.tsx @@ -16,7 +16,6 @@ import { DialogActions, DialogContent, DialogTitle, - Grid, InputAdornment, Link, MenuItem, @@ -25,6 +24,7 @@ import { ToggleButtonGroup, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { restart } from 'api/system'; @@ -514,7 +514,7 @@ const Customizations = () => { justifyContent="flex-start" alignItems="center" > - + { onChange={(event) => { setSearch(event.target.value); }} - InputProps={{ - startAdornment: ( - - - - ) + slotProps={{ + input: { + startAdornment: ( + + + + ) + } }} /> - + { - + - + - + {LL.SHOWING()} {shown_data.length}/{deviceEntities.length}  {LL.ENTITIES(deviceEntities.length)} diff --git a/interface/src/app/main/CustomizationsDialog.tsx b/interface/src/app/main/CustomizationsDialog.tsx index b29130dba..62bd2e83d 100644 --- a/interface/src/app/main/CustomizationsDialog.tsx +++ b/interface/src/app/main/CustomizationsDialog.tsx @@ -10,10 +10,10 @@ import { DialogActions, DialogContent, DialogTitle, - Grid, TextField, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { dialogStyle } from 'CustomTheme'; import { useI18nContext } from 'i18n/i18n-react'; @@ -81,7 +81,7 @@ const CustomizationsDialog = ({ {LL.EDIT() + ' ' + LL.ENTITY()} - + {LL.ID_OF(LL.ENTITY())}:  @@ -112,19 +112,18 @@ const CustomizationsDialog = ({ - + {isWriteableNumber && ( <> - + - + { - + diff --git a/interface/src/app/main/DevicesDialog.tsx b/interface/src/app/main/DevicesDialog.tsx index e226897ee..e668da663 100644 --- a/interface/src/app/main/DevicesDialog.tsx +++ b/interface/src/app/main/DevicesDialog.tsx @@ -11,12 +11,12 @@ import { DialogContent, DialogTitle, FormHelperText, - Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { dialogStyle } from 'CustomTheme'; import type Schema from 'async-validator'; @@ -112,15 +112,14 @@ const DevicesDialog = ({ {editItem.id.slice(2)} - - + + {editItem.l ? ( - {setUom(editItem.u)} - - ) + : {}, + input: { + startAdornment: ( + + {setUom(editItem.u)} + + ) + } }} /> ) : ( @@ -162,7 +161,6 @@ const DevicesDialog = ({ label={LL.VALUE(0)} value={editItem.v} disabled={!writeable} - // autoFocus sx={{ width: '30ch' }} multiline={editItem.u ? false : true} onChange={updateFormValue} @@ -170,7 +168,7 @@ const DevicesDialog = ({ )} {writeable && ( - + {showHelperText(editItem)} )} diff --git a/interface/src/app/main/ModulesDialog.tsx b/interface/src/app/main/ModulesDialog.tsx index 570c9ab14..e045c69f7 100644 --- a/interface/src/app/main/ModulesDialog.tsx +++ b/interface/src/app/main/ModulesDialog.tsx @@ -10,9 +10,9 @@ import { DialogActions, DialogContent, DialogTitle, - Grid, TextField } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { dialogStyle } from 'CustomTheme'; import { BlockFormControlLabel } from 'components'; diff --git a/interface/src/app/main/SchedulerDialog.tsx b/interface/src/app/main/SchedulerDialog.tsx index 7769bac00..5bcb82abd 100644 --- a/interface/src/app/main/SchedulerDialog.tsx +++ b/interface/src/app/main/SchedulerDialog.tsx @@ -13,12 +13,12 @@ import { DialogActions, DialogContent, DialogTitle, - Grid, TextField, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { dialogStyle } from 'CustomTheme'; import type Schema from 'async-validator'; diff --git a/interface/src/app/main/SensorsAnalogDialog.tsx b/interface/src/app/main/SensorsAnalogDialog.tsx index 59700ba4c..e3c1b12b0 100644 --- a/interface/src/app/main/SensorsAnalogDialog.tsx +++ b/interface/src/app/main/SensorsAnalogDialog.tsx @@ -10,12 +10,12 @@ import { DialogActions, DialogContent, DialogTitle, - Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { dialogStyle } from 'CustomTheme'; import type Schema from 'async-validator'; @@ -86,11 +86,12 @@ const SensorsAnalogDialog = ({ - + {creating && ( - + {LL.WARN_GPIO()} )} - + - + {editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && ( - + @@ -150,55 +151,61 @@ const SensorsAnalogDialog = ({ )} {editItem.t === AnalogType.ADC && ( - + mV - ) + slotProps={{ + input: { + startAdornment: ( + mV + ) + }, + htmlInput: { min: '0', max: '3300', step: '1' } }} /> )} {editItem.t === AnalogType.COUNTER && ( - + )} {editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && ( - + )} {editItem.t === AnalogType.DIGITAL_OUT && (editItem.g === 25 || editItem.g === 26) && ( - + )} @@ -215,12 +224,11 @@ const SensorsAnalogDialog = ({ editItem.g !== 25 && editItem.g !== 26 && ( <> - + {LL.ON()} - + @@ -242,12 +250,12 @@ const SensorsAnalogDialog = ({ {LL.ACTIVELOW()} - + @@ -266,37 +274,41 @@ const SensorsAnalogDialog = ({ editItem.t === AnalogType.PWM_1 || editItem.t === AnalogType.PWM_2) && ( <> - + Hz - ) + slotProps={{ + input: { + startAdornment: ( + Hz + ) + }, + htmlInput: { min: '1', max: '5000', step: '1' } }} /> - + % - ) + slotProps={{ + input: { + startAdornment: ( + % + ) + }, + htmlInput: { min: '0', max: '100', step: '0.1' } }} /> diff --git a/interface/src/app/main/SensorsTemperatureDialog.tsx b/interface/src/app/main/SensorsTemperatureDialog.tsx index cc3b94705..da19906c8 100644 --- a/interface/src/app/main/SensorsTemperatureDialog.tsx +++ b/interface/src/app/main/SensorsTemperatureDialog.tsx @@ -9,11 +9,11 @@ import { DialogActions, DialogContent, DialogTitle, - Grid, InputAdornment, TextField, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { dialogStyle } from 'CustomTheme'; import type Schema from 'async-validator'; @@ -80,18 +80,17 @@ const SensorsTemperatureDialog = ({ - + - + °C + slotProps={{ + input: { + startAdornment: ( + °C + ) + }, + htmlInput: { min: '-5', max: '5', step: '0.1' } }} /> diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index 895082137..e386951c1 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -420,12 +420,11 @@ export const enum DeviceValueType { TIME, // same as UINT24 UINT32, ENUM, - STRING, + STRING, // RAW CMD } export const DeviceValueTypeNames = [ - // 'BOOL', 'INT8', 'UINT8', diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index f25abc407..409393746 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -9,12 +9,12 @@ import { Button, Checkbox, Divider, - Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import { readHardwareStatus, restart } from 'api/system'; @@ -114,6 +114,19 @@ const ApplicationSettings = () => { useLayoutTitle(LL.SETTINGS_OF(LL.APPLICATION())); + const SecondsInputProps = { + endAdornment: {LL.SECONDS()} + }; + const MilliSecondsInputProps = { + endAdornment: ms + }; + const MinutesInputProps = { + endAdornment: {LL.MINUTES()} + }; + const HoursInputProps = { + endAdornment: {LL.HOURS()} + }; + const content = () => { if (!data || !hardwareData) { return ; @@ -191,19 +204,12 @@ const ApplicationSettings = () => { label={LL.ENABLE_MODBUS()} /> {data.modbus_enabled && ( - - + + { margin="normal" /> - + { margin="normal" /> - + ms + slotProps={{ + input: MilliSecondsInputProps }} - fullWidth variant="outlined" value={numberValue(data.modbus_timeout)} type="number" @@ -254,31 +258,23 @@ const ApplicationSettings = () => { label={LL.ENABLE_SYSLOG()} /> {data.syslog_enabled && ( - - + + - + { margin="normal" /> - + { ALL - + {LL.SECONDS()} - ) + slotProps={{ + input: SecondsInputProps }} - fullWidth variant="outlined" value={numberValue(data.syslog_mark_interval)} type="number" @@ -358,43 +351,37 @@ const ApplicationSettings = () => { {LL.FORMATTING_OPTIONS()} - - - Deutsch (DE) - English (EN) - Français (FR) - Italiano (IT) - Nederlands (NL) - Norsk (NO) - Polski (PL) - Slovenčina (SK) - Svenska (SV) - Türk (TR) - - - - + + + + Deutsch (DE) + English (EN) + Français (FR) + Italiano (IT) + Nederlands (NL) + Norsk (NO) + Polski (PL) + Slovenčina (SK) + Svenska (SV) + Türk (TR) + + + { 1/0 - + { 1/0 - + { label={LL.BOARD_PROFILE()} value={data.board_profile} disabled={processingBoard || hardwareData.model.startsWith('BBQKees')} - fullWidth variant="outlined" onChange={changeBoardProfile} margin="normal" @@ -483,15 +469,8 @@ const ApplicationSettings = () => { {data.board_profile === 'CUSTOM' && ( <> - - + + { margin="normal" /> - + { margin="normal" /> - + { margin="normal" /> - + { margin="normal" /> - + { margin="normal" /> - + { {data.phy_type !== 0 && ( - - + + { margin="normal" /> - + { margin="normal" /> - + { )} )} - - + + { {LL.HARDWARE()} - + { fieldErrors={fieldErrors} name="remote_timeout" label={LL.REMOTE_TIMEOUT()} - InputProps={{ - endAdornment: ( - {LL.HOURS()} - ) + slotProps={{ + input: HoursInputProps }} variant="outlined" value={numberValue(data.remote_timeout)} @@ -753,13 +717,7 @@ const ApplicationSettings = () => { /> )} - + { disabled={!data.shower_timer} /> - + {data.shower_timer && ( - + {LL.SECONDS()} - ) + slotProps={{ + input: SecondsInputProps }} variant="outlined" value={numberValue(data.shower_min_duration)} @@ -812,15 +760,13 @@ const ApplicationSettings = () => { )} {data.shower_alert && ( <> - + {LL.MINUTES()} - ) + slotProps={{ + input: MinutesInputProps }} variant="outlined" value={numberValue(data.shower_alert_trigger)} @@ -830,15 +776,13 @@ const ApplicationSettings = () => { disabled={!data.shower_timer} /> - + {LL.SECONDS()} - ) + slotProps={{ + input: SecondsInputProps }} variant="outlined" value={numberValue(data.shower_alert_coldshot)} diff --git a/interface/src/app/settings/MqttSettings.tsx b/interface/src/app/settings/MqttSettings.tsx index 715bb1d2c..416d0c493 100644 --- a/interface/src/app/settings/MqttSettings.tsx +++ b/interface/src/app/settings/MqttSettings.tsx @@ -5,12 +5,12 @@ import WarningIcon from '@mui/icons-material/Warning'; import { Button, Checkbox, - Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; +import Grid from '@mui/material/Grid2'; import * as MqttApi from 'api/mqtt'; @@ -59,6 +59,10 @@ const MqttSettings = () => { updateDataValue ); + const SecondsInputProps = { + endAdornment: {LL.SECONDS()} + }; + const content = () => { if (!data) { return ; @@ -86,19 +90,12 @@ const MqttSettings = () => { } label={LL.ENABLE_MQTT()} /> - - + + { margin="normal" /> - + { margin="normal" /> - + - + - + - + - + {LL.SECONDS()} - ) + slotProps={{ + input: SecondsInputProps }} - fullWidth variant="outlined" value={numberValue(data.keep_alive)} type="number" @@ -182,12 +171,11 @@ const MqttSettings = () => { margin="normal" /> - + { )} - { } label={LL.MQTT_RETAIN_FLAG()} /> - {LL.FORMATTING()} @@ -251,7 +236,6 @@ const MqttSettings = () => { name="nested_format" label={LL.MQTT_FORMAT()} value={data.nested_format} - fullWidth variant="outlined" onChange={updateFormValue} margin="normal" @@ -271,15 +255,8 @@ const MqttSettings = () => { label={LL.MQTT_RESPONSE()} /> {!data.ha_enabled && ( - - + + { /> {data.publish_single && ( - + { )} {!data.publish_single && ( - - + + { /> {data.ha_enabled && ( - - + + { Domoticz (latest) - + - + { {LL.MQTT_PUBLISH_INTERVALS()} (0=auto) - - + + {LL.SECONDS()} - ) + slotProps={{ + input: SecondsInputProps }} - fullWidth variant="outlined" value={numberValue(data.publish_time_heartbeat)} type="number" @@ -417,127 +369,105 @@ const MqttSettings = () => { margin="normal" /> - + {LL.SECONDS()} - ) - }} - fullWidth variant="outlined" value={numberValue(data.publish_time_boiler)} type="number" onChange={updateFormValue} margin="normal" + slotProps={{ + input: SecondsInputProps + }} /> - + {LL.SECONDS()} - ) - }} - fullWidth variant="outlined" value={numberValue(data.publish_time_thermostat)} type="number" onChange={updateFormValue} margin="normal" + slotProps={{ + input: SecondsInputProps + }} /> - + {LL.SECONDS()} - ) - }} - fullWidth variant="outlined" value={numberValue(data.publish_time_solar)} type="number" onChange={updateFormValue} margin="normal" + slotProps={{ + input: SecondsInputProps + }} /> - + {LL.SECONDS()} - ) - }} - fullWidth variant="outlined" value={numberValue(data.publish_time_mixer)} type="number" onChange={updateFormValue} margin="normal" + slotProps={{ + input: SecondsInputProps + }} /> - + {LL.SECONDS()} - ) - }} - fullWidth variant="outlined" value={numberValue(data.publish_time_water)} type="number" onChange={updateFormValue} margin="normal" + slotProps={{ + input: SecondsInputProps + }} /> - + {LL.SECONDS()} - ) - }} - fullWidth variant="outlined" value={numberValue(data.publish_time_sensor)} type="number" onChange={updateFormValue} margin="normal" + slotProps={{ + input: SecondsInputProps + }} /> - + {LL.SECONDS()} - ) - }} label={LL.DEFAULT(0)} - fullWidth variant="outlined" value={numberValue(data.publish_time_other)} type="number" onChange={updateFormValue} margin="normal" + slotProps={{ + input: SecondsInputProps + }} /> - {dirtyFlags && dirtyFlags.length !== 0 && ( + {dirtyFlags && dirtyFlags.length !== 0 && ( - {dirtyFlags && dirtyFlags.length !== 0 && ( - - )} - + )} ; -const ValidatedPasswordField: FC = ({ - InputProps, - ...props -}) => { +const ValidatedPasswordField: FC = ({ ...props }) => { const [showPassword, setShowPassword] = useState(false); return ( - setShowPassword(!showPassword)} edge="end"> - {showPassword ? : } - - - ) + slotProps={{ + input: { + endAdornment: ( + + setShowPassword(!showPassword)} edge="end"> + {showPassword ? : } + + + ) + } }} /> ); diff --git a/interface/src/components/upload/SingleUpload.tsx b/interface/src/components/upload/SingleUpload.tsx index 1eb669e8e..09cd22fc1 100644 --- a/interface/src/components/upload/SingleUpload.tsx +++ b/interface/src/components/upload/SingleUpload.tsx @@ -88,7 +88,7 @@ const SingleUpload = ({ callRestart }) => { sx={{ ml: 2, mt: 2 }} startIcon={} variant="outlined" - color="error" + color="secondary" onClick={cancelUpload} > {LL.CANCEL()} From 71d90d6416ea257846d992b09b93e7898ab4fd89 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 30 Aug 2024 14:59:12 +0200 Subject: [PATCH 32/66] CANCEL button always in dark blue (secondary) color --- interface/src/app/settings/APSettings.tsx | 2 +- interface/src/app/settings/ApplicationSettings.tsx | 2 +- interface/src/app/settings/MqttSettings.tsx | 2 +- interface/src/app/settings/NTPSettings.tsx | 2 +- interface/src/app/settings/network/NetworkSettings.tsx | 2 +- interface/src/app/settings/security/ManageUsers.tsx | 2 +- interface/src/app/settings/security/SecuritySettings.tsx | 2 +- interface/src/components/upload/DragNdrop.tsx | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/src/app/settings/APSettings.tsx b/interface/src/app/settings/APSettings.tsx index 4e7a5087a..0f1f8b462 100644 --- a/interface/src/app/settings/APSettings.tsx +++ b/interface/src/app/settings/APSettings.tsx @@ -206,7 +206,7 @@ const APSettings = () => { startIcon={} disabled={saving} variant="outlined" - color="primary" + color="secondary" type="submit" onClick={loadData} > diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index 409393746..16ac0e31b 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -813,7 +813,7 @@ const ApplicationSettings = () => { diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index e386951c1..093b55a9d 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -272,8 +272,8 @@ export interface BoardProfile { export interface APIcall { device: string; - entity: string; - id: unknown; + cmd: string; + id: number; } export interface WriteAnalogSensor { id: number; diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index 16ac0e31b..9ddc4dd50 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -16,7 +16,7 @@ import { } from '@mui/material'; import Grid from '@mui/material/Grid2'; -import { readHardwareStatus, restart } from 'api/system'; +import { readHardwareStatus } from 'api/system'; import { useRequest } from 'alova/client'; import RestartMonitor from 'app/status/RestartMonitor'; @@ -35,9 +35,9 @@ import { useI18nContext } from 'i18n/i18n-react'; import { numberValue, updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; -import { getBoardProfile, readSettings, writeSettings } from '../../api/app'; +import { API, getBoardProfile, readSettings, writeSettings } from '../../api/app'; import { BOARD_PROFILES } from '../main/types'; -import type { Settings } from '../main/types'; +import type { APIcall, Settings } from '../main/types'; import { createSettingsValidator } from '../main/validators'; export function boardProfileSelectItems() { @@ -80,6 +80,10 @@ const ApplicationSettings = () => { const [fieldErrors, setFieldErrors] = useState(); + const { send: sendAPI } = useRequest((data: APIcall) => API(data), { + immediate: false + }); + const { loading: processingBoard, send: readBoardProfile } = useRequest( (boardProfile: string) => getBoardProfile(boardProfile), { @@ -102,9 +106,14 @@ const ApplicationSettings = () => { }); }); - const { send: restartCommand } = useRequest(restart(), { - immediate: false - }); + const doRestart = async () => { + setRestarting(true); + await sendAPI({ device: 'system', cmd: 'restart', id: -1 }).catch( + (error: Error) => { + toast.error(error.message); + } + ); + }; const updateBoardProfile = async (board_profile: string) => { await readBoardProfile(board_profile).catch((error: Error) => { @@ -158,10 +167,7 @@ const ApplicationSettings = () => { const restart = async () => { await validateAndSubmit(); - await restartCommand().catch((error: Error) => { - toast.error(error.message); - }); - setRestarting(true); + await doRestart(); }; return ( @@ -204,7 +210,7 @@ const ApplicationSettings = () => { label={LL.ENABLE_MODBUS()} /> {data.modbus_enabled && ( - + { label={LL.ENABLE_SYSLOG()} /> {data.syslog_enabled && ( - + { {LL.FORMATTING_OPTIONS()} - + { {data.board_profile === 'CUSTOM' && ( <> - + { {data.phy_type !== 0 && ( - + { )} )} - + { /> )} - + { disabled={!data.shower_timer} /> - + {data.shower_timer && ( { saveFile(event.data, 'schedule.json'); }); - const { send: getAPI } = useRequest((data: APIcall) => API(data), { + const { send: sendAPI } = useRequest((data: APIcall) => API(data), { + immediate: false + }); + + const { send: sendAPIandSave } = useRequest((data: APIcall) => API(data), { immediate: false }).onSuccess((event) => { saveFile( @@ -98,15 +101,13 @@ const DownloadUpload = () => { } ); - const { send: restartCommand } = useRequest(restart(), { - immediate: false - }); - - const callRestart = async () => { + const doRestart = async () => { setRestarting(true); - await restartCommand().catch((error: Error) => { - toast.error(error.message); - }); + await sendAPI({ device: 'system', cmd: 'restart', id: -1 }).catch( + (error: Error) => { + toast.error(error.message); + } + ); }; const { send: sendCheckUpgrade } = useRequest(checkUpgrade, { @@ -200,8 +201,8 @@ const DownloadUpload = () => { }); }; - const callAPI = async (device: string, entity: string) => { - await getAPI({ device, entity, id: 0 }).catch((error: Error) => { + const callAPIandSave = async (device: string, cmd: string) => { + await sendAPIandSave({ device, cmd, id: 0 }).catch((error: Error) => { toast.error(error.message); }); }; @@ -291,7 +292,7 @@ const DownloadUpload = () => { startIcon={} variant="outlined" color="primary" - onClick={() => callAPI('system', 'info')} + onClick={() => callAPIandSave('system', 'info')} > {LL.SUPPORT_INFORMATION(0)} @@ -300,7 +301,7 @@ const DownloadUpload = () => { startIcon={} variant="outlined" color="primary" - onClick={() => callAPI('system', 'allvalues')} + onClick={() => callAPIandSave('system', 'allvalues')} > {LL.ALLVALUES()} @@ -420,15 +421,13 @@ const DownloadUpload = () => { {LL.UPLOAD_TEXT()} - + ); }; return ( - - {restarting ? : content()} - + {restarting ? : content()} ); }; diff --git a/interface/src/app/settings/Settings.tsx b/interface/src/app/settings/Settings.tsx index 06790ada4..f7ef83077 100644 --- a/interface/src/app/settings/Settings.tsx +++ b/interface/src/app/settings/Settings.tsx @@ -21,9 +21,11 @@ import { } from '@mui/material'; import * as SystemApi from 'api/system'; +import { API } from 'api/app'; import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova/client'; +import type { APIcall } from 'app/main/types'; import { SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; import { useI18nContext } from 'i18n/i18n-react'; @@ -34,13 +36,14 @@ const Settings = () => { const [confirmFactoryReset, setConfirmFactoryReset] = useState(false); - const { send: factoryResetCommand } = useRequest(SystemApi.factoryReset(), { + const { send: sendAPI } = useRequest((data: APIcall) => API(data), { immediate: false }); - const factoryReset = async () => { - await factoryResetCommand(); - setConfirmFactoryReset(false); + const doFormat = async () => { + await sendAPI({ device: 'system', cmd: 'format', id: 0 }).then(() => { + setConfirmFactoryReset(false); + }); }; const renderFactoryResetDialog = () => ( @@ -63,7 +66,7 @@ const Settings = () => { diff --git a/interface/src/app/status/RestartMonitor.tsx b/interface/src/app/status/RestartMonitor.tsx index 4b1f32daf..e652fe757 100644 --- a/interface/src/app/status/RestartMonitor.tsx +++ b/interface/src/app/status/RestartMonitor.tsx @@ -1,52 +1,80 @@ -import { type FC, useEffect, useRef, useState } from 'react'; +import { useState } from 'react'; + +import { + Box, + CircularProgress, + Dialog, + DialogContent, + Typography +} from '@mui/material'; import { readHardwareStatus } from 'api/system'; -import { useRequest } from 'alova/client'; -import { FormLoader } from 'components'; +import { dialogStyle } from 'CustomTheme'; +import { useAutoRequest } from 'alova/client'; +import MessageBox from 'components/MessageBox'; import { useI18nContext } from 'i18n/i18n-react'; -const RESTART_TIMEOUT = 2 * 60 * 1000; // 2 minutes -const POLL_INTERVAL = 2000; // every 2 seconds - -export interface RestartMonitorProps { - message?: string; -} - -const RestartMonitor: FC = ({ message }) => { - const [failed, setFailed] = useState(false); - const [timeoutId, setTimeoutId] = useState(); +const RestartMonitor = () => { + const [errorMessage, setErrorMessage] = useState(); const { LL } = useI18nContext(); - const timeoutAt = useRef(new Date().getTime() + RESTART_TIMEOUT); + let count = 0; - const { send } = useRequest(readHardwareStatus, { immediate: false }); - - const poll = useRef(async () => { - try { - await send(); - document.location.href = '/'; - } catch { - if (new Date().getTime() < timeoutAt.current) { - setTimeoutId(setTimeout(poll.current, POLL_INTERVAL)); - } else { - setFailed(true); + const { data } = useAutoRequest(readHardwareStatus, { + pollingTime: 1000, + force: true, + initialData: { status: 'Getting ready...' }, + async middleware(_, next) { + if (count++ >= 1) { + // skip first request (1 seconds) to allow AsyncWS to send its response + await next(); } } - }); - - useEffect(() => { - setTimeoutId(setTimeout(poll.current, POLL_INTERVAL)); - }, []); - - useEffect(() => () => timeoutId && clearTimeout(timeoutId), [timeoutId]); + }) + .onSuccess((event) => { + console.log(event.data.status); // TODO remove + if (event.data.status === 'ready' || event.data.status === undefined) { + document.location.href = '/'; + } + }) + .onError((error, _method) => { + setErrorMessage(error.message); + }); return ( - + + + + + {data?.status === 'uploading' + ? LL.WAIT_FIRMWARE() + : data?.status === 'restarting' + ? LL.APPLICATION_RESTARTING() + : data?.status === 'ready' + ? 'Reloading' + : 'Preparing'} + + + {LL.PLEASE_WAIT()}… + + + {errorMessage ? ( + + ) : ( + + + + )} + + + ); }; diff --git a/interface/src/app/status/Status.tsx b/interface/src/app/status/Status.tsx index 95b880fa0..e14ee3948 100644 --- a/interface/src/app/status/Status.tsx +++ b/interface/src/app/status/Status.tsx @@ -30,10 +30,11 @@ import { } from '@mui/material'; import * as SystemApi from 'api/system'; +import { API } from 'api/app'; import { dialogStyle } from 'CustomTheme'; import { useAutoRequest, useRequest } from 'alova/client'; -import { busConnectionStatus } from 'app/main/types'; +import { type APIcall, busConnectionStatus } from 'app/main/types'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; import { AuthenticatedContext } from 'contexts/authentication'; @@ -54,7 +55,7 @@ const SystemStatus = () => { const [confirmRestart, setConfirmRestart] = useState(false); const [restarting, setRestarting] = useState(); - const { send: restartCommand } = useRequest(SystemApi.restart(), { + const { send: sendAPI } = useRequest((data: APIcall) => API(data), { immediate: false }); @@ -64,7 +65,12 @@ const SystemStatus = () => { error } = useAutoRequest(SystemApi.readSystemStatus, { initialData: [], - pollingTime: 5000 + pollingTime: 5000, + async middleware(_, next) { + if (!restarting) { + await next(); + } + } }); const theme = useTheme(); @@ -195,17 +201,14 @@ const SystemStatus = () => { const activeHighlight = (value: boolean) => value ? theme.palette.success.main : theme.palette.info.main; - const restart = async () => { - await restartCommand() - .then(() => { - setRestarting(true); - }) - .catch((error: Error) => { + const doRestart = async () => { + setConfirmRestart(false); + setRestarting(true); + await sendAPI({ device: 'system', cmd: 'restart', id: -1 }).catch( + (error: Error) => { toast.error(error.message); - }) - .finally(() => { - setConfirmRestart(false); - }); + } + ); }; const renderRestartDialog = () => ( @@ -228,7 +231,7 @@ const SystemStatus = () => { + ) : ( + + + {LL.DOWNLOAD(1)} + + )} diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index 2d07b583b..f184475ff 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -389,7 +389,8 @@ let hardware_status = { fs_used: 24, fs_free: 2024, free_caps: 8376, - psram: 8189, + // psram: false, + psram: true, psram_size: 8189, free_psram: 8166, has_loader: true, @@ -4541,7 +4542,7 @@ router // check upgrade .post(EMSESP_CHECK_UPGRADE_ENDPOINT, async (request: any) => { const content = await request.json(); - console.log('check upgrade', content.version); + console.log('check upgrade from ', content.version); const data = { upgradeable: true // upgradeable: false From cbd38dbf157796205c6c1da600471f8dc8cd2749 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 1 Sep 2024 14:17:37 +0200 Subject: [PATCH 63/66] fix upload_status --- src/emsesp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 504ae3d99..0523562a3 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -1653,9 +1653,9 @@ void EMSESP::start() { // main loop calling all services void EMSESP::loop() { - esp8266React.loop(); // web services - system_.loop(); // does LED and checks system health, and syslog service - bool upload_status = true; // ready for any OTA uploads + esp8266React.loop(); // web services + system_.loop(); // does LED and checks system health, and syslog service + static bool upload_status = true; // ready for any OTA uploads // if we're doing an OTA upload, skip everything except from console refresh if (!system_.upload_isrunning()) { From 4807e9749f4a3e3c4e95b42ba206ca85131f474e Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 1 Sep 2024 20:14:20 +0200 Subject: [PATCH 64/66] package update --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index 90f1db04a..129141dd1 100644 --- a/interface/package.json +++ b/interface/package.json @@ -48,7 +48,7 @@ "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/babel__core": "^7", "@types/formidable": "^3", - "@types/node": "^22.5.1", + "@types/node": "^22.5.2", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", diff --git a/interface/yarn.lock b/interface/yarn.lock index 5b0c264ca..71ca62e1b 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1486,12 +1486,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^22.5.1": - version: 22.5.1 - resolution: "@types/node@npm:22.5.1" +"@types/node@npm:^22.5.2": + version: 22.5.2 + resolution: "@types/node@npm:22.5.2" dependencies: undici-types: "npm:~6.19.2" - checksum: 10c0/35373176d8a1d4e16004a1ed303e68d39e4c6341024dc056f2577982df98c1a045a6b677f12ed557796f09bbf7d621f428f6874cc37ed28f7b336fa604b5f6a6 + checksum: 10c0/624a7fd76229eacc6c158eb3b9afd55b811d7f01976c5f92c630d5b9d47047cc218928c343988484a165ac400e5eb6fe70ea300fc7242deeb0e920c7724290f6 languageName: node linkType: hard @@ -1719,7 +1719,7 @@ __metadata: "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@types/babel__core": "npm:^7" "@types/formidable": "npm:^3" - "@types/node": "npm:^22.5.1" + "@types/node": "npm:^22.5.2" "@types/react": "npm:^18.3.5" "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" From b3a89ee8c964779b6237d6a26cfc7f42d0874ff0 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 1 Sep 2024 20:14:51 +0200 Subject: [PATCH 65/66] add S32 --- pio_local.ini_example | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pio_local.ini_example b/pio_local.ini_example index c77b2b619..c8ff57ce9 100644 --- a/pio_local.ini_example +++ b/pio_local.ini_example @@ -17,7 +17,8 @@ [platformio] ; default_envs = s_16M_P ; BBQKees E32V2 -default_envs = s3_16M_P ; BBQKees S3 +; default_envs = s3_16M_P ; BBQKees S3 +default_envs = s_4M ; BBQKees S32 ; default_envs = native ; default_envs = debug @@ -25,11 +26,10 @@ default_envs = s3_16M_P ; BBQKees S3 ; upload settings ; for USB ; upload_protocol = esptool -; upload_port = /dev/ttyUSB* +upload_port = /dev/ttyUSB* ; for OTA add scripts/upload.py to extra_scripts upload_protocol = custom custom_emsesp_ip = 10.10.10.175 -; custom_emsesp_ip = 192.168.1.23 ; custom_emsesp_ip = ems-esp.local custom_username = admin custom_password = admin @@ -51,10 +51,16 @@ extra_scripts = [env:s3_16M_P] extra_scripts = - pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time + ; pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time scripts/rename_fw.py scripts/upload.py +[env:s_4M] +extra_scripts = + pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time + scripts/rename_fw.py + scripts/upload.py + ; pio run -e debug ; or from Visual Studio Code do PIO -> Project Tasks -> debug -> General -> Upload and Monitor ; options for debugging are: EMSESP_DEBUG EMSESP_UART_DEBUG EMSESP_DEBUG_SENSOR From 6d020fa4d16f2300a326f1634b9584e23d5045cf Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 1 Sep 2024 20:37:03 +0200 Subject: [PATCH 66/66] fix dev vs stable for 4MB downloads --- interface/src/app/settings/DownloadUpload.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/src/app/settings/DownloadUpload.tsx b/interface/src/app/settings/DownloadUpload.tsx index 3ca25bc03..812d0c9e3 100644 --- a/interface/src/app/settings/DownloadUpload.tsx +++ b/interface/src/app/settings/DownloadUpload.tsx @@ -142,6 +142,7 @@ const DownloadUpload = () => { if (!latestVersion || !latestDevVersion) { return ''; } + console.log('getBinURL', useDevVersion, latestDevVersion, latestVersion); const filename = 'EMS-ESP-' + (useDevVersion ? latestDevVersion : latestVersion).replaceAll('.', '_') + @@ -270,7 +271,7 @@ const DownloadUpload = () => { ); }; - // useDev = true to force using the dev version + // useDevVersion = true to force using the dev version const showFirmwareDialog = (useDevVersion: boolean) => { if (useDevVersion || data.emsesp_version.includes('dev')) { setUseDev(true); @@ -415,11 +416,13 @@ const DownloadUpload = () => { : LL.INSTALL('v' + latestVersion)} ) : ( - - - {LL.DOWNLOAD(1)} + <> +    + + {LL.DOWNLOAD(1)} v + {isDev ? latestDevVersion : latestVersion} - + )}