diff --git a/interface/package.json b/interface/package.json index 2fd14b079..00152873d 100644 --- a/interface/package.json +++ b/interface/package.json @@ -41,17 +41,17 @@ "typescript": "^5.7.3" }, "devDependencies": { - "@babel/core": "^7.26.0", - "@eslint/js": "^9.18.0", + "@babel/core": "^7.26.7", + "@eslint/js": "^9.19.0", "@preact/compat": "^18.3.1", "@preact/preset-vite": "^2.10.0", "@trivago/prettier-plugin-sort-imports": "^5.2.1", "@types/formidable": "^3", - "@types/node": "^22.10.7", - "@types/react": "^19.0.7", + "@types/node": "^22.10.10", + "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", "concurrently": "^9.1.2", - "eslint": "^9.18.0", + "eslint": "^9.19.0", "eslint-config-prettier": "^10.0.1", "formidable": "^3.5.2", "prettier": "^3.4.2", diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index 7ff37415c..7cda3cb2b 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -552,19 +552,19 @@ const ApplicationSettings = () => { {data.led_gpio !== 0 && ( - - LED - RGB-LED - + + LED + RGB-LED + )} diff --git a/interface/src/app/status/SystemMonitor.tsx b/interface/src/app/status/SystemMonitor.tsx index 85dbd6c61..eb5faea23 100644 --- a/interface/src/app/status/SystemMonitor.tsx +++ b/interface/src/app/status/SystemMonitor.tsx @@ -56,7 +56,7 @@ const SystemMonitor = () => { useInterval(() => { void send(); - }, 1000); // check every second + }, 1000); // check every 1 second const onCancel = async () => { setErrorMessage(undefined); @@ -78,7 +78,7 @@ const SystemMonitor = () => { > {data?.status >= SystemStatusCodes.SYSTEM_STATUS_UPLOADING ? LL.WAIT_FIRMWARE() - : data?.status === SystemStatusCodes.SYSTEM_STATUS_RESTART_REQUESTED + : data?.status === SystemStatusCodes.SYSTEM_STATUS_PENDING_RESTART ? LL.APPLICATION_RESTARTING() : data?.status === SystemStatusCodes.SYSTEM_STATUS_NORMAL ? LL.RESTARTING_PRE() @@ -105,7 +105,7 @@ const SystemMonitor = () => { {LL.PLEASE_WAIT()}… - {data && data.status > SystemStatusCodes.SYSTEM_STATUS_UPLOADING && ( + {data && data.status >= SystemStatusCodes.SYSTEM_STATUS_UPLOADING && ( void; } -const FormLoader = ({ - errorMessage, - onRetry, - message = 'Loading…' -}: FormLoaderProps) => { +const FormLoader = ({ errorMessage, onRetry }: FormLoaderProps) => { const { LL } = useI18nContext(); if (errorMessage) { @@ -38,9 +33,6 @@ const FormLoader = ({ - - {message} - ); }; diff --git a/interface/src/components/loading/LoadingSpinner.tsx b/interface/src/components/loading/LoadingSpinner.tsx index 46e07af4c..8b61b056c 100644 --- a/interface/src/components/loading/LoadingSpinner.tsx +++ b/interface/src/components/loading/LoadingSpinner.tsx @@ -1,15 +1,11 @@ -import { Box, CircularProgress, Typography } from '@mui/material'; +import { Box, CircularProgress } from '@mui/material'; import type { Theme } from '@mui/material'; -import { useI18nContext } from 'i18n/i18n-react'; - interface LoadingSpinnerProps { height?: number | string; } const LoadingSpinner = ({ height = '100%' }: LoadingSpinnerProps) => { - const { LL } = useI18nContext(); - return ( { })} size={100} /> - - {LL.LOADING()}… - ); }; diff --git a/interface/yarn.lock b/interface/yarn.lock index 8ad89b4a6..bbd835c2e 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -51,7 +51,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.22.1, @babel/core@npm:^7.26.0": +"@babel/core@npm:^7.22.1": version: 7.26.0 resolution: "@babel/core@npm:7.26.0" dependencies: @@ -74,6 +74,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/core@npm:7.26.7" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^7.26.2" + "@babel/generator": "npm:^7.26.5" + "@babel/helper-compilation-targets": "npm:^7.26.5" + "@babel/helper-module-transforms": "npm:^7.26.0" + "@babel/helpers": "npm:^7.26.7" + "@babel/parser": "npm:^7.26.7" + "@babel/template": "npm:^7.25.9" + "@babel/traverse": "npm:^7.26.7" + "@babel/types": "npm:^7.26.7" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10c0/fbd2cd9fc23280bdcaca556e558f715c0a42d940b9913c52582e8e3d24e391d269cb8a9cd6589172593983569021c379e28bba6b19ea2ee08674f6068c210a9d + languageName: node + linkType: hard + "@babel/generator@npm:^7.26.0, @babel/generator@npm:^7.26.2, @babel/generator@npm:^7.26.5": version: 7.26.5 resolution: "@babel/generator@npm:7.26.5" @@ -96,7 +119,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.25.9": +"@babel/helper-compilation-targets@npm:^7.25.9, @babel/helper-compilation-targets@npm:^7.26.5": version: 7.26.5 resolution: "@babel/helper-compilation-targets@npm:7.26.5" dependencies: @@ -170,6 +193,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/helpers@npm:7.26.7" + dependencies: + "@babel/template": "npm:^7.25.9" + "@babel/types": "npm:^7.26.7" + checksum: 10c0/37fec398e53a2dbbf24bc2a025c4d571b2556cef18d8116d05d04b153f13ef659cdfbaab96c8eed875e629d39bdf9b3ea5d099ccf80544537de224e2d94f9b11 + languageName: node + linkType: hard + "@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.2, @babel/parser@npm:^7.26.5": version: 7.26.5 resolution: "@babel/parser@npm:7.26.5" @@ -181,6 +214,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/parser@npm:7.26.7" + dependencies: + "@babel/types": "npm:^7.26.7" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/dcb08a4f2878ece33caffefe43b71488d753324bae7ca58d64bca3bc4af34dcfa1b58abdf9972516d76af760fceb25bb9294ca33461d56b31c5059ccfe32001f + languageName: node + linkType: hard + "@babel/plugin-syntax-jsx@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-syntax-jsx@npm:7.25.9" @@ -253,6 +297,21 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/traverse@npm:7.26.7" + dependencies: + "@babel/code-frame": "npm:^7.26.2" + "@babel/generator": "npm:^7.26.5" + "@babel/parser": "npm:^7.26.7" + "@babel/template": "npm:^7.25.9" + "@babel/types": "npm:^7.26.7" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10c0/b23a36ce40d2e4970741431c45d4f92e3f4c2895c0a421456516b2729bd9e17278846e01ee3d9039b0adf5fc5a071768061c17fcad040e74a5c3e39517449d5b + languageName: node + linkType: hard + "@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.26.5": version: 7.26.5 resolution: "@babel/types@npm:7.26.5" @@ -263,6 +322,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/types@npm:7.26.7" + dependencies: + "@babel/helper-string-parser": "npm:^7.25.9" + "@babel/helper-validator-identifier": "npm:^7.25.9" + checksum: 10c0/7810a2bca97b13c253f07a0863a628d33dbe76ee3c163367f24be93bfaf4c8c0a325f73208abaaa050a6b36059efc2950c2e4b71fb109c0f07fa62221d8473d4 + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.13.5": version: 11.13.5 resolution: "@emotion/babel-plugin@npm:11.13.5" @@ -646,10 +715,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.18.0, @eslint/js@npm:^9.18.0": - version: 9.18.0 - resolution: "@eslint/js@npm:9.18.0" - checksum: 10c0/3938344c5ac7feef4b73fcb30f3c3e753570cea74c24904bb5d07e9c42fcd34fcbc40f545b081356a299e11f360c9c274b348c05fb0113fc3d492e5175eee140 +"@eslint/js@npm:9.19.0, @eslint/js@npm:^9.19.0": + version: 9.19.0 + resolution: "@eslint/js@npm:9.19.0" + checksum: 10c0/45dc544c8803984f80a438b47a8e578fae4f6e15bc8478a703827aaf05e21380b42a43560374ce4dad0d5cb6349e17430fc9ce1686fed2efe5d1ff117939ff90 languageName: node linkType: hard @@ -1399,7 +1468,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^22.10.7": +"@types/node@npm:*": version: 22.10.7 resolution: "@types/node@npm:22.10.7" dependencies: @@ -1408,6 +1477,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^22.10.10": + version: 22.10.10 + resolution: "@types/node@npm:22.10.10" + dependencies: + undici-types: "npm:~6.20.0" + checksum: 10c0/3425772d4513cd5dbdd87c00acda088113c03a97445f84f6a89744c60a66990b56c9d3a7213d09d57b6b944ae8ff45f985565e0c1846726112588e33a22dd12b + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -1440,12 +1518,12 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^19.0.7": - version: 19.0.7 - resolution: "@types/react@npm:19.0.7" +"@types/react@npm:^19.0.8": + version: 19.0.8 + resolution: "@types/react@npm:19.0.8" dependencies: csstype: "npm:^3.0.2" - checksum: 10c0/818e546fa03a2a65ac2652fc472891ac96684211e8967bc25e1da6a8a09e2301ad972b1b038d128f8b4cbbd7691f6f57fee274db568169e9b6b01556abbb5bee + checksum: 10c0/5fa7236356b1476de03519c66ef65d4fd904826956105619e2ad60cb0b55ae7b251dd5fff02234076225b5e15333d0d936bf9dbe1d461406f8a2ba01c197ddcd languageName: node linkType: hard @@ -1584,10 +1662,10 @@ __metadata: resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": "npm:2.1.1" - "@babel/core": "npm:^7.26.0" + "@babel/core": "npm:^7.26.7" "@emotion/react": "npm:^11.14.0" "@emotion/styled": "npm:^11.14.0" - "@eslint/js": "npm:^9.18.0" + "@eslint/js": "npm:^9.19.0" "@mui/icons-material": "npm:^6.4.1" "@mui/material": "npm:^6.4.1" "@preact/compat": "npm:^18.3.1" @@ -1595,13 +1673,13 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@trivago/prettier-plugin-sort-imports": "npm:^5.2.1" "@types/formidable": "npm:^3" - "@types/node": "npm:^22.10.7" - "@types/react": "npm:^19.0.7" + "@types/node": "npm:^22.10.10" + "@types/react": "npm:^19.0.8" "@types/react-dom": "npm:^19.0.3" alova: "npm:3.2.8" async-validator: "npm:^4.2.5" concurrently: "npm:^9.1.2" - eslint: "npm:^9.18.0" + eslint: "npm:^9.19.0" eslint-config-prettier: "npm:^10.0.1" formidable: "npm:^3.5.2" jwt-decode: "npm:^4.0.0" @@ -3046,16 +3124,16 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9.18.0": - version: 9.18.0 - resolution: "eslint@npm:9.18.0" +"eslint@npm:^9.19.0": + version: 9.19.0 + resolution: "eslint@npm:9.19.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.12.1" "@eslint/config-array": "npm:^0.19.0" "@eslint/core": "npm:^0.10.0" "@eslint/eslintrc": "npm:^3.2.0" - "@eslint/js": "npm:9.18.0" + "@eslint/js": "npm:9.19.0" "@eslint/plugin-kit": "npm:^0.2.5" "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" @@ -3091,7 +3169,7 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/7f592ad228b9bd627a24870fdc875bacdab7bf535d4b67316c4cb791e90d0125130a74769f3c407b0c4b7027b3082ef33864a63ee1024552a60a17db60493f15 + checksum: 10c0/3b0dfaeff6a831de086884a3e2432f18468fe37c69f35e1a0a9a2833d9994a65b6dd2a524aaee28f361c849035ad9d15e3841029b67d261d0abd62c7de6d51f5 languageName: node linkType: hard diff --git a/lib_standalone/Arduino.cpp b/lib_standalone/Arduino.cpp index 1f136fbd4..69cb01aef 100644 --- a/lib_standalone/Arduino.cpp +++ b/lib_standalone/Arduino.cpp @@ -146,5 +146,6 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num) { }; void ledcAttachPin(uint8_t pin, uint8_t chan) {}; void ledcWrite(uint8_t chan, uint32_t duty) {}; +void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val) {}; #endif \ No newline at end of file diff --git a/lib_standalone/Arduino.h b/lib_standalone/Arduino.h index 12a294793..adecdc7d0 100644 --- a/lib_standalone/Arduino.h +++ b/lib_standalone/Arduino.h @@ -71,6 +71,7 @@ void dacWrite(uint8_t pin, uint8_t value); double ledcSetup(uint8_t chan, double freq, uint8_t bit_num); void ledcAttachPin(uint8_t pin, uint8_t chan); void ledcWrite(uint8_t chan, uint32_t duty); +void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val); #define PROGMEM #define PGM_P const char * diff --git a/platformio.ini b/platformio.ini index e02248eb9..a58abd811 100644 --- a/platformio.ini +++ b/platformio.ini @@ -53,6 +53,7 @@ unbuild_flags = framework = arduino board_build.partitions = partitions/esp32_partition_16M.csv board_upload.flash_size = 16MB +board_build.app_partition_name = app0 platform = espressif32@6.9.0 ; Arduino Core 2.0.18 / IDF 4.4.8 ; platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.11/platform-espressif32.zip ; Arduino Core 3.1.1 / IDF 5.3.2 ; @@ -87,6 +88,7 @@ platform = espressif32@6.9.0 ; Arduino Core 2.0.18 / IDF 4.4.8 framework = arduino board_build.partitions = partitions/esp32_partition_32M.csv board_upload.flash_size = 32MB +board_build.app_partition_name = app0 platform = espressif32@6.9.0 ; Arduino Core 2.0.18 / IDF 4.4.8 ; use Tasmota's library for 4MB Flash variants. @@ -95,6 +97,7 @@ platform = espressif32@6.9.0 ; Arduino Core 2.0.18 / IDF 4.4.8 framework = arduino board_build.partitions = partitions/esp32_partition_4M.csv board_upload.flash_size = 4MB +board_build.app_partition_name = app0 platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.06.00/platform-espressif32.zip ; Arduino Core 2.0.18 with IPv6 support, based on IDF 4.4.8 ; platform = https://github.com/tasmota/platform-espressif32/releases/download/2025.01.31/platform-espressif32.zip ; Arduino Core 3.1.1, based on IDF 5.3.2 @@ -104,6 +107,7 @@ platform = https://github.com/tasmota/platform-espressif32/releases/download/202 framework = arduino board_build.partitions = partitions/esp32_partition_16M.csv board_upload.flash_size = 16MB +board_build.app_partition_name = app0 platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.06.00/platform-espressif32.zip ; Arduino Core 2.0.18 with IPv6 support, based on IDF 4.4.8 ; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.12.30/platform-espressif32.zip ; Arduino Core 3.1.0.241206 based on IDF 5.3.2 @@ -122,8 +126,8 @@ build_type = release board_build.filesystem = littlefs lib_deps = bblanchon/ArduinoJson @ 7.3.0 - mathieucarbou/AsyncTCP @ 3.3.2 - mathieucarbou/ESPAsyncWebServer @ 3.6.0 + ESP32Async/AsyncTCP @ ^3.3.2 + ESP32Async/ESPAsyncWebServer @ 3.6.2 https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.4 ; diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index 54807e7cb..20c5bbbb5 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -668,6 +668,7 @@ bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int return false; // not found } +// note we don't add the device and state classes here, as we do in the custom entity service void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) { output["name"] = sensor.name(); output["fullname"] = sensor.name(); diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index b208a1d20..203c51c4c 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -1670,10 +1670,8 @@ void EMSdevice::get_value_json(JsonObject json, DeviceValue & dv) { } } - // add uom if it's not a " " (single space) - if (dv.uom != DeviceValueUOM::NONE) { - json["uom"] = uom_to_string(dv.uom); - } + // add uom, state class and device class + Mqtt::add_ha_uom(json, dv.type, dv.uom, dv.short_name, false); // no icon json["readable"] = !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE); json["writeable"] = dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY); diff --git a/src/core/emsesp.cpp b/src/core/emsesp.cpp index c7c5e798a..216724341 100644 --- a/src/core/emsesp.cpp +++ b/src/core/emsesp.cpp @@ -1637,10 +1637,10 @@ void EMSESP::start() { esp32React.begin(); #ifndef EMSESP_STANDALONE - LOG_INFO("EMS-ESP version %s (%s partition)", EMSESP_APP_VERSION, - esp_ota_get_running_partition()->label); // welcome message + LOG_INFO("EMS-ESP version %s", EMSESP_APP_VERSION); + LOG_DEBUG("Boot partition %s, Active partition %s", esp_ota_get_boot_partition()->label, esp_ota_get_running_partition()->label); #else - LOG_INFO("EMS-ESP version %s", EMSESP_APP_VERSION); // welcome message + LOG_INFO("EMS-ESP version %s", EMSESP_APP_VERSION); #endif LOG_DEBUG("System is running in Debug mode"); LOG_INFO("Last system reset reason Core0: %s, Core1: %s", system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str()); diff --git a/src/core/mqtt.cpp b/src/core/mqtt.cpp index 84f26a450..558a0f9d0 100644 --- a/src/core/mqtt.cpp +++ b/src/core/mqtt.cpp @@ -1117,15 +1117,16 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev return queue_ha(topic, doc.as()); } -// Add the state class, device class and an optional icon based on the uom -void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) { - const char * dc_ha = "dev_cla"; // device class - const char * sc_ha = "stat_cla"; // state class - - // set icon, except for booleans - // using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py +// Add the uom, state class, device class and an optional icon based on the uom +void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity, bool is_discovery) { + // for HA discovery we use different namings + const char * dc_ha = is_discovery ? "dev_cla" : "device_class"; // device class + const char * sc_ha = is_discovery ? "stat_cla" : "state_class"; // state class + const char * uom_ha = is_discovery ? "unit_of_meas" : "uom"; // unit of measure + + // set uom, unless boolean + // using HA uom specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py if (type != DeviceValueType::BOOL) { - const char * uom_ha = "unit_of_meas"; // unit of measure if (uom == DeviceValueUOM::HOURS) { doc[uom_ha] = "h"; } else if (uom == DeviceValueUOM::MINUTES) { @@ -1133,7 +1134,7 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con } else if (uom == DeviceValueUOM::SECONDS) { doc[uom_ha] = "s"; } else if (uom != DeviceValueUOM::NONE) { - doc[uom_ha] = EMSdevice::uom_to_string(uom); // default + doc[uom_ha] = EMSdevice::uom_to_string(uom); // use default } else if (discovery_type() != discoveryType::HOMEASSISTANT) { // Domoticz use " " for a no-uom doc[uom_ha] = " "; @@ -1148,12 +1149,16 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con case DeviceValueUOM::K: doc[sc_ha] = F_(measurement); doc[dc_ha] = "temperature"; - doc["ic"] = F_(icondegrees); // icon + if (is_discovery) + doc["ic"] = F_(icondegrees); // icon // TODO check if still needed + // override uom if fahrenheit + doc[uom_ha] = EMSESP::system_.fahrenheit() ? DeviceValue::DeviceValueUOM_s[DeviceValueUOM::FAHRENHEIT] : DeviceValue::DeviceValueUOM_s[uom]; break; case DeviceValueUOM::PERCENT: doc[sc_ha] = F_(measurement); doc[dc_ha] = "power_factor"; - doc["ic"] = F_(iconpercent); // icon + if (is_discovery) + doc["ic"] = F_(iconpercent); // icon // TODO check if still needed break; case DeviceValueUOM::SECONDS: case DeviceValueUOM::MINUTES: @@ -1166,11 +1171,13 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con doc[dc_ha] = "duration"; // https://github.com/emsesp/EMS-ESP32/issues/822 break; case DeviceValueUOM::KB: - doc["ic"] = F_(iconkb); + if (is_discovery) + doc["ic"] = F_(iconkb); break; case DeviceValueUOM::LMIN: case DeviceValueUOM::LH: - doc["ic"] = F_(iconlmin); + if (is_discovery) + doc["ic"] = F_(iconlmin); doc[sc_ha] = F_(measurement); break; case DeviceValueUOM::WH: @@ -1189,7 +1196,8 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con doc[dc_ha] = "energy"; break; case DeviceValueUOM::UA: - doc["ic"] = F_(iconua); + if (is_discovery) + doc["ic"] = F_(iconua); doc[sc_ha] = F_(measurement); break; case DeviceValueUOM::BAR: @@ -1214,7 +1222,8 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con if ((type != DeviceValueType::STRING) && (type == DeviceValueType::INT8 || type == DeviceValueType::UINT8 || type == DeviceValueType::INT16 || type == DeviceValueType::UINT16 || type == DeviceValueType::UINT24 || type == DeviceValueType::UINT32)) { - doc["ic"] = F_(iconnum); // set icon + if (is_discovery) + doc["ic"] = F_(iconnum); // set icon // determine if its a measurement or total increasing // most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart // all the starts are increasing, and they are ULONGs diff --git a/src/core/mqtt.h b/src/core/mqtt.h index 61c096cd1..2a7fadf0f 100644 --- a/src/core/mqtt.h +++ b/src/core/mqtt.h @@ -232,7 +232,7 @@ class Mqtt { static std::string tag_to_topic(uint8_t device_type, int8_t tag); - static void add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity = nullptr); + static void add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity = nullptr, bool is_discovery = true); static void add_ha_sections_to_doc(const char * name, const char * state_t, diff --git a/src/core/system.cpp b/src/core/system.cpp index db717439e..603352e46 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -2076,7 +2076,7 @@ bool System::uploadFirmwareURL(const char * url) { http.end(); saved_url.clear(); // prevent from downloading again LOG_INFO("Firmware uploaded successfully. Restarting..."); - EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_RESTART_REQUESTED); + EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_PENDING_RESTART); #endif return true; // OK diff --git a/src/core/temperaturesensor.cpp b/src/core/temperaturesensor.cpp index 0e67cf291..02769cdc8 100644 --- a/src/core/temperaturesensor.cpp +++ b/src/core/temperaturesensor.cpp @@ -379,6 +379,7 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons return false; // not found } +// note we don't add the device and state classes here, as we do in the custom entity service void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor) { output["id"] = sensor.id(); output["name"] = sensor.name(); @@ -395,7 +396,6 @@ void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor) output["visible"] = true; } - // publish a single sensor to MQTT void TemperatureSensor::publish_sensor(const Sensor & sensor) { if (Mqtt::enabled() && Mqtt::publish_single()) { diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 0ac133207..1db89549b 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -112,7 +112,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatValve_, DeviceValueType::UINT8, FL_(heatValve), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DHW1, &wwValve_, DeviceValueType::UINT8, FL_(wwValve), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); + // register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &keepWarmTemp_, DeviceValueType::UINT8, diff --git a/src/test/test.h b/src/test/test.h index 93dadbbe3..8e58e1b23 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -42,7 +42,7 @@ namespace emsesp { // #define EMSESP_DEBUG_DEFAULT "render" // #define EMSESP_DEBUG_DEFAULT "api" // #define EMSESP_DEBUG_DEFAULT "api3" -#define EMSESP_DEBUG_DEFAULT "api4" +// #define EMSESP_DEBUG_DEFAULT "api4" // #define EMSESP_DEBUG_DEFAULT "crash" // #define EMSESP_DEBUG_DEFAULT "dv" // #define EMSESP_DEBUG_DEFAULT "lastcode" diff --git a/src/version.h b/src/version.h index fb18d55c2..15ebda94d 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.2-dev.14" +#define EMSESP_APP_VERSION "3.7.2-dev.15" diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 6ff441e39..985e21008 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -325,9 +325,8 @@ void WebCustomEntityService::get_value_json(JsonObject output, CustomEntityItem output["fullname"] = entity.name; output["storage"] = entity.ram ? "ram" : "ems"; output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : entity.value_type == DeviceValueType::STRING ? "string" : F_(number); - if (entity.uom > 0) { - output["uom"] = EMSdevice::uom_to_string(entity.uom); - } + // add uom state class and device class + Mqtt::add_ha_uom(output, entity.value_type, entity.uom, nullptr, false); output["readable"] = true; output["writeable"] = entity.writeable; output["visible"] = true; diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 7781bf0f4..ffd5cf0ab 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -139,7 +139,7 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { #if defined(ARDUINO_LOLIN_C3_MINI) && !defined(BOARD_C3_MINI_V1) (int8_t)(root["led_type"] | 1)}; #else - (int8_t)(root["led_type"] | 0)}; + (int8_t)(root["led_type"] | 0)}; // 0 = LED, 1 = RGB-LED #endif } // check valid pins in this board profile