diff --git a/usermods/Internal_Temperature_v2/assets/screenshot_info.png b/usermods/Internal_Temperature_v2/assets/screenshot_info.png new file mode 100644 index 000000000..7990f2e8f Binary files /dev/null and b/usermods/Internal_Temperature_v2/assets/screenshot_info.png differ diff --git a/usermods/Internal_Temperature_v2/assets/screenshot_settings.png b/usermods/Internal_Temperature_v2/assets/screenshot_settings.png new file mode 100644 index 000000000..d97dc2bea Binary files /dev/null and b/usermods/Internal_Temperature_v2/assets/screenshot_settings.png differ diff --git a/usermods/Internal_Temperature_v2/readme.md b/usermods/Internal_Temperature_v2/readme.md index 58a9e1939..d574f3abf 100644 --- a/usermods/Internal_Temperature_v2/readme.md +++ b/usermods/Internal_Temperature_v2/readme.md @@ -1,17 +1,44 @@ # Internal Temperature Usermod -This usermod adds the temperature readout to the Info tab and also publishes that over the topic `mcutemp` topic. -## Important -A shown temp of 53,33°C might indicate that the internal temp is not supported. +![Screenshot of WLED info page](assets/screenshot_info.png) -ESP8266 does not have a internal temp sensor +![Screenshot of WLED usermod settings page](assets/screenshot_settings.png) + + +## Features + - 🌡️ Adds the internal temperature readout of the chip to the `Info` tab + - 🥵 High temperature indicator/action. (Configurable threshold and preset) + - 📣 Publishes the internal temperature over the MQTT topic: `mcutemp` + + +## Use Examples +- Warn of excessive/damaging temperatures by the triggering of a 'warning' preset +- Activate a cooling fan (when used with the multi-relay usermod) + + +## Compatibility +- A shown temp of 53,33°C might indicate that the internal temp is not supported +- ESP8266 does not have a internal temp sensor -> Disabled (Indicated with a readout of '-1') +- ESP32S2 seems to crash on reading the sensor -> Disabled (Indicated with a readout of '-1') -ESP32S2 seems to crash on reading the sensor -> disabled ## Installation -Add a build flag `-D USERMOD_INTERNAL_TEMPERATURE` to your `platformio.ini` (or `platformio_override.ini`). +- Add a build flag `-D USERMOD_INTERNAL_TEMPERATURE` to your `platformio.ini` (or `platformio_override.ini`). + + +## 📝 Change Log + +2024-06-26 + +- Added "high-temperature-indication" feature +- Documentation updated + +2023-09-01 + +* "Internal Temperature" usermod created + ## Authors -Soeren Willrodt [@lost-hope](https://github.com/lost-hope) - -Dimitry Zhemkov [@dima-zhemkov](https://github.com/dima-zhemkov) \ No newline at end of file +- Soeren Willrodt [@lost-hope](https://github.com/lost-hope) +- Dimitry Zhemkov [@dima-zhemkov](https://github.com/dima-zhemkov) +- Adam Matthews [@adamsthws](https://github.com/adamsthws) diff --git a/usermods/Internal_Temperature_v2/usermod_internal_temperature.h b/usermods/Internal_Temperature_v2/usermod_internal_temperature.h index 3989e7668..2236bfeab 100644 --- a/usermods/Internal_Temperature_v2/usermod_internal_temperature.h +++ b/usermods/Internal_Temperature_v2/usermod_internal_temperature.h @@ -6,14 +6,23 @@ class InternalTemperatureUsermod : public Usermod { private: + static constexpr unsigned long minLoopInterval = 1000; // minimum allowable interval (ms) unsigned long loopInterval = 10000; unsigned long lastTime = 0; bool isEnabled = false; - float temperature = 0; + float temperature = 0.0f; + uint8_t previousPlaylist = 0; // Stores the playlist that was active before high-temperature activation + uint8_t previousPreset = 0; // Stores the preset that was active before high-temperature activation + uint8_t presetToActivate = 0; // Preset to activate when temp goes above threshold (0 = disabled) + float activationThreshold = 95.0f; // Temperature threshold to trigger high-temperature actions + float resetMargin = 2.0f; // Margin below the activation threshold (Prevents frequent toggling when close to threshold) + bool isAboveThreshold = false; // Flag to track if the high temperature preset is currently active static const char _name[]; static const char _enabled[]; static const char _loopInterval[]; + static const char _activationThreshold[]; + static const char _presetToActivate[]; // any private methods should go here (non-inline method should be defined out of class) void publishMqtt(const char *state, bool retain = false); // example for publishing MQTT message @@ -32,6 +41,7 @@ public: lastTime = millis(); +// Measure the temperature #ifdef ESP8266 // ESP8266 // does not seem possible temperature = -1; @@ -41,6 +51,57 @@ public: temperature = roundf(temperatureRead() * 10) / 10; #endif + // Check if temperature has exceeded the activation threshold + if (temperature >= activationThreshold) { + // Update the state flag if not already set + if (!isAboveThreshold) { + isAboveThreshold = true; + } + // Check if a 'high temperature' preset is configured and it's not already active + if (presetToActivate != 0 && currentPreset != presetToActivate) { + // If a playlist is active, store it for reactivation later + if (currentPlaylist > 0) { + previousPlaylist = currentPlaylist; + } + // If a preset is active, store it for reactivation later + else if (currentPreset > 0) { + previousPreset = currentPreset; + // If no playlist or preset is active, save current state for reactivation later + } else { + saveTemporaryPreset(); + } + // Activate the 'high temperature' preset + applyPreset(presetToActivate); + } + } + // Check if temperature is back below the threshold + else if (temperature <= (activationThreshold - resetMargin)) { + // Update the state flag if not already set + if (isAboveThreshold){ + isAboveThreshold = false; + } + // Check if the 'high temperature' preset is active + if (currentPreset == presetToActivate) { + // Check if a previous playlist was stored + if (previousPlaylist > 0) { + // Reactivate the stored playlist + applyPreset(previousPlaylist); + // Clear the stored playlist + previousPlaylist = 0; + } + // Check if a previous preset was stored + else if (previousPreset > 0) { + // Reactivate the stored preset + applyPreset(previousPreset); + // Clear the stored preset + previousPreset = 0; + // If no previous playlist or preset was stored, revert to the stored state + } else { + applyTemporaryPreset(); + } + } + } + #ifndef WLED_DISABLE_MQTT if (WLED_MQTT_CONNECTED) { @@ -80,15 +141,30 @@ public: JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = isEnabled; top[FPSTR(_loopInterval)] = loopInterval; + top[FPSTR(_activationThreshold)] = activationThreshold; + top[FPSTR(_presetToActivate)] = presetToActivate; } + // Append useful info to the usermod settings gui + void appendConfigData() + { + // Display 'ms' next to the 'Loop Interval' setting + oappend(SET_F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');")); + // Display '°C' next to the 'Activation Threshold' setting + oappend(SET_F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');")); + // Display '0 = Disabled' next to the 'Preset To Activate' setting + oappend(SET_F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');")); + } + bool readFromConfig(JsonObject &root) { JsonObject top = root[FPSTR(_name)]; bool configComplete = !top.isNull(); configComplete &= getJsonValue(top[FPSTR(_enabled)], isEnabled); configComplete &= getJsonValue(top[FPSTR(_loopInterval)], loopInterval); - + loopInterval = max(loopInterval, minLoopInterval); // Makes sure the loop interval isn't too small. + configComplete &= getJsonValue(top[FPSTR(_presetToActivate)], presetToActivate); + configComplete &= getJsonValue(top[FPSTR(_activationThreshold)], activationThreshold); return configComplete; } @@ -101,6 +177,8 @@ public: const char InternalTemperatureUsermod::_name[] PROGMEM = "Internal Temperature"; const char InternalTemperatureUsermod::_enabled[] PROGMEM = "Enabled"; const char InternalTemperatureUsermod::_loopInterval[] PROGMEM = "Loop Interval"; +const char InternalTemperatureUsermod::_activationThreshold[] PROGMEM = "Activation Threshold"; +const char InternalTemperatureUsermod::_presetToActivate[] PROGMEM = "Preset To Activate"; void InternalTemperatureUsermod::publishMqtt(const char *state, bool retain) {