Merge pull request #940 from MichaelDvP/dev

Entitiy blacklist (remove from mem, #891) and RC20/30 modes/seltemps #932
This commit is contained in:
Proddy
2023-02-04 13:53:21 +01:00
committed by GitHub
24 changed files with 535 additions and 494 deletions

View File

@@ -32,7 +32,8 @@
- Add Rego 3000, TR120RF thermostats [#917](https://github.com/emsesp/EMS-ESP32/issues/917) - Add Rego 3000, TR120RF thermostats [#917](https://github.com/emsesp/EMS-ESP32/issues/917)
- Add config for ESP32-S3 - Add config for ESP32-S3
- Add heatpump silent mode and other entities [#896](https://github.com/emsesp/EMS-ESP32/issues/896) - Add heatpump silent mode and other entities [#896](https://github.com/emsesp/EMS-ESP32/issues/896)
- Allow reboot to other partition (factory or asymmetric OTA) - Allow reboot to other partition (factory or asymetric OTA)
- Blacklist entities to remove from memory [#891](https://github.com/emsesp/EMS-ESP32/issues/891)
## Fixed ## Fixed
@@ -41,20 +42,21 @@
- Commands for multiple thermostats [#826](https://github.com/emsesp/EMS-ESP32/issues/826) - Commands for multiple thermostats [#826](https://github.com/emsesp/EMS-ESP32/issues/826)
- API queries for multiple devices [#865](https://github.com/emsesp/EMS-ESP32/issues/865) - API queries for multiple devices [#865](https://github.com/emsesp/EMS-ESP32/issues/865)
- Console crash when using call with command `hcx` only. [#841](https://github.com/emsesp/EMS-ESP32/issues/841) - Console crash when using call with command `hcx` only. [#841](https://github.com/emsesp/EMS-ESP32/issues/841)
- heatingPump2Mod was wrong, changed to absBurnPow [[#908](https://github.com/emsesp/EMS-ESP32/issues/908) - `heatingPump2Mod` was wrong, changed to absBurnPow [[#908](https://github.com/emsesp/EMS-ESP32/issues/908)
- rounding of web input values - Rounding of web input values
- analog sensor with single gpio number [#915](https://github.com/emsesp/EMS-ESP32/issues/915) - Analog sensor with single gpio number [#915](https://github.com/emsesp/EMS-ESP32/issues/915)
- HA dallas and analog configs: remove/rebuild on change [#888](https://github.com/emsesp/EMS-ESP32/issues/888) - HA dallas and analog configs: remove/rebuild on change [#888](https://github.com/emsesp/EMS-ESP32/issues/888)
- Modes and set seltemp for RC30 and RC20 [#932](https://github.com/emsesp/EMS-ESP32/issues/932)
## Changed ## Changed
- Discovery in HomeAssistant don't work with custom base topic. [#596](https://github.com/emsesp/EMS-ESP32/issues/596) Base topic containing `/` are changed to `_` - Discovery in HomeAssistant don't work with custom base topic. [#596](https://github.com/emsesp/EMS-ESP32/issues/596) Base topic containing `/` are changed to `_`
- RF room temperature sensor are shown as thermostat - RF room temperature sensor are shown as thermostat
- render mqtt float json values with trailing zero - Render mqtt float json values with trailing zero
- removed flash strings, to increase available heap memory - Removed flash strings, to increase available heap memory
- reload page after restart button is pressed - Reload page after restart button is pressed
- analog/dallas values command as list like ems-devices - Analog/dallas values command as list like ems-devices
- analog/dallas HA-entities based on id - Analog/dallas HA-entities based on id
- MQTT Base is a mandatory field. Removed MQTT topic length from settings - MQTT Base is a mandatory field. Removed MQTT topic length from settings
- HA duration class for time entities [[#822](https://github.com/emsesp/EMS-ESP32/issues/822) - HA duration class for time entities [[#822](https://github.com/emsesp/EMS-ESP32/issues/822)
- AM200 alternative heatsource as class heatsource [[#857](https://github.com/emsesp/EMS-ESP32/issues/857) - AM200 alternative heatsource as class heatsource [[#857](https://github.com/emsesp/EMS-ESP32/issues/857)

View File

@@ -1,5 +1,5 @@
{ {
"adapter": "react", "adapter": "react",
"baseLocale": "pl", "baseLocale": "pl",
"$schema": "https://unpkg.com/typesafe-i18n@5.20.0/schema/typesafe-i18n.json" "$schema": "https://unpkg.com/typesafe-i18n@5.21.0/schema/typesafe-i18n.json"
} }

View File

@@ -32,8 +32,8 @@
"react-router-dom": "^6.8.0", "react-router-dom": "^6.8.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"sockette": "^2.0.6", "sockette": "^2.0.6",
"typesafe-i18n": "^5.20.0", "typesafe-i18n": "^5.21.0",
"typescript": "^4.9.4" "typescript": "^4.9.5"
}, },
"devDependencies": { "devDependencies": {
"http-proxy-middleware": "^2.0.6", "http-proxy-middleware": "^2.0.6",
@@ -65,9 +65,9 @@
} }
}, },
"node_modules/@babel/compat-data": { "node_modules/@babel/compat-data": {
"version": "7.20.10", "version": "7.20.14",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz",
"integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==",
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
} }
@@ -127,9 +127,9 @@
} }
}, },
"node_modules/@babel/generator": { "node_modules/@babel/generator": {
"version": "7.20.7", "version": "7.20.14",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz",
"integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==",
"dependencies": { "dependencies": {
"@babel/types": "^7.20.7", "@babel/types": "^7.20.7",
"@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/gen-mapping": "^0.3.2",
@@ -1069,9 +1069,9 @@
} }
}, },
"node_modules/@babel/plugin-transform-block-scoping": { "node_modules/@babel/plugin-transform-block-scoping": {
"version": "7.20.11", "version": "7.20.14",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.14.tgz",
"integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==", "integrity": "sha512-sMPepQtsOs5fM1bwNvuJJHvaCfOEQfmc01FGw0ELlTpTJj5Ql/zuNRRldYhAPys4ghXdBIQJbRVYi44/7QflQQ==",
"dependencies": { "dependencies": {
"@babel/helper-plugin-utils": "^7.20.2" "@babel/helper-plugin-utils": "^7.20.2"
}, },
@@ -2080,9 +2080,9 @@
} }
}, },
"node_modules/@csstools/selector-specificity": { "node_modules/@csstools/selector-specificity": {
"version": "2.1.0", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.0.tgz", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz",
"integrity": "sha512-zJ6hb3FDgBbO8d2e83vg6zq7tNvDqSq9RwdwfzJ8tdm9JHNvANq2fqwyRn6mlpUb7CwTs5ILdUrGwi9Gk4vY5w==", "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==",
"engines": { "engines": {
"node": "^14 || ^16 || >=18" "node": "^14 || ^16 || >=18"
}, },
@@ -2268,9 +2268,9 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
}, },
"node_modules/@eslint/eslintrc/node_modules/globals": { "node_modules/@eslint/eslintrc/node_modules/globals": {
"version": "13.19.0", "version": "13.20.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
"integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
"dependencies": { "dependencies": {
"type-fest": "^0.20.2" "type-fest": "^0.20.2"
}, },
@@ -3082,14 +3082,14 @@
} }
}, },
"node_modules/@mui/base": { "node_modules/@mui/base": {
"version": "5.0.0-alpha.115", "version": "5.0.0-alpha.116",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.115.tgz", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.116.tgz",
"integrity": "sha512-OGQ84whT/yNYd6xKCGGS6MxqEfjVjk5esXM7HP6bB2Rim7QICUapxZt4nm8q39fpT08rNDkv3xPVqDDwRdRg1g==", "integrity": "sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.7", "@babel/runtime": "^7.20.7",
"@emotion/is-prop-valid": "^1.2.0", "@emotion/is-prop-valid": "^1.2.0",
"@mui/types": "^7.2.3", "@mui/types": "^7.2.3",
"@mui/utils": "^5.11.2", "@mui/utils": "^5.11.7",
"@popperjs/core": "^2.11.6", "@popperjs/core": "^2.11.6",
"clsx": "^1.2.1", "clsx": "^1.2.1",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
@@ -3114,9 +3114,9 @@
} }
}, },
"node_modules/@mui/core-downloads-tracker": { "node_modules/@mui/core-downloads-tracker": {
"version": "5.11.6", "version": "5.11.7",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.6.tgz", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.7.tgz",
"integrity": "sha512-lbD3qdafBOf2dlqKhOcVRxaPAujX+9UlPC6v8iMugMeAXe0TCgU3QbGXY3zrJsu6ex64WYDpH4y1+WOOBmWMuA==", "integrity": "sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw==",
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
"url": "https://opencollective.com/mui" "url": "https://opencollective.com/mui"
@@ -3148,16 +3148,16 @@
} }
}, },
"node_modules/@mui/material": { "node_modules/@mui/material": {
"version": "5.11.6", "version": "5.11.7",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.6.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.7.tgz",
"integrity": "sha512-MzkkL5KC2PCkFiv8cLpkzgLUPXSrAtnvJBR0emV7mLVWbkwV3n5832vjBx154B6R032fHjFTziTh7YEb50nK6Q==", "integrity": "sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.7", "@babel/runtime": "^7.20.7",
"@mui/base": "5.0.0-alpha.115", "@mui/base": "5.0.0-alpha.116",
"@mui/core-downloads-tracker": "^5.11.6", "@mui/core-downloads-tracker": "^5.11.7",
"@mui/system": "^5.11.5", "@mui/system": "^5.11.7",
"@mui/types": "^7.2.3", "@mui/types": "^7.2.3",
"@mui/utils": "^5.11.2", "@mui/utils": "^5.11.7",
"@types/react-transition-group": "^4.4.5", "@types/react-transition-group": "^4.4.5",
"clsx": "^1.2.1", "clsx": "^1.2.1",
"csstype": "^3.1.1", "csstype": "^3.1.1",
@@ -3192,12 +3192,12 @@
} }
}, },
"node_modules/@mui/private-theming": { "node_modules/@mui/private-theming": {
"version": "5.11.2", "version": "5.11.7",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.2.tgz", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz",
"integrity": "sha512-qZwMaqRFPwlYmqwVKblKBGKtIjJRAj3nsvX93pOmatsXyorW7N/0IPE/swPgz1VwChXhHO75DwBEx8tB+aRMNg==", "integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.7", "@babel/runtime": "^7.20.7",
"@mui/utils": "^5.11.2", "@mui/utils": "^5.11.7",
"prop-types": "^15.8.1" "prop-types": "^15.8.1"
}, },
"engines": { "engines": {
@@ -3249,15 +3249,15 @@
} }
}, },
"node_modules/@mui/system": { "node_modules/@mui/system": {
"version": "5.11.5", "version": "5.11.7",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.5.tgz", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.7.tgz",
"integrity": "sha512-KNVsJ0sgRRp2XBqhh4wPS5aacteqjwxgiYTVwVnll2fgkgunZKo3DsDiGMrFlCg25ZHA3Ax58txWGE9w58zp0w==", "integrity": "sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.7", "@babel/runtime": "^7.20.7",
"@mui/private-theming": "^5.11.2", "@mui/private-theming": "^5.11.7",
"@mui/styled-engine": "^5.11.0", "@mui/styled-engine": "^5.11.0",
"@mui/types": "^7.2.3", "@mui/types": "^7.2.3",
"@mui/utils": "^5.11.2", "@mui/utils": "^5.11.7",
"clsx": "^1.2.1", "clsx": "^1.2.1",
"csstype": "^3.1.1", "csstype": "^3.1.1",
"prop-types": "^15.8.1" "prop-types": "^15.8.1"
@@ -3301,9 +3301,9 @@
} }
}, },
"node_modules/@mui/utils": { "node_modules/@mui/utils": {
"version": "5.11.2", "version": "5.11.7",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.2.tgz", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz",
"integrity": "sha512-AyizuHHlGdAtH5hOOXBW3kriuIwUIKUIgg0P7LzMvzf6jPhoQbENYqY6zJqfoZ7fAWMNNYT8mgN5EftNGzwE2w==", "integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.7", "@babel/runtime": "^7.20.7",
"@types/prop-types": "^15.7.5", "@types/prop-types": "^15.7.5",
@@ -3920,9 +3920,9 @@
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
}, },
"node_modules/@types/express": { "node_modules/@types/express": {
"version": "4.17.15", "version": "4.17.16",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.16.tgz",
"integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==", "integrity": "sha512-LkKpqRZ7zqXJuvoELakaFYuETHjZkSol8EV6cNnyishutDBCCdv6+dsKPbKkCcIk57qRphOLY5sEgClw1bO3gA==",
"dependencies": { "dependencies": {
"@types/body-parser": "*", "@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.31", "@types/express-serve-static-core": "^4.17.31",
@@ -3931,9 +3931,9 @@
} }
}, },
"node_modules/@types/express-serve-static-core": { "node_modules/@types/express-serve-static-core": {
"version": "4.17.32", "version": "4.17.33",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.32.tgz", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz",
"integrity": "sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==", "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==",
"dependencies": { "dependencies": {
"@types/node": "*", "@types/node": "*",
"@types/qs": "*", "@types/qs": "*",
@@ -4175,14 +4175,15 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA=="
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.50.0.tgz",
"integrity": "sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg==", "integrity": "sha512-vwksQWSFZiUhgq3Kv7o1Jcj0DUNylwnIlGvKvLLYsq8pAWha6/WCnXUeaSoNNha/K7QSf2+jvmkxggC1u3pIwQ==",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.48.2", "@typescript-eslint/scope-manager": "5.50.0",
"@typescript-eslint/type-utils": "5.48.2", "@typescript-eslint/type-utils": "5.50.0",
"@typescript-eslint/utils": "5.48.2", "@typescript-eslint/utils": "5.50.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
"natural-compare-lite": "^1.4.0", "natural-compare-lite": "^1.4.0",
"regexpp": "^3.2.0", "regexpp": "^3.2.0",
@@ -4237,11 +4238,11 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}, },
"node_modules/@typescript-eslint/experimental-utils": { "node_modules/@typescript-eslint/experimental-utils": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.50.0.tgz",
"integrity": "sha512-Iwx8De8dwl6qPaPZWIaEfP1feN/YFlA5FlCxF3zUIm+2AG92C5Tefkugj2L9ytOFrmTYkTE/CqvJFZbYoVZQMg==", "integrity": "sha512-gZIhzNRivy0RVqcxjKnQ+ipGc0qolilhBeNmvH+Dvu7Vymug+IfiYxTj2zM7mIlHsw6Q5aH7L7WmuTE3tZyzag==",
"dependencies": { "dependencies": {
"@typescript-eslint/utils": "5.48.2" "@typescript-eslint/utils": "5.50.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -4255,13 +4256,13 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.50.0.tgz",
"integrity": "sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw==", "integrity": "sha512-KCcSyNaogUDftK2G9RXfQyOCt51uB5yqC6pkUYqhYh8Kgt+DwR5M0EwEAxGPy/+DH6hnmKeGsNhiZRQxjH71uQ==",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.48.2", "@typescript-eslint/scope-manager": "5.50.0",
"@typescript-eslint/types": "5.48.2", "@typescript-eslint/types": "5.50.0",
"@typescript-eslint/typescript-estree": "5.48.2", "@typescript-eslint/typescript-estree": "5.50.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@@ -4281,12 +4282,12 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.50.0.tgz",
"integrity": "sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==", "integrity": "sha512-rt03kaX+iZrhssaT974BCmoUikYtZI24Vp/kwTSy841XhiYShlqoshRFDvN1FKKvU2S3gK+kcBW1EA7kNUrogg==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.48.2", "@typescript-eslint/types": "5.50.0",
"@typescript-eslint/visitor-keys": "5.48.2" "@typescript-eslint/visitor-keys": "5.50.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -4297,12 +4298,12 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.50.0.tgz",
"integrity": "sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==", "integrity": "sha512-dcnXfZ6OGrNCO7E5UY/i0ktHb7Yx1fV6fnQGGrlnfDhilcs6n19eIRcvLBqx6OQkrPaFlDPk3OJ0WlzQfrV0bQ==",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "5.48.2", "@typescript-eslint/typescript-estree": "5.50.0",
"@typescript-eslint/utils": "5.48.2", "@typescript-eslint/utils": "5.50.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
@@ -4323,9 +4324,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.50.0.tgz",
"integrity": "sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==", "integrity": "sha512-atruOuJpir4OtyNdKahiHZobPKFvZnBnfDiyEaBf6d9vy9visE7gDjlmhl+y29uxZ2ZDgvXijcungGFjGGex7w==",
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}, },
@@ -4335,12 +4336,12 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.50.0.tgz",
"integrity": "sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==", "integrity": "sha512-Gq4zapso+OtIZlv8YNAStFtT6d05zyVCK7Fx3h5inlLBx2hWuc/0465C2mg/EQDDU2LKe52+/jN4f0g9bd+kow==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.48.2", "@typescript-eslint/types": "5.50.0",
"@typescript-eslint/visitor-keys": "5.48.2", "@typescript-eslint/visitor-keys": "5.50.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@@ -4391,15 +4392,15 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.50.0.tgz",
"integrity": "sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==", "integrity": "sha512-v/AnUFImmh8G4PH0NDkf6wA8hujNNcrwtecqW4vtQ1UOSNBaZl49zP1SHoZ/06e+UiwzHpgb5zP5+hwlYYWYAw==",
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12", "@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.48.2", "@typescript-eslint/scope-manager": "5.50.0",
"@typescript-eslint/types": "5.48.2", "@typescript-eslint/types": "5.50.0",
"@typescript-eslint/typescript-estree": "5.48.2", "@typescript-eslint/typescript-estree": "5.50.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"semver": "^7.3.7" "semver": "^7.3.7"
@@ -4466,11 +4467,11 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.48.2", "version": "5.50.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.50.0.tgz",
"integrity": "sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==", "integrity": "sha512-cdMeD9HGu6EXIeGOh2yVW6oGf9wq8asBgZx7nsR/D36gTfQ0odE5kcRYe5M81vjEFAcPeugXrHg78Imu55F6gg==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.48.2", "@typescript-eslint/types": "5.50.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@@ -4646,9 +4647,9 @@
} }
}, },
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.8.1", "version": "8.8.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@@ -5068,9 +5069,9 @@
} }
}, },
"node_modules/axe-core": { "node_modules/axe-core": {
"version": "4.6.2", "version": "4.6.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.3.tgz",
"integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", "integrity": "sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==",
"engines": { "engines": {
"node": ">=4" "node": ">=4"
} }
@@ -5507,9 +5508,9 @@
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.21.4", "version": "4.21.5",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
"integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@@ -5521,10 +5522,10 @@
} }
], ],
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001400", "caniuse-lite": "^1.0.30001449",
"electron-to-chromium": "^1.4.251", "electron-to-chromium": "^1.4.284",
"node-releases": "^2.0.6", "node-releases": "^2.0.8",
"update-browserslist-db": "^1.0.9" "update-browserslist-db": "^1.0.10"
}, },
"bin": { "bin": {
"browserslist": "cli.js" "browserslist": "cli.js"
@@ -5625,9 +5626,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001446", "version": "1.0.30001449",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001446.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001449.tgz",
"integrity": "sha512-fEoga4PrImGcwUUGEol/PoFCSBnSkA9drgdkxXkJLsUBOnJ8rs3zDv6ApqYXGQFOyMPsjh79naWhF4DAxbF8rw==", "integrity": "sha512-CPB+UL9XMT/Av+pJxCKGhdx+yg1hzplvFJQlJ2n68PyQGMz9L/E2zCyLdOL8uasbouTUgnPl+y0tccI/se+BEw==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@@ -5934,9 +5935,9 @@
} }
}, },
"node_modules/content-type": { "node_modules/content-type": {
"version": "1.0.4", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
@@ -6304,9 +6305,9 @@
} }
}, },
"node_modules/cssdb": { "node_modules/cssdb": {
"version": "7.3.0", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.3.0.tgz", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.4.1.tgz",
"integrity": "sha512-9YymIstaCsXo9qQSxrXzOv27bXJmb/q/LkbORepKzKjHE0TS6Pn3ewoazoBDGvODUvPO0pMG2O4YzVGmVGYK5A==", "integrity": "sha512-0Q8NOMpXJ3iTDDbUv9grcmQAfdDx4qz+fN/+Md2FGbevT+6+bJNQ2LjB2YIUlLbpBTM32idU1Sb+tb/uGt6/XQ==",
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
"url": "https://opencollective.com/csstools" "url": "https://opencollective.com/csstools"
@@ -6535,9 +6536,9 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
}, },
"node_modules/deepmerge": { "node_modules/deepmerge": {
"version": "4.2.2", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -7143,9 +7144,9 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "8.32.0", "version": "8.33.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.33.0.tgz",
"integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", "integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==",
"dependencies": { "dependencies": {
"@eslint/eslintrc": "^1.4.1", "@eslint/eslintrc": "^1.4.1",
"@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/config-array": "^0.11.8",
@@ -7383,9 +7384,9 @@
} }
}, },
"node_modules/eslint-plugin-react": { "node_modules/eslint-plugin-react": {
"version": "7.32.1", "version": "7.32.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz",
"integrity": "sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www==", "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==",
"dependencies": { "dependencies": {
"array-includes": "^3.1.6", "array-includes": "^3.1.6",
"array.prototype.flatmap": "^1.3.1", "array.prototype.flatmap": "^1.3.1",
@@ -7449,11 +7450,11 @@
} }
}, },
"node_modules/eslint-plugin-testing-library": { "node_modules/eslint-plugin-testing-library": {
"version": "5.9.1", "version": "5.10.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.0.tgz",
"integrity": "sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ==", "integrity": "sha512-aTOsCAEI9trrX3TLOnsskfhe57DmsjP/yMKLPqg4ftdRvfR4qut2PGWUa8TwP7whZbwMzJjh98tgAPcE8vdHow==",
"dependencies": { "dependencies": {
"@typescript-eslint/utils": "^5.13.0" "@typescript-eslint/utils": "^5.43.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0", "node": "^12.22.0 || ^14.17.0 || >=16.0.0",
@@ -7690,9 +7691,9 @@
} }
}, },
"node_modules/eslint/node_modules/globals": { "node_modules/eslint/node_modules/globals": {
"version": "13.19.0", "version": "13.20.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
"integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
"dependencies": { "dependencies": {
"type-fest": "^0.20.2" "type-fest": "^0.20.2"
}, },
@@ -9174,9 +9175,9 @@
"dev": true "dev": true
}, },
"node_modules/immer": { "node_modules/immer": {
"version": "9.0.18", "version": "9.0.19",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.18.tgz", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz",
"integrity": "sha512-eAPNpsj7Ax1q6Y/3lm2PmlwRcFzpON7HSNQ3ru5WQH1/PSpnyed/HpNOELl2CxLKoj4r+bAHgdyKqW5gc2Se1A==", "integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==",
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
"url": "https://opencollective.com/immer" "url": "https://opencollective.com/immer"
@@ -11357,9 +11358,9 @@
} }
}, },
"node_modules/jest-watch-typeahead/node_modules/@types/yargs": { "node_modules/jest-watch-typeahead/node_modules/@types/yargs": {
"version": "17.0.20", "version": "17.0.21",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.21.tgz",
"integrity": "sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A==", "integrity": "sha512-kQxgIw2qr3/au36DPzK4Kzl5fpB/SehrD7TUBdWQlOLUkgBMhOBQzz1R9Kuukng9ukWxD3lewSMUZWCwNcmRHg==",
"dependencies": { "dependencies": {
"@types/yargs-parser": "*" "@types/yargs-parser": "*"
} }
@@ -12424,9 +12425,9 @@
"integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.8", "version": "2.0.9",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz",
"integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" "integrity": "sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA=="
}, },
"node_modules/nodemon": { "node_modules/nodemon": {
"version": "2.0.20", "version": "2.0.20",
@@ -15798,9 +15799,9 @@
} }
}, },
"node_modules/shell-quote": { "node_modules/shell-quote": {
"version": "1.7.4", "version": "1.8.0",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz",
"integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==",
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
@@ -16507,9 +16508,9 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.16.1", "version": "5.16.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.2.tgz",
"integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", "integrity": "sha512-JKuM+KvvWVqT7muHVyrwv7FVRPnmHDwF6XwoIxdbF5Witi0vu99RYpxDexpJndXt3jbZZmmWr2/mQa6HvSNdSg==",
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.2", "@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0", "acorn": "^8.5.0",
@@ -16702,9 +16703,9 @@
} }
}, },
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.4.1", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
}, },
"node_modules/tsutils": { "node_modules/tsutils": {
"version": "3.21.0", "version": "3.21.0",
@@ -16789,9 +16790,9 @@
} }
}, },
"node_modules/typesafe-i18n": { "node_modules/typesafe-i18n": {
"version": "5.20.0", "version": "5.21.0",
"resolved": "https://registry.npmjs.org/typesafe-i18n/-/typesafe-i18n-5.20.0.tgz", "resolved": "https://registry.npmjs.org/typesafe-i18n/-/typesafe-i18n-5.21.0.tgz",
"integrity": "sha512-uOvKnVkp1tXRDNBz9Aom54qs0LP2xWrtDliMPdKm9Scsnvn0DC7ZqjSGdOWxVplpbFbqYWNZuzx5Q5jWOjnBTA==", "integrity": "sha512-hfJQ7j0jvz21s2Iiv92Nx7rGyEQZJnVaQ64ek6Bn3IDaADiGFoUbSc7ZPYqeI9iTO8mOe35ACJ9MTn2cEp1ECA==",
"bin": { "bin": {
"typesafe-i18n": "cli/typesafe-i18n.mjs" "typesafe-i18n": "cli/typesafe-i18n.mjs"
}, },
@@ -16804,9 +16805,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "4.9.4", "version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"

View File

@@ -28,8 +28,8 @@
"react-router-dom": "^6.8.0", "react-router-dom": "^6.8.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"sockette": "^2.0.6", "sockette": "^2.0.6",
"typesafe-i18n": "^5.20.0", "typesafe-i18n": "^5.21.0",
"typescript": "^4.9.4" "typescript": "^4.9.5"
}, },
"scripts": { "scripts": {
"start": "react-app-rewired start", "start": "react-app-rewired start",

View File

@@ -157,6 +157,7 @@ const de: Translation = {
CUSTOMIZATIONS_HELP_3: 'Schreibaktion deaktivieren', CUSTOMIZATIONS_HELP_3: 'Schreibaktion deaktivieren',
CUSTOMIZATIONS_HELP_4: 'von MQTT und API ausschließen', CUSTOMIZATIONS_HELP_4: 'von MQTT und API ausschließen',
CUSTOMIZATIONS_HELP_5: 'Aus dem Kontrollzentrum ausblenden', CUSTOMIZATIONS_HELP_5: 'Aus dem Kontrollzentrum ausblenden',
CUSTOMIZATIONS_HELP_6: 'Aus dem Speicher löschen',
SELECT_DEVICE: 'Wählen Sie ein Gerät aus', SELECT_DEVICE: 'Wählen Sie ein Gerät aus',
SET_ALL: 'setzen Sie alle', SET_ALL: 'setzen Sie alle',
OPTIONS: 'Optionen', OPTIONS: 'Optionen',

View File

@@ -157,6 +157,7 @@ const en: Translation = {
CUSTOMIZATIONS_HELP_3: 'disable write action', CUSTOMIZATIONS_HELP_3: 'disable write action',
CUSTOMIZATIONS_HELP_4: 'exclude from MQTT and API', CUSTOMIZATIONS_HELP_4: 'exclude from MQTT and API',
CUSTOMIZATIONS_HELP_5: 'hide from Dashboard', CUSTOMIZATIONS_HELP_5: 'hide from Dashboard',
CUSTOMIZATIONS_HELP_6: 'remove from memory',
SELECT_DEVICE: 'Select a device', SELECT_DEVICE: 'Select a device',
SET_ALL: 'set all', SET_ALL: 'set all',
OPTIONS: 'Options', OPTIONS: 'Options',

View File

@@ -157,6 +157,7 @@ const fr: Translation = {
CUSTOMIZATIONS_HELP_3: 'désactiver l\'action d\'écriture', CUSTOMIZATIONS_HELP_3: 'désactiver l\'action d\'écriture',
CUSTOMIZATIONS_HELP_4: 'exclure de MQTT et de l\'API', CUSTOMIZATIONS_HELP_4: 'exclure de MQTT et de l\'API',
CUSTOMIZATIONS_HELP_5: 'cacher du Tableau de bord', CUSTOMIZATIONS_HELP_5: 'cacher du Tableau de bord',
CUSTOMIZATIONS_HELP_6: 'remove from memory',
SELECT_DEVICE: 'Sélectionnez un appareil', SELECT_DEVICE: 'Sélectionnez un appareil',
SET_ALL: 'tout régler', SET_ALL: 'tout régler',
OPTIONS: 'Options', OPTIONS: 'Options',

View File

@@ -157,6 +157,7 @@ const nl: Translation = {
CUSTOMIZATIONS_HELP_3: 'Zet schrijfacties uit', CUSTOMIZATIONS_HELP_3: 'Zet schrijfacties uit',
CUSTOMIZATIONS_HELP_4: 'Uitsluiten van MQTT en API', CUSTOMIZATIONS_HELP_4: 'Uitsluiten van MQTT en API',
CUSTOMIZATIONS_HELP_5: 'verberg van het Dashboard', CUSTOMIZATIONS_HELP_5: 'verberg van het Dashboard',
CUSTOMIZATIONS_HELP_6: 'remove from memory',
SELECT_DEVICE: 'Selecteer een apparaat', SELECT_DEVICE: 'Selecteer een apparaat',
SET_ALL: 'Alles aanzetten', SET_ALL: 'Alles aanzetten',
OPTIONS: 'Opties', OPTIONS: 'Opties',

View File

@@ -157,6 +157,7 @@ const no: Translation = {
CUSTOMIZATIONS_HELP_3: 'inaktiviser skriving', CUSTOMIZATIONS_HELP_3: 'inaktiviser skriving',
CUSTOMIZATIONS_HELP_4: 'ekskludere fra MQTT og API', CUSTOMIZATIONS_HELP_4: 'ekskludere fra MQTT og API',
CUSTOMIZATIONS_HELP_5: 'gjemme fra Dashboard', CUSTOMIZATIONS_HELP_5: 'gjemme fra Dashboard',
CUSTOMIZATIONS_HELP_6: 'remove from memory',
SELECT_DEVICE: 'Velg en enhet', SELECT_DEVICE: 'Velg en enhet',
SET_ALL: 'sett alle', SET_ALL: 'sett alle',
OPTIONS: 'Alternativ', OPTIONS: 'Alternativ',

View File

@@ -157,6 +157,7 @@ const pl: BaseTranslation = {
CUSTOMIZATIONS_HELP_3: 'zablokuj akcje zapisu', CUSTOMIZATIONS_HELP_3: 'zablokuj akcje zapisu',
CUSTOMIZATIONS_HELP_4: 'wyklucz z MQTT i API', CUSTOMIZATIONS_HELP_4: 'wyklucz z MQTT i API',
CUSTOMIZATIONS_HELP_5: 'ukryj na pulpicie', CUSTOMIZATIONS_HELP_5: 'ukryj na pulpicie',
CUSTOMIZATIONS_HELP_6: 'remove from memory',
SELECT_DEVICE: 'wybierz urządzenie', SELECT_DEVICE: 'wybierz urządzenie',
SET_ALL: 'Ustaw wszystko jako', SET_ALL: 'Ustaw wszystko jako',
OPTIONS: 'Opcje', OPTIONS: 'Opcje',

View File

@@ -157,6 +157,7 @@ const sv: Translation = {
CUSTOMIZATIONS_HELP_3: 'Inaktivera skrivningar', CUSTOMIZATIONS_HELP_3: 'Inaktivera skrivningar',
CUSTOMIZATIONS_HELP_4: 'Exkludera från MQTT & API', CUSTOMIZATIONS_HELP_4: 'Exkludera från MQTT & API',
CUSTOMIZATIONS_HELP_5: 'Göm från Kontrollpanel', CUSTOMIZATIONS_HELP_5: 'Göm från Kontrollpanel',
CUSTOMIZATIONS_HELP_6: 'remove from memory',
SELECT_DEVICE: 'Välj en enhet', SELECT_DEVICE: 'Välj en enhet',
SET_ALL: 'ställ in alla', SET_ALL: 'ställ in alla',
OPTIONS: 'Alternativ', OPTIONS: 'Alternativ',

View File

@@ -13,9 +13,13 @@ import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined'; import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined'; import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
type OptionType = 'readonly' | 'web_exclude' | 'api_mqtt_exclude' | 'favorite'; import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import DeleteForeverIcon from '@mui/icons-material/DeleteForever';
type OptionType = 'deleted' | 'readonly' | 'web_exclude' | 'api_mqtt_exclude' | 'favorite';
const OPTION_ICONS: { [type in OptionType]: [React.ComponentType<SvgIconProps>, React.ComponentType<SvgIconProps>] } = { const OPTION_ICONS: { [type in OptionType]: [React.ComponentType<SvgIconProps>, React.ComponentType<SvgIconProps>] } = {
deleted: [DeleteForeverIcon, DeleteOutlineIcon],
readonly: [EditOffOutlinedIcon, EditOutlinedIcon], readonly: [EditOffOutlinedIcon, EditOutlinedIcon],
web_exclude: [VisibilityOffOutlinedIcon, VisibilityOutlinedIcon], web_exclude: [VisibilityOffOutlinedIcon, VisibilityOutlinedIcon],
api_mqtt_exclude: [CommentsDisabledOutlinedIcon, InsertCommentOutlinedIcon], api_mqtt_exclude: [CommentsDisabledOutlinedIcon, InsertCommentOutlinedIcon],

View File

@@ -17,6 +17,9 @@ import {
Link Link
} from '@mui/material'; } from '@mui/material';
import { MessageBox } from '../components';
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
import { Table } from '@table-library/react-table-library/table'; import { Table } from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme'; import { useTheme } from '@table-library/react-table-library/theme';
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
@@ -41,11 +44,14 @@ import { extractErrorMessage, updateValue } from '../utils';
import { DeviceShort, Devices, DeviceEntity, DeviceEntityMask } from './types'; import { DeviceShort, Devices, DeviceEntity, DeviceEntityMask } from './types';
import { useI18nContext } from '../i18n/i18n-react'; import { useI18nContext } from '../i18n/i18n-react';
import RestartMonitor from '../framework/system/RestartMonitor';
export const APIURL = window.location.origin + '/api/'; export const APIURL = window.location.origin + '/api/';
const SettingsCustomization: FC = () => { const SettingsCustomization: FC = () => {
const { LL } = useI18nContext(); const { LL } = useI18nContext();
const [restarting, setRestarting] = useState<boolean>(false);
const [restartNeeded, setRestartNeeded] = useState<boolean>(false);
const { enqueueSnackbar } = useSnackbar(); const { enqueueSnackbar } = useSnackbar();
@@ -66,7 +72,7 @@ const SettingsCustomization: FC = () => {
const entities_theme = useTheme({ const entities_theme = useTheme({
Table: ` Table: `
--data-table-library_grid-template-columns: 120px repeat(1, minmax(80px, 1fr)) 45px 45px 120px; --data-table-library_grid-template-columns: 150px repeat(1, minmax(80px, 1fr)) 45px 45px 120px;
`, `,
BaseRow: ` BaseRow: `
font-size: 14px; font-size: 14px;
@@ -210,6 +216,9 @@ const SettingsCustomization: FC = () => {
if ((m & 8) === 8) { if ((m & 8) === 8) {
new_masks.push('8'); new_masks.push('8');
} }
if ((m & 128) === 128) {
new_masks.push('128');
}
return new_masks; return new_masks;
}; };
@@ -235,6 +244,7 @@ const SettingsCustomization: FC = () => {
const selected_device = parseInt(event.target.value, 10); const selected_device = parseInt(event.target.value, 10);
setSelectedDevice(selected_device); setSelectedDevice(selected_device);
fetchDeviceEntities(devices?.devices[selected_device].i); fetchDeviceEntities(devices?.devices[selected_device].i);
setRestartNeeded(false);
} }
}; };
@@ -249,6 +259,15 @@ const SettingsCustomization: FC = () => {
} }
}; };
const restart = async () => {
try {
await EMSESP.restart();
setRestarting(true);
} catch (error) {
enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
}
};
const saveCustomization = async () => { const saveCustomization = async () => {
if (devices && deviceEntities && selectedDevice !== -1) { if (devices && deviceEntities && selectedDevice !== -1) {
const masked_entities = deviceEntities const masked_entities = deviceEntities
@@ -277,6 +296,8 @@ const SettingsCustomization: FC = () => {
}); });
if (response.status === 200) { if (response.status === 200) {
enqueueSnackbar(LL.CUSTOMIZATIONS_SAVED(), { variant: 'success' }); enqueueSnackbar(LL.CUSTOMIZATIONS_SAVED(), { variant: 'success' });
} else if (response.status === 201) {
setRestartNeeded(true);
} else { } else {
enqueueSnackbar(LL.PROBLEM_UPDATING(), { variant: 'error' }); enqueueSnackbar(LL.PROBLEM_UPDATING(), { variant: 'error' });
} }
@@ -300,7 +321,8 @@ const SettingsCustomization: FC = () => {
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}&nbsp;&nbsp; <OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}&nbsp;&nbsp;
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}&nbsp;&nbsp; <OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}&nbsp;&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_4()}&nbsp;&nbsp; <OptionIcon type="api_mqtt_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_4()}&nbsp;&nbsp;
<OptionIcon type="web_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_5()} <OptionIcon type="web_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_5()}&nbsp;&nbsp;
<OptionIcon type="deleted" isSet={true} />={LL.CUSTOMIZATIONS_HELP_6()}
</Typography> </Typography>
</Box> </Box>
<ValidatedTextField <ValidatedTextField
@@ -413,6 +435,9 @@ const SettingsCustomization: FC = () => {
<ToggleButton value="1"> <ToggleButton value="1">
<OptionIcon type="web_exclude" isSet={true} /> <OptionIcon type="web_exclude" isSet={true} />
</ToggleButton> </ToggleButton>
<ToggleButton value="128">
<OptionIcon type="deleted" isSet={true} />
</ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
</Grid> </Grid>
@@ -467,13 +492,14 @@ const SettingsCustomization: FC = () => {
{tableList.map((de: DeviceEntity) => ( {tableList.map((de: DeviceEntity) => (
<Row key={de.id} item={de} onClick={() => editEntity(de)}> <Row key={de.id} item={de} onClick={() => editEntity(de)}>
<Cell stiff> <Cell stiff>
{!deviceEntity && (
<ToggleButtonGroup <ToggleButtonGroup
size="small" size="small"
color="secondary" color="secondary"
value={getMaskString(de.m)} value={getMaskString(de.m)}
onChange={(event, mask) => { onChange={(event, mask) => {
de.m = getMaskNumber(mask); de.m = getMaskNumber(mask);
if (de.n === '' && de.m & DeviceEntityMask.DV_READONLY) { if (de.n === '' && (de.m & DeviceEntityMask.DV_READONLY)) {
de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE; de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE;
} }
if (de.m & DeviceEntityMask.DV_WEB_EXCLUDE) { if (de.m & DeviceEntityMask.DV_WEB_EXCLUDE) {
@@ -482,19 +508,19 @@ const SettingsCustomization: FC = () => {
setMasks(['']); setMasks(['']);
}} }}
> >
<ToggleButton value="8" disabled={(de.m & 1) !== 0 || de.n === undefined}> <ToggleButton value="8" disabled={(de.m & 0x81) !== 0 || de.n === undefined}>
<OptionIcon <OptionIcon
type="favorite" type="favorite"
isSet={(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE} isSet={(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE}
/> />
</ToggleButton> </ToggleButton>
<ToggleButton value="4" disabled={!de.w || (de.m & 3) === 3}> <ToggleButton value="4" disabled={!de.w || (de.m & 0x83) >= 3}>
<OptionIcon <OptionIcon
type="readonly" type="readonly"
isSet={(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY} isSet={(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY}
/> />
</ToggleButton> </ToggleButton>
<ToggleButton value="2" disabled={de.n === ''}> <ToggleButton value="2" disabled={de.n === '' || (de.m & 0x80) !== 0}>
<OptionIcon <OptionIcon
type="api_mqtt_exclude" type="api_mqtt_exclude"
isSet={ isSet={
@@ -502,18 +528,25 @@ const SettingsCustomization: FC = () => {
} }
/> />
</ToggleButton> </ToggleButton>
<ToggleButton value="1" disabled={de.n === undefined}> <ToggleButton value="1" disabled={de.n === undefined || (de.m & 0x80) !== 0}>
<OptionIcon <OptionIcon
type="web_exclude" type="web_exclude"
isSet={(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) === DeviceEntityMask.DV_WEB_EXCLUDE} isSet={(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) === DeviceEntityMask.DV_WEB_EXCLUDE}
/> />
</ToggleButton> </ToggleButton>
<ToggleButton value="128" >
<OptionIcon
type="deleted"
isSet={(de.m & DeviceEntityMask.DV_DELETED) === DeviceEntityMask.DV_DELETED}
/>
</ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
)}
</Cell> </Cell>
<Cell>{formatName(de)}</Cell> <Cell>{!deviceEntity && (formatName(de))}</Cell>
<Cell>{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)}</Cell> <Cell>{!deviceEntity && !(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)}</Cell>
<Cell>{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)}</Cell> <Cell>{!deviceEntity && !(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)}</Cell>
<Cell>{formatValue(de.v)}</Cell> <Cell>{!deviceEntity && (formatValue(de.v))}</Cell>
</Row> </Row>
))} ))}
</Body> </Body>
@@ -552,6 +585,14 @@ const SettingsCustomization: FC = () => {
</Typography> </Typography>
{renderDeviceList()} {renderDeviceList()}
{renderDeviceData()} {renderDeviceData()}
{restartNeeded && (
<MessageBox my={2} level="warning" message={LL.RESTART_TEXT()}>
<Button startIcon={<PowerSettingsNewIcon />} variant="contained" color="error" onClick={restart}>
{LL.RESTART()}
</Button>
</MessageBox>
)}
{!restartNeeded && (
<Box display="flex" flexWrap="wrap"> <Box display="flex" flexWrap="wrap">
<Box flexGrow={1}> <Box flexGrow={1}>
<ButtonRow> <ButtonRow>
@@ -571,6 +612,7 @@ const SettingsCustomization: FC = () => {
</Button> </Button>
</ButtonRow> </ButtonRow>
</Box> </Box>
)}
{renderResetDialog()} {renderResetDialog()}
</> </>
); );
@@ -582,48 +624,7 @@ const SettingsCustomization: FC = () => {
<Dialog open={!!deviceEntity} onClose={() => setDeviceEntity(undefined)}> <Dialog open={!!deviceEntity} onClose={() => setDeviceEntity(undefined)}>
<DialogTitle>{LL.EDIT() + ' ' + LL.ENTITY() + ' "' + de.id + '"'}</DialogTitle> <DialogTitle>{LL.EDIT() + ' ' + LL.ENTITY() + ' "' + de.id + '"'}</DialogTitle>
<DialogContent dividers> <DialogContent dividers>
<ToggleButtonGroup <Box color="warning.main" mb={2}>
size="small"
color="secondary"
value={getMaskString(de.m)}
onChange={(event, mask) => {
de.m = getMaskNumber(mask);
if (de.n === '' && de.m & DeviceEntityMask.DV_READONLY) {
de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE;
}
if (de.m & DeviceEntityMask.DV_WEB_EXCLUDE) {
de.m = de.m & ~DeviceEntityMask.DV_FAVORITE;
}
setMasks(['']);
}}
>
<ToggleButton value="8" disabled={(de.m & 1) !== 0 || de.n === undefined}>
<OptionIcon
type="favorite"
isSet={(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE}
/>
</ToggleButton>
<ToggleButton value="4" disabled={!de.w || (de.m & 3) === 3}>
<OptionIcon
type="readonly"
isSet={(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY}
/>
</ToggleButton>
<ToggleButton value="2" disabled={de.n === ''}>
<OptionIcon
type="api_mqtt_exclude"
isSet={(de.m & DeviceEntityMask.DV_API_MQTT_EXCLUDE) === DeviceEntityMask.DV_API_MQTT_EXCLUDE}
/>
</ToggleButton>
<ToggleButton value="1" disabled={de.n === undefined}>
<OptionIcon
type="web_exclude"
isSet={(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) === DeviceEntityMask.DV_WEB_EXCLUDE}
/>
</ToggleButton>
</ToggleButtonGroup>
<Box color="warning.main" p={0} pl={0} pr={0} mt={2} mb={2}>
<Typography variant="body2"> <Typography variant="body2">
{LL.DEFAULT(1) + ' ' + LL.NAME(1)}:&nbsp;{deviceEntity.n} {LL.DEFAULT(1) + ' ' + LL.NAME(1)}:&nbsp;{deviceEntity.n}
</Typography> </Typography>
@@ -689,7 +690,7 @@ const SettingsCustomization: FC = () => {
return ( return (
<SectionContent title={LL.USER_CUSTOMIZATION()} titleGutter> <SectionContent title={LL.USER_CUSTOMIZATION()} titleGutter>
{renderContent()} {restarting ? <RestartMonitor /> : renderContent()}
{renderEditDialog()} {renderEditDialog()}
</SectionContent> </SectionContent>
); );

View File

@@ -298,5 +298,6 @@ export enum DeviceEntityMask {
DV_WEB_EXCLUDE = 1, DV_WEB_EXCLUDE = 1,
DV_API_MQTT_EXCLUDE = 2, DV_API_MQTT_EXCLUDE = 2,
DV_READONLY = 4, DV_READONLY = 4,
DV_FAVORITE = 8 DV_FAVORITE = 8,
DV_DELETED = 128
} }

View File

@@ -38,7 +38,7 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri
#endif #endif
is_firmware = false; is_firmware = false;
if ((extension == "bin") && (fsize > 1500000)) { if ((extension == "bin") && (fsize > 1000000)) {
is_firmware = true; is_firmware = true;
} else if (extension == "json") { } else if (extension == "json") {
md5[0] = '\0'; // clear md5 md5[0] = '\0'; // clear md5

6
package-lock.json generated
View File

@@ -1,6 +0,0 @@
{
"name": "EMS-ESP32",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

View File

@@ -424,7 +424,7 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const {
} else if (mode == 0) { } else if (mode == 0) {
return HeatingCircuit::Mode::OFF; return HeatingCircuit::Mode::OFF;
} }
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20) { } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20 || model == EMSdevice::EMS_DEVICE_FLAG_RC30) {
if (mode == 0) { if (mode == 0) {
return HeatingCircuit::Mode::OFF; return HeatingCircuit::Mode::OFF;
} else if (mode == 1) { } else if (mode == 1) {
@@ -561,7 +561,7 @@ void Thermostat::process_RC20Set(std::shared_ptr<const Telegram> telegram) {
return; return;
} }
has_update(telegram, hc->mode, 23); // 0:off, 1:manual, 2:auto has_update(telegram, hc->mode, 23); // 0:off, 1:manual, 2:auto
// has_update(telegram, hc->nofrosttemp, 24); // guess, not confirmed yet, maybe nighttemp? has_update(telegram, hc->nofrosttemp, 24); // for mode off
// has_update(telegram, hc->tempautotemp, 28); // no need to read this // has_update(telegram, hc->tempautotemp, 28); // no need to read this
has_update(telegram, hc->manualtemp, 29); has_update(telegram, hc->manualtemp, 29);
} }
@@ -573,7 +573,7 @@ void Thermostat::process_RC20Temp(std::shared_ptr<const Telegram> telegram) {
if (hc == nullptr) { if (hc == nullptr) {
return; return;
} }
has_update(telegram, hc->nighttemp, 3); // 0:off, 1:manual, 2:auto has_update(telegram, hc->nighttemp, 3);
has_update(telegram, hc->daylowtemp, 4); has_update(telegram, hc->daylowtemp, 4);
has_update(telegram, hc->daymidtemp, 5); has_update(telegram, hc->daymidtemp, 5);
has_update(telegram, hc->daytemp, 6); has_update(telegram, hc->daytemp, 6);
@@ -1131,6 +1131,7 @@ void Thermostat::process_RC300Floordry(std::shared_ptr<const Telegram> telegram)
} }
// type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long // type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long
// RC30Monitor(0x41), data: 80 20 00 AC 00 00 00 02 00 05 09 00 AC 00
void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) { void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) {
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram); std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
if (hc == nullptr) { if (hc == nullptr) {
@@ -1144,6 +1145,8 @@ void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) {
} }
// type 0xA7 - for reading the mode from the RC30 thermostat (0x10) and all the installation settings // type 0xA7 - for reading the mode from the RC30 thermostat (0x10) and all the installation settings
// RC30Set(0xA7), data: 01 00 FF F6 01 06 00 01 0D 00 00 FF FF 01 02 02 02 00 00 05 1F 05 1F 01 0E 00 FF
// RC30Set(0xA7), data: 00 00 20 02 (offset 27)
void Thermostat::process_RC30Set(std::shared_ptr<const Telegram> telegram) { void Thermostat::process_RC30Set(std::shared_ptr<const Telegram> telegram) {
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram); std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
if (hc == nullptr) { if (hc == nullptr) {
@@ -1158,12 +1161,15 @@ void Thermostat::process_RC30Set(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, mixingvalves_, 17); // Number of Mixing Valves: (0x00=0, 0x01=1, 0x02=2) has_update(telegram, mixingvalves_, 17); // Number of Mixing Valves: (0x00=0, 0x01=1, 0x02=2)
has_update(telegram, brightness_, 18); // Screen brightness 0F=dark F1=light has_update(telegram, brightness_, 18); // Screen brightness 0F=dark F1=light
has_update(telegram, hc->mode, 23); has_update(telegram, hc->mode, 23);
has_update(telegram, offtemp_, 24); // Set Temperature when mode is Off / 10 (e.g.: 0x0F = 7.5 degrees Celsius) has_update(telegram, hc->nofrosttemp, 24); // Set Temperature when mode is Off / 10 (e.g.: 0x0F = 7.5 degrees Celsius)
has_update(telegram, heatingpid_, 25); // PID setting 00=1 01=2 02=3 has_update(telegram, heatingpid_, 25); // PID setting 00=1 01=2 02=3
has_update(telegram, preheating_, 26); // Preheating in the clock program: (0x00 = off, 0xFF = on) has_update(telegram, preheating_, 26); // Preheating in the clock program: (0x00 = off, 0xFF = on)
has_update(telegram, hc->tempautotemp, 28); // is * 2
has_update(telegram, hc->manualtemp, 29); // manualtemp is * 2
} }
// type 0x40 (HC1) - for reading the operating mode from the RC30 thermostat (0x10) // type 0x40 (HC1) - for reading the operating mode from the RC30 thermostat (0x10)
// RC30Temp(0x40), data: 01 01 02 20 24 28 2A 1E 0E 00 01 5A 32 05 4B 2D 00 28 00 3C FF 11 00 05 00
void Thermostat::process_RC30Temp(std::shared_ptr<const Telegram> telegram) { void Thermostat::process_RC30Temp(std::shared_ptr<const Telegram> telegram) {
// check to see we have a valid type. heating: 1 radiator, 2 convectors, 3 floors // check to see we have a valid type. heating: 1 radiator, 2 convectors, 3 floors
if (telegram->offset == 0 && telegram->message_data[0] == 0x00) { if (telegram->offset == 0 && telegram->message_data[0] == 0x00) {
@@ -2032,18 +2038,6 @@ bool Thermostat::set_preheating(const char * value, const int8_t id) {
return true; return true;
} }
bool Thermostat::set_offtemp(const char * value, const int8_t id) {
int ot;
if (!Helpers::value2temperature(value, ot, true)) {
return false;
}
auto t = (int8_t)(ot * 2);
write_command(EMS_TYPE_RC30Settings, 24, t, EMS_TYPE_RC30Settings);
return true;
}
bool Thermostat::set_mixingvalves(const char * value, const int8_t id) { bool Thermostat::set_mixingvalves(const char * value, const int8_t id) {
int m; int m;
if (!Helpers::value2number(value, m, 0, 2)) { if (!Helpers::value2number(value, m, 0, 2)) {
@@ -2256,11 +2250,11 @@ bool Thermostat::set_mode(const char * value, const int8_t id) {
mode_list = FL_(enum_mode6); mode_list = FL_(enum_mode6);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC20: case EMSdevice::EMS_DEVICE_FLAG_RC20:
case EMSdevice::EMS_DEVICE_FLAG_RC20_N: case EMSdevice::EMS_DEVICE_FLAG_RC30:
mode_list = FL_(enum_mode2); mode_list = FL_(enum_mode2);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC20_N:
case EMSdevice::EMS_DEVICE_FLAG_RC25: case EMSdevice::EMS_DEVICE_FLAG_RC25:
case EMSdevice::EMS_DEVICE_FLAG_RC30:
case EMSdevice::EMS_DEVICE_FLAG_RC35: case EMSdevice::EMS_DEVICE_FLAG_RC35:
case EMSdevice::EMS_DEVICE_FLAG_RC30_N: case EMSdevice::EMS_DEVICE_FLAG_RC30_N:
mode_list = FL_(enum_mode3); mode_list = FL_(enum_mode3);
@@ -2281,14 +2275,7 @@ bool Thermostat::set_mode(const char * value, const int8_t id) {
uint8_t enum_index = 0; uint8_t enum_index = 0;
// check for a mode number as a string with a single digit (0..9) // check for the mode being a full string name or single digit
if (value[0] >= '0' && value[0] <= '9') {
enum_index = value[0] - '0';
if (enum_index >= Helpers::count_items(mode_list)) {
return false; // invalid number, not in enum
}
} else {
// check for the mode being a full string name
if (!Helpers::value2enum(value, enum_index, mode_list)) { if (!Helpers::value2enum(value, enum_index, mode_list)) {
mode_list = FL_(enum_mode_ha); mode_list = FL_(enum_mode_ha);
if (Mqtt::ha_enabled() && !Helpers::value2enum(value, enum_index, mode_list)) { if (Mqtt::ha_enabled() && !Helpers::value2enum(value, enum_index, mode_list)) {
@@ -2296,7 +2283,6 @@ bool Thermostat::set_mode(const char * value, const int8_t id) {
return false; // not found return false; // not found
} }
} }
}
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; // heating circuit uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; // heating circuit
@@ -2911,6 +2897,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
default: default:
break; break;
} }
} else if (model == EMS_DEVICE_FLAG_RC20) { } else if (model == EMS_DEVICE_FLAG_RC20) {
switch (mode) { switch (mode) {
case HeatingCircuit::Mode::NIGHT: case HeatingCircuit::Mode::NIGHT:
@@ -2935,9 +2922,16 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
break; break;
case HeatingCircuit::Mode::MANUAL: case HeatingCircuit::Mode::MANUAL:
offset = EMS_OFFSET_RC20Set_temp_manual; offset = EMS_OFFSET_RC20Set_temp_manual;
validate_typeid = set_typeid;
break;
case HeatingCircuit::Mode::OFF:
offset = EMS_OFFSET_RC20Set_temp_off;
validate_typeid = set_typeid;
break; break;
case HeatingCircuit::Mode::AUTO: case HeatingCircuit::Mode::AUTO:
if (hc->get_mode() == HeatingCircuit::Mode::MANUAL) { if (hc->get_mode() == HeatingCircuit::Mode::OFF) {
offset = EMS_OFFSET_RC20Set_temp_off;
} else if (hc->get_mode() == HeatingCircuit::Mode::MANUAL) {
offset = EMS_OFFSET_RC20Set_temp_manual; offset = EMS_OFFSET_RC20Set_temp_manual;
} else { } else {
offset = EMS_OFFSET_RC20Set_temp_auto; offset = EMS_OFFSET_RC20Set_temp_auto;
@@ -2949,28 +2943,51 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
} else if (model == EMS_DEVICE_FLAG_RC30) { } else if (model == EMS_DEVICE_FLAG_RC30) {
switch (mode) { switch (mode) {
case HeatingCircuit::Mode::NIGHT: // change the night temp case HeatingCircuit::Mode::OFF:
offset = EMS_OFFSET_RC30Set_temp_off;
validate_typeid = set_typeid;
break;
case HeatingCircuit::Mode::MANUAL:
offset = EMS_OFFSET_RC30Set_temp_manual;
validate_typeid = set_typeid;
break;
case HeatingCircuit::Mode::TEMPAUTO:
offset = EMS_OFFSET_RC30Set_temp_auto;
validate_typeid = set_typeid;
break;
case HeatingCircuit::Mode::NIGHT:
set_typeid = curve_typeids[hc->hc()]; set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_night; offset = EMS_OFFSET_RC30Temp_temp_night;
validate_typeid = set_typeid;
break; break;
case HeatingCircuit::Mode::DAYLOW: // change the offset temp case HeatingCircuit::Mode::DAYLOW:
set_typeid = curve_typeids[hc->hc()]; set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_daylow; offset = EMS_OFFSET_RC30Temp_temp_daylow;
validate_typeid = set_typeid;
break; break;
case HeatingCircuit::Mode::DAYMID: // change the offset of flowtemp case HeatingCircuit::Mode::DAYMID:
set_typeid = curve_typeids[hc->hc()]; set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_daymid; offset = EMS_OFFSET_RC30Temp_temp_daymid;
validate_typeid = set_typeid;
break; break;
case HeatingCircuit::Mode::DAY: // change the day temp case HeatingCircuit::Mode::DAY:
set_typeid = curve_typeids[hc->hc()]; set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_day; offset = EMS_OFFSET_RC30Temp_temp_day;
validate_typeid = set_typeid;
break; break;
case HeatingCircuit::Mode::HOLIDAY: // change the holiday temp case HeatingCircuit::Mode::HOLIDAY:
set_typeid = curve_typeids[hc->hc()]; set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_holiday; offset = EMS_OFFSET_RC30Temp_temp_holiday;
validate_typeid = set_typeid;
break; break;
default: default:
offset = EMS_OFFSET_RC30Set_temp; if (hc->get_mode() == HeatingCircuit::Mode::OFF) {
offset = EMS_OFFSET_RC30Set_temp_off;
} else if (hc->get_mode() == HeatingCircuit::Mode::MANUAL) {
offset = EMS_OFFSET_RC30Set_temp_manual;
} else {
offset = EMS_OFFSET_RC30Set_temp_auto;
}
break; break;
} }
@@ -3293,101 +3310,8 @@ bool Thermostat::set_temperature_value(const char * value, const int8_t id, cons
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
if (Helpers::value2temperature(value, f, relative)) { if (Helpers::value2temperature(value, f, relative)) {
return set_temperature(f, mode, hc_num); return set_temperature(f, mode, hc_num);
} else {
return false;
} }
} return false;
bool Thermostat::set_temp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::AUTO);
}
bool Thermostat::set_nighttemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::NIGHT);
}
bool Thermostat::set_daytemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DAY);
}
bool Thermostat::set_daylowtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DAYLOW);
}
bool Thermostat::set_daymidtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DAYMID);
}
bool Thermostat::set_comforttemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::COMFORT);
}
bool Thermostat::set_nofrosttemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::NOFROST);
}
bool Thermostat::set_ecotemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::ECO);
}
bool Thermostat::set_heattemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::HEAT);
}
bool Thermostat::set_summertemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::SUMMER);
}
bool Thermostat::set_designtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DESIGN);
}
bool Thermostat::set_offsettemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::OFFSET);
}
bool Thermostat::set_holidaytemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::HOLIDAY);
}
bool Thermostat::set_manualtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::MANUAL);
}
bool Thermostat::set_tempautotemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::TEMPAUTO);
}
bool Thermostat::set_noreducetemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::NOREDUCE);
}
bool Thermostat::set_reducetemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::REDUCE);
}
bool Thermostat::set_vacreducetemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::VACREDUCE);
}
bool Thermostat::set_flowtempoffset(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::FLOWOFFSET, true);
}
bool Thermostat::set_maxflowtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::MAXFLOW);
}
bool Thermostat::set_minflowtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::MINFLOW);
}
bool Thermostat::set_roominfluence(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::ROOMINFLUENCE, true);
}
bool Thermostat::set_remoteseltemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::REMOTESELTEMP);
} }
// register main device values, top level for all thermostats (excluding heating circuits) // register main device values, top level for all thermostats (excluding heating circuits)
@@ -3652,15 +3576,6 @@ void Thermostat::register_device_values() {
FL_(ibaCalIntTemperature), FL_(ibaCalIntTemperature),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_calinttemp)); MAKE_CF_CB(set_calinttemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&offtemp_,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(offtemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_offtemp),
5,
30);
register_device_value( register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
@@ -4180,6 +4095,8 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
register_device_value( register_device_value(
tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp));
register_device_value(
tag, &hc->nofrosttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp));
register_device_value( register_device_value(
tag, &hc->daylowtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); tag, &hc->daylowtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp));
register_device_value( register_device_value(
@@ -4192,7 +4109,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1));
break; break;
case EMS_DEVICE_FLAG_RC20_N: case EMS_DEVICE_FLAG_RC20_N:
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE);
register_device_value( register_device_value(
tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
@@ -4237,7 +4154,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE);
break; break;
case EMS_DEVICE_FLAG_RC30: case EMS_DEVICE_FLAG_RC30:
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday));
register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
@@ -4264,6 +4181,10 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
tag, &hc->daymidtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); tag, &hc->daymidtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp));
register_device_value( register_device_value(
tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
register_device_value(
tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp));
register_device_value(
tag, &hc->nofrosttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp));
break; break;
case EMS_DEVICE_FLAG_RC30_N: case EMS_DEVICE_FLAG_RC30_N:
case EMS_DEVICE_FLAG_RC35: case EMS_DEVICE_FLAG_RC35:

