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 418eae1a..79568596 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 5e6d4706..b0002b95 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 4086f8e3..4bf004ab 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 3c7eaf1d..4433c434 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 4bf004ab..65215900 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 a6f0c10c..87413ce7 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 @@ private: 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 | 305 ++++++++++++++++++++++---------------------- 2 files changed, 164 insertions(+), 161 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 79568596..102cf715 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 b0002b95..74da0aef 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== +"@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.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== +"@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.1" - debug "^4.1.1" + "@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 b2b30a2e..08970ff1 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 102cf715..1a42b8ee 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 74da0aef..2cde79a0 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 365f0efc..cb9f4ef4 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 e7b3d263..eda3500b 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 00000000..37799d14 --- /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 00000000..048ccb61 --- /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 00000000..f47b35e2 --- /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 00000000..70c1ad21 --- /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 c080a735..6d6104a2 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 08970ff1..0900a1ac 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 aed09834..817e71b2 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 32a47235..68983ab9 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 1d9c111a..b5b9e172 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 b5196789..08fe9c05 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 00000000..26aa4d61 --- /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 da510947..c9dfa975 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 82fabba9..4375137b 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 6a706b5b..24f0a951 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 4c09e6b4..7c37a567 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 1f2167aa..da7fa43c 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 d311ca61..b218c114 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 6da7266b..5d2c5167 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 953d5cf4..0bd01333 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 21ea8dd7..9216f592 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 5fdd21c7..14a05667 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 56030d9b..c30cb32e 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 441d2dac..a1764f1e 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 df530ca8..3a7d827a 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 c751eed3..f8918de2 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 89387032..5aded483 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 88514e63..90be3c99 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 594361d7..70fe6084 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 898cd4f6..54cc5adb 100644 --- a/webapp/src/views/PowerLimiterAdminView.vue +++ b/webapp/src/views/PowerLimiterAdminView.vue @@ -77,6 +77,11 @@
+ +