# Applying a setpoint curve

**URL:** <https://discourse.nodered.org/t/applying-a-setpoint-curve/62708>\
**Category:** General\
**Created:** [16 May 2022 18:03 UTC](https://discourse.nodered.org/t/applying-a-setpoint-curve/62708 "2022-05-16T18:03:32Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![SeRiusRod](https://avatars.discourse-cdn.com/v4/letter/s/278dde/32.png) [@SeRiusRod](https://discourse.nodered.org/u/SeRiusRod)\
**Post date:** [16 May 2022 18:03 UTC](https://discourse.nodered.org/t/applying-a-setpoint-curve/62708/1 "2022-05-16T18:03:32Z")

</div>

I'm writing because perhaps someone knows a better way of implementing setpoint curves based on a known value. Basically what I'm calculating there is the charging power for a battery on a SoC value based on certain conditions. In this case environmental, but I'd like to implement something more.

```javascript
if (!msg.payload.hasOwnProperty("capacity"))
    msg.payload.capacity = global.get("settings.battery.capacity") || 0;

if (msg.payload.capacity == 0) {
    node.status({ fill: "red", shape: "dot", text: "Error!" });
    msg.payload.setpoint = 10000;
    return msg;
}

var c = Math.round(msg.payload.consumed_ah * -100) / 100;

const absminin = 0;
const absmaxin = msg.payload.capacity;

if (c < absminin) c = absminin;
if (c > absmaxin) c = absmaxin;

if (!msg.hasOwnProperty("battery_chargeCurve"))
    msg.battery_chargeCurve = global.get("settings.battery.chargeCurve") || 0;

// Consumed Ah to Charging Watts
const mappings = [
    [[[100, 80], [80, 30], [30, 10], [10, 0]], [[5825, 4500], [3000, 1000], [1000, 0], [0, 0]]], // Winter
    [[[100, 80], [80, 30], [30, 10], [10, 0]], [[4500, 3500], [3500, 500], [500, 0], [0, 0]]], // Overcast / Raining
    [[[100, 80], [80, 30], [30, 10], [10, 0]], [[3500, 750], [750, 500], [500, 0], [0, 0]]], // Spring / Autumm
    [[[100, 80], [80, 30], [30, 10], [10, 0]], [[2000, 500], [500, 300], [300, 0], [0, 0]]] // Summer
];

// Different mapping on conditions, weather, season, etc...
const m = mappings[msg.battery_chargeCurve];

var minin = 0, maxin = 0, minout = 0, maxout = 0
for (let i = 0; i < m[0].length; i++) {
    if (i == 0 && c >= m[0][i][0]) {
        minin = m[0][i][0];
        maxin = m[0][i][0];
        minout = m[1][i][0];
        maxout = m[1][i][0];
        break;
    }
    else if (c < m[0][i][0] && c >= m[0][i][1]) {
        minin = m[0][i][0];
        maxin = m[0][i][1];
        minout = m[1][i][0];
        maxout = m[1][i][1];
        break;
    }
}

msg.payload.setpoint = Math.round(((c - minin) / (maxin - minin) * (maxout - minout)) + minout);

if (minin == 0 && maxin == 0 && minout == 0 && maxout == 0)
    node.status({ fill: "red", shape: "dot", text: 'c: ' + c + ', m: ' + m });
else
    node.status({ fill: "green", shape: "dot", text: 'c: ' + c + ', in: ' + minin + "-" + maxin + ', out: ' + minout + "-" + maxout + ", sp: " + msg.payload.setpoint });

//TODO: Add override based on current voltage and a parametrized max.
//TODO: Control charge limit based on season.

return msg;

```

Here I'm using a fixed set of curves and calculating intermediate points between two values. I'd better like to have only a set of points and not a pair, and get values as if those points where defining a bezier curve, but I don't know how to do it.  
I would like to be able to edit those points ad define the curve in a x,y form.

Any suggestions? 😊

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [15 July 2022 18:04 UTC](https://discourse.nodered.org/t/applying-a-setpoint-curve/62708/2 "2022-07-15T18:04:06Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
