Code: Alles auswählen
/*
Shelly 2PM Pro Steuerung mit SOC + PV-Überschuss
------------------------------------------------
- SOC aus Influx (60s), Bitshake Power (10s)
- Relais 0 EIN wenn SOC < 30% oder PV-Überschuss
- AUS wenn SOC >= 70% und kein Überschuss
- Manuelles Schalten stoppt Automatik
- Automatik kann per HTTP-Befehl reaktiviert werden
*/
// ===== Konfiguration =====
let SOC_URL = "http://192.168.178.54:8086/query?db=JBDBMS1&q=SELECT+last(%22SOC%22)+FROM+Batterie";
let BIT_URL = "http://192.168.178.18/cm?cmnd=status%2010";
let RELAY_ID = 0;
let POLL_SOC = 60000;
let POLL_BIT = 10000;
let SOC_ON = 30;
let SOC_OFF = 70;
let autoMode = true;
// ===== Funktionen =====
function checkSOC(){
if(!autoMode) return;
Shelly.call("http.get", { url:SOC_URL }, function(res){
if(res.code === 200){
try {
let data = JSON.parse(res.body);
let soc = data.results[0].series[0].values[0][1];
print("📊 SOC =", soc, "%");
if(soc < SOC_ON){
setRelay(true, "SOC niedrig");
} else if(soc >= SOC_OFF){
checkBitshake(false, soc);
}
} catch(e){ print("❌ Fehler SOC-Parse:", e); }
}
});
}
function checkBitshake(forceOn, socVal){
if(!autoMode) return;
Shelly.call("http.get", { url:BIT_URL }, function(res){
if(res.code === 200){
try {
let data = JSON.parse(res.body);
let power = data.StatusSNS.mMe4.Power;
print("🔌 Bitshake Power =", power, "W");
if(forceOn){
setRelay(true, "SOC <"+SOC_ON+"%");
} else {
if(power < 0){
setRelay(true, "PV-Überschuss");
} else if(socVal >= SOC_OFF){
setRelay(false, "SOC >="+SOC_OFF+"% und kein Überschuss");
}
}
} catch(e){ print("❌ Fehler Bitshake-Parse:", e); }
}
});
}
function setRelay(state, reason){
Shelly.call("Switch.GetStatus", { id:RELAY_ID }, function(res){
if(res.output !== state){
Shelly.call("Switch.Set", { id:RELAY_ID, on:state });
print("⚡ Relais", RELAY_ID, state ? "EIN" : "AUS", "Grund:", reason);
}
});
}
// === Automatik speichern ===
function saveKV(){
Shelly.call("KV.Set", { key:"autoMode", value:(autoMode ? "true":"false") });
}
function loadKV(){
Shelly.call("KV.Get", { key:"autoMode" }, function(res){
if(res && typeof res.value !== "undefined" && res.value !== null){
autoMode = (res.value === "true");
} else {
autoMode = true;
}
print("🔧 Automatik-Status geladen:", autoMode);
});
}
// === Manuelles Schalten abfangen ===
Shelly.addEventHandler(function(ev){
if(ev.component === "switch:"+RELAY_ID && typeof ev.info.output !== "undefined"){
if(autoMode){
print("🖐 Manuell geschaltet – Automatik deaktiviert!");
autoMode = false;
saveKV();
}
}
});
// === HTTP-Kommando für Automatik aktivieren ===
// Aufruf im Browser oder von Grafana:
// http://192.168.178.79/rpc/Script.Eval?code=autoMode%3Dtrue%3BsaveKV()
//
// Damit wird autoMode=true gesetzt und gespeichert.
// === Start ===
print("▶️ Steuerung gestartet: SOC alle", POLL_SOC/1000, "s, Bitshake alle", POLL_BIT/1000, "s");
loadKV();
Timer.set(POLL_SOC, true, checkSOC);
Timer.set(POLL_BIT, true, function(){ checkBitshake(false, 0); });
Was bezweckt es ich schalte damit SOC abhängig und mit der Überwachung des Netzbezuges bzw Einspeisung wie wann der Akku nach geladen wird.
Ich Beriebe ja 1 Wärmepumpe und 2 Splitklimaanlagen an einem 22 km/h (Netto) Akku,
Nachts versuche ich soviel wie möglich den Akku zunutzen, um am Tag diesen wieder nach zuladen immer noch besser als den überflüssigen Strom zuverkaufen ( es wird ja eh noch einiges Erweitert grösserer Akku mehr PV).
Man kann die Werte und Zeit abfragen Variabel im Skript einstellen das ganze läuft Standallone auf dem Shelly der Bitshake wird alle 10 Sekunden abgefragt der SOC aus der Solarnzeige alle 60 Sekunden. Ist eine kleine Dokumentation dazu was dieses Skript kann.
Und wie immer dieser Hinweis:
*****************************ACHTUNG********ACHTUNG********************ACHTUNG**************ACHTUNG************************************************
Ich weise Ausdrücklich darauf hin das programierungen mit Skripten funktionieren können, und nicht müssen hier ist jeder selbst dafür verantwortlich, und muss auch alle Sicherheitsregeln beachten, alle meine Angaben sind somit ohne Gewähr und Rechtlichkeit verbunden.
Ich übernehme keinerlei Haftung bei Schäden, WICHTIG!!!!!!!!!!!!!!!!!!!! immer erst vorher genau prüfen ob das Skript auch zuverlässig läuft!!!!!!!