View File

@@ -191,7 +191,6 @@ class Thermostat : public EMSdevice {
int8_t brightness_; // Screen brightness 0F=dark F1=light int8_t brightness_; // Screen brightness 0F=dark F1=light
uint8_t preheating_; // Preheating in the clock program: (0x00 = off, 0xFF = on) uint8_t preheating_; // Preheating in the clock program: (0x00 = off, 0xFF = on)
uint8_t autodst_; // Automatic change Daylight Saving time: (0x00 = off, 0xFF = on) uint8_t autodst_; // Automatic change Daylight Saving time: (0x00 = off, 0xFF = on)
uint8_t offtemp_; // Set Temperature when mode is Off / 10 (e.g.: 0x0F = 7.5 degrees Celsius)
uint8_t mixingvalves_; // Number of Mixing Valves: (0x00=0, 0x01=1, 0x02=2) uint8_t mixingvalves_; // Number of Mixing Valves: (0x00=0, 0x01=1, 0x02=2)
int8_t dampedoutdoortemp_; int8_t dampedoutdoortemp_;
@@ -255,6 +254,7 @@ class Thermostat : public EMSdevice {
static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_setpoint = 1; // setpoint temp static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_setpoint = 1; // setpoint temp
static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_curr = 2; // current temp static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_curr = 2; // current temp
static constexpr uint8_t EMS_OFFSET_RC20Set_mode = 23; // position of thermostat mode static constexpr uint8_t EMS_OFFSET_RC20Set_mode = 23; // position of thermostat mode
static constexpr uint8_t EMS_OFFSET_RC20Set_temp_off = 24; // position of thermostat setpoint mode:off
static constexpr uint8_t EMS_OFFSET_RC20Set_temp_auto = 28; // position of thermostat setpoint temperature static constexpr uint8_t EMS_OFFSET_RC20Set_temp_auto = 28; // position of thermostat setpoint temperature
static constexpr uint8_t EMS_OFFSET_RC20Set_temp_manual = 29; // position of thermostat setpoint temperature static constexpr uint8_t EMS_OFFSET_RC20Set_temp_manual = 29; // position of thermostat setpoint temperature
@@ -265,7 +265,9 @@ class Thermostat : public EMSdevice {
static constexpr uint8_t EMS_OFFSET_RC30StatusMessage_setpoint = 1; // setpoint temp static constexpr uint8_t EMS_OFFSET_RC30StatusMessage_setpoint = 1; // setpoint temp
static constexpr uint8_t EMS_OFFSET_RC30StatusMessage_curr = 2; // current temp static constexpr uint8_t EMS_OFFSET_RC30StatusMessage_curr = 2; // current temp
static constexpr uint8_t EMS_OFFSET_RC30Set_mode = 23; // position of thermostat mode static constexpr uint8_t EMS_OFFSET_RC30Set_mode = 23; // position of thermostat mode
static constexpr uint8_t EMS_OFFSET_RC30Set_temp = 28; // position of thermostat setpoint temperature static constexpr uint8_t EMS_OFFSET_RC30Set_temp_off = 24; // position of thermostat setpoint mode:off
static constexpr uint8_t EMS_OFFSET_RC30Set_temp_auto = 28; // position of thermostat setpoint temperature
static constexpr uint8_t EMS_OFFSET_RC30Set_temp_manual = 29; // position of thermostat setpoint temperature for manual mode
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_night = 3; // position of thermostat setpoint temperature for night time (T1) static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_night = 3; // position of thermostat setpoint temperature for night time (T1)
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_daylow = 4; // position of thermostat setpoint temperature for daylow time (T2) static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_daylow = 4; // position of thermostat setpoint temperature for daylow time (T2)
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_daymid = 5; // position of thermostat setpoint temperature for daymid time (T3) static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_daymid = 5; // position of thermostat setpoint temperature for daymid time (T3)
@@ -408,33 +410,10 @@ class Thermostat : public EMSdevice {
bool set_pause(const char * value, const int8_t id); bool set_pause(const char * value, const int8_t id);
bool set_party(const char * value, const int8_t id); bool set_party(const char * value, const int8_t id);
bool set_summermode(const char * value, const int8_t id); bool set_summermode(const char * value, const int8_t id);
bool set_temp(const char * value, const int8_t id);
bool set_nighttemp(const char * value, const int8_t id);
bool set_daytemp(const char * value, const int8_t id);
bool set_daylowtemp(const char * value, const int8_t id);
bool set_daymidtemp(const char * value, const int8_t id);
bool set_comforttemp(const char * value, const int8_t id);
bool set_nofrosttemp(const char * value, const int8_t id);
bool set_ecotemp(const char * value, const int8_t id);
bool set_heattemp(const char * value, const int8_t id);
bool set_summertemp(const char * value, const int8_t id);
bool set_designtemp(const char * value, const int8_t id);
bool set_offsettemp(const char * value, const int8_t id);
bool set_holidaytemp(const char * value, const int8_t id);
bool set_manualtemp(const char * value, const int8_t id);
bool set_tempautotemp(const char * value, const int8_t id);
bool set_noreducetemp(const char * value, const int8_t id);
bool set_reducetemp(const char * value, const int8_t id);
bool set_vacreducetemp(const char * value, const int8_t id);
bool set_vacreducemode(const char * value, const int8_t id); bool set_vacreducemode(const char * value, const int8_t id);
bool set_nofrostmode(const char * value, const int8_t id); bool set_nofrostmode(const char * value, const int8_t id);
bool set_remotetemp(const char * value, const int8_t id); bool set_remotetemp(const char * value, const int8_t id);
bool set_roominfluence(const char * value, const int8_t id);
bool set_roominfl_factor(const char * value, const int8_t id); bool set_roominfl_factor(const char * value, const int8_t id);
bool set_flowtempoffset(const char * value, const int8_t id);
bool set_minflowtemp(const char * value, const int8_t id);
bool set_maxflowtemp(const char * value, const int8_t id);
bool set_reducemode(const char * value, const int8_t id); bool set_reducemode(const char * value, const int8_t id);
bool set_switchtime1(const char * value, const int8_t id); bool set_switchtime1(const char * value, const int8_t id);
bool set_switchtime2(const char * value, const int8_t id); bool set_switchtime2(const char * value, const int8_t id);
@@ -443,7 +422,79 @@ class Thermostat : public EMSdevice {
bool set_wwprio(const char * value, const int8_t id); bool set_wwprio(const char * value, const int8_t id);
bool set_fastheatup(const char * value, const int8_t id); bool set_fastheatup(const char * value, const int8_t id);
bool set_switchonoptimization(const char * value, const int8_t id); bool set_switchonoptimization(const char * value, const int8_t id);
bool set_remoteseltemp(const char * value, const int8_t id);
inline bool set_temp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::AUTO);
}
inline bool set_nighttemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::NIGHT);
}
inline bool set_daytemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DAY);
}
inline bool set_daylowtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DAYLOW);
}
inline bool set_daymidtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DAYMID);
}
inline bool set_comforttemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::COMFORT);
}
inline bool set_nofrosttemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::NOFROST);
}
inline bool set_ecotemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::ECO);
}
inline bool set_heattemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::HEAT);
}
inline bool set_summertemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::SUMMER);
}
inline bool set_designtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::DESIGN);
}
inline bool set_offsettemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::OFFSET);
}
inline bool set_holidaytemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::HOLIDAY);
}
inline bool set_offtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::OFF);
}
inline bool set_manualtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::MANUAL);
}
inline bool set_tempautotemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::TEMPAUTO);
}
inline bool set_noreducetemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::NOREDUCE);
}
inline bool set_reducetemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::REDUCE);
}
inline bool set_vacreducetemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::VACREDUCE);
}
inline bool set_flowtempoffset(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::FLOWOFFSET, true);
}
inline bool set_maxflowtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::MAXFLOW);
}
inline bool set_minflowtemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::MINFLOW);
}
inline bool set_roominfluence(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::ROOMINFLUENCE, true);
}
inline bool set_remoteseltemp(const char * value, const int8_t id) {
return set_temperature_value(value, id, HeatingCircuit::Mode::REMOTESELTEMP);
}
// set functions - these don't use the id/hc, the parameters are ignored // set functions - these don't use the id/hc, the parameters are ignored
bool set_wwmode(const char * value, const int8_t id); bool set_wwmode(const char * value, const int8_t id);
@@ -487,7 +538,6 @@ class Thermostat : public EMSdevice {
bool set_autodst(const char * value, const int8_t id); bool set_autodst(const char * value, const int8_t id);
bool set_preheating(const char * value, const int8_t id); bool set_preheating(const char * value, const int8_t id);
bool set_mixingvalves(const char * value, const int8_t id); bool set_mixingvalves(const char * value, const int8_t id);
bool set_offtemp(const char * value, const int8_t id);
bool set_hybridStrategy(const char * value, const int8_t id); bool set_hybridStrategy(const char * value, const int8_t id);
bool set_switchOverTemp(const char * value, const int8_t id); bool set_switchOverTemp(const char * value, const int8_t id);

View File

@@ -40,7 +40,16 @@ bool EMSdevice::has_entities() const {
return true; return true;
} }
} }
return false; bool found = false;
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
if (entityCustomization.device_id == device_id() && entityCustomization.entity_ids.size()) {
found = true;
break;
}
}
});
return found;
} }
std::string EMSdevice::tag_to_string(uint8_t tag, const bool translate) { std::string EMSdevice::tag_to_string(uint8_t tag, const bool translate) {
@@ -511,14 +520,9 @@ void EMSdevice::add_device_value(uint8_t tag,
for (std::string entity_id : entityCustomization.entity_ids) { for (std::string entity_id : entityCustomization.entity_ids) {
// if there is an appended custom name, strip it to get the true entity name // if there is an appended custom name, strip it to get the true entity name
// and extract the new custom name // and extract the new custom name
std::string shortname;
auto custom_name_pos = entity_id.find('|'); auto custom_name_pos = entity_id.find('|');
bool has_custom_name = (custom_name_pos != std::string::npos); bool has_custom_name = (custom_name_pos != std::string::npos);
if (has_custom_name) { std::string shortname = has_custom_name ? entity_id.substr(2, custom_name_pos - 2) : entity_id.substr(2);
shortname = entity_id.substr(2, custom_name_pos - 2);
} else {
shortname = entity_id.substr(2);
}
// we found the device entity // we found the device entity
if (shortname == entity) { if (shortname == entity) {
@@ -1014,6 +1018,22 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
} }
} }
} }
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
if ((entityCustomization.device_id == device_id())) {
for (std::string entity_id : entityCustomization.entity_ids) {
uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str());
if (mask & 0x80) {
JsonObject obj = output.createNestedObject();
obj["id"] = DeviceValue::get_name(entity_id);
obj["m"] = mask;
obj["w"] = false;
}
}
break;
}
}
});
} }
void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) { void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) {
@@ -1037,14 +1057,9 @@ void EMSdevice::setCustomEntity(const std::string & entity_id) {
std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? dv.short_name : tag_to_mqtt(dv.tag) + "/" + dv.short_name; std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? dv.short_name : tag_to_mqtt(dv.tag) + "/" + dv.short_name;
// extra shortname // extra shortname
std::string shortname;
auto custom_name_pos = entity_id.find('|'); auto custom_name_pos = entity_id.find('|');
bool has_custom_name = (custom_name_pos != std::string::npos); bool has_custom_name = (custom_name_pos != std::string::npos);
if (has_custom_name) { std::string shortname = has_custom_name ? entity_id.substr(2, custom_name_pos - 2) : entity_id.substr(2);
shortname = entity_id.substr(2, custom_name_pos - 2);
} else {
shortname = entity_id.substr(2);
}
if (entity_name == shortname) { if (entity_name == shortname) {
// check the masks // check the masks
@@ -1088,8 +1103,14 @@ void EMSdevice::getCustomEntities(std::vector<std::string> & entity_ids) {
for (const auto & dv : devicevalues_) { for (const auto & dv : devicevalues_) {
std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? dv.short_name : tag_to_mqtt(dv.tag) + "/" + dv.short_name; std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? dv.short_name : tag_to_mqtt(dv.tag) + "/" + dv.short_name;
uint8_t mask = dv.state >> 4; uint8_t mask = dv.state >> 4;
bool is_set = false;
if (mask || !dv.custom_fullname.empty()) { for (auto & eid : entity_ids) {
if (DeviceValue::get_name(eid) == entity_name) {
is_set = true;
break;
}
}
if (!is_set && (mask || !dv.custom_fullname.empty())) {
if (dv.custom_fullname.empty()) { if (dv.custom_fullname.empty()) {
entity_ids.push_back(Helpers::hextoa(mask, false) + entity_name); entity_ids.push_back(Helpers::hextoa(mask, false) + entity_name);
} else { } else {

View File

@@ -378,4 +378,12 @@ std::string DeviceValue::get_fullname() const {
return customname; return customname;
} }
std::string DeviceValue::get_name(std::string & entity) {
auto pos = entity.find('|');
if (pos != std::string::npos) {
return entity.substr(2, pos - 2);
}
return entity.substr(2);
}
} // namespace emsesp } // namespace emsesp

View File

@@ -186,6 +186,7 @@ class DeviceValue {
bool get_custom_max(uint16_t & val); bool get_custom_max(uint16_t & val);
std::string get_custom_fullname() const; std::string get_custom_fullname() const;
std::string get_fullname() const; std::string get_fullname() const;
static std::string get_name(std::string & entity);
// dv state flags // dv state flags
void add_state(uint8_t s) { void add_state(uint8_t s) {

View File

@@ -276,8 +276,8 @@ MAKE_PSTR_ENUM(enum_summer, FL_(winter), FL_(summer))
MAKE_PSTR_ENUM(enum_operatingstate, FL_(heating), FL_(off), FL_(cooling)) MAKE_PSTR_ENUM(enum_operatingstate, FL_(heating), FL_(off), FL_(cooling))
MAKE_PSTR_ENUM(enum_mode, FL_(manual), FL_(auto)) // RC100, RC300, RC310 MAKE_PSTR_ENUM(enum_mode, FL_(manual), FL_(auto)) // RC100, RC300, RC310
MAKE_PSTR_ENUM(enum_mode2, FL_(off), FL_(manual), FL_(auto)) // RC20 MAKE_PSTR_ENUM(enum_mode2, FL_(off), FL_(manual), FL_(auto)) // RC20, RC30
MAKE_PSTR_ENUM(enum_mode3, FL_(night), FL_(day), FL_(auto)) // RC35, RC30, RC25 MAKE_PSTR_ENUM(enum_mode3, FL_(night), FL_(day), FL_(auto)) // RC35, RC30_N, RC25, RC20_N
MAKE_PSTR_ENUM(enum_mode4, FL_(nofrost), FL_(eco), FL_(heat), FL_(auto)) // JUNKERS MAKE_PSTR_ENUM(enum_mode4, FL_(nofrost), FL_(eco), FL_(heat), FL_(auto)) // JUNKERS
MAKE_PSTR_ENUM(enum_mode5, FL_(auto), FL_(off)) // CRF MAKE_PSTR_ENUM(enum_mode5, FL_(auto), FL_(off)) // CRF
MAKE_PSTR_ENUM(enum_mode6, FL_(nofrost), FL_(night), FL_(day)) // RC10 MAKE_PSTR_ENUM(enum_mode6, FL_(nofrost), FL_(night), FL_(day)) // RC10

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.5.0-dev.16" #define EMSESP_APP_VERSION "3.5.0-dev.17"

View File

@@ -235,6 +235,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request, J
// saves it in the customization service // saves it in the customization service
// and updates the entity list real-time // and updates the entity list real-time
void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, JsonVariant & json) { void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, JsonVariant & json) {
bool need_reboot = false;
if (json.is<JsonObject>()) { if (json.is<JsonObject>()) {
// find the device using the unique_id // find the device using the unique_id
for (const auto & emsdevice : EMSESP::emsdevices) { for (const auto & emsdevice : EMSESP::emsdevices) {
@@ -246,9 +247,45 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J
// and set the mask and custom names immediately for any listed entities // and set the mask and custom names immediately for any listed entities
JsonArray entity_ids_json = json["entity_ids"]; JsonArray entity_ids_json = json["entity_ids"];
std::vector<std::string> entity_ids;
for (const JsonVariant id : entity_ids_json) { for (const JsonVariant id : entity_ids_json) {
emsdevice->setCustomEntity(id.as<std::string>()); std::string id_s = id.as<std::string>();
if (id_s[0] == '8') {
entity_ids.push_back(id_s);
need_reboot = true;
} else {
emsdevice->setCustomEntity(id_s);
} }
// emsesp::EMSESP::logger().info(id.as<const char *>());
}
// add deleted entities from file
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
if (entityCustomization.device_id == device_id) {
for (std::string entity_id : entityCustomization.entity_ids) {
uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str());
std::string name = DeviceValue::get_name(entity_id);
if (mask & 0x80) {
bool is_set = false;
for (const JsonVariant id : entity_ids_json) {
std::string id_s = id.as<std::string>();
if (name == DeviceValue::get_name(id_s)) {
is_set = true;
need_reboot = true;
break;
}
}
if (!is_set) {
entity_ids.push_back(entity_id);
}
}
}
break;
}
}
});
// get list of entities that have masks set or a custom fullname
emsdevice->getCustomEntities(entity_ids);
// Save the list to the customization file // Save the list to the customization file
EMSESP::webCustomizationService.update( EMSESP::webCustomizationService.update(
@@ -263,18 +300,11 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J
} }
} }
if (!entity_ids_json.size()) {
return StateUpdateResult::UNCHANGED; // nothing to add
}
// create a new entry for this device if there are values // create a new entry for this device if there are values
EntityCustomization new_entry; EntityCustomization new_entry;
new_entry.product_id = product_id; new_entry.product_id = product_id;
new_entry.device_id = device_id; new_entry.device_id = device_id;
// get list of entities that have masks set or a custom fullname
std::vector<std::string> entity_ids;
emsdevice->getCustomEntities(entity_ids);
new_entry.entity_ids = entity_ids; new_entry.entity_ids = entity_ids;
// add the record and save // add the record and save
@@ -289,7 +319,7 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J
} }
} }
AsyncWebServerResponse * response = request->beginResponse(200); // OK AsyncWebServerResponse * response = request->beginResponse(need_reboot ? 201 : 200); // OK
request->send(response); request->send(response);
} }