Merge branch 'core3' of https://github.com/emsesp/EMS-ESP32 into core3

This commit is contained in:
MichaelDvP
2026-03-18 14:21:59 +01:00
15 changed files with 1361 additions and 3615 deletions

View File

@@ -63,9 +63,8 @@
"rollup-plugin-visualizer": "^7.0.1", "rollup-plugin-visualizer": "^7.0.1",
"terser": "^5.46.1", "terser": "^5.46.1",
"typescript-eslint": "^8.57.1", "typescript-eslint": "^8.57.1",
"vite": "^7.3.1", "vite": "^8.0.0",
"vite-plugin-imagemin": "^0.6.1", "vite-plugin-imagemin": "^0.6.1"
"vite-tsconfig-paths": "^6.1.1"
}, },
"packageManager": "pnpm@10.29.3+sha512.498e1fb4cca5aa06c1dcf2611e6fafc50972ffe7189998c409e90de74566444298ffe43e6cd2acdc775ba1aa7cc5e092a8b7054c811ba8c5770f84693d33d2dc" "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be"
} }

4814
interface/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -274,7 +274,6 @@ const InstallDialog = memo(
fetchDevVersion, fetchDevVersion,
latestVersion, latestVersion,
latestDevVersion, latestDevVersion,
downloadOnly,
platform, platform,
LL, LL,
onClose, onClose,
@@ -284,7 +283,6 @@ const InstallDialog = memo(
fetchDevVersion: boolean; fetchDevVersion: boolean;
latestVersion?: VersionInfo; latestVersion?: VersionInfo;
latestDevVersion?: VersionInfo; latestDevVersion?: VersionInfo;
downloadOnly: boolean;
platform: string; platform: string;
LL: TranslationFunctions; LL: TranslationFunctions;
onClose: () => void; onClose: () => void;
@@ -309,7 +307,7 @@ const InstallDialog = memo(
<DialogContent dividers> <DialogContent dividers>
<Typography mb={2}> <Typography mb={2}>
{LL.INSTALL_VERSION( {LL.INSTALL_VERSION(
downloadOnly ? LL.DOWNLOAD(1) : LL.INSTALL(), LL.INSTALL(),
fetchDevVersion ? latestDevVersion?.name : latestVersion?.name fetchDevVersion ? latestDevVersion?.name : latestVersion?.name
)} )}
</Typography> </Typography>
@@ -333,16 +331,14 @@ const InstallDialog = memo(
{LL.DOWNLOAD(0)} {LL.DOWNLOAD(0)}
</Link> </Link>
</Button> </Button>
{!downloadOnly && ( <Button
<Button startIcon={<WarningIcon color="warning" />}
startIcon={<WarningIcon color="warning" />} variant="outlined"
variant="outlined" onClick={() => onInstall(binURL)}
onClick={() => onInstall(binURL)} color="primary"
color="primary" >
> {LL.INSTALL()}
{LL.INSTALL()} </Button>
</Button>
)}
</DialogActions> </DialogActions>
</Dialog> </Dialog>
); );
@@ -423,7 +419,6 @@ const Version = () => {
const [stableUpgradeAvailable, setStableUpgradeAvailable] = const [stableUpgradeAvailable, setStableUpgradeAvailable] =
useState<boolean>(false); useState<boolean>(false);
const [internetLive, setInternetLive] = useState<boolean>(false); const [internetLive, setInternetLive] = useState<boolean>(false);
const [downloadOnly, setDownloadOnly] = useState<boolean>(false);
const [showVersionInfo, setShowVersionInfo] = useState<number>(0); // 1 = stable, 2 = dev, 3 = partition const [showVersionInfo, setShowVersionInfo] = useState<number>(0); // 1 = stable, 2 = dev, 3 = partition
const [firmwareSize, setFirmwareSize] = useState<number>(0); const [firmwareSize, setFirmwareSize] = useState<number>(0);
@@ -449,9 +444,6 @@ const Version = () => {
error error
} = useRequest(SystemApi.readSystemStatus).onSuccess((event) => { } = useRequest(SystemApi.readSystemStatus).onSuccess((event) => {
const systemData = event.data as VersionData; const systemData = event.data as VersionData;
if (systemData.arduino_version.startsWith('Tasmota')) {
setDownloadOnly(true);
}
setUsingDevVersion(systemData.emsesp_version.includes('dev')); setUsingDevVersion(systemData.emsesp_version.includes('dev'));
}); });
@@ -815,7 +807,6 @@ const Version = () => {
fetchDevVersion={fetchDevVersion} fetchDevVersion={fetchDevVersion}
latestVersion={latestVersion} latestVersion={latestVersion}
latestDevVersion={latestDevVersion} latestDevVersion={latestDevVersion}
downloadOnly={downloadOnly}
platform={platform} platform={platform}
LL={LL} LL={LL}
onClose={closeInstallDialog} onClose={closeInstallDialog}
@@ -851,7 +842,6 @@ const Version = () => {
locale, locale,
openInstallDialog, openInstallDialog,
fetchDevVersion, fetchDevVersion,
downloadOnly,
me.admin, me.admin,
showButtons, showButtons,
handleVersionInfoClose, handleVersionInfoClose,

View File

@@ -23,6 +23,8 @@ export const saveFile = (
}, 100); }, 100);
} catch (error) { } catch (error) {
console.error('Failed to save file:', error); console.error('Failed to save file:', error);
throw new Error(`Unable to save file: ${filename}${extension}`, { cause: error }); throw new Error(`Unable to save file: ${filename}${extension}`, {
cause: error
});
} }
}; };

