Merge pull request #2208 from proddy/dev

Wifi Reconnect #2207
This commit is contained in:
Proddy
2024-11-16 14:57:10 +01:00
committed by GitHub
27 changed files with 1833 additions and 1778 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.26.0", "@babel/core": "^7.26.0",
"@eslint/js": "^9.14.0", "@eslint/js": "^9.15.0",
"@preact/compat": "^18.3.1", "@preact/compat": "^18.3.1",
"@preact/preset-vite": "^2.9.1", "@preact/preset-vite": "^2.9.1",
"@trivago/prettier-plugin-sort-imports": "^4.3.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0",
@@ -52,7 +52,7 @@
"@types/react-dom": "^18.3.1", "@types/react-dom": "^18.3.1",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"concurrently": "^9.1.0", "concurrently": "^9.1.0",
"eslint": "^9.14.0", "eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"formidable": "^3.5.2", "formidable": "^3.5.2",
"prettier": "^3.3.3", "prettier": "^3.3.3",

View File

@@ -310,7 +310,10 @@ const Dashboard = () => {
{me.admin && {me.admin &&
di.dv?.c && di.dv?.c &&
!hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && ( !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && (
<IconButton onClick={() => editDashboardValue(di)}> <IconButton
size="small"
onClick={() => editDashboardValue(di)}
>
<EditIcon <EditIcon
color="primary" color="primary"
sx={{ fontSize: 16 }} sx={{ fontSize: 16 }}

View File

@@ -39,7 +39,7 @@ const Help = () => {
const [customSupportHTML, setCustomSupportHTML] = useState<string | null>(null); const [customSupportHTML, setCustomSupportHTML] = useState<string | null>(null);
const [notFound, setNotFound] = useState<boolean>(false); const [notFound, setNotFound] = useState<boolean>(false);
useRequest(() => callAction({ action: 'customSupport' })).onSuccess((event) => { useRequest(() => callAction({ action: 'getCustomSupport' })).onSuccess((event) => {
if (event && event.data && Object.keys(event.data).length !== 0) { if (event && event.data && Object.keys(event.data).length !== 0) {
const data = event.data.Support; const data = event.data.Support;
if (data.img_url) { if (data.img_url) {

View File

@@ -94,6 +94,8 @@ const NetworkStatus = () => {
const networkStatus = ({ status }: NetworkStatusType) => { const networkStatus = ({ status }: NetworkStatusType) => {
switch (status) { switch (status) {
case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED:
return LL.CONNECTED(0) + ' (Ethernet)';
case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD: case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD:
return LL.INACTIVE(1); return LL.INACTIVE(1);
case NetworkConnectionStatus.WIFI_STATUS_IDLE: case NetworkConnectionStatus.WIFI_STATUS_IDLE:
@@ -101,13 +103,13 @@ const NetworkStatus = () => {
case NetworkConnectionStatus.WIFI_STATUS_NO_SSID_AVAIL: case NetworkConnectionStatus.WIFI_STATUS_NO_SSID_AVAIL:
return 'No SSID Available'; return 'No SSID Available';
case NetworkConnectionStatus.WIFI_STATUS_CONNECTED: case NetworkConnectionStatus.WIFI_STATUS_CONNECTED:
return LL.CONNECTED(0) + ' (WiFi)'; return LL.CONNECTED(0) + ' (WiFi) (' + data.reconnect_count + ')';
case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED:
return LL.CONNECTED(0) + ' (Ethernet)';
case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED: case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED:
return LL.CONNECTED(1) + ' ' + LL.FAILED(0); return (
LL.CONNECTED(1) + ' ' + LL.FAILED(0) + ' (' + data.reconnect_count + ')'
);
case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST: case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST:
return LL.CONNECTED(1) + ' ' + LL.LOST(); return LL.CONNECTED(1) + ' ' + LL.LOST() + ' (' + data.reconnect_count + ')';
case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED: case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED:
return LL.DISCONNECTED(); return LL.DISCONNECTED();
default: default:

View File

@@ -34,6 +34,7 @@ export interface NetworkStatusType {
dns_ip_1: string; dns_ip_1: string;
dns_ip_2: string; dns_ip_2: string;
hostname: string; hostname: string;
reconnect_count: number;
} }
export interface NetworkSettingsType { export interface NetworkSettingsType {

View File

@@ -678,27 +678,27 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint/config-array@npm:^0.18.0": "@eslint/config-array@npm:^0.19.0":
version: 0.18.0 version: 0.19.0
resolution: "@eslint/config-array@npm:0.18.0" resolution: "@eslint/config-array@npm:0.19.0"
dependencies: dependencies:
"@eslint/object-schema": "npm:^2.1.4" "@eslint/object-schema": "npm:^2.1.4"
debug: "npm:^4.3.1" debug: "npm:^4.3.1"
minimatch: "npm:^3.1.2" minimatch: "npm:^3.1.2"
checksum: 10c0/0234aeb3e6b052ad2402a647d0b4f8a6aa71524bafe1adad0b8db1dfe94d7f5f26d67c80f79bb37ac61361a1d4b14bb8fb475efe501de37263cf55eabb79868f checksum: 10c0/def23c6c67a8f98dc88f1b87e17a5668e5028f5ab9459661aabfe08e08f2acd557474bbaf9ba227be0921ae4db232c62773dbb7739815f8415678eb8f592dbf5
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint/core@npm:^0.7.0": "@eslint/core@npm:^0.9.0":
version: 0.7.0 version: 0.9.0
resolution: "@eslint/core@npm:0.7.0" resolution: "@eslint/core@npm:0.9.0"
checksum: 10c0/3cdee8bc6cbb96ac6103d3ead42e59830019435839583c9eb352b94ed558bd78e7ffad5286dc710df21ec1e7bd8f52aa6574c62457a4dd0f01f3736fa4a7d87a checksum: 10c0/6d8e8e0991cef12314c49425d8d2d9394f5fb1a36753ff82df7c03185a4646cb7c8736cf26638a4a714782cedf4b23cfc17667d282d3e5965b3920a0e7ce20d4
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint/eslintrc@npm:^3.1.0": "@eslint/eslintrc@npm:^3.2.0":
version: 3.1.0 version: 3.2.0
resolution: "@eslint/eslintrc@npm:3.1.0" resolution: "@eslint/eslintrc@npm:3.2.0"
dependencies: dependencies:
ajv: "npm:^6.12.4" ajv: "npm:^6.12.4"
debug: "npm:^4.3.2" debug: "npm:^4.3.2"
@@ -709,14 +709,14 @@ __metadata:
js-yaml: "npm:^4.1.0" js-yaml: "npm:^4.1.0"
minimatch: "npm:^3.1.2" minimatch: "npm:^3.1.2"
strip-json-comments: "npm:^3.1.1" strip-json-comments: "npm:^3.1.1"
checksum: 10c0/5b7332ed781edcfc98caa8dedbbb843abfb9bda2e86538529c843473f580e40c69eb894410eddc6702f487e9ee8f8cfa8df83213d43a8fdb549f23ce06699167 checksum: 10c0/43867a07ff9884d895d9855edba41acf325ef7664a8df41d957135a81a477ff4df4196f5f74dc3382627e5cc8b7ad6b815c2cea1b58f04a75aced7c43414ab8b
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint/js@npm:9.14.0, @eslint/js@npm:^9.14.0": "@eslint/js@npm:9.15.0, @eslint/js@npm:^9.15.0":
version: 9.14.0 version: 9.15.0
resolution: "@eslint/js@npm:9.14.0" resolution: "@eslint/js@npm:9.15.0"
checksum: 10c0/a423dd435e10aa3b461599aa02f6cbadd4b5128cb122467ee4e2c798e7ca4f9bb1fce4dcea003b29b983090238cf120899c1af657cf86300b399e4f996b83ddc checksum: 10c0/56552966ab1aa95332f70d0e006db5746b511c5f8b5e0c6a9b2d6764ff6d964e0b2622731877cbc4e3f0e74c5b39191290d5f48147be19175292575130d499ab
languageName: node languageName: node
linkType: hard linkType: hard
@@ -727,12 +727,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint/plugin-kit@npm:^0.2.0": "@eslint/plugin-kit@npm:^0.2.3":
version: 0.2.1 version: 0.2.3
resolution: "@eslint/plugin-kit@npm:0.2.1" resolution: "@eslint/plugin-kit@npm:0.2.3"
dependencies: dependencies:
levn: "npm:^0.4.1" levn: "npm:^0.4.1"
checksum: 10c0/34b1ecb35df97b0adeb6a43366fc1b8aa1a54d23fc9753019277e80a7295724fddb547a795fd59c9eb56d690bbf0d76d7f2286cb0f5db367a86a763d5acbde5f checksum: 10c0/89a8035976bb1780e3fa8ffe682df013bd25f7d102d991cecd3b7c297f4ce8c1a1b6805e76dd16465b5353455b670b545eff2b4ec3133e0eab81a5f9e99bd90f
languageName: node languageName: node
linkType: hard linkType: hard
@@ -767,10 +767,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@humanwhocodes/retry@npm:^0.4.0": "@humanwhocodes/retry@npm:^0.4.1":
version: 0.4.0 version: 0.4.1
resolution: "@humanwhocodes/retry@npm:0.4.0" resolution: "@humanwhocodes/retry@npm:0.4.1"
checksum: 10c0/28dcf1ed70b28ae8bc07b268c457a02f6b53fe4591b73e31f6735e7673dfd9e662f24a69e065aada1a64311bf5692d93d4ef35aba849314e8a87a870ba3b47aa checksum: 10c0/be7bb6841c4c01d0b767d9bb1ec1c9359ee61421ce8ba66c249d035c5acdfd080f32d55a5c9e859cdd7868788b8935774f65b2caf24ec0b7bd7bf333791f063b
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1663,7 +1663,7 @@ __metadata:
"@babel/core": "npm:^7.26.0" "@babel/core": "npm:^7.26.0"
"@emotion/react": "npm:^11.13.3" "@emotion/react": "npm:^11.13.3"
"@emotion/styled": "npm:^11.13.0" "@emotion/styled": "npm:^11.13.0"
"@eslint/js": "npm:^9.14.0" "@eslint/js": "npm:^9.15.0"
"@mui/icons-material": "npm:^6.1.7" "@mui/icons-material": "npm:^6.1.7"
"@mui/material": "npm:^6.1.7" "@mui/material": "npm:^6.1.7"
"@preact/compat": "npm:^18.3.1" "@preact/compat": "npm:^18.3.1"
@@ -1678,7 +1678,7 @@ __metadata:
alova: "npm:3.2.3" alova: "npm:3.2.3"
async-validator: "npm:^4.2.5" async-validator: "npm:^4.2.5"
concurrently: "npm:^9.1.0" concurrently: "npm:^9.1.0"
eslint: "npm:^9.14.0" eslint: "npm:^9.15.0"
eslint-config-prettier: "npm:^9.1.0" eslint-config-prettier: "npm:^9.1.0"
formidable: "npm:^3.5.2" formidable: "npm:^3.5.2"
jwt-decode: "npm:^4.0.0" jwt-decode: "npm:^4.0.0"
@@ -2358,7 +2358,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3":
version: 7.0.3 version: 7.0.3
resolution: "cross-spawn@npm:7.0.3" resolution: "cross-spawn@npm:7.0.3"
dependencies: dependencies:
@@ -2369,6 +2369,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cross-spawn@npm:^7.0.5":
version: 7.0.5
resolution: "cross-spawn@npm:7.0.5"
dependencies:
path-key: "npm:^3.1.0"
shebang-command: "npm:^2.0.0"
which: "npm:^2.0.1"
checksum: 10c0/aa82ce7ac0814a27e6f2b738c5a7cf1fa21a3558a1e42df449fc96541ba3ba731e4d3ecffa4435348808a86212f287c6f20a1ee551ef1ff95d01cfec5f434944
languageName: node
linkType: hard
"css-select@npm:^4.1.3": "css-select@npm:^4.1.3":
version: 4.3.0 version: 4.3.0
resolution: "css-select@npm:4.3.0" resolution: "css-select@npm:4.3.0"
@@ -3145,25 +3156,25 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint@npm:^9.14.0": "eslint@npm:^9.15.0":
version: 9.14.0 version: 9.15.0
resolution: "eslint@npm:9.14.0" resolution: "eslint@npm:9.15.0"
dependencies: dependencies:
"@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/eslint-utils": "npm:^4.2.0"
"@eslint-community/regexpp": "npm:^4.12.1" "@eslint-community/regexpp": "npm:^4.12.1"
"@eslint/config-array": "npm:^0.18.0" "@eslint/config-array": "npm:^0.19.0"
"@eslint/core": "npm:^0.7.0" "@eslint/core": "npm:^0.9.0"
"@eslint/eslintrc": "npm:^3.1.0" "@eslint/eslintrc": "npm:^3.2.0"
"@eslint/js": "npm:9.14.0" "@eslint/js": "npm:9.15.0"
"@eslint/plugin-kit": "npm:^0.2.0" "@eslint/plugin-kit": "npm:^0.2.3"
"@humanfs/node": "npm:^0.16.6" "@humanfs/node": "npm:^0.16.6"
"@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/module-importer": "npm:^1.0.1"
"@humanwhocodes/retry": "npm:^0.4.0" "@humanwhocodes/retry": "npm:^0.4.1"
"@types/estree": "npm:^1.0.6" "@types/estree": "npm:^1.0.6"
"@types/json-schema": "npm:^7.0.15" "@types/json-schema": "npm:^7.0.15"
ajv: "npm:^6.12.4" ajv: "npm:^6.12.4"
chalk: "npm:^4.0.0" chalk: "npm:^4.0.0"
cross-spawn: "npm:^7.0.2" cross-spawn: "npm:^7.0.5"
debug: "npm:^4.3.2" debug: "npm:^4.3.2"
escape-string-regexp: "npm:^4.0.0" escape-string-regexp: "npm:^4.0.0"
eslint-scope: "npm:^8.2.0" eslint-scope: "npm:^8.2.0"
@@ -3183,7 +3194,6 @@ __metadata:
minimatch: "npm:^3.1.2" minimatch: "npm:^3.1.2"
natural-compare: "npm:^1.4.0" natural-compare: "npm:^1.4.0"
optionator: "npm:^0.9.3" optionator: "npm:^0.9.3"
text-table: "npm:^0.2.0"
peerDependencies: peerDependencies:
jiti: "*" jiti: "*"
peerDependenciesMeta: peerDependenciesMeta:
@@ -3191,7 +3201,7 @@ __metadata:
optional: true optional: true
bin: bin:
eslint: bin/eslint.js eslint: bin/eslint.js
checksum: 10c0/e1cbf571b75519ad0b24c27e66a6575e57cab2671ef5296e7b345d9ac3adc1a549118dcc74a05b651a7a13a5e61ebb680be6a3e04a80e1f22eba1931921b5187 checksum: 10c0/d0d7606f36bfcccb1c3703d0a24df32067b207a616f17efe5fb1765a91d13f085afffc4fc97ecde4ab9c9f4edd64d9b4ce750e13ff7937a25074b24bee15b20f
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6636,13 +6646,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"text-table@npm:^0.2.0":
version: 0.2.0
resolution: "text-table@npm:0.2.0"
checksum: 10c0/02805740c12851ea5982686810702e2f14369a5f4c5c40a836821e3eefc65ffeec3131ba324692a37608294b0fd8c1e55a2dd571ffed4909822787668ddbee5c
languageName: node
linkType: hard
"through@npm:^2.3.8": "through@npm:^2.3.8":
version: 2.3.8 version: 2.3.8
resolution: "through@npm:2.3.8" resolution: "through@npm:2.3.8"

View File

@@ -239,11 +239,11 @@
#define ARDUINOJSON_BIN2ALPHA_1111() P #define ARDUINOJSON_BIN2ALPHA_1111() P
#define ARDUINOJSON_BIN2ALPHA_(A, B, C, D) ARDUINOJSON_BIN2ALPHA_##A##B##C##D() #define ARDUINOJSON_BIN2ALPHA_(A, B, C, D) ARDUINOJSON_BIN2ALPHA_##A##B##C##D()
#define ARDUINOJSON_BIN2ALPHA(A, B, C, D) ARDUINOJSON_BIN2ALPHA_(A, B, C, D) #define ARDUINOJSON_BIN2ALPHA(A, B, C, D) ARDUINOJSON_BIN2ALPHA_(A, B, C, D)
#define ARDUINOJSON_VERSION "7.2.0" #define ARDUINOJSON_VERSION "7.2.1"
#define ARDUINOJSON_VERSION_MAJOR 7 #define ARDUINOJSON_VERSION_MAJOR 7
#define ARDUINOJSON_VERSION_MINOR 2 #define ARDUINOJSON_VERSION_MINOR 2
#define ARDUINOJSON_VERSION_REVISION 0 #define ARDUINOJSON_VERSION_REVISION 1
#define ARDUINOJSON_VERSION_MACRO V720 #define ARDUINOJSON_VERSION_MACRO V721
#ifndef ARDUINOJSON_VERSION_NAMESPACE #ifndef ARDUINOJSON_VERSION_NAMESPACE
# define ARDUINOJSON_VERSION_NAMESPACE \ # define ARDUINOJSON_VERSION_NAMESPACE \
ARDUINOJSON_CONCAT5( \ ARDUINOJSON_CONCAT5( \
@@ -323,15 +323,15 @@ template <int Bits>
struct uint_; struct uint_;
template <> template <>
struct uint_<8> { struct uint_<8> {
typedef uint8_t type; using type = uint8_t;
}; };
template <> template <>
struct uint_<16> { struct uint_<16> {
typedef uint16_t type; using type = uint16_t;
}; };
template <> template <>
struct uint_<32> { struct uint_<32> {
typedef uint32_t type; using type = uint32_t;
}; };
template <int Bits> template <int Bits>
using uint_t = typename uint_<Bits>::type; using uint_t = typename uint_<Bits>::type;
@@ -417,11 +417,11 @@ class MemoryPool {
}; };
template <bool Condition, class TrueType, class FalseType> template <bool Condition, class TrueType, class FalseType>
struct conditional { struct conditional {
typedef TrueType type; using type = TrueType;
}; };
template <class TrueType, class FalseType> template <class TrueType, class FalseType>
struct conditional<false, TrueType, FalseType> { struct conditional<false, TrueType, FalseType> {
typedef FalseType type; using type = FalseType;
}; };
template <bool Condition, class TrueType, class FalseType> template <bool Condition, class TrueType, class FalseType>
using conditional_t = using conditional_t =
@@ -430,7 +430,7 @@ template <bool Condition, typename T = void>
struct enable_if {}; struct enable_if {};
template <typename T> template <typename T>
struct enable_if<true, T> { struct enable_if<true, T> {
typedef T type; using type = T;
}; };
template <bool Condition, typename T = void> template <bool Condition, typename T = void>
using enable_if_t = typename enable_if<Condition, T>::type; using enable_if_t = typename enable_if<Condition, T>::type;
@@ -451,8 +451,10 @@ template <typename T, T v>
struct integral_constant { struct integral_constant {
static const T value = v; static const T value = v;
}; };
typedef integral_constant<bool, true> true_type; template <bool B>
typedef integral_constant<bool, false> false_type; using bool_constant = integral_constant<bool, B>;
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
template <typename T> template <typename T>
struct is_array : false_type {}; struct is_array : false_type {};
template <typename T> template <typename T>
@@ -461,11 +463,11 @@ template <typename T, size_t N>
struct is_array<T[N]> : true_type {}; struct is_array<T[N]> : true_type {};
template <typename T> template <typename T>
struct remove_reference { struct remove_reference {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_reference<T&> { struct remove_reference<T&> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
using remove_reference_t = typename remove_reference<T>::type; using remove_reference_t = typename remove_reference<T>::type;
@@ -509,7 +511,7 @@ struct is_convertible {
protected: // <- to avoid GCC's "all member functions in class are private" protected: // <- to avoid GCC's "all member functions in class are private"
static int probe(To); static int probe(To);
static char probe(...); static char probe(...);
static From& from_; static const From& from_;
public: public:
static const bool value = sizeof(probe(from_)) == sizeof(int); static const bool value = sizeof(probe(from_)) == sizeof(int);
}; };
@@ -527,19 +529,19 @@ template <typename T>
struct is_same<T, T> : true_type {}; struct is_same<T, T> : true_type {};
template <typename T> template <typename T>
struct remove_cv { struct remove_cv {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_cv<const T> { struct remove_cv<const T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_cv<volatile T> { struct remove_cv<volatile T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_cv<const volatile T> { struct remove_cv<const volatile T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
using remove_cv_t = typename remove_cv<T>::type; using remove_cv_t = typename remove_cv<T>::type;
@@ -592,7 +594,7 @@ struct is_unsigned : integral_constant<bool,
is_same<remove_cv_t<T>, bool>::value> {}; is_same<remove_cv_t<T>, bool>::value> {};
template <typename T> template <typename T>
struct type_identity { struct type_identity {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct make_unsigned; struct make_unsigned;
@@ -622,11 +624,11 @@ template <typename T>
using make_unsigned_t = typename make_unsigned<T>::type; using make_unsigned_t = typename make_unsigned<T>::type;
template <typename T> template <typename T>
struct remove_const { struct remove_const {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
struct remove_const<const T> { struct remove_const<const T> {
typedef T type; using type = T;
}; };
template <typename T> template <typename T>
using remove_const_t = typename remove_const<T>::type; using remove_const_t = typename remove_const<T>::type;
@@ -964,16 +966,6 @@ class ZeroTerminatedRamString {
const char* data() const { const char* data() const {
return str_; return str_;
} }
friend int stringCompare(ZeroTerminatedRamString a,
ZeroTerminatedRamString b) {
ARDUINOJSON_ASSERT(!a.isNull());
ARDUINOJSON_ASSERT(!b.isNull());
return ::strcmp(a.str_, b.str_);
}
friend bool stringEquals(ZeroTerminatedRamString a,
ZeroTerminatedRamString b) {
return stringCompare(a, b) == 0;
}
bool isLinked() const { bool isLinked() const {
return false; return false;
} }
@@ -982,14 +974,14 @@ class ZeroTerminatedRamString {
}; };
template <typename TChar> template <typename TChar>
struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> { struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
typedef ZeroTerminatedRamString AdaptedString; using AdaptedString = ZeroTerminatedRamString;
static AdaptedString adapt(const TChar* p) { static AdaptedString adapt(const TChar* p) {
return AdaptedString(reinterpret_cast<const char*>(p)); return AdaptedString(reinterpret_cast<const char*>(p));
} }
}; };
template <typename TChar, size_t N> template <typename TChar, size_t N>
struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> { struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
typedef ZeroTerminatedRamString AdaptedString; using AdaptedString = ZeroTerminatedRamString;
static AdaptedString adapt(const TChar* p) { static AdaptedString adapt(const TChar* p) {
return AdaptedString(reinterpret_cast<const char*>(p)); return AdaptedString(reinterpret_cast<const char*>(p));
} }
@@ -1003,7 +995,7 @@ class StaticStringAdapter : public ZeroTerminatedRamString {
}; };
template <> template <>
struct StringAdapter<const char*, void> { struct StringAdapter<const char*, void> {
typedef StaticStringAdapter AdaptedString; using AdaptedString = StaticStringAdapter;
static AdaptedString adapt(const char* p) { static AdaptedString adapt(const char* p) {
return AdaptedString(p); return AdaptedString(p);
} }
@@ -1035,7 +1027,7 @@ class SizedRamString {
}; };
template <typename TChar> template <typename TChar>
struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> { struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
typedef SizedRamString AdaptedString; using AdaptedString = SizedRamString;
static AdaptedString adapt(const TChar* p, size_t n) { static AdaptedString adapt(const TChar* p, size_t n) {
return AdaptedString(reinterpret_cast<const char*>(p), n); return AdaptedString(reinterpret_cast<const char*>(p), n);
} }
@@ -1107,7 +1099,7 @@ class JsonStringAdapter : public SizedRamString {
}; };
template <> template <>
struct StringAdapter<JsonString> { struct StringAdapter<JsonString> {
typedef JsonStringAdapter AdaptedString; using AdaptedString = JsonStringAdapter;
static AdaptedString adapt(const JsonString& s) { static AdaptedString adapt(const JsonString& s) {
return AdaptedString(s); return AdaptedString(s);
} }
@@ -1150,7 +1142,7 @@ struct StringAdapter<
T, T,
enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) && enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) &&
(string_traits<T>::has_length || string_traits<T>::has_size)>> { (string_traits<T>::has_length || string_traits<T>::has_size)>> {
typedef SizedRamString AdaptedString; using AdaptedString = SizedRamString;
static AdaptedString adapt(const T& s) { static AdaptedString adapt(const T& s) {
return AdaptedString(get_data(s), get_size(s)); return AdaptedString(get_data(s), get_size(s));
} }
@@ -1350,14 +1342,14 @@ class FlashString {
}; };
template <> template <>
struct StringAdapter<const __FlashStringHelper*, void> { struct StringAdapter<const __FlashStringHelper*, void> {
typedef FlashString AdaptedString; using AdaptedString = FlashString;
static AdaptedString adapt(const __FlashStringHelper* s) { static AdaptedString adapt(const __FlashStringHelper* s) {
return AdaptedString(s, s ? strlen_P(reinterpret_cast<const char*>(s)) : 0); return AdaptedString(s, s ? strlen_P(reinterpret_cast<const char*>(s)) : 0);
} }
}; };
template <> template <>
struct SizedStringAdapter<const __FlashStringHelper*, void> { struct SizedStringAdapter<const __FlashStringHelper*, void> {
typedef FlashString AdaptedString; using AdaptedString = FlashString;
static AdaptedString adapt(const __FlashStringHelper* s, size_t n) { static AdaptedString adapt(const __FlashStringHelper* s, size_t n) {
return AdaptedString(s, n); return AdaptedString(s, n);
} }
@@ -1616,11 +1608,11 @@ template <typename T, size_t = sizeof(T)>
struct FloatTraits {}; struct FloatTraits {};
template <typename T> template <typename T>
struct FloatTraits<T, 8 /*64bits*/> { struct FloatTraits<T, 8 /*64bits*/> {
typedef uint64_t mantissa_type; using mantissa_type = uint64_t;
static const short mantissa_bits = 52; static const short mantissa_bits = 52;
static const mantissa_type mantissa_max = static const mantissa_type mantissa_max =
(mantissa_type(1) << mantissa_bits) - 1; (mantissa_type(1) << mantissa_bits) - 1;
typedef int16_t exponent_type; using exponent_type = int16_t;
static const exponent_type exponent_max = 308; static const exponent_type exponent_max = 308;
static pgm_ptr<T> positiveBinaryPowersOfTen() { static pgm_ptr<T> positiveBinaryPowersOfTen() {
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( // ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
@@ -1686,11 +1678,11 @@ struct FloatTraits<T, 8 /*64bits*/> {
}; };
template <typename T> template <typename T>
struct FloatTraits<T, 4 /*32bits*/> { struct FloatTraits<T, 4 /*32bits*/> {
typedef uint32_t mantissa_type; using mantissa_type = uint32_t;
static const short mantissa_bits = 23; static const short mantissa_bits = 23;
static const mantissa_type mantissa_max = static const mantissa_type mantissa_max =
(mantissa_type(1) << mantissa_bits) - 1; (mantissa_type(1) << mantissa_bits) - 1;
typedef int8_t exponent_type; using exponent_type = int8_t;
static const exponent_type exponent_max = 38; static const exponent_type exponent_max = 38;
static pgm_ptr<T> positiveBinaryPowersOfTen() { static pgm_ptr<T> positiveBinaryPowersOfTen() {
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors, ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
@@ -1777,9 +1769,9 @@ inline TFloat make_float(TFloat m, TExponent e) {
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
#if ARDUINOJSON_USE_DOUBLE #if ARDUINOJSON_USE_DOUBLE
typedef double JsonFloat; using JsonFloat = double;
#else #else
typedef float JsonFloat; using JsonFloat = float;
#endif #endif
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
@@ -1996,11 +1988,11 @@ class ArrayData : public CollectionData {
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
#if ARDUINOJSON_USE_LONG_LONG #if ARDUINOJSON_USE_LONG_LONG
typedef int64_t JsonInteger; using JsonInteger = int64_t;
typedef uint64_t JsonUInt; using JsonUInt = uint64_t;
#else #else
typedef long JsonInteger; using JsonInteger = long;
typedef unsigned long JsonUInt; using JsonUInt = unsigned long;
#endif #endif
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \ #define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
@@ -2675,15 +2667,15 @@ template <typename T>
struct VariantTo {}; struct VariantTo {};
template <> template <>
struct VariantTo<JsonArray> { struct VariantTo<JsonArray> {
typedef JsonArray type; using type = JsonArray;
}; };
template <> template <>
struct VariantTo<JsonObject> { struct VariantTo<JsonObject> {
typedef JsonObject type; using type = JsonObject;
}; };
template <> template <>
struct VariantTo<JsonVariant> { struct VariantTo<JsonVariant> {
typedef JsonVariant type; using type = JsonVariant;
}; };
class VariantAttorney { class VariantAttorney {
public: public:
@@ -3008,7 +3000,7 @@ class JsonVariantConst : public detail::VariantTag,
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
else else
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
} }
template <typename TString> template <typename TString>
ARDUINOJSON_DEPRECATED("use var[key].is<T>() instead") ARDUINOJSON_DEPRECATED("use var[key].is<T>() instead")
@@ -3155,7 +3147,7 @@ class VariantRefBase : public VariantTag {
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
else else
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
} }
ARDUINOJSON_DEPRECATED("use add<JsonVariant>() instead") ARDUINOJSON_DEPRECATED("use add<JsonVariant>() instead")
JsonVariant add() const; JsonVariant add() const;
@@ -3392,7 +3384,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
friend class JsonArray; friend class JsonArray;
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonArrayConstIterator iterator; using iterator = JsonArrayConstIterator;
iterator begin() const { iterator begin() const {
if (!data_) if (!data_)
return iterator(); return iterator();
@@ -3468,7 +3460,7 @@ class JsonObject;
class JsonArray : public detail::VariantOperators<JsonArray> { class JsonArray : public detail::VariantOperators<JsonArray> {
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonArrayIterator iterator; using iterator = JsonArrayIterator;
JsonArray() : data_(0), resources_(0) {} JsonArray() : data_(0), resources_(0) {}
JsonArray(detail::ArrayData* data, detail::ResourceManager* resources) JsonArray(detail::ArrayData* data, detail::ResourceManager* resources)
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
@@ -3687,7 +3679,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
friend class JsonObject; friend class JsonObject;
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonObjectConstIterator iterator; using iterator = JsonObjectConstIterator;
JsonObjectConst() : data_(0), resources_(0) {} JsonObjectConst() : data_(0), resources_(0) {}
JsonObjectConst(const detail::ObjectData* data, JsonObjectConst(const detail::ObjectData* data,
const detail::ResourceManager* resources) const detail::ResourceManager* resources)
@@ -3751,8 +3743,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
template <typename TVariant> template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst> detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<JsonString>())
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
else else
return JsonVariantConst(); return JsonVariantConst();
} }
@@ -3835,7 +3827,7 @@ class JsonArray;
class JsonObject : public detail::VariantOperators<JsonObject> { class JsonObject : public detail::VariantOperators<JsonObject> {
friend class detail::VariantAttorney; friend class detail::VariantAttorney;
public: public:
typedef JsonObjectIterator iterator; using iterator = JsonObjectIterator;
JsonObject() : data_(0), resources_(0) {} JsonObject() : data_(0), resources_(0) {}
JsonObject(detail::ObjectData* data, detail::ResourceManager* resource) JsonObject(detail::ObjectData* data, detail::ResourceManager* resource)
: data_(data), resources_(resource) {} : data_(data), resources_(resource) {}
@@ -3897,10 +3889,10 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
} }
template <typename TVariant> template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value,
detail::MemberProxy<JsonObject, const char*>> detail::MemberProxy<JsonObject, JsonString>>
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<JsonString>())
return {*this, key.template as<const char*>()}; return {*this, key.template as<JsonString>()};
else else
return {*this, nullptr}; return {*this, nullptr};
} }
@@ -4059,6 +4051,10 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
const T& src) { const T& src) {
return to<JsonVariant>().set(src); return to<JsonVariant>().set(src);
} }
template <typename TChar>
bool set(TChar* src) {
return to<JsonVariant>().set(src);
}
template <typename T> template <typename T>
typename detail::VariantTo<T>::type to() { typename detail::VariantTo<T>::type to() {
clear(); clear();
@@ -4117,8 +4113,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TVariant> template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst> detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<JsonString>())
return operator[](key.template as<const char*>()); return operator[](key.template as<JsonString>());
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
return {}; return {};
@@ -4238,7 +4234,7 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TResult> template <typename TResult>
struct VariantDataVisitor { struct VariantDataVisitor {
typedef TResult result_type; using result_type = TResult;
template <typename T> template <typename T>
TResult visit(const T&) { TResult visit(const T&) {
return TResult(); return TResult();
@@ -4246,7 +4242,7 @@ struct VariantDataVisitor {
}; };
template <typename TResult> template <typename TResult>
struct JsonVariantVisitor { struct JsonVariantVisitor {
typedef TResult result_type; using result_type = TResult;
template <typename T> template <typename T>
TResult visit(const T&) { TResult visit(const T&) {
return TResult(); return TResult();
@@ -4822,7 +4818,7 @@ struct FloatParts {
}; };
template <typename TFloat> template <typename TFloat>
inline int16_t normalize(TFloat& value) { inline int16_t normalize(TFloat& value) {
typedef FloatTraits<TFloat> traits; using traits = FloatTraits<TFloat>;
int16_t powersOf10 = 0; int16_t powersOf10 = 0;
int8_t index = sizeof(TFloat) == 8 ? 8 : 5; int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
int bit = 1 << index; int bit = 1 << index;
@@ -4965,7 +4961,7 @@ class TextFormatter {
} }
template <typename T> template <typename T>
enable_if_t<is_signed<T>::value> writeInteger(T value) { enable_if_t<is_signed<T>::value> writeInteger(T value) {
typedef make_unsigned_t<T> unsigned_type; using unsigned_type = make_unsigned_t<T>;
unsigned_type unsigned_value; unsigned_type unsigned_value;
if (value < 0) { if (value < 0) {
writeRaw('-'); writeRaw('-');
@@ -5703,7 +5699,7 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class JsonVariantCopier { class JsonVariantCopier {
public: public:
typedef bool result_type; using result_type = bool;
JsonVariantCopier(JsonVariant dst) : dst_(dst) {} JsonVariantCopier(JsonVariant dst) : dst_(dst) {}
template <typename T> template <typename T>
bool visit(T src) { bool visit(T src) {
@@ -6325,13 +6321,10 @@ template <typename T, typename... Rest>
struct first_or_void<T, Rest...> { struct first_or_void<T, Rest...> {
using type = T; using type = T;
}; };
template <class T, class = void>
struct is_deserialize_destination : false_type {};
template <class T> template <class T>
struct is_deserialize_destination< using is_deserialize_destination =
T, enable_if_t<is_same<decltype(VariantAttorney::getResourceManager( bool_constant<is_base_of<JsonDocument, remove_cv_t<T>>::value ||
detail::declval<T&>())), IsVariant<T>::value>;
ResourceManager*>::value>> : true_type {};
template <typename TDestination> template <typename TDestination>
inline void shrinkJsonDocument(TDestination&) { inline void shrinkJsonDocument(TDestination&) {
} }
@@ -6571,9 +6564,9 @@ class Number {
#endif #endif
}; };
inline Number parseNumber(const char* s) { inline Number parseNumber(const char* s) {
typedef FloatTraits<JsonFloat> traits; using traits = FloatTraits<JsonFloat>;
typedef largest_type<traits::mantissa_type, JsonUInt> mantissa_t; using mantissa_t = largest_type<traits::mantissa_type, JsonUInt>;
typedef traits::exponent_type exponent_t; using exponent_t = traits::exponent_type;
ARDUINOJSON_ASSERT(s != 0); ARDUINOJSON_ASSERT(s != 0);
bool is_negative = false; bool is_negative = false;
switch (*s) { switch (*s) {
@@ -7212,7 +7205,7 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TWriter> template <typename TWriter>
class PrettyJsonSerializer : public JsonSerializer<TWriter> { class PrettyJsonSerializer : public JsonSerializer<TWriter> {
typedef JsonSerializer<TWriter> base; using base = JsonSerializer<TWriter>;
public: public:
PrettyJsonSerializer(TWriter writer, const ResourceManager* resources) PrettyJsonSerializer(TWriter writer, const ResourceManager* resources)
: base(writer, resources), nesting_(0) {} : base(writer, resources), nesting_(0) {}

View File

@@ -1,4 +1,4 @@
Version 7.2.0 Version 7.2.1
From https://github.com/bblanchon/ArduinoJson/releases From https://github.com/bblanchon/ArduinoJson/releases

View File

@@ -66,6 +66,10 @@ class ESP8266React {
return _apSettingsService.getAPNetworkStatus() == APNetworkStatus::ACTIVE; return _apSettingsService.getAPNetworkStatus() == APNetworkStatus::ACTIVE;
} }
uint16_t getWifiReconnects() {
return _networkSettingsService.getWifiReconnects();
}
private: private:
SecuritySettingsService _securitySettingsService; SecuritySettingsService _securitySettingsService;
NetworkSettingsService _networkSettingsService; NetworkSettingsService _networkSettingsService;

View File

@@ -304,10 +304,14 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
break; break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
emsesp::EMSESP::logger().warning("WiFi disconnected. Reason: %s (%d)", connectcount_++; // count the number of WiFi reconnects
emsesp::EMSESP::logger().warning("WiFi disconnected (#%d). Reason: %s (%d)",
connectcount_,
disconnectReason(info.wifi_sta_disconnected.reason), disconnectReason(info.wifi_sta_disconnected.reason),
info.wifi_sta_disconnected.reason); // IDF 4.0 info.wifi_sta_disconnected.reason); // IDF 4.0
emsesp::EMSESP::system_.has_ipv6(false); emsesp::EMSESP::system_.has_ipv6(false);
break; break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_WIFI_STA_GOT_IP:

View File

@@ -87,7 +87,6 @@ class NetworkSettings {
static StateUpdateResult update(JsonObject root, NetworkSettings & settings); static StateUpdateResult update(JsonObject root, NetworkSettings & settings);
}; };
class NetworkSettingsService : public StatefulService<NetworkSettings> { class NetworkSettingsService : public StatefulService<NetworkSettings> {
public: public:
NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
@@ -95,6 +94,10 @@ class NetworkSettingsService : public StatefulService<NetworkSettings> {
void begin(); void begin();
void loop(); void loop();
uint16_t getWifiReconnects() const {
return connectcount_;
}
private: private:
HttpEndpoint<NetworkSettings> _httpEndpoint; HttpEndpoint<NetworkSettings> _httpEndpoint;
FSPersistence<NetworkSettings> _fsPersistence; FSPersistence<NetworkSettings> _fsPersistence;
@@ -102,6 +105,8 @@ class NetworkSettingsService : public StatefulService<NetworkSettings> {
unsigned long _lastConnectionAttempt; unsigned long _lastConnectionAttempt;
bool _stopping; bool _stopping;
uint16_t connectcount_ = 0; // number of wifi reconnects
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info);
void mDNS_start() const; void mDNS_start() const;
const char * disconnectReason(uint8_t code); const char * disconnectReason(uint8_t code);

View File

@@ -60,12 +60,13 @@ void NetworkStatus::networkStatus(AsyncWebServerRequest * request) {
#else #else
root["local_ipv6"] = WiFi.linkLocalIPv6().toString(); root["local_ipv6"] = WiFi.linkLocalIPv6().toString();
#endif #endif
root["mac_address"] = WiFi.macAddress(); root["mac_address"] = WiFi.macAddress();
root["rssi"] = WiFi.RSSI(); root["rssi"] = WiFi.RSSI();
root["ssid"] = WiFi.SSID(); root["ssid"] = WiFi.SSID();
root["bssid"] = WiFi.BSSIDstr(); root["bssid"] = WiFi.BSSIDstr();
root["channel"] = WiFi.channel(); root["channel"] = WiFi.channel();
root["subnet_mask"] = WiFi.subnetMask().toString(); root["reconnect_count"] = emsesp::EMSESP::esp8266React.getWifiReconnects();
root["subnet_mask"] = WiFi.subnetMask().toString();
if (WiFi.gatewayIP() != INADDR_NONE) { if (WiFi.gatewayIP() != INADDR_NONE) {
root["gateway_ip"] = WiFi.gatewayIP().toString(); root["gateway_ip"] = WiFi.gatewayIP().toString();

View File

@@ -368,7 +368,8 @@ const network_status = {
gateway_ip: '10.10.10.1', gateway_ip: '10.10.10.1',
dns_ip_1: '10.10.10.1', dns_ip_1: '10.10.10.1',
dns_ip_2: '0.0.0.0', dns_ip_2: '0.0.0.0',
hostname: 'ems-esp' hostname: 'ems-esp',
reconnect_count: 1
}; };
const list_networks = { const list_networks = {
networks: [ networks: [
@@ -4839,7 +4840,7 @@ router
if (action === 'export') { if (action === 'export') {
// export data // export data
return export_data(content.param); return export_data(content.param);
} else if (action === 'customSupport') { } else if (action === 'getCustomSupport') {
// send custom support // send custom support
return custom_support(); return custom_support();
} else if (action === 'checkUpgrade') { } else if (action === 'checkUpgrade') {

View File

@@ -81,7 +81,7 @@ check_flags =
clangtidy: --checks=-*,clang-analyzer-*,performance-* clangtidy: --checks=-*,clang-analyzer-*,performance-*
lib_ldf_mode = chain+ lib_ldf_mode = chain+
lib_deps = lib_deps =
https://github.com/emsesp/EMS-ESP-Modules.git@1.0.2 https://github.com/emsesp/EMS-ESP-Modules.git@1.0.3
; ;
; builds for GitHub Actions CI ; builds for GitHub Actions CI

View File

@@ -1365,4 +1365,6 @@ poolshuntstatus
pooltemp pooltemp
stoptime stoptime
showertimer showertimer
showeralert showeralert
CTKWH
wifireconnects

View File

@@ -1776,10 +1776,10 @@ void EMSESP::loop() {
void EMSESP::start_serial_console() { void EMSESP::start_serial_console() {
shell_ = std::make_shared<EMSESPConsole>(*this, serial_console_, true); shell_ = std::make_shared<EMSESPConsole>(*this, serial_console_, true);
shell_->maximum_log_messages(100); shell_->maximum_log_messages(100);
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests
shell_->start(); shell_->start();
#if defined(EMSESP_DEBUG) #if defined(EMSESP_DEBUG)
shell_->log_level(uuid::log::Level::DEBUG); shell_->log_level(uuid::log::Level::DEBUG);
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when compiled with debug
#else #else
shell_->log_level(uuid::log::Level::TRACE); shell_->log_level(uuid::log::Level::TRACE);
#endif #endif

View File

@@ -128,70 +128,71 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOnly), 206, 1), // auxheateronly REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOnly), 206, 1), // auxheateronly
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOff), 207, 1), // auxheateroff REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOff), 207, 1), // auxheateroff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterStatus), 208, 1), // auxheaterstatus REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterStatus), 208, 1), // auxheaterstatus
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterDelay), 209, 1), // auxheaterdelay REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterLevel), 209, 1), // auxheaterlevel
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 210, 1), // auxmaxlimit REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterDelay), 210, 1), // auxheaterdelay
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 211, 1), // auxlimitstart REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 211, 1), // auxmaxlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 212, 1), // auxheatrmode REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 212, 1), // auxlimitstart
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 213, 1), // hphystheat REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 213, 1), // auxheatrmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 214, 1), // hphystcool REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 214, 1), // hphystheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 215, 1), // hphystpool REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 215, 1), // hphystcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 216, 1), // silentmode REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 216, 1), // hphystpool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 217, 1), // silentfrom REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 217, 1), // silentmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 218, 1), // silentto REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 218, 1), // silentfrom
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 219, 1), // mintempsilent REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 219, 1), // silentto
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 220, 1), // tempparmode REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 220, 1), // mintempsilent
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 221, 1), // auxheatmix REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 221, 1), // tempparmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 222, 1), // tempdiffheat REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 222, 1), // auxheatmix
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 223, 1), // tempdiffcool REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 223, 1), // tempdiffheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 224, 1), // vpcooling REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 224, 1), // tempdiffcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 225, 1), // heatcable REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 225, 1), // vpcooling
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 226, 1), // vc0valve REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 226, 1), // heatcable
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 227, 1), // primepump REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 227, 1), // vc0valve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 228, 1), // primepumpmod REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 228, 1), // primepump
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 229, 1), // hp3way REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 229, 1), // primepumpmod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 230, 1), // elheatstep1 REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 230, 1), // hp3way
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 231, 1), // elheatstep2 REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 231, 1), // elheatstep1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 232, 1), // elheatstep3 REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 232, 1), // elheatstep2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 233, 1), // hpea0 REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 233, 1), // elheatstep3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 234, 1), // hppumpmode REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 234, 1), // hpea0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 235, 1), // fan REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 235, 1), // hppumpmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 236, 1), // shutdown REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 236, 1), // fan
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 237, 1), // hpcurrpower REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 237, 1), // shutdown
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 238, 1), // hppowerlimit REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 238, 1), // hpcurrpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc0Flow), 239, 1), // pc0flow REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 239, 1), // hppowerlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Flow), 240, 1), // pc1flow REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc0Flow), 240, 1), // pc0flow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1On), 241, 1), // pc1on REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Flow), 241, 1), // pc1flow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Rate), 242, 1), // pc1rate REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1On), 242, 1), // pc1on
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 243, 1), // exhausttemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Rate), 243, 1), // pc1rate
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 244, 1), // burngas REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 244, 1), // exhausttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 245, 1), // burngas2 REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 245, 1), // burngas
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 246, 1), // flamecurr REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 246, 1), // burngas2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 247, 1), // fanwork REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 247, 1), // flamecurr
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 248, 1), // ignwork REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 248, 1), // fanwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 249, 1), // oilpreheat REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 249, 1), // ignwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 250, 1), // burnminpower REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 250, 1), // oilpreheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 251, 1), // burnmaxpower REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 251, 1), // burnminpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 252, 1), // burnminperiod REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 252, 1), // burnmaxpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 253, 1), // absburnpow REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 253, 1), // burnminperiod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 254, 1), // heatblock REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 254, 1), // absburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 255, 1), // boilhyston REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 255, 1), // heatblock
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 256, 1), // boilhystoff REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 256, 1), // boilhyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 257, 1), // boil2hyston REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 257, 1), // boilhystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 258, 1), // boil2hystoff REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 258, 1), // boil2hyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 259, 1), // curveon REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 259, 1), // boil2hystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 260, 1), // curvebase REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 260, 1), // curveon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 261, 1), // curveend REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 261, 1), // curvebase
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 262, 1), // summertemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 262, 1), // curveend
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 263, 1), // nofrostmode REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 263, 1), // summertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 264, 1), // nofrosttemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 264, 1), // nofrostmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 265, 2), // gasmeterheat REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 265, 1), // nofrosttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 267, 2), // nrgheat2 REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 266, 2), // gasmeterheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 269, 1), // nompower REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 268, 2), // nrgheat2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 270, 1), // netflowtemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 270, 1), // nompower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 271, 1), // heatvalve REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 271, 1), // netflowtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 272, 1), // keepwarmtemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 272, 1), // heatvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 273, 1), // setreturntemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 273, 1), // keepwarmtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 274, 1), // heating REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 274, 1), // setreturntemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 275, 1), // heating
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(upTimeCompWw), 4, 2), // uptimecomp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(upTimeCompWw), 4, 2), // uptimecomp
@@ -484,25 +485,25 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseMode), 17, 1), // lownoisemode REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseMode), 17, 1), // lownoisemode
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseStart), 18, 1), // lownoisestart REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseStart), 18, 1), // lownoisestart
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseStop), 19, 1), // lownoisestop REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseStop), 19, 1), // lownoisestop
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(hybridDHW), 20, 1), // hybriddhw REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceGas), 20, 1), // energypricegas
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceGas), 21, 1), // energypricegas REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceEl), 21, 1), // energypriceel
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceEl), 22, 1), // energypriceel REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPricePV), 22, 1), // energyfeedpv
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPricePV), 23, 1), // energyfeedpv REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(switchOverTemp), 23, 1), // switchovertemp
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(switchOverTemp), 24, 1), // switchovertemp REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(airPurgeMode), 24, 1), // airpurgemode
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(airPurgeMode), 25, 1), // airpurgemode REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatPumpOutput), 25, 1), // heatpumpoutput
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatPumpOutput), 26, 1), // heatpumpoutput REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(coolingCircuit), 26, 1), // coolingcircuit
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(coolingCircuit), 27, 1), // coolingcircuit REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(compStartMod), 27, 1), // compstartmod
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(compStartMod), 28, 1), // compstartmod REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatDrainPan), 28, 1), // heatdrainpan
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatDrainPan), 29, 1), // heatdrainpan REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 29, 1), // heatcable
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 30, 1), // heatcable REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgTotal), 30, 2), // nrgtotal
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgTotal), 31, 2), // nrgtotal REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat), 32, 2), // nrgheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat), 33, 2), // nrgheat REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterTotal), 34, 2), // metertotal
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterTotal), 35, 2), // metertotal REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterComp), 36, 2), // metercomp
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterComp), 37, 2), // metercomp REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterEHeat), 38, 2), // metereheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterEHeat), 39, 2), // metereheat REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterHeat), 40, 2), // meterheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterHeat), 41, 2), // meterheat REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(hybridDHW), 0, 1), // hybriddhw
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(nrgWw), 1, 2), // nrg
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(meterWw), 3, 2), // meter
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(activated), 0, 1), // activated REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(activated), 0, 1), // activated
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(flowTempHc), 1, 1), // flowtemphc REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(flowTempHc), 1, 1), // flowtemphc
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(status), 2, 1), // status REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(status), 2, 1), // status

View File

@@ -513,7 +513,7 @@ void Mqtt::on_connect() {
// with disabled HA we subscribe and the broker sends all stored HA-emsesp-configs. // with disabled HA we subscribe and the broker sends all stored HA-emsesp-configs.
// Around line 272 they are removed (search for "// remove HA topics if we don't use discover") // Around line 272 they are removed (search for "// remove HA topics if we don't use discover")
// If HA is enabled the subscriptions are removed. // If HA is enabled the subscriptions are removed.
// As described in the doc (https://emsesp.github.io/docs/#/Troubleshooting?id=home-assistant): // As described in the doc (https://docs.emsesp.org/Troubleshooting?id=home-assistant):
// disable HA, wait 5 minutes (to allow the broker to send all), than reenable HA again. // disable HA, wait 5 minutes (to allow the broker to send all), than reenable HA again.
queue_subscribe_message(discovery_prefix_ + "/+/" + mqtt_basename_ + "/#"); queue_subscribe_message(discovery_prefix_ + "/+/" + mqtt_basename_ + "/#");
} }
@@ -593,8 +593,9 @@ void Mqtt::ha_status() {
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx reads", "txreads", DeviceValueUOM::NONE); publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx reads", "txreads", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx writes", "txwrites", DeviceValueUOM::NONE); publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx writes", "txwrites", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx fails", "txfails", DeviceValueUOM::NONE); publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx fails", "txfails", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::INT16, "WiFi reconnects", "wifireconnects", DeviceValueUOM::NONE);
// This comes from the info MQTT topic // This comes from the info MQTT topic - and handled in the publish_ha_sensor_config function
publish_system_ha_sensor_config(DeviceValueType::STRING, "Version", "version", DeviceValueUOM::NONE); publish_system_ha_sensor_config(DeviceValueType::STRING, "Version", "version", DeviceValueUOM::NONE);
} }

View File

@@ -683,15 +683,7 @@ void System::heartbeat_json(JsonObject output) {
output["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); output["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
output["uptime_sec"] = uuid::get_uptime_sec(); output["uptime_sec"] = uuid::get_uptime_sec();
bool value_b = ntp_connected();
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
output["ntp_status"] = value_b;
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
output["ntp_status"] = value_b ? 1 : 0;
} else {
char s[12];
output["ntp_status"] = Helpers::render_boolean(s, value_b);
}
output["rxreceived"] = EMSESP::rxservice_.telegram_count(); output["rxreceived"] = EMSESP::rxservice_.telegram_count();
output["rxfails"] = EMSESP::rxservice_.telegram_error_count(); output["rxfails"] = EMSESP::rxservice_.telegram_error_count();
output["txreads"] = EMSESP::txservice_.telegram_read_count(); output["txreads"] = EMSESP::txservice_.telegram_read_count();
@@ -721,9 +713,10 @@ void System::heartbeat_json(JsonObject output) {
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
if (!ethernet_connected_) { if (!ethernet_connected_) {
int8_t rssi = WiFi.RSSI(); int8_t rssi = WiFi.RSSI();
output["rssi"] = rssi; output["rssi"] = rssi;
output["wifistrength"] = wifi_quality(rssi); output["wifistrength"] = wifi_quality(rssi);
output["wifireconnects"] = EMSESP::esp8266React.getWifiReconnects();
} }
#endif #endif
} }
@@ -1174,7 +1167,7 @@ bool System::check_restore() {
// it's a custom support file - save it to /config // it's a custom support file - save it to /config
new_file.close(); new_file.close();
if (LittleFS.rename(TEMP_FILENAME_PATH, EMSESP_CUSTOMSUPPORT_FILE)) { if (LittleFS.rename(TEMP_FILENAME_PATH, EMSESP_CUSTOMSUPPORT_FILE)) {
LOG_DEBUG("Custom support information found"); LOG_INFO("Custom support file stored");
return false; // no need to reboot return false; // no need to reboot
} else { } else {
LOG_ERROR("Failed to save custom support file"); LOG_ERROR("Failed to save custom support file");
@@ -1504,9 +1497,10 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
// node["IPv6 address"] = uuid::printable_to_string(ETH.localIPv6()); // node["IPv6 address"] = uuid::printable_to_string(ETH.localIPv6());
// } // }
} else if (WiFi.status() == WL_CONNECTED) { } else if (WiFi.status() == WL_CONNECTED) {
node["network"] = "WiFi"; node["network"] = "WiFi";
node["hostname"] = WiFi.getHostname(); node["hostname"] = WiFi.getHostname();
node["RSSI"] = WiFi.RSSI(); node["RSSI"] = WiFi.RSSI();
node["WIFIReconnects"] = EMSESP::esp8266React.getWifiReconnects();
// node["MAC"] = WiFi.macAddress(); // node["MAC"] = WiFi.macAddress();
// node["IPv4 address"] = uuid::printable_to_string(WiFi.localIP()) + "/" + uuid::printable_to_string(WiFi.subnetMask()); // node["IPv4 address"] = uuid::printable_to_string(WiFi.localIP()) + "/" + uuid::printable_to_string(WiFi.subnetMask());
// node["IPv4 gateway"] = uuid::printable_to_string(WiFi.gatewayIP()); // node["IPv4 gateway"] = uuid::printable_to_string(WiFi.gatewayIP());
@@ -1535,6 +1529,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
node["CORSOrigin"] = settings.CORSOrigin; node["CORSOrigin"] = settings.CORSOrigin;
} }
}); });
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
EMSESP::esp8266React.getAPSettingsService()->read([&](const APSettings & settings) { EMSESP::esp8266React.getAPSettingsService()->read([&](const APSettings & settings) {
const char * pM[] = {"always", "disconnected", "never"}; const char * pM[] = {"always", "disconnected", "never"};

View File

@@ -1014,10 +1014,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// request.url("/api"); // request.url("/api");
// EMSESP::webAPIService.webAPIService(&request, doc.as<JsonVariant>()); // EMSESP::webAPIService.webAPIService(&request, doc.as<JsonVariant>());
// char data2[] = "{\"action\":\"customSupport\", \"param\":\"hello\"}"; char data2[] = "{\"action\":\"getCustomSupport\", \"param\":\"hello\"}";
// deserializeJson(doc, data2); deserializeJson(doc, data2);
// request.url("/rest/action"); request.url("/rest/action");
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>()); EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// char data3[] = "{\"action\":\"export\", \"param\":\"schedule\"}"; // char data3[] = "{\"action\":\"export\", \"param\":\"schedule\"}";
// deserializeJson(doc, data3); // deserializeJson(doc, data3);
@@ -1031,11 +1031,11 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// test version checks // test version checks
// test with "current_version_s = "3.7.1-dev.8" in WebStatusService::checkUpgrade() // test with "current_version_s = "3.7.1-dev.8" in WebStatusService::checkUpgrade()
request.url("/rest/action"); // request.url("/rest/action");
deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.9,3.7.0\"}"); // is upgradable // deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.9,3.7.0\"}"); // is upgradable
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>()); // EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is not upgradable // deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is not upgradable
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>()); // EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// test with "current_version_s = "3.6.5" in WebStatusService::checkUpgrade() // test with "current_version_s = "3.6.5" in WebStatusService::checkUpgrade()
// request.url("/rest/action"); // request.url("/rest/action");
@@ -1044,7 +1044,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is upgradable // deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is upgradable
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>()); // EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// char data6[] = "{\"device\":\"system\", \"cmd\":\"read\",\"value\":\"8 2 27 1\"}"; // char data6[] = "{\"device\":\"system\", \"cmd\":\"read\",\"value\":\"8 2 27 1\"}";
// deserializeJson(doc, data6); // deserializeJson(doc, data6);
// json = doc.as<JsonVariant>(); // json = doc.as<JsonVariant>();

View File

@@ -41,7 +41,7 @@ namespace emsesp {
// #define EMSESP_DEBUG_DEFAULT "310" // #define EMSESP_DEBUG_DEFAULT "310"
// #define EMSESP_DEBUG_DEFAULT "render" // #define EMSESP_DEBUG_DEFAULT "render"
// #define EMSESP_DEBUG_DEFAULT "api" // #define EMSESP_DEBUG_DEFAULT "api"
#define EMSESP_DEBUG_DEFAULT "api3" // #define EMSESP_DEBUG_DEFAULT "api3"
// #define EMSESP_DEBUG_DEFAULT "crash" // #define EMSESP_DEBUG_DEFAULT "crash"
// #define EMSESP_DEBUG_DEFAULT "dv" // #define EMSESP_DEBUG_DEFAULT "dv"
// #define EMSESP_DEBUG_DEFAULT "lastcode" // #define EMSESP_DEBUG_DEFAULT "lastcode"

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.1-dev.7" #define EMSESP_APP_VERSION "3.7.1-dev.8"

View File

@@ -179,8 +179,8 @@ void WebStatusService::action(AsyncWebServerRequest * request, JsonVariant json)
if (has_param) { if (has_param) {
ok = exportData(root, param); ok = exportData(root, param);
} }
} else if (action == "customSupport") { } else if (action == "getCustomSupport") {
ok = customSupport(root); ok = getCustomSupport(root);
} else if (action == "uploadURL" && is_admin) { } else if (action == "uploadURL" && is_admin) {
ok = uploadURL(param.c_str()); ok = uploadURL(param.c_str());
} }
@@ -301,19 +301,28 @@ bool WebStatusService::exportData(JsonObject root, std::string & type) {
return true; return true;
} }
// action = customSupport // action = getCustomSupport
// reads any upload customSupport.json file and sends to to Help page to be shown as Guest // reads any upload customSupport.json file and sends to to Help page to be shown as Guest
bool WebStatusService::customSupport(JsonObject root) { bool WebStatusService::getCustomSupport(JsonObject root) {
#ifndef EMSESP_STANDALONE JsonDocument doc;
#if defined(EMSESP_STANDALONE)
// dummy test data for "test api3"
deserializeJson(
doc, "{\"type\":\"customSupport\",\"Support\":{\"html\":[\"html code\",\"here\"], \"img_url\": \"https://docs.emsesp.org/_media/images/designer.png\"}");
#else
// check if we have custom support file uploaded // check if we have custom support file uploaded
File file = LittleFS.open(EMSESP_CUSTOMSUPPORT_FILE, "r"); File file = LittleFS.open(EMSESP_CUSTOMSUPPORT_FILE, "r");
if (!file) { if (!file) {
// there is no custom file, return empty object // there is no custom file, return empty object
#if defined(EMSESP_DEBUG)
emsesp::EMSESP::logger().debug("No custom support file found");
#endif
return true; return true;
} }
// read the contents of the file into the root output json object // read the contents of the file into a json doc. We can't do this direct to object since 7.2.1
DeserializationError error = deserializeJson(root, file); DeserializationError error = deserializeJson(doc, file);
if (error) { if (error) {
emsesp::EMSESP::logger().err("Failed to read custom support file"); emsesp::EMSESP::logger().err("Failed to read custom support file");
return false; return false;
@@ -321,6 +330,13 @@ bool WebStatusService::customSupport(JsonObject root) {
file.close(); file.close();
#endif #endif
#if defined(EMSESP_DEBUG)
emsesp::EMSESP::logger().debug("Showing custom support page");
#endif
root.set(doc.as<JsonObject>()); // add to web response root object
return true; return true;
} }

View File

@@ -25,7 +25,7 @@ class WebStatusService {
// actions // actions
bool checkUpgrade(JsonObject root, std::string & latest_version); bool checkUpgrade(JsonObject root, std::string & latest_version);
bool exportData(JsonObject root, std::string & type); bool exportData(JsonObject root, std::string & type);
bool customSupport(JsonObject root); bool getCustomSupport(JsonObject root);
bool uploadURL(const char * url); bool uploadURL(const char * url);
void allvalues(JsonObject output); void allvalues(JsonObject output);

View File

@@ -0,0 +1,18 @@
{
"type": "customSupport",
"Support": {
"html": [
"This product is installed and managed by:",
"",
"<b>Bosch Installer Example</b>",
"",
"Nefit Road 12",
"1234 AB Amsterdam",
"Phone: +31 123 456 789",
"email: support@boschinstaller.nl",
"",
"For help and questions please <a target='_blank' href='https://emsesp.org'>contact</a> your installer."
],
"img_url": "https://docs.emsesp.org/_media/images/designer.png"
}
}