From f80d03210b27a45fddce27d8d3b347f1b3a8d33e Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Mon, 19 Feb 2024 15:47:59 +0100 Subject: [PATCH 01/66] webapp: update dependencies --- webapp/package.json | 4 ++-- webapp/yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 418eae1aa..795685967 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -29,7 +29,7 @@ "@types/bootstrap": "^5.2.10", "@types/node": "^20.11.19", "@types/pulltorefreshjs": "^0.1.7", - "@types/sortablejs": "^1.15.7", + "@types/sortablejs": "^1.15.8", "@types/spark-md5": "^3.0.4", "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-typescript": "^12.0.0", @@ -39,7 +39,7 @@ "npm-run-all": "^4.1.5", "pulltorefreshjs": "^0.1.22", "sass": "^1.71.0", - "terser": "^5.27.1", + "terser": "^5.27.2", "typescript": "^5.3.3", "vite": "^5.1.3", "vite-plugin-compression": "^0.5.1", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 5e6d47068..b0002b956 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -452,10 +452,10 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367" integrity sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg== -"@types/sortablejs@^1.15.7": - version "1.15.7" - resolved "https://registry.yarnpkg.com/@types/sortablejs/-/sortablejs-1.15.7.tgz#11f85e98fce2854708e5c6d6011f7a236d79ae9f" - integrity sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ== +"@types/sortablejs@^1.15.8": + version "1.15.8" + resolved "https://registry.yarnpkg.com/@types/sortablejs/-/sortablejs-1.15.8.tgz#11ed555076046e00869a5ef85d1e7651e7a66ef6" + integrity sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg== "@types/spark-md5@^3.0.4": version "3.0.4" @@ -2450,10 +2450,10 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -terser@^5.27.1: - version "5.27.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.27.1.tgz#b0092975ea1b379d166088a1a57e32f0839d84a2" - integrity sha512-29wAr6UU/oQpnTw5HoadwjUZnFQXGdOfj0LjZ4sVxzqwHh/QVkvr7m8y9WoR4iN3FRitVduTc6KdjcW38Npsug== +terser@^5.27.2: + version "5.27.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.27.2.tgz#577a362515ff5635f98ba149643793a3973ba77e" + integrity sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" From 9b7df71da03779e4db279998e8eadbe2b77c9c67 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Sun, 25 Feb 2024 11:23:49 +0100 Subject: [PATCH 02/66] webapp: Fix typo Fixes #1780 --- lib/Hoymiles/src/parser/AlarmLogParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Hoymiles/src/parser/AlarmLogParser.cpp b/lib/Hoymiles/src/parser/AlarmLogParser.cpp index 4086f8e38..4bf004abe 100644 --- a/lib/Hoymiles/src/parser/AlarmLogParser.cpp +++ b/lib/Hoymiles/src/parser/AlarmLogParser.cpp @@ -55,7 +55,7 @@ const std::array AlarmLogParser::_alarmMe { AlarmMessageType_t::ALL, 144, "Grid: Grid overfrequency", "Netz: Netzüberfrequenz", "Réseau: Surfréquence du réseau" }, { AlarmMessageType_t::ALL, 145, "Grid: Grid underfrequency", "Netz: Netzunterfrequenz", "Réseau: Sous-fréquence du réseau" }, { AlarmMessageType_t::ALL, 146, "Grid: Rapid grid frequency change rate", "Netz: Schnelle Wechselrate der Netzfrequenz", "Réseau: Taux de fluctuation rapide de la fréquence du réseau" }, - { AlarmMessageType_t::ALL, 147, "Grid: Power grid outage", "Netz: Eletrizitätsnetzausfall", "Réseau: Panne du réseau électrique" }, + { AlarmMessageType_t::ALL, 147, "Grid: Power grid outage", "Netz: Elektrizitätsnetzausfall", "Réseau: Panne du réseau électrique" }, { AlarmMessageType_t::ALL, 148, "Grid: Grid disconnection", "Netz: Netztrennung", "Réseau: Déconnexion du réseau" }, { AlarmMessageType_t::ALL, 149, "Grid: Island detected", "Netz: Inselbetrieb festgestellt", "Réseau: Détection d’îlots" }, @@ -294,4 +294,4 @@ int AlarmLogParser::getTimezoneOffset() gmt = mktime(ptm); return static_cast(difftime(rawtime, gmt)); -} \ No newline at end of file +} From 50abcd10617dcbbc6cf47496d51910a0aad1f1a9 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Fri, 1 Mar 2024 19:30:24 +0100 Subject: [PATCH 03/66] Fix: Prevent hiding text on display if it's too long Fixes: #1797 --- src/Display_Graphic.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index 3c7eaf1df..4433c4342 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -29,11 +29,16 @@ const uint8_t languages[] = { }; static const char* const i18n_offline[] = { "Offline", "Offline", "Offline" }; + static const char* const i18n_current_power_w[] = { "%.0f W", "%.0f W", "%.0f W" }; static const char* const i18n_current_power_kw[] = { "%.1f kW", "%.1f kW", "%.1f kW" }; + static const char* const i18n_yield_today_wh[] = { "today: %4.0f Wh", "Heute: %4.0f Wh", "auj.: %4.0f Wh" }; +static const char* const i18n_yield_today_kwh[] = { "today: %.1f kWh", "Heute: %.1f kWh", "auj.: %.1f kWh" }; + static const char* const i18n_yield_total_kwh[] = { "total: %.1f kWh", "Ges.: %.1f kWh", "total: %.1f kWh" }; static const char* const i18n_yield_total_mwh[] = { "total: %.0f kWh", "Ges.: %.0f kWh", "total: %.0f kWh" }; + static const char* const i18n_date_format[] = { "%m/%d/%Y %H:%M", "%d.%m.%Y %H:%M", "%d/%m/%Y %H:%M" }; DisplayGraphicClass::DisplayGraphicClass() @@ -129,6 +134,10 @@ void DisplayGraphicClass::printText(const char* text, const uint8_t line) offset -= (_isLarge ? 5 : 0); // oscillate around center on large screens dispX += offset; } + + if (dispX > _display->getDisplayWidth()) { + dispX = 0; + } _display->drawStr(dispX, _lineOffsets[line], text); } @@ -237,15 +246,20 @@ void DisplayGraphicClass::loop() //<======================= if (showText) { - //=====> Today & Total Production ======= - snprintf(_fmtText, sizeof(_fmtText), i18n_yield_today_wh[_display_language], Datastore.getTotalAcYieldDayEnabled()); + // Daily production + float wattsToday = Datastore.getTotalAcYieldDayEnabled(); + if (wattsToday >= 10000) { + snprintf(_fmtText, sizeof(_fmtText), i18n_yield_today_kwh[_display_language], wattsToday / 1000); + } else { + snprintf(_fmtText, sizeof(_fmtText), i18n_yield_today_wh[_display_language], wattsToday); + } printText(_fmtText, 1); - const float watts = Datastore.getTotalAcYieldTotalEnabled(); - auto const format = (watts >= 1000) ? i18n_yield_total_mwh : i18n_yield_total_kwh; - snprintf(_fmtText, sizeof(_fmtText), format[_display_language], watts); + // Total production + const float wattsTotal = Datastore.getTotalAcYieldTotalEnabled(); + auto const format = (wattsTotal >= 1000) ? i18n_yield_total_mwh : i18n_yield_total_kwh; + snprintf(_fmtText, sizeof(_fmtText), format[_display_language], wattsTotal); printText(_fmtText, 2); - //<======================= //=====> IP or Date-Time ======== // Change every 3 seconds From 021d9b5f44c499f309e28c60c3e797b3f1237e0d Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Fri, 1 Mar 2024 19:31:47 +0100 Subject: [PATCH 04/66] Feature: Added description for alarm id 152 Fixes: #1798 --- lib/Hoymiles/src/parser/AlarmLogParser.cpp | 1 + lib/Hoymiles/src/parser/AlarmLogParser.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Hoymiles/src/parser/AlarmLogParser.cpp b/lib/Hoymiles/src/parser/AlarmLogParser.cpp index 4bf004abe..652159002 100644 --- a/lib/Hoymiles/src/parser/AlarmLogParser.cpp +++ b/lib/Hoymiles/src/parser/AlarmLogParser.cpp @@ -60,6 +60,7 @@ const std::array AlarmLogParser::_alarmMe { AlarmMessageType_t::ALL, 149, "Grid: Island detected", "Netz: Inselbetrieb festgestellt", "Réseau: Détection d’îlots" }, { AlarmMessageType_t::ALL, 150, "DCI exceeded", "", "" }, + { AlarmMessageType_t::ALL, 152, "Grid: Phase angle difference between two phases exceeded 5° >10 times", "", "" }, { AlarmMessageType_t::HMT, 171, "Grid: Abnormal phase difference between phase to phase", "", "" }, { AlarmMessageType_t::ALL, 181, "Abnormal insulation impedance", "", "" }, { AlarmMessageType_t::ALL, 182, "Abnormal grounding", "", "" }, diff --git a/lib/Hoymiles/src/parser/AlarmLogParser.h b/lib/Hoymiles/src/parser/AlarmLogParser.h index a6f0c10c6..87413ce7a 100644 --- a/lib/Hoymiles/src/parser/AlarmLogParser.h +++ b/lib/Hoymiles/src/parser/AlarmLogParser.h @@ -8,7 +8,7 @@ #define ALARM_LOG_ENTRY_SIZE 12 #define ALARM_LOG_PAYLOAD_SIZE (ALARM_LOG_ENTRY_COUNT * ALARM_LOG_ENTRY_SIZE + 4) -#define ALARM_MSG_COUNT 130 +#define ALARM_MSG_COUNT 131 struct AlarmLogEntry_t { uint16_t MessageId; @@ -62,4 +62,4 @@ class AlarmLogParser : public Parser { AlarmMessageType_t _messageType = AlarmMessageType_t::ALL; static const std::array _alarmMessages; -}; \ No newline at end of file +}; From 3c2b35016aefeb6a501d9d0bc2e0db3f725cd6bb Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Fri, 1 Mar 2024 19:36:18 +0100 Subject: [PATCH 05/66] webapp: update dependencies --- webapp/package.json | 20 +-- webapp/yarn.lock | 309 ++++++++++++++++++++++---------------------- 2 files changed, 166 insertions(+), 163 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 795685967..102cf7152 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -13,35 +13,35 @@ }, "dependencies": { "@popperjs/core": "^2.11.8", - "bootstrap": "^5.3.2", + "bootstrap": "^5.3.3", "bootstrap-icons-vue": "^1.11.3", "mitt": "^3.0.1", "sortablejs": "^1.15.2", "spark-md5": "^3.0.2", - "vue": "^3.4.19", - "vue-i18n": "^9.9.1", - "vue-router": "^4.2.5" + "vue": "^3.4.21", + "vue-i18n": "^9.10.1", + "vue-router": "^4.3.0" }, "devDependencies": { "@intlify/unplugin-vue-i18n": "^2.0.0", "@rushstack/eslint-patch": "^1.7.2", "@tsconfig/node18": "^18.2.2", "@types/bootstrap": "^5.2.10", - "@types/node": "^20.11.19", + "@types/node": "^20.11.24", "@types/pulltorefreshjs": "^0.1.7", "@types/sortablejs": "^1.15.8", "@types/spark-md5": "^3.0.4", "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-typescript": "^12.0.0", "@vue/tsconfig": "^0.5.1", - "eslint": "^8.56.0", - "eslint-plugin-vue": "^9.21.1", + "eslint": "^8.57.0", + "eslint-plugin-vue": "^9.22.0", "npm-run-all": "^4.1.5", "pulltorefreshjs": "^0.1.22", - "sass": "^1.71.0", - "terser": "^5.27.2", + "sass": "^1.71.1", + "terser": "^5.28.1", "typescript": "^5.3.3", - "vite": "^5.1.3", + "vite": "^5.1.4", "vite-plugin-compression": "^0.5.1", "vite-plugin-css-injected-by-js": "^3.4.0", "vue-tsc": "^1.8.27" diff --git a/webapp/yarn.lock b/webapp/yarn.lock index b0002b956..74da0aef8 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -171,18 +171,18 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.56.0": - version "8.56.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" - integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== - -"@humanwhocodes/config-array@^0.11.13": - version "0.11.13" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" - integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== - dependencies: - "@humanwhocodes/object-schema" "^2.0.1" - debug "^4.1.1" +"@eslint/js@8.57.0": + version "8.57.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" + integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== + +"@humanwhocodes/config-array@^0.11.14": + version "0.11.14" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== + dependencies: + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" minimatch "^3.0.5" "@humanwhocodes/module-importer@^1.0.1": @@ -190,10 +190,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" - integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" + integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== "@intlify/bundle-utils@^7.4.0": version "7.4.0" @@ -211,20 +211,20 @@ source-map-js "^1.0.1" yaml-eslint-parser "^1.2.2" -"@intlify/core-base@9.9.1": - version "9.9.1" - resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.9.1.tgz#97ff0a98bf416c3f895e2a4fbcb0da353326b71a" - integrity sha512-qsV15dg7jNX2faBRyKMgZS8UcFJViWEUPLdzZ9UR0kQZpFVeIpc0AG7ZOfeP7pX2T9SQ5jSiorq/tii9nkkafA== +"@intlify/core-base@9.10.1": + version "9.10.1" + resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.10.1.tgz#e61d507d35beb0c69f9c94566313f9520c25a84a" + integrity sha512-0+Wtjj04GIyglh5KKiNjRwgjpHrhqqGZhaKY/QVjjogWKZq5WHROrTi84pNVsRN18QynyPmjtsVUWqFKPQ45xQ== dependencies: - "@intlify/message-compiler" "9.9.1" - "@intlify/shared" "9.9.1" + "@intlify/message-compiler" "9.10.1" + "@intlify/shared" "9.10.1" -"@intlify/message-compiler@9.9.1": - version "9.9.1" - resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.9.1.tgz#4cd9c5a408be27784928e4cd57a77ea6ddb17e56" - integrity sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA== +"@intlify/message-compiler@9.10.1": + version "9.10.1" + resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.10.1.tgz#d70c9ec211dab67d50a42ad1fb782c0e02f89c42" + integrity sha512-b68UTmRhgZfswJZI7VAgW6BXZK5JOpoi5swMLGr4j6ss2XbFY13kiw+Hu+xYAfulMPSapcHzdWHnq21VGnMCnA== dependencies: - "@intlify/shared" "9.9.1" + "@intlify/shared" "9.10.1" source-map-js "^1.0.2" "@intlify/message-compiler@^9.4.0": @@ -235,16 +235,16 @@ "@intlify/shared" "9.4.0" source-map-js "^1.0.2" +"@intlify/shared@9.10.1": + version "9.10.1" + resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.10.1.tgz#024ad6dd4ee9581962437570b3dc25516c82f4e9" + integrity sha512-liyH3UMoglHBUn70iCYcy9CQlInx/lp50W2aeSxqqrvmG+LDj/Jj7tBJhBoQL4fECkldGhbmW0g2ommHfL6Wmw== + "@intlify/shared@9.4.0", "@intlify/shared@^9.4.0": version "9.4.0" resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.4.0.tgz#4a78d462fc82433db900981e12eb5b1aae3d6085" integrity sha512-AFqymip2kToqA0B6KZPg5jSrdcVHoli9t/VhGKE2iiMq9utFuMoGdDC/JOCIZgwxo6aXAk86QyU2XtzEoMuZ6A== -"@intlify/shared@9.9.1": - version "9.9.1" - resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.9.1.tgz#b602d012b35f6c336b29a8098296dfac96a005f5" - integrity sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA== - "@intlify/unplugin-vue-i18n@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-2.0.0.tgz#5b087e17b4eb4381d0a111cd89df4037880e932f" @@ -435,10 +435,10 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== -"@types/node@^20.11.19": - version "20.11.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.19.tgz#b466de054e9cb5b3831bee38938de64ac7f81195" - integrity sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ== +"@types/node@^20.11.24": + version "20.11.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.24.tgz#cc207511104694e84e9fb17f9a0c4c42d4517792" + integrity sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long== dependencies: undici-types "~5.26.4" @@ -599,13 +599,13 @@ estree-walker "^2.0.2" source-map-js "^1.0.2" -"@vue/compiler-core@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.19.tgz#3161b1ede69da00f3ce8155dfab907a3eaa0515e" - integrity sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w== +"@vue/compiler-core@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz#868b7085378fc24e58c9aed14c8d62110a62be1a" + integrity sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og== dependencies: "@babel/parser" "^7.23.9" - "@vue/shared" "3.4.19" + "@vue/shared" "3.4.21" entities "^4.5.0" estree-walker "^2.0.2" source-map-js "^1.0.2" @@ -618,13 +618,13 @@ "@vue/compiler-core" "3.2.47" "@vue/shared" "3.2.47" -"@vue/compiler-dom@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz#2457e57e978f431e3b5fd11fc50a3e92d5816f9a" - integrity sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA== +"@vue/compiler-dom@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz#0077c355e2008207283a5a87d510330d22546803" + integrity sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA== dependencies: - "@vue/compiler-core" "3.4.19" - "@vue/shared" "3.4.19" + "@vue/compiler-core" "3.4.21" + "@vue/shared" "3.4.21" "@vue/compiler-dom@^3.3.0": version "3.3.2" @@ -634,19 +634,19 @@ "@vue/compiler-core" "3.3.2" "@vue/shared" "3.3.2" -"@vue/compiler-sfc@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz#33b238ded6d63e51f6a7048b742626f6007df129" - integrity sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg== +"@vue/compiler-sfc@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz#4af920dc31ab99e1ff5d152b5fe0ad12181145b2" + integrity sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ== dependencies: "@babel/parser" "^7.23.9" - "@vue/compiler-core" "3.4.19" - "@vue/compiler-dom" "3.4.19" - "@vue/compiler-ssr" "3.4.19" - "@vue/shared" "3.4.19" + "@vue/compiler-core" "3.4.21" + "@vue/compiler-dom" "3.4.21" + "@vue/compiler-ssr" "3.4.21" + "@vue/shared" "3.4.21" estree-walker "^2.0.2" - magic-string "^0.30.6" - postcss "^8.4.33" + magic-string "^0.30.7" + postcss "^8.4.35" source-map-js "^1.0.2" "@vue/compiler-sfc@^3.2.47": @@ -673,19 +673,24 @@ "@vue/compiler-dom" "3.2.47" "@vue/shared" "3.2.47" -"@vue/compiler-ssr@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz#1f8ee06005ebbaa354f8783fad84e9f7ea4a69c2" - integrity sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw== +"@vue/compiler-ssr@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz#b84ae64fb9c265df21fc67f7624587673d324fef" + integrity sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q== dependencies: - "@vue/compiler-dom" "3.4.19" - "@vue/shared" "3.4.19" + "@vue/compiler-dom" "3.4.21" + "@vue/shared" "3.4.21" "@vue/devtools-api@^6.5.0": version "6.5.0" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07" integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q== +"@vue/devtools-api@^6.5.1": + version "6.6.1" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.1.tgz#7c14346383751d9f6ad4bea0963245b30220ef83" + integrity sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA== + "@vue/eslint-config-typescript@^12.0.0": version "12.0.0" resolved "https://registry.yarnpkg.com/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz#0ce22d97af5e4155f3f2e7b21a48cfde8a6f3365" @@ -721,37 +726,37 @@ estree-walker "^2.0.2" magic-string "^0.25.7" -"@vue/reactivity@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.19.tgz#8cf335d97d07881d8184cb23289289dc18b03f60" - integrity sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA== +"@vue/reactivity@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.21.tgz#affd3415115b8ebf4927c8d2a0d6a24bccfa9f02" + integrity sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw== dependencies: - "@vue/shared" "3.4.19" + "@vue/shared" "3.4.21" -"@vue/runtime-core@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.19.tgz#ef10357fdf3afdf68523b55424541000105e2aeb" - integrity sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw== +"@vue/runtime-core@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz#3749c3f024a64c4c27ecd75aea4ca35634db0062" + integrity sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA== dependencies: - "@vue/reactivity" "3.4.19" - "@vue/shared" "3.4.19" + "@vue/reactivity" "3.4.21" + "@vue/shared" "3.4.21" -"@vue/runtime-dom@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz#079141e31d9f47515b9595f29843d51011f88739" - integrity sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g== +"@vue/runtime-dom@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz#91f867ef64eff232cac45095ab28ebc93ac74588" + integrity sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw== dependencies: - "@vue/runtime-core" "3.4.19" - "@vue/shared" "3.4.19" + "@vue/runtime-core" "3.4.21" + "@vue/shared" "3.4.21" csstype "^3.1.3" -"@vue/server-renderer@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.19.tgz#e6f8ff5268d0758766ca9835375218924d5f0eb6" - integrity sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw== +"@vue/server-renderer@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz#150751579d26661ee3ed26a28604667fa4222a97" + integrity sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg== dependencies: - "@vue/compiler-ssr" "3.4.19" - "@vue/shared" "3.4.19" + "@vue/compiler-ssr" "3.4.21" + "@vue/shared" "3.4.21" "@vue/shared@3.2.47": version "3.2.47" @@ -763,10 +768,10 @@ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.2.tgz#774cd9b4635ce801b70a3fc3713779a5ef5d77c3" integrity sha512-0rFu3h8JbclbnvvKrs7Fe5FNGV9/5X2rPD7KmOzhLSUAiQH5//Hq437Gv0fR5Mev3u/nbtvmLl8XgwCU20/ZfQ== -"@vue/shared@3.4.19": - version "3.4.19" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.19.tgz#28105147811bcf1e6612bf1c9ab0c6d91ada019c" - integrity sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw== +"@vue/shared@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.21.tgz#de526a9059d0a599f0b429af7037cd0c3ed7d5a1" + integrity sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g== "@vue/tsconfig@^0.5.1": version "0.5.1" @@ -860,10 +865,10 @@ bootstrap-icons-vue@^1.11.3: resolved "https://registry.yarnpkg.com/bootstrap-icons-vue/-/bootstrap-icons-vue-1.11.3.tgz#717745c433b2043d6d1ec24260b9bbc9eea16c66" integrity sha512-Xba1GTDYon8KYSDTKiiAtiyfk4clhdKQYvCQPMkE58+F5loVwEmh0Wi+ECCfowNc9SGwpoSLpSkvg7rhgZBttw== -bootstrap@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.2.tgz#97226583f27aae93b2b28ab23f4c114757ff16ae" - integrity sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g== +bootstrap@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.3.tgz#de35e1a765c897ac940021900fcbb831602bac38" + integrity sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg== brace-expansion@^1.1.7: version "1.1.11" @@ -1011,7 +1016,7 @@ de-indent@^1.0.2: resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== -debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1146,16 +1151,16 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-plugin-vue@^9.21.1: - version "9.21.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz#da5629efa48527cec98278dca0daa90fada4caf7" - integrity sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw== +eslint-plugin-vue@^9.22.0: + version "9.22.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.22.0.tgz#e8a625adb0b6ce3b65635dd74fec8345146f8e26" + integrity sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg== dependencies: "@eslint-community/eslint-utils" "^4.4.0" natural-compare "^1.4.0" nth-check "^2.1.1" - postcss-selector-parser "^6.0.13" - semver "^7.5.4" + postcss-selector-parser "^6.0.15" + semver "^7.6.0" vue-eslint-parser "^9.4.2" xml-name-validator "^4.0.0" @@ -1190,16 +1195,16 @@ eslint-visitor-keys@^3.4.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== -eslint@^8.56.0: - version "8.56.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" - integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== +eslint@^8.57.0: + version "8.57.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" + integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.56.0" - "@humanwhocodes/config-array" "^0.11.13" + "@eslint/js" "8.57.0" + "@humanwhocodes/config-array" "^0.11.14" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" "@ungap/structured-clone" "^1.2.0" @@ -1834,7 +1839,7 @@ magic-string@^0.30.0: dependencies: "@jridgewell/sourcemap-codec" "^1.4.13" -magic-string@^0.30.6: +magic-string@^0.30.7: version "0.30.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.7.tgz#0cecd0527d473298679da95a2d7aeb8c64048505" integrity sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA== @@ -2111,10 +2116,10 @@ pkg-types@^1.0.3: mlly "^1.2.0" pathe "^1.1.0" -postcss-selector-parser@^6.0.13: - version "6.0.13" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" - integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== +postcss-selector-parser@^6.0.15: + version "6.0.15" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz#11cc2b21eebc0b99ea374ffb9887174855a01535" + integrity sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -2128,15 +2133,6 @@ postcss@^8.1.10: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.4.33: - version "8.4.33" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.33.tgz#1378e859c9f69bf6f638b990a0212f43e2aaa742" - integrity sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.0.2" - postcss@^8.4.35: version "8.4.35" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7" @@ -2257,10 +2253,10 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -sass@^1.71.0: - version "1.71.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.71.0.tgz#b3085759b9b2ab503a977aecb7e91153bf941117" - integrity sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w== +sass@^1.71.1: + version "1.71.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.71.1.tgz#dfb09c63ce63f89353777bbd4a88c0a38386ee54" + integrity sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -2285,6 +2281,13 @@ semver@^7.3.6: dependencies: lru-cache "^6.0.0" +semver@^7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -2450,10 +2453,10 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -terser@^5.27.2: - version "5.27.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.27.2.tgz#577a362515ff5635f98ba149643793a3973ba77e" - integrity sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w== +terser@^5.28.1: + version "5.28.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.28.1.tgz#bf00f7537fd3a798c352c2d67d67d65c915d1b28" + integrity sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -2570,10 +2573,10 @@ vite-plugin-css-injected-by-js@^3.4.0: resolved "https://registry.yarnpkg.com/vite-plugin-css-injected-by-js/-/vite-plugin-css-injected-by-js-3.4.0.tgz#b09a571ab50744623736a4b056ecc85d7516311a" integrity sha512-wS5+UYtJXQ/vNornsqTQxOLBVO/UjXU54ZsYMeX0mj2OrbStMQ4GLgvneVDQGPwyGJcm/ntBPawc2lA7xx+Lpg== -vite@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.3.tgz#dd072653a80225702265550a4700561740dfde55" - integrity sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew== +vite@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.4.tgz#14e9d3e7a6e488f36284ef13cebe149f060bcfb6" + integrity sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg== dependencies: esbuild "^0.19.3" postcss "^8.4.35" @@ -2607,21 +2610,21 @@ vue-eslint-parser@^9.4.2: lodash "^4.17.21" semver "^7.3.6" -vue-i18n@^9.9.1: - version "9.9.1" - resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.9.1.tgz#3c2fdf3c9db430572a1246439d541d01e2795c06" - integrity sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw== +vue-i18n@^9.10.1: + version "9.10.1" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.10.1.tgz#b3244233da31a55a07a2ae72cdddab7296bca814" + integrity sha512-37HVJQZ/pZaRXGzFmmMomM1u1k7kndv3xCBPYHKEVfv5W3UVK67U/TpBug71ILYLNmjHLHdvTUPRF81pFT5fFg== dependencies: - "@intlify/core-base" "9.9.1" - "@intlify/shared" "9.9.1" + "@intlify/core-base" "9.10.1" + "@intlify/shared" "9.10.1" "@vue/devtools-api" "^6.5.0" -vue-router@^4.2.5: - version "4.2.5" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.2.5.tgz#b9e3e08f1bd9ea363fdd173032620bc50cf0e98a" - integrity sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw== +vue-router@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.3.0.tgz#d5913f27bf68a0a178ee798c3c88be471811a235" + integrity sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ== dependencies: - "@vue/devtools-api" "^6.5.0" + "@vue/devtools-api" "^6.5.1" vue-template-compiler@^2.7.14: version "2.7.14" @@ -2640,16 +2643,16 @@ vue-tsc@^1.8.27: "@vue/language-core" "1.8.27" semver "^7.5.4" -vue@^3.4.19: - version "3.4.19" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.19.tgz#f9ae0a44db86628548736ff04152830726a97263" - integrity sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw== +vue@^3.4.21: + version "3.4.21" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.21.tgz#69ec30e267d358ee3a0ce16612ba89e00aaeb731" + integrity sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA== dependencies: - "@vue/compiler-dom" "3.4.19" - "@vue/compiler-sfc" "3.4.19" - "@vue/runtime-dom" "3.4.19" - "@vue/server-renderer" "3.4.19" - "@vue/shared" "3.4.19" + "@vue/compiler-dom" "3.4.21" + "@vue/compiler-sfc" "3.4.21" + "@vue/runtime-dom" "3.4.21" + "@vue/server-renderer" "3.4.21" + "@vue/shared" "3.4.21" webpack-sources@^3.2.3: version "3.2.3" From b8c1168687221d026ee116c5690741a373c7a081 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Sun, 3 Mar 2024 16:35:34 +0100 Subject: [PATCH 06/66] Fix: Exclude hardware part number 124097 from valid part numbers. This triggers a re-fetch of the hardware information. Especially 124097 seems to be a wrong read-out. --- lib/Hoymiles/src/parser/DevInfoParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Hoymiles/src/parser/DevInfoParser.cpp b/lib/Hoymiles/src/parser/DevInfoParser.cpp index b2b30a2e8..08970ff13 100644 --- a/lib/Hoymiles/src/parser/DevInfoParser.cpp +++ b/lib/Hoymiles/src/parser/DevInfoParser.cpp @@ -200,7 +200,7 @@ bool DevInfoParser::containsValidData() const struct tm info; localtime_r(&t, &info); - return info.tm_year > (2016 - 1900); + return info.tm_year > (2016 - 1900) || getHwPartNumber() == 124097; } uint8_t DevInfoParser::getDevIdx() const From 10cd2e4201c69e42d6d118eb44c05fdfaa174ca0 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Mon, 4 Mar 2024 19:09:26 +0100 Subject: [PATCH 07/66] webapp: update dependencies --- webapp/package.json | 2 +- webapp/yarn.lock | 98 ++++++++++++++++----------------------------- 2 files changed, 35 insertions(+), 65 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 102cf7152..1a42b8ee7 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -44,6 +44,6 @@ "vite": "^5.1.4", "vite-plugin-compression": "^0.5.1", "vite-plugin-css-injected-by-js": "^3.4.0", - "vue-tsc": "^1.8.27" + "vue-tsc": "^2.0.4" } } diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 74da0aef8..2cde79a07 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -12,11 +12,6 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== -"@babel/parser@^7.21.3": - version "7.21.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8" - integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA== - "@babel/parser@^7.23.9": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" @@ -557,26 +552,26 @@ resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37" integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ== -"@volar/language-core@1.11.1", "@volar/language-core@~1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-1.11.1.tgz#ecdf12ea8dc35fb8549e517991abcbf449a5ad4f" - integrity sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw== +"@volar/language-core@2.1.0", "@volar/language-core@~2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.1.0.tgz#26953a62f5d956a4ba4003faf59ae09b2a8aabb6" + integrity sha512-BrYEgYHx92ocpt1OUxJs2x3TAXEjpPLxsQoARb96g2GdF62xnfRQUqCNBwiU7Z3MQ/0tOAdqdHNYNmrFtx6q4A== dependencies: - "@volar/source-map" "1.11.1" + "@volar/source-map" "2.1.0" -"@volar/source-map@1.11.1", "@volar/source-map@~1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-1.11.1.tgz#535b0328d9e2b7a91dff846cab4058e191f4452f" - integrity sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg== +"@volar/source-map@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.1.0.tgz#f8c70b5043ae4a3d2cbd66a84036ef030b655a8e" + integrity sha512-VPyi+DTv67cvUOkUewzsOQJY3VUhjOjQxigT487z/H7tEI8ZFd5RksC5afk3JelOK+a/3Y8LRDbKmYKu1dz87g== dependencies: - muggle-string "^0.3.1" + muggle-string "^0.4.0" -"@volar/typescript@~1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-1.11.1.tgz#ba86c6f326d88e249c7f5cfe4b765be3946fd627" - integrity sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ== +"@volar/typescript@~2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.1.0.tgz#640abcdcb6b822f9860006d090e1d5252c655e37" + integrity sha512-2cicVoW4q6eU/omqfOBv+6r9JdrF5bBelujbJhayPNKiOj/xwotSJ/DM8IeMvTZvtkOZkm6suyOCLEokLY0w2w== dependencies: - "@volar/language-core" "1.11.1" + "@volar/language-core" "2.1.0" path-browserify "^1.0.1" "@vue/compiler-core@3.2.47": @@ -589,16 +584,6 @@ estree-walker "^2.0.2" source-map "^0.6.1" -"@vue/compiler-core@3.3.2": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.2.tgz#39567bd15c7f97add97bfc4d44e814df36eb797b" - integrity sha512-CKZWo1dzsQYTNTft7whzjL0HsrEpMfiK7pjZ2WFE3bC1NA7caUjWioHSK+49y/LK7Bsm4poJZzAMnvZMQ7OTeg== - dependencies: - "@babel/parser" "^7.21.3" - "@vue/shared" "3.3.2" - estree-walker "^2.0.2" - source-map-js "^1.0.2" - "@vue/compiler-core@3.4.21": version "3.4.21" resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz#868b7085378fc24e58c9aed14c8d62110a62be1a" @@ -618,7 +603,7 @@ "@vue/compiler-core" "3.2.47" "@vue/shared" "3.2.47" -"@vue/compiler-dom@3.4.21": +"@vue/compiler-dom@3.4.21", "@vue/compiler-dom@^3.4.0": version "3.4.21" resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz#0077c355e2008207283a5a87d510330d22546803" integrity sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA== @@ -626,14 +611,6 @@ "@vue/compiler-core" "3.4.21" "@vue/shared" "3.4.21" -"@vue/compiler-dom@^3.3.0": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.2.tgz#2012ef4879375a4ca4ee68012a9256398b848af2" - integrity sha512-6gS3auANuKXLw0XH6QxkWqyPYPunziS2xb6VRenM3JY7gVfZcJvkCBHkb5RuNY1FCbBO3lkIi0CdXUCW1c7SXw== - dependencies: - "@vue/compiler-core" "3.3.2" - "@vue/shared" "3.3.2" - "@vue/compiler-sfc@3.4.21": version "3.4.21" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz#4af920dc31ab99e1ff5d152b5fe0ad12181145b2" @@ -700,18 +677,16 @@ "@typescript-eslint/parser" "^6.7.0" vue-eslint-parser "^9.3.1" -"@vue/language-core@1.8.27": - version "1.8.27" - resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-1.8.27.tgz#2ca6892cb524e024a44e554e4c55d7a23e72263f" - integrity sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA== +"@vue/language-core@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.0.4.tgz#324ae3de55d34f926f43b85901f60a33c3c63211" + integrity sha512-IYlVEICXKRWYjRQ4JyPlXhydU/p0C7uY5LpqXyJzzJHWo44LWHZtTP3USfWNQif3VAK5QZpdZKQ5HYIeQL3BJQ== dependencies: - "@volar/language-core" "~1.11.1" - "@volar/source-map" "~1.11.1" - "@vue/compiler-dom" "^3.3.0" - "@vue/shared" "^3.3.0" + "@volar/language-core" "~2.1.0" + "@vue/compiler-dom" "^3.4.0" + "@vue/shared" "^3.4.0" computeds "^0.0.1" minimatch "^9.0.3" - muggle-string "^0.3.1" path-browserify "^1.0.1" vue-template-compiler "^2.7.14" @@ -763,12 +738,7 @@ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.47.tgz#e597ef75086c6e896ff5478a6bfc0a7aa4bbd14c" integrity sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ== -"@vue/shared@3.3.2", "@vue/shared@^3.3.0": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.2.tgz#774cd9b4635ce801b70a3fc3713779a5ef5d77c3" - integrity sha512-0rFu3h8JbclbnvvKrs7Fe5FNGV9/5X2rPD7KmOzhLSUAiQH5//Hq437Gv0fR5Mev3u/nbtvmLl8XgwCU20/ZfQ== - -"@vue/shared@3.4.21": +"@vue/shared@3.4.21", "@vue/shared@^3.4.0": version "3.4.21" resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.21.tgz#de526a9059d0a599f0b429af7037cd0c3ed7d5a1" integrity sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g== @@ -1898,10 +1868,10 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -muggle-string@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.3.1.tgz#e524312eb1728c63dd0b2ac49e3282e6ed85963a" - integrity sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg== +muggle-string@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328" + integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ== nanoid@^3.3.4: version "3.3.4" @@ -2634,13 +2604,13 @@ vue-template-compiler@^2.7.14: de-indent "^1.0.2" he "^1.2.0" -vue-tsc@^1.8.27: - version "1.8.27" - resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-1.8.27.tgz#feb2bb1eef9be28017bb9e95e2bbd1ebdd48481c" - integrity sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg== +vue-tsc@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-2.0.4.tgz#23f0e642e27720484f3c549ab61a202ed6b82ef4" + integrity sha512-FJk+F1QhqROr6DK8raTuWk5ezNw1/kZ+7TYhc08k+cpvb1fmi7wguPZHX0svIhT4bAxCGDtF8534It8fiAkScg== dependencies: - "@volar/typescript" "~1.11.1" - "@vue/language-core" "1.8.27" + "@volar/typescript" "~2.1.0" + "@vue/language-core" "2.0.4" semver "^7.5.4" vue@^3.4.21: From f995287a6e721d5be06d9bdedfb354f76be2eaf6 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Wed, 6 Mar 2024 21:57:18 +0100 Subject: [PATCH 08/66] Feature: Add support for HERF inverters --- README.md | 3 + lib/Hoymiles/src/Hoymiles.cpp | 10 +- lib/Hoymiles/src/inverters/HERF_2CH.cpp | 62 ++++++++++++ lib/Hoymiles/src/inverters/HERF_2CH.h | 13 +++ lib/Hoymiles/src/inverters/HERF_4CH.cpp | 20 ++++ lib/Hoymiles/src/inverters/HERF_4CH.h | 11 +++ lib/Hoymiles/src/inverters/README.md | 2 + lib/Hoymiles/src/parser/DevInfoParser.cpp | 6 +- src/WebApi_dtu.cpp | 8 +- src/WebApi_inverter.cpp | 14 ++- src/WebApi_limit.cpp | 6 +- src/WebApi_power.cpp | 6 +- webapp/src/components/InputSerial.vue | 114 ++++++++++++++++++++++ webapp/src/locales/de.json | 7 ++ webapp/src/locales/en.json | 7 ++ webapp/src/locales/fr.json | 7 ++ webapp/src/types/DevInfoStatus.ts | 4 +- webapp/src/types/InverterConfig.ts | 2 +- webapp/src/types/LimitConfig.ts | 4 +- webapp/src/types/LiveDataStatus.ts | 4 +- webapp/src/views/HomeView.vue | 16 +-- webapp/src/views/InverterAdminView.vue | 7 +- 22 files changed, 301 insertions(+), 32 deletions(-) create mode 100644 lib/Hoymiles/src/inverters/HERF_2CH.cpp create mode 100644 lib/Hoymiles/src/inverters/HERF_2CH.h create mode 100644 lib/Hoymiles/src/inverters/HERF_4CH.cpp create mode 100644 lib/Hoymiles/src/inverters/HERF_4CH.h create mode 100644 webapp/src/components/InputSerial.vue diff --git a/README.md b/README.md index 365f0efc6..cb9f4ef48 100644 --- a/README.md +++ b/README.md @@ -75,3 +75,6 @@ Generated using: `git log --date=short --pretty=format:"* %h%x09%ad%x09%s" | gre | TSUN TSOL-M350 | NRF24L01+ | 1 | 1 | 1 | | TSUN TSOL-M800 | NRF24L01+ | 2 | 2 | 1 | | TSUN TSOL-M1600 | NRF24L01+ | 4 | 2 | 1 | +| E-Star HERF-800 | NRF24L01+ | 2 | 2 | 1 | +| E-Star HERF-1600 | NRF24L01+ | 4 | 2 | 1 | +| E-Star HERF-1800 | NRF24L01+ | 4 | 2 | 1 | diff --git a/lib/Hoymiles/src/Hoymiles.cpp b/lib/Hoymiles/src/Hoymiles.cpp index e7b3d2632..eda3500b5 100644 --- a/lib/Hoymiles/src/Hoymiles.cpp +++ b/lib/Hoymiles/src/Hoymiles.cpp @@ -1,9 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * Copyright (C) 2022-2023 Thomas Basler and others + * Copyright (C) 2022-2024 Thomas Basler and others */ #include "Hoymiles.h" #include "Utils.h" +#include "inverters/HERF_2CH.h" +#include "inverters/HERF_4CH.h" #include "inverters/HMS_1CH.h" #include "inverters/HMS_1CHv2.h" #include "inverters/HMS_2CH.h" @@ -168,6 +170,10 @@ std::shared_ptr HoymilesClass::addInverter(const char* name, c i = std::make_shared(_radioNrf.get(), serial); } else if (HM_1CH::isValidSerial(serial)) { i = std::make_shared(_radioNrf.get(), serial); + } else if (HERF_2CH::isValidSerial(serial)) { + i = std::make_shared(_radioNrf.get(), serial); + } else if (HERF_4CH::isValidSerial(serial)) { + i = std::make_shared(_radioNrf.get(), serial); } if (i) { @@ -271,4 +277,4 @@ void HoymilesClass::setMessageOutput(Print* output) Print* HoymilesClass::getMessageOutput() { return _messageOutput; -} \ No newline at end of file +} diff --git a/lib/Hoymiles/src/inverters/HERF_2CH.cpp b/lib/Hoymiles/src/inverters/HERF_2CH.cpp new file mode 100644 index 000000000..37799d14b --- /dev/null +++ b/lib/Hoymiles/src/inverters/HERF_2CH.cpp @@ -0,0 +1,62 @@ + +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022-2024 Thomas Basler and others + */ +#include "HERF_2CH.h" + +static const byteAssign_t byteAssignment[] = { + { TYPE_DC, CH0, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, + { TYPE_DC, CH0, FLD_IDC, UNIT_A, 6, 2, 100, false, 2 }, + { TYPE_DC, CH0, FLD_PDC, UNIT_W, 10, 2, 10, false, 1 }, + { TYPE_DC, CH0, FLD_YD, UNIT_WH, 22, 2, 1, false, 0 }, + { TYPE_DC, CH0, FLD_YT, UNIT_KWH, 14, 4, 1000, false, 3 }, + { TYPE_DC, CH0, FLD_IRR, UNIT_PCT, CALC_CH_IRR, CH0, CMD_CALC, false, 3 }, + + { TYPE_DC, CH1, FLD_UDC, UNIT_V, 4, 2, 10, false, 1 }, + { TYPE_DC, CH1, FLD_IDC, UNIT_A, 8, 2, 100, false, 2 }, + { TYPE_DC, CH1, FLD_PDC, UNIT_W, 12, 2, 10, false, 1 }, + { TYPE_DC, CH1, FLD_YD, UNIT_WH, 24, 2, 1, false, 0 }, + { TYPE_DC, CH1, FLD_YT, UNIT_KWH, 18, 4, 1000, false, 3 }, + { TYPE_DC, CH1, FLD_IRR, UNIT_PCT, CALC_CH_IRR, CH1, CMD_CALC, false, 3 }, + + { TYPE_AC, CH0, FLD_UAC, UNIT_V, 26, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_IAC, UNIT_A, 34, 2, 100, false, 2 }, + { TYPE_AC, CH0, FLD_PAC, UNIT_W, 30, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_Q, UNIT_VAR, 32, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_F, UNIT_HZ, 28, 2, 100, false, 2 }, + { TYPE_AC, CH0, FLD_PF, UNIT_NONE, 36, 2, 1000, false, 3 }, + + { TYPE_INV, CH0, FLD_T, UNIT_C, 38, 2, 10, true, 1 }, + { TYPE_INV, CH0, FLD_EVT_LOG, UNIT_NONE, 40, 2, 1, false, 0 }, + + { TYPE_INV, CH0, FLD_YD, UNIT_WH, CALC_TOTAL_YD, 0, CMD_CALC, false, 0 }, + { TYPE_INV, CH0, FLD_YT, UNIT_KWH, CALC_TOTAL_YT, 0, CMD_CALC, false, 3 }, + { TYPE_INV, CH0, FLD_PDC, UNIT_W, CALC_TOTAL_PDC, 0, CMD_CALC, false, 1 }, + { TYPE_INV, CH0, FLD_EFF, UNIT_PCT, CALC_TOTAL_EFF, 0, CMD_CALC, false, 3 } +}; + +HERF_2CH::HERF_2CH(HoymilesRadio* radio, const uint64_t serial) + : HM_Abstract(radio, serial) {}; + +bool HERF_2CH::isValidSerial(const uint64_t serial) +{ + // serial >= 0x282100000000 && serial <= 0x282199999999 + uint16_t preSerial = (serial >> 32) & 0xffff; + return preSerial == 0x2821; +} + +String HERF_2CH::typeName() const +{ + return "HERF-800-2T"; +} + +const byteAssign_t* HERF_2CH::getByteAssignment() const +{ + return byteAssignment; +} + +uint8_t HERF_2CH::getByteAssignmentSize() const +{ + return sizeof(byteAssignment) / sizeof(byteAssignment[0]); +} diff --git a/lib/Hoymiles/src/inverters/HERF_2CH.h b/lib/Hoymiles/src/inverters/HERF_2CH.h new file mode 100644 index 000000000..048ccb618 --- /dev/null +++ b/lib/Hoymiles/src/inverters/HERF_2CH.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include "HM_Abstract.h" + +class HERF_2CH : public HM_Abstract { +public: + explicit HERF_2CH(HoymilesRadio* radio, const uint64_t serial); + static bool isValidSerial(const uint64_t serial); + String typeName() const; + const byteAssign_t* getByteAssignment() const; + uint8_t getByteAssignmentSize() const; +}; diff --git a/lib/Hoymiles/src/inverters/HERF_4CH.cpp b/lib/Hoymiles/src/inverters/HERF_4CH.cpp new file mode 100644 index 000000000..f47b35e2d --- /dev/null +++ b/lib/Hoymiles/src/inverters/HERF_4CH.cpp @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022-2024 Thomas Basler and others + */ +#include "HERF_4CH.h" + +HERF_4CH::HERF_4CH(HoymilesRadio* radio, const uint64_t serial) + : HM_4CH(radio, serial) {}; + +bool HERF_4CH::isValidSerial(const uint64_t serial) +{ + // serial >= 0x280100000000 && serial <= 0x280199999999 + uint16_t preSerial = (serial >> 32) & 0xffff; + return preSerial == 0x2801; +} + +String HERF_4CH::typeName() const +{ + return "HERF-1600/1800-4T"; +} diff --git a/lib/Hoymiles/src/inverters/HERF_4CH.h b/lib/Hoymiles/src/inverters/HERF_4CH.h new file mode 100644 index 000000000..70c1ad216 --- /dev/null +++ b/lib/Hoymiles/src/inverters/HERF_4CH.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include "HM_4CH.h" + +class HERF_4CH : public HM_4CH { +public: + explicit HERF_4CH(HoymilesRadio* radio, const uint64_t serial); + static bool isValidSerial(const uint64_t serial); + String typeName() const; +}; diff --git a/lib/Hoymiles/src/inverters/README.md b/lib/Hoymiles/src/inverters/README.md index c080a7351..6d6104a20 100644 --- a/lib/Hoymiles/src/inverters/README.md +++ b/lib/Hoymiles/src/inverters/README.md @@ -11,3 +11,5 @@ | HMS_4CH | HMS-1600/1800/2000-4T | 1164 | | HMT_4CH | HMT-1600/1800/2000-4T | 1361 | | HMT_6CH | HMT-1800/2250-6T | 1382 | +| HERF_2CH | HERF 800 | 2821 | +| HERF_4CH | HERF 1800 | 2801 | diff --git a/lib/Hoymiles/src/parser/DevInfoParser.cpp b/lib/Hoymiles/src/parser/DevInfoParser.cpp index 08970ff13..0900a1ace 100644 --- a/lib/Hoymiles/src/parser/DevInfoParser.cpp +++ b/lib/Hoymiles/src/parser/DevInfoParser.cpp @@ -52,7 +52,11 @@ const devInfo_t devInfo[] = { { { 0x10, 0x32, 0x71, ALL }, 2000, "HMT-2000-4T" }, // 0 { { 0x10, 0x33, 0x11, ALL }, 1800, "HMT-1800-6T" }, // 01 - { { 0x10, 0x33, 0x31, ALL }, 2250, "HMT-2250-6T" } // 01 + { { 0x10, 0x33, 0x31, ALL }, 2250, "HMT-2250-6T" }, // 01 + + { { 0xF1, 0x01, 0x14, ALL }, 800, "HERF-800" }, // 00 + { { 0xF1, 0x01, 0x24, ALL }, 1600, "HERF-1600" }, // 00 + { { 0xF1, 0x01, 0x22, ALL }, 1800, "HERF-1800" }, // 00 }; DevInfoParser::DevInfoParser() diff --git a/src/WebApi_dtu.cpp b/src/WebApi_dtu.cpp index aed098340..817e71b27 100644 --- a/src/WebApi_dtu.cpp +++ b/src/WebApi_dtu.cpp @@ -129,7 +129,10 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) return; } - if (root["serial"].as() == 0) { + // Interpret the string as a hex value and convert it to uint64_t + const uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); + + if (serial == 0) { retMsg["message"] = "Serial cannot be zero!"; retMsg["code"] = WebApiError::DtuSerialZero; response->setLength(); @@ -185,8 +188,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) CONFIG_T& config = Configuration.get(); - // Interpret the string as a hex value and convert it to uint64_t - config.Dtu.Serial = strtoll(root["serial"].as().c_str(), NULL, 16); + config.Dtu.Serial = serial; config.Dtu.PollInterval = root["pollinterval"].as(); config.Dtu.Nrf.PaLevel = root["nrf_palevel"].as(); config.Dtu.Cmt.PaLevel = root["cmt_palevel"].as(); diff --git a/src/WebApi_inverter.cpp b/src/WebApi_inverter.cpp index 32a472350..68983ab9c 100644 --- a/src/WebApi_inverter.cpp +++ b/src/WebApi_inverter.cpp @@ -129,7 +129,10 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) return; } - if (root["serial"].as() == 0) { + // Interpret the string as a hex value and convert it to uint64_t + const uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); + + if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::InverterSerialZero; response->setLength(); @@ -158,7 +161,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) } // Interpret the string as a hex value and convert it to uint64_t - inverter->Serial = strtoll(root["serial"].as().c_str(), NULL, 16); + inverter->Serial = serial; strncpy(inverter->Name, root["name"].as().c_str(), INV_MAX_NAME_STRLEN); @@ -233,7 +236,10 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) return; } - if (root["serial"].as() == 0) { + // Interpret the string as a hex value and convert it to uint64_t + const uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); + + if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::InverterSerialZero; response->setLength(); @@ -261,7 +267,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) INVERTER_CONFIG_T& inverter = Configuration.get().Inverter[root["id"].as()]; - uint64_t new_serial = strtoll(root["serial"].as().c_str(), NULL, 16); + uint64_t new_serial = serial; uint64_t old_serial = inverter.Serial; // Interpret the string as a hex value and convert it to uint64_t diff --git a/src/WebApi_limit.cpp b/src/WebApi_limit.cpp index 1d9c111a5..b5b9e1726 100644 --- a/src/WebApi_limit.cpp +++ b/src/WebApi_limit.cpp @@ -100,7 +100,10 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) return; } - if (root["serial"].as() == 0) { + // Interpret the string as a hex value and convert it to uint64_t + const uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); + + if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::LimitSerialZero; response->setLength(); @@ -129,7 +132,6 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) return; } - uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); uint16_t limit = root["limit_value"].as(); PowerLimitControlType type = root["limit_type"].as(); diff --git a/src/WebApi_power.cpp b/src/WebApi_power.cpp index b51967894..08fe9c051 100644 --- a/src/WebApi_power.cpp +++ b/src/WebApi_power.cpp @@ -93,7 +93,10 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) return; } - if (root["serial"].as() == 0) { + // Interpret the string as a hex value and convert it to uint64_t + const uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); + + if (serial == 0) { retMsg["message"] = "Serial must be a number > 0!"; retMsg["code"] = WebApiError::PowerSerialZero; response->setLength(); @@ -101,7 +104,6 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) return; } - uint64_t serial = strtoll(root["serial"].as().c_str(), NULL, 16); auto inv = Hoymiles.getInverterBySerial(serial); if (inv == nullptr) { retMsg["message"] = "Invalid inverter specified!"; diff --git a/webapp/src/components/InputSerial.vue b/webapp/src/components/InputSerial.vue new file mode 100644 index 000000000..26aa4d617 --- /dev/null +++ b/webapp/src/components/InputSerial.vue @@ -0,0 +1,114 @@ + + + diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index da510947b..c9dfa975b 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -618,5 +618,12 @@ "Name": "Name", "ValueSelected": "Ausgewählt", "ValueActive": "Aktiv" + }, + "inputserial": { + "format_hoymiles": "Hoymiles Seriennummerformat", + "format_converted": "Bereits konvertierte Seriennummer", + "format_herf_valid": "E-Star HERF Format (wird konvertiert gespeichert): {serial}", + "format_herf_invalid": "E-Star HERF Format: Ungültige Prüfsumme", + "format_unknown": "Unbekanntes Format" } } diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 82fabba9f..4375137b9 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -619,5 +619,12 @@ "Number": "Number", "ValueSelected": "Selected", "ValueActive": "Active" + }, + "inputserial": { + "format_hoymiles": "Hoymiles serial number format", + "format_converted": "Already converted serial number", + "format_herf_valid": "E-Star HERF format (will be saved converted): {serial}", + "format_herf_invalid": "E-Star HERF format: Invalid checksum", + "format_unknown": "Unknown format" } } diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 6a706b5b6..24f0a951d 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -618,5 +618,12 @@ "Name": "Nom", "ValueSelected": "Sélectionné", "ValueActive": "Activé" + }, + "inputserial": { + "format_hoymiles": "Hoymiles serial number format", + "format_converted": "Already converted serial number", + "format_herf_valid": "E-Star HERF format (will be saved converted): {serial}", + "format_herf_invalid": "E-Star HERF format: Invalid checksum", + "format_unknown": "Unknown format" } } diff --git a/webapp/src/types/DevInfoStatus.ts b/webapp/src/types/DevInfoStatus.ts index 4c09e6b46..7c37a5673 100644 --- a/webapp/src/types/DevInfoStatus.ts +++ b/webapp/src/types/DevInfoStatus.ts @@ -1,5 +1,5 @@ export interface DevInfoStatus { - serial: number; + serial: string; valid_data: boolean; fw_bootloader_version: number; fw_build_version: number; @@ -8,4 +8,4 @@ export interface DevInfoStatus { hw_version: number; hw_model_name: string; max_power: number; -} \ No newline at end of file +} diff --git a/webapp/src/types/InverterConfig.ts b/webapp/src/types/InverterConfig.ts index 1f2167aa4..da7fa43c4 100644 --- a/webapp/src/types/InverterConfig.ts +++ b/webapp/src/types/InverterConfig.ts @@ -6,7 +6,7 @@ export interface InverterChannel { export interface Inverter { id: string; - serial: number; + serial: string; name: string; type: string; order: number; diff --git a/webapp/src/types/LimitConfig.ts b/webapp/src/types/LimitConfig.ts index d311ca612..b218c1140 100644 --- a/webapp/src/types/LimitConfig.ts +++ b/webapp/src/types/LimitConfig.ts @@ -1,5 +1,5 @@ export interface LimitConfig { - serial: number; + serial: string; limit_value: number; limit_type: number; -} \ No newline at end of file +} diff --git a/webapp/src/types/LiveDataStatus.ts b/webapp/src/types/LiveDataStatus.ts index 6da7266b1..5d2c51674 100644 --- a/webapp/src/types/LiveDataStatus.ts +++ b/webapp/src/types/LiveDataStatus.ts @@ -22,7 +22,7 @@ export interface InverterStatistics { } export interface Inverter { - serial: number; + serial: string; name: string; order: number; data_age: number; @@ -53,4 +53,4 @@ export interface LiveData { inverters: Inverter[]; total: Total; hints: Hints; -} \ No newline at end of file +} diff --git a/webapp/src/views/HomeView.vue b/webapp/src/views/HomeView.vue index 953d5cf49..0bd013335 100644 --- a/webapp/src/views/HomeView.vue +++ b/webapp/src/views/HomeView.vue @@ -346,7 +346,7 @@ export default defineComponent({ showAlertLimit: false, powerSettingView: {} as bootstrap.Modal, - powerSettingSerial: 0, + powerSettingSerial: "", powerSettingLoading: true, alertMessagePower: "", alertTypePower: "info", @@ -515,7 +515,7 @@ export default defineComponent({ this.heartInterval && clearTimeout(this.heartInterval); this.isFirstFetchAfterConnect = true; }, - onShowEventlog(serial: number) { + onShowEventlog(serial: string) { this.eventLogLoading = true; fetch("/api/eventlog/status?inv=" + serial + "&locale=" + this.$i18n.locale, { headers: authHeader() }) .then((response) => handleResponse(response, this.$emitter, this.$router)) @@ -526,7 +526,7 @@ export default defineComponent({ this.eventLogView.show(); }, - onShowDevInfo(serial: number) { + onShowDevInfo(serial: string) { this.devInfoLoading = true; fetch("/api/devinfo/status?inv=" + serial, { headers: authHeader() }) .then((response) => handleResponse(response, this.$emitter, this.$router)) @@ -538,7 +538,7 @@ export default defineComponent({ this.devInfoView.show(); }, - onShowGridProfile(serial: number) { + onShowGridProfile(serial: string) { this.gridProfileLoading = true; fetch("/api/gridprofile/status?inv=" + serial, { headers: authHeader() }) .then((response) => handleResponse(response, this.$emitter, this.$router)) @@ -555,9 +555,9 @@ export default defineComponent({ this.gridProfileView.show(); }, - onShowLimitSettings(serial: number) { + onShowLimitSettings(serial: string) { this.showAlertLimit = false; - this.targetLimitList.serial = 0; + this.targetLimitList.serial = ""; this.targetLimitList.limit_value = 0; this.targetLimitType = 1; this.targetLimitTypeText = this.$t('home.Relative'); @@ -611,9 +611,9 @@ export default defineComponent({ this.targetLimitType = type; }, - onShowPowerSettings(serial: number) { + onShowPowerSettings(serial: string) { this.showAlertPower = false; - this.powerSettingSerial = 0; + this.powerSettingSerial = ""; this.powerSettingLoading = true; fetch("/api/power/status", { headers: authHeader() }) .then((response) => handleResponse(response, this.$emitter, this.$router)) diff --git a/webapp/src/views/InverterAdminView.vue b/webapp/src/views/InverterAdminView.vue index 21ea8dd76..9216f592f 100644 --- a/webapp/src/views/InverterAdminView.vue +++ b/webapp/src/views/InverterAdminView.vue @@ -8,8 +8,7 @@
- +
@@ -91,7 +90,7 @@ - + @@ -207,6 +206,7 @@ import BasePage from '@/components/BasePage.vue'; import BootstrapAlert from "@/components/BootstrapAlert.vue"; import CardElement from '@/components/CardElement.vue'; import InputElement from '@/components/InputElement.vue'; +import InputSerial from '@/components/InputSerial.vue'; import ModalDialog from '@/components/ModalDialog.vue'; import type { Inverter } from '@/types/InverterConfig'; import { authHeader, handleResponse } from '@/utils/authentication'; @@ -235,6 +235,7 @@ export default defineComponent({ BootstrapAlert, CardElement, InputElement, + InputSerial, ModalDialog, BIconInfoCircle, BIconPencil, From b11b1dbcbac53303201ceebc0752e1780bf519a8 Mon Sep 17 00:00:00 2001 From: Bernhard Kirchen Date: Fri, 8 Mar 2024 22:53:34 +0100 Subject: [PATCH 09/66] DPL: define IsInverterSolarPowered config switch --- include/Configuration.h | 1 + include/defaults.h | 1 + src/Configuration.cpp | 2 ++ 3 files changed, 4 insertions(+) diff --git a/include/Configuration.h b/include/Configuration.h index 5fdd21c7f..14a056670 100644 --- a/include/Configuration.h +++ b/include/Configuration.h @@ -207,6 +207,7 @@ struct CONFIG_T { uint8_t BatteryDrainStategy; uint32_t Interval; bool IsInverterBehindPowerMeter; + bool IsInverterSolarPowered; uint8_t InverterId; uint8_t InverterChannelId; int32_t TargetPowerConsumption; diff --git a/include/defaults.h b/include/defaults.h index 56030d9b3..c30cb32e2 100644 --- a/include/defaults.h +++ b/include/defaults.h @@ -122,6 +122,7 @@ #define POWERLIMITER_BATTERY_DRAIN_STRATEGY 0 #define POWERLIMITER_INTERVAL 10 #define POWERLIMITER_IS_INVERTER_BEHIND_POWER_METER true +#define POWERLIMITER_IS_INVERTER_SOLAR_POWERED false #define POWERLIMITER_INVERTER_ID 0 #define POWERLIMITER_INVERTER_CHANNEL_ID 0 #define POWERLIMITER_TARGET_POWER_CONSUMPTION 0 diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 441d2dac9..a1764f1e7 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -185,6 +185,7 @@ bool ConfigurationClass::write() powerlimiter["battery_drain_strategy"] = config.PowerLimiter.BatteryDrainStategy; powerlimiter["interval"] = config.PowerLimiter.Interval; powerlimiter["is_inverter_behind_powermeter"] = config.PowerLimiter.IsInverterBehindPowerMeter; + powerlimiter["is_inverter_solar_powered"] = config.PowerLimiter.IsInverterSolarPowered; powerlimiter["inverter_id"] = config.PowerLimiter.InverterId; powerlimiter["inverter_channel_id"] = config.PowerLimiter.InverterChannelId; powerlimiter["target_power_consumption"] = config.PowerLimiter.TargetPowerConsumption; @@ -431,6 +432,7 @@ bool ConfigurationClass::read() config.PowerLimiter.BatteryDrainStategy = powerlimiter["battery_drain_strategy"] | POWERLIMITER_BATTERY_DRAIN_STRATEGY; config.PowerLimiter.Interval = powerlimiter["interval"] | POWERLIMITER_INTERVAL; config.PowerLimiter.IsInverterBehindPowerMeter = powerlimiter["is_inverter_behind_powermeter"] | POWERLIMITER_IS_INVERTER_BEHIND_POWER_METER; + config.PowerLimiter.IsInverterSolarPowered = powerlimiter["is_inverter_solar_powered"] | POWERLIMITER_IS_INVERTER_SOLAR_POWERED; config.PowerLimiter.InverterId = powerlimiter["inverter_id"] | POWERLIMITER_INVERTER_ID; config.PowerLimiter.InverterChannelId = powerlimiter["inverter_channel_id"] | POWERLIMITER_INVERTER_CHANNEL_ID; config.PowerLimiter.TargetPowerConsumption = powerlimiter["target_power_consumption"] | POWERLIMITER_TARGET_POWER_CONSUMPTION; From c6f81806d681acd983918393841d91393b219d84 Mon Sep 17 00:00:00 2001 From: Bernhard Kirchen Date: Sat, 9 Mar 2024 15:39:16 +0100 Subject: [PATCH 10/66] DPL: make "IsInverterSolarPowered" configurable through web app --- src/WebApi_powerlimiter.cpp | 2 ++ webapp/src/locales/de.json | 1 + webapp/src/locales/en.json | 1 + webapp/src/locales/fr.json | 1 + webapp/src/types/PowerLimiterConfig.ts | 1 + webapp/src/views/PowerLimiterAdminView.vue | 5 +++++ 6 files changed, 11 insertions(+) diff --git a/src/WebApi_powerlimiter.cpp b/src/WebApi_powerlimiter.cpp index df530ca8b..3a7d827a2 100644 --- a/src/WebApi_powerlimiter.cpp +++ b/src/WebApi_powerlimiter.cpp @@ -39,6 +39,7 @@ void WebApiPowerLimiterClass::onStatus(AsyncWebServerRequest* request) root["solar_passthrough_losses"] = config.PowerLimiter.SolarPassThroughLosses; root["battery_drain_strategy"] = config.PowerLimiter.BatteryDrainStategy; root["is_inverter_behind_powermeter"] = config.PowerLimiter.IsInverterBehindPowerMeter; + root["is_inverter_solar_powered"] = config.PowerLimiter.IsInverterSolarPowered; root["inverter_id"] = config.PowerLimiter.InverterId; root["inverter_channel_id"] = config.PowerLimiter.InverterChannelId; root["target_power_consumption"] = config.PowerLimiter.TargetPowerConsumption; @@ -128,6 +129,7 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request) config.PowerLimiter.SolarPassThroughLosses = root["solar_passthrough_losses"].as(); config.PowerLimiter.BatteryDrainStategy= root["battery_drain_strategy"].as(); config.PowerLimiter.IsInverterBehindPowerMeter = root["is_inverter_behind_powermeter"].as(); + config.PowerLimiter.IsInverterSolarPowered = root["is_inverter_solar_powered"].as(); config.PowerLimiter.InverterId = root["inverter_id"].as(); config.PowerLimiter.InverterChannelId = root["inverter_channel_id"].as(); config.PowerLimiter.TargetPowerConsumption = root["target_power_consumption"].as(); diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index c751eed36..f8918de2c 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -610,6 +610,7 @@ "VoltageLoadCorrectionFactor": "DC Spannung - Lastkorrekturfaktor", "BatterySocInfo": "Hinweis: Die Akku SoC (State of Charge) Werte werden nur benutzt, wenn die Batterie-Kommunikationsschnittstelle innerhalb der letzten Minute gültige Werte geschickt hat. Andernfalls werden als Fallback-Option die Spannungseinstellungen verwendet.", "InverterIsBehindPowerMeter": "Welchselrichter ist hinter Leistungsmesser", + "InverterIsSolarPowered": "Wechselrichter wird von Solarmodulen gespeist", "Battery": "DC / Akku", "VoltageLoadCorrectionInfo": "Hinweis: Wenn Leistung von der Batterie abgegeben wird, bricht normalerweise die Spannung etwas ein. Damit nicht vorzeitig der Wechelrichter ausgeschaltet wird sobald der \"Stop\"-Schwellenwert erreicht wird, wird der hier angegebene Korrekturfaktor mit einberechnet. Korrigierte Spannung = DC Spannung + (Aktuelle Leistung (W) * Korrekturfaktor).", "InverterRestart": "Wechselrichter Neustart", diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 893870324..5aded483d 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -616,6 +616,7 @@ "VoltageLoadCorrectionFactor": "DC Voltage - Load correction factor", "BatterySocInfo": "Hint: The battery SoC (State of Charge) values are only used if the battery communication interface reported SoC updates in the last minute. Otherwise the voltage thresholds will be used as fallback.", "InverterIsBehindPowerMeter": "Inverter is behind Power meter", + "InverterIsSolarPowered": "Inverter is powered by solar modules", "Battery": "DC / Battery", "VoltageLoadCorrectionInfo": "Hint: When the power output is higher, the voltage is usually decreasing. In order to not stop the inverter too early (Stop treshold), a power factor can be specified here to correct this. Corrected voltage = DC Voltage + (Current power * correction factor).", "InverterRestart": "Inverter Restart", diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 88514e63d..90be3c99f 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -699,6 +699,7 @@ "VoltageLoadCorrectionFactor": "DC Voltage - Load correction factor", "BatterySocInfo": "Hint: The battery SoC (State of Charge) values are only used if the battery communication interface reported SoC updates in the last minute. Otherwise the voltage thresholds will be used as fallback.", "InverterIsBehindPowerMeter": "Inverter is behind Power meter", + "InverterIsSolarPowered": "Inverter is powered by solar modules", "Battery": "DC / Battery", "VoltageLoadCorrectionInfo": "Hint: When the power output is higher, the voltage is usually decreasing. In order to not stop the inverter too early (Stop treshold), a power factor can be specified here to correct this. Corrected voltage = DC Voltage + (Current power * correction factor)." }, diff --git a/webapp/src/types/PowerLimiterConfig.ts b/webapp/src/types/PowerLimiterConfig.ts index 594361d77..70fe6084a 100644 --- a/webapp/src/types/PowerLimiterConfig.ts +++ b/webapp/src/types/PowerLimiterConfig.ts @@ -5,6 +5,7 @@ export interface PowerLimiterConfig { solar_passthrough_losses: number; battery_drain_strategy: number; is_inverter_behind_powermeter: boolean; + is_inverter_solar_powered: boolean; inverter_id: number; inverter_channel_id: number; target_power_consumption: number; diff --git a/webapp/src/views/PowerLimiterAdminView.vue b/webapp/src/views/PowerLimiterAdminView.vue index 898cd4f64..54cc5adb0 100644 --- a/webapp/src/views/PowerLimiterAdminView.vue +++ b/webapp/src/views/PowerLimiterAdminView.vue @@ -77,6 +77,11 @@
+ +