View File

@@ -2,9 +2,8 @@ import preact from '@preact/preset-vite';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { visualizer } from 'rollup-plugin-visualizer'; import { visualizer } from 'rollup-plugin-visualizer';
import { Plugin, defineConfig } from 'vite'; import { Plugin, PluginOption, defineConfig } from 'vite';
import viteImagemin from 'vite-plugin-imagemin'; import viteImagemin from 'vite-plugin-imagemin';
import viteTsconfigPaths from 'vite-tsconfig-paths';
import zlib from 'zlib'; import zlib from 'zlib';
// @ts-expect-error - mock server doesn't have type declarations // @ts-expect-error - mock server doesn't have type declarations
@@ -99,16 +98,31 @@ const createPreactPlugin = (devToolsEnabled: boolean) =>
prefreshEnabled: false prefreshEnabled: false
}); });
// Patch preact/compat to export stub React 19 APIs (use, useOptimistic) so that
// react-router v7 doesn't trigger IMPORT_IS_UNDEFINED warnings from Rolldown.
const preactCompatPatchPlugin = (): Plugin => ({
name: 'preact-compat-react19-patch',
transform(code, id) {
if (id.includes('preact') && id.includes('compat.module.js')) {
return {
code:
code +
'\nexport var use = undefined;\nexport var useOptimistic = undefined;\n',
map: null
};
}
return undefined;
}
});
// Common base plugins // Common base plugins
const createBasePlugins = ( const createBasePlugins = (
devToolsEnabled: boolean, devToolsEnabled: boolean,
includeBundleReporter = true includeBundleReporter = true
) => { ): PluginOption[] => {
const plugins = [ const plugins: PluginOption[] = [
createPreactPlugin(devToolsEnabled), createPreactPlugin(devToolsEnabled),
viteTsconfigPaths({ preactCompatPatchPlugin()
projects: ['./tsconfig.json']
})
]; ];
if (includeBundleReporter) { if (includeBundleReporter) {
plugins.push(bundleSizeReporter()); plugins.push(bundleSizeReporter());
@@ -234,7 +248,8 @@ export default defineConfig(
plugins: [...createBasePlugins(true, true), mockServer()], plugins: [...createBasePlugins(true, true), mockServer()],
resolve: { resolve: {
alias: RESOLVE_ALIASES, alias: RESOLVE_ALIASES,
extensions: RESOLVE_EXTENSIONS extensions: RESOLVE_EXTENSIONS,
tsconfigPaths: true
}, },
server: { server: {
open: true, open: true,
@@ -263,7 +278,8 @@ export default defineConfig(
plugins: createBasePlugins(false, true), plugins: createBasePlugins(false, true),
resolve: { resolve: {
alias: RESOLVE_ALIASES, alias: RESOLVE_ALIASES,
extensions: RESOLVE_EXTENSIONS extensions: RESOLVE_EXTENSIONS,
tsconfigPaths: true
}, },
build: { build: {
...createBaseBuildConfig(), ...createBaseBuildConfig(),
@@ -297,7 +313,8 @@ export default defineConfig(
], ],
resolve: { resolve: {
alias: RESOLVE_ALIASES, alias: RESOLVE_ALIASES,
extensions: RESOLVE_EXTENSIONS extensions: RESOLVE_EXTENSIONS,
tsconfigPaths: true
}, },
build: { build: {
...createBaseBuildConfig(), ...createBaseBuildConfig(),
@@ -306,8 +323,7 @@ export default defineConfig(
rollupOptions: { rollupOptions: {
treeshake: { treeshake: {
moduleSideEffects: false, moduleSideEffects: false,
propertyReadSideEffects: false, propertyReadSideEffects: false as const,
tryCatchDeoptimization: false,
unknownGlobalSideEffects: false unknownGlobalSideEffects: false
}, },
output: { output: {

View File

@@ -12,8 +12,8 @@
"@msgpack/msgpack": "^3.1.3", "@msgpack/msgpack": "^3.1.3",
"@trivago/prettier-plugin-sort-imports": "^6.0.2", "@trivago/prettier-plugin-sort-imports": "^6.0.2",
"formidable": "^3.5.4", "formidable": "^3.5.4",
"itty-router": "^5.0.22", "itty-router": "^5.0.23",
"prettier": "^3.8.1" "prettier": "^3.8.1"
}, },
"packageManager": "pnpm@10.29.3+sha512.498e1fb4cca5aa06c1dcf2611e6fafc50972ffe7189998c409e90de74566444298ffe43e6cd2acdc775ba1aa7cc5e092a8b7054c811ba8c5770f84693d33d2dc" "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be"
} }

View File

@@ -18,8 +18,8 @@ importers:
specifier: ^3.5.4 specifier: ^3.5.4
version: 3.5.4 version: 3.5.4
itty-router: itty-router:
specifier: ^5.0.22 specifier: ^5.0.23
version: 5.0.22 version: 5.0.23
prettier: prettier:
specifier: ^3.8.1 specifier: ^3.8.1
version: 3.8.1 version: 3.8.1
@@ -46,8 +46,8 @@ packages:
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@babel/parser@7.29.0': '@babel/parser@7.29.2':
resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
@@ -131,8 +131,8 @@ packages:
resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
itty-router@5.0.22: itty-router@5.0.23:
resolution: {integrity: sha512-9hmdGErWdYDOurGYxSbqLhy4EFReIwk71hMZTJ5b+zfa2zjMNV1ftFno2b8VjAQvX615gNB8Qxbl9JMRqHnIVA==} resolution: {integrity: sha512-i49WU+SNPrwOZA4Z61En1RYd5h2Lcqa+5IvCpMrNi4dxymzJK15ozUUnRrWIUAv95Zamd4eJPAot2UvHRrQg7w==}
javascript-natural-sort@0.7.1: javascript-natural-sort@0.7.1:
resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==}
@@ -148,8 +148,8 @@ packages:
lodash-es@4.17.23: lodash-es@4.17.23:
resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==}
minimatch@9.0.5: minimatch@9.0.9:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
engines: {node: '>=16 || 14 >=14.17'} engines: {node: '>=16 || 14 >=14.17'}
ms@2.1.3: ms@2.1.3:
@@ -185,7 +185,7 @@ snapshots:
'@babel/generator@7.29.1': '@babel/generator@7.29.1':
dependencies: dependencies:
'@babel/parser': 7.29.0 '@babel/parser': 7.29.2
'@babel/types': 7.29.0 '@babel/types': 7.29.0
'@jridgewell/gen-mapping': 0.3.13 '@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31 '@jridgewell/trace-mapping': 0.3.31
@@ -197,14 +197,14 @@ snapshots:
'@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-identifier@7.28.5': {}
'@babel/parser@7.29.0': '@babel/parser@7.29.2':
dependencies: dependencies:
'@babel/types': 7.29.0 '@babel/types': 7.29.0
'@babel/template@7.28.6': '@babel/template@7.28.6':
dependencies: dependencies:
'@babel/code-frame': 7.29.0 '@babel/code-frame': 7.29.0
'@babel/parser': 7.29.0 '@babel/parser': 7.29.2
'@babel/types': 7.29.0 '@babel/types': 7.29.0
'@babel/traverse@7.29.0': '@babel/traverse@7.29.0':
@@ -212,7 +212,7 @@ snapshots:
'@babel/code-frame': 7.29.0 '@babel/code-frame': 7.29.0
'@babel/generator': 7.29.1 '@babel/generator': 7.29.1
'@babel/helper-globals': 7.28.0 '@babel/helper-globals': 7.28.0
'@babel/parser': 7.29.0 '@babel/parser': 7.29.2
'@babel/template': 7.28.6 '@babel/template': 7.28.6
'@babel/types': 7.29.0 '@babel/types': 7.29.0
debug: 4.4.3 debug: 4.4.3
@@ -249,12 +249,12 @@ snapshots:
'@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.1)': '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.1)':
dependencies: dependencies:
'@babel/generator': 7.29.1 '@babel/generator': 7.29.1
'@babel/parser': 7.29.0 '@babel/parser': 7.29.2
'@babel/traverse': 7.29.0 '@babel/traverse': 7.29.0
'@babel/types': 7.29.0 '@babel/types': 7.29.0
javascript-natural-sort: 0.7.1 javascript-natural-sort: 0.7.1
lodash-es: 4.17.23 lodash-es: 4.17.23
minimatch: 9.0.5 minimatch: 9.0.9
parse-imports-exports: 0.2.4 parse-imports-exports: 0.2.4
prettier: 3.8.1 prettier: 3.8.1
transitivePeerDependencies: transitivePeerDependencies:
@@ -283,7 +283,7 @@ snapshots:
dezalgo: 1.0.4 dezalgo: 1.0.4
once: 1.4.0 once: 1.4.0
itty-router@5.0.22: {} itty-router@5.0.23: {}
javascript-natural-sort@0.7.1: {} javascript-natural-sort@0.7.1: {}
@@ -293,7 +293,7 @@ snapshots:
lodash-es@4.17.23: {} lodash-es@4.17.23: {}
minimatch@9.0.5: minimatch@9.0.9:
dependencies: dependencies:
brace-expansion: 2.0.2 brace-expansion: 2.0.2

View File

@@ -21,8 +21,8 @@ extra_configs =
pio_local.ini pio_local.ini
[common] [common]
core_build_flags = -std=c++17 -std=gnu++17 -O3 -flto=auto -Wno-type-limits -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable -Wno-format -Wno-missing-field-initializers core_build_flags = -std=c++17 -std=gnu++17 -O3 -Wno-type-limits -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable -Wno-format -Wno-missing-field-initializers
core_unbuild_flags = -std=gnu++11 -fno-lto core_unbuild_flags = -std=gnu++11
my_build_flags = my_build_flags =
@@ -59,7 +59,7 @@ framework = arduino
board_build.partitions = partitions/esp32_partition_4M.csv board_build.partitions = partitions/esp32_partition_4M.csv
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.app_partition_name = app0 board_build.app_partition_name = app0
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.03.30/platform-espressif32.zip ; Tasmota Arduino Core 3.1.10 based on IDF 5.3.4.20260127 platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.03.30/platform-espressif32.zip ; Tasmota Arduino Core 3.1.11 based on IDF 5.3.4.20260127
; 16MB Flash variants ; 16MB Flash variants
[espressif32_base_16M] [espressif32_base_16M]
@@ -67,7 +67,7 @@ framework = arduino
board_build.partitions = partitions/esp32_partition_16M.csv board_build.partitions = partitions/esp32_partition_16M.csv
board_upload.flash_size = 16MB board_upload.flash_size = 16MB
board_build.app_partition_name = app0 board_build.app_partition_name = app0
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.03.30/platform-espressif32.zip ; Tasmota Arduino Core 3.1.10 based on IDF 5.3.4.20260127 platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.03.30/platform-espressif32.zip ; Tasmota Arduino Core 3.1.11 based on IDF 5.3.4.20260127
; 32MB Flash variants ; 32MB Flash variants
[espressif32_base_32M] [espressif32_base_32M]
@@ -75,7 +75,7 @@ framework = arduino
board_build.partitions = partitions/esp32_partition_32M.csv board_build.partitions = partitions/esp32_partition_32M.csv
board_upload.flash_size = 32MB board_upload.flash_size = 32MB
board_build.app_partition_name = app0 board_build.app_partition_name = app0
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.03.30/platform-espressif32.zip ; Tasmota Arduino Core 3.1.10 based on IDF 5.3.4.20260127 platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.03.30/platform-espressif32.zip ; Tasmota Arduino Core 3.1.11 based on IDF 5.3.4.20260127
[env] [env]
build_flags = build_flags =

View File

@@ -1324,4 +1324,8 @@ zyxwvutsrqponmlkjihgfedcba
ACAO ACAO
ACAH ACAH
ACAC ACAC
coolingtype coolingtype
starttls
recp
READYCLIENT
readymail

View File

@@ -70,9 +70,9 @@ class APSettings {
IPAddress subnetMask; IPAddress subnetMask;
bool operator==(const APSettings & settings) const { bool operator==(const APSettings & settings) const {
return provisionMode == settings.provisionMode && channel == settings.channel && ssidHidden == settings.ssidHidden return provisionMode == settings.provisionMode && channel == settings.channel && ssidHidden == settings.ssidHidden && maxClients == settings.maxClients
&& maxClients == settings.maxClients && localIP == settings.localIP && gatewayIP == settings.gatewayIP && localIP == settings.localIP && gatewayIP == settings.gatewayIP && subnetMask == settings.subnetMask && ssid == settings.ssid
&& subnetMask == settings.subnetMask && ssid == settings.ssid && password == settings.password; && password == settings.password;
} }
static void read(const APSettings & settings, JsonObject root); static void read(const APSettings & settings, JsonObject root);

View File

@@ -886,9 +886,9 @@ std::string AnalogSensor::get_metrics_prometheus() {
result += (std::string) "\n# TYPE emsesp_" + sensor.name() + " gauge\n"; result += (std::string) "\n# TYPE emsesp_" + sensor.name() + " gauge\n";
result += (std::string) "emsesp_" + sensor.name() + " "; result += (std::string) "emsesp_" + sensor.name() + " ";
if (sensor.type() != AnalogType::DIGITAL_OUT && sensor.type() != AnalogType::DIGITAL_IN) { if (sensor.type() != AnalogType::DIGITAL_OUT && sensor.type() != AnalogType::DIGITAL_IN) {
result += (std::string) Helpers::render_value(val, sensor.value(), 2) + "\n"; result += (std::string)Helpers::render_value(val, sensor.value(), 2) + "\n";
} else { } else {
result += (std::string) (sensor.value() == 0 ? "0\n" : "1\n"); result += (std::string)(sensor.value() == 0 ? "0\n" : "1\n");
} }
} }
return result; return result;

View File

@@ -20,7 +20,7 @@
#define EMSESP_HELPERS_H #define EMSESP_HELPERS_H
#include "telegram.h" // for EMS_VALUE_* settings #include "telegram.h" // for EMS_VALUE_* settings
#include "common.h" #include "emsesp_common.h"
namespace emsesp { namespace emsesp {

View File

@@ -20,6 +20,7 @@
#include "emsesp.h" // for send_raw_telegram() command #include "emsesp.h" // for send_raw_telegram() command
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
#include "esp_image_format.h"
#include "esp_ota_ops.h" #include "esp_ota_ops.h"
#include "esp_partition.h" #include "esp_partition.h"
#endif #endif
@@ -183,7 +184,7 @@ bool System::command_sendmail(const char * value, const int8_t id) {
return false; return false;
} }
// LOG_INFO("autenticate %s:%s", login.c_str(), pass.c_str()); // LOG_INFO("authenticate %s:%s", login.c_str(), pass.c_str());
smtp->authenticate(login, pass, readymail_auth_password); smtp->authenticate(login, pass, readymail_auth_password);
if (!smtp->isAuthenticated()) { if (!smtp->isAuthenticated()) {
LOG_ERROR("Sendmail authenticate error"); LOG_ERROR("Sendmail authenticate error");
@@ -210,7 +211,7 @@ bool System::command_sendmail(const char * value, const int8_t id) {
msg.headers.add(rfc822_from, sender); msg.headers.add(rfc822_from, sender);
msg.headers.add(rfc822_to, recp); msg.headers.add(rfc822_to, recp);
// Use addCustom to add custom header e.g. Imprtance and Priority. // Use addCustom to add custom header e.g. Importance and Priority.
// msg.headers.addCustom("Importance", PRIORITY); // msg.headers.addCustom("Importance", PRIORITY);
// msg.headers.addCustom("X-MSMail-Priority", PRIORITY); // msg.headers.addCustom("X-MSMail-Priority", PRIORITY);
// msg.headers.addCustom("X-Priority", PRIORITY_NUM); // msg.headers.addCustom("X-Priority", PRIORITY_NUM);
@@ -469,7 +470,13 @@ void System::get_partition_info() {
strftime(time_string, sizeof(time_string), "%FT%T", localtime(&d)); strftime(time_string, sizeof(time_string), "%FT%T", localtime(&d));
p_info.install_date = d > 1500000000L ? time_string : ""; p_info.install_date = d > 1500000000L ? time_string : "";
p_info.size = part->size / 1024; // set size in KB esp_image_metadata_t meta = {};
esp_partition_pos_t part_pos = {.offset = part->address, .size = part->size};
if (esp_image_verify(ESP_IMAGE_VERIFY_SILENT, &part_pos, &meta) == ESP_OK) {
p_info.size = meta.image_len / 1024; // actual firmware size in KB
} else {
p_info.size = 0;
}
partition_info_[part->label] = p_info; partition_info_[part->label] = p_info;
} }
@@ -493,7 +500,7 @@ void System::set_partition_install_date() {
snprintf(c, sizeof(c), "d_%s", current_partition); snprintf(c, sizeof(c), "d_%s", current_partition);
time_t d = EMSESP::nvs_.getULong(c, 0); time_t d = EMSESP::nvs_.getULong(c, 0);
if (d < 1500000000L) { if (d < 1500000000L) {
LOG_INFO("Firmware is fresh, setting the new install date in partition %s", current_partition); LOG_DEBUG("Setting the install date in partition %s", current_partition);
auto t = time(nullptr) - uuid::get_uptime_sec(); auto t = time(nullptr) - uuid::get_uptime_sec();
EMSESP::nvs_.putULong(c, t); EMSESP::nvs_.putULong(c, t);
} }
@@ -1336,7 +1343,7 @@ void System::show_system(uuid::console::Shell & shell) {
partition.first.c_str(), partition.first.c_str(),
partition.second.version.c_str(), partition.second.version.c_str(),
partition.second.size, partition.second.size,
partition.second.install_date.empty() ? "" : (std::string(", installed ") + partition.second.install_date).c_str(), partition.second.install_date.empty() ? "" : (std::string(", installed on ") + partition.second.install_date).c_str(),
(strcmp(esp_ota_get_running_partition()->label, partition.first.c_str()) == 0) ? "** active **" : ""); (strcmp(esp_ota_get_running_partition()->label, partition.first.c_str()) == 0) ? "** active **" : "");
} }

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.8.2-dev.11" #define EMSESP_APP_VERSION "3.8.2-dev.C10"