Add /gpu-fan/save endpoint with serializeConfig()
- New POST endpoint handles JSON body with curve config - Calls serializeConfig() to persist to flash - Simplified and cleaned up code
This commit is contained in:
parent
fdcd26b3ce
commit
211118f8ff
@ -1,44 +1,16 @@
|
||||
#include "wled.h"
|
||||
#include "gpu_fan_html.h"
|
||||
|
||||
/*
|
||||
* GPU Fan Controller Usermod for WLED
|
||||
*
|
||||
* This usermod controls a PWM fan based on GPU temperature received via HTTP API
|
||||
* from a Python monitoring script. It supports fixed speed mode and temperature
|
||||
* curve-based control.
|
||||
*
|
||||
* Features:
|
||||
* - Web API for temperature updates from external sources (GPU, etc.)
|
||||
* - Fixed speed mode with configurable percentage
|
||||
* - Temperature curve mode with up to 5 configurable points
|
||||
* - Visual curve editor at /gpu-fan
|
||||
* - Safety fallback to 100% if temperature data times out
|
||||
* - Integration with WLED's web interface
|
||||
*
|
||||
* Connections:
|
||||
* - Fan GND -> ESP32 GND
|
||||
* - Fan +12V -> 12V Power Supply
|
||||
* - Fan PWM -> Configured GPIO (default: GPIO 13)
|
||||
*
|
||||
* API Endpoints:
|
||||
* - POST /json/state with JSON: {"GPU-Fan": {"temperature": 65.5}}
|
||||
* - GET /json/info
|
||||
* - GET /gpu-fan (curve editor page)
|
||||
*/
|
||||
|
||||
#ifndef PWM_FAN_PIN
|
||||
#define PWM_FAN_PIN 13
|
||||
#endif
|
||||
|
||||
// PWM configuration for 4-pin PC fans (Intel spec: 25kHz)
|
||||
#define GPU_FAN_PWM_FREQ 25000
|
||||
#define GPU_FAN_PWM_RESOLUTION 8
|
||||
|
||||
class GPUFanControllerUsermod : public Usermod {
|
||||
|
||||
private:
|
||||
// Configuration
|
||||
bool enabled = true;
|
||||
bool initDone = false;
|
||||
bool webHandlerRegistered = false;
|
||||
@ -48,53 +20,43 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
uint8_t pwmChannel = 255;
|
||||
#endif
|
||||
|
||||
// Control modes
|
||||
enum ControlMode {
|
||||
MODE_FIXED = 0,
|
||||
MODE_CURVE = 1
|
||||
};
|
||||
|
||||
// Fan configuration
|
||||
ControlMode controlMode = MODE_CURVE;
|
||||
uint8_t fixedSpeedPct = 50; // 0-100%
|
||||
uint8_t fixedSpeedPct = 50;
|
||||
|
||||
// Temperature curve - using flat structure for WLED config compatibility
|
||||
// 5 curve points with separate temp and speed values
|
||||
static const uint8_t MAX_CURVE_POINTS = 5;
|
||||
uint8_t curveCount = 4;
|
||||
|
||||
// Curve point temperatures (°C)
|
||||
int16_t curveTemp1 = 30;
|
||||
int16_t curveTemp2 = 50;
|
||||
int16_t curveTemp3 = 70;
|
||||
int16_t curveTemp4 = 85;
|
||||
int16_t curveTemp5 = 95;
|
||||
|
||||
// Curve point speeds (%)
|
||||
uint8_t curveSpeed1 = 30;
|
||||
uint8_t curveSpeed2 = 50;
|
||||
uint8_t curveSpeed3 = 75;
|
||||
uint8_t curveSpeed4 = 100;
|
||||
uint8_t curveSpeed5 = 100;
|
||||
|
||||
// Runtime state
|
||||
float currentTemp = 25.0f;
|
||||
uint8_t currentPWM = 0;
|
||||
unsigned long lastTempUpdate = 0;
|
||||
unsigned long tempTimeoutMs = 10000; // 10 second timeout
|
||||
unsigned long tempTimeoutMs = 10000;
|
||||
unsigned long lastLoopTime = 0;
|
||||
unsigned long loopIntervalMs = 2000; // Update every 2 seconds
|
||||
unsigned long loopIntervalMs = 2000;
|
||||
|
||||
// String constants
|
||||
static const char _name[];
|
||||
static const char _enabled[];
|
||||
|
||||
// Initialize PWM
|
||||
void initPWM() {
|
||||
if (pwmPin < 0 || !PinManager::allocatePin(pwmPin, true, PinOwner::UM_Unspecified)) {
|
||||
enabled = false;
|
||||
pwmPin = -1;
|
||||
DEBUG_PRINTLN(F("GPU Fan: PWM pin allocation failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -105,20 +67,15 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
pwmChannel = PinManager::allocateLedc(1);
|
||||
if (pwmChannel == 255) {
|
||||
deinitPWM();
|
||||
DEBUG_PRINTLN(F("GPU Fan: LEDC channel allocation failed"));
|
||||
return;
|
||||
}
|
||||
ledcSetup(pwmChannel, GPU_FAN_PWM_FREQ, GPU_FAN_PWM_RESOLUTION);
|
||||
ledcAttachPin(pwmPin, pwmChannel);
|
||||
#endif
|
||||
|
||||
DEBUG_PRINTLN(F("GPU Fan: PWM initialized successfully"));
|
||||
}
|
||||
|
||||
// Deinitialize PWM
|
||||
void deinitPWM() {
|
||||
if (pwmPin < 0) return;
|
||||
|
||||
PinManager::deallocatePin(pwmPin, PinOwner::UM_Unspecified);
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (pwmChannel != 255) {
|
||||
@ -129,10 +86,8 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
pwmPin = -1;
|
||||
}
|
||||
|
||||
// Set fan speed (0-255 PWM value)
|
||||
void setFanPWM(uint8_t pwmValue) {
|
||||
if (!enabled || pwmPin < 0) return;
|
||||
|
||||
currentPWM = pwmValue;
|
||||
#ifdef ESP8266
|
||||
analogWrite(pwmPin, pwmValue);
|
||||
@ -141,7 +96,6 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get curve temperature at index
|
||||
int16_t getCurveTemp(uint8_t idx) {
|
||||
switch(idx) {
|
||||
case 0: return curveTemp1;
|
||||
@ -153,7 +107,6 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
}
|
||||
}
|
||||
|
||||
// Get curve speed at index
|
||||
uint8_t getCurveSpeed(uint8_t idx) {
|
||||
switch(idx) {
|
||||
case 0: return curveSpeed1;
|
||||
@ -165,21 +118,12 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate fan speed from temperature curve
|
||||
uint8_t calculateCurveSpeed(float temp) {
|
||||
if (curveCount < 2) return 50; // Fallback
|
||||
if (curveCount < 2) return 50;
|
||||
|
||||
// Below first point
|
||||
if (temp <= getCurveTemp(0)) {
|
||||
return getCurveSpeed(0);
|
||||
}
|
||||
if (temp <= getCurveTemp(0)) return getCurveSpeed(0);
|
||||
if (temp >= getCurveTemp(curveCount - 1)) return getCurveSpeed(curveCount - 1);
|
||||
|
||||
// Above last point
|
||||
if (temp >= getCurveTemp(curveCount - 1)) {
|
||||
return getCurveSpeed(curveCount - 1);
|
||||
}
|
||||
|
||||
// Linear interpolation between points
|
||||
for (uint8_t i = 0; i < curveCount - 1; i++) {
|
||||
int16_t t1 = getCurveTemp(i);
|
||||
int16_t t2 = getCurveTemp(i + 1);
|
||||
@ -187,40 +131,19 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
uint8_t s2 = getCurveSpeed(i + 1);
|
||||
|
||||
if (temp >= t1 && temp <= t2) {
|
||||
float tempRange = t2 - t1;
|
||||
float speedRange = s2 - s1;
|
||||
float tempDiff = temp - t1;
|
||||
|
||||
int speed = s1 + (int)((tempDiff / tempRange) * speedRange);
|
||||
return constrain(speed, 0, 100);
|
||||
float ratio = (temp - t1) / (float)(t2 - t1);
|
||||
return s1 + (uint8_t)(ratio * (s2 - s1));
|
||||
}
|
||||
}
|
||||
|
||||
return 50; // Fallback
|
||||
return 50;
|
||||
}
|
||||
|
||||
// Update fan speed based on current mode and temperature
|
||||
void updateFanSpeed() {
|
||||
uint8_t targetSpeedPct;
|
||||
|
||||
if (controlMode == MODE_FIXED) {
|
||||
targetSpeedPct = fixedSpeedPct;
|
||||
} else {
|
||||
targetSpeedPct = calculateCurveSpeed(currentTemp);
|
||||
}
|
||||
|
||||
// Convert percentage to PWM (0-255)
|
||||
uint8_t targetSpeedPct = (controlMode == MODE_FIXED) ? fixedSpeedPct : calculateCurveSpeed(currentTemp);
|
||||
uint8_t targetPWM = map(constrain(targetSpeedPct, 0, 100), 0, 100, 0, 255);
|
||||
|
||||
if (targetPWM != currentPWM) {
|
||||
setFanPWM(targetPWM);
|
||||
DEBUG_PRINTF("GPU Fan: %d%% (PWM: %d) | Temp: %.1f°C | Mode: %s\n",
|
||||
targetSpeedPct, currentPWM, currentTemp,
|
||||
controlMode == MODE_FIXED ? "Fixed" : "Curve");
|
||||
}
|
||||
if (targetPWM != currentPWM) setFanPWM(targetPWM);
|
||||
}
|
||||
|
||||
// Register web handler - call this once
|
||||
void registerWebHandler() {
|
||||
if (webHandlerRegistered) return;
|
||||
|
||||
@ -228,26 +151,50 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
request->send_P(200, "text/html", GPU_FAN_HTML);
|
||||
});
|
||||
|
||||
// Custom save endpoint
|
||||
server.on("/gpu-fan/save", HTTP_POST,
|
||||
[](AsyncWebServerRequest *request) {
|
||||
request->send(200, "application/json", "{\"success\":true}");
|
||||
},
|
||||
NULL,
|
||||
[this](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
|
||||
DynamicJsonDocument doc(1024);
|
||||
if (deserializeJson(doc, (const char*)data, len)) return;
|
||||
|
||||
if (doc.containsKey("mode")) controlMode = (ControlMode)doc["mode"].as<int>();
|
||||
if (doc.containsKey("fixed-speed")) fixedSpeedPct = doc["fixed-speed"].as<int>();
|
||||
if (doc.containsKey("curve-points")) curveCount = constrain(doc["curve-points"].as<int>(), 2, 5);
|
||||
|
||||
if (doc.containsKey("curve-t1")) curveTemp1 = doc["curve-t1"].as<int>();
|
||||
if (doc.containsKey("curve-t2")) curveTemp2 = doc["curve-t2"].as<int>();
|
||||
if (doc.containsKey("curve-t3")) curveTemp3 = doc["curve-t3"].as<int>();
|
||||
if (doc.containsKey("curve-t4")) curveTemp4 = doc["curve-t4"].as<int>();
|
||||
if (doc.containsKey("curve-t5")) curveTemp5 = doc["curve-t5"].as<int>();
|
||||
if (doc.containsKey("curve-s1")) curveSpeed1 = constrain(doc["curve-s1"].as<int>(), 0, 100);
|
||||
if (doc.containsKey("curve-s2")) curveSpeed2 = constrain(doc["curve-s2"].as<int>(), 0, 100);
|
||||
if (doc.containsKey("curve-s3")) curveSpeed3 = constrain(doc["curve-s3"].as<int>(), 0, 100);
|
||||
if (doc.containsKey("curve-s4")) curveSpeed4 = constrain(doc["curve-s4"].as<int>(), 0, 100);
|
||||
if (doc.containsKey("curve-s5")) curveSpeed5 = constrain(doc["curve-s5"].as<int>(), 0, 100);
|
||||
|
||||
serializeConfig();
|
||||
updateFanSpeed();
|
||||
}
|
||||
);
|
||||
|
||||
webHandlerRegistered = true;
|
||||
DEBUG_PRINTLN(F("GPU Fan: Web handler registered at /gpu-fan"));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void setup() override {
|
||||
initPWM();
|
||||
setFanPWM((fixedSpeedPct * 255) / 100); // Initial speed
|
||||
setFanPWM((fixedSpeedPct * 255) / 100);
|
||||
lastTempUpdate = millis();
|
||||
initDone = true;
|
||||
|
||||
// Register web handler immediately during setup
|
||||
registerWebHandler();
|
||||
|
||||
DEBUG_PRINTLN(F("GPU Fan Controller initialized"));
|
||||
}
|
||||
|
||||
void connected() override {
|
||||
// Also try to register here in case setup was too early
|
||||
registerWebHandler();
|
||||
}
|
||||
|
||||
@ -256,110 +203,75 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
|
||||
unsigned long now = millis();
|
||||
|
||||
// Check for temperature timeout in curve mode
|
||||
if (controlMode == MODE_CURVE && (now - lastTempUpdate > tempTimeoutMs)) {
|
||||
if (currentPWM != 255) {
|
||||
setFanPWM(255);
|
||||
DEBUG_PRINTLN(F("GPU Fan: Temperature timeout - running at 100% for safety"));
|
||||
}
|
||||
if (currentPWM != 255) setFanPWM(255);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update fan speed periodically
|
||||
if (now - lastLoopTime > loopIntervalMs) {
|
||||
updateFanSpeed();
|
||||
lastLoopTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle HTTP API requests
|
||||
bool handleButton(uint8_t b) override {
|
||||
// Not used for this usermod
|
||||
return false;
|
||||
}
|
||||
bool handleButton(uint8_t b) override { return false; }
|
||||
|
||||
// Add info to the WLED info panel
|
||||
void addToJsonInfo(JsonObject& root) override {
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
// Add enable/disable button and link to curve editor
|
||||
JsonArray infoArr = user.createNestedArray(FPSTR(_name));
|
||||
String uiDomString = F("<button class=\"btn btn-xs\" onclick=\"requestJson({'");
|
||||
uiDomString += FPSTR(_name);
|
||||
uiDomString += F("':{'");
|
||||
uiDomString += FPSTR(_enabled);
|
||||
uiDomString += F("':");
|
||||
uiDomString += F("':{'enabled':");
|
||||
uiDomString += enabled ? "false" : "true";
|
||||
uiDomString += F("}});\"><i class=\"icons ");
|
||||
uiDomString += enabled ? "on" : "off";
|
||||
uiDomString += F("\"></i></button>");
|
||||
uiDomString += F(" <a href=\"/gpu-fan\" target=\"_blank\" style=\"color:#e94560;font-size:0.9em;\">[Editor]</a>");
|
||||
uiDomString += F("\"></i></button> <a href=\"/gpu-fan\" target=\"_blank\" style=\"color:#e94560\">[Editor]</a>");
|
||||
infoArr.add(uiDomString);
|
||||
|
||||
if (enabled) {
|
||||
// Temperature display
|
||||
JsonArray tempArr = user.createNestedArray(F("GPU Temp"));
|
||||
tempArr.add(currentTemp);
|
||||
tempArr.add(F("°C"));
|
||||
|
||||
// Fan speed display
|
||||
JsonArray speedArr = user.createNestedArray(F("Fan Speed"));
|
||||
uint8_t speedPct = (currentPWM * 100) / 255;
|
||||
speedArr.add(speedPct);
|
||||
speedArr.add((currentPWM * 100) / 255);
|
||||
speedArr.add(F("%"));
|
||||
|
||||
// Mode display
|
||||
JsonArray modeArr = user.createNestedArray(F("Fan Mode"));
|
||||
modeArr.add(controlMode == MODE_FIXED ? F("Fixed") : F("Curve"));
|
||||
|
||||
// Manual speed slider
|
||||
JsonArray sliderArr = user.createNestedArray(F("Manual"));
|
||||
String sliderStr = F("<div class=\"slider\"><div class=\"sliderwrap il\"><input class=\"noslide\" onchange=\"requestJson({'");
|
||||
sliderStr += FPSTR(_name);
|
||||
sliderStr += F("':{'speed':parseInt(this.value)}});\" oninput=\"updateTrail(this);\" max=100 min=0 type=\"range\" value=");
|
||||
sliderStr += String(fixedSpeedPct);
|
||||
sliderStr += F(" /><div class=\"sliderdisplay\"></div></div></div>");
|
||||
sliderArr.add(sliderStr);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle state changes from JSON API
|
||||
void readFromJsonState(JsonObject& root) override {
|
||||
if (!initDone) return;
|
||||
|
||||
JsonObject usermod = root[FPSTR(_name)];
|
||||
if (!usermod.isNull()) {
|
||||
// Enable/disable
|
||||
if (usermod[FPSTR(_enabled)].is<bool>()) {
|
||||
enabled = usermod[FPSTR(_enabled)].as<bool>();
|
||||
if (usermod.isNull()) return;
|
||||
|
||||
if (usermod["enabled"].is<bool>()) {
|
||||
enabled = usermod["enabled"].as<bool>();
|
||||
if (!enabled) setFanPWM(0);
|
||||
}
|
||||
|
||||
// Manual speed control
|
||||
if (enabled && !usermod["speed"].isNull() && usermod["speed"].is<int>()) {
|
||||
if (usermod["speed"].is<int>()) {
|
||||
fixedSpeedPct = usermod["speed"].as<int>();
|
||||
controlMode = MODE_FIXED; // Switch to fixed mode when manually setting speed
|
||||
controlMode = MODE_FIXED;
|
||||
updateFanSpeed();
|
||||
}
|
||||
|
||||
// Mode selection
|
||||
if (!usermod["mode"].isNull() && usermod["mode"].is<int>()) {
|
||||
if (usermod["mode"].is<int>()) {
|
||||
controlMode = (ControlMode)usermod["mode"].as<int>();
|
||||
}
|
||||
|
||||
// Temperature update (from external source like Python script)
|
||||
if (!usermod["temperature"].isNull()) {
|
||||
currentTemp = usermod["temperature"].as<float>();
|
||||
lastTempUpdate = millis();
|
||||
if (controlMode == MODE_CURVE) {
|
||||
updateFanSpeed();
|
||||
}
|
||||
}
|
||||
if (controlMode == MODE_CURVE) updateFanSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
// Save configuration
|
||||
void addToConfig(JsonObject& root) override {
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
@ -368,8 +280,6 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
top["fixed-speed"] = fixedSpeedPct;
|
||||
top["timeout-ms"] = (int)tempTimeoutMs;
|
||||
top["curve-points"] = curveCount;
|
||||
|
||||
// Save curve points as flat values
|
||||
top["curve-t1"] = curveTemp1;
|
||||
top["curve-t2"] = curveTemp2;
|
||||
top["curve-t3"] = curveTemp3;
|
||||
@ -382,86 +292,51 @@ class GPUFanControllerUsermod : public Usermod {
|
||||
top["curve-s5"] = curveSpeed5;
|
||||
}
|
||||
|
||||
// Append config data (labels for config page)
|
||||
void appendConfigData() override {
|
||||
oappend(SET_F("addInfo('GPU-Fan:pwm-pin',1,'GPIO');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:mode',1,'0=Fixed, 1=Curve');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:fixed-speed',1,'%');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:timeout-ms',1,'ms (safety timeout)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-points',1,'2-5 points');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-t1',1,'°C (Point 1 temp)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-s1',1,'% (Point 1 speed)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-t2',1,'°C (Point 2 temp)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-s2',1,'% (Point 2 speed)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-t3',1,'°C (Point 3 temp)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-s3',1,'% (Point 3 speed)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-t4',1,'°C (Point 4 temp)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-s4',1,'% (Point 4 speed)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-t5',1,'°C (Point 5 temp)');"));
|
||||
oappend(SET_F("addInfo('GPU-Fan:curve-s5',1,'% (Point 5 speed)');"));
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
bool readFromConfig(JsonObject& root) override {
|
||||
int8_t newPwmPin = pwmPin;
|
||||
|
||||
JsonObject top = root[FPSTR(_name)];
|
||||
if (top.isNull()) {
|
||||
DEBUG_PRINTLN(F("GPU Fan: No config found, using defaults"));
|
||||
return false;
|
||||
}
|
||||
if (top.isNull()) return false;
|
||||
|
||||
enabled = top[FPSTR(_enabled)] | enabled;
|
||||
newPwmPin = top["pwm-pin"] | newPwmPin;
|
||||
controlMode = (ControlMode)(top["mode"] | (int)controlMode);
|
||||
fixedSpeedPct = top["fixed-speed"] | fixedSpeedPct;
|
||||
tempTimeoutMs = top["timeout-ms"] | (int)tempTimeoutMs;
|
||||
curveCount = top["curve-points"] | curveCount;
|
||||
curveCount = constrain(curveCount, 2, MAX_CURVE_POINTS);
|
||||
curveCount = constrain(top["curve-points"] | curveCount, 2, MAX_CURVE_POINTS);
|
||||
|
||||
// Load curve points
|
||||
curveTemp1 = top["curve-t1"] | curveTemp1;
|
||||
curveTemp2 = top["curve-t2"] | curveTemp2;
|
||||
curveTemp3 = top["curve-t3"] | curveTemp3;
|
||||
curveTemp4 = top["curve-t4"] | curveTemp4;
|
||||
curveTemp5 = top["curve-t5"] | curveTemp5;
|
||||
curveSpeed1 = top["curve-s1"] | curveSpeed1;
|
||||
curveSpeed2 = top["curve-s2"] | curveSpeed2;
|
||||
curveSpeed3 = top["curve-s3"] | curveSpeed3;
|
||||
curveSpeed4 = top["curve-s4"] | curveSpeed4;
|
||||
curveSpeed5 = top["curve-s5"] | curveSpeed5;
|
||||
|
||||
// Constrain speed values
|
||||
curveSpeed1 = constrain(curveSpeed1, 0, 100);
|
||||
curveSpeed2 = constrain(curveSpeed2, 0, 100);
|
||||
curveSpeed3 = constrain(curveSpeed3, 0, 100);
|
||||
curveSpeed4 = constrain(curveSpeed4, 0, 100);
|
||||
curveSpeed5 = constrain(curveSpeed5, 0, 100);
|
||||
curveSpeed1 = constrain(top["curve-s1"] | curveSpeed1, 0, 100);
|
||||
curveSpeed2 = constrain(top["curve-s2"] | curveSpeed2, 0, 100);
|
||||
curveSpeed3 = constrain(top["curve-s3"] | curveSpeed3, 0, 100);
|
||||
curveSpeed4 = constrain(top["curve-s4"] | curveSpeed4, 0, 100);
|
||||
curveSpeed5 = constrain(top["curve-s5"] | curveSpeed5, 0, 100);
|
||||
|
||||
if (!initDone) {
|
||||
pwmPin = newPwmPin;
|
||||
DEBUG_PRINTLN(F("GPU Fan: Config loaded"));
|
||||
} else {
|
||||
if (pwmPin != newPwmPin) {
|
||||
DEBUG_PRINTLN(F("GPU Fan: Re-initializing pins"));
|
||||
} else if (pwmPin != newPwmPin) {
|
||||
deinitPWM();
|
||||
pwmPin = newPwmPin;
|
||||
setup();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return !top["curve-t1"].isNull();
|
||||
}
|
||||
|
||||
uint16_t getId() override {
|
||||
return USERMOD_ID_UNSPECIFIED; // Change this if you add to const.h
|
||||
}
|
||||
uint16_t getId() override { return USERMOD_ID_UNSPECIFIED; }
|
||||
};
|
||||
|
||||
// String constants
|
||||
const char GPUFanControllerUsermod::_name[] PROGMEM = "GPU-Fan";
|
||||
const char GPUFanControllerUsermod::_enabled[] PROGMEM = "enabled";
|
||||
|
||||
// Register the usermod
|
||||
static GPUFanControllerUsermod gpuFanController;
|
||||
REGISTER_USERMOD(gpuFanController);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user