From cc2865ebdd4141fed1d2788e264d3dcaa2610b09 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 3 Sep 2026 21:20:18 +0200 Subject: [PATCH 01/20] #3216 --- .../src/components/upload/SingleUpload.tsx | 26 ++- mock-api/mockSSEServer.js | 106 +++++++++ mock-api/mockServer.js | 218 ------------------ mock-api/restServer.ts | 117 +++++++++- project-words.txt | 2 +- src/ESP32React/UploadFileService.cpp | 54 ++++- src/ESP32React/UploadFileService.h | 1 + 7 files changed, 287 insertions(+), 237 deletions(-) create mode 100644 mock-api/mockSSEServer.js delete mode 100644 mock-api/mockServer.js diff --git a/interface/src/components/upload/SingleUpload.tsx b/interface/src/components/upload/SingleUpload.tsx index 3f698b29e..134cb9918 100644 --- a/interface/src/components/upload/SingleUpload.tsx +++ b/interface/src/components/upload/SingleUpload.tsx @@ -29,11 +29,22 @@ const SingleUpload = ({ doRestart }: SingleUploadProps) => { } = useRequest(SystemApi.uploadFile, { immediate: false }).onSuccess(({ data }) => { - if (data && typeof data === 'object' && 'md5' in data) { - setMd5((data as { md5: string }).md5); - toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL()); + let payload = data; + if (typeof payload === 'string' && payload.length > 0) { + try { + payload = JSON.parse(payload); + } catch { + payload = data; + } + } + if (payload && typeof payload === 'object' && 'md5' in payload) { + setMd5((payload as { md5: string }).md5); + toast.success(LL.UPLOAD_MD5_RECEIVED()); setFile(undefined); } else { + if (payload && typeof payload === 'object' && 'md5_ok' in payload) { + toast.success(LL.UPLOAD_MD5_MATCHED()); + } doRestart(); } }); @@ -80,12 +91,17 @@ const SingleUpload = ({ doRestart }: SingleUploadProps) => { ) : ( - + )} {md5 && ( - {'MD5: ' + md5} + + {'MD5: ' + md5} + )} diff --git a/mock-api/mockSSEServer.js b/mock-api/mockSSEServer.js new file mode 100644 index 000000000..914164d8d --- /dev/null +++ b/mock-api/mockSSEServer.js @@ -0,0 +1,106 @@ +// Simulate EventSource for log messages in EMS-ESP standalone mode +// Server-Sent Events (SSE) +const ONE_SECOND_MS = 1000; + +// padding function +const pad = (number) => String(number).padStart(2, '0'); + +// Cached date formatter to avoid prototype pollution +const formatDate = (date) => { + const year = date.getUTCFullYear(); + const month = pad(date.getUTCMonth() + 1); + const day = pad(date.getUTCDate()); + const hours = pad(date.getUTCHours()); + const minutes = pad(date.getUTCMinutes()); + const seconds = pad(date.getUTCSeconds()); + const milliseconds = String((date.getUTCMilliseconds() / 1000).toFixed(3)).slice( + 2, + 5 + ); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`; +}; + +export default () => { + return { + name: 'vite:mockserver', + configureServer: async (server) => { + server.middlewares.use(async (req, res, next) => { + // Handle Server-Sent Events (SSE) for log streaming + if (req.url.startsWith('/es/log')) { + // Set SSE headers + res.writeHead(200, { + Connection: 'keep-alive', + 'Cache-Control': 'no-cache, no-transform', + 'Content-Type': 'text/event-stream', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Cache-Control', + 'X-Accel-Buffering': 'no' // disable proxy buffering (nginx, etc.) + }); + + // Flush headers early when supported + if (typeof res.flushHeaders === 'function') { + res.flushHeaders(); + } + + let messageCount = 0; + const logLevels = [3, 4, 5, 6, 7, 8]; // Different log levels + const logNames = ['system', 'ems', 'wifi', 'mqtt', 'ntp', 'api']; + + const sendLogMessage = () => { + const level = logLevels[messageCount % logLevels.length]; + const name = logNames[messageCount % logNames.length]; + let message = `Log message #${messageCount}`; + + // Add long message every 6th message + if (messageCount % 6 === 1) { + message += + ' - This is a longer message to test text wrapping and truncation behavior in the UI'; + } + + const logData = { + t: formatDate(new Date()), + l: level, + i: messageCount, + n: name, + m: message + }; + + res.write(`data: ${JSON.stringify(logData)}\n\n`); + messageCount++; + }; + + // Send initial message + res.write(`retry: 2000\n\n`); // client reconnection delay + sendLogMessage(); + + // Set up interval for periodic messages + const messageInterval = setInterval(sendLogMessage, 500); + if (typeof messageInterval.unref === 'function') messageInterval.unref(); + + // Heartbeat to keep connections alive through proxies + const heartbeat = setInterval(() => { + res.write(`:keep-alive ${Date.now()}\n\n`); + }, 15 * ONE_SECOND_MS); + if (typeof heartbeat.unref === 'function') heartbeat.unref(); + + // Clean up on connection close + const cleanup = () => { + console.log('SSE connection closed'); + clearInterval(messageInterval); + clearInterval(heartbeat); + if (!res.destroyed) { + res.end(); + } + }; + + res.on('close', cleanup); + res.on('error', cleanup); + res.on('finish', cleanup); + } else { + next(); // Continue to next middleware (Vite proxy → restServer) + } + }); + } + }; +}; diff --git a/mock-api/mockServer.js b/mock-api/mockServer.js deleted file mode 100644 index 2987ac012..000000000 --- a/mock-api/mockServer.js +++ /dev/null @@ -1,218 +0,0 @@ -// Mock server for development -// Simulates file uploads and EventSource (SSE) for log messages -import formidable from 'formidable'; - -// Constants reused across requests -const VALID_EXTENSIONS = new Set(['bin', 'json', 'md5']); -const ONE_SECOND_MS = 1000; -const TEN_PERCENT = 10; - -// padding function -const pad = (number) => String(number).padStart(2, '0'); - -// Simple throttle helper (time-based) -const throttle = (fn, intervalMs) => { - let last = 0; - return (...args) => { - const now = Date.now(); - if (now - last >= intervalMs) { - last = now; - fn(...args); - } - }; -}; - -// Cached date formatter to avoid prototype pollution -const formatDate = (date) => { - const year = date.getUTCFullYear(); - const month = pad(date.getUTCMonth() + 1); - const day = pad(date.getUTCDate()); - const hours = pad(date.getUTCHours()); - const minutes = pad(date.getUTCMinutes()); - const seconds = pad(date.getUTCSeconds()); - const milliseconds = String((date.getUTCMilliseconds() / 1000).toFixed(3)).slice( - 2, - 5 - ); - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`; -}; - -export default () => { - return { - name: 'vite:mockserver', - configureServer: async (server) => { - server.middlewares.use(async (req, res, next) => { - // Handle file uploads - if (req.url.startsWith('/rest/uploadFile')) { - // CORS preflight support - if (req.method === 'OPTIONS') { - res.writeHead(204, { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'POST, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Cache-Control', - 'Access-Control-Max-Age': '600' - }); - res.end(); - return; - } - - if (req.method !== 'POST') { - res.statusCode = 405; - res.setHeader('Allow', 'POST, OPTIONS'); - res.end('Method Not Allowed'); - return; - } - - const fileSize = parseInt(req.headers['content-length'] || '0', 10); - let progress = 0; - - // Track upload progress - const logThrottled = throttle((percentage) => { - console.log(`Upload progress: ${percentage}%`); - }, ONE_SECOND_MS); - - req.on('data', (chunk) => { - progress += chunk.length; - if (fileSize > 0) { - const percentage = Math.round((progress / fileSize) * 100); - // Only log every ~1s and for meaningful changes (>=10%) - if (percentage % TEN_PERCENT === 0) { - logThrottled(percentage); - } - } - }); - - try { - const form = formidable({ - maxFileSize: 50 * 1024 * 1024, // 50MB limit - keepExtensions: true, - multiples: false, - allowEmptyFiles: false - }); - - const [fields, files] = await form.parse(req); - - if (Object.keys(files).length === 0) { - res.statusCode = 400; - res.end('No file uploaded'); - return; - } - - const uploadedFile = Array.isArray(files.file) - ? files.file[0] - : files.file; - const fileName = uploadedFile.originalFilename; - const fileExtension = fileName - .substring(fileName.lastIndexOf('.') + 1) - .toLowerCase(); - - console.log( - `File uploaded: ${fileName} (${fileExtension}, ${fileSize} bytes)` - ); - - // Validate file extension - if (!VALID_EXTENSIONS.has(fileExtension)) { - res.statusCode = 406; - res.end('Invalid file extension'); - return; - } - - // Handle different file types - if (fileExtension === 'md5') { - res.setHeader('Content-Type', 'application/json'); - res.end( - JSON.stringify({ - md5: 'ef4304fc4d9025a58dcf25d71c882d2c' - }) - ); - } else { - console.log('File uploaded successfully!'); - res.end(); - } - } catch (err) { - console.error('Upload error:', err && err.message ? err.message : err); - res.statusCode = err.httpCode || 400; - res.setHeader('Content-Type', 'text/plain'); - res.end(err && err.message ? err.message : 'Upload error'); - } - } - - // Handle Server-Sent Events (SSE) for log streaming - else if (req.url.startsWith('/es/log')) { - // Set SSE headers - res.writeHead(200, { - Connection: 'keep-alive', - 'Cache-Control': 'no-cache, no-transform', - 'Content-Type': 'text/event-stream', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Cache-Control', - 'X-Accel-Buffering': 'no' // disable proxy buffering (nginx, etc.) - }); - - // Flush headers early when supported - if (typeof res.flushHeaders === 'function') { - res.flushHeaders(); - } - - let messageCount = 0; - const logLevels = [3, 4, 5, 6, 7, 8]; // Different log levels - const logNames = ['system', 'ems', 'wifi', 'mqtt', 'ntp', 'api']; - - const sendLogMessage = () => { - const level = logLevels[messageCount % logLevels.length]; - const name = logNames[messageCount % logNames.length]; - let message = `Log message #${messageCount}`; - - // Add long message every 6th message - if (messageCount % 6 === 1) { - message += - ' - This is a longer message to test text wrapping and truncation behavior in the UI'; - } - - const logData = { - t: formatDate(new Date()), - l: level, - i: messageCount, - n: name, - m: message - }; - - res.write(`data: ${JSON.stringify(logData)}\n\n`); - messageCount++; - }; - - // Send initial message - res.write(`retry: 2000\n\n`); // client reconnection delay - sendLogMessage(); - - // Set up interval for periodic messages - const messageInterval = setInterval(sendLogMessage, 500); - if (typeof messageInterval.unref === 'function') messageInterval.unref(); - - // Heartbeat to keep connections alive through proxies - const heartbeat = setInterval(() => { - res.write(`:keep-alive ${Date.now()}\n\n`); - }, 15 * ONE_SECOND_MS); - if (typeof heartbeat.unref === 'function') heartbeat.unref(); - - // Clean up on connection close - const cleanup = () => { - console.log('SSE connection closed'); - clearInterval(messageInterval); - clearInterval(heartbeat); - if (!res.destroyed) { - res.end(); - } - }; - - res.on('close', cleanup); - res.on('error', cleanup); - res.on('finish', cleanup); - } else { - next(); // Continue to next middleware - } - }); - } - }; -}; diff --git a/mock-api/restServer.ts b/mock-api/restServer.ts index de1fce771..a2ba1e60f 100644 --- a/mock-api/restServer.ts +++ b/mock-api/restServer.ts @@ -239,6 +239,65 @@ switch (emulate_esp) { // GLOBAL VARIABLES let countWifiScanPoll = 0; // wifi network scan 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]; + if (/^[0-9a-fA-F]{32}$/.test(token)) { + return token.toLowerCase(); + } + 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 { + 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 { @@ -434,16 +493,20 @@ function upgradeImportantMessages(version: string) { // 0 is do nothing // 1 means 3.9 and factory reset required // 2 means a major version upgrade + let upgradeImportantMessageType_n = 0; - // see if its a filename with a .bin extension - if (version.endsWith('.bin')) { - upgradeImportantMessageType_n = 1; // make it 1, for testing, meaning factory reset required - } else if (version.endsWith('.md')) { - upgradeImportantMessageType_n = 0; // use default 0, no message + // check file extensions + if (version.endsWith('.md5') || version.endsWith('.json')) { + upgradeImportantMessageType_n = 0; // digest / backup restore: no upgrade warning + } else if (version.endsWith('.bin')) { + // extract the version number from the filename and if its going from 3.8.x to 3.9.x, then set upgradeImportantMessageType_n to 1 + const versionNumber = version.split('.'); + if (versionNumber[0] === '3' && versionNumber[1] === '8') { + upgradeImportantMessageType_n = 1; // make it 1, factory reset required + } } else { // this is a version string like "3.9.0" - // upgradeImportantMessageType_n = 2; // make it 2, for testing, meaning a major version upgrade upgradeImportantMessageType_n = 1; // make it 1, for testing, meaning a factory reset is required } @@ -774,6 +837,7 @@ const EMSESP_COMMANDS_ENDPOINT = REST_ENDPOINT_ROOT + 'commands'; const EMSESP_CUSTOMENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customEntities'; const EMSESP_MODULES_ENDPOINT = REST_ENDPOINT_ROOT + 'modules'; const EMSESP_ACTION_ENDPOINT = REST_ENDPOINT_ROOT + 'action'; +const EMSESP_UPLOAD_FILE_ENDPOINT = REST_ENDPOINT_ROOT + 'uploadFile'; // these are used in the API calls only const EMSESP_SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info'; @@ -4637,6 +4701,47 @@ router // SYSTEM and SETTINGS router + .post(EMSESP_UPLOAD_FILE_ENDPOINT, async (request: Request) => { + const formData = await readUploadSlowly(request); + const uploaded = formData.get('file'); + if (!uploaded || typeof uploaded === 'string') { + return status(400); + } + + const fileName = uploaded.name || ''; + const fileExtension = fileName.includes('.') + ? fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase() + : ''; + console.log( + `File uploaded: ${fileName} (${fileExtension}, ${uploaded.size} bytes)` + ); + + if (!VALID_UPLOAD_EXTENSIONS.has(fileExtension)) { + console.log('Invalid file extension'); + return status(406); + } + + if (fileExtension === 'md5') { + const digest = parseMd5Digest(await uploaded.text()); + if (!digest) { + console.log('Invalid MD5 digest file'); + return status(406); + } + pendingFirmwareMd5 = true; + console.log('MD5 digest received', digest); + return { md5: digest }; + } + + if (fileExtension === 'bin' && pendingFirmwareMd5) { + pendingFirmwareMd5 = false; + console.log('Firmware MD5 matches'); + return { md5_ok: true }; + } + + pendingFirmwareMd5 = false; + console.log('File uploaded successfully!'); + return status(200); + }) .get(ACTIVITY_ENDPOINT, () => activity) .get(SYSTEM_STATUS_ENDPOINT, async () => { if (countHardwarePoll >= 2) { diff --git a/project-words.txt b/project-words.txt index 2aa5d4e27..3204475a4 100644 --- a/project-words.txt +++ b/project-words.txt @@ -744,7 +744,7 @@ mlongcalls mmio mmode mmplus -mockserver +mockSSEServer modbus modee modetype diff --git a/src/ESP32React/UploadFileService.cpp b/src/ESP32React/UploadFileService.cpp index 240701ef2..a10266192 100644 --- a/src/ESP32React/UploadFileService.cpp +++ b/src/ESP32React/UploadFileService.cpp @@ -13,10 +13,32 @@ static String getFilenameExtension(const String & filename) { return {}; } +// Accepts a raw 32-char hex digest, optionally with trailing newline or a GNU "hash filename" suffix. +static bool parseMd5Digest(const uint8_t * data, size_t len, std::array & out) { + size_t i = 0; + while (i < len && (data[i] == ' ' || data[i] == '\t' || data[i] == '\r' || data[i] == '\n')) { + ++i; + } + if (len - i < 32) { + return false; + } + for (size_t n = 0; n < 32; n++) { + const char c = static_cast(data[i + n]); + const bool hex = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); + if (!hex) { + return false; + } + out[n] = (c >= 'A' && c <= 'F') ? static_cast(c - 'A' + 'a') : c; + } + out[32] = '\0'; + return true; +} + UploadFileService::UploadFileService(AsyncWebServer * server, SecurityManager * securityManager) : _securityManager(securityManager) , _is_firmware(false) , _is_filesystem(false) + , _md5_applied(false) , _md5() { server->on( UPLOAD_FILE_PATH, @@ -48,18 +70,23 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri // LittleFS filesystem image _is_filesystem = true; _md5[0] = '\0'; // clear any stale md5 so Update.end() doesn't compare against it + _md5_applied = false; } else if ((extension == "bin") && (filesize > 1000000)) { _is_firmware = true; } else if (extension == "json") { - _md5[0] = '\0'; // clear md5 + _md5[0] = '\0'; // clear md5 + _md5_applied = false; } else if (extension == "md5") { - if (len == _md5.size() - 1) { - std::memcpy(_md5.data(), data, _md5.size() - 1); - _md5.back() = '\0'; + if (!parseMd5Digest(data, len, _md5)) { + emsesp::EMSESP::logger().err("Invalid MD5 digest file"); + handleError(request, 406); // Not Acceptable + } else { + emsesp::EMSESP::logger().info("MD5 digest received (%s). Now upload the firmware BIN", _md5.data()); } return; } else { _md5.front() = '\0'; + _md5_applied = false; emsesp::EMSESP::logger().err("Unsupported file type: %s, size: %u", filename.c_str(), filesize); handleError(request, 406); // Not Acceptable - unsupported file type return; @@ -103,9 +130,11 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri emsesp::EMSESP::system_.systemStatus(emsesp::SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING); if (Update.begin(filesize - sizeof(esp_image_header_t))) { + _md5_applied = false; if (strlen(_md5.data()) == _md5.size() - 1) { Update.setMD5(_md5.data()); - _md5.front() = '\0'; + _md5_applied = true; + emsesp::EMSESP::logger().info("Firmware MD5 check enabled (%s)", _md5.data()); } request->onDisconnect([this] { handleDisconnect(); }); // success, let's make sure we end the update if the client hangs up } else { @@ -183,8 +212,19 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) { emsesp::EMSESP::nvs_.putBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, true); } - AsyncWebServerResponse * response = request->beginResponse(200); - request->send(response); + if (_is_firmware && _md5_applied) { + emsesp::EMSESP::logger().info("Firmware MD5 matches"); + auto * response = new emsesp::PsramAsyncJsonResponse(false); + JsonObject root = response->getRoot(); + root["md5_ok"] = true; + response->setLength(); + request->send(response); + _md5.front() = '\0'; + _md5_applied = false; + } else { + AsyncWebServerResponse * response = request->beginResponse(200); + request->send(response); + } emsesp::EMSESP::system_.systemStatus( emsesp::SYSTEM_STATUS::SYSTEM_STATUS_PENDING_RESTART); // will be handled by the main loop. We use pending for the Web's SystemMonitor return; diff --git a/src/ESP32React/UploadFileService.h b/src/ESP32React/UploadFileService.h index 4c8a20dbb..9da611c7a 100644 --- a/src/ESP32React/UploadFileService.h +++ b/src/ESP32React/UploadFileService.h @@ -23,6 +23,7 @@ class UploadFileService { SecurityManager * _securityManager; bool _is_firmware; bool _is_filesystem; + bool _md5_applied; // true if an MD5 digest was applied to the current firmware upload std::array _md5; void handleUpload(AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t * data, size_t len, bool final); -- 2.54.0 From dc623cb32adb620e718de81a6e9bc42f380d4e8d Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:27:59 +0200 Subject: [PATCH 02/20] pkg update --- interface/package.json | 2 +- interface/pnpm-lock.yaml | 160 +++++++++++++++++++-------------------- interface/tsconfig.json | 1 + 3 files changed, 82 insertions(+), 81 deletions(-) diff --git a/interface/package.json b/interface/package.json index b728a853b..2125f07d3 100644 --- a/interface/package.json +++ b/interface/package.json @@ -44,7 +44,7 @@ "@trivago/prettier-plugin-sort-imports": "^6.0.2", "@types/node": "^26.4.1", "@types/react": "^19.2.18", - "@types/react-dom": "^19.2.5", + "@types/react-dom": "^19.2.7", "concurrently": "^10.0.5", "eslint": "^10.9.1", "eslint-config-prettier": "^10.1.8", diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index 69bf335c2..82c2ad841 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -67,8 +67,8 @@ importers: specifier: ^19.2.18 version: 19.2.18 '@types/react-dom': - specifier: ^19.2.5 - version: 19.2.5(@types/react@19.2.18) + specifier: ^19.2.7 + version: 19.2.7(@types/react@19.2.18) concurrently: specifier: ^10.0.5 version: 10.0.5 @@ -89,7 +89,7 @@ importers: version: 3.9.6 rollup-plugin-visualizer: specifier: ^7.1.1 - version: 7.1.1(rolldown@1.2.6) + version: 7.1.1(rolldown@1.2.7) terser: specifier: ^5.51.2 version: 5.51.2 @@ -454,8 +454,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@oxc-project/types@0.147.0': - resolution: {integrity: sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==} + '@oxc-project/types@0.148.0': + resolution: {integrity: sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==} '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -483,98 +483,98 @@ packages: preact: ^10.4.0 || ^11.0.0-0 vite: '>=2.0.0' - '@rolldown/binding-android-arm-eabi@1.2.6': - resolution: {integrity: sha512-b+jTcARdTiFLI6jB4a5XjTm0RWd6KcRfQj/I2356fxUZemiho9zQLxo0RtCuMDAyKcLo6cEltkgbQp6d1+sjjQ==} + '@rolldown/binding-android-arm-eabi@1.2.7': + resolution: {integrity: sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@rolldown/binding-android-arm64@1.2.6': - resolution: {integrity: sha512-lkWU8ZJaRk9q3CIEY1Tc7vIFALp3Xw5NfGJo2hQg5oIqNgxWi1zI+IiDEK3r70BF5Dzol1tcXsnzsRc8NLhG+Q==} + '@rolldown/binding-android-arm64@1.2.7': + resolution: {integrity: sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.2.6': - resolution: {integrity: sha512-dgR56NYnvAszm7Ob1B2/Vn0e8bUQYZH2UjVaMMtMVOCKFSfjhfLmuA/9+O+F+ajUdG6B/bSssrKW6JJYASa8jA==} + '@rolldown/binding-darwin-arm64@1.2.7': + resolution: {integrity: sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.6': - resolution: {integrity: sha512-vpVxFvUCFioJqug7OTvqptkc4yb8UX0AwfDmJpaR/0sWz+BUmqSVAf7c8JkUgnN8YLspb4a/N6NhTyMAmdyQ7Q==} + '@rolldown/binding-darwin-x64@1.2.7': + resolution: {integrity: sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.2.6': - resolution: {integrity: sha512-h1wG6Y6K3JlRswxsI64qQJqBAy4vrLuHgRbc8CZMGSWTOFRY6ghMApM1NKzB2I0n5xV1fjkE18SuVl2QpLeNpA==} + '@rolldown/binding-freebsd-x64@1.2.7': + resolution: {integrity: sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.2.6': - resolution: {integrity: sha512-tbCiqub0q2MVWJKgF5PoAlNWCtQydiOYSLIkd8sByqK/6MMYLJRcSXSYodqYtd0O+Fw7QaVmKKlS4oL94YRZ0w==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.7': + resolution: {integrity: sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.2.6': - resolution: {integrity: sha512-oxK9+baEBPhZG5HB4URY+uU04zJWeZlH6Tb9rB5DK4DF9XR1uXNLXt5Q5ZsugTKayNCNLhkcwz/ye74hRI98dg==} + '@rolldown/binding-linux-arm64-gnu@1.2.7': + resolution: {integrity: sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.2.6': - resolution: {integrity: sha512-muWCk27FVBEZtv0MsK8gnfSmgczA8KQ0uRVJbTABKhkRfQc38aUrcb7fhi3BNiyseFmgcRsoMfQsSNJ+DbZdSw==} + '@rolldown/binding-linux-arm64-musl@1.2.7': + resolution: {integrity: sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.2.6': - resolution: {integrity: sha512-eWDoSfU7Co2qj3vgB3Dt4lj1mG6CoWbcJQkRMP3XJplyCMtuaq3LHvPFjS9QIPvMGWVadJC04Xiy0IdcVPtnwQ==} + '@rolldown/binding-linux-ppc64-gnu@1.2.7': + resolution: {integrity: sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.6': - resolution: {integrity: sha512-2bWNjRSIayvupRKxXUY2tWG9fYdoUlTqWywHRvE8Eq3GvuQ+f2HeIkve697fIt+IQs/PV8yFsdWuhp1aJ1PdnA==} + '@rolldown/binding-linux-s390x-gnu@1.2.7': + resolution: {integrity: sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.6': - resolution: {integrity: sha512-KekI0gS0wLxe1UBSQSjenBVwou/JkcQPDzBPICGZjxUv9k3RteHDPBQaiOicZUFKRIH2wKEimGwVpnJsbPzu7w==} + '@rolldown/binding-linux-x64-gnu@1.2.7': + resolution: {integrity: sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.2.6': - resolution: {integrity: sha512-TvtPnfVr+HtyGiDmPK4VWmlNm7QhNNAcK5Q9A7aOXsI8545yCyaoMaicXrFZ72JzeYjaUVk7yT243zT0jzjFKQ==} + '@rolldown/binding-linux-x64-musl@1.2.7': + resolution: {integrity: sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.2.6': - resolution: {integrity: sha512-iOo0VEay2XFhaCcH0sps5XIimkSuOnNaZrf6+ZkoSOQBJPKNU48RkmJv0/lSpipexu5P+ouFgafe5IGr/DiQfg==} + '@rolldown/binding-openharmony-arm64@1.2.7': + resolution: {integrity: sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-win32-arm64-msvc@1.2.6': - resolution: {integrity: sha512-y5NTmmasMS455JlOCO4ZM9krIchv3Mvm1crL1iUPGOPgEzSkves9n0SdC5Sjz6+qWDFhd8/JpfWMH8NSWNHe+A==} + '@rolldown/binding-win32-arm64-msvc@1.2.7': + resolution: {integrity: sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.6': - resolution: {integrity: sha512-np8iZSLfXlAD4kWhiyq/u0Yt8oZDtRQ8lGhQaCXo2rl37KNjeU0GjJuwr4P3oeZ++ROfofsKNBqR5LTO8aXyWQ==} + '@rolldown/binding-win32-x64-msvc@1.2.7': + resolution: {integrity: sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -677,8 +677,8 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - '@types/react-dom@19.2.5': - resolution: {integrity: sha512-fMPwH9v7r/pp43yUd2/Mbiex5KouJwwR3dzHkhLREUC6764VyDsqxhAxv6OFEYR1RhjOyD1naqba8ECDBe7ZQg==} + '@types/react-dom@19.2.7': + resolution: {integrity: sha512-I8bPpDLcHBv1qiIiXDCy71Rt8eQDKJP0sMSWJphDdAcdqiJ1sGpZamavoEIRZmYzjia9LuEb2HlYdDpmoENpvQ==} peerDependencies: '@types/react': ^19.2.0 @@ -2346,8 +2346,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss@8.5.26: - resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + postcss@8.5.27: + resolution: {integrity: sha512-79Iho8QeYyooJ8e9lCRyTVlyTAkS/kXBYKff6TMzS3kEWGQ8Ds5UEtXpGrSUDLUWok6QTvxeYy0GO8fopHnaSA==} engines: {node: ^10 || ^12 || >=14} powershell-utils@0.1.0: @@ -2505,8 +2505,8 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rolldown@1.2.6: - resolution: {integrity: sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==} + rolldown@1.2.7: + resolution: {integrity: sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -3390,7 +3390,7 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.3 - '@oxc-project/types@0.147.0': {} + '@oxc-project/types@0.148.0': {} '@popperjs/core@2.11.8': {} @@ -3433,49 +3433,49 @@ snapshots: transitivePeerDependencies: - supports-color - '@rolldown/binding-android-arm-eabi@1.2.6': + '@rolldown/binding-android-arm-eabi@1.2.7': optional: true - '@rolldown/binding-android-arm64@1.2.6': + '@rolldown/binding-android-arm64@1.2.7': optional: true - '@rolldown/binding-darwin-arm64@1.2.6': + '@rolldown/binding-darwin-arm64@1.2.7': optional: true - '@rolldown/binding-darwin-x64@1.2.6': + '@rolldown/binding-darwin-x64@1.2.7': optional: true - '@rolldown/binding-freebsd-x64@1.2.6': + '@rolldown/binding-freebsd-x64@1.2.7': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.6': + '@rolldown/binding-linux-arm-gnueabihf@1.2.7': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.6': + '@rolldown/binding-linux-arm64-gnu@1.2.7': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.6': + '@rolldown/binding-linux-arm64-musl@1.2.7': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.6': + '@rolldown/binding-linux-ppc64-gnu@1.2.7': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.6': + '@rolldown/binding-linux-s390x-gnu@1.2.7': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.6': + '@rolldown/binding-linux-x64-gnu@1.2.7': optional: true - '@rolldown/binding-linux-x64-musl@1.2.6': + '@rolldown/binding-linux-x64-musl@1.2.7': optional: true - '@rolldown/binding-openharmony-arm64@1.2.6': + '@rolldown/binding-openharmony-arm64@1.2.7': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.6': + '@rolldown/binding-win32-arm64-msvc@1.2.7': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.6': + '@rolldown/binding-win32-x64-msvc@1.2.7': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -3576,7 +3576,7 @@ snapshots: '@types/prop-types@15.7.15': {} - '@types/react-dom@19.2.5(@types/react@19.2.18)': + '@types/react-dom@19.2.7(@types/react@19.2.18)': dependencies: '@types/react': 19.2.18 @@ -5289,7 +5289,7 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss@8.5.26: + postcss@8.5.27: dependencies: nanoid: 3.3.18 picocolors: 1.1.1 @@ -5432,35 +5432,35 @@ snapshots: dependencies: glob: 7.2.3 - rolldown@1.2.6: + rolldown@1.2.7: dependencies: - '@oxc-project/types': 0.147.0 + '@oxc-project/types': 0.148.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm-eabi': 1.2.6 - '@rolldown/binding-android-arm64': 1.2.6 - '@rolldown/binding-darwin-arm64': 1.2.6 - '@rolldown/binding-darwin-x64': 1.2.6 - '@rolldown/binding-freebsd-x64': 1.2.6 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.6 - '@rolldown/binding-linux-arm64-gnu': 1.2.6 - '@rolldown/binding-linux-arm64-musl': 1.2.6 - '@rolldown/binding-linux-ppc64-gnu': 1.2.6 - '@rolldown/binding-linux-s390x-gnu': 1.2.6 - '@rolldown/binding-linux-x64-gnu': 1.2.6 - '@rolldown/binding-linux-x64-musl': 1.2.6 - '@rolldown/binding-openharmony-arm64': 1.2.6 - '@rolldown/binding-win32-arm64-msvc': 1.2.6 - '@rolldown/binding-win32-x64-msvc': 1.2.6 + '@rolldown/binding-android-arm-eabi': 1.2.7 + '@rolldown/binding-android-arm64': 1.2.7 + '@rolldown/binding-darwin-arm64': 1.2.7 + '@rolldown/binding-darwin-x64': 1.2.7 + '@rolldown/binding-freebsd-x64': 1.2.7 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.7 + '@rolldown/binding-linux-arm64-gnu': 1.2.7 + '@rolldown/binding-linux-arm64-musl': 1.2.7 + '@rolldown/binding-linux-ppc64-gnu': 1.2.7 + '@rolldown/binding-linux-s390x-gnu': 1.2.7 + '@rolldown/binding-linux-x64-gnu': 1.2.7 + '@rolldown/binding-linux-x64-musl': 1.2.7 + '@rolldown/binding-openharmony-arm64': 1.2.7 + '@rolldown/binding-win32-arm64-msvc': 1.2.7 + '@rolldown/binding-win32-x64-msvc': 1.2.7 - rollup-plugin-visualizer@7.1.1(rolldown@1.2.6): + rollup-plugin-visualizer@7.1.1(rolldown@1.2.7): dependencies: open: 11.0.2 picomatch: 4.0.7 source-map: 0.8.0 yargs: 18.1.0 optionalDependencies: - rolldown: 1.2.6 + rolldown: 1.2.7 run-applescript@7.1.0: {} @@ -5818,8 +5818,8 @@ snapshots: dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 - postcss: 8.5.26 - rolldown: 1.2.6 + postcss: 8.5.27 + rolldown: 1.2.7 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 26.4.1 diff --git a/interface/tsconfig.json b/interface/tsconfig.json index f10d8a42a..4ad1c27bc 100644 --- a/interface/tsconfig.json +++ b/interface/tsconfig.json @@ -57,6 +57,7 @@ "assumeChangesOnlyAffectDirectDependencies": true, // Path mapping for cleaner imports + "ignoreDeprecations": "6.0", "baseUrl": ".", "paths": { "@/*": ["src/*"], -- 2.54.0 From 09e1ee9914b13307a77d505cfe039c199e4e2108 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:28:21 +0200 Subject: [PATCH 03/20] rename EXECUTE to RUN --- interface/src/app/status/SystemLog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/app/status/SystemLog.tsx b/interface/src/app/status/SystemLog.tsx index c88adaf61..7870d03cf 100644 --- a/interface/src/app/status/SystemLog.tsx +++ b/interface/src/app/status/SystemLog.tsx @@ -369,7 +369,7 @@ const SystemLog = () => { ) : ( <> {data.developer_mode && ( - + )} -- 2.54.0 From e43226af7efdc8cf147f6ed298223b68e8665ef5 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:28:31 +0200 Subject: [PATCH 04/20] add missing translations --- interface/src/i18n/cs/index.ts | 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, 22 insertions(+) diff --git a/interface/src/i18n/cs/index.ts b/interface/src/i18n/cs/index.ts index f44f2ab4e..6c8e67707 100644 --- a/interface/src/i18n/cs/index.ts +++ b/interface/src/i18n/cs/index.ts @@ -180,6 +180,8 @@ const cs: Translation = { 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', diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index ea4388a81..f94a3573c 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -180,6 +180,8 @@ const de: Translation = { 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', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index c1579693e..fdda0b131 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -180,6 +180,8 @@ const en: Translation = { 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', diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 42d32bba3..25953e148 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -180,6 +180,8 @@ const fr: Translation = { 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', diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 674781a89..78eb196a8 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -180,6 +180,8 @@ const it: Translation = { 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', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 9c33c29f7..2afeee95d 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -180,6 +180,8 @@ const nl: Translation = { 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', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index df3f028b8..7576d0c8b 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -180,6 +180,8 @@ const no: Translation = { 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', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 6878f2918..3f0e4ab8e 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -180,6 +180,8 @@ const pl: BaseTranslation = { 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', diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 4933a7954..d0ab4c72d 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -180,6 +180,8 @@ const sk: Translation = { 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', diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 563d0f58f..7d299d96a 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -180,6 +180,8 @@ const sv: Translation = { 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', diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 080b409d6..3525b3efd 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -180,6 +180,8 @@ const tr: Translation = { 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', -- 2.54.0 From 889ddee86edaa29d08bde4d455bd5d43fb691d36 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:30:28 +0200 Subject: [PATCH 05/20] 3.9.0-dev.8 --- src/emsesp_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 2bce065ab..be3d8d15d 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.9.0-dev.7" +#define EMSESP_APP_VERSION "3.9.0-dev.8" -- 2.54.0 From 355029ca9f1e43d51bb0658277c5a87313cfb3e2 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:30:34 +0200 Subject: [PATCH 06/20] update --- CHANGELOG_LATEST.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 89a912bdd..446c7b035 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -13,6 +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 PHY’s power draw. It’s 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) ## Fixed -- 2.54.0 From 9d3a49a0dec7f749c84d726c75210f3d58e38e1b Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:32:11 +0200 Subject: [PATCH 07/20] remove lambda check --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 01ce71667..9e1fcb0f7 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ CPPFLAGS += $(DEFINES) $(DEFAULTS) $(INCLUDE) CPPFLAGS += -ggdb -g3 -MMD CPPFLAGS += -flto=auto CPPFLAGS += -Wall -Wextra -Werror -CPPFLAGS += -Wno-unused-parameter -Wno-missing-braces -Wno-vla-cxx-extension -Wno-switch-enum -Wno-unused-lambda-capture +CPPFLAGS += -Wno-unused-parameter -Wno-missing-braces -Wno-vla-cxx-extension -Wno-switch-enum CPPFLAGS += -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-threadsafe-statics CPPFLAGS += -Os -DNDEBUG -- 2.54.0 From b4548ed25716fbbb5006984c8b2a0812793d0136 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:35:51 +0200 Subject: [PATCH 08/20] formatting --- mock-api/restServer.ts | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/mock-api/restServer.ts b/mock-api/restServer.ts index a2ba1e60f..a75f81127 100644 --- a/mock-api/restServer.ts +++ b/mock-api/restServer.ts @@ -388,10 +388,10 @@ function updateMask(entity: any, de: any, dd: any) { const old_custom_name = dd.nodes[dd_objIndex].cn; console.log( 'comparing names, old (' + - old_custom_name + - ') with new (' + - new_custom_name + - ')' + old_custom_name + + ') with new (' + + new_custom_name + + ')' ); if (old_custom_name !== new_custom_name) { changed = true; @@ -512,9 +512,9 @@ function upgradeImportantMessages(version: string) { console.log( 'upgradeImportantMessageType: version=' + - version + - ' type=' + - upgradeImportantMessageType_n + version + + ' type=' + + upgradeImportantMessageType_n ); return { upgradeImportantMessageType: upgradeImportantMessageType_n }; } @@ -565,17 +565,17 @@ function get_versions() { console.log( 'getVersions: current=' + - THIS_VERSION + - ' stable=' + - LATEST_STABLE_VERSION + - ' (upgradeable=' + - (STABLE_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO') + - ') dev=' + - LATEST_DEV_VERSION + - ' (upgradeable=' + - (DEV_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO') + - ')' + - (MOCK_OFFLINE ? ' [offline]' : '') + THIS_VERSION + + ' stable=' + + LATEST_STABLE_VERSION + + ' (upgradeable=' + + (STABLE_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO') + + ') dev=' + + LATEST_DEV_VERSION + + ' (upgradeable=' + + (DEV_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO') + + ')' + + (MOCK_OFFLINE ? ' [offline]' : '') ); return data; } -- 2.54.0 From 1b345f788d5468555181ac335cd47a04690ab4df Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 13:48:25 +0200 Subject: [PATCH 09/20] added heatblock temp translations --- src/core/locale_translations.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/locale_translations.h b/src/core/locale_translations.h index 622ec16e9..3f83da378 100644 --- a/src/core/locale_translations.h +++ b/src/core/locale_translations.h @@ -430,7 +430,7 @@ MAKE_TRANSLATION(pumpMode, "pumpmode", "boiler pump mode", "Kesselpumpenmodus", MAKE_TRANSLATION(pumpCharacter, "pumpcharacter", "boiler pump characteristic", "Charakteristik der Kesselpumpe", "karakteristiek ketelpomp", "pannpumpsegenskaper", "charakterystyka pompy kotłowej", "kjelepumpekarakteristikk", "caractéristique de la pompe de la chaudière", "kazan pompası karakteristiği", "caratteristica della pompa della caldaia", "charakteristika kotlového čerpadla", "charakteristika čerpadla kotle") MAKE_TRANSLATION(pumpOnTemp, "pumpontemp", "pump logic temperature", "Pumpenlogiktemperatur", "pomplogica temperatuur", "Pumplogiktemperatur", "temperatura logiki pompy", "pumpelogikktemperatur", "température logique pompe", "pompa mantık sıcaklığı", "temperatura logica pompa", "teplota logiky čerpadla", "teplota logiky čerpadla") MAKE_TRANSLATION(headertemp, "headertemp", "low loss header", "Hydr. Weiche", "open verdeler", "Fördelare", "sprzęgło hydrauliczne", "lav tap header", "bouteille de déc. hydr.", "isı bloğu gidiş suyu sıc.", "comp. idr.", "nízkostratová hlavica", "hydraulický oddělovač") -MAKE_TRANSLATION(heatblock, "heatblock", "Heatblok temperature", "Wärmeblocktemperatur", "Aanvoertemp. warmtecel", "Värmeblock", "blok grzewczy", "varmeblokk", "départ corps de chauffe", "Hid.denge kabı sıcaklığı", "mandata scamb. pr.", "vykurovací blok", "blok topení") +MAKE_TRANSLATION(heatblock, "heatblock", "Heatblock temperature", "Wärmeblocktemperatur", "Heatblock temperatuur", "Värmeblocktemperatur", "temperatura bloku grzewczego", "varmeblokk temperatur", "température du bloc chauffant", "ısı bloğu sıcaklığı", "temperatura blocco riscaldante", "teplota tepelného bloku", "teplota tepelného bloku") MAKE_TRANSLATION(pumpKickHour, "pumpkickhour", "pump kick hour", "Stunde Pumpkick") MAKE_TRANSLATION(pumpKickDay, "pumpkickday", "pump kick day", "Tag Pumpkick") MAKE_TRANSLATION(pumpKickDelay, "pumpkickdelay", "pump kick delay", "Pause vor Pumpkick") -- 2.54.0 From 81fa7c592ed3fac2fe59198d0ee517fe13ee904c Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 16:27:02 +0200 Subject: [PATCH 10/20] update for heating block rename --- docs/Modbus-Entity-Registers.md | 54 ++++++++++++++++----------------- docs/dump_entities.csv | 54 ++++++++++++++++----------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/docs/Modbus-Entity-Registers.md b/docs/Modbus-Entity-Registers.md index 797379c60..b130611ab 100644 --- a/docs/Modbus-Entity-Registers.md +++ b/docs/Modbus-Entity-Registers.md @@ -317,7 +317,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -477,7 +477,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -637,7 +637,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -797,7 +797,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -957,7 +957,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -1117,7 +1117,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -1277,7 +1277,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -1437,7 +1437,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -1597,7 +1597,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -1757,7 +1757,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -1917,7 +1917,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -2077,7 +2077,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -2237,7 +2237,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -2397,7 +2397,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -2557,7 +2557,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -2717,7 +2717,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -2877,7 +2877,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -3037,7 +3037,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -3197,7 +3197,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -3357,7 +3357,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -4067,7 +4067,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -4227,7 +4227,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -4387,7 +4387,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -4547,7 +4547,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -4707,7 +4707,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -4867,7 +4867,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 @@ -5155,7 +5155,7 @@ uint8 uint8 | burnminperiod | burner min period | uint8 (>=0<=120) | minutes | true | DEVICE_DATA | 262 | 1 | 1 | | absburnpow | burner current power (absolute) | uint8 | % | false | DEVICE_DATA | 263 | 1 | 1 | -| heatblock | heating block | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | +| heatblock | Heatblock temperature | uint16 | C | false | DEVICE_DATA | 264 | 1 | 1/10 | int8 | boilhyston | hysteresis on temperature | int8 (>=-20<=0) | C | true | DEVICE_DATA | 265 | 1 | 1 | int8 diff --git a/docs/dump_entities.csv b/docs/dump_entities.csv index ec42bd26c..660b7c49b 100644 --- a/docs/dump_entities.csv +++ b/docs/dump_entities.csv @@ -242,7 +242,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Greenstar 2000",boiler,11,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Greenstar 2000",boiler,11,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Greenstar 2000",boiler,11,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Greenstar 2000",boiler,11,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Greenstar 2000",boiler,11,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Greenstar 2000",boiler,11,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Greenstar 2000",boiler,11,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Greenstar 2000",boiler,11,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -362,7 +362,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "C1200W",boiler,12,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "C1200W",boiler,12,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "C1200W",boiler,12,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"C1200W",boiler,12,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"C1200W",boiler,12,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "C1200W",boiler,12,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "C1200W",boiler,12,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "C1200W",boiler,12,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -482,7 +482,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "CS5800iG",boiler,16,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "CS5800iG",boiler,16,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "CS5800iG",boiler,16,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"CS5800iG",boiler,16,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"CS5800iG",boiler,16,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "CS5800iG",boiler,16,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "CS5800iG",boiler,16,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "CS5800iG",boiler,16,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -602,7 +602,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "BK13/BK15, Smartline, GB1*2",boiler,64,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "BK13/BK15, Smartline, GB1*2",boiler,64,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "BK13/BK15, Smartline, GB1*2",boiler,64,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"BK13/BK15, Smartline, GB1*2",boiler,64,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"BK13/BK15, Smartline, GB1*2",boiler,64,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "BK13/BK15, Smartline, GB1*2",boiler,64,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "BK13/BK15, Smartline, GB1*2",boiler,64,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "BK13/BK15, Smartline, GB1*2",boiler,64,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -722,7 +722,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Logano GB1*5, Logamatic MC10",boiler,72,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Logano GB1*5, Logamatic MC10",boiler,72,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Logano GB1*5, Logamatic MC10",boiler,72,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Logano GB1*5, Logamatic MC10",boiler,72,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Logano GB1*5, Logamatic MC10",boiler,72,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Logano GB1*5, Logamatic MC10",boiler,72,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Logano GB1*5, Logamatic MC10",boiler,72,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Logano GB1*5, Logamatic MC10",boiler,72,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -842,7 +842,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Cascade CM10",boiler,81,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Cascade CM10",boiler,81,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Cascade CM10",boiler,81,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Cascade CM10",boiler,81,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Cascade CM10",boiler,81,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Cascade CM10",boiler,81,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Cascade CM10",boiler,81,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Cascade CM10",boiler,81,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -962,7 +962,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Logamax Plus GB022",boiler,84,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Logamax Plus GB022",boiler,84,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Logamax Plus GB022",boiler,84,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Logamax Plus GB022",boiler,84,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Logamax Plus GB022",boiler,84,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Logamax Plus GB022",boiler,84,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Logamax Plus GB022",boiler,84,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Logamax Plus GB022",boiler,84,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1082,7 +1082,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Condens, Logamax/Logomatic, Cerapur Top, Greenstar, Generic HT3",boiler,95,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1202,7 +1202,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Topline, GB162",boiler,115,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Topline, GB162",boiler,115,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Topline, GB162",boiler,115,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Topline, GB162",boiler,115,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Topline, GB162",boiler,115,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Topline, GB162",boiler,115,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Topline, GB162",boiler,115,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Topline, GB162",boiler,115,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1322,7 +1322,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Cascade MCM10",boiler,121,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Cascade MCM10",boiler,121,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Cascade MCM10",boiler,121,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Cascade MCM10",boiler,121,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Cascade MCM10",boiler,121,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Cascade MCM10",boiler,121,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Cascade MCM10",boiler,121,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Cascade MCM10",boiler,121,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1442,7 +1442,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Proline",boiler,122,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Proline",boiler,122,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Proline",boiler,122,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Proline",boiler,122,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Proline",boiler,122,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Proline",boiler,122,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Proline",boiler,122,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Proline",boiler,122,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1562,7 +1562,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "GB*72, Trendline, Cerapur, Greenstar Si",boiler,123,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1682,7 +1682,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "GB212",boiler,131,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "GB212",boiler,131,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "GB212",boiler,131,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"GB212",boiler,131,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"GB212",boiler,131,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "GB212",boiler,131,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "GB212",boiler,131,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "GB212",boiler,131,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1802,7 +1802,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "GC7000F",boiler,132,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "GC7000F",boiler,132,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "GC7000F",boiler,132,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"GC7000F",boiler,132,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"GC7000F",boiler,132,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "GC7000F",boiler,132,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "GC7000F",boiler,132,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "GC7000F",boiler,132,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -1922,7 +1922,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Logano GB125/KB195i, Logamatic MC110",boiler,133,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Logano GB125/KB195i, Logamatic MC110",boiler,133,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Logano GB125/KB195i, Logamatic MC110",boiler,133,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Logano GB125/KB195i, Logamatic MC110",boiler,133,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Logano GB125/KB195i, Logamatic MC110",boiler,133,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Logano GB125/KB195i, Logamatic MC110",boiler,133,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Logano GB125/KB195i, Logamatic MC110",boiler,133,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Logano GB125/KB195i, Logamatic MC110",boiler,133,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -2042,7 +2042,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Greenstar 30Ri Compact",boiler,154,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Greenstar 30Ri Compact",boiler,154,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Greenstar 30Ri Compact",boiler,154,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Greenstar 30Ri Compact",boiler,154,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Greenstar 30Ri Compact",boiler,154,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Greenstar 30Ri Compact",boiler,154,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Greenstar 30Ri Compact",boiler,154,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Greenstar 30Ri Compact",boiler,154,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -2162,7 +2162,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Suprapur-o",boiler,155,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Suprapur-o",boiler,155,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Suprapur-o",boiler,155,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Suprapur-o",boiler,155,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Suprapur-o",boiler,155,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Suprapur-o",boiler,155,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Suprapur-o",boiler,155,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Suprapur-o",boiler,155,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -2282,7 +2282,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Cerapur Aero",boiler,167,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Cerapur Aero",boiler,167,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Cerapur Aero",boiler,167,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Cerapur Aero",boiler,167,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Cerapur Aero",boiler,167,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Cerapur Aero",boiler,167,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Cerapur Aero",boiler,167,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Cerapur Aero",boiler,167,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -2402,7 +2402,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Hybrid Heatpump",boiler,168,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Hybrid Heatpump",boiler,168,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Hybrid Heatpump",boiler,168,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Hybrid Heatpump",boiler,168,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Hybrid Heatpump",boiler,168,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Hybrid Heatpump",boiler,168,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Hybrid Heatpump",boiler,168,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Hybrid Heatpump",boiler,168,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -2522,7 +2522,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Logano GB212",boiler,170,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Logano GB212",boiler,170,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Logano GB212",boiler,170,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Logano GB212",boiler,170,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Logano GB212",boiler,170,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Logano GB212",boiler,170,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Logano GB212",boiler,170,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Logano GB212",boiler,170,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -3078,7 +3078,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Condens 5000i, Greenstar 8000/GC9800IW, GB192i*2",boiler,195,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -3198,7 +3198,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Logamax U122, Cerapur",boiler,203,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Logamax U122, Cerapur",boiler,203,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Logamax U122, Cerapur",boiler,203,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Logamax U122, Cerapur",boiler,203,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Logamax U122, Cerapur",boiler,203,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Logamax U122, Cerapur",boiler,203,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Logamax U122, Cerapur",boiler,203,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Logamax U122, Cerapur",boiler,203,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -3318,7 +3318,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Ecomline Excellent",boiler,206,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Ecomline Excellent",boiler,206,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Ecomline Excellent",boiler,206,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Ecomline Excellent",boiler,206,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Ecomline Excellent",boiler,206,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Ecomline Excellent",boiler,206,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Ecomline Excellent",boiler,206,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Ecomline Excellent",boiler,206,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -3438,7 +3438,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Logamax Plus, GB192, Condens GC9000, Greenstar ErP",boiler,208,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -3558,7 +3558,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Cascade MC400",boiler,210,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Cascade MC400",boiler,210,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Cascade MC400",boiler,210,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Cascade MC400",boiler,210,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Cascade MC400",boiler,210,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Cascade MC400",boiler,210,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Cascade MC400",boiler,210,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Cascade MC400",boiler,210,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -3678,7 +3678,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "EasyControl Adapter",boiler,211,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "EasyControl Adapter",boiler,211,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "EasyControl Adapter",boiler,211,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"EasyControl Adapter",boiler,211,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"EasyControl Adapter",boiler,211,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "EasyControl Adapter",boiler,211,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "EasyControl Adapter",boiler,211,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "EasyControl Adapter",boiler,211,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 @@ -3898,7 +3898,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower,6,0,1,261,1 "Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod,6,0,1,262,1 "Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,absburnpow,burner current power (absolute),uint8,%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow,6,0,1,263,1 -"Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,heatblock,heating block,uint16,C,false,sensor.boiler_heating_block,sensor.boiler_heatblock,6,0,1/10,264,1 +"Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,heatblock,Heatblock temperature,uint16,C,false,sensor.boiler_Heatblock_temperature,sensor.boiler_heatblock,6,0,1/10,264,1 "Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston,6,0,1,265,1 "Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff,6,0,1,266,1 "Logamax Plus GB122, Condense 2300, Junkers Cerapur GC2200W",boiler,234,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston,6,0,1,267,1 -- 2.54.0 From 6291bdfa5dd3e7359ed67bae42660bfe15040d29 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 16:27:14 +0200 Subject: [PATCH 11/20] pkg update --- mock-api/package.json | 1 - mock-api/pnpm-lock.yaml | 51 ----------------------------------------- 2 files changed, 52 deletions(-) diff --git a/mock-api/package.json b/mock-api/package.json index 2ec07a076..90358d940 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -11,7 +11,6 @@ }, "dependencies": { "@msgpack/msgpack": "^3.1.3", - "formidable": "^3.5.4", "itty-router": "^5.0.24" }, "devDependencies": { diff --git a/mock-api/pnpm-lock.yaml b/mock-api/pnpm-lock.yaml index fffb7c7ae..6ef04fe6e 100644 --- a/mock-api/pnpm-lock.yaml +++ b/mock-api/pnpm-lock.yaml @@ -11,9 +11,6 @@ importers: '@msgpack/msgpack': specifier: ^3.1.3 version: 3.1.3 - formidable: - specifier: ^3.5.4 - version: 3.5.4 itty-router: specifier: ^5.0.24 version: 5.0.24 @@ -81,13 +78,6 @@ packages: resolution: {integrity: sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==} engines: {node: '>= 18'} - '@noble/hashes@1.8.0': - resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} - engines: {node: ^14.21.3 || >=16} - - '@paralleldrive/cuid2@2.3.1': - resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==} - '@trivago/prettier-plugin-sort-imports@6.0.2': resolution: {integrity: sha512-3DgfkukFyC/sE/VuYjaUUWoFfuVjPK55vOFDsxD56XXynFMCZDYFogH2l/hDfOsQAm1myoU/1xByJ3tWqtulXA==} engines: {node: '>= 20'} @@ -107,9 +97,6 @@ packages: svelte: optional: true - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -125,13 +112,6 @@ packages: supports-color: optional: true - dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - - formidable@3.5.4: - resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} - engines: {node: '>=14.0.0'} - itty-router@5.0.24: resolution: {integrity: sha512-PXij1qGKtE6jg3dLgrTRdh/Frovl5Wc4Av67sD2xfhDPrgNt4u79++/il8/c/OfZGkhD/8uYJub8tjo+H165rA==} @@ -156,9 +136,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - parse-imports-exports@0.2.4: resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} @@ -173,9 +150,6 @@ packages: engines: {node: '>=14'} hasBin: true - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - snapshots: '@babel/code-frame@7.29.7': @@ -241,12 +215,6 @@ snapshots: '@msgpack/msgpack@3.1.3': {} - '@noble/hashes@1.8.0': {} - - '@paralleldrive/cuid2@2.3.1': - dependencies: - '@noble/hashes': 1.8.0 - '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.9.6)': dependencies: '@babel/generator': 7.29.8 @@ -261,8 +229,6 @@ snapshots: transitivePeerDependencies: - supports-color - asap@2.0.6: {} - balanced-match@1.0.2: {} brace-expansion@2.1.4: @@ -273,17 +239,6 @@ snapshots: dependencies: ms: 2.1.3 - dezalgo@1.0.4: - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - - formidable@3.5.4: - dependencies: - '@paralleldrive/cuid2': 2.3.1 - dezalgo: 1.0.4 - once: 1.4.0 - itty-router@5.0.24: {} javascript-natural-sort@0.7.1: {} @@ -300,10 +255,6 @@ snapshots: ms@2.1.3: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 - parse-imports-exports@0.2.4: dependencies: parse-statements: 1.0.11 @@ -313,5 +264,3 @@ snapshots: picocolors@1.1.1: {} prettier@3.9.6: {} - - wrappy@1.0.2: {} -- 2.54.0 From 0a50a9b1fa73c88fa14641a725fa5281cbabe8da Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 4 Sep 2026 16:30:58 +0200 Subject: [PATCH 12/20] update --- CHANGELOG_LATEST.md | 2 +- interface/src/api/system.ts | 3 +- interface/src/app/settings/DownloadUpload.tsx | 6 +- interface/src/app/settings/Version.tsx | 2 +- .../src/components/upload/SingleUpload.tsx | 5 +- interface/src/i18n/cs/index.ts | 10 +- interface/src/i18n/de/index.ts | 10 +- interface/src/i18n/en/index.ts | 10 +- interface/src/i18n/fr/index.ts | 10 +- interface/src/i18n/it/index.ts | 10 +- interface/src/i18n/nl/index.ts | 10 +- interface/src/i18n/no/index.ts | 10 +- interface/src/i18n/pl/index.ts | 10 +- interface/src/i18n/sk/index.ts | 10 +- interface/src/i18n/sv/index.ts | 10 +- interface/src/i18n/tr/index.ts | 10 +- interface/vite.config.ts | 3 - mock-api/{mockSSEServer.js => mockServer.js} | 109 +++++++++++++++++- mock-api/restServer.ts | 50 +------- project-words.txt | 2 +- 20 files changed, 171 insertions(+), 121 deletions(-) rename mock-api/{mockSSEServer.js => mockServer.js} (55%) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 446c7b035..fa7e77d20 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -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 PHY’s power draw. It’s 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 diff --git a/interface/src/api/system.ts b/interface/src/api/system.ts index f12d5daa1..918929789 100644 --- a/interface/src/api/system.ts +++ b/interface/src/api/system.ts @@ -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 }); }; diff --git a/interface/src/app/settings/DownloadUpload.tsx b/interface/src/app/settings/DownloadUpload.tsx index 24bbab1e8..3f2980451 100644 --- a/interface/src/app/settings/DownloadUpload.tsx +++ b/interface/src/app/settings/DownloadUpload.tsx @@ -165,11 +165,7 @@ const DownloadUpload = () => { {LL.UPLOAD()} - - {LL.UPLOAD_TEXT()}: - - - + ); }; diff --git a/interface/src/app/settings/Version.tsx b/interface/src/app/settings/Version.tsx index 464bfd818..61a0cff22 100644 --- a/interface/src/app/settings/Version.tsx +++ b/interface/src/app/settings/Version.tsx @@ -846,7 +846,7 @@ const Version = () => { {LL.UPLOAD()} - + )} diff --git a/interface/src/components/upload/SingleUpload.tsx b/interface/src/components/upload/SingleUpload.tsx index 134cb9918..affc3c3cb 100644 --- a/interface/src/components/upload/SingleUpload.tsx +++ b/interface/src/components/upload/SingleUpload.tsx @@ -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(); const [file, setFile] = useState(); const { LL } = useI18nContext(); @@ -92,7 +93,7 @@ const SingleUpload = ({ doRestart }: SingleUploadProps) => { ) : ( )} diff --git a/interface/src/i18n/cs/index.ts b/interface/src/i18n/cs/index.ts index 6c8e67707..395a7cf77 100644 --- a/interface/src/i18n/cs/index.ts +++ b/interface/src/i18n/cs/index.ts @@ -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; diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index f94a3573c..a356c4af0 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -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; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index fdda0b131..ee4dde8b5 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -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; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 25953e148..b6245bfbe 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -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; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 78eb196a8..6a5bc8b00 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -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; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 2afeee95d..82ebaf690 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -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; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 7576d0c8b..e75c0156e 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -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; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 3f0e4ab8e..a258e5e3a 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -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; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index d0ab4c72d..9e5efbd7c 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -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; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 7d299d96a..af7351901 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -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; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 3525b3efd..c214abe47 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -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; diff --git a/interface/vite.config.ts b/interface/vite.config.ts index 65ff0d722..c87ab4e41 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -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; diff --git a/mock-api/mockSSEServer.js b/mock-api/mockServer.js similarity index 55% rename from mock-api/mockSSEServer.js rename to mock-api/mockServer.js index 914164d8d..7fba27344 100644 --- a/mock-api/mockSSEServer.js +++ b/mock-api/mockServer.js @@ -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 diff --git a/mock-api/restServer.ts b/mock-api/restServer.ts index a75f81127..ea02c45e3 100644 --- a/mock-api/restServer.ts +++ b/mock-api/restServer.ts @@ -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 { - 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); diff --git a/project-words.txt b/project-words.txt index 3204475a4..ae59838d4 100644 --- a/project-words.txt +++ b/project-words.txt @@ -744,7 +744,7 @@ mlongcalls mmio mmode mmplus -mockSSEServer +mockServer modbus modee modetype -- 2.54.0 From a6ea91439b1d18d4b5fbfe6f44d0613eecd640a5 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 5 Sep 2026 10:58:14 +0200 Subject: [PATCH 13/20] pkg update --- interface/pnpm-lock.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index 82c2ad841..81a7e0e77 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -308,8 +308,8 @@ packages: resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.7.2': - resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} + '@eslint/plugin-kit@0.7.3': + resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@humanfs/core@0.19.2': @@ -2346,8 +2346,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss@8.5.27: - resolution: {integrity: sha512-79Iho8QeYyooJ8e9lCRyTVlyTAkS/kXBYKff6TMzS3kEWGQ8Ds5UEtXpGrSUDLUWok6QTvxeYy0GO8fopHnaSA==} + postcss@8.5.28: + resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} engines: {node: ^10 || ^12 || >=14} powershell-utils@0.1.0: @@ -3246,7 +3246,7 @@ snapshots: '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.7.2': + '@eslint/plugin-kit@0.7.3': dependencies: '@eslint/core': 1.2.1 levn: 0.4.1 @@ -4303,7 +4303,7 @@ snapshots: '@eslint/config-array': 0.23.5(supports-color@10.2.2) '@eslint/config-helpers': 0.7.0 '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.2 + '@eslint/plugin-kit': 0.7.3 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -5289,7 +5289,7 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss@8.5.27: + postcss@8.5.28: dependencies: nanoid: 3.3.18 picocolors: 1.1.1 @@ -5818,7 +5818,7 @@ snapshots: dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 - postcss: 8.5.27 + postcss: 8.5.28 rolldown: 1.2.7 tinyglobby: 0.2.17 optionalDependencies: -- 2.54.0 From 928e1e7a69294684c4ec36dd1cf0b826eebb625d Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 5 Sep 2026 11:02:07 +0200 Subject: [PATCH 14/20] update --- project-words.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index ae59838d4..c805e891c 100644 --- a/project-words.txt +++ b/project-words.txt @@ -1347,4 +1347,6 @@ roomtempoffset dhcpc wifioff autonegotiation -Mbit \ No newline at end of file +Mbit +WROVER +OLIMEXPOEW \ No newline at end of file -- 2.54.0 From 204ad1f8c95daa07ec047435b0a4b029bc0187ec Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 5 Sep 2026 11:02:20 +0200 Subject: [PATCH 15/20] add psram so standalone compiles --- lib_standalone/Arduino.cpp | 1 + lib_standalone/Arduino.h | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/lib_standalone/Arduino.cpp b/lib_standalone/Arduino.cpp index cf7651354..3932cce76 100644 --- a/lib_standalone/Arduino.cpp +++ b/lib_standalone/Arduino.cpp @@ -29,6 +29,7 @@ NativeConsole Serial; +EspClass ESP; ETHClass ETH; WiFiClass WiFi; diff --git a/lib_standalone/Arduino.h b/lib_standalone/Arduino.h index e521fa40b..e1f19c0fe 100644 --- a/lib_standalone/Arduino.h +++ b/lib_standalone/Arduino.h @@ -34,6 +34,15 @@ #include "WString.h" #include "Network.h" +// stub of Arduino-ESP32's EspClass, holding only what is called outside of #ifndef EMSESP_STANDALONE +class EspClass { + public: + size_t getPsramSize() { + return 0; // standalone has no PSRAM + } +}; + +extern EspClass ESP; extern ETHClass ETH; extern WiFiClass WiFi; -- 2.54.0 From dbf54f09f503f45b170422da83e05c25e839b15e Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 5 Sep 2026 11:02:33 +0200 Subject: [PATCH 16/20] auto-formatting --- src/core/console.cpp | 57 ++++++++++++++++++++++---------------------- src/core/network.cpp | 4 ++-- src/core/system.cpp | 2 +- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/core/console.cpp b/src/core/console.cpp index d7ea0f118..0e2981649 100644 --- a/src/core/console.cpp +++ b/src/core/console.cpp @@ -295,36 +295,35 @@ static void setup_commands(std::shared_ptr const & commands) { }); - commands->add_command( - ShellContext::MAIN, - CommandFlags::ADMIN, - string_vector{F_(set), F_(board_profile)}, - {F_(name_mandatory)}, - [](Shell & shell, const std::vector & arguments) { - std::vector data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode - std::string board_profile = Helpers::toUpper(arguments.front()); - if (!EMSESP::system_.load_board_profile(data, board_profile)) { - shell.println( - "Invalid board profile (S32, E32, E32V2, E32V2_2, MH-ET, NODEMCU, LOLIN, OLIMEX, OLIMEXPOE, OLIMEXPOEW, C3MINI, S2MINI, S3MINI, S32S3, CUSTOM)"); - return; - } + commands->add_command(ShellContext::MAIN, + CommandFlags::ADMIN, + string_vector{F_(set), F_(board_profile)}, + {F_(name_mandatory)}, + [](Shell & shell, const std::vector & arguments) { + std::vector data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode + std::string board_profile = Helpers::toUpper(arguments.front()); + if (!EMSESP::system_.load_board_profile(data, board_profile)) { + shell.println("Invalid board profile (S32, E32, E32V2, E32V2_2, MH-ET, NODEMCU, LOLIN, OLIMEX, OLIMEXPOE, OLIMEXPOEW, " + "C3MINI, S2MINI, S3MINI, S32S3, CUSTOM)"); + return; + } - EMSESP::webSettingsService.update([&](WebSettings & settings) { - settings.board_profile = board_profile.c_str(); - settings.led_gpio = data[0]; - settings.dallas_gpio = data[1]; - settings.rx_gpio = data[2]; - settings.tx_gpio = data[3]; - settings.pbutton_gpio = data[4]; - settings.phy_type = data[5]; - settings.eth_power = data[6]; // can be -1 - settings.eth_phy_addr = data[7]; - settings.eth_clock_mode = data[8]; - return StateUpdateResult::CHANGED; - }); - shell.printfln("Loaded board profile %s. Restarting...", board_profile.c_str()); - EMSESP::system_.system_restart(); - }); + EMSESP::webSettingsService.update([&](WebSettings & settings) { + settings.board_profile = board_profile.c_str(); + settings.led_gpio = data[0]; + settings.dallas_gpio = data[1]; + settings.rx_gpio = data[2]; + settings.tx_gpio = data[3]; + settings.pbutton_gpio = data[4]; + settings.phy_type = data[5]; + settings.eth_power = data[6]; // can be -1 + settings.eth_phy_addr = data[7]; + settings.eth_clock_mode = data[8]; + return StateUpdateResult::CHANGED; + }); + shell.printfln("Loaded board profile %s. Restarting...", board_profile.c_str()); + EMSESP::system_.system_restart(); + }); commands->add_command( ShellContext::MAIN, diff --git a/src/core/network.cpp b/src/core/network.cpp index 0c8f6494b..b14b8ec03 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -229,8 +229,8 @@ void Network::reconnect() { // boards without an Ethernet PHY skip straight to WIFI; without a configured SSID, straight to AP // (unless AP provision mode is Never — then stay on WIFI and keep waiting) NetPhase Network::initialPhase() const { - bool eth_clock_conflicts_psram = ESP.getPsramSize() - && ((eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO16_OUT || (eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO17_OUT); + bool eth_clock_conflicts_psram = + ESP.getPsramSize() && ((eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO16_OUT || (eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO17_OUT); if (phy_type_ != PHY_type::PHY_TYPE_NONE && !eth_clock_conflicts_psram) { return NetPhase::ETHERNET; } diff --git a/src/core/system.cpp b/src/core/system.cpp index 050c62f34..c71b16561 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -2823,7 +2823,7 @@ bool System::load_board_profile(std::vector & data, const std::string & // uart0 = 1, 3; SD-card = 2, 14, 15; button = 34; valid_system_gpios_ = {4, 34, 36, 12, 13, 21, 22, 25, 26, 27, 32, 33, 39}; } else if (board_profile == "OLIMEXPOEW") { - data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, 12, 0, 1, 0}; // Olimex ESP32-POE-ISO WROVER (PSRAM) + data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, 12, 0, 1, 0}; // Olimex ESP32-POE-ISO WROVER (PSRAM) valid_system_gpios_ = {4, 34, 36, 12, 13, 21, 22, 25, 26, 27, 32, 33, 39}; } else if (board_profile == "C3MINI") { #if defined(BOARD_C3_MINI_V1) -- 2.54.0 From ff47722693d701ccb98b6f76dfddc2508f54fc8a Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 8 Sep 2026 21:08:33 +0200 Subject: [PATCH 17/20] package update --- interface/package.json | 8 +- interface/pnpm-lock.yaml | 515 +++++++++++++++++++++++++-------------- mock-api/package.json | 2 +- mock-api/pnpm-lock.yaml | 101 ++++++++ 4 files changed, 438 insertions(+), 188 deletions(-) diff --git a/interface/package.json b/interface/package.json index 2125f07d3..09b506215 100644 --- a/interface/package.json +++ b/interface/package.json @@ -42,11 +42,11 @@ "@eslint/js": "^10.0.1", "@preact/preset-vite": "^2.10.6", "@trivago/prettier-plugin-sort-imports": "^6.0.2", - "@types/node": "^26.4.1", + "@types/node": "^26.5.0", "@types/react": "^19.2.18", "@types/react-dom": "^19.2.7", "concurrently": "^10.0.5", - "eslint": "^10.9.1", + "eslint": "^10.10.0", "eslint-config-prettier": "^10.1.8", "etag": "^1.8.1", "mime-types": "^3.0.2", @@ -54,9 +54,9 @@ "rollup-plugin-visualizer": "^7.1.1", "terser": "^5.51.2", "typescript": "^6.0.3", - "typescript-eslint": "^8.69.0", + "typescript-eslint": "^8.70.0", "vite": "^8.2.2", "vite-plugin-imagemin": "^0.6.1" }, - "packageManager": "pnpm@11.25.0+sha512.5cde925b4f075f725eb71fbae18a42ffe784524789f19b61c731cb8721ec28aaee160e01a8d5af4fedb2a42cdbf300efe23db356b0d4a17b4d63e11f8ab7c956" + "packageManager": "pnpm@12.3.4+sha512.961aa41fb077da3a04a441d9f8e15ebc0c96da8ef710b2eb67bf9ee7cb0610eabd48f1fd85f51cffe73846785fa0f87c56a3a872a1d893f8446741b5cce45457" } diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index 81a7e0e77..0f5ab5aa3 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -1,3 +1,104 @@ +--- +lockfileVersion: '9.0' + +importers: + + .: + configDependencies: {} + packageManagerDependencies: + pnpm: + specifier: 12.3.4 + version: 12.3.4 + +packages: + + '@pnpm/exe.darwin-arm64@12.3.4': + resolution: {integrity: sha512-PAyUol8T1+/+ViOiXAt51ECA+QnfXCqz6foL4bW+LsoX0NcVd5XVEM2mRQu+LV4oc7uRz9zf9U0P+XFfuQeDAw==} + cpu: [arm64] + os: [darwin] + + '@pnpm/exe.darwin-x64@12.3.4': + resolution: {integrity: sha512-fxP9JCk0Cdye+ePuj+GJJLMUMTqHGWRdb1dtv4How876uQ2ehxvenpgiYAir/ceO9PsYUZkFTtyZdx+rRu5QOA==} + cpu: [x64] + os: [darwin] + + '@pnpm/exe.linux-arm64-musl@12.3.4': + resolution: {integrity: sha512-FBOt0/7ye6O6q4AllVV5QMviB6qE6fqkeczV/+MDWQsmo+QJrlfsh6X7CpH/tClVpBZEyIbjpUoT8bNhCYBxEg==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-arm64@12.3.4': + resolution: {integrity: sha512-t71AVA7LRqiKTyZ5xMYaZc2n5DfdpMbfokZuiIOXHBOM03ECnF0t4iYwaBDqJgVjlKYUOwaF/bRQajGNA4cJ4w==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-x64-musl@12.3.4': + resolution: {integrity: sha512-RPmk7Jb/aYaFvL2iyDN/AtMY+hUEsue732WmXpcuQ9tBpMnGyA5py7Z3+e+qmQaJ0zY/4ni9jJiyPBQHujmv6w==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-x64@12.3.4': + resolution: {integrity: sha512-2ZqOlSPkfwX1h5cR+FPiWf8+F+2hZT/3TvhUK5sigHqwaQCIiq8R7CGxhndKs63JtcLi2a1Qpo+wX/EoyfjyJQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.win32-arm64@12.3.4': + resolution: {integrity: sha512-ANyrHqyqco6SXBysUTRF74itDyyraea7IbFsKFdNXTjcFnfycTDx37EwuhdpPYFNSIh2JhUG4fByclsRfiHX7w==} + cpu: [arm64] + os: [win32] + + '@pnpm/exe.win32-x64@12.3.4': + resolution: {integrity: sha512-WH/KqBPY/hq2Tb7SgQltEZytimcjgKRaCRL/aM9CI0c67iKc5TVmHUhIiL3Ux9FB4bWn36i6XewUcScQI+zG8w==} + cpu: [x64] + os: [win32] + + pnpm@12.3.4: + resolution: {integrity: sha512-lhqkH7B32joEpEHZ+OFevAyW2o73ELLrZ7+e58sGEOq9SPH9hfUc/+c4RnhfoPh8VqOocqHYk/hEZ0G1zORUVw==} + engines: {node: '>=18.*'} + hasBin: true + +snapshots: + + '@pnpm/exe.darwin-arm64@12.3.4': + optional: true + + '@pnpm/exe.darwin-x64@12.3.4': + optional: true + + '@pnpm/exe.linux-arm64-musl@12.3.4': + optional: true + + '@pnpm/exe.linux-arm64@12.3.4': + optional: true + + '@pnpm/exe.linux-x64-musl@12.3.4': + optional: true + + '@pnpm/exe.linux-x64@12.3.4': + optional: true + + '@pnpm/exe.win32-arm64@12.3.4': + optional: true + + '@pnpm/exe.win32-x64@12.3.4': + optional: true + + pnpm@12.3.4: + optionalDependencies: + '@pnpm/exe.darwin-arm64': 12.3.4 + '@pnpm/exe.darwin-x64': 12.3.4 + '@pnpm/exe.linux-arm64': 12.3.4 + '@pnpm/exe.linux-arm64-musl': 12.3.4 + '@pnpm/exe.linux-x64': 12.3.4 + '@pnpm/exe.linux-x64-musl': 12.3.4 + '@pnpm/exe.win32-arm64': 12.3.4 + '@pnpm/exe.win32-x64': 12.3.4 + +--- lockfileVersion: '9.0' settings: @@ -53,16 +154,16 @@ importers: devDependencies: '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.9.1(supports-color@10.2.2)) + version: 10.0.1(eslint@10.10.0(supports-color@10.2.2)) '@preact/preset-vite': specifier: ^2.10.6 - version: 2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2)) + version: 2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2)) '@trivago/prettier-plugin-sort-imports': specifier: ^6.0.2 version: 6.0.2(prettier@3.9.6)(supports-color@10.2.2) '@types/node': - specifier: ^26.4.1 - version: 26.4.1 + specifier: ^26.5.0 + version: 26.5.0 '@types/react': specifier: ^19.2.18 version: 19.2.18 @@ -73,11 +174,11 @@ importers: specifier: ^10.0.5 version: 10.0.5 eslint: - specifier: ^10.9.1 - version: 10.9.1(supports-color@10.2.2) + specifier: ^10.10.0 + version: 10.10.0(supports-color@10.2.2) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.9.1(supports-color@10.2.2)) + version: 10.1.8(eslint@10.10.0(supports-color@10.2.2)) etag: specifier: ^1.8.1 version: 1.8.1 @@ -97,14 +198,14 @@ importers: specifier: ^6.0.3 version: 6.0.3 typescript-eslint: - specifier: ^8.69.0 - version: 8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + specifier: ^8.70.0 + version: 8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) vite: specifier: ^8.2.2 - version: 8.2.2(@types/node@26.4.1)(terser@5.51.2) + version: 8.2.2(@types/node@26.5.0)(terser@5.51.2) vite-plugin-imagemin: specifier: ^0.6.1 - version: 0.6.1(supports-color@10.2.2)(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2)) + version: 0.6.1(supports-color@10.2.2)(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2)) packages: @@ -213,6 +314,12 @@ packages: resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} + '@cacheable/memory@2.2.0': + resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} + + '@cacheable/utils@2.5.0': + resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} + '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -351,6 +458,15 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@keyv/bigmap@1.3.1': + resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} + engines: {node: '>= 18'} + peerDependencies: + keyv: ^5.6.0 + + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} + '@mui/core-downloads-tracker@9.4.0': resolution: {integrity: sha512-d+gIYM1raJP87yrVQcVg+Q3vycVMArMkgu/TjJLi2vTvO9FHKWNRR1xs9nnN4eLpM9nGxxm02UMvc9BrmcUKvQ==} @@ -655,9 +771,6 @@ packages: '@types/imagemin@7.0.1': resolution: {integrity: sha512-xEn5+M3lDBtI3JxLy6eU3ksoVurygnlG7OYhTqJfGGP4PcvYnfn+IABCmMve7ziM/SneHDm5xgJFKC8hCYPicw==} - '@types/imagemin@9.0.1': - resolution: {integrity: sha512-xMWpvrUhtYxl6EeW+UhVH3rwUKhCRx21XddcoWByjDAasXZT5pQaCn0YVnXoTijX5hlTrGqV4TGQL/Htpp00+w==} - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -668,8 +781,8 @@ packages: resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - '@types/node@26.4.1': - resolution: {integrity: sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==} + '@types/node@26.5.0': + resolution: {integrity: sha512-dVSGpriSoCgz8WnDNTuSSuSv1PC/ALXihO4ulRZt7Md8k9mlbdin3lGOcDE8SnWOgf513ByWlXd7BK4azmyg/A==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -696,63 +809,63 @@ packages: '@types/svgo@2.6.4': resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} - '@typescript-eslint/eslint-plugin@8.69.0': - resolution: {integrity: sha512-t5jQTKPIgVW1PE6dR6H6Qz5gm8zjMlX5/2gRaOGd9eO6V7J+tQc6iWKukEe7dY8u9HyYasQ0yfF0/FSSTEO2gA==} + '@typescript-eslint/eslint-plugin@8.70.0': + resolution: {integrity: sha512-/v8HZt6RlyIZxB3ntehELOcUcfxKPVGWXnQdJuHRmzrqgF8nQypcC/oxGW+Ot4VGKDq81XugPKxx0n5PBtf9PA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.69.0 + '@typescript-eslint/parser': ^8.70.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.69.0': - resolution: {integrity: sha512-l4b0DhWioGg6Gt2ebGlvfkFMOjRsauxtsnDRwUSRX1qHq3HdTfQHV8wW9zEXeciai6HfeaKOedQn2Zoofx3WBw==} + '@typescript-eslint/parser@8.70.0': + resolution: {integrity: sha512-zYvrmj9Yxd63UGaXw+kdt6A0F0s0qveJyuatIM77bYC2DE4pgmg7a50u8LR7PRtXd0x+h+Tl3eXabGm06SWd3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.69.0': - resolution: {integrity: sha512-yi4obFrHMmnsesWehHbkg9zMA7Jt8cXT+mKM08G999pH1yT6nqgsHx7MYm0uY1wAj8CqiBXYRJ7WAT0QdQHQXg==} + '@typescript-eslint/project-service@8.70.0': + resolution: {integrity: sha512-hFHbTNqhU9G+2eKFXCBVb1tjFT/LceiJ4+HfLO4pTpDI0KHi6iajpcFFkaSQ9gXmCh7n82A0PthaayEdN6mspQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.69.0': - resolution: {integrity: sha512-ewfspqWvSxKSOaplqAUNbaSFO0eB6w1EtQ+esfYFRm3614Ty4uNtExkcbgd6nWsXphbqKyf9ZYdbZdv2xEoWEQ==} + '@typescript-eslint/scope-manager@8.70.0': + resolution: {integrity: sha512-8nP3Kwh5hlgZ4FicGvmznAmJe8UL4sdU8tLukrPaMuQmDuk4Y8xYfzu/aYZW4xT2JCgc7H/TpDI5cGlxcWJSqQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.69.0': - resolution: {integrity: sha512-xNqK7YTDZsLniQMV/4rpFR8Z5JlqeRvVjuG1YgF/mdPVH84HSD19L8CczMA0qg2RfwEV231GHH3VnToJDo4MfQ==} + '@typescript-eslint/tsconfig-utils@8.70.0': + resolution: {integrity: sha512-adnkeeNq9Sq1sUf4+FRVc0KdgYghzsgFpZSQVZVvY0LCuUuN0FnQgyGzCJeC4fW1cdXseBAjU2EOqUIjbNcZUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.69.0': - resolution: {integrity: sha512-ZfoJAVg3JZndQEpEl9petVlxau3lRuElc4HRMuAlLCf8to04/iHz692RUSNmXKDjEuJmIL+KZ2/BsOcBc16dsA==} + '@typescript-eslint/type-utils@8.70.0': + resolution: {integrity: sha512-NUMKIhYVaVIVLnRL9CRt+VVcuLgSHUCpXn4/+K8wql+vdInUzvx8BjUO1oJ7cG9shjFJKtF8F8Hh2kCh3/KBVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.69.0': - resolution: {integrity: sha512-K3VrubUPhlo9VDBS6QdI8YB5j7ClpqLRdefcz6PFrhnwicehBweqQ9Evhl4l+FYz0HdDmMqIiSX0aldGRYtDCA==} + '@typescript-eslint/types@8.70.0': + resolution: {integrity: sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.69.0': - resolution: {integrity: sha512-AdFkgqck3Vudb/kWnxlyafU/4aBhHrbQ9locP2N4psXTy5mOBg0SHJumnLvx7r6g1gV4DKvUFwV2nJZBoqOD8w==} + '@typescript-eslint/typescript-estree@8.70.0': + resolution: {integrity: sha512-d9NmHMPEKQ7QCLLm1jI3zmoQBwT5KwFYjXBJ9ymZfKCUU+5rmTRykKAFvH5Qn/ZCds3CEAFS9OC9M/jkl0X2bA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.69.0': - resolution: {integrity: sha512-tUbx60BBqQa31kXF5MCsOOLL5E/WzUuxIn7YpAvq+eaUlqvk8/NXnXMBNAdLCr0icjkzem7iUA5QqWHe/hJ1aw==} + '@typescript-eslint/utils@8.70.0': + resolution: {integrity: sha512-oZmtKJz/4fufZ2p3+Cn3ijEojcdfR+1zYDH2xKYrEly0dR/Q/1xUPRCOlKGxod78nWlU2UnDe09GZ3TaknBFGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.69.0': - resolution: {integrity: sha512-+rmdgPA+EXkNgKYvHvFfhrs35utXbwaC5PGpDquSXcoXQDKUA5UjV0LmTucG/4JXkM31BTu4TilHtrN8IVBe8w==} + '@typescript-eslint/visitor-keys@8.70.0': + resolution: {integrity: sha512-BoC8PiO4Hkdo0TVJh9Ntxr5MxPDI7/oFsrygN5ADelFSeXG/qgNuucIGA+L5Z6JpPTE/uRfcTWtscjbUaufepQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -830,8 +943,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.11.8: - resolution: {integrity: sha512-zAgkquC2WYF0PIc6XbNYkA2uuxxFavzgmX61R+dHDUa558V8Ejf8ozTZFR6QzM24RWu4kBcRkhJ5kpz77j9fnQ==} + baseline-browser-mapping@2.11.21: + resolution: {integrity: sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==} engines: {node: '>=6.0.0'} hasBin: true @@ -875,8 +988,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.7: - resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} + browserslist@4.28.9: + resolution: {integrity: sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -905,6 +1018,9 @@ packages: cacheable-request@2.1.4: resolution: {integrity: sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==} + cacheable@2.5.0: + resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -929,8 +1045,8 @@ packages: resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} engines: {node: '>=0.10.0'} - caniuse-lite@1.0.30001806: - resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} + caniuse-lite@1.0.30001810: + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==} caw@2.0.1: resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==} @@ -1161,8 +1277,8 @@ packages: duplexer3@0.1.5: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} - electron-to-chromium@1.5.399: - resolution: {integrity: sha512-lEcqhErbHjXRvd41rnWLpzbyU/IXfIYo7QwaFWmxGeLiLyY2TBCdHnWY88vB+p3ubnihRypDm66panXl7TylLA==} + electron-to-chromium@1.5.422: + resolution: {integrity: sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -1347,8 +1463,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.9.1: - resolution: {integrity: sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==} + eslint@10.10.0: + resolution: {integrity: sha512-NPXn6r5zl4uET1DAVPaOwzX3rut4c0wcmw3dWJAfOsTM5+TogXo0DDjz8pwm/hL8cyVNpHqeK4JpN0NjnyFFNw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -1452,9 +1568,8 @@ packages: resolution: {integrity: sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==} engines: {node: '>=0.10.0'} - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + file-entry-cache@11.1.5: + resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==} file-type@10.11.0: resolution: {integrity: sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==} @@ -1511,9 +1626,8 @@ packages: resolution: {integrity: sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==} engines: {node: '>=6'} - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + flat-cache@6.1.23: + resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} flatted@3.4.4: resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} @@ -1596,11 +1710,6 @@ packages: engines: {node: '>=10'} hasBin: true - gifsicle@5.3.0: - resolution: {integrity: sha512-FJTpgdj1Ow/FITB7SVza5HlzXa+/lqEY0tHQazAJbuAdvyJtkH4wIdsR2K414oaTwRXHFLLF+tYbipj+OpYg+Q==} - engines: {node: '>=10'} - hasBin: true - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1657,6 +1766,10 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} + engines: {node: '>=20'} + hasown@2.0.4: resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} @@ -1668,6 +1781,12 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hookified@1.15.1: + resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} + + hookified@2.2.0: + resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==} + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -1885,9 +2004,6 @@ packages: json-buffer@3.0.0: resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -1916,8 +2032,8 @@ packages: keyv@3.0.0: resolution: {integrity: sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==} - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyv@5.6.0: + resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} @@ -2141,8 +2257,8 @@ packages: node-html-parser@6.1.13: resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} - node-releases@2.0.51: - resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} + node-releases@2.0.54: + resolution: {integrity: sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==} engines: {node: '>=18'} normalize-package-data@2.5.0: @@ -2402,6 +2518,10 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qified@0.10.1: + resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} + engines: {node: '>=20'} + query-string@5.1.1: resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} engines: {node: '>=0.10.0'} @@ -2816,8 +2936,8 @@ packages: peerDependencies: typescript: '>=3.5.1' - typescript-eslint@8.69.0: - resolution: {integrity: sha512-B3MltX0VqjUBNEe3b3sSuiRbfa6XrfHFtBiPamjT5AsW/dfq+y+bc0wyuS9DxAS1LyzCxRp2+rxzpLUvqM2BvA==} + typescript-eslint@8.70.0: + resolution: {integrity: sha512-P/W5cz70/cQAuKfY3xwQMWWTV7BvJ0mAQmi+9mBcsVPaBUpd6Ohpa+fECv9rBFrQcig86jAiNBFNWUqnTjr4pw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2831,15 +2951,15 @@ packages: unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - undici-types@8.3.0: - resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + update-browserslist-db@1.3.2: + resolution: {integrity: sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -3044,7 +3164,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.7 + browserslist: 4.28.9 lru-cache: 5.1.1 semver: 6.3.1 @@ -3131,6 +3251,18 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@cacheable/memory@2.2.0': + dependencies: + '@cacheable/utils': 2.5.0 + '@keyv/bigmap': 1.3.1(keyv@5.6.0) + hookified: 1.15.1 + keyv: 5.6.0 + + '@cacheable/utils@2.5.0': + dependencies: + hashery: 1.5.1 + keyv: 5.6.0 + '@emotion/babel-plugin@11.13.5(supports-color@10.2.2)': dependencies: '@babel/helper-module-imports': 7.29.7(supports-color@10.2.2) @@ -3217,9 +3349,9 @@ snapshots: '@esbuild/linux-loong64@0.14.54': optional: true - '@eslint-community/eslint-utils@4.10.1(eslint@10.9.1(supports-color@10.2.2))': + '@eslint-community/eslint-utils@4.10.1(eslint@10.10.0(supports-color@10.2.2))': dependencies: - eslint: 10.9.1(supports-color@10.2.2) + eslint: 10.10.0(supports-color@10.2.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -3240,9 +3372,9 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.9.1(supports-color@10.2.2))': + '@eslint/js@10.0.1(eslint@10.10.0(supports-color@10.2.2))': optionalDependencies: - eslint: 10.9.1(supports-color@10.2.2) + eslint: 10.10.0(supports-color@10.2.2) '@eslint/object-schema@3.0.5': {} @@ -3291,6 +3423,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.6.0 + '@keyv/bigmap@1.3.1(keyv@5.6.0)': + dependencies: + hashery: 1.5.1 + hookified: 1.15.1 + keyv: 5.6.0 + + '@keyv/serialize@1.1.1': {} + '@mui/core-downloads-tracker@9.4.0': {} '@mui/icons-material@9.4.0(@mui/material@9.4.0(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.18)(react@19.2.8)(supports-color@10.2.2))(@types/react@19.2.18)(react@19.2.8)(supports-color@10.2.2))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/react@19.2.18)(react@19.2.8)': @@ -3394,19 +3534,19 @@ snapshots: '@popperjs/core@2.11.8': {} - '@preact/preset-vite@2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2))': + '@preact/preset-vite@2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2))': dependencies: '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) '@babel/plugin-transform-react-jsx-development': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) - '@prefresh/vite': 2.4.12(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2)) + '@prefresh/vite': 2.4.12(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2)) '@rollup/pluginutils': 5.4.0 babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.29.7(supports-color@10.2.2)) debug: 4.4.3(supports-color@10.2.2) magic-string: 0.30.21 picocolors: 1.1.1 - vite: 8.2.2(@types/node@26.4.1)(terser@5.51.2) - vite-prerender-plugin: 0.5.13(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2)) + vite: 8.2.2(@types/node@26.5.0)(terser@5.51.2) + vite-prerender-plugin: 0.5.13(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2)) zimmerframe: 1.1.5 transitivePeerDependencies: - preact @@ -3421,7 +3561,7 @@ snapshots: '@prefresh/utils@1.2.1': {} - '@prefresh/vite@2.4.12(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2))': + '@prefresh/vite@2.4.12(preact@10.29.8)(supports-color@10.2.2)(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2))': dependencies: '@babel/core': 7.29.7(supports-color@10.2.2) '@prefresh/babel-plugin': 0.5.3 @@ -3429,7 +3569,7 @@ snapshots: '@prefresh/utils': 1.2.1 '@rollup/pluginutils': 4.2.1 preact: 10.29.8 - vite: 8.2.2(@types/node@26.4.1)(terser@5.51.2) + vite: 8.2.2(@types/node@26.5.0)(terser@5.51.2) transitivePeerDependencies: - supports-color @@ -3523,54 +3663,50 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 26.4.1 + '@types/node': 26.5.0 '@types/imagemin-gifsicle@7.0.4': dependencies: - '@types/imagemin': 9.0.1 + '@types/imagemin': 7.0.1 '@types/imagemin-jpegtran@5.0.4': dependencies: - '@types/imagemin': 9.0.1 + '@types/imagemin': 7.0.1 '@types/imagemin-mozjpeg@8.0.4': dependencies: - '@types/imagemin': 9.0.1 + '@types/imagemin': 7.0.1 '@types/imagemin-optipng@5.2.4': dependencies: - '@types/imagemin': 9.0.1 + '@types/imagemin': 7.0.1 '@types/imagemin-svgo@10.0.5': dependencies: - '@types/imagemin': 9.0.1 + '@types/imagemin': 7.0.1 '@types/svgo': 2.6.4 '@types/imagemin-webp@7.0.3': dependencies: - '@types/imagemin': 9.0.1 + '@types/imagemin': 7.0.1 '@types/imagemin@7.0.1': dependencies: - '@types/node': 26.4.1 - - '@types/imagemin@9.0.1': - dependencies: - '@types/node': 26.4.1 + '@types/node': 26.5.0 '@types/json-schema@7.0.15': {} '@types/keyv@3.1.4': dependencies: - '@types/node': 26.4.1 + '@types/node': 26.5.0 '@types/minimatch@6.0.0': dependencies: minimatch: 10.2.6 - '@types/node@26.4.1': + '@types/node@26.5.0': dependencies: - undici-types: 8.3.0 + undici-types: 8.9.0 '@types/parse-json@4.0.2': {} @@ -3590,21 +3726,21 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 26.4.1 + '@types/node': 26.5.0 '@types/svgo@2.6.4': dependencies: - '@types/node': 26.4.1 + '@types/node': 26.5.0 - '@typescript-eslint/eslint-plugin@8.69.0(@typescript-eslint/parser@8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.70.0(@typescript-eslint/parser@8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.69.0 - '@typescript-eslint/type-utils': 8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/utils': 8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.69.0 - eslint: 10.9.1(supports-color@10.2.2) + '@typescript-eslint/parser': 8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.70.0 + '@typescript-eslint/type-utils': 8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.70.0 + eslint: 10.10.0(supports-color@10.2.2) ignore: 7.0.8 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -3612,56 +3748,56 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + '@typescript-eslint/parser@8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.69.0 - '@typescript-eslint/types': 8.69.0 - '@typescript-eslint/typescript-estree': 8.69.0(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.69.0 + '@typescript-eslint/scope-manager': 8.70.0 + '@typescript-eslint/types': 8.70.0 + '@typescript-eslint/typescript-estree': 8.70.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.70.0 debug: 4.4.3(supports-color@10.2.2) - eslint: 10.9.1(supports-color@10.2.2) + eslint: 10.10.0(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.69.0(supports-color@10.2.2)(typescript@6.0.3)': + '@typescript-eslint/project-service@8.70.0(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.69.0(typescript@6.0.3) - '@typescript-eslint/types': 8.69.0 + '@typescript-eslint/tsconfig-utils': 8.70.0(typescript@6.0.3) + '@typescript-eslint/types': 8.70.0 debug: 4.4.3(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.69.0': + '@typescript-eslint/scope-manager@8.70.0': dependencies: - '@typescript-eslint/types': 8.69.0 - '@typescript-eslint/visitor-keys': 8.69.0 + '@typescript-eslint/types': 8.70.0 + '@typescript-eslint/visitor-keys': 8.70.0 - '@typescript-eslint/tsconfig-utils@8.69.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.70.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.69.0 - '@typescript-eslint/typescript-estree': 8.69.0(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/utils': 8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/types': 8.70.0 + '@typescript-eslint/typescript-estree': 8.70.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) debug: 4.4.3(supports-color@10.2.2) - eslint: 10.9.1(supports-color@10.2.2) + eslint: 10.10.0(supports-color@10.2.2) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.69.0': {} + '@typescript-eslint/types@8.70.0': {} - '@typescript-eslint/typescript-estree@8.69.0(supports-color@10.2.2)(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.70.0(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.69.0(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.69.0(typescript@6.0.3) - '@typescript-eslint/types': 8.69.0 - '@typescript-eslint/visitor-keys': 8.69.0 + '@typescript-eslint/project-service': 8.70.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.70.0(typescript@6.0.3) + '@typescript-eslint/types': 8.70.0 + '@typescript-eslint/visitor-keys': 8.70.0 debug: 4.4.3(supports-color@10.2.2) minimatch: 10.2.6 semver: 7.8.5 @@ -3671,20 +3807,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': + '@typescript-eslint/utils@8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.1(supports-color@10.2.2)) - '@typescript-eslint/scope-manager': 8.69.0 - '@typescript-eslint/types': 8.69.0 - '@typescript-eslint/typescript-estree': 8.69.0(supports-color@10.2.2)(typescript@6.0.3) - eslint: 10.9.1(supports-color@10.2.2) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.10.0(supports-color@10.2.2)) + '@typescript-eslint/scope-manager': 8.70.0 + '@typescript-eslint/types': 8.70.0 + '@typescript-eslint/typescript-estree': 8.70.0(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.10.0(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.69.0': + '@typescript-eslint/visitor-keys@8.70.0': dependencies: - '@typescript-eslint/types': 8.69.0 + '@typescript-eslint/types': 8.70.0 eslint-visitor-keys: 5.0.1 acorn-jsx@5.3.2(acorn@8.18.0): @@ -3747,7 +3883,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.11.8: {} + baseline-browser-mapping@2.11.21: {} bin-build@3.0.0: dependencies: @@ -3806,13 +3942,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.7: + browserslist@4.28.9: dependencies: - baseline-browser-mapping: 2.11.8 - caniuse-lite: 1.0.30001806 - electron-to-chromium: 1.5.399 - node-releases: 2.0.51 - update-browserslist-db: 1.2.3(browserslist@4.28.7) + baseline-browser-mapping: 2.11.21 + caniuse-lite: 1.0.30001810 + electron-to-chromium: 1.5.422 + node-releases: 2.0.54 + update-browserslist-db: 1.3.2(browserslist@4.28.9) buffer-alloc-unsafe@1.1.0: {} @@ -3846,6 +3982,14 @@ snapshots: normalize-url: 2.0.1 responselike: 1.0.2 + cacheable@2.5.0: + dependencies: + '@cacheable/memory': 2.2.0 + '@cacheable/utils': 2.5.0 + hookified: 1.15.1 + keyv: 5.6.0 + qified: 0.10.1 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -3872,7 +4016,7 @@ snapshots: camelcase@2.1.1: {} - caniuse-lite@1.0.30001806: {} + caniuse-lite@1.0.30001810: {} caw@2.0.1: dependencies: @@ -4167,7 +4311,7 @@ snapshots: duplexer3@0.1.5: {} - electron-to-chromium@1.5.399: {} + electron-to-chromium@1.5.422: {} emoji-regex@10.6.0: {} @@ -4281,9 +4425,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.9.1(supports-color@10.2.2)): + eslint-config-prettier@10.1.8(eslint@10.10.0(supports-color@10.2.2)): dependencies: - eslint: 10.9.1(supports-color@10.2.2) + eslint: 10.10.0(supports-color@10.2.2) eslint-scope@9.1.2: dependencies: @@ -4296,9 +4440,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.9.1(supports-color@10.2.2): + eslint@10.10.0(supports-color@10.2.2): dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.1(supports-color@10.2.2)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.10.0(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5(supports-color@10.2.2) '@eslint/config-helpers': 0.7.0 @@ -4318,7 +4462,7 @@ snapshots: esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 + file-entry-cache: 11.1.5 find-up: 5.0.0 glob-parent: 6.0.2 ignore: 5.3.2 @@ -4453,9 +4597,9 @@ snapshots: escape-string-regexp: 1.0.5 object-assign: 4.1.1 - file-entry-cache@8.0.0: + file-entry-cache@11.1.5: dependencies: - flat-cache: 4.0.1 + flat-cache: 6.1.23 file-type@10.11.0: {} @@ -4499,10 +4643,11 @@ snapshots: dependencies: semver-regex: 2.0.0 - flat-cache@4.0.1: + flat-cache@6.1.23: dependencies: + cacheable: 2.5.0 flatted: 3.4.4 - keyv: 4.5.4 + hookified: 1.15.1 flatted@3.4.4: {} @@ -4584,12 +4729,6 @@ snapshots: execa: 5.1.1 logalot: 2.1.0 - gifsicle@5.3.0: - dependencies: - bin-build: 3.0.0 - bin-wrapper: 4.1.0 - execa: 5.1.1 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4685,6 +4824,10 @@ snapshots: dependencies: has-symbols: 1.1.0 + hashery@1.5.1: + dependencies: + hookified: 1.15.1 + hasown@2.0.4: dependencies: function-bind: 1.1.2 @@ -4695,6 +4838,10 @@ snapshots: dependencies: react-is: 16.13.1 + hookified@1.15.1: {} + + hookified@2.2.0: {} + hosted-git-info@2.8.9: {} http-cache-semantics@3.8.1: {} @@ -4712,7 +4859,7 @@ snapshots: imagemin-gifsicle@7.0.0: dependencies: execa: 1.0.0 - gifsicle: 5.3.0 + gifsicle: 5.2.0 is-gif: 3.0.0 imagemin-jpegtran@7.0.0: @@ -4883,8 +5030,6 @@ snapshots: json-buffer@3.0.0: {} - json-buffer@3.0.1: {} - json-parse-even-better-errors@2.3.1: {} json-schema-traverse@0.4.1: {} @@ -4907,9 +5052,9 @@ snapshots: dependencies: json-buffer: 3.0.0 - keyv@4.5.4: + keyv@5.6.0: dependencies: - json-buffer: 3.0.1 + '@keyv/serialize': 1.1.1 kolorist@1.8.0: {} @@ -5103,7 +5248,7 @@ snapshots: css-select: 5.2.2 he: 1.2.0 - node-releases@2.0.51: {} + node-releases@2.0.54: {} normalize-package-data@2.5.0: dependencies: @@ -5328,6 +5473,10 @@ snapshots: punycode@2.3.1: {} + qified@0.10.1: + dependencies: + hookified: 2.2.0 + query-string@5.1.1: dependencies: decode-uri-component: 0.2.2 @@ -5724,13 +5873,13 @@ snapshots: dependencies: typescript: 6.0.3 - typescript-eslint@8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3): + typescript-eslint@8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.69.0(@typescript-eslint/parser@8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/parser': 8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.69.0(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/utils': 8.69.0(eslint@10.9.1(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - eslint: 10.9.1(supports-color@10.2.2) + '@typescript-eslint/eslint-plugin': 8.70.0(@typescript-eslint/parser@8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/parser': 8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.70.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.70.0(eslint@10.10.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.10.0(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -5742,13 +5891,13 @@ snapshots: buffer: 5.7.1 through: 2.3.8 - undici-types@8.3.0: {} + undici-types@8.9.0: {} universalify@2.0.1: {} - update-browserslist-db@1.2.3(browserslist@4.28.7): + update-browserslist-db@1.3.2(browserslist@4.28.9): dependencies: - browserslist: 4.28.7 + browserslist: 4.28.9 escalade: 3.2.0 picocolors: 1.1.1 @@ -5775,7 +5924,7 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-plugin-imagemin@0.6.1(supports-color@10.2.2)(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2)): + vite-plugin-imagemin@0.6.1(supports-color@10.2.2)(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2)): dependencies: '@types/imagemin': 7.0.1 '@types/imagemin-gifsicle': 7.0.4 @@ -5800,11 +5949,11 @@ snapshots: imagemin-webp: 6.1.0 jpegtran-bin: 6.0.1 pathe: 0.2.0 - vite: 8.2.2(@types/node@26.4.1)(terser@5.51.2) + vite: 8.2.2(@types/node@26.5.0)(terser@5.51.2) transitivePeerDependencies: - supports-color - vite-prerender-plugin@0.5.13(vite@8.2.2(@types/node@26.4.1)(terser@5.51.2)): + vite-prerender-plugin@0.5.13(vite@8.2.2(@types/node@26.5.0)(terser@5.51.2)): dependencies: kolorist: 1.8.0 magic-string: 0.30.21 @@ -5812,9 +5961,9 @@ snapshots: simple-code-frame: 1.3.0 source-map: 0.7.6 stack-trace: 1.0.0 - vite: 8.2.2(@types/node@26.4.1)(terser@5.51.2) + vite: 8.2.2(@types/node@26.5.0)(terser@5.51.2) - vite@8.2.2(@types/node@26.4.1)(terser@5.51.2): + vite@8.2.2(@types/node@26.5.0)(terser@5.51.2): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 @@ -5822,7 +5971,7 @@ snapshots: rolldown: 1.2.7 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 26.4.1 + '@types/node': 26.5.0 fsevents: 2.3.3 terser: 5.51.2 diff --git a/mock-api/package.json b/mock-api/package.json index 90358d940..48ac4a20b 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -17,5 +17,5 @@ "@trivago/prettier-plugin-sort-imports": "^6.0.2", "prettier": "^3.9.6" }, - "packageManager": "pnpm@11.25.0+sha512.5cde925b4f075f725eb71fbae18a42ffe784524789f19b61c731cb8721ec28aaee160e01a8d5af4fedb2a42cdbf300efe23db356b0d4a17b4d63e11f8ab7c956" + "packageManager": "pnpm@12.3.4+sha512.961aa41fb077da3a04a441d9f8e15ebc0c96da8ef710b2eb67bf9ee7cb0610eabd48f1fd85f51cffe73846785fa0f87c56a3a872a1d893f8446741b5cce45457" } diff --git a/mock-api/pnpm-lock.yaml b/mock-api/pnpm-lock.yaml index 6ef04fe6e..73a3545ef 100644 --- a/mock-api/pnpm-lock.yaml +++ b/mock-api/pnpm-lock.yaml @@ -1,3 +1,104 @@ +--- +lockfileVersion: '9.0' + +importers: + + .: + configDependencies: {} + packageManagerDependencies: + pnpm: + specifier: 12.3.4 + version: 12.3.4 + +packages: + + '@pnpm/exe.darwin-arm64@12.3.4': + resolution: {integrity: sha512-PAyUol8T1+/+ViOiXAt51ECA+QnfXCqz6foL4bW+LsoX0NcVd5XVEM2mRQu+LV4oc7uRz9zf9U0P+XFfuQeDAw==} + cpu: [arm64] + os: [darwin] + + '@pnpm/exe.darwin-x64@12.3.4': + resolution: {integrity: sha512-fxP9JCk0Cdye+ePuj+GJJLMUMTqHGWRdb1dtv4How876uQ2ehxvenpgiYAir/ceO9PsYUZkFTtyZdx+rRu5QOA==} + cpu: [x64] + os: [darwin] + + '@pnpm/exe.linux-arm64-musl@12.3.4': + resolution: {integrity: sha512-FBOt0/7ye6O6q4AllVV5QMviB6qE6fqkeczV/+MDWQsmo+QJrlfsh6X7CpH/tClVpBZEyIbjpUoT8bNhCYBxEg==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-arm64@12.3.4': + resolution: {integrity: sha512-t71AVA7LRqiKTyZ5xMYaZc2n5DfdpMbfokZuiIOXHBOM03ECnF0t4iYwaBDqJgVjlKYUOwaF/bRQajGNA4cJ4w==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-x64-musl@12.3.4': + resolution: {integrity: sha512-RPmk7Jb/aYaFvL2iyDN/AtMY+hUEsue732WmXpcuQ9tBpMnGyA5py7Z3+e+qmQaJ0zY/4ni9jJiyPBQHujmv6w==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-x64@12.3.4': + resolution: {integrity: sha512-2ZqOlSPkfwX1h5cR+FPiWf8+F+2hZT/3TvhUK5sigHqwaQCIiq8R7CGxhndKs63JtcLi2a1Qpo+wX/EoyfjyJQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.win32-arm64@12.3.4': + resolution: {integrity: sha512-ANyrHqyqco6SXBysUTRF74itDyyraea7IbFsKFdNXTjcFnfycTDx37EwuhdpPYFNSIh2JhUG4fByclsRfiHX7w==} + cpu: [arm64] + os: [win32] + + '@pnpm/exe.win32-x64@12.3.4': + resolution: {integrity: sha512-WH/KqBPY/hq2Tb7SgQltEZytimcjgKRaCRL/aM9CI0c67iKc5TVmHUhIiL3Ux9FB4bWn36i6XewUcScQI+zG8w==} + cpu: [x64] + os: [win32] + + pnpm@12.3.4: + resolution: {integrity: sha512-lhqkH7B32joEpEHZ+OFevAyW2o73ELLrZ7+e58sGEOq9SPH9hfUc/+c4RnhfoPh8VqOocqHYk/hEZ0G1zORUVw==} + engines: {node: '>=18.*'} + hasBin: true + +snapshots: + + '@pnpm/exe.darwin-arm64@12.3.4': + optional: true + + '@pnpm/exe.darwin-x64@12.3.4': + optional: true + + '@pnpm/exe.linux-arm64-musl@12.3.4': + optional: true + + '@pnpm/exe.linux-arm64@12.3.4': + optional: true + + '@pnpm/exe.linux-x64-musl@12.3.4': + optional: true + + '@pnpm/exe.linux-x64@12.3.4': + optional: true + + '@pnpm/exe.win32-arm64@12.3.4': + optional: true + + '@pnpm/exe.win32-x64@12.3.4': + optional: true + + pnpm@12.3.4: + optionalDependencies: + '@pnpm/exe.darwin-arm64': 12.3.4 + '@pnpm/exe.darwin-x64': 12.3.4 + '@pnpm/exe.linux-arm64': 12.3.4 + '@pnpm/exe.linux-arm64-musl': 12.3.4 + '@pnpm/exe.linux-x64': 12.3.4 + '@pnpm/exe.linux-x64-musl': 12.3.4 + '@pnpm/exe.win32-arm64': 12.3.4 + '@pnpm/exe.win32-x64': 12.3.4 + +--- lockfileVersion: '9.0' settings: -- 2.54.0 From 4dac338e2ce70479e601590381054f6ba7a11145 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 8 Sep 2026 21:08:44 +0200 Subject: [PATCH 18/20] remove comments --- src/core/emsesp.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/core/emsesp.cpp b/src/core/emsesp.cpp index 6448c3f66..f459eb8c6 100644 --- a/src/core/emsesp.cpp +++ b/src/core/emsesp.cpp @@ -1740,11 +1740,6 @@ void EMSESP::start() { bool factory_settings = false; #endif - // #if defined(EMSESP_DEBUG) - // LOG_DEBUG("Listing root directory before:"); - // system_.listDir("/", 3); // show the contents of the root directory - // #endif - // start NVS storage if (!nvs_.begin("ems-esp", false, "nvs1")) { // try bigger nvs partition on 16M flash first nvs_.begin("ems-esp", false, "nvs"); // fallback to small nvs @@ -1759,11 +1754,6 @@ void EMSESP::start() { // loads core system services settings (mqtt, ap, ntp etc) esp32React.begin(); - // #if defined(EMSESP_DEBUG) - // LOG_DEBUG("Listing root directory after:"); - // system_.listDir("/", 3); // show the contents of the root directory - // #endif - #ifndef EMSESP_STANDALONE if (factory_settings) { LOG_WARNING("No settings found on filesystem. Using factory settings."); -- 2.54.0 From 99dd04cbf5b7efa6bfb1d3d65d489274c4b2e570 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 8 Sep 2026 21:08:58 +0200 Subject: [PATCH 19/20] remove writing efuse --- src/core/system.cpp | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/core/system.cpp b/src/core/system.cpp index c71b16561..ea62f780f 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1092,6 +1092,7 @@ void System::show_system(uuid::console::Shell & shell) { shell.println(); shell.println("System:"); shell.printfln(" Version: %s", EMSESP_APP_VERSION); + shell.printfln(" System name: %s", system_name_.c_str()); #ifndef EMSESP_STANDALONE shell.printfln(" Platform: %s (%s)", EMSESP_PLATFORM, ESP.getChipModel()); shell.printfln(" Model: %s", getBBQKeesGatewayDetails().c_str()); @@ -1978,24 +1979,6 @@ bool System::command_service(const char * cmd, const char * value) { } } - int n; - if (!ok && Helpers::value2number(value, n)) { -#ifndef EMSESP_STANDALONE - if (!strcmp(cmd, "fuse/mfg")) { - ok = esp_efuse_write_reg(EFUSE_BLK3, 0, (uint32_t)n) == ESP_OK; - ok ? LOG_INFO("fuse programed with value '%X': successful", n) : LOG_ERROR("fuse programed with value '%X': failed", n); - } - if (!strcmp(cmd, "fuse/mfgadd")) { - uint8_t reg = 0; - while (esp_efuse_read_reg(EFUSE_BLK3, reg) != 0 && reg < 7) - reg++; - ok = esp_efuse_write_reg(EFUSE_BLK3, reg, (uint32_t)n) == ESP_OK; - ok ? LOG_INFO("fuse %d programed with value '%X': successful", reg, n) : LOG_ERROR("fuse %d programed with value '%X': failed", reg, n); - return true; - } -#endif - } - if (ok) { LOG_INFO("System command '%s' with value '%s'", cmd, value); } @@ -2917,7 +2900,7 @@ bool System::command_txpause(const char * value, const int8_t) { return true; } -// format command - factory reset, removing all config files +// format command - factory reset, removing all settings files bool System::command_format(const char * value, const int8_t id) { if (EMSESP::system_.disable_reset()) { LOG_NOTICE("Factory reset disabled"); @@ -2927,7 +2910,7 @@ bool System::command_format(const char * value, const int8_t id) { #if !defined(EMSESP_STANDALONE) && !defined(EMSESP_TEST) // don't really format the filesystem in test or standalone mode if (LittleFS.format()) { - LOG_INFO("Filesystem formatted successfully. All config files removed."); + LOG_INFO("Filesystem formatted successfully. All settings files removed."); } else { LOG_ERROR("Format failed"); } -- 2.54.0 From e3d9f03097dc73e6d3d4d3740af77d257a9d18af Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 8 Sep 2026 22:08:22 +0200 Subject: [PATCH 20/20] don't use Eth if not on ESP32 --- src/core/network.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/network.cpp b/src/core/network.cpp index b14b8ec03..348df4c05 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -229,11 +229,14 @@ void Network::reconnect() { // boards without an Ethernet PHY skip straight to WIFI; without a configured SSID, straight to AP // (unless AP provision mode is Never — then stay on WIFI and keep waiting) NetPhase Network::initialPhase() const { +#if CONFIG_IDF_TARGET_ESP32 + bool eth_clock_conflicts_psram = ESP.getPsramSize() && ((eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO16_OUT || (eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO17_OUT); if (phy_type_ != PHY_type::PHY_TYPE_NONE && !eth_clock_conflicts_psram) { return NetPhase::ETHERNET; } +#endif if (!ssid_.isEmpty() || ap_provisionMode_ == AP_MODE_NEVER) { return NetPhase::WIFI; } -- 2.54.0