-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Battery usermod/general update 2026 #5399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e01c8c8
44f9554
4527f7c
885f7a6
d3fac23
9149d8b
b6e8fd9
d1ec2c4
51160d4
519eefe
5b63354
fe07bff
753e10c
3f39e9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,26 +11,61 @@ class UMBattery | |
| { | ||
| private: | ||
|
|
||
| public: | ||
| /** | ||
| * Lookup table entry for voltage-to-percentage mapping. | ||
| * Table must be sorted descending by voltage. | ||
| */ | ||
| struct LutEntry { float voltage; float percent; }; | ||
|
|
||
| protected: | ||
| float minVoltage; | ||
| float maxVoltage; | ||
| float voltage; | ||
| int8_t level = 100; | ||
| float calibration; // offset or calibration value to fine tune the calculated voltage | ||
| float voltageMultiplier; // ratio for the voltage divider | ||
|
|
||
| float linearMapping(float v, float min, float max, float oMin = 0.0f, float oMax = 100.0f) | ||
| { | ||
| return (v-min) * (oMax-oMin) / (max-min) + oMin; | ||
| } | ||
|
|
||
| float lutInterpolate(float v, const LutEntry* lut, uint8_t size) | ||
| { | ||
| if (size == 0) return 0.0f; | ||
|
|
||
| LutEntry first, last; | ||
| memcpy_P(&first, &lut[0], sizeof(LutEntry)); | ||
| memcpy_P(&last, &lut[size-1], sizeof(LutEntry)); | ||
|
|
||
| if (v >= first.voltage) return first.percent; | ||
| if (v <= last.voltage) return last.percent; | ||
|
|
||
| for (uint8_t i = 0; i < size - 1; i++) { | ||
| LutEntry hi, lo; | ||
| memcpy_P(&hi, &lut[i], sizeof(LutEntry)); | ||
| memcpy_P(&lo, &lut[i+1], sizeof(LutEntry)); | ||
|
|
||
| if (v >= lo.voltage) { | ||
| float span = hi.voltage - lo.voltage; | ||
| if (fabsf(span) < 1e-6f) return hi.percent; | ||
| float ratio = (v - lo.voltage) / span; | ||
| return lo.percent + ratio * (hi.percent - lo.percent); | ||
| } | ||
| } | ||
| return last.percent; | ||
| } | ||
|
|
||
| public: | ||
| UMBattery() | ||
| { | ||
| this->setVoltageMultiplier(USERMOD_BATTERY_VOLTAGE_MULTIPLIER); | ||
| this->setCalibration(USERMOD_BATTERY_CALIBRATION); | ||
| } | ||
|
|
||
| virtual ~UMBattery() = default; | ||
|
|
||
| virtual void update(batteryConfig cfg) | ||
| { | ||
| if(cfg.minVoltage) this->setMinVoltage(cfg.minVoltage); | ||
|
|
@@ -42,15 +77,14 @@ class UMBattery | |
|
|
||
| /** | ||
| * Corresponding battery curves | ||
| * calculates the level in % (0-100) with given voltage and possible voltage range | ||
| * calculates the level in % (0-100) with given voltage | ||
| */ | ||
| virtual float mapVoltage(float v, float min, float max) = 0; | ||
| // { | ||
| // example implementation, linear mapping | ||
| // return (v-min) * 100 / (max-min); | ||
| // }; | ||
| virtual float mapVoltage(float v) = 0; | ||
|
|
||
| virtual void calculateAndSetLevel(float voltage) = 0; | ||
| void calculateAndSetLevel(float voltage) | ||
| { | ||
| this->setLevel(this->mapVoltage(voltage)); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
@@ -104,20 +138,19 @@ class UMBattery | |
| */ | ||
| void setVoltage(float voltage) | ||
| { | ||
| // this->voltage = ( (voltage < this->getMinVoltage() * 0.85f) || (voltage > this->getMaxVoltage() * 1.1f) ) | ||
| // ? -1.0f | ||
| // : voltage; | ||
| this->voltage = voltage; | ||
| this->voltage = ( (voltage < this->getMinVoltage() * 0.85f) || (voltage > this->getMaxVoltage() * 1.1f) ) | ||
| ? -1.0f | ||
| : voltage; | ||
| } | ||
|
|
||
| float getLevel() | ||
| int8_t getLevel() | ||
| { | ||
| return this->level; | ||
| } | ||
|
|
||
| void setLevel(float level) | ||
| { | ||
| this->level = constrain(level, 0.0f, 110.0f); | ||
| this->level = (int8_t)constrain(level, 0.0f, 110.0f); | ||
| } | ||
|
Comment on lines
+146
to
154
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
rg -nP 'String\s*\([^)]*getLevel\s*\(\)\s*,\s*0\s*\)' --type=cpp --type=hRepository: wled/WLED Length of output: 151 🏁 Script executed: rg -n "getLevel\s*\(\)" --type=cpp --type=h usermods/Battery/Repository: wled/WLED Length of output: 975 🏁 Script executed: sed -n '395,405p' usermods/Battery/Battery.cppRepository: wled/WLED Length of output: 530 🏁 Script executed: rg -n "umLevel\s*=" usermods/Battery/Battery.cpp -B2 -A2Repository: wled/WLED Length of output: 357 🏁 Script executed: rg -n "infoPercentage" usermods/Battery/Battery.cpp -B2 -A2 | head -30Repository: wled/WLED Length of output: 713 Fix the The return-type change of Update publishMqtt("battery", String(bat->getLevel(), 0).c_str());to: publishMqtt("battery", String(bat->getLevel()).c_str());All other 🤖 Prompt for AI Agents |
||
|
|
||
| /* | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Propagate rejected readings to
leveltoo.Line 141 only invalidates
voltage.Battery.cppstill callscalculateAndSetLevel(filteredVoltage)immediately afterward and gates auto-off, Coulomb init/recalibration, MQTT, and UI onbat->getLevel() >= 0, so an out-of-range spike can still become0or100and trigger downstream behavior. Make invalid readings forcelevel = -1as part of the same contract, or havecalculateAndSetLevel()bail out when the stored voltage is invalid.🤖 Prompt for AI Agents