Mijn accu is een Tewaycell 48V 51.2V 600Ah 30KWh LiFePO4. Deze heeft geen software voor demping van de laadstroom richting de 100% vulling. Dit is volgens mij niet zo goed voor de accu. Met behulp van AI de onder staande software gemaakt voor de demping van de laadstroom en hierin en bescherming zodat bij hoge opbrengst van de PV elke dag tot 100% wordt opgeladen. Nu zo geformuleerd dat dit eens in de 14 dagen voor balanceren mogelijk is. Dit wordt verwerkt in Venus OS Large, Node-Red en draait op Dynamic ESS van Victron
graag jullie menig/opmerkingen over dit stukje software.
| // ---- Read latest stored values ---- |
|---|
| const socRaw = flow.get(“soc”); |
| const vmin = flow.get(“vmin”); |
| const vmax = flow.get(“vmax”); |
| // SOC is vereist |
| if (!Number.isFinite(socRaw)) return null; |
| // gebruik echte waarde (geen afronding) |
| const soc = socRaw; |
| // ---- SOC-based current limit (smooth curve) ---- |
| const Imax = 180; |
| const k = 0.50; |
| const s0 = 91.2; |
| let I = Imax / (1 + Math.exp(k * (soc - s0))); |
| // ---- Full charge counter logic ---- |
| let fullCounter = context.get(“fullCounter”) |
| let wasAbove91 = context.get(“wasAbove91”) |
| // detecteer overgang over 91% |
| if (soc >= 91 && !wasAbove91) { |
| fullCounter += 1; |
| context.set(“fullCounter”, fullCounter); |
| wasAbove91 = true; |
| } |
| // reset flag als je weer onder 85% komt (nieuwe cyclus) |
| if (soc < 90) { |
| wasAbove91 = false; |
| } |
| context.set(“wasAbove91”, wasAbove91); |
| // ---- Blokkeer laden naar 100% tenzij teller >= 14 ---- |
| if (fullCounter < 14 && soc >= 91) { |
| I = Math.min(I, 5); // kleine stroom voor balanceren |
| } |
| // harde cutoff bovenin |
| if (soc >= 98) I = 0; |
| // ---- Reset teller bij volledige lading ---- |
| if (soc >= 98 && fullCounter >= 14) { |
| context.set(“fullCounter”, 0); |
| } |
| // ---- Slimme SOC-afhankelijke delta regeling ---- |
| if (Number.isFinite(vmin) && Number.isFinite(vmax)) { |
| const delta = vmax - vmin; |
| const socFactor = Math.pow(soc / 100, 2); |
| const dStart = 0.02 + 0.05 * (1 - socFactor); |
| const dEnd = 0.08 + 0.05 * (1 - socFactor); |
| let factor; |
| if (delta <= dStart) { |
| factor = 1; |
| } else if (delta >= dEnd) { |
| factor = 0; |
| } else { |
| const x = (delta - dStart) / (dEnd - dStart); |
| factor = 1 - (x * x * x); |
| } |
| I = I * factor; |
| } |
| // ---- Clamp ---- |
| I = Math.max(0, Math.min(180, Math.round(I))); |
| // ---- Send logic ---- |
| const now = Date.now(); |
| const lastI = context.get(“lastI”); |
| const lastSent = context.get(“lastSent”) |
| const isTick = (msg.topic === “tick”); |
| const forceResend = isTick |
| if (!forceResend && lastI === I) return null; |
| context.set(“lastI”, I); |
| context.set(“lastSent”, now); |
| msg.payload = I; |
| return msg; |