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

View File

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

View File

@@ -39,7 +39,7 @@ const Help = () => {
const [customSupportHTML, setCustomSupportHTML] = useState<string | null>(null);
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) {
const data = event.data.Support;
if (data.img_url) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -304,10 +304,14 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
break;
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),
info.wifi_sta_disconnected.reason); // IDF 4.0
emsesp::EMSESP::system_.has_ipv6(false);
break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP:

View File

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

View File

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

View File

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

View File

@@ -81,7 +81,7 @@ check_flags =
clangtidy: --checks=-*,clang-analyzer-*,performance-*
lib_ldf_mode = chain+
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

View File

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

View File

@@ -1776,10 +1776,10 @@ void EMSESP::loop() {
void EMSESP::start_serial_console() {
shell_ = std::make_shared<EMSESPConsole>(*this, serial_console_, true);
shell_->maximum_log_messages(100);
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests
shell_->start();
#if defined(EMSESP_DEBUG)
shell_->log_level(uuid::log::Level::DEBUG);
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when compiled with debug
#else
shell_->log_level(uuid::log::Level::TRACE);
#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_(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_(auxHeaterDelay), 209, 1), // auxheaterdelay
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 210, 1), // auxmaxlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 211, 1), // auxlimitstart
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 212, 1), // auxheatrmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 213, 1), // hphystheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 214, 1), // hphystcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 215, 1), // hphystpool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 216, 1), // silentmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 217, 1), // silentfrom
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 218, 1), // silentto
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 219, 1), // mintempsilent
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 220, 1), // tempparmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 221, 1), // auxheatmix
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 222, 1), // tempdiffheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 223, 1), // tempdiffcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 224, 1), // vpcooling
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 225, 1), // heatcable
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 226, 1), // vc0valve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 227, 1), // primepump
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 228, 1), // primepumpmod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 229, 1), // hp3way
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 230, 1), // elheatstep1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 231, 1), // elheatstep2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 232, 1), // elheatstep3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 233, 1), // hpea0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 234, 1), // hppumpmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 235, 1), // fan
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 236, 1), // shutdown
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 237, 1), // hpcurrpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 238, 1), // hppowerlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc0Flow), 239, 1), // pc0flow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Flow), 240, 1), // pc1flow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1On), 241, 1), // pc1on
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Rate), 242, 1), // pc1rate
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 243, 1), // exhausttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 244, 1), // burngas
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 245, 1), // burngas2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 246, 1), // flamecurr
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 247, 1), // fanwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 248, 1), // ignwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 249, 1), // oilpreheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 250, 1), // burnminpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 251, 1), // burnmaxpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 252, 1), // burnminperiod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 253, 1), // absburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 254, 1), // heatblock
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 255, 1), // boilhyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 256, 1), // boilhystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 257, 1), // boil2hyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 258, 1), // boil2hystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 259, 1), // curveon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 260, 1), // curvebase
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 261, 1), // curveend
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 262, 1), // summertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 263, 1), // nofrostmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 264, 1), // nofrosttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 265, 2), // gasmeterheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 267, 2), // nrgheat2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 269, 1), // nompower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 270, 1), // netflowtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 271, 1), // heatvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 272, 1), // keepwarmtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 273, 1), // setreturntemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 274, 1), // heating
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterLevel), 209, 1), // auxheaterlevel
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterDelay), 210, 1), // auxheaterdelay
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 211, 1), // auxmaxlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 212, 1), // auxlimitstart
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 213, 1), // auxheatrmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 214, 1), // hphystheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 215, 1), // hphystcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 216, 1), // hphystpool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 217, 1), // silentmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 218, 1), // silentfrom
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 219, 1), // silentto
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 220, 1), // mintempsilent
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 221, 1), // tempparmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 222, 1), // auxheatmix
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 223, 1), // tempdiffheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 224, 1), // tempdiffcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 225, 1), // vpcooling
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 226, 1), // heatcable
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 227, 1), // vc0valve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 228, 1), // primepump
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 229, 1), // primepumpmod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 230, 1), // hp3way
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 231, 1), // elheatstep1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 232, 1), // elheatstep2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 233, 1), // elheatstep3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 234, 1), // hpea0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 235, 1), // hppumpmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 236, 1), // fan
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 237, 1), // shutdown
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 238, 1), // hpcurrpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 239, 1), // hppowerlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc0Flow), 240, 1), // pc0flow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Flow), 241, 1), // pc1flow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1On), 242, 1), // pc1on
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Rate), 243, 1), // pc1rate
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 244, 1), // exhausttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 245, 1), // burngas
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 246, 1), // burngas2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 247, 1), // flamecurr
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 248, 1), // fanwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 249, 1), // ignwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 250, 1), // oilpreheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 251, 1), // burnminpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 252, 1), // burnmaxpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 253, 1), // burnminperiod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 254, 1), // absburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 255, 1), // heatblock
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 256, 1), // boilhyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 257, 1), // boilhystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 258, 1), // boil2hyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 259, 1), // boil2hystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 260, 1), // curveon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 261, 1), // curvebase
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 262, 1), // curveend
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 263, 1), // summertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 264, 1), // nofrostmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 265, 1), // nofrosttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 266, 2), // gasmeterheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 268, 2), // nrgheat2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 270, 1), // nompower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 271, 1), // netflowtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 272, 1), // heatvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 273, 1), // keepwarmtemp
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_(meterWw), 2, 2), // meter
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_(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_(hybridDHW), 20, 1), // hybriddhw
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceGas), 21, 1), // energypricegas
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceEl), 22, 1), // energypriceel
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPricePV), 23, 1), // energyfeedpv
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(switchOverTemp), 24, 1), // switchovertemp
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(airPurgeMode), 25, 1), // airpurgemode
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatPumpOutput), 26, 1), // heatpumpoutput
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(coolingCircuit), 27, 1), // coolingcircuit
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(compStartMod), 28, 1), // compstartmod
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatDrainPan), 29, 1), // heatdrainpan
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 30, 1), // heatcable
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgTotal), 31, 2), // nrgtotal
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat), 33, 2), // nrgheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterTotal), 35, 2), // metertotal
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterComp), 37, 2), // metercomp
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterEHeat), 39, 2), // metereheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterHeat), 41, 2), // meterheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceGas), 20, 1), // energypricegas
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceEl), 21, 1), // energypriceel
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPricePV), 22, 1), // energyfeedpv
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(switchOverTemp), 23, 1), // switchovertemp
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(airPurgeMode), 24, 1), // airpurgemode
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatPumpOutput), 25, 1), // heatpumpoutput
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(coolingCircuit), 26, 1), // coolingcircuit
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(compStartMod), 27, 1), // compstartmod
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatDrainPan), 28, 1), // heatdrainpan
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 29, 1), // heatcable
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgTotal), 30, 2), // nrgtotal
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat), 32, 2), // nrgheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterTotal), 34, 2), // metertotal
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterComp), 36, 2), // metercomp
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterEHeat), 38, 2), // metereheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterHeat), 40, 2), // meterheat
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(hybridDHW), 0, 1), // hybriddhw
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(nrgWw), 1, 2), // nrg
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_(flowTempHc), 1, 1), // flowtemphc
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.
// 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.
// 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.
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 writes", "txwrites", 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);
}

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_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["rxfails"] = EMSESP::rxservice_.telegram_error_count();
output["txreads"] = EMSESP::txservice_.telegram_read_count();
@@ -721,9 +713,10 @@ void System::heartbeat_json(JsonObject output) {
#ifndef EMSESP_STANDALONE
if (!ethernet_connected_) {
int8_t rssi = WiFi.RSSI();
output["rssi"] = rssi;
output["wifistrength"] = wifi_quality(rssi);
int8_t rssi = WiFi.RSSI();
output["rssi"] = rssi;
output["wifistrength"] = wifi_quality(rssi);
output["wifireconnects"] = EMSESP::esp8266React.getWifiReconnects();
}
#endif
}
@@ -1174,7 +1167,7 @@ bool System::check_restore() {
// it's a custom support file - save it to /config
new_file.close();
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
} else {
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());
// }
} else if (WiFi.status() == WL_CONNECTED) {
node["network"] = "WiFi";
node["hostname"] = WiFi.getHostname();
node["RSSI"] = WiFi.RSSI();
node["network"] = "WiFi";
node["hostname"] = WiFi.getHostname();
node["RSSI"] = WiFi.RSSI();
node["WIFIReconnects"] = EMSESP::esp8266React.getWifiReconnects();
// node["MAC"] = WiFi.macAddress();
// node["IPv4 address"] = uuid::printable_to_string(WiFi.localIP()) + "/" + uuid::printable_to_string(WiFi.subnetMask());
// 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;
}
});
#ifndef EMSESP_STANDALONE
EMSESP::esp8266React.getAPSettingsService()->read([&](const APSettings & settings) {
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");
// EMSESP::webAPIService.webAPIService(&request, doc.as<JsonVariant>());
// char data2[] = "{\"action\":\"customSupport\", \"param\":\"hello\"}";
// deserializeJson(doc, data2);
// request.url("/rest/action");
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
char data2[] = "{\"action\":\"getCustomSupport\", \"param\":\"hello\"}";
deserializeJson(doc, data2);
request.url("/rest/action");
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// char data3[] = "{\"action\":\"export\", \"param\":\"schedule\"}";
// deserializeJson(doc, data3);
@@ -1031,11 +1031,11 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// test version checks
// test with "current_version_s = "3.7.1-dev.8" in WebStatusService::checkUpgrade()
request.url("/rest/action");
deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.9,3.7.0\"}"); // is upgradable
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is not upgradable
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// request.url("/rest/action");
// deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.9,3.7.0\"}"); // is upgradable
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is not upgradable
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// test with "current_version_s = "3.6.5" in WebStatusService::checkUpgrade()
// 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
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
// char data6[] = "{\"device\":\"system\", \"cmd\":\"read\",\"value\":\"8 2 27 1\"}";
// deserializeJson(doc, data6);
// json = doc.as<JsonVariant>();

View File

@@ -41,7 +41,7 @@ namespace emsesp {
// #define EMSESP_DEBUG_DEFAULT "310"
// #define EMSESP_DEBUG_DEFAULT "render"
// #define EMSESP_DEBUG_DEFAULT "api"
#define EMSESP_DEBUG_DEFAULT "api3"
// #define EMSESP_DEBUG_DEFAULT "api3"
// #define EMSESP_DEBUG_DEFAULT "crash"
// #define EMSESP_DEBUG_DEFAULT "dv"
// #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) {
ok = exportData(root, param);
}
} else if (action == "customSupport") {
ok = customSupport(root);
} else if (action == "getCustomSupport") {
ok = getCustomSupport(root);
} else if (action == "uploadURL" && is_admin) {
ok = uploadURL(param.c_str());
}
@@ -301,19 +301,28 @@ bool WebStatusService::exportData(JsonObject root, std::string & type) {
return true;
}
// action = customSupport
// action = getCustomSupport
// reads any upload customSupport.json file and sends to to Help page to be shown as Guest
bool WebStatusService::customSupport(JsonObject root) {
#ifndef EMSESP_STANDALONE
bool WebStatusService::getCustomSupport(JsonObject root) {
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
File file = LittleFS.open(EMSESP_CUSTOMSUPPORT_FILE, "r");
if (!file) {
// there is no custom file, return empty object
#if defined(EMSESP_DEBUG)
emsesp::EMSESP::logger().debug("No custom support file found");
#endif
return true;
}
// read the contents of the file into the root output json object
DeserializationError error = deserializeJson(root, file);
// 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(doc, file);
if (error) {
emsesp::EMSESP::logger().err("Failed to read custom support file");
return false;
@@ -321,6 +330,13 @@ bool WebStatusService::customSupport(JsonObject root) {
file.close();
#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;
}

View File

@@ -25,7 +25,7 @@ class WebStatusService {
// actions
bool checkUpgrade(JsonObject root, std::string & latest_version);
bool exportData(JsonObject root, std::string & type);
bool customSupport(JsonObject root);
bool getCustomSupport(JsonObject root);
bool uploadURL(const char * url);
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"
}
}