This commit is contained in:
proddy
2026-09-04 16:30:58 +02:00
parent 6291bdfa5d
commit 0a50a9b1fa
20 changed files with 171 additions and 121 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ This release is based on the latest Espressif/Arduino core version 3. It brings
- option to disable factory reset [#3150](https://github.com/emsesp/EMS-ESP32/issues/3150)
- TLS support with 4MB boards without PSRAM
- added eth_10mbit to Network Settings, which forces 10BASE-T half-duplex & autonegotiation off, halving the PHYs power draw. Its off by default as it will cause issues on managed switches with a port forced to 100Mb [#3213](https://github.com/emsesp/EMS-ESP32/pull/3213)
- cleaner MD5 and firmware uploading in WebUI [#3203](https://github.com/emsesp/EMS-ESP32/discussions/3203)
- cleaner MD5 and firmware uploading in WebUI [#3222](https://github.com/emsesp/EMS-ESP32/issues/3222)
## Fixed
+2 -1
View File
@@ -19,6 +19,7 @@ export const uploadFile = (file: File) => {
const formData = new FormData();
formData.append('file', file);
return alovaInstance.Post('/rest/uploadFile', formData, {
timeout: UPLOAD_TIMEOUT
timeout: UPLOAD_TIMEOUT,
enableUpload: true
});
};
@@ -165,11 +165,7 @@ const DownloadUpload = () => {
{LL.UPLOAD()}
</Typography>
<Typography sx={{ pb: 2 }} color="warning" variant="body1">
{LL.UPLOAD_TEXT()}:
</Typography>
<SingleUpload doRestart={doRestart} />
<SingleUpload text={LL.UPLOAD_BACKUP_TEXT()} doRestart={doRestart} />
</SectionContent>
);
};
+1 -1
View File
@@ -846,7 +846,7 @@ const Version = () => {
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
{LL.UPLOAD()}
</Typography>
<SingleUpload doRestart={doRestart} />
<SingleUpload text={LL.UPLOAD_FIRMWARE_TEXT()} doRestart={doRestart} />
</>
)}
</Box>
@@ -14,9 +14,10 @@ import { LinearProgressWithLabel } from './LinearProgressWithLabel';
interface SingleUploadProps {
doRestart: () => void;
text: string;
}
const SingleUpload = ({ doRestart }: SingleUploadProps) => {
const SingleUpload = ({ doRestart, text }: SingleUploadProps) => {
const [md5, setMd5] = useState<string>();
const [file, setFile] = useState<File>();
const { LL } = useI18nContext();
@@ -92,7 +93,7 @@ const SingleUpload = ({ doRestart }: SingleUploadProps) => {
</>
) : (
<DragNdrop
text={(md5 ? LL.UPLOAD_MD5_RECEIVED() : LL.UPLOAD_DROP_TEXT()) + '...'}
text={(md5 ? LL.UPLOAD_MD5_RECEIVED() : text) + '...'}
onFileSelected={setFile}
/>
)}
+5 -5
View File
@@ -178,10 +178,6 @@ const cs: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Vytvořte zálohu svého nastavení a konfigurace',
DOWNLOAD_SETTINGS_TEXT2: 'Exportovat všechny hodnoty',
DOWNLOAD_SYSTEM_BACKUP: 'Systémová záloha',
UPLOAD_TEXT: 'Nahrajte nový soubor firmwaru (.bin) nebo záložní soubor (.json)',
UPLOAD_DROP_TEXT: 'Přetáhněte soubor sem nebo klikněte pro výběr',
UPLOAD_MD5_RECEIVED: 'Digest přijat, nyní nahrajte firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 souhlasí, firmware se instaluje...',
ERROR: 'Neočekávaná chyba, zkuste to prosím znovu',
TIME_SET: 'Čas nastaven',
MANAGE_USERS: 'Spravovat uživatele',
@@ -351,7 +347,11 @@ const cs: Translation = {
COMMANDS_HELP_1: 'Definujte vlastní příkazy pro magistrali EMS',
COMMAND_EXECUTED: 'Příkaz úspěšně spuštěn',
RUN: 'Spustit příkaz',
INTERNET_CONNECTION_CHECK: 'Kontrola online pro dostupné verze'
INTERNET_CONNECTION_CHECK: 'Kontrola online pro dostupné verze',
UPLOAD_BACKUP_TEXT: 'Klikněte, abyste vybrali nebo přetáhli a pustili soubor zálohy (.json) sem',
UPLOAD_FIRMWARE_TEXT: 'Klikněte, abyste vybrali nebo přetáhli a pustili soubor firmware .bin/.md5 sem',
UPLOAD_MD5_RECEIVED: 'Digest přijat, nyní nahrajte firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 souhlasí, firmware se instaluje...'
};
export default cs;
+5 -5
View File
@@ -178,10 +178,6 @@ const de: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Erstellen Sie eine Sicherung Ihrer Konfigurationen und Einstellungen',
DOWNLOAD_SETTINGS_TEXT2: 'Exportiere alle Werte',
DOWNLOAD_SYSTEM_BACKUP: 'Systemsicherung',
UPLOAD_TEXT: 'Laden Sie eine neue Firmware-Datei (.bin) oder eine Sicherungsdatei (.json) hoch',
UPLOAD_DROP_TEXT: 'Legen Sie eine Firmware-Datei (.bin) ab oder klicken Sie hier',
UPLOAD_MD5_RECEIVED: 'Prüfsumme empfangen, jetzt die Firmware-Datei (.bin) hochladen',
UPLOAD_MD5_MATCHED: 'MD5 stimmt überein, Firmware wird installiert...',
ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut.',
TIME_SET: 'Zeit gesetzt',
MANAGE_USERS: 'Nutzerverwaltung',
@@ -351,7 +347,11 @@ const de: Translation = {
COMMANDS_HELP_1: 'Definieren Sie eigene Befehle für die EMS-Magistral',
COMMAND_EXECUTED: 'Befehl erfolgreich ausgeführt',
RUN: 'Befehl ausführen',
INTERNET_CONNECTION_CHECK: 'Online-Prüfung auf verfügbare Versionen'
INTERNET_CONNECTION_CHECK: 'Online-Prüfung auf verfügbare Versionen',
UPLOAD_BACKUP_TEXT: 'Klicken Sie, um eine Sicherungsdatei (.json) auszuwählen oder zu ziehen und abzulegen',
UPLOAD_FIRMWARE_TEXT: 'Klicken Sie, um eine Firmware-Datei (.bin/.md5) auszuwählen oder zu ziehen und abzulegen',
UPLOAD_MD5_RECEIVED: 'Prüfsumme empfangen, jetzt die Firmware-Datei (.bin) hochladen',
UPLOAD_MD5_MATCHED: 'MD5 stimmt überein, Firmware wird installiert...'
};
export default de;
+5 -5
View File
@@ -178,10 +178,6 @@ const en: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings',
DOWNLOAD_SETTINGS_TEXT2: 'Export all values',
DOWNLOAD_SYSTEM_BACKUP: 'System Backup',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)',
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
UPLOAD_MD5_RECEIVED: 'Digest received, now upload the firmware .bin file',
UPLOAD_MD5_MATCHED: 'MD5 matches, installing firmware...',
ERROR: 'Unexpected Error, please try again',
TIME_SET: 'Time set',
MANAGE_USERS: 'Manage Users',
@@ -351,7 +347,11 @@ const en: Translation = {
COMMANDS_HELP_1: 'Define reusable named commands below. These can be executed from the console, API/MQTT, or referenced by the Scheduler',
COMMAND_EXECUTED: 'Command executed successfully',
RUN: 'Run',
INTERNET_CONNECTION_CHECK: 'Checking online for available versions'
INTERNET_CONNECTION_CHECK: 'Checking online for available versions',
UPLOAD_BACKUP_TEXT: 'Click to select or Drag&Drop a backup file (.json) here',
UPLOAD_FIRMWARE_TEXT: 'Click to select or Drag&Drop a firmware .bin/.md5 file',
UPLOAD_MD5_RECEIVED: 'Digest received, now upload the firmware .bin file',
UPLOAD_MD5_MATCHED: 'MD5 matches, installing firmware...'
};
export default en;
+5 -5
View File
@@ -178,10 +178,6 @@ const fr: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Créer une sauvegarde de vos paramètres et configurations',
DOWNLOAD_SETTINGS_TEXT2: 'Exporter toutes les valeurs',
DOWNLOAD_SYSTEM_BACKUP: 'Sauvegarde système',
UPLOAD_TEXT: 'Télécharger un nouveau fichier firmware (.bin) ou une sauvegarde (.json)',
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
UPLOAD_MD5_RECEIVED: 'Empreinte reçue, téléversez maintenant le fichier firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 concordant, installation du firmware...',
ERROR: 'Erreur inattendue, veuillez réessayer',
TIME_SET: 'Time set',
MANAGE_USERS: 'Gérer les utilisateurs',
@@ -351,7 +347,11 @@ const fr: Translation = {
COMMANDS_HELP_1: 'Définir des commandes personnalisées pour la magistral EMS',
COMMAND_EXECUTED: 'Commande exécutée avec succès',
RUN: 'Exécuter une commande',
INTERNET_CONNECTION_CHECK: 'Vérification en ligne pour les versions disponibles'
INTERNET_CONNECTION_CHECK: 'Vérification en ligne pour les versions disponibles',
UPLOAD_BACKUP_TEXT: 'Cliquez pour sélectionner ou faites glisser et déposez un fichier de sauvegarde (.json) ici',
UPLOAD_FIRMWARE_TEXT: 'Cliquez pour sélectionner ou faites glisser et déposez un fichier firmware .bin/.md5 ici',
UPLOAD_MD5_RECEIVED: 'Empreinte reçue, téléversez maintenant le fichier firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 concordant, installation du firmware...'
};
export default fr;
+5 -5
View File
@@ -178,10 +178,6 @@ const it: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings',
DOWNLOAD_SETTINGS_TEXT2: 'Esporta tutti i valori',
DOWNLOAD_SYSTEM_BACKUP: 'Backup sistema',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)',
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
UPLOAD_MD5_RECEIVED: 'Digest received, now upload the firmware .bin file',
UPLOAD_MD5_MATCHED: 'MD5 matches, installing firmware...',
ERROR: 'Errore Inaspettato, prego tenta ancora',
TIME_SET: 'Imposta Ora',
MANAGE_USERS: 'Gestione Utenti',
@@ -351,7 +347,11 @@ const it: Translation = {
COMMANDS_HELP_1: 'Definisci comandi personalizzati per la magistrali EMS',
COMMAND_EXECUTED: 'Comando eseguito con successo',
RUN: 'Esegui comando',
INTERNET_CONNECTION_CHECK: 'Controllo online per le versioni disponibili'
INTERNET_CONNECTION_CHECK: 'Controllo online per le versioni disponibili',
UPLOAD_BACKUP_TEXT: 'Klik per selezionare o trascinare e rilasciare un file di backup (.json) qui',
UPLOAD_FIRMWARE_TEXT: 'Klik per selezionare o trascinare e rilasciare un file firmware .bin/.md5 qui',
UPLOAD_MD5_RECEIVED: 'Digest ricevuto, ora caricare il file firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 corrispondente, installazione firmware...'
};
export default it;
+5 -5
View File
@@ -178,10 +178,6 @@ const nl: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Maak een back-up van uw configuratie en instellingen',
DOWNLOAD_SETTINGS_TEXT2: 'Exporteer alle waarden',
DOWNLOAD_SYSTEM_BACKUP: 'Systeem Backup',
UPLOAD_TEXT: 'Upload een nieuw firmwarebestand (.bin) of een back-upbestand (.json)',
UPLOAD_DROP_TEXT: 'Sleep en firmware .bin bestand hierheen of klik hier',
UPLOAD_MD5_RECEIVED: 'Digest ontvangen, upload nu het firmware .bin-bestand',
UPLOAD_MD5_MATCHED: 'MD5 komt overeen, firmware wordt geïnstalleerd...',
ERROR: 'Onverwachte fout, probeer opnieuw',
TIME_SET: 'Tijd ingesteld',
MANAGE_USERS: 'Gebruikersbeheer',
@@ -351,7 +347,11 @@ const nl: Translation = {
COMMANDS_HELP_1: 'Definieer hergebruikbare benoemde commando\'s hieronder. Deze kunnen worden uitgevoerd vanuit de console, API/MQTT, of worden aangeroepen door de Scheduler',
COMMAND_EXECUTED: 'Commando uitgevoerd succesvol',
RUN: 'Commando uitvoeren',
INTERNET_CONNECTION_CHECK: 'Controleren op online beschikbare versies'
INTERNET_CONNECTION_CHECK: 'Controleren op online beschikbare versies',
UPLOAD_BACKUP_TEXT: 'Klik voor selecteren of sleep en drop een back-upbestand (.json) hier',
UPLOAD_FIRMWARE_TEXT: 'Klik voor selecteren of sleep en drop een firmware .bin/.md5 bestand hier',
UPLOAD_MD5_RECEIVED: 'Digest ontvangen, upload nu het firmware .bin-bestand',
UPLOAD_MD5_MATCHED: 'MD5 komt overeen, firmware wordt geïnstalleerd...'
};
export default nl;
+5 -5
View File
@@ -178,10 +178,6 @@ const no: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Lag en sikkerhetskopi av dine konfigurasjon og innstillinger',
DOWNLOAD_SETTINGS_TEXT2: 'Eksporter alle verdier',
DOWNLOAD_SYSTEM_BACKUP: 'System Sikkerhetskopi',
UPLOAD_TEXT: 'Last opp en ny firmware fil (.bin) eller en sikkerhetskopi fil (.json)',
UPLOAD_DROP_TEXT: 'Dropp en firmware fil (.bin) eller klikk her',
UPLOAD_MD5_RECEIVED: 'Digest mottatt, last nå opp firmware .bin-filen',
UPLOAD_MD5_MATCHED: 'MD5 stemmer, firmware installeres...',
ERROR: 'Ukjent feil, prøv igjen',
TIME_SET: 'Still in tid',
MANAGE_USERS: 'Administrer Brukere',
@@ -351,7 +347,11 @@ const no: Translation = {
COMMANDS_HELP_1: 'Definer egne kommandoer for EMS-Magistral',
COMMAND_EXECUTED: 'Kommando kjørt lykkes',
RUN: 'Kjør',
INTERNET_CONNECTION_CHECK: 'Kontrollerer online for tilgjengelige versjoner'
INTERNET_CONNECTION_CHECK: 'Kontrollerer online for tilgjengelige versjoner',
UPLOAD_BACKUP_TEXT: 'Klikk for å velge eller dra og slipp en sikkerhetskopi (.json) her',
UPLOAD_FIRMWARE_TEXT: 'Klikk for å velge eller dra og slipp en firmware .bin/.md5 her',
UPLOAD_MD5_RECEIVED: 'MD5 mottatt, last nå opp firmware .bin-filen',
UPLOAD_MD5_MATCHED: 'MD5 stemmer, firmware installeres...'
};
export default no;
+5 -5
View File
@@ -178,10 +178,6 @@ const pl: BaseTranslation = {
DOWNLOAD_SETTINGS_TEXT: 'Utwórz kopię swoich ustawień i konfiguracji',
DOWNLOAD_SETTINGS_TEXT2: 'Eksportuj wszystkie wartości',
DOWNLOAD_SYSTEM_BACKUP: 'Kopia zapasowa systemu',
UPLOAD_TEXT: 'Wgraj nowy plik firmware (.bin) lub kopię ustawień (.json)',
UPLOAD_DROP_TEXT: 'Upuść plik firmware .bin lub kliknij tutaj',
UPLOAD_MD5_RECEIVED: 'Suma MD5 odebrana, teraz wgraj plik firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 zgodne, instalowanie firmware...',
ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!',
TIME_SET: 'Zegar został ustawiony.',
MANAGE_USERS: 'Zarządzanie użytkownikami',
@@ -351,7 +347,11 @@ const pl: BaseTranslation = {
COMMANDS_HELP_1: 'Zdefiniuj niestandardowe komendy dla magistrali EMS',
COMMAND_EXECUTED: 'Komenda wykonana pomyślnie',
RUN: 'Wykonaj',
INTERNET_CONNECTION_CHECK: 'Sprawdzanie online dla dostępnych wersji'
INTERNET_CONNECTION_CHECK: 'Sprawdzanie online dla dostępnych wersji',
UPLOAD_BACKUP_TEXT: 'Kliknij, aby wybrać lub przeciągnij i upuść plik kopii zapasowej (.json) tutaj',
UPLOAD_FIRMWARE_TEXT: 'Kliknij, aby wybrać lub przeciągnij i upuść plik firmware .bin/.md5',
UPLOAD_MD5_RECEIVED: 'Suma MD5 odebrana, teraz wgraj plik firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 zgodne, instalowanie firmware...'
};
export default pl;
+5 -5
View File
@@ -178,10 +178,6 @@ const sk: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Vytvorte zálohu svojej konfigurácie a nastavení',
DOWNLOAD_SETTINGS_TEXT2: 'Exportovať všetky hodnoty',
DOWNLOAD_SYSTEM_BACKUP: 'Systémová záloha',
UPLOAD_TEXT: 'Nahrajte nový súbor firmvéru (.bin) alebo súbor zálohy (.json)',
UPLOAD_DROP_TEXT: 'Presuňte súbor .bin firmvéru alebo kliknite sem',
UPLOAD_MD5_RECEIVED: 'Digest prijatý, teraz nahrajte firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 súhlasí, firmvér sa inštaluje...',
ERROR: 'Neočakávaná chyba, prosím skúste to znova',
TIME_SET: 'Nastavený čas',
MANAGE_USERS: 'Správa používateľov',
@@ -351,7 +347,11 @@ const sk: Translation = {
COMMANDS_HELP_1: 'Definujte vlastné príkazy pre magistrali EMS',
COMMAND_EXECUTED: 'Príkaz vykonaný úspešne',
RUN: 'Volať príkaz',
INTERNET_CONNECTION_CHECK: 'Kontrola online pre dostupné verzie'
INTERNET_CONNECTION_CHECK: 'Kontrola online pre dostupné verzie',
UPLOAD_BACKUP_TEXT: 'Kliknite, aby ste vybrali alebo presuňte a upustili súbor zálohy (.json) sem',
UPLOAD_FIRMWARE_TEXT: 'Kliknite, aby ste vybrali alebo presuňte a upustili súbor firmware .bin/.md5',
UPLOAD_MD5_RECEIVED: 'Suma MD5 prijatá, teraz nahrajte firmware .bin',
UPLOAD_MD5_MATCHED: 'MD5 súhlasí, firmvér sa inštaluje...'
};
export default sk;
+5 -5
View File
@@ -178,10 +178,6 @@ const sv: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Skapa en säkerhetskopia av din konfiguration och inställningar',
DOWNLOAD_SETTINGS_TEXT2: 'Exportera alla värden',
DOWNLOAD_SYSTEM_BACKUP: 'System säkerhetskopia',
UPLOAD_TEXT: 'Ladda upp en ny firmwarefil (.bin) eller en säkerhetskopiafil (.json)',
UPLOAD_DROP_TEXT: 'Droppa en firmware .bin fil eller klicka här',
UPLOAD_MD5_RECEIVED: 'Digest mottagen, ladda nu upp firmware .bin-filen',
UPLOAD_MD5_MATCHED: 'MD5 stämmer, firmware installeras...',
ERROR: 'Okänt fel, var god försök igen',
TIME_SET: 'Ställ in tid',
MANAGE_USERS: 'Användare',
@@ -351,7 +347,11 @@ const sv: Translation = {
COMMANDS_HELP_1: 'Definiera egna kommandon för EMS-Magistral',
COMMAND_EXECUTED: 'Kommando kört lyckades',
RUN: 'Kör kommando',
INTERNET_CONNECTION_CHECK: 'Kontrollerar online för tillgängliga versioner'
INTERNET_CONNECTION_CHECK: 'Kontrollerar online för tillgängliga versioner',
UPLOAD_BACKUP_TEXT: 'Klicka för att välja eller dra och släpp en säkerhetskopia (.json) här',
UPLOAD_FIRMWARE_TEXT: 'Klicka för att välja eller dra och släpp en firmware .bin/.md5 här',
UPLOAD_MD5_RECEIVED: 'MD5 mottagen, ladda nu upp firmware .bin-filen',
UPLOAD_MD5_MATCHED: 'MD5 stämmer, firmware installeras...'
};
export default sv;
+5 -5
View File
@@ -178,10 +178,6 @@ const tr: Translation = {
DOWNLOAD_SETTINGS_TEXT: 'Yapılandırma ve ayarlarınızın yedekleme yapın',
DOWNLOAD_SETTINGS_TEXT2: 'Tüm değerleri dışarı al',
DOWNLOAD_SYSTEM_BACKUP: 'Sistem yedekleme',
UPLOAD_TEXT: 'Yeni bir firmware dosyası (.bin) veya yedek dosyası (.json) yükle',
UPLOAD_DROP_TEXT: 'Bir firmware .bin dosyası veya buraya tıklayın',
UPLOAD_MD5_RECEIVED: 'Özet alındı, şimdi firmware .bin dosyasını yükleyin',
UPLOAD_MD5_MATCHED: 'MD5 eşleşti, firmware yükleniyor...',
ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.',
TIME_SET: 'Zaman ayarı',
MANAGE_USERS: 'Kullanıcıları yönet',
@@ -351,7 +347,11 @@ const tr: Translation = {
COMMANDS_HELP_1: 'Özel komutları EMS hattına tanımlayın',
COMMAND_EXECUTED: 'Komut başarıyla çalıştırıldı',
RUN: 'Komutu çalıştır',
INTERNET_CONNECTION_CHECK: 'Online bağlantısı kontrol ediliyor'
INTERNET_CONNECTION_CHECK: 'Online bağlantısı kontrol ediliyor',
UPLOAD_BACKUP_TEXT: 'Yeni bir firmware dosyası (.bin) veya yedek dosyası (.json) yükle',
UPLOAD_FIRMWARE_TEXT: 'Bir firmware .bin dosyası veya buraya tıklayın',
UPLOAD_MD5_RECEIVED: 'Özet alındı, şimdi firmware .bin dosyasını yükleyin',
UPLOAD_MD5_MATCHED: 'MD5 eşleşti, firmware yükleniyor...'
};
export default tr;
-3
View File
@@ -207,9 +207,6 @@ export default defineConfig(
async ({ command, mode }: { command: string; mode: string }) => {
if (command === 'serve') {
console.log(`Preparing for standalone build with server, mode=${mode}`);
// Imported through a computed URL so the config bundler leaves it as a real
// runtime import: mock-api is a separate package with its own node_modules,
// and inlining it here would drag its dependencies into every build.
const mockServerUrl = pathToFileURL(
path.resolve(import.meta.dirname, '../mock-api/mockServer.js')
).href;
@@ -1,5 +1,6 @@
// Simulate EventSource for log messages in EMS-ESP standalone mode
// Server-Sent Events (SSE)
// EMS-ESP standalone mode to simulate
// a REST server for file uploads
// an EventSource (Server-Sent Events) for log messages in EMS-ESP standalone mode
const ONE_SECOND_MS = 1000;
// padding function
@@ -21,11 +22,113 @@ const formatDate = (date) => {
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
};
const MOCK_REST_ORIGIN = 'http://localhost:3080';
const UPLOAD_SIMULATED_KB_PER_SEC = 256;
const UPLOAD_SLICE_BYTES = 16 * 1024;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const readRequestThrottled = (req) =>
new Promise((resolve, reject) => {
const chunks = [];
let ended = false;
let settled = false;
const settle = (settler, value) => {
if (settled) {
return;
}
settled = true;
settler(value);
};
req.on('error', (error) => settle(reject, error));
req.on('end', () => {
ended = true;
void step();
});
const step = async () => {
if (settled) {
return;
}
try {
const chunk = req.read(UPLOAD_SLICE_BYTES);
if (chunk) {
chunks.push(chunk);
await sleep((chunk.length / (UPLOAD_SIMULATED_KB_PER_SEC * 1024)) * 1000);
void step();
return;
}
if (ended || req.readableEnded) {
settle(resolve, Buffer.concat(chunks));
return;
}
req.once('readable', () => {
void step();
});
} catch (error) {
settle(reject, error);
}
};
void step();
});
const forwardThrottledUpload = async (req, res) => {
const startedAt = Date.now();
try {
const body = await readRequestThrottled(req);
console.log(
`Upload received: ${body.length} bytes in ${((Date.now() - startedAt) / 1000).toFixed(1)}s`
);
const headers = {};
if (req.headers['content-type']) {
headers['content-type'] = req.headers['content-type'];
}
if (req.headers.authorization) {
headers.authorization = req.headers.authorization;
}
headers['content-length'] = String(body.length);
const bunRes = await fetch(`${MOCK_REST_ORIGIN}${req.url}`, {
method: 'POST',
headers,
body
});
const buf = Buffer.from(await bunRes.arrayBuffer());
res.statusCode = bunRes.status;
bunRes.headers.forEach((value, key) => {
if (key !== 'transfer-encoding' && key !== 'content-encoding') {
res.setHeader(key, value);
}
});
res.end(buf);
} catch (error) {
if (error?.code === 'ECONNRESET' || req.destroyed) {
console.log('Upload cancelled by the client');
} else {
console.error('Throttled upload proxy failed', error);
}
if (!res.headersSent) {
res.statusCode = 502;
}
if (!res.writableEnded) {
res.end();
}
}
};
export default () => {
return {
name: 'vite:mockserver',
name: 'vite:mockServer',
configureServer: async (server) => {
server.middlewares.use(async (req, res, next) => {
if (req.url.startsWith('/rest/uploadFile') && req.method === 'POST') {
await forwardThrottledUpload(req, res);
return;
}
// Handle Server-Sent Events (SSE) for log streaming
if (req.url.startsWith('/es/log')) {
// Set SSE headers
+1 -49
View File
@@ -242,15 +242,6 @@ let countHardwarePoll = 0; // for during an upload
let pendingFirmwareMd5 = false; // set by a .md5 upload, cleared by the next .bin
const VALID_UPLOAD_EXTENSIONS = new Set(['bin', 'json', 'md5']);
const UPLOAD_PROGRESS_LOG_STEP = 10; // log every 10%
// A real device takes a while to accept a firmware image, so uploads are read at
// this rate instead of completing instantly. That keeps the WebUI progress bar on
// screen long enough to see. Lower it to watch the progress bar for longer.
const UPLOAD_SIMULATED_KB_PER_SEC = 2048;
const UPLOAD_SLICE_BYTES = 64 * 1024; // granularity of the simulated transfer
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
function parseMd5Digest(text: string): string | null {
const token = text.trim().split(/\s+/)[0];
@@ -260,45 +251,6 @@ function parseMd5Digest(text: string): string | null {
return null;
}
// Read the multipart body in slices at UPLOAD_SIMULATED_KB_PER_SEC, logging progress
// as it goes, then hand the buffered bytes back as FormData so they parse normally.
async function readUploadSlowly(request: Request): Promise<FormData> {
const contentType = request.headers.get('content-type') || '';
const expected = Number(request.headers.get('content-length') || '0');
const reader = request.body?.getReader();
const chunks: Uint8Array[] = [];
let received = 0;
let loggedPercentage = 0;
while (reader) {
const { done, value } = await reader.read();
if (done) {
break;
}
chunks.push(value);
// A fast local client arrives in very few chunks, so pace each one slice by
// slice to keep the reported progress gradual instead of jumping to 100%
for (let offset = 0; offset < value.length; offset += UPLOAD_SLICE_BYTES) {
const sliceLength = Math.min(UPLOAD_SLICE_BYTES, value.length - offset);
await sleep((sliceLength / (UPLOAD_SIMULATED_KB_PER_SEC * 1024)) * 1000);
received += sliceLength;
if (expected > 0) {
const percentage = Math.round((received / expected) * 100);
if (percentage >= loggedPercentage + UPLOAD_PROGRESS_LOG_STEP) {
loggedPercentage = percentage;
console.log(`Upload progress: ${percentage}%`);
}
}
}
}
return new Response(new Blob(chunks as BlobPart[]), {
headers: { 'content-type': contentType }
}).formData();
}
// DeviceTypes
const enum ScheduleFlag {
SCHEDULE_SUN = 1,
@@ -4702,7 +4654,7 @@ router
// SYSTEM and SETTINGS
router
.post(EMSESP_UPLOAD_FILE_ENDPOINT, async (request: Request) => {
const formData = await readUploadSlowly(request);
const formData = await request.formData();
const uploaded = formData.get('file');
if (!uploaded || typeof uploaded === 'string') {
return status(400);
+1 -1
View File
@@ -744,7 +744,7 @@ mlongcalls
mmio
mmode
mmplus
mockSSEServer
mockServer
modbus
modee
modetype