From 5d7be32b909405d8160c87ea79e0b907dfeec006 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Tue, 31 Jan 2023 18:35:50 +0100 Subject: [PATCH 01/12] Fixed typo --- src/MqttHandleHass.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/MqttHandleHass.cpp b/src/MqttHandleHass.cpp index 0eaed40b..5afd6dd9 100644 --- a/src/MqttHandleHass.cpp +++ b/src/MqttHandleHass.cpp @@ -115,9 +115,9 @@ void MqttHandleHassClass::publishField(std::shared_ptr inv, ui root[F("stat_t")] = stateTopic; root[F("uniq_id")] = serial + "_ch" + String(channel) + "_" + fieldName; - String unit_of_meausure = inv->Statistics()->getChannelFieldUnit(channel, fieldType.fieldId); - if (unit_of_meausure != "") { - root[F("unit_of_meas")] = unit_of_meausure; + String unit_of_measure = inv->Statistics()->getChannelFieldUnit(channel, fieldType.fieldId); + if (unit_of_measure != "") { + root[F("unit_of_meas")] = unit_of_measure; } JsonObject deviceObj = root.createNestedObject("dev"); From 7b9d870cce752475f71ed7e25b5020cfc279b788 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Mon, 6 Feb 2023 19:42:11 +0100 Subject: [PATCH 02/12] webapp: Update dependencies --- webapp/package.json | 10 +- webapp/yarn.lock | 405 +++++++++++++++++++++++++------------------- 2 files changed, 240 insertions(+), 175 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index e82162be..911c984e 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -16,14 +16,14 @@ "bootstrap-icons-vue": "^1.8.1", "mitt": "^3.0.0", "spark-md5": "^3.0.2", - "vue": "^3.2.45", + "vue": "^3.2.47", "vue-i18n": "^9.2.2", "vue-router": "^4.1.6" }, "devDependencies": { "@rushstack/eslint-patch": "^1.2.0", "@types/bootstrap": "^5.2.6", - "@types/node": "^18.11.18", + "@types/node": "^18.11.19", "@types/spark-md5": "^3.0.2", "@vitejs/plugin-vue": "^4.0.0", "@vue/eslint-config-typescript": "^11.0.2", @@ -31,9 +31,9 @@ "eslint": "^8.33.0", "eslint-plugin-vue": "^9.9.0", "npm-run-all": "^4.1.5", - "sass": "^1.57.1", - "typescript": "^4.9.4", - "vite": "^4.0.4", + "sass": "^1.58.0", + "typescript": "^4.9.5", + "vite": "^4.1.1", "vite-plugin-compression": "^0.5.1", "vite-plugin-css-injected-by-js": "^2.4.0", "vue-tsc": "^1.0.24" diff --git a/webapp/yarn.lock b/webapp/yarn.lock index b788be68..815a3117 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -7,115 +7,115 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== -"@esbuild/android-arm64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.4.tgz#4b31b9e3da2e4c12a8170bd682f713c775f68ab1" - integrity sha512-VPuTzXFm/m2fcGfN6CiwZTlLzxrKsWbPkG7ArRFpuxyaHUm/XFHQPD4xNwZT6uUmpIHhnSjcaCmcla8COzmZ5Q== +"@esbuild/android-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz#cf91e86df127aa3d141744edafcba0abdc577d23" + integrity sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg== -"@esbuild/android-arm@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.4.tgz#057d3e8b0ee41ff59386c33ba6dcf20f4bedd1f7" - integrity sha512-rZzb7r22m20S1S7ufIc6DC6W659yxoOrl7sKP1nCYhuvUlnCFHVSbATG4keGUtV8rDz11sRRDbWkvQZpzPaHiw== +"@esbuild/android-arm@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz#025b6246d3f68b7bbaa97069144fb5fb70f2fff2" + integrity sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw== -"@esbuild/android-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.4.tgz#62ccab8ac1d3e6ef1df3fa2e1974bc2b8528d74a" - integrity sha512-MW+B2O++BkcOfMWmuHXB15/l1i7wXhJFqbJhp82IBOais8RBEQv2vQz/jHrDEHaY2X0QY7Wfw86SBL2PbVOr0g== +"@esbuild/android-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz#c820e0fef982f99a85c4b8bfdd582835f04cd96e" + integrity sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ== -"@esbuild/darwin-arm64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.4.tgz#c19a6489d626c36fc611c85ccd8a3333c1f2a930" - integrity sha512-a28X1O//aOfxwJVZVs7ZfM8Tyih2Za4nKJrBwW5Wm4yKsnwBy9aiS/xwpxiiTRttw3EaTg4Srerhcm6z0bu9Wg== +"@esbuild/darwin-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz#edef4487af6b21afabba7be5132c26d22379b220" + integrity sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w== -"@esbuild/darwin-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.4.tgz#b726bbc84a1e277f6ec2509d10b8ee03f242b776" - integrity sha512-e3doCr6Ecfwd7VzlaQqEPrnbvvPjE9uoTpxG5pyLzr2rI2NMjDHmvY1E5EO81O/e9TUOLLkXA5m6T8lfjK9yAA== +"@esbuild/darwin-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz#42829168730071c41ef0d028d8319eea0e2904b4" + integrity sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg== -"@esbuild/freebsd-arm64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.4.tgz#364568e6ca2901297f247de0681c9b14bbe658c8" - integrity sha512-Oup3G/QxBgvvqnXWrBed7xxkFNwAwJVHZcklWyQt7YCAL5bfUkaa6FVWnR78rNQiM8MqqLiT6ZTZSdUFuVIg1w== +"@esbuild/freebsd-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz#1f4af488bfc7e9ced04207034d398e793b570a27" + integrity sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw== -"@esbuild/freebsd-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.4.tgz#44701ba4a5497ba64eec0a6c9e221d8f46a25e72" - integrity sha512-vAP+eYOxlN/Bpo/TZmzEQapNS8W1njECrqkTpNgvXskkkJC2AwOXwZWai/Kc2vEFZUXQttx6UJbj9grqjD/+9Q== +"@esbuild/freebsd-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz#636306f19e9bc981e06aa1d777302dad8fddaf72" + integrity sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug== -"@esbuild/linux-arm64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.4.tgz#b58fb418ec9ac714d8dbb38c787ff2441eb1d9db" - integrity sha512-2zXoBhv4r5pZiyjBKrOdFP4CXOChxXiYD50LRUU+65DkdS5niPFHbboKZd/c81l0ezpw7AQnHeoCy5hFrzzs4g== +"@esbuild/linux-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz#a003f7ff237c501e095d4f3a09e58fc7b25a4aca" + integrity sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g== -"@esbuild/linux-arm@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.4.tgz#b37f15ecddb53eeea466e5960e31a58f33e0e87e" - integrity sha512-A47ZmtpIPyERxkSvIv+zLd6kNIOtJH03XA0Hy7jaceRDdQaQVGSDt4mZqpWqJYgDk9rg96aglbF6kCRvPGDSUA== +"@esbuild/linux-arm@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz#b591e6a59d9c4fe0eeadd4874b157ab78cf5f196" + integrity sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ== -"@esbuild/linux-ia32@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.4.tgz#117e32a9680b5deac184ebee122f8575369fad1b" - integrity sha512-uxdSrpe9wFhz4yBwt2kl2TxS/NWEINYBUFIxQtaEVtglm1eECvsj1vEKI0KX2k2wCe17zDdQ3v+jVxfwVfvvjw== +"@esbuild/linux-ia32@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz#24333a11027ef46a18f57019450a5188918e2a54" + integrity sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg== -"@esbuild/linux-loong64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.4.tgz#dd504fb83c280752d4b485d9acb3cf391cb7bf5b" - integrity sha512-peDrrUuxbZ9Jw+DwLCh/9xmZAk0p0K1iY5d2IcwmnN+B87xw7kujOkig6ZRcZqgrXgeRGurRHn0ENMAjjD5DEg== +"@esbuild/linux-loong64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz#d5ad459d41ed42bbd4d005256b31882ec52227d8" + integrity sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ== -"@esbuild/linux-mips64el@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.4.tgz#9ab77e31cf3be1e35572afff94b51df8149d15bd" - integrity sha512-sD9EEUoGtVhFjjsauWjflZklTNr57KdQ6xfloO4yH1u7vNQlOfAlhEzbyBKfgbJlW7rwXYBdl5/NcZ+Mg2XhQA== +"@esbuild/linux-mips64el@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz#4e5967a665c38360b0a8205594377d4dcf9c3726" + integrity sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw== -"@esbuild/linux-ppc64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.4.tgz#69d56c2a960808bee1c7b9b84a115220ec9ce05c" - integrity sha512-X1HSqHUX9D+d0l6/nIh4ZZJ94eQky8d8z6yxAptpZE3FxCWYWvTDd9X9ST84MGZEJx04VYUD/AGgciddwO0b8g== +"@esbuild/linux-ppc64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz#206443a02eb568f9fdf0b438fbd47d26e735afc8" + integrity sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g== -"@esbuild/linux-riscv64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.4.tgz#9fc23583f4a1508a8d352bd376340e42217e8a90" - integrity sha512-97ANpzyNp0GTXCt6SRdIx1ngwncpkV/z453ZuxbnBROCJ5p/55UjhbaG23UdHj88fGWLKPFtMoU4CBacz4j9FA== +"@esbuild/linux-riscv64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz#c351e433d009bf256e798ad048152c8d76da2fc9" + integrity sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw== -"@esbuild/linux-s390x@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.4.tgz#4cae1f70ac2943f076dd130c3c80d28f57bf75d1" - integrity sha512-pUvPQLPmbEeJRPjP0DYTC1vjHyhrnCklQmCGYbipkep+oyfTn7GTBJXoPodR7ZS5upmEyc8lzAkn2o29wD786A== +"@esbuild/linux-s390x@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz#661f271e5d59615b84b6801d1c2123ad13d9bd87" + integrity sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w== -"@esbuild/linux-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.4.tgz#fdf494de07cda23a2dc4b71ff1e0848e4ee6539c" - integrity sha512-N55Q0mJs3Sl8+utPRPBrL6NLYZKBCLLx0bme/+RbjvMforTGGzFvsRl4xLTZMUBFC1poDzBEPTEu5nxizQ9Nlw== +"@esbuild/linux-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz#e4ba18e8b149a89c982351443a377c723762b85f" + integrity sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw== -"@esbuild/netbsd-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.4.tgz#b59ecb49087119c575c0f64d7e66001d52799e24" - integrity sha512-LHSJLit8jCObEQNYkgsDYBh2JrJT53oJO2HVdkSYLa6+zuLJh0lAr06brXIkljrlI+N7NNW1IAXGn/6IZPi3YQ== +"@esbuild/netbsd-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz#7d4f4041e30c5c07dd24ffa295c73f06038ec775" + integrity sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA== -"@esbuild/openbsd-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.4.tgz#c51e36db875948b7b11d08bafa355605a1aa289c" - integrity sha512-nLgdc6tWEhcCFg/WVFaUxHcPK3AP/bh+KEwKtl69Ay5IBqUwKDaq/6Xk0E+fh/FGjnLwqFSsarsbPHeKM8t8Sw== +"@esbuild/openbsd-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz#970fa7f8470681f3e6b1db0cc421a4af8060ec35" + integrity sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg== -"@esbuild/sunos-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.4.tgz#0b50e941cd44f069e9f2573321aec984244ec228" - integrity sha512-08SluG24GjPO3tXKk95/85n9kpyZtXCVwURR2i4myhrOfi3jspClV0xQQ0W0PYWHioJj+LejFMt41q+PG3mlAQ== +"@esbuild/sunos-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz#abc60e7c4abf8b89fb7a4fe69a1484132238022c" + integrity sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw== -"@esbuild/win32-arm64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.4.tgz#d1c93b20f17355ab2221cd18e13ae2f1b68013e3" - integrity sha512-yYiRDQcqLYQSvNQcBKN7XogbrSvBE45FEQdH8fuXPl7cngzkCvpsG2H9Uey39IjQ6gqqc+Q4VXYHsQcKW0OMjQ== +"@esbuild/win32-arm64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz#7b0ff9e8c3265537a7a7b1fd9a24e7bd39fcd87a" + integrity sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw== -"@esbuild/win32-ia32@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.4.tgz#df5910e76660e0acbbdceb8d4ae6bf1efeade6ae" - integrity sha512-5rabnGIqexekYkh9zXG5waotq8mrdlRoBqAktjx2W3kb0zsI83mdCwrcAeKYirnUaTGztR5TxXcXmQrEzny83w== +"@esbuild/win32-ia32@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz#e90fe5267d71a7b7567afdc403dfd198c292eb09" + integrity sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig== -"@esbuild/win32-x64@0.16.4": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.4.tgz#6ec594468610c176933da1387c609558371d37e0" - integrity sha512-sN/I8FMPtmtT2Yw+Dly8Ur5vQ5a/RmC8hW7jO9PtPSQUPkowxWpcUZnqOggU7VwyT3Xkj6vcXWd3V/qTXwultQ== +"@esbuild/win32-x64@0.16.17": + version "0.16.17" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz#c5a1a4bfe1b57f0c3e61b29883525c6da3e5c091" + integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q== "@eslint/eslintrc@^1.4.1": version "1.4.1" @@ -237,10 +237,10 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/node@^18.11.18": - version "18.11.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" - integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== +"@types/node@^18.11.19": + version "18.11.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.19.tgz#35e26df9ec441ab99d73e99e9aca82935eea216d" + integrity sha512-YUgMWAQBWLObABqrvx8qKO1enAvBUdjZOAWQ5grBAkp5LQv45jBvYKZ3oFS9iKRCQyFjqw6iuEa1vmFqtxYLZw== "@types/spark-md5@^3.0.2": version "3.0.2" @@ -420,6 +420,16 @@ estree-walker "^2.0.2" source-map "^0.6.1" +"@vue/compiler-core@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz#3e07c684d74897ac9aa5922c520741f3029267f8" + integrity sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig== + dependencies: + "@babel/parser" "^7.16.4" + "@vue/shared" "3.2.47" + estree-walker "^2.0.2" + source-map "^0.6.1" + "@vue/compiler-dom@3.2.45", "@vue/compiler-dom@^3.2.45": version "3.2.45" resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz#c43cc15e50da62ecc16a42f2622d25dc5fd97dce" @@ -428,7 +438,31 @@ "@vue/compiler-core" "3.2.45" "@vue/shared" "3.2.45" -"@vue/compiler-sfc@3.2.45", "@vue/compiler-sfc@^3.2.45": +"@vue/compiler-dom@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz#a0b06caf7ef7056939e563dcaa9cbde30794f305" + integrity sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ== + dependencies: + "@vue/compiler-core" "3.2.47" + "@vue/shared" "3.2.47" + +"@vue/compiler-sfc@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz#1bdc36f6cdc1643f72e2c397eb1a398f5004ad3d" + integrity sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ== + dependencies: + "@babel/parser" "^7.16.4" + "@vue/compiler-core" "3.2.47" + "@vue/compiler-dom" "3.2.47" + "@vue/compiler-ssr" "3.2.47" + "@vue/reactivity-transform" "3.2.47" + "@vue/shared" "3.2.47" + estree-walker "^2.0.2" + magic-string "^0.25.7" + postcss "^8.1.10" + source-map "^0.6.1" + +"@vue/compiler-sfc@^3.2.45": version "3.2.45" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz#7f7989cc04ec9e7c55acd406827a2c4e96872c70" integrity sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q== @@ -452,6 +486,14 @@ "@vue/compiler-dom" "3.2.45" "@vue/shared" "3.2.45" +"@vue/compiler-ssr@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz#35872c01a273aac4d6070ab9d8da918ab13057ee" + integrity sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw== + dependencies: + "@vue/compiler-dom" "3.2.47" + "@vue/shared" "3.2.47" + "@vue/devtools-api@^6.2.1", "@vue/devtools-api@^6.4.5": version "6.4.5" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz#d54e844c1adbb1e677c81c665ecef1a2b4bb8380" @@ -477,43 +519,66 @@ estree-walker "^2.0.2" magic-string "^0.25.7" -"@vue/reactivity@3.2.45", "@vue/reactivity@^3.2.45": +"@vue/reactivity-transform@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz#e45df4d06370f8abf29081a16afd25cffba6d84e" + integrity sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA== + dependencies: + "@babel/parser" "^7.16.4" + "@vue/compiler-core" "3.2.47" + "@vue/shared" "3.2.47" + estree-walker "^2.0.2" + magic-string "^0.25.7" + +"@vue/reactivity@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.47.tgz#1d6399074eadfc3ed35c727e2fd707d6881140b6" + integrity sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ== + dependencies: + "@vue/shared" "3.2.47" + +"@vue/reactivity@^3.2.45": version "3.2.45" resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.45.tgz#412a45b574de601be5a4a5d9a8cbd4dee4662ff0" integrity sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A== dependencies: "@vue/shared" "3.2.45" -"@vue/runtime-core@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.45.tgz#7ad7ef9b2519d41062a30c6fa001ec43ac549c7f" - integrity sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A== +"@vue/runtime-core@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.47.tgz#406ebade3d5551c00fc6409bbc1eeb10f32e121d" + integrity sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA== dependencies: - "@vue/reactivity" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/reactivity" "3.2.47" + "@vue/shared" "3.2.47" -"@vue/runtime-dom@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz#1a2ef6ee2ad876206fbbe2a884554bba2d0faf59" - integrity sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA== +"@vue/runtime-dom@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz#93e760eeaeab84dedfb7c3eaf3ed58d776299382" + integrity sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA== dependencies: - "@vue/runtime-core" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/runtime-core" "3.2.47" + "@vue/shared" "3.2.47" csstype "^2.6.8" -"@vue/server-renderer@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.45.tgz#ca9306a0c12b0530a1a250e44f4a0abac6b81f3f" - integrity sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g== +"@vue/server-renderer@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.47.tgz#8aa1d1871fc4eb5a7851aa7f741f8f700e6de3c0" + integrity sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA== dependencies: - "@vue/compiler-ssr" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/compiler-ssr" "3.2.47" + "@vue/shared" "3.2.47" "@vue/shared@3.2.45", "@vue/shared@^3.2.45": version "3.2.45" resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.45.tgz#a3fffa7489eafff38d984e23d0236e230c818bc2" integrity sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg== +"@vue/shared@3.2.47": + version "3.2.47" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.47.tgz#e597ef75086c6e896ff5478a6bfc0a7aa4bbd14c" + integrity sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ== + "@vue/tsconfig@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@vue/tsconfig/-/tsconfig-0.1.3.tgz#4a61dbd29783d01ddab504276dcf0c2b6988654f" @@ -812,33 +877,33 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild@^0.16.3: - version "0.16.4" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.4.tgz#06c86298d233386f5e41bcc14d36086daf3f40bd" - integrity sha512-qQrPMQpPTWf8jHugLWHoGqZjApyx3OEm76dlTXobHwh/EBbavbRdjXdYi/GWr43GyN0sfpap14GPkb05NH3ROA== +esbuild@^0.16.14: + version "0.16.17" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.17.tgz#fc2c3914c57ee750635fee71b89f615f25065259" + integrity sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg== optionalDependencies: - "@esbuild/android-arm" "0.16.4" - "@esbuild/android-arm64" "0.16.4" - "@esbuild/android-x64" "0.16.4" - "@esbuild/darwin-arm64" "0.16.4" - "@esbuild/darwin-x64" "0.16.4" - "@esbuild/freebsd-arm64" "0.16.4" - "@esbuild/freebsd-x64" "0.16.4" - "@esbuild/linux-arm" "0.16.4" - "@esbuild/linux-arm64" "0.16.4" - "@esbuild/linux-ia32" "0.16.4" - "@esbuild/linux-loong64" "0.16.4" - "@esbuild/linux-mips64el" "0.16.4" - "@esbuild/linux-ppc64" "0.16.4" - "@esbuild/linux-riscv64" "0.16.4" - "@esbuild/linux-s390x" "0.16.4" - "@esbuild/linux-x64" "0.16.4" - "@esbuild/netbsd-x64" "0.16.4" - "@esbuild/openbsd-x64" "0.16.4" - "@esbuild/sunos-x64" "0.16.4" - "@esbuild/win32-arm64" "0.16.4" - "@esbuild/win32-ia32" "0.16.4" - "@esbuild/win32-x64" "0.16.4" + "@esbuild/android-arm" "0.16.17" + "@esbuild/android-arm64" "0.16.17" + "@esbuild/android-x64" "0.16.17" + "@esbuild/darwin-arm64" "0.16.17" + "@esbuild/darwin-x64" "0.16.17" + "@esbuild/freebsd-arm64" "0.16.17" + "@esbuild/freebsd-x64" "0.16.17" + "@esbuild/linux-arm" "0.16.17" + "@esbuild/linux-arm64" "0.16.17" + "@esbuild/linux-ia32" "0.16.17" + "@esbuild/linux-loong64" "0.16.17" + "@esbuild/linux-mips64el" "0.16.17" + "@esbuild/linux-ppc64" "0.16.17" + "@esbuild/linux-riscv64" "0.16.17" + "@esbuild/linux-s390x" "0.16.17" + "@esbuild/linux-x64" "0.16.17" + "@esbuild/netbsd-x64" "0.16.17" + "@esbuild/openbsd-x64" "0.16.17" + "@esbuild/sunos-x64" "0.16.17" + "@esbuild/win32-arm64" "0.16.17" + "@esbuild/win32-ia32" "0.16.17" + "@esbuild/win32-x64" "0.16.17" escape-string-regexp@^1.0.5: version "1.0.5" @@ -1720,10 +1785,10 @@ postcss@^8.1.10: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.4.20: - version "8.4.20" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56" - integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g== +postcss@^8.4.21: + version "8.4.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" + integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== dependencies: nanoid "^3.3.4" picocolors "^1.0.0" @@ -1800,10 +1865,10 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rollup@^3.7.0: - version "3.7.4" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.7.4.tgz#993c3b30eff1df96f5eafb7c2ef7648960f2fa34" - integrity sha512-jN9rx3k5pfg9H9al0r0y1EYKSeiRANZRYX32SuNXAnKzh6cVyf4LZVto1KAuDnbHT03E1CpsgqDKaqQ8FZtgxw== +rollup@^3.10.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.14.0.tgz#f5925255f3b6e8de1dba3916d7619c7da5708d95" + integrity sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q== optionalDependencies: fsevents "~2.3.2" @@ -1823,10 +1888,10 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -sass@^1.57.1: - version "1.57.1" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.57.1.tgz#dfafd46eb3ab94817145e8825208ecf7281119b5" - integrity sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw== +sass@^1.58.0: + version "1.58.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.58.0.tgz#ee8aea3ad5ea5c485c26b3096e2df6087d0bb1cc" + integrity sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -2032,10 +2097,10 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -typescript@^4.9.4: - version "4.9.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== +typescript@^4.9.5: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== unbox-primitive@^1.0.2: version "1.0.2" @@ -2086,15 +2151,15 @@ vite-plugin-css-injected-by-js@^2.4.0: resolved "https://registry.yarnpkg.com/vite-plugin-css-injected-by-js/-/vite-plugin-css-injected-by-js-2.4.0.tgz#32eb77e3ea0c45fbecf1c5f1e65703cccd42ecdb" integrity sha512-fQkJ5baPEasjjJLxHINLjXuPREO61VIDFUeUqleEBghOLfZZe/k/zrxG5b3kFZXu6JtdI11pnwtj3dh3CN9X4Q== -vite@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/vite/-/vite-4.0.4.tgz#4612ce0b47bbb233a887a54a4ae0c6e240a0da31" - integrity sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw== +vite@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.1.1.tgz#3b18b81a4e85ce3df5cbdbf4c687d93ebf402e6b" + integrity sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg== dependencies: - esbuild "^0.16.3" - postcss "^8.4.20" + esbuild "^0.16.14" + postcss "^8.4.21" resolve "^1.22.1" - rollup "^3.7.0" + rollup "^3.10.0" optionalDependencies: fsevents "~2.3.2" @@ -2144,16 +2209,16 @@ vue-tsc@^1.0.24: "@volar/vue-language-core" "1.0.24" "@volar/vue-typescript" "1.0.24" -vue@^3.2.45: - version "3.2.45" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.45.tgz#94a116784447eb7dbd892167784619fef379b3c8" - integrity sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA== +vue@^3.2.47: + version "3.2.47" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.47.tgz#3eb736cbc606fc87038dbba6a154707c8a34cff0" + integrity sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ== dependencies: - "@vue/compiler-dom" "3.2.45" - "@vue/compiler-sfc" "3.2.45" - "@vue/runtime-dom" "3.2.45" - "@vue/server-renderer" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/compiler-dom" "3.2.47" + "@vue/compiler-sfc" "3.2.47" + "@vue/runtime-dom" "3.2.47" + "@vue/server-renderer" "3.2.47" + "@vue/shared" "3.2.47" which-boxed-primitive@^1.0.2: version "1.0.2" From 6b36369b06375a5d29c180e8448af36f12c0dcb5 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Sun, 29 Jan 2023 11:46:50 +0100 Subject: [PATCH 03/12] Hoymiles Lib: Migrate byteAssign array to std::list --- lib/Hoymiles/src/inverters/HM_1CH.cpp | 9 +-- lib/Hoymiles/src/inverters/HM_1CH.h | 6 +- lib/Hoymiles/src/inverters/HM_2CH.cpp | 9 +-- lib/Hoymiles/src/inverters/HM_2CH.h | 5 +- lib/Hoymiles/src/inverters/HM_4CH.cpp | 9 +-- lib/Hoymiles/src/inverters/HM_4CH.h | 5 +- .../src/inverters/InverterAbstract.cpp | 2 +- lib/Hoymiles/src/inverters/InverterAbstract.h | 4 +- lib/Hoymiles/src/parser/StatisticsParser.cpp | 61 ++++++++----------- lib/Hoymiles/src/parser/StatisticsParser.h | 8 +-- 10 files changed, 45 insertions(+), 73 deletions(-) diff --git a/lib/Hoymiles/src/inverters/HM_1CH.cpp b/lib/Hoymiles/src/inverters/HM_1CH.cpp index 246339c7..7154611d 100644 --- a/lib/Hoymiles/src/inverters/HM_1CH.cpp +++ b/lib/Hoymiles/src/inverters/HM_1CH.cpp @@ -32,12 +32,7 @@ String HM_1CH::typeName() return F("HM-300, HM-350, HM-400"); } -const byteAssign_t* HM_1CH::getByteAssignment() +const std::list* HM_1CH::getByteAssignment() { - return byteAssignment; -} - -uint8_t HM_1CH::getAssignmentCount() -{ - return sizeof(byteAssignment) / sizeof(byteAssign_t); + return &byteAssignment; } \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_1CH.h b/lib/Hoymiles/src/inverters/HM_1CH.h index 6fb345f5..7599b686 100644 --- a/lib/Hoymiles/src/inverters/HM_1CH.h +++ b/lib/Hoymiles/src/inverters/HM_1CH.h @@ -2,17 +2,17 @@ #pragma once #include "HM_Abstract.h" +#include class HM_1CH : public HM_Abstract { public: explicit HM_1CH(uint64_t serial); static bool isValidSerial(uint64_t serial); String typeName(); - const byteAssign_t* getByteAssignment(); - uint8_t getAssignmentCount(); + const std::list* getByteAssignment(); private: - const byteAssign_t byteAssignment[18] = { + const std::list byteAssignment = { { CH1, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, { CH1, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, { CH1, FLD_PDC, UNIT_W, 6, 2, 10, false, 1 }, diff --git a/lib/Hoymiles/src/inverters/HM_2CH.cpp b/lib/Hoymiles/src/inverters/HM_2CH.cpp index ef148bed..f93746ee 100644 --- a/lib/Hoymiles/src/inverters/HM_2CH.cpp +++ b/lib/Hoymiles/src/inverters/HM_2CH.cpp @@ -33,12 +33,7 @@ String HM_2CH::typeName() return F("HM-600, HM-700, HM-800"); } -const byteAssign_t* HM_2CH::getByteAssignment() +const std::list* HM_2CH::getByteAssignment() { - return byteAssignment; -} - -uint8_t HM_2CH::getAssignmentCount() -{ - return sizeof(byteAssignment) / sizeof(byteAssign_t); + return &byteAssignment; } \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_2CH.h b/lib/Hoymiles/src/inverters/HM_2CH.h index d20d43f2..5ff5c069 100644 --- a/lib/Hoymiles/src/inverters/HM_2CH.h +++ b/lib/Hoymiles/src/inverters/HM_2CH.h @@ -8,11 +8,10 @@ public: explicit HM_2CH(uint64_t serial); static bool isValidSerial(uint64_t serial); String typeName(); - const byteAssign_t* getByteAssignment(); - uint8_t getAssignmentCount(); + const std::list* getByteAssignment(); private: - const byteAssign_t byteAssignment[24] = { + const std::list byteAssignment = { { CH1, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, { CH1, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, { CH1, FLD_PDC, UNIT_W, 6, 2, 10, false, 1 }, diff --git a/lib/Hoymiles/src/inverters/HM_4CH.cpp b/lib/Hoymiles/src/inverters/HM_4CH.cpp index afffbead..9cf5a4af 100644 --- a/lib/Hoymiles/src/inverters/HM_4CH.cpp +++ b/lib/Hoymiles/src/inverters/HM_4CH.cpp @@ -32,12 +32,7 @@ String HM_4CH::typeName() return F("HM-1000, HM-1200, HM-1500"); } -const byteAssign_t* HM_4CH::getByteAssignment() +const std::list* HM_4CH::getByteAssignment() { - return byteAssignment; -} - -uint8_t HM_4CH::getAssignmentCount() -{ - return sizeof(byteAssignment) / sizeof(byteAssign_t); + return &byteAssignment; } \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_4CH.h b/lib/Hoymiles/src/inverters/HM_4CH.h index 2a950f2e..2a511c52 100644 --- a/lib/Hoymiles/src/inverters/HM_4CH.h +++ b/lib/Hoymiles/src/inverters/HM_4CH.h @@ -8,11 +8,10 @@ public: explicit HM_4CH(uint64_t serial); static bool isValidSerial(uint64_t serial); String typeName(); - const byteAssign_t* getByteAssignment(); - uint8_t getAssignmentCount(); + const std::list* getByteAssignment(); private: - const byteAssign_t byteAssignment[36] = { + const std::list byteAssignment = { { CH1, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, { CH1, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, { CH1, FLD_PDC, UNIT_W, 8, 2, 10, false, 1 }, diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.cpp b/lib/Hoymiles/src/inverters/InverterAbstract.cpp index 30da998a..8c0677bc 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.cpp +++ b/lib/Hoymiles/src/inverters/InverterAbstract.cpp @@ -30,7 +30,7 @@ void InverterAbstract::init() // Not possible in constructor --> virtual function // Not possible in verifyAllFragments --> Because no data if nothing is ever received // It has to be executed because otherwise the getChannelCount method in stats always returns 0 - _statisticsParser.get()->setByteAssignment(getByteAssignment(), getAssignmentCount()); + _statisticsParser.get()->setByteAssignment(getByteAssignment()); } uint64_t InverterAbstract::serial() diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.h b/lib/Hoymiles/src/inverters/InverterAbstract.h index 018e06d2..6334c648 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.h +++ b/lib/Hoymiles/src/inverters/InverterAbstract.h @@ -11,6 +11,7 @@ #include "types.h" #include #include +#include #define MAX_NAME_LENGTH 32 @@ -38,8 +39,7 @@ public: void setName(const char* name); const char* name(); virtual String typeName() = 0; - virtual const byteAssign_t* getByteAssignment() = 0; - virtual uint8_t getAssignmentCount() = 0; + virtual const std::list* getByteAssignment() = 0; bool isProducing(); bool isReachable(); diff --git a/lib/Hoymiles/src/parser/StatisticsParser.cpp b/lib/Hoymiles/src/parser/StatisticsParser.cpp index be7ce046..117ced32 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.cpp +++ b/lib/Hoymiles/src/parser/StatisticsParser.cpp @@ -28,10 +28,9 @@ const calcFunc_t calcFunctions[] = { { CALC_IRR_CH, &calcIrradiation } }; -void StatisticsParser::setByteAssignment(const byteAssign_t* byteAssignment, const uint8_t count) +void StatisticsParser::setByteAssignment(const std::list* byteAssignment) { _byteAssignment = byteAssignment; - _byteAssignmentCount = count; } void StatisticsParser::clearBuffer() @@ -50,31 +49,26 @@ void StatisticsParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t _statisticLength += len; } -uint8_t StatisticsParser::getAssignIdxByChannelField(uint8_t channel, uint8_t fieldId) +const byteAssign_t* StatisticsParser::getAssignmentByChannelField(uint8_t channel, uint8_t fieldId) { - const byteAssign_t* b = _byteAssignment; - - uint8_t pos; - for (pos = 0; pos < _byteAssignmentCount; pos++) { - if (b[pos].ch == channel && b[pos].fieldId == fieldId) { - return pos; + for (auto const& i : *_byteAssignment) { + if (i.ch == channel && i.fieldId == fieldId) { + return &i; } } - return 0xff; + return NULL; } float StatisticsParser::getChannelFieldValue(uint8_t channel, uint8_t fieldId) { - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - if (pos == 0xff) { + const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + if (pos == NULL) { return 0; } - const byteAssign_t* b = _byteAssignment; - - uint8_t ptr = b[pos].start; - uint8_t end = ptr + b[pos].num; - uint16_t div = b[pos].div; + uint8_t ptr = pos->start; + uint8_t end = ptr + pos->num; + uint16_t div = pos->div; if (CMD_CALC != div) { // Value is a static value @@ -85,9 +79,9 @@ float StatisticsParser::getChannelFieldValue(uint8_t channel, uint8_t fieldId) } while (++ptr != end); float result; - if (b[pos].isSigned && b[pos].num == 2) { + if (pos->isSigned && pos->num == 2) { result = static_cast(static_cast(val)); - } else if (b[pos].isSigned && b[pos].num == 4) { + } else if (pos->isSigned && pos->num == 4) { result = static_cast(static_cast(val)); } else { result = static_cast(val); @@ -97,7 +91,7 @@ float StatisticsParser::getChannelFieldValue(uint8_t channel, uint8_t fieldId) return result; } else { // Value has to be calculated - return calcFunctions[b[pos].start].func(this, b[pos].num); + return calcFunctions[pos->start].func(this, pos->num); } return 0; @@ -105,39 +99,34 @@ float StatisticsParser::getChannelFieldValue(uint8_t channel, uint8_t fieldId) bool StatisticsParser::hasChannelFieldValue(uint8_t channel, uint8_t fieldId) { - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - return pos != 0xff; + const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + return pos != NULL; } const char* StatisticsParser::getChannelFieldUnit(uint8_t channel, uint8_t fieldId) { - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - const byteAssign_t* b = _byteAssignment; - - return units[b[pos].unitId]; + const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + return units[pos->unitId]; } const char* StatisticsParser::getChannelFieldName(uint8_t channel, uint8_t fieldId) { - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - const byteAssign_t* b = _byteAssignment; - - return fields[b[pos].fieldId]; + const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + return fields[pos->fieldId]; } uint8_t StatisticsParser::getChannelFieldDigits(uint8_t channel, uint8_t fieldId) { - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - return _byteAssignment[pos].digits; + const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + return pos->digits; } uint8_t StatisticsParser::getChannelCount() { - const byteAssign_t* b = _byteAssignment; uint8_t cnt = 0; - for (uint8_t pos = 0; pos < _byteAssignmentCount; pos++) { - if (b[pos].ch > cnt) { - cnt = b[pos].ch; + for (auto const &b: *_byteAssignment) { + if (b.ch > cnt) { + cnt = b.ch; } } diff --git a/lib/Hoymiles/src/parser/StatisticsParser.h b/lib/Hoymiles/src/parser/StatisticsParser.h index e4defc94..cc7cb76f 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.h +++ b/lib/Hoymiles/src/parser/StatisticsParser.h @@ -3,6 +3,7 @@ #include "Parser.h" #include #include +#include #define STATISTIC_PACKET_SIZE (4 * 16) @@ -78,9 +79,9 @@ public: void clearBuffer(); void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len); - void setByteAssignment(const byteAssign_t* byteAssignment, const uint8_t count); + void setByteAssignment(const std::list* byteAssignment); - uint8_t getAssignIdxByChannelField(uint8_t channel, uint8_t fieldId); + const byteAssign_t* getAssignmentByChannelField(uint8_t channel, uint8_t fieldId); float getChannelFieldValue(uint8_t channel, uint8_t fieldId); bool hasChannelFieldValue(uint8_t channel, uint8_t fieldId); const char* getChannelFieldUnit(uint8_t channel, uint8_t fieldId); @@ -101,8 +102,7 @@ private: uint8_t _statisticLength = 0; uint16_t _chanMaxPower[CH4]; - const byteAssign_t* _byteAssignment; - uint8_t _byteAssignmentCount; + const std::list* _byteAssignment; uint32_t _rxFailureCount = 0; }; \ No newline at end of file From d4c838a16ee2dddc93cd1b5bc51ab8552cc1047b Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Mon, 6 Feb 2023 19:51:10 +0100 Subject: [PATCH 04/12] BREAKING CHANGE: Prometheus API! Added additional field to the prometheus api which identifies a channel by it's type. That means that e.g. channel 0 exists for type AC and DC. This commit also introduces a additional field in the statistics byte assignment table. This field identifies whether a channel is on the AC or DC side. MQTT and WebAPI is still compatible with the previous design. --- include/MqttHandleHass.h | 4 +- include/MqttHandleInverter.h | 6 +- include/WebApi_prometheus.h | 2 +- include/WebApi_ws_live.h | 2 +- lib/Hoymiles/src/inverters/HM_1CH.h | 38 ++++---- lib/Hoymiles/src/inverters/HM_2CH.h | 50 +++++------ lib/Hoymiles/src/inverters/HM_4CH.h | 74 ++++++++-------- lib/Hoymiles/src/inverters/HM_Abstract.cpp | 6 +- .../src/inverters/InverterAbstract.cpp | 9 +- lib/Hoymiles/src/parser/StatisticsParser.cpp | 86 +++++++++++-------- lib/Hoymiles/src/parser/StatisticsParser.h | 36 +++++--- src/Display_Graphic.cpp | 13 +-- src/MqttHandleHass.cpp | 38 +++++--- src/MqttHandleInverter.cpp | 43 ++++++---- src/WebApi_inverter.cpp | 2 +- src/WebApi_prometheus.cpp | 57 ++++++------ src/WebApi_ws_live.cpp | 82 ++++++++++-------- 17 files changed, 315 insertions(+), 233 deletions(-) diff --git a/include/MqttHandleHass.h b/include/MqttHandleHass.h index 33d9df82..45d11cfb 100644 --- a/include/MqttHandleHass.h +++ b/include/MqttHandleHass.h @@ -25,7 +25,7 @@ enum { const char* const stateClasses[] = { 0, "measurement", "total_increasing" }; typedef struct { - uint8_t fieldId; // field id + FieldId_t fieldId; // field id uint8_t deviceClsId; // device class uint8_t stateClsId; // state class } byteAssign_fieldDeviceClass_t; @@ -57,7 +57,7 @@ public: private: void publish(const String& subtopic, const String& payload); - void publishField(std::shared_ptr inv, uint8_t channel, byteAssign_fieldDeviceClass_t fieldType, bool clear = false); + void publishField(std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, byteAssign_fieldDeviceClass_t fieldType, bool clear = false); void publishInverterButton(std::shared_ptr inv, const char* caption, const char* icon, const char* category, const char* deviceClass, const char* subTopic, const char* payload); void publishInverterNumber(std::shared_ptr inv, const char* caption, const char* icon, const char* category, const char* commandTopic, const char* stateTopic, const char* unitOfMeasure, int16_t min = 1, int16_t max = 100); void publishInverterBinarySensor(std::shared_ptr inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off); diff --git a/include/MqttHandleInverter.h b/include/MqttHandleInverter.h index a4e49ce4..9df43cb7 100644 --- a/include/MqttHandleInverter.h +++ b/include/MqttHandleInverter.h @@ -10,16 +10,16 @@ public: void init(); void loop(); - static String getTopic(std::shared_ptr inv, uint8_t channel, uint8_t fieldId); + static String getTopic(std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); private: - void publishField(std::shared_ptr inv, uint8_t channel, uint8_t fieldId); + void publishField(std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total); uint32_t _lastPublishStats[INV_MAX_COUNT]; uint32_t _lastPublish; - uint8_t _publishFields[14] = { + FieldId_t _publishFields[14] = { FLD_UDC, FLD_IDC, FLD_PDC, diff --git a/include/WebApi_prometheus.h b/include/WebApi_prometheus.h index 60e8e102..ac2478a0 100644 --- a/include/WebApi_prometheus.h +++ b/include/WebApi_prometheus.h @@ -12,7 +12,7 @@ public: private: void onPrometheusMetricsGet(AsyncWebServerRequest* request); - void addField(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr inv, uint8_t channel, uint8_t fieldId, const char* channelName = NULL); + void addField(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, const char* channelName = NULL); AsyncWebServer* _server; }; \ No newline at end of file diff --git a/include/WebApi_ws_live.h b/include/WebApi_ws_live.h index 5da18640..0cf1449b 100644 --- a/include/WebApi_ws_live.h +++ b/include/WebApi_ws_live.h @@ -13,7 +13,7 @@ public: private: void generateJsonResponse(JsonVariant& root); - void addField(JsonObject& root, uint8_t idx, std::shared_ptr inv, uint8_t channel, uint8_t fieldId, String topic = ""); + void addField(JsonObject& root, uint8_t idx, std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, String topic = ""); void addTotalField(JsonObject& root, String name, float value, String unit, uint8_t digits); void onLivedataStatus(AsyncWebServerRequest* request); void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len); diff --git a/lib/Hoymiles/src/inverters/HM_1CH.h b/lib/Hoymiles/src/inverters/HM_1CH.h index 7599b686..94186467 100644 --- a/lib/Hoymiles/src/inverters/HM_1CH.h +++ b/lib/Hoymiles/src/inverters/HM_1CH.h @@ -13,24 +13,26 @@ public: private: const std::list byteAssignment = { - { CH1, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, - { CH1, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, - { CH1, FLD_PDC, UNIT_W, 6, 2, 10, false, 1 }, - { CH1, FLD_YD, UNIT_WH, 12, 2, 1, false, 0 }, - { CH1, FLD_YT, UNIT_KWH, 8, 4, 1000, false, 3 }, - { CH1, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH1, CMD_CALC, false, 3 }, + { TYPE_DC, CH0, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, + { TYPE_DC, CH0, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, + { TYPE_DC, CH0, FLD_PDC, UNIT_W, 6, 2, 10, false, 1 }, + { TYPE_DC, CH0, FLD_YD, UNIT_WH, 12, 2, 1, false, 0 }, + { TYPE_DC, CH0, FLD_YT, UNIT_KWH, 8, 4, 1000, false, 3 }, + { TYPE_DC, CH0, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH0, CMD_CALC, false, 3 }, - { CH0, FLD_UAC, UNIT_V, 14, 2, 10, false, 1 }, - { CH0, FLD_IAC, UNIT_A, 22, 2, 100, false, 2 }, - { CH0, FLD_PAC, UNIT_W, 18, 2, 10, false, 1 }, - { CH0, FLD_PRA, UNIT_VA, 20, 2, 10, false, 1 }, - { CH0, FLD_F, UNIT_HZ, 16, 2, 100, false, 2 }, - { CH0, FLD_PF, UNIT_NONE, 24, 2, 1000, false, 3 }, - { CH0, FLD_T, UNIT_C, 26, 2, 10, true, 1 }, - { CH0, FLD_EVT_LOG, UNIT_NONE, 28, 2, 1, false, 0 }, - { CH0, FLD_YD, UNIT_WH, CALC_YD_CH0, 0, CMD_CALC, false, 0 }, - { CH0, FLD_YT, UNIT_KWH, CALC_YT_CH0, 0, CMD_CALC, false, 3 }, - { CH0, FLD_PDC, UNIT_W, CALC_PDC_CH0, 0, CMD_CALC, false, 1 }, - { CH0, FLD_EFF, UNIT_PCT, CALC_EFF_CH0, 0, CMD_CALC, false, 3 } + { TYPE_AC, CH0, FLD_UAC, UNIT_V, 14, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_IAC, UNIT_A, 22, 2, 100, false, 2 }, + { TYPE_AC, CH0, FLD_PAC, UNIT_W, 18, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_PRA, UNIT_VA, 20, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_F, UNIT_HZ, 16, 2, 100, false, 2 }, + { TYPE_AC, CH0, FLD_PF, UNIT_NONE, 24, 2, 1000, false, 3 }, + + { TYPE_INV, CH0, FLD_T, UNIT_C, 26, 2, 10, true, 1 }, + { TYPE_INV, CH0, FLD_EVT_LOG, UNIT_NONE, 28, 2, 1, false, 0 }, + + { TYPE_AC, CH0, FLD_YD, UNIT_WH, CALC_YD_CH0, 0, CMD_CALC, false, 0 }, + { TYPE_AC, CH0, FLD_YT, UNIT_KWH, CALC_YT_CH0, 0, CMD_CALC, false, 3 }, + { TYPE_AC, CH0, FLD_PDC, UNIT_W, CALC_PDC_CH0, 0, CMD_CALC, false, 1 }, + { TYPE_AC, CH0, FLD_EFF, UNIT_PCT, CALC_EFF_CH0, 0, CMD_CALC, false, 3 } }; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_2CH.h b/lib/Hoymiles/src/inverters/HM_2CH.h index 5ff5c069..6e8672ca 100644 --- a/lib/Hoymiles/src/inverters/HM_2CH.h +++ b/lib/Hoymiles/src/inverters/HM_2CH.h @@ -12,31 +12,33 @@ public: private: const std::list byteAssignment = { - { CH1, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, - { CH1, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, - { CH1, FLD_PDC, UNIT_W, 6, 2, 10, false, 1 }, - { CH1, FLD_YD, UNIT_WH, 22, 2, 1, false, 0 }, - { CH1, FLD_YT, UNIT_KWH, 14, 4, 1000, false, 3 }, - { CH1, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH1, CMD_CALC, false, 3 }, + { TYPE_DC, CH0, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, + { TYPE_DC, CH0, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, + { TYPE_DC, CH0, FLD_PDC, UNIT_W, 6, 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_IRR_CH, CH0, CMD_CALC, false, 3 }, - { CH2, FLD_UDC, UNIT_V, 8, 2, 10, false, 1 }, - { CH2, FLD_IDC, UNIT_A, 10, 2, 100, false, 2 }, - { CH2, FLD_PDC, UNIT_W, 12, 2, 10, false, 1 }, - { CH2, FLD_YD, UNIT_WH, 24, 2, 1, false, 0 }, - { CH2, FLD_YT, UNIT_KWH, 18, 4, 1000, false, 3 }, - { CH2, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH2, CMD_CALC, false, 3 }, + { TYPE_DC, CH1, FLD_UDC, UNIT_V, 8, 2, 10, false, 1 }, + { TYPE_DC, CH1, FLD_IDC, UNIT_A, 10, 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_IRR_CH, CH1, CMD_CALC, false, 3 }, - { CH0, FLD_UAC, UNIT_V, 26, 2, 10, false, 1 }, - { CH0, FLD_IAC, UNIT_A, 34, 2, 100, false, 2 }, - { CH0, FLD_PAC, UNIT_W, 30, 2, 10, false, 1 }, - { CH0, FLD_PRA, UNIT_VA, 32, 2, 10, false, 1 }, - { CH0, FLD_F, UNIT_HZ, 28, 2, 100, false, 2 }, - { CH0, FLD_PF, UNIT_NONE, 36, 2, 1000, false, 3 }, - { CH0, FLD_T, UNIT_C, 38, 2, 10, true, 1 }, - { CH0, FLD_EVT_LOG, UNIT_NONE, 40, 2, 1, false, 0 }, - { CH0, FLD_YD, UNIT_WH, CALC_YD_CH0, 0, CMD_CALC, false, 0 }, - { CH0, FLD_YT, UNIT_KWH, CALC_YT_CH0, 0, CMD_CALC, false, 3 }, - { CH0, FLD_PDC, UNIT_W, CALC_PDC_CH0, 0, CMD_CALC, false, 1 }, - { CH0, FLD_EFF, UNIT_PCT, CALC_EFF_CH0, 0, 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_PRA, UNIT_VA, 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_AC, CH0, FLD_YD, UNIT_WH, CALC_YD_CH0, 0, CMD_CALC, false, 0 }, + { TYPE_AC, CH0, FLD_YT, UNIT_KWH, CALC_YT_CH0, 0, CMD_CALC, false, 3 }, + { TYPE_AC, CH0, FLD_PDC, UNIT_W, CALC_PDC_CH0, 0, CMD_CALC, false, 1 }, + { TYPE_AC, CH0, FLD_EFF, UNIT_PCT, CALC_EFF_CH0, 0, CMD_CALC, false, 3 } }; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_4CH.h b/lib/Hoymiles/src/inverters/HM_4CH.h index 2a511c52..eccc60f2 100644 --- a/lib/Hoymiles/src/inverters/HM_4CH.h +++ b/lib/Hoymiles/src/inverters/HM_4CH.h @@ -12,45 +12,47 @@ public: private: const std::list byteAssignment = { - { CH1, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, - { CH1, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, - { CH1, FLD_PDC, UNIT_W, 8, 2, 10, false, 1 }, - { CH1, FLD_YD, UNIT_WH, 20, 2, 1, false, 0 }, - { CH1, FLD_YT, UNIT_KWH, 12, 4, 1000, false, 3 }, - { CH1, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH1, CMD_CALC, false, 3 }, + { TYPE_DC, CH0, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 }, + { TYPE_DC, CH0, FLD_IDC, UNIT_A, 4, 2, 100, false, 2 }, + { TYPE_DC, CH0, FLD_PDC, UNIT_W, 8, 2, 10, false, 1 }, + { TYPE_DC, CH0, FLD_YD, UNIT_WH, 20, 2, 1, false, 0 }, + { TYPE_DC, CH0, FLD_YT, UNIT_KWH, 12, 4, 1000, false, 3 }, + { TYPE_DC, CH0, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH0, CMD_CALC, false, 3 }, - { CH2, FLD_UDC, UNIT_V, CALC_UDC_CH, CH1, CMD_CALC, false, 1 }, - { CH2, FLD_IDC, UNIT_A, 6, 2, 100, false, 2 }, - { CH2, FLD_PDC, UNIT_W, 10, 2, 10, false, 1 }, - { CH2, FLD_YD, UNIT_WH, 22, 2, 1, false, 0 }, - { CH2, FLD_YT, UNIT_KWH, 16, 4, 1000, false, 3 }, - { CH2, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH2, CMD_CALC, false, 3 }, + { TYPE_DC, CH1, FLD_UDC, UNIT_V, CALC_UDC_CH, CH0, CMD_CALC, false, 1 }, + { TYPE_DC, CH1, FLD_IDC, UNIT_A, 6, 2, 100, false, 2 }, + { TYPE_DC, CH1, FLD_PDC, UNIT_W, 10, 2, 10, false, 1 }, + { TYPE_DC, CH1, FLD_YD, UNIT_WH, 22, 2, 1, false, 0 }, + { TYPE_DC, CH1, FLD_YT, UNIT_KWH, 16, 4, 1000, false, 3 }, + { TYPE_DC, CH1, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH1, CMD_CALC, false, 3 }, - { CH3, FLD_UDC, UNIT_V, 24, 2, 10, false, 1 }, - { CH3, FLD_IDC, UNIT_A, 26, 2, 100, false, 2 }, - { CH3, FLD_PDC, UNIT_W, 30, 2, 10, false, 1 }, - { CH3, FLD_YD, UNIT_WH, 42, 2, 1, false, 0 }, - { CH3, FLD_YT, UNIT_KWH, 34, 4, 1000, false, 3 }, - { CH3, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH3, CMD_CALC, false, 3 }, + { TYPE_DC, CH2, FLD_UDC, UNIT_V, 24, 2, 10, false, 1 }, + { TYPE_DC, CH2, FLD_IDC, UNIT_A, 26, 2, 100, false, 2 }, + { TYPE_DC, CH2, FLD_PDC, UNIT_W, 30, 2, 10, false, 1 }, + { TYPE_DC, CH2, FLD_YD, UNIT_WH, 42, 2, 1, false, 0 }, + { TYPE_DC, CH2, FLD_YT, UNIT_KWH, 34, 4, 1000, false, 3 }, + { TYPE_DC, CH2, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH2, CMD_CALC, false, 3 }, - { CH4, FLD_UDC, UNIT_V, CALC_UDC_CH, CH3, CMD_CALC, false, 1 }, - { CH4, FLD_IDC, UNIT_A, 28, 2, 100, false, 2 }, - { CH4, FLD_PDC, UNIT_W, 32, 2, 10, false, 1 }, - { CH4, FLD_YD, UNIT_WH, 44, 2, 1, false, 0 }, - { CH4, FLD_YT, UNIT_KWH, 38, 4, 1000, false, 3 }, - { CH4, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH4, CMD_CALC, false, 3 }, + { TYPE_DC, CH3, FLD_UDC, UNIT_V, CALC_UDC_CH, CH2, CMD_CALC, false, 1 }, + { TYPE_DC, CH3, FLD_IDC, UNIT_A, 28, 2, 100, false, 2 }, + { TYPE_DC, CH3, FLD_PDC, UNIT_W, 32, 2, 10, false, 1 }, + { TYPE_DC, CH3, FLD_YD, UNIT_WH, 44, 2, 1, false, 0 }, + { TYPE_DC, CH3, FLD_YT, UNIT_KWH, 38, 4, 1000, false, 3 }, + { TYPE_DC, CH3, FLD_IRR, UNIT_PCT, CALC_IRR_CH, CH3, CMD_CALC, false, 3 }, - { CH0, FLD_UAC, UNIT_V, 46, 2, 10, false, 1 }, - { CH0, FLD_IAC, UNIT_A, 54, 2, 100, false, 2 }, - { CH0, FLD_PAC, UNIT_W, 50, 2, 10, false, 1 }, - { CH0, FLD_PRA, UNIT_VA, 52, 2, 10, false, 1 }, - { CH0, FLD_F, UNIT_HZ, 48, 2, 100, false, 2 }, - { CH0, FLD_PF, UNIT_NONE, 56, 2, 1000, false, 3 }, - { CH0, FLD_T, UNIT_C, 58, 2, 10, true, 1 }, - { CH0, FLD_EVT_LOG, UNIT_NONE, 60, 2, 1, false, 0 }, - { CH0, FLD_YD, UNIT_WH, CALC_YD_CH0, 0, CMD_CALC, false, 0 }, - { CH0, FLD_YT, UNIT_KWH, CALC_YT_CH0, 0, CMD_CALC, false, 3 }, - { CH0, FLD_PDC, UNIT_W, CALC_PDC_CH0, 0, CMD_CALC, false, 1 }, - { CH0, FLD_EFF, UNIT_PCT, CALC_EFF_CH0, 0, CMD_CALC, false, 3 } + { TYPE_AC, CH0, FLD_UAC, UNIT_V, 46, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_IAC, UNIT_A, 54, 2, 100, false, 2 }, + { TYPE_AC, CH0, FLD_PAC, UNIT_W, 50, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_PRA, UNIT_VA, 52, 2, 10, false, 1 }, + { TYPE_AC, CH0, FLD_F, UNIT_HZ, 48, 2, 100, false, 2 }, + { TYPE_AC, CH0, FLD_PF, UNIT_NONE, 56, 2, 1000, false, 3 }, + + { TYPE_INV, CH0, FLD_T, UNIT_C, 58, 2, 10, true, 1 }, + { TYPE_INV, CH0, FLD_EVT_LOG, UNIT_NONE, 60, 2, 1, false, 0 }, + + { TYPE_AC, CH0, FLD_YD, UNIT_WH, CALC_YD_CH0, 0, CMD_CALC, false, 0 }, + { TYPE_AC, CH0, FLD_YT, UNIT_KWH, CALC_YT_CH0, 0, CMD_CALC, false, 3 }, + { TYPE_AC, CH0, FLD_PDC, UNIT_W, CALC_PDC_CH0, 0, CMD_CALC, false, 1 }, + { TYPE_AC, CH0, FLD_EFF, UNIT_PCT, CALC_EFF_CH0, 0, CMD_CALC, false, 3 } }; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_Abstract.cpp b/lib/Hoymiles/src/inverters/HM_Abstract.cpp index 73e02cee..63db5998 100644 --- a/lib/Hoymiles/src/inverters/HM_Abstract.cpp +++ b/lib/Hoymiles/src/inverters/HM_Abstract.cpp @@ -40,14 +40,14 @@ bool HM_Abstract::sendAlarmLogRequest(HoymilesRadio* radio, bool force) } if (!force) { - if (Statistics()->hasChannelFieldValue(CH0, FLD_EVT_LOG)) { - if ((uint8_t)Statistics()->getChannelFieldValue(CH0, FLD_EVT_LOG) == _lastAlarmLogCnt) { + if (Statistics()->hasChannelFieldValue(TYPE_INV, CH0, FLD_EVT_LOG)) { + if ((uint8_t)Statistics()->getChannelFieldValue(TYPE_INV, CH0, FLD_EVT_LOG) == _lastAlarmLogCnt) { return false; } } } - _lastAlarmLogCnt = (uint8_t)Statistics()->getChannelFieldValue(CH0, FLD_EVT_LOG); + _lastAlarmLogCnt = (uint8_t)Statistics()->getChannelFieldValue(TYPE_INV, CH0, FLD_EVT_LOG); time_t now; time(&now); diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.cpp b/lib/Hoymiles/src/inverters/InverterAbstract.cpp index 8c0677bc..c9798473 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.cpp +++ b/lib/Hoymiles/src/inverters/InverterAbstract.cpp @@ -60,11 +60,14 @@ const char* InverterAbstract::name() bool InverterAbstract::isProducing() { - if (!Statistics()->hasChannelFieldValue(CH0, FLD_PAC)) { - return false; + float totalAc = 0; + for (auto& c : Statistics()->getChannelsByType(TYPE_AC)) { + if (Statistics()->hasChannelFieldValue(TYPE_AC, c, FLD_PAC)) { + totalAc += Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_PAC); + } } - return Statistics()->getChannelFieldValue(CH0, FLD_PAC) > 0; + return totalAc > 0; } bool InverterAbstract::isReachable() diff --git a/lib/Hoymiles/src/parser/StatisticsParser.cpp b/lib/Hoymiles/src/parser/StatisticsParser.cpp index 117ced32..cccf760e 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.cpp +++ b/lib/Hoymiles/src/parser/StatisticsParser.cpp @@ -49,19 +49,19 @@ void StatisticsParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t _statisticLength += len; } -const byteAssign_t* StatisticsParser::getAssignmentByChannelField(uint8_t channel, uint8_t fieldId) +const byteAssign_t* StatisticsParser::getAssignmentByChannelField(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { for (auto const& i : *_byteAssignment) { - if (i.ch == channel && i.fieldId == fieldId) { + if (i.type == type && i.ch == channel && i.fieldId == fieldId) { return &i; } } return NULL; } -float StatisticsParser::getChannelFieldValue(uint8_t channel, uint8_t fieldId) +float StatisticsParser::getChannelFieldValue(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { - const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + const byteAssign_t* pos = getAssignmentByChannelField(type, channel, fieldId); if (pos == NULL) { return 0; } @@ -97,40 +97,54 @@ float StatisticsParser::getChannelFieldValue(uint8_t channel, uint8_t fieldId) return 0; } -bool StatisticsParser::hasChannelFieldValue(uint8_t channel, uint8_t fieldId) +bool StatisticsParser::hasChannelFieldValue(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { - const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + const byteAssign_t* pos = getAssignmentByChannelField(type, channel, fieldId); return pos != NULL; } -const char* StatisticsParser::getChannelFieldUnit(uint8_t channel, uint8_t fieldId) +const char* StatisticsParser::getChannelFieldUnit(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { - const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + const byteAssign_t* pos = getAssignmentByChannelField(type, channel, fieldId); return units[pos->unitId]; } -const char* StatisticsParser::getChannelFieldName(uint8_t channel, uint8_t fieldId) +const char* StatisticsParser::getChannelFieldName(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { - const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + const byteAssign_t* pos = getAssignmentByChannelField(type, channel, fieldId); return fields[pos->fieldId]; } -uint8_t StatisticsParser::getChannelFieldDigits(uint8_t channel, uint8_t fieldId) +uint8_t StatisticsParser::getChannelFieldDigits(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { - const byteAssign_t* pos = getAssignmentByChannelField(channel, fieldId); + const byteAssign_t* pos = getAssignmentByChannelField(type, channel, fieldId); return pos->digits; } -uint8_t StatisticsParser::getChannelCount() +std::list StatisticsParser::getChannelTypes() { - uint8_t cnt = 0; - for (auto const &b: *_byteAssignment) { - if (b.ch > cnt) { - cnt = b.ch; + return { + TYPE_AC, + TYPE_DC, + TYPE_INV + }; +} + +const char* StatisticsParser::getChannelTypeName(ChannelType_t type) +{ + return channelsTypes[type]; +} + +std::list StatisticsParser::getChannelsByType(ChannelType_t type) +{ + std::list l; + for (auto const& b : *_byteAssignment) { + if (b.type == type) { + l.push_back(b.ch); } } - - return cnt; + l.unique(); + return l; } uint16_t StatisticsParser::getChannelMaxPower(uint8_t channel) @@ -140,7 +154,7 @@ uint16_t StatisticsParser::getChannelMaxPower(uint8_t channel) void StatisticsParser::setChannelMaxPower(uint8_t channel, uint16_t power) { - if (channel < CH4) { + if (channel < sizeof(_chanMaxPower) / sizeof(_chanMaxPower[0])) { _chanMaxPower[channel] = power; } } @@ -163,8 +177,8 @@ uint32_t StatisticsParser::getRxFailureCount() static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0) { float yield = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - yield += iv->getChannelFieldValue(i, FLD_YT); + for (auto& channel : iv->getChannelsByType(TYPE_DC)) { + yield += iv->getChannelFieldValue(TYPE_DC, channel, FLD_YT); } return yield; } @@ -172,8 +186,8 @@ static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0) static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0) { float yield = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - yield += iv->getChannelFieldValue(i, FLD_YD); + for (auto& channel : iv->getChannelsByType(TYPE_DC)) { + yield += iv->getChannelFieldValue(TYPE_DC, channel, FLD_YD); } return yield; } @@ -181,14 +195,14 @@ static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0) // arg0 = channel of source static float calcUdcCh(StatisticsParser* iv, uint8_t arg0) { - return iv->getChannelFieldValue(arg0, FLD_UDC); + return iv->getChannelFieldValue(TYPE_DC, static_cast(arg0), FLD_UDC); } static float calcPowerDcCh0(StatisticsParser* iv, uint8_t arg0) { float dcPower = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - dcPower += iv->getChannelFieldValue(i, FLD_PDC); + for (auto& channel : iv->getChannelsByType(TYPE_DC)) { + dcPower += iv->getChannelFieldValue(TYPE_DC, channel, FLD_PDC); } return dcPower; } @@ -196,15 +210,19 @@ static float calcPowerDcCh0(StatisticsParser* iv, uint8_t arg0) // arg0 = channel static float calcEffiencyCh0(StatisticsParser* iv, uint8_t arg0) { - float acPower = iv->getChannelFieldValue(CH0, FLD_PAC); - float dcPower = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - dcPower += iv->getChannelFieldValue(i, FLD_PDC); + float acPower = 0; + for (auto& channel : iv->getChannelsByType(TYPE_AC)) { + acPower += iv->getChannelFieldValue(TYPE_AC, channel, FLD_PAC); } + + float dcPower = 0; + for (auto& channel : iv->getChannelsByType(TYPE_DC)) { + dcPower += iv->getChannelFieldValue(TYPE_DC, channel, FLD_PDC); + } + if (dcPower > 0) { return acPower / dcPower * 100.0f; } - return 0.0; } @@ -212,8 +230,8 @@ static float calcEffiencyCh0(StatisticsParser* iv, uint8_t arg0) static float calcIrradiation(StatisticsParser* iv, uint8_t arg0) { if (NULL != iv) { - if (iv->getChannelMaxPower(arg0 - 1) > 0) - return iv->getChannelFieldValue(arg0, FLD_PDC) / iv->getChannelMaxPower(arg0 - 1) * 100.0f; + if (iv->getChannelMaxPower(arg0) > 0) + return iv->getChannelFieldValue(TYPE_DC, static_cast(arg0), FLD_PDC) / iv->getChannelMaxPower(arg0) * 100.0f; } return 0.0; } diff --git a/lib/Hoymiles/src/parser/StatisticsParser.h b/lib/Hoymiles/src/parser/StatisticsParser.h index cc7cb76f..a8fa420d 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.h +++ b/lib/Hoymiles/src/parser/StatisticsParser.h @@ -8,7 +8,7 @@ #define STATISTIC_PACKET_SIZE (4 * 16) // units -enum { +enum UnitId_t { UNIT_V = 0, UNIT_A, UNIT_W, @@ -23,7 +23,7 @@ enum { const char* const units[] = { "V", "A", "W", "Wh", "kWh", "Hz", "°C", "%", "var", "" }; // field types -enum { +enum FieldId_t { FLD_UDC = 0, FLD_IDC, FLD_PDC, @@ -55,7 +55,7 @@ enum { enum { CMD_CALC = 0xffff }; // CH0 is default channel (freq, ac, temp) -enum { +enum ChannelNum_t { CH0 = 0, CH1, CH2, @@ -63,10 +63,18 @@ enum { CH4 }; +enum ChannelType_t { + TYPE_AC = 0, + TYPE_DC, + TYPE_INV +}; +const char* const channelsTypes[] = { "AC", "DC", "INV" }; + typedef struct { - uint8_t ch; // channel 0 - 4 - uint8_t fieldId; // field id - uint8_t unitId; // uint id + ChannelType_t type; + ChannelNum_t ch; // channel 0 - 4 + FieldId_t fieldId; // field id + UnitId_t unitId; // uint id uint8_t start; // pos of first byte in buffer uint8_t num; // number of bytes in buffer uint16_t div; // divisor / calc command @@ -81,14 +89,16 @@ public: void setByteAssignment(const std::list* byteAssignment); - const byteAssign_t* getAssignmentByChannelField(uint8_t channel, uint8_t fieldId); - float getChannelFieldValue(uint8_t channel, uint8_t fieldId); - bool hasChannelFieldValue(uint8_t channel, uint8_t fieldId); - const char* getChannelFieldUnit(uint8_t channel, uint8_t fieldId); - const char* getChannelFieldName(uint8_t channel, uint8_t fieldId); - uint8_t getChannelFieldDigits(uint8_t channel, uint8_t fieldId); + const byteAssign_t* getAssignmentByChannelField(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); + float getChannelFieldValue(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); + bool hasChannelFieldValue(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); + const char* getChannelFieldUnit(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); + const char* getChannelFieldName(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); + uint8_t getChannelFieldDigits(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId); - uint8_t getChannelCount(); + std::list getChannelTypes(); + const char* getChannelTypeName(ChannelType_t type); + std::list getChannelsByType(ChannelType_t type); uint16_t getChannelMaxPower(uint8_t channel); void setChannelMaxPower(uint8_t channel, uint16_t power); diff --git a/src/Display_Graphic.cpp b/src/Display_Graphic.cpp index aa192b92..23c826ea 100644 --- a/src/Display_Graphic.cpp +++ b/src/Display_Graphic.cpp @@ -37,7 +37,8 @@ std::map }; DisplayGraphicClass::DisplayGraphicClass() -{} +{ +} DisplayGraphicClass::~DisplayGraphicClass() { @@ -88,7 +89,7 @@ void DisplayGraphicClass::printText(const char* text, uint8_t line) break; } - // get the font height, to calculate the textheight + // get the font height, to calculate the textheight _dispY += (_display->getMaxCharHeight()) + 1; // calculate the starting position of the text @@ -126,9 +127,11 @@ void DisplayGraphicClass::loop() isprod++; } - totalPower += inv->Statistics()->getChannelFieldValue(CH0, FLD_PAC); - totalYieldDay += inv->Statistics()->getChannelFieldValue(CH0, FLD_YD); - totalYieldTotal += inv->Statistics()->getChannelFieldValue(CH0, FLD_YT); + for (auto& c : inv->Statistics()->getChannelsByType(TYPE_AC)) { + totalPower += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_PAC); + totalYieldDay += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_YD); + totalYieldTotal += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_YT); + } } _display->clearBuffer(); diff --git a/src/MqttHandleHass.cpp b/src/MqttHandleHass.cpp index 5afd6dd9..916bdb2c 100644 --- a/src/MqttHandleHass.cpp +++ b/src/MqttHandleHass.cpp @@ -65,13 +65,15 @@ void MqttHandleHassClass::publishConfig() publishInverterBinarySensor(inv, "Producing", "status/producing", "1", "0"); // Loop all channels - for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) { - for (uint8_t f = 0; f < DEVICE_CLS_ASSIGN_LIST_LEN; f++) { - bool clear = false; - if (c > 0 && !config.Mqtt_Hass_IndividualPanels) { - clear = true; + for (auto& t : inv->Statistics()->getChannelTypes()) { + for (auto& c : inv->Statistics()->getChannelsByType(t)) { + for (uint8_t f = 0; f < DEVICE_CLS_ASSIGN_LIST_LEN; f++) { + bool clear = false; + if (t == TYPE_DC && !config.Mqtt_Hass_IndividualPanels) { + clear = true; + } + publishField(inv, t, c, deviceFieldAssignment[f], clear); } - publishField(inv, c, deviceFieldAssignment[f], clear); } } @@ -79,32 +81,40 @@ void MqttHandleHassClass::publishConfig() } } -void MqttHandleHassClass::publishField(std::shared_ptr inv, uint8_t channel, byteAssign_fieldDeviceClass_t fieldType, bool clear) +void MqttHandleHassClass::publishField(std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, byteAssign_fieldDeviceClass_t fieldType, bool clear) { - if (!inv->Statistics()->hasChannelFieldValue(channel, fieldType.fieldId)) { + if (!inv->Statistics()->hasChannelFieldValue(type, channel, fieldType.fieldId)) { return; } String serial = inv->serialString(); String fieldName; - if (channel == CH0 && fieldType.fieldId == FLD_PDC) { + if (type == TYPE_AC && fieldType.fieldId == FLD_PDC) { fieldName = "PowerDC"; } else { - fieldName = inv->Statistics()->getChannelFieldName(channel, fieldType.fieldId); + fieldName = inv->Statistics()->getChannelFieldName(type, channel, fieldType.fieldId); + } + + String chanNum; + if (type == TYPE_DC) { + // TODO(tbnobody) + chanNum = static_cast(channel) + 1; + } else { + chanNum = channel; } String configTopic = "sensor/dtu_" + serial - + "/" + "ch" + String(channel) + "_" + fieldName + + "/" + "ch" + chanNum + "_" + fieldName + "/config"; if (!clear) { - String stateTopic = MqttSettings.getPrefix() + MqttHandleInverter.getTopic(inv, channel, fieldType.fieldId); + String stateTopic = MqttSettings.getPrefix() + MqttHandleInverter.getTopic(inv, type, channel, fieldType.fieldId); const char* devCls = deviceClasses[fieldType.deviceClsId]; const char* stateCls = stateClasses[fieldType.stateClsId]; String name; - if (channel == CH0) { + if (type != TYPE_DC) { name = String(inv->name()) + " " + fieldName; } else { name = String(inv->name()) + " CH" + String(channel) + " " + fieldName; @@ -115,7 +125,7 @@ void MqttHandleHassClass::publishField(std::shared_ptr inv, ui root[F("stat_t")] = stateTopic; root[F("uniq_id")] = serial + "_ch" + String(channel) + "_" + fieldName; - String unit_of_measure = inv->Statistics()->getChannelFieldUnit(channel, fieldType.fieldId); + String unit_of_measure = inv->Statistics()->getChannelFieldUnit(type, channel, fieldType.fieldId); if (unit_of_measure != "") { root[F("unit_of_meas")] = unit_of_measure; } diff --git a/src/MqttHandleInverter.cpp b/src/MqttHandleInverter.cpp index 46cc0d2b..3703630c 100644 --- a/src/MqttHandleInverter.cpp +++ b/src/MqttHandleInverter.cpp @@ -96,15 +96,18 @@ void MqttHandleInverterClass::loop() _lastPublishStats[i] = lastUpdate; // Loop all channels - for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) { - if (c > 0) { - INVERTER_CONFIG_T* inv_cfg = Configuration.getInverterConfig(inv->serial()); - if (inv_cfg != nullptr) { - MqttSettings.publish(inv->serialString() + "/" + String(c) + "/name", inv_cfg->channel[c - 1].Name); + for (auto& t : inv->Statistics()->getChannelTypes()) { + for (auto& c : inv->Statistics()->getChannelsByType(t)) { + if (t == TYPE_DC) { + INVERTER_CONFIG_T* inv_cfg = Configuration.getInverterConfig(inv->serial()); + if (inv_cfg != nullptr) { + // TODO(tbnobody) + MqttSettings.publish(inv->serialString() + "/" + String(static_cast(c) + 1) + "/name", inv_cfg->channel[c].Name); + } + } + for (uint8_t f = 0; f < sizeof(_publishFields) / sizeof(FieldId_t); f++) { + publishField(inv, t, c, _publishFields[f]); } - } - for (uint8_t f = 0; f < sizeof(_publishFields); f++) { - publishField(inv, c, _publishFields[f]); } } } @@ -116,31 +119,39 @@ void MqttHandleInverterClass::loop() } } -void MqttHandleInverterClass::publishField(std::shared_ptr inv, uint8_t channel, uint8_t fieldId) +void MqttHandleInverterClass::publishField(std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { - String topic = getTopic(inv, channel, fieldId); + String topic = getTopic(inv, type, channel, fieldId); if (topic == "") { return; } - MqttSettings.publish(topic, String(inv->Statistics()->getChannelFieldValue(channel, fieldId))); + MqttSettings.publish(topic, String(inv->Statistics()->getChannelFieldValue(type, channel, fieldId))); } -String MqttHandleInverterClass::getTopic(std::shared_ptr inv, uint8_t channel, uint8_t fieldId) +String MqttHandleInverterClass::getTopic(std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId) { - if (!inv->Statistics()->hasChannelFieldValue(channel, fieldId)) { + if (!inv->Statistics()->hasChannelFieldValue(type, channel, fieldId)) { return String(""); } String chanName; - if (channel == 0 && fieldId == FLD_PDC) { + if (type == TYPE_AC && fieldId == FLD_PDC) { chanName = "powerdc"; } else { - chanName = inv->Statistics()->getChannelFieldName(channel, fieldId); + chanName = inv->Statistics()->getChannelFieldName(type, channel, fieldId); chanName.toLowerCase(); } - return inv->serialString() + "/" + String(channel) + "/" + chanName; + String chanNum; + if (type == TYPE_DC) { + // TODO(tbnobody) + chanNum = static_cast(channel) + 1; + } else { + chanNum = channel; + } + + return inv->serialString() + "/" + chanNum + "/" + chanName; } void MqttHandleInverterClass::onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) diff --git a/src/WebApi_inverter.cpp b/src/WebApi_inverter.cpp index cda8f338..1e844e44 100644 --- a/src/WebApi_inverter.cpp +++ b/src/WebApi_inverter.cpp @@ -59,7 +59,7 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request) max_channels = INV_MAX_CHAN_COUNT; } else { obj[F("type")] = inv->typeName(); - max_channels = inv->Statistics()->getChannelCount(); + max_channels = inv->Statistics()->getChannelsByType(TYPE_DC).size(); } JsonArray channel = obj.createNestedArray("channel"); diff --git a/src/WebApi_prometheus.cpp b/src/WebApi_prometheus.cpp index 45f23ff6..b200abf8 100644 --- a/src/WebApi_prometheus.cpp +++ b/src/WebApi_prometheus.cpp @@ -63,39 +63,48 @@ void WebApiPrometheusClass::onPrometheusMetricsGet(AsyncWebServerRequest* reques serial.c_str(), i, name, inv->Statistics()->getLastUpdate() / 1000); // Loop all channels - for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) { - addField(stream, serial, i, inv, c, FLD_PAC); - addField(stream, serial, i, inv, c, FLD_UAC); - addField(stream, serial, i, inv, c, FLD_IAC); - if (c == 0) { - addField(stream, serial, i, inv, c, FLD_PDC, "PowerDC"); - } else { - addField(stream, serial, i, inv, c, FLD_PDC); + for (auto& t : inv->Statistics()->getChannelTypes()) { + for (auto& c : inv->Statistics()->getChannelsByType(t)) { + addField(stream, serial, i, inv, t, c, FLD_PAC); + addField(stream, serial, i, inv, t, c, FLD_UAC); + addField(stream, serial, i, inv, t, c, FLD_IAC); + if (t == TYPE_AC) { + addField(stream, serial, i, inv, t, c, FLD_PDC, "PowerDC"); + } else { + addField(stream, serial, i, inv, t, c, FLD_PDC); + } + addField(stream, serial, i, inv, t, c, FLD_UDC); + addField(stream, serial, i, inv, t, c, FLD_IDC); + addField(stream, serial, i, inv, t, c, FLD_YD); + addField(stream, serial, i, inv, t, c, FLD_YT); + addField(stream, serial, i, inv, t, c, FLD_F); + addField(stream, serial, i, inv, t, c, FLD_T); + addField(stream, serial, i, inv, t, c, FLD_PF); + addField(stream, serial, i, inv, t, c, FLD_PRA); + addField(stream, serial, i, inv, t, c, FLD_EFF); + addField(stream, serial, i, inv, t, c, FLD_IRR); } - addField(stream, serial, i, inv, c, FLD_UDC); - addField(stream, serial, i, inv, c, FLD_IDC); - addField(stream, serial, i, inv, c, FLD_YD); - addField(stream, serial, i, inv, c, FLD_YT); - addField(stream, serial, i, inv, c, FLD_F); - addField(stream, serial, i, inv, c, FLD_T); - addField(stream, serial, i, inv, c, FLD_PF); - addField(stream, serial, i, inv, c, FLD_PRA); - addField(stream, serial, i, inv, c, FLD_EFF); - addField(stream, serial, i, inv, c, FLD_IRR); } } stream->addHeader(F("Cache-Control"), F("no-cache")); request->send(stream); } -void WebApiPrometheusClass::addField(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr inv, uint8_t channel, uint8_t fieldId, const char* channelName) +void WebApiPrometheusClass::addField(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, const char* channelName) { - if (inv->Statistics()->hasChannelFieldValue(channel, fieldId)) { - const char* chanName = (channelName == NULL) ? inv->Statistics()->getChannelFieldName(channel, fieldId) : channelName; - if (idx == 0 && channel == 0) { - stream->printf("# HELP opendtu_%s in %s\n", chanName, inv->Statistics()->getChannelFieldUnit(channel, fieldId)); + if (inv->Statistics()->hasChannelFieldValue(type, channel, fieldId)) { + const char* chanName = (channelName == NULL) ? inv->Statistics()->getChannelFieldName(type, channel, fieldId) : channelName; + if (idx == 0 && type == TYPE_AC && channel == 0) { + stream->printf("# HELP opendtu_%s in %s\n", chanName, inv->Statistics()->getChannelFieldUnit(type, channel, fieldId)); stream->printf("# TYPE opendtu_%s gauge\n", chanName); } - stream->printf("opendtu_%s{serial=\"%s\",unit=\"%d\",name=\"%s\",channel=\"%d\"} %f\n", chanName, serial.c_str(), idx, inv->name(), channel, inv->Statistics()->getChannelFieldValue(channel, fieldId)); + stream->printf("opendtu_%s{serial=\"%s\",unit=\"%d\",name=\"%s\",type=\"%s\",channel=\"%d\"} %f\n", + chanName, + serial.c_str(), + idx, + inv->name(), + inv->Statistics()->getChannelTypeName(type), + channel, + inv->Statistics()->getChannelFieldValue(type, channel, fieldId)); } } \ No newline at end of file diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index ae1ed188..737cefe7 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -111,36 +111,39 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root) } // Loop all channels - for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) { - if (c > 0) { - INVERTER_CONFIG_T* inv_cfg = Configuration.getInverterConfig(inv->serial()); - if (inv_cfg != nullptr) { - invObject[String(c)][F("name")]["u"] = inv_cfg->channel[c - 1].Name; + for (auto& t : inv->Statistics()->getChannelTypes()) { + for (auto& c : inv->Statistics()->getChannelsByType(t)) { + if (t == TYPE_DC) { + INVERTER_CONFIG_T* inv_cfg = Configuration.getInverterConfig(inv->serial()); + if (inv_cfg != nullptr) { + // TODO(tbnobody) + invObject[String(static_cast(c) + 1)][F("name")]["u"] = inv_cfg->channel[c].Name; + } + } + addField(invObject, i, inv, t, c, FLD_PAC); + addField(invObject, i, inv, t, c, FLD_UAC); + addField(invObject, i, inv, t, c, FLD_IAC); + if (t == TYPE_AC) { + addField(invObject, i, inv, t, c, FLD_PDC, F("Power DC")); + } else { + addField(invObject, i, inv, t, c, FLD_PDC); + } + addField(invObject, i, inv, t, c, FLD_UDC); + addField(invObject, i, inv, t, c, FLD_IDC); + addField(invObject, i, inv, t, c, FLD_YD); + addField(invObject, i, inv, t, c, FLD_YT); + addField(invObject, i, inv, t, c, FLD_F); + addField(invObject, i, inv, t, c, FLD_T); + addField(invObject, i, inv, t, c, FLD_PF); + addField(invObject, i, inv, t, c, FLD_PRA); + addField(invObject, i, inv, t, c, FLD_EFF); + if (t == TYPE_DC && inv->Statistics()->getChannelMaxPower(c) > 0) { + addField(invObject, i, inv, t, c, FLD_IRR); } - } - addField(invObject, i, inv, c, FLD_PAC); - addField(invObject, i, inv, c, FLD_UAC); - addField(invObject, i, inv, c, FLD_IAC); - if (c == 0) { - addField(invObject, i, inv, c, FLD_PDC, F("Power DC")); - } else { - addField(invObject, i, inv, c, FLD_PDC); - } - addField(invObject, i, inv, c, FLD_UDC); - addField(invObject, i, inv, c, FLD_IDC); - addField(invObject, i, inv, c, FLD_YD); - addField(invObject, i, inv, c, FLD_YT); - addField(invObject, i, inv, c, FLD_F); - addField(invObject, i, inv, c, FLD_T); - addField(invObject, i, inv, c, FLD_PF); - addField(invObject, i, inv, c, FLD_PRA); - addField(invObject, i, inv, c, FLD_EFF); - if (c > 0 && inv->Statistics()->getChannelMaxPower(c - 1) > 0) { - addField(invObject, i, inv, c, FLD_IRR); } } - if (inv->Statistics()->hasChannelFieldValue(CH0, FLD_EVT_LOG)) { + if (inv->Statistics()->hasChannelFieldValue(TYPE_INV, CH0, FLD_EVT_LOG)) { invObject[F("events")] = inv->EventLog()->getEntryCount(); } else { invObject[F("events")] = -1; @@ -150,9 +153,11 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root) _newestInverterTimestamp = inv->Statistics()->getLastUpdate(); } - totalPower += inv->Statistics()->getChannelFieldValue(CH0, FLD_PAC); - totalYieldDay += inv->Statistics()->getChannelFieldValue(CH0, FLD_YD); - totalYieldTotal += inv->Statistics()->getChannelFieldValue(CH0, FLD_YT); + for (auto& c : inv->Statistics()->getChannelsByType(TYPE_AC)) { + totalPower += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_PAC); + totalYieldDay += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_YD); + totalYieldTotal += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_YT); + } } JsonObject totalObj = root.createNestedObject("total"); @@ -172,18 +177,25 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root) } } -void WebApiWsLiveClass::addField(JsonObject& root, uint8_t idx, std::shared_ptr inv, uint8_t channel, uint8_t fieldId, String topic) +void WebApiWsLiveClass::addField(JsonObject& root, uint8_t idx, std::shared_ptr inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, String topic) { - if (inv->Statistics()->hasChannelFieldValue(channel, fieldId)) { + if (inv->Statistics()->hasChannelFieldValue(type, channel, fieldId)) { String chanName; if (topic == "") { - chanName = inv->Statistics()->getChannelFieldName(channel, fieldId); + chanName = inv->Statistics()->getChannelFieldName(type, channel, fieldId); } else { chanName = topic; } - root[String(channel)][chanName]["v"] = inv->Statistics()->getChannelFieldValue(channel, fieldId); - root[String(channel)][chanName]["u"] = inv->Statistics()->getChannelFieldUnit(channel, fieldId); - root[String(channel)][chanName]["d"] = inv->Statistics()->getChannelFieldDigits(channel, fieldId); + String chanNum; + if (type == TYPE_DC) { + // TODO(tbnobody) + chanNum = static_cast(channel) + 1; + } else { + chanNum = channel; + } + root[chanNum][chanName]["v"] = inv->Statistics()->getChannelFieldValue(type, channel, fieldId); + root[chanNum][chanName]["u"] = inv->Statistics()->getChannelFieldUnit(type, channel, fieldId); + root[chanNum][chanName]["d"] = inv->Statistics()->getChannelFieldDigits(type, channel, fieldId); } } From ceaf08c1a080f3001fb26c272f839897ad35f4fc Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Mon, 6 Feb 2023 19:56:12 +0100 Subject: [PATCH 05/12] Hoymiles Lib: Rename ChannelMaxPower to StringMaxPower --- lib/Hoymiles/src/parser/StatisticsParser.cpp | 14 +++++++------- lib/Hoymiles/src/parser/StatisticsParser.h | 6 +++--- src/WebApi_inverter.cpp | 4 ++-- src/WebApi_ws_live.cpp | 2 +- src/main.cpp | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/Hoymiles/src/parser/StatisticsParser.cpp b/lib/Hoymiles/src/parser/StatisticsParser.cpp index cccf760e..79ff16da 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.cpp +++ b/lib/Hoymiles/src/parser/StatisticsParser.cpp @@ -147,15 +147,15 @@ std::list StatisticsParser::getChannelsByType(ChannelType_t type) return l; } -uint16_t StatisticsParser::getChannelMaxPower(uint8_t channel) +uint16_t StatisticsParser::getStringMaxPower(uint8_t channel) { - return _chanMaxPower[channel]; + return _stringMaxPower[channel]; } -void StatisticsParser::setChannelMaxPower(uint8_t channel, uint16_t power) +void StatisticsParser::setStringMaxPower(uint8_t channel, uint16_t power) { - if (channel < sizeof(_chanMaxPower) / sizeof(_chanMaxPower[0])) { - _chanMaxPower[channel] = power; + if (channel < sizeof(_stringMaxPower) / sizeof(_stringMaxPower[0])) { + _stringMaxPower[channel] = power; } } @@ -230,8 +230,8 @@ static float calcEffiencyCh0(StatisticsParser* iv, uint8_t arg0) static float calcIrradiation(StatisticsParser* iv, uint8_t arg0) { if (NULL != iv) { - if (iv->getChannelMaxPower(arg0) > 0) - return iv->getChannelFieldValue(TYPE_DC, static_cast(arg0), FLD_PDC) / iv->getChannelMaxPower(arg0) * 100.0f; + if (iv->getStringMaxPower(arg0) > 0) + return iv->getChannelFieldValue(TYPE_DC, static_cast(arg0), FLD_PDC) / iv->getStringMaxPower(arg0) * 100.0f; } return 0.0; } diff --git a/lib/Hoymiles/src/parser/StatisticsParser.h b/lib/Hoymiles/src/parser/StatisticsParser.h index a8fa420d..36116790 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.h +++ b/lib/Hoymiles/src/parser/StatisticsParser.h @@ -100,8 +100,8 @@ public: const char* getChannelTypeName(ChannelType_t type); std::list getChannelsByType(ChannelType_t type); - uint16_t getChannelMaxPower(uint8_t channel); - void setChannelMaxPower(uint8_t channel, uint16_t power); + uint16_t getStringMaxPower(uint8_t channel); + void setStringMaxPower(uint8_t channel, uint16_t power); void resetRxFailureCount(); void incrementRxFailureCount(); @@ -110,7 +110,7 @@ public: private: uint8_t _payloadStatistic[STATISTIC_PACKET_SIZE] = {}; uint8_t _statisticLength = 0; - uint16_t _chanMaxPower[CH4]; + uint16_t _stringMaxPower[CH4]; const std::list* _byteAssignment; diff --git a/src/WebApi_inverter.cpp b/src/WebApi_inverter.cpp index 1e844e44..4305c87d 100644 --- a/src/WebApi_inverter.cpp +++ b/src/WebApi_inverter.cpp @@ -167,7 +167,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) if (inv != nullptr) { for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { - inv->Statistics()->setChannelMaxPower(c, inverter->channel[c].MaxChannelPower); + inv->Statistics()->setStringMaxPower(c, inverter->channel[c].MaxChannelPower); } } @@ -296,7 +296,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) if (inv != nullptr) { for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { - inv->Statistics()->setChannelMaxPower(c, inverter.channel[c].MaxChannelPower); + inv->Statistics()->setStringMaxPower(c, inverter.channel[c].MaxChannelPower); } } diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index 737cefe7..459197ec 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -137,7 +137,7 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root) addField(invObject, i, inv, t, c, FLD_PF); addField(invObject, i, inv, t, c, FLD_PRA); addField(invObject, i, inv, t, c, FLD_EFF); - if (t == TYPE_DC && inv->Statistics()->getChannelMaxPower(c) > 0) { + if (t == TYPE_DC && inv->Statistics()->getStringMaxPower(c) > 0) { addField(invObject, i, inv, t, c, FLD_IRR); } } diff --git a/src/main.cpp b/src/main.cpp index a68ac0ad..56aa65b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -149,7 +149,7 @@ void setup() if (inv != nullptr) { for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { - inv->Statistics()->setChannelMaxPower(c, config.Inverter[i].channel[c].MaxChannelPower); + inv->Statistics()->setStringMaxPower(c, config.Inverter[i].channel[c].MaxChannelPower); } } MessageOutput.println(F(" done")); From 24ad73fc160853fedc84e5d798d84f3b82b0c984 Mon Sep 17 00:00:00 2001 From: Dennis Rathjen Date: Mon, 6 Feb 2023 20:26:21 +0100 Subject: [PATCH 06/12] Added missing topic in 'DC input channel topics'. --- docs/MQTT_Topics.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/MQTT_Topics.md b/docs/MQTT_Topics.md index 2c6206e3..3445486e 100644 --- a/docs/MQTT_Topics.md +++ b/docs/MQTT_Topics.md @@ -51,6 +51,7 @@ serial will be replaced with the serial number of the inverter. | Topic | R / W | Description | Value / Unit | | --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- | | [serial]/[1-4]/current | R | DC current of specific input in ampere | Ampere (A) | +| [serial]/[1-4]/name | R | Name of the DC input channel as configured in web GUI| | | [serial]/[1-4]/irradiation | R | Ratio DC Power over set maximum power (in web GUI) | % | | [serial]/[1-4]/power | R | DC power of specific input in watt | Watt (W) | | [serial]/[1-4]/voltage | R | DC voltage of specific input in volt | Volt (V) | From e97bddcce1f755a2a66e6997b2577bd649a69ba3 Mon Sep 17 00:00:00 2001 From: Felix Schulze Date: Mon, 13 Feb 2023 15:18:53 +0100 Subject: [PATCH 07/12] New case with display --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dee06188..68f1a23d 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,7 @@ A documentation of the Web API can be found here: [Web-API Documentation](docs/W * * * +* ## Building From 3b7aef63f85f6f5bcbb204e5a3bc56a69db562ce Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Mon, 13 Feb 2023 18:37:55 +0100 Subject: [PATCH 08/12] BREAKING CHANGE: Web API! In order to support multiple AC channels in future the WebAPI had to be changed. AC and DC channels are now grouped in a sub object containing the channels beginning with 0. --- docs/Web-API.md | 590 ++++++++++-------- src/WebApi_ws_live.cpp | 41 +- webapp/src/components/InverterChannelInfo.vue | 29 +- webapp/src/locales/de.json | 1 + webapp/src/locales/en.json | 1 + webapp/src/locales/fr.json | 1 + webapp/src/types/LiveDataStatus.ts | 4 +- webapp/src/views/HomeView.vue | 11 +- 8 files changed, 394 insertions(+), 284 deletions(-) diff --git a/docs/Web-API.md b/docs/Web-API.md index cd640782..f772b05c 100644 --- a/docs/Web-API.md +++ b/docs/Web-API.md @@ -56,7 +56,7 @@ You can "talk" to the OpenDTU with a command line tool like `curl`. The output i ``` ~$ curl http://192.168.10.10/api/livedata/status -{"inverters":[{"serial":"11418186xxxx","name":"HM600","data_age":4,"reachable":true,"producing":true,"limit_relative":100,"limit_absolute":600,"0":{"Power":{"v":70.69999695,"u":"W","d":1},"Voltage":{"v":233,"u":"V","d":1},"Current":{"v":0.300000012,"u":"A","d":2},"Power DC":{"v":74,"u":"W","d":2},"YieldDay":{"v":23,"u":"Wh","d":2},"YieldTotal":{"v":150.5050049,"u":"kWh","d":2},"Frequency":{"v":50.02000046,"u":"Hz","d":2},"Temperature":{"v":8.300000191,"u":"°C","d":1},"PowerFactor":{"v":1,"u":"","d":3},"ReactivePower":{"v":0.100000001,"u":"var","d":1},"Efficiency":{"v":95.54053497,"u":"%","d":2}},"1":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":1,"u":"V","d":1},"Current":{"v":0.02,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":49.0320015,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":2}},"2":{"Power":{"v":74,"u":"W","d":1},"Voltage":{"v":42.40000153,"u":"V","d":1},"Current":{"v":1.74000001,"u":"A","d":2},"YieldDay":{"v":23,"u":"Wh","d":0},"YieldTotal":{"v":101.4729996,"u":"kWh","d":3},"Irradiation":{"v":18.04878044,"u":"%","d":2}},"events":3},{"serial":"11418180xxxx","name":"HM800","data_age":11,"reachable":true,"producing":true,"limit_relative":100,"limit_absolute":800,"0":{"Power":{"v":70.09999847,"u":"W","d":1},"Voltage":{"v":233.1000061,"u":"V","d":1},"Current":{"v":0.300000012,"u":"A","d":2},"Power DC":{"v":73.59999847,"u":"W","d":2},"YieldDay":{"v":48,"u":"Wh","d":2},"YieldTotal":{"v":48.5399971,"u":"kWh","d":2},"Frequency":{"v":50.02000046,"u":"Hz","d":2},"Temperature":{"v":11.39999962,"u":"°C","d":1},"PowerFactor":{"v":1,"u":"","d":3},"ReactivePower":{"v":0.100000001,"u":"var","d":1},"Efficiency":{"v":95.24456024,"u":"%","d":2}},"1":{"Power":{"v":36.5,"u":"W","d":1},"Voltage":{"v":39.09999847,"u":"V","d":1},"Current":{"v":0.930000007,"u":"A","d":2},"YieldDay":{"v":31,"u":"Wh","d":0},"YieldTotal":{"v":4.301000118,"u":"kWh","d":3},"Irradiation":{"v":8.902439117,"u":"%","d":2}},"2":{"Power":{"v":37.09999847,"u":"W","d":1},"Voltage":{"v":40.79999924,"u":"V","d":1},"Current":{"v":0.910000026,"u":"A","d":2},"YieldDay":{"v":17,"u":"Wh","d":0},"YieldTotal":{"v":44.23899841,"u":"kWh","d":3},"Irradiation":{"v":9.048780441,"u":"%","d":2}},"events":1}],"total":{"Power":{"v":140.7999878,"u":"W","d":1},"YieldDay":{"v":71,"u":"Wh","d":0},"YieldTotal":{"v":199.0449982,"u":"kWh","d":2}}} +{"inverters":[{"serial":"11617160xxxx","name":"Meine Solaranlage","data_age":6983,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"DC":{"0":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"1":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"2":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"3":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3}}},"INV":{"0":{"Temperature":{"v":0,"u":"°C","d":1}}},"events":0},{"serial":"11417160xxxx","name":"test","data_age":6983,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"DC":{"0":{"name":{"u":"test 1"},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"1":{"name":{"u":"test 2"},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}}},"INV":{"0":{"Temperature":{"v":0,"u":"°C","d":1}}},"events":0}],"total":{"Power":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":2}},"hints":{"time_sync":false,"radio_problem":false,"default_password":false}} ``` @@ -67,284 +67,382 @@ To enhance readability (and filter information) use the JSON command line proces { "inverters": [ { - "serial": "11418186xxxx", - "name": "HM600", - "data_age": 4, - "reachable": true, - "producing": true, - "limit_relative": 100, - "limit_absolute": 600, - "0": { - "Power": { - "v": 70.69999695, - "u": "W", - "d": 1 - }, - "Voltage": { - "v": 233, - "u": "V", - "d": 1 - }, - "Current": { - "v": 0.300000012, - "u": "A", - "d": 2 - }, - "Power DC": { - "v": 74, - "u": "W", - "d": 2 - }, - "YieldDay": { - "v": 23, - "u": "Wh", - "d": 2 - }, - "YieldTotal": { - "v": 150.5050049, - "u": "kWh", - "d": 2 - }, - "Frequency": { - "v": 50.02000046, - "u": "Hz", - "d": 2 - }, - "Temperature": { - "v": 8.300000191, - "u": "°C", - "d": 1 - }, - "PowerFactor": { - "v": 1, - "u": "", - "d": 3 - }, - "ReactivePower": { - "v": 0.100000001, - "u": "var", - "d": 1 - }, - "Efficiency": { - "v": 95.54053497, - "u": "%", - "d": 2 + "serial": "116171603546", + "name": "Meine Solaranlage", + "data_age": 7038, + "reachable": false, + "producing": false, + "limit_relative": 0, + "limit_absolute": -1, + "AC": { + "0": { + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "Power DC": { + "v": 0, + "u": "W", + "d": 1 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + }, + "Frequency": { + "v": 0, + "u": "Hz", + "d": 2 + }, + "PowerFactor": { + "v": 0, + "u": "", + "d": 3 + }, + "ReactivePower": { + "v": 0, + "u": "var", + "d": 1 + }, + "Efficiency": { + "v": 0, + "u": "%", + "d": 3 + } } }, - "1": { - "Power": { - "v": 0, - "u": "W", - "d": 1 + "DC": { + "0": { + "name": { + "u": "" + }, + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + }, + "Irradiation": { + "v": 0, + "u": "%", + "d": 3 + } }, - "Voltage": { - "v": 1, - "u": "V", - "d": 1 + "1": { + "name": { + "u": "" + }, + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + }, + "Irradiation": { + "v": 0, + "u": "%", + "d": 3 + } }, - "Current": { - "v": 0.02, - "u": "A", - "d": 2 + "2": { + "name": { + "u": "" + }, + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + }, + "Irradiation": { + "v": 0, + "u": "%", + "d": 3 + } }, - "YieldDay": { - "v": 0, - "u": "Wh", - "d": 0 - }, - "YieldTotal": { - "v": 49.0320015, - "u": "kWh", - "d": 3 - }, - "Irradiation": { - "v": 0, - "u": "%", - "d": 2 + "3": { + "name": { + "u": "" + }, + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + } } }, - "2": { - "Power": { - "v": 74, - "u": "W", - "d": 1 - }, - "Voltage": { - "v": 42.40000153, - "u": "V", - "d": 1 - }, - "Current": { - "v": 1.74000001, - "u": "A", - "d": 2 - }, - "YieldDay": { - "v": 23, - "u": "Wh", - "d": 0 - }, - "YieldTotal": { - "v": 101.4729996, - "u": "kWh", - "d": 3 - }, - "Irradiation": { - "v": 18.04878044, - "u": "%", - "d": 2 + "INV": { + "0": { + "Temperature": { + "v": 0, + "u": "°C", + "d": 1 + } } }, - "events": 3 + "events": 0 }, { - "serial": "11418180xxxx", - "name": "HM800", - "data_age": 11, - "reachable": true, - "producing": true, - "limit_relative": 100, - "limit_absolute": 800, - "0": { - "Power": { - "v": 70.09999847, - "u": "W", - "d": 1 - }, - "Voltage": { - "v": 233.1000061, - "u": "V", - "d": 1 - }, - "Current": { - "v": 0.300000012, - "u": "A", - "d": 2 - }, - "Power DC": { - "v": 73.59999847, - "u": "W", - "d": 2 - }, - "YieldDay": { - "v": 48, - "u": "Wh", - "d": 2 - }, - "YieldTotal": { - "v": 48.5399971, - "u": "kWh", - "d": 2 - }, - "Frequency": { - "v": 50.02000046, - "u": "Hz", - "d": 2 - }, - "Temperature": { - "v": 11.39999962, - "u": "°C", - "d": 1 - }, - "PowerFactor": { - "v": 1, - "u": "", - "d": 3 - }, - "ReactivePower": { - "v": 0.100000001, - "u": "var", - "d": 1 - }, - "Efficiency": { - "v": 95.24456024, - "u": "%", - "d": 2 + "serial": "114171603548", + "name": "test", + "data_age": 7038, + "reachable": false, + "producing": false, + "limit_relative": 0, + "limit_absolute": -1, + "AC": { + "0": { + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "Power DC": { + "v": 0, + "u": "W", + "d": 1 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + }, + "Frequency": { + "v": 0, + "u": "Hz", + "d": 2 + }, + "PowerFactor": { + "v": 0, + "u": "", + "d": 3 + }, + "ReactivePower": { + "v": 0, + "u": "var", + "d": 1 + }, + "Efficiency": { + "v": 0, + "u": "%", + "d": 3 + } } }, - "1": { - "Power": { - "v": 36.5, - "u": "W", - "d": 1 + "DC": { + "0": { + "name": { + "u": "test 1" + }, + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + }, + "Irradiation": { + "v": 0, + "u": "%", + "d": 3 + } }, - "Voltage": { - "v": 39.09999847, - "u": "V", - "d": 1 - }, - "Current": { - "v": 0.930000007, - "u": "A", - "d": 2 - }, - "YieldDay": { - "v": 31, - "u": "Wh", - "d": 0 - }, - "YieldTotal": { - "v": 4.301000118, - "u": "kWh", - "d": 3 - }, - "Irradiation": { - "v": 8.902439117, - "u": "%", - "d": 2 + "1": { + "name": { + "u": "test 2" + }, + "Power": { + "v": 0, + "u": "W", + "d": 1 + }, + "Voltage": { + "v": 0, + "u": "V", + "d": 1 + }, + "Current": { + "v": 0, + "u": "A", + "d": 2 + }, + "YieldDay": { + "v": 0, + "u": "Wh", + "d": 0 + }, + "YieldTotal": { + "v": 0, + "u": "kWh", + "d": 3 + }, + "Irradiation": { + "v": 0, + "u": "%", + "d": 3 + } } }, - "2": { - "Power": { - "v": 37.09999847, - "u": "W", - "d": 1 - }, - "Voltage": { - "v": 40.79999924, - "u": "V", - "d": 1 - }, - "Current": { - "v": 0.910000026, - "u": "A", - "d": 2 - }, - "YieldDay": { - "v": 17, - "u": "Wh", - "d": 0 - }, - "YieldTotal": { - "v": 44.23899841, - "u": "kWh", - "d": 3 - }, - "Irradiation": { - "v": 9.048780441, - "u": "%", - "d": 2 + "INV": { + "0": { + "Temperature": { + "v": 0, + "u": "°C", + "d": 1 + } } }, - "events": 1 + "events": 0 } ], "total": { "Power": { - "v": 140.7999878, + "v": 0, "u": "W", "d": 1 }, "YieldDay": { - "v": 71, + "v": 0, "u": "Wh", "d": 0 }, "YieldTotal": { - "v": 199.0449982, + "v": 0, "u": "kWh", "d": 2 } + }, + "hints": { + "time_sync": false, + "radio_problem": false, + "default_password": false } } ``` diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index 459197ec..fedc9fff 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -112,33 +112,33 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root) // Loop all channels for (auto& t : inv->Statistics()->getChannelTypes()) { + JsonObject chanTypeObj = invObject.createNestedObject(inv->Statistics()->getChannelTypeName(t)); for (auto& c : inv->Statistics()->getChannelsByType(t)) { if (t == TYPE_DC) { INVERTER_CONFIG_T* inv_cfg = Configuration.getInverterConfig(inv->serial()); if (inv_cfg != nullptr) { - // TODO(tbnobody) - invObject[String(static_cast(c) + 1)][F("name")]["u"] = inv_cfg->channel[c].Name; + chanTypeObj[String(static_cast(c))][F("name")]["u"] = inv_cfg->channel[c].Name; } } - addField(invObject, i, inv, t, c, FLD_PAC); - addField(invObject, i, inv, t, c, FLD_UAC); - addField(invObject, i, inv, t, c, FLD_IAC); + addField(chanTypeObj, i, inv, t, c, FLD_PAC); + addField(chanTypeObj, i, inv, t, c, FLD_UAC); + addField(chanTypeObj, i, inv, t, c, FLD_IAC); if (t == TYPE_AC) { - addField(invObject, i, inv, t, c, FLD_PDC, F("Power DC")); + addField(chanTypeObj, i, inv, t, c, FLD_PDC, F("Power DC")); } else { - addField(invObject, i, inv, t, c, FLD_PDC); + addField(chanTypeObj, i, inv, t, c, FLD_PDC); } - addField(invObject, i, inv, t, c, FLD_UDC); - addField(invObject, i, inv, t, c, FLD_IDC); - addField(invObject, i, inv, t, c, FLD_YD); - addField(invObject, i, inv, t, c, FLD_YT); - addField(invObject, i, inv, t, c, FLD_F); - addField(invObject, i, inv, t, c, FLD_T); - addField(invObject, i, inv, t, c, FLD_PF); - addField(invObject, i, inv, t, c, FLD_PRA); - addField(invObject, i, inv, t, c, FLD_EFF); + addField(chanTypeObj, i, inv, t, c, FLD_UDC); + addField(chanTypeObj, i, inv, t, c, FLD_IDC); + addField(chanTypeObj, i, inv, t, c, FLD_YD); + addField(chanTypeObj, i, inv, t, c, FLD_YT); + addField(chanTypeObj, i, inv, t, c, FLD_F); + addField(chanTypeObj, i, inv, t, c, FLD_T); + addField(chanTypeObj, i, inv, t, c, FLD_PF); + addField(chanTypeObj, i, inv, t, c, FLD_PRA); + addField(chanTypeObj, i, inv, t, c, FLD_EFF); if (t == TYPE_DC && inv->Statistics()->getStringMaxPower(c) > 0) { - addField(invObject, i, inv, t, c, FLD_IRR); + addField(chanTypeObj, i, inv, t, c, FLD_IRR); } } } @@ -187,12 +187,7 @@ void WebApiWsLiveClass::addField(JsonObject& root, uint8_t idx, std::shared_ptr< chanName = topic; } String chanNum; - if (type == TYPE_DC) { - // TODO(tbnobody) - chanNum = static_cast(channel) + 1; - } else { - chanNum = channel; - } + chanNum = channel; root[chanNum][chanName]["v"] = inv->Statistics()->getChannelFieldValue(type, channel, fieldId); root[chanNum][chanName]["u"] = inv->Statistics()->getChannelFieldUnit(type, channel, fieldId); root[chanNum][chanName]["d"] = inv->Statistics()->getChannelFieldDigits(type, channel, fieldId); diff --git a/webapp/src/components/InverterChannelInfo.vue b/webapp/src/components/InverterChannelInfo.vue index 0025a3b8..d169f5a2 100644 --- a/webapp/src/components/InverterChannelInfo.vue +++ b/webapp/src/components/InverterChannelInfo.vue @@ -1,11 +1,21 @@ @@ -41,6 +51,7 @@ import { defineComponent, type PropType } from 'vue'; export default defineComponent({ props: { channelData: { type: Object as PropType, required: true }, + channelType: { type: String, required: true }, channelNumber: { type: Number, required: true }, }, }); diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index 4690c5ed..c63fa352 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -263,6 +263,7 @@ "inverterchannelinfo": { "String": "String {num}", "Phase": "Phase {num}", + "General": "Allgemein", "Property": "Eigenschaft", "Value": "Wert", "Unit": "Einheit" diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 3fb93cd3..655a0560 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -263,6 +263,7 @@ "inverterchannelinfo": { "String": "String {num}", "Phase": "Phase {num}", + "General": "General", "Property": "Property", "Value": "Value", "Unit": "Unit" diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 0d05ae5e..a5ecbc82 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -263,6 +263,7 @@ "inverterchannelinfo": { "String": "Ligne {num}", "Phase": "Phase {num}", + "General": "General", "Property": "Propriété", "Value": "Valeur", "Unit": "Unité" diff --git a/webapp/src/types/LiveDataStatus.ts b/webapp/src/types/LiveDataStatus.ts index f8702810..64292ebf 100644 --- a/webapp/src/types/LiveDataStatus.ts +++ b/webapp/src/types/LiveDataStatus.ts @@ -29,7 +29,9 @@ export interface Inverter { limit_relative: number; limit_absolute: number; events: number; - [key: number]: InverterStatistics; + AC: InverterStatistics[]; + DC: InverterStatistics[]; + INV: InverterStatistics[]; } export interface Total { diff --git a/webapp/src/views/HomeView.vue b/webapp/src/views/HomeView.vue index 51faf5ec..720013dd 100644 --- a/webapp/src/views/HomeView.vue +++ b/webapp/src/views/HomeView.vue @@ -92,11 +92,12 @@
-
-