Skip to content

Commit

Permalink
gg
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieucarbou committed Jul 1, 2024
1 parent dd0b0a3 commit f41a039
Showing 1 changed file with 80 additions and 37 deletions.
117 changes: 80 additions & 37 deletions docs/blog/solar_diverter.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,118 @@
const SCRIPT_ID = JSON.stringify(Shelly.getCurrentScriptId());

const CONFIG = {
const KV = {
DEBUG: "SOLAR_DIVERTER_DEBUG",
// PID Set point (usually 0 in the case of a router)
PID_SETPOINT: "SOLAR_DIVERTER_PID_SETPOINT",
// PID Kp term
KP: "SOLAR_DIVERTER_PID_KP",
PID_KP: "SOLAR_DIVERTER_PID_KP",
// PID Ki term
KI: "SOLAR_DIVERTER_PID_KI",
PID_KI: "SOLAR_DIVERTER_PID_KI",
// PID Kd term
KD: "SOLAR_DIVERTER_PID_KD",
PID_KD: "SOLAR_DIVERTER_PID_KD",
// Read interval in seconds
READ_INTERVAL_S: "SOLAR_DIVERTER_READ_INTERVAL_S",
}

const DEFAULTS = {
KP: 0.66,
KI: 0.005,
KD: 0.8,
DEBUG: true,
PID_SETPOINT: 0,
PID_KP: 0.6,
PID_KI: 0.001,
PID_KD: 0.8,
PID_OUTPUT_MIN: 0,
READ_INTERVAL_S: 1,
}

let kp = DEFAULTS.KP, ki = DEFAULTS.KI, kd = DEFAULTS.KD;
let readItvl = DEFAULTS.READ_INTERVAL_S;
let CONFIG = {
DEBUG: DEFAULTS.DEBUG,
PID_SETPOINT: DEFAULTS.PID_SETPOINT,
PID_KP: DEFAULTS.PID_KP,
PID_KI: DEFAULTS.PID_KI,
PID_KD: DEFAULTS.PID_KD,
PID_OUTPUT_MIN: DEFAULTS.PID_OUTPUT_MIN,
READ_INTERVAL_S: DEFAULTS.READ_INTERVAL_S,
}

let PID = {
lastError: 0,
errorSum: 0,
}

let divertPower = 0;

function calculatePID(input) {
const error = CONFIG.PID_SETPOINT - input;
const dError = error - PID.lastError;
PID.errorSum = Math.max(PID.errorSum + error, CONFIG.PID_OUTPUT_MIN);
const pTerm = error * CONFIG.PID_KP;
const iTerm = PID.errorSum * CONFIG.PID_KI;
const dTerm = dError * CONFIG.PID_KD;
PID.lastError = error;
return pTerm + iTerm + dTerm;
}

function onPowerUpdate(result, err) {
if (err)
return;
if (CONFIG.DEBUG)
print("Data: ", JSON.stringify(result));
const output = calculatePID(result.act_power);
if (CONFIG.DEBUG)
print("PID output: ", output);
divertPower = Math.max(0, divertPower + output);
if (CONFIG.DEBUG)
print("Divert Power: ", divertPower, " W");
}

function loadConfig(cb) {
Shelly.call("KVS.Get", { key: CONFIG.KP }, function (result, err) {
kp = err ? DEFAULTS.KP : parseFloat(result.value);
print("Kp = ", kp);
Shelly.call("KVS.Get", { key: CONFIG.KI }, function (result, err) {
ki = err ? DEFAULTS.KI : parseFloat(result.value);
print("Ki = ", ki);
Shelly.call("KVS.Get", { key: CONFIG.KD }, function (result, err) {
kd = err ? DEFAULTS.KD : parseFloat(result.value);
print("Kd = ", kd);
Shelly.call("KVS.Get", { key: CONFIG.READ_INTERVAL_S }, function (result, err) {
readFreq = err ? DEFAULTS.READ_INTERVAL_S : parseInt(result.value);
if (!readFreq) {
readFreq = DEFAULTS.READ_INTERVAL_S;
}
print("Read Interval = ", readItvl, " s");
cb();
cb();
Shelly.call("KVS.Get", { key: KV.PID_KP }, function (result, err) {
if (!err) CONFIG.PID_KP = parseFloat(result.value);
print("CONFIG.PID_KP = ", CONFIG.PID_KP);
Shelly.call("KVS.Get", { key: KV.PID_KI }, function (result, err) {
if (!err) CONFIG.PID_KI = parseFloat(result.value);
print("CONFIG.PID_KI = ", CONFIG.PID_KI);
Shelly.call("KVS.Get", { key: KV.PID_KD }, function (result, err) {
if (!err) CONFIG.PID_KD = parseFloat(result.value);
print("CONFIG.PID_KD = ", CONFIG.PID_KD);
Shelly.call("KVS.Get", { key: KV.SETPOINT }, function (result, err) {
if (!err) CONFIG.PID_SETPOINT = parseFloat(result.value);
print("CONFIG.PID_SETPOINT = ", CONFIG.PID_SETPOINT, " W");
Shelly.call("KVS.Get", { key: KV.READ_INTERVAL_S }, function (result, err) {
if (!err) CONFIG.READ_INTERVAL_S = parseInt(result.value);
if (!CONFIG.READ_INTERVAL_S) CONFIG.READ_INTERVAL_S = DEFAULTS.READ_INTERVAL_S;
print("CONFIG.READ_INTERVAL_S = ", CONFIG.READ_INTERVAL_S, " s");
cb();
});
});
});
});
});
}

function saveConfig(cb) {
Shelly.call("KVS.Set", { key: CONFIG.KP, value: ("" + kp) }, function (result, err) {
Shelly.call("KVS.Set", { key: CONFIG.KI, value: ("" + ki) }, function (result, err) {
Shelly.call("KVS.Set", { key: CONFIG.KD, value: ("" + kd) }, function (result, err) {
Shelly.call("KVS.Set", { key: CONFIG.READ_INTERVAL_S, value: ("" + readItvl) }, function (result, err) {
cb();
Shelly.call("KVS.Set", { key: KV.PID_KP, value: ("" + CONFIG.PID_KP) }, function (result, err) {
Shelly.call("KVS.Set", { key: KV.PID_KI, value: ("" + CONFIG.PID_KI) }, function (result, err) {
Shelly.call("KVS.Set", { key: KV.PID_KD, value: ("" + CONFIG.PID_KD) }, function (result, err) {
Shelly.call("KVS.Set", { key: KV.PID_SETPOINT, value: ("" + CONFIG.PID_SETPOINT) }, function (result, err) {
Shelly.call("KVS.Set", { key: KV.READ_INTERVAL_S, value: ("" + CONFIG.READ_INTERVAL_S) }, function (result, err) {
cb();
});
});
});
});
});
}

function onPowerUpdate(result, err) {
if (!err) {
print(JSON.stringify(result));
}
}

loadConfig(function () {
saveConfig(function () {
// Shelly.addStatusHandler(function (evt) {
// if (evt.id == 0 && evt.name === 'em1' && evt.delta.act_power !== undefined) {
// onPowerUpdate(evt.delta);
// }
// });
Timer.set(readItvl * 1000, true, function () {
Timer.set(CONFIG.READ_INTERVAL_S * 1000, true, function () {
Shelly.call("EM1.GetStatus", { id: 0 }, onPowerUpdate);
});
});
Expand Down

0 comments on commit f41a039

Please sign in to comment.