ich stecke beim Programmieren fest und brauche Hilfe. Auf meinen Shellys können Java Skripte ausgeführt werden. Neuerdings kann Shelly auch mit dynamischen Tarifen arbeiten - via Skript.
Gesucht wird ein Skript, bei dem der Abruf des aktuellen Stundenpreises klappt (priceInfo). Mein Tibber-Token funktioniert, das habe ich via cUrl getestet und erhalte den korrekten Preis. Lediglich das Übersetzen in .js gelingt mir nicht. Ebenso funktioniert der Aufruf via Tibber Developer Explorer.
Ich poste bewusst keinen Code, um keine falsche Fährte zu legen
Auf meinen Shellys können Java Skripte ausgeführt werden. Gesucht wird ein Skript, bei dem der Abruf des aktuellen Stundenpreises von Tibber klappt (priceInfo). Mein Tibber-Token funktioniert,
Und da wurde auch sofort geantwortet:
Super, dass dein Tibber-Token funktioniert. Dann kannst du mit einem Shelly (z. B. Gen2-Gerät mit Skript-Unterstützung) über ein JavaScript-Skript den aktuellen Tibber-Strompreis abrufen. Tibber stellt die Preisinfos über eine GraphQL-API zur Verfügung.
Hier ist ein Beispiel-Skript, das du auf deinem Shelly laufen lassen kannst. Es ruft den aktuellen Tibber-Preis per HTTP-Anfrage ab:
let token = "<DEIN_TIBBER_TOKEN>";
let homeId = "<DEINE_HOME_ID>"; // optional – wird für genauere Abfrage benötigt
let query = JSON.stringify({
query: `
{
viewer {
homes {
currentSubscription {
priceInfo {
current {
total
energy
tax
startsAt
}
}
}
}
}
}`
});
HTTP.request({
url: "https://api.tibber.com/v1-beta/gql",
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: query,
timeout: 5,
success: function(resp, code, headers, body) {
let data = JSON.parse(body);
let price = data.data.viewer.homes[0].currentSubscription.priceInfo.current.total;
print("Aktueller Strompreis:", price, "EUR/kWh");
},
error: function(err) {
print("Fehler beim Abruf:", err);
}
});
Hinweise:
Ersetze <DEIN_TIBBER_TOKEN> durch deinen API-Token.
Falls du mehrere „homes“ hast, kannst du homeId zur genaueren Auswahl anpassen (in der Query z. B. viewer { home(id: "<dein_id>") { ... } }).
Der Strompreis kommt als Wert in Euro/kWh zurück, z. B. 0.287.
Möchtest du das Skript regelmäßig ausführen (z. B. jede Stunde oder alle 5 Minuten), kann ich dir auch ein Timer.set() Beispiel hinzufügen.
Die KI hatte ich auch schon befragt und angewendet. Leider erhalte ich immer einen Fehler, dass die Authentifizierung nicht geklappt hat (no Token und unauthenticated). Laut Recherche muss im query ein Fehler sein, welchen ich nicht finde.
Home Assistant ist keine Option? Das kann Tibber und Shelly. Eine Automation die auf Preisänderung triggert und das Shelly an oder abschaltet ist kein Hexenwerk.
Derzeit nicht, da ich keine Anwendung dafür habe. Ich wollte lediglich den dynamischen Tarif in Shelly implementieren um die Kostendarstellung zu optimieren.
Für den HA benötige ich einen Server/Raspi, korrekt?
Raspi (4/5) geht, aber „besser“ und langfristig flexibler ist ein kleiner Mini-PC-Server. Braucht idR unwesentlich mehr Strom, leistet aber ggf. mehr und man ist auch flexibler in der Konfiguration (z.B. 16/32GB RAM, große, schnelle SSD)
Gegenmeinung: Server macht, wer Bock auf Linux, Docker und Co hat.
Ein HA auf Raspi geht komplett ohne Linuxkenntnisse. Imageprogramm unter Win/Mac runterladen, Image auswählen, SD Karte einlegen und warten. Umstecken in Raspi, einschalten. Im Browser anmelden.
So, meine bessere Hälfte hat das Problem gelöst. Hauptfehler war das HTTP.POST, welches die Shellys nicht verarbeiten können. Derzeit ist die Firmware 1.4.4 drauf. Diese basiert nicht auf MGOS sondern der Shelly Script Engine (Gen2). Daher muss HTTP.REQUEST genutzt werden.
let apiUrl = "https://api.tibber.com/v1-beta/gql";
let token = "XXX";
// Hier euren Tibber-Token einsetzen
let query = JSON.stringify({
query: '{ viewer { homes { currentSubscription { priceInfo { current { total }}}}}}'
});
let shellyCloudUrl = "XXX";
// Die URL sieht grob so aus: https://shelly-NN-eu.shelly.cloud/v2/user/pp-ltu/xxx
let shellyVar = "current_price";
// Variable zur lokalen Speicherung des Preises
function fetchTibberPrice()
{
Shelly.call("HTTP.REQUEST",
{
method: "POST",
url: apiUrl,
headers:
{
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: query
},
function (res, err)
{
if (err)
{
print("Fehler beim Abrufen: ", JSON.stringify(err));
return;
}
let response = JSON.parse(res.body);
//print("Antwortcode: ", res.code);
//print("Antwort: ", JSON.stringify(response));
//print(response);
// 1 Preis in Shelly lokal speichern
Shelly.call("KVS.Set",
{
key: shellyVar, value: response
}
);
// 2 Preis an die Shelly Cloud API senden
let jsonPayload = JSON.stringify({ price: response.data.viewer.homes[0].currentSubscription.priceInfo.current.total.toFixed(4) });
//print(jsonPayload);
print("Strompreis aktuell: ", response.data.viewer.homes[0].currentSubscription.priceInfo.current.total, " €/kWh");
Shelly.call("HTTP.REQUEST",
{
method: "POST",
url: shellyCloudUrl,
headers:
{
"Content-Type": "application/json"
},
body: jsonPayload
},
function (cloudRes, cloudErr)
{
if (cloudErr)
{
print("Fehler beim Senden an Shelly Cloud: ", JSON.stringify(cloudErr));
}
else
{
print("Brutto-Preis erfolgreich an Shelly Cloud gesendet!");
}
}
);
}
);
}
// Skript beim Start ausführen und dann entsprechend aktualisieren
fetchTibberPrice();
Timer.set(300000, true, fetchTibberPrice);
// Zeit in Millisekunden
// alle fünf Minuten = 300000
Als Basis habe ich folgenden Code genutzt - Dank an @tvbshelly geht raus!
Ich habe nun den Timer optimiert. Er prüft minütlich, ob eine neue Viertelstunde angebrochen ist. Wenn ja, dann wird ein neuer Preis ermittelt und gesendet:
Timer.set(60000, true, function ()
{
let now = new Date();
let minute = now.getMinutes();
// Nur alle 15 Minuten
if (minute % 15 === 0)
{
fetchTibberPrice();
}
function pad(num)
{
return (num < 10 ? "0" : "") + num;
}
let hourStr = pad(now.getHours());
let minuteStr = pad(now.getMinutes());
let secondStr = pad(now.getSeconds());
let timeStr = hourStr + ":" + minuteStr + ":" + secondStr;
print("Timer ausgeführt um ", timeStr);
}, null
);
Aktueller Ablauf:
• Es prüft jede Minute (60000 ms).
• Wenn die aktuelle Minute durch 15 teilbar ist (00, 15, 30, 45), wird fetchTibberPrice() aufgerufen.
• Die Ausgabe zeigt sauber „Timer ausgeführt um HH:MM:SS“.
Ich frage mich, was Du jetzt mit dem aktuellen Preis anstellst ?
Für eine smarte Steuerung braucht es doch zusätzlich Kontext wie z.B. Tagestief und Tagesmittel.