From c6578870f0c908a93510e18624a09682565ae93a Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Wed, 18 May 2022 19:46:31 +0200 Subject: [PATCH 1/2] PWM fan JSON API control. --- usermods/PWM_fan/readme.md | 9 +++++++++ usermods/PWM_fan/usermod_PWM_fan.h | 23 +++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/usermods/PWM_fan/readme.md b/usermods/PWM_fan/readme.md index 976d6b24..8cd04a91 100644 --- a/usermods/PWM_fan/readme.md +++ b/usermods/PWM_fan/readme.md @@ -30,7 +30,16 @@ _NOTE:_ You may also need to tweak Dallas Temperature usermod sampling frequency No special requirements. +## Control PWM fan speed using JSON API + +You can use e.g. `{"PWM-fan":{"speed":30,"lock":true}}` to set fan speed to 30 percent of maximum speed (replace 30 with arbitrary value between 0 and 100) and lock the speed. +If you include `speed` property you can set fan speed in percent (%) of maximum speed. +If you include `lock` property you can lock (_true_) or unlock (_false_) fan speed. +If the fan speed is unlocked it will revert to temperature controlled speed on next update cycle. Once fan speed is locked it will remain so until it is unlocked by next API call. + ## Change Log 2021-10 * First public release +2022-05 +* Added JSON API call to allow changing of speed \ No newline at end of file diff --git a/usermods/PWM_fan/usermod_PWM_fan.h b/usermods/PWM_fan/usermod_PWM_fan.h index a8df1202..ba4e1726 100644 --- a/usermods/PWM_fan/usermod_PWM_fan.h +++ b/usermods/PWM_fan/usermod_PWM_fan.h @@ -38,6 +38,7 @@ class PWMFanUsermod : public Usermod { #ifdef ARDUINO_ARCH_ESP32 uint8_t pwmChannel = 255; #endif + bool lockFan = false; #ifdef USERMOD_DALLASTEMPERATURE UsermodTemperature* tempUM; @@ -60,6 +61,8 @@ class PWMFanUsermod : public Usermod { static const char _tachoUpdateSec[]; static const char _minPWMValuePct[]; static const char _IRQperRotation[]; + static const char _speed[]; + static const char _lock[]; void initTacho(void) { if (tachoPin < 0 || !pinManager.allocatePin(tachoPin, false, PinOwner::UM_Unspecified)){ @@ -205,7 +208,7 @@ class PWMFanUsermod : public Usermod { if ((now - msLastTachoMeasurement) < (tachoUpdateSec * 1000)) return; updateTacho(); - setFanPWMbasedOnTemperature(); + if (!lockFan) setFanPWMbasedOnTemperature(); } /* @@ -233,9 +236,19 @@ class PWMFanUsermod : public Usermod { * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - //void readFromJsonState(JsonObject& root) { - // if (!initDone) return; // prevent crash on boot applyPreset() - //} + void readFromJsonState(JsonObject& root) { + if (!initDone || !enabled) return; // prevent crash on boot applyPreset() + JsonObject usermod = root[FPSTR(_name)]; + if (!usermod.isNull()) { + if (!usermod[FPSTR(_speed)].isNull() && usermod[FPSTR(_speed)].is()) { + int pwmValuePct = usermod[FPSTR(_speed)].as(); + updateFanSpeed((MAX(0,MIN(100,pwmValuePct)) * 255) / 100); + } + if (!usermod[FPSTR(_lock)].isNull() && usermod[FPSTR(_lock)].is()) { + lockFan = usermod[FPSTR(_lock)].as(); + } + } + } /* * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object. @@ -337,3 +350,5 @@ const char PWMFanUsermod::_temperature[] PROGMEM = "target-temp-C"; const char PWMFanUsermod::_tachoUpdateSec[] PROGMEM = "tacho-update-s"; const char PWMFanUsermod::_minPWMValuePct[] PROGMEM = "min-PWM-percent"; const char PWMFanUsermod::_IRQperRotation[] PROGMEM = "IRQs-per-rotation"; +const char PWMFanUsermod::_speed[] PROGMEM = "speed"; +const char PWMFanUsermod::_lock[] PROGMEM = "lock"; From 7d25b234d5c3550d165331f58aa4da44a2e7e67c Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Wed, 18 May 2022 19:49:49 +0200 Subject: [PATCH 2/2] Temperature usermod HA autodicovery. --- usermods/Temperature/usermod_temperature.h | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h index 09ffc259..9c932ff1 100644 --- a/usermods/Temperature/usermod_temperature.h +++ b/usermods/Temperature/usermod_temperature.h @@ -46,6 +46,8 @@ class UsermodTemperature : public Usermod { bool enabled = true; + bool HApublished = false; + // strings to reduce flash memory usage (used more than twice) static const char _name[]; static const char _enabled[]; @@ -132,6 +134,28 @@ class UsermodTemperature : public Usermod { return false; } + void publishHomeAssistantAutodiscovery() { + if (!WLED_MQTT_CONNECTED) return; + + char json_str[1024], buf[128]; + size_t payload_size; + StaticJsonDocument<1024> json; + + sprintf_P(buf, PSTR("%s Temperature"), serverDescription); + json[F("name")] = buf; + strcpy(buf, mqttDeviceTopic); + strcat_P(buf, PSTR("/temperature")); + json[F("state_topic")] = buf; + json[F("device_class")] = F("tempearature"); + json[F("unique_id")] = escapedMac.c_str(); + json[F("unit_of_measurement")] = F("°C"); + payload_size = serializeJson(json, json_str); + + sprintf_P(buf, PSTR("homeassistant/sensor/%s/config"), escapedMac.c_str()); + mqtt->publish(buf, 0, true, json_str, payload_size); + HApublished = true; + } + public: void setup() { @@ -206,6 +230,23 @@ class UsermodTemperature : public Usermod { } } + /** + * connected() is called every time the WiFi is (re)connected + * Use it to initialize network interfaces + */ + //void connected() {} + + /** + * subscribe to MQTT topic if needed + */ + void onMqttConnect(bool sessionPresent) { + //(re)subscribe to required topics + //char subuf[64]; + if (mqttDeviceTopic[0] != 0) { + publishHomeAssistantAutodiscovery(); + } + } + /* * API calls te enable data exchange between WLED modules */