Beiträge von Viedotraum
VPN/Proxy erkannt
Es scheint, dass Sie einen VPN- oder Proxy-Dienst verwenden. Bitte beachten Sie, dass die Nutzung eines solchen Dienstes die Funktionalität dieser Webseite einschränken kann.
-
-
Ja, natürlich. Aber ich denke du bist erst beim programmieren am Anfang.
Hier ein paar Tips die dich später nicht verzweifeln lassen.
Versuche immer einzelne Aktionen über Funktionen abzubilden.
Sie können entweder ein Wert berechnen mit Rückgabe oder etwas Schalten.
Der Sinn dahinter ist sie wiederverwendbar im Code zu machen.Ein Beispiel Temperatur:
Code
Alles anzeigenvar tempHome; function readTemperaturSensor() { // HTTP-Aufruf, um die Temperaturdaten abzurufen Shelly.call( "HTTP.GET", { url: "http://192.168.178.70/rpc/Temperature.GetStatus?id=100" }, function(result, error_code, error_message) { if (error_code !== 0) { print('Error beim Abrufen der Temperatur:', error_message); } else { let jsonData = JSON.parse(result.body); tempHome = jsonData.tC; print("Temp Home:", tempHome); // Temperatur wird hier korrekt ausgegeben } } ); } function timerLoop() { readTemperaturSensor(); // Temperatur aktualisieren if (tempHome !== undefined) { print("Aktuelle Temperatur:" + tempHome + " °C"); // Ausgabe der aktuellen Temperatur frostschutz(tempHome); // Hier könnten weitere function gestartet werden... } else { print("Temperatur ist noch nicht verfügbar."); } } function frostschutz(temp) { // print ("Abfrage Frostschutz"); // Ist temp < als Vorgabe ? = Lüfter An. if (temp < 1.5) { // Unter 1,5 °C ? ioLuefter(true); } else { // Größer = aus. ioLuefter(false); } } function ioLuefter(io) { if (io) { // Wenn io = true ist callOn() // Hier könnten noch weitere Aktionen gestartet werden. } else { // Wenn io false ist callOff() // Hier auch... } } function callOn() { // Die Funktion sollte nur den Aufruf für das Relais zum schalten haben. // HTTP aufruf --> Relais vom Shelly ON print("Lüfter Relais ON"); } function callOff() { // Die Funktion sollte nur den Aufruf für das Relais zum schalten haben. // HTTP aufruf --> Relais vom Shelly OFF print("Lüfter Relais OFF"); } // Timer einrichten: Wiederholung alle 1000 ms Timer.set(1000, true, timerLoop);Du siehst im Code das jede function eine Funktion hat. Entweder entscheidet sie was, oder führt was aus.
Ich habe den einfachen Temp lese Code wieder verwand. Da jetzt die Abfrage im Loop abläuft.
Im ersten Durchlauf ist die Temperatur noch nicht in der Globalen Variable var tempHome; gespeichert.
Beim 2. durchlauf liegt sie jetzt vor und kann verarbeitet werden. -
Ja, Shelly zu Shelly mit AddOn. Um Daten abzufragen.
-
Hallo Forumsmitglieder,
hat jemand schon seine Enthärtungsanlage mit einem Shelly nachgerüstet der die Salzbehälterfüllung überwacht?
Meine Anlage ist sehr einfach aufgebaut und ich kann keine Kontakte abgreifen.
Mich würde interessieren mit welchen Sensor man Füllstand zuverlässig überwacht.
Also wann er fast leer ist. -
Oder etwas Smarter mit Callback in der Funktion und Error Handling.
Code
Alles anzeigenfunction readTemperatureSensor(callback) { Shelly.call( "HTTP.GET", { url: "http://192.168.178.70/rpc/Temperature.GetStatus?id=100" }, function (result, error_code, error_message) { if (error_code !== 0) { callback(null, error_message); // Fehler an den Callback weitergeben } else { try { let jsonData = JSON.parse(result.body); callback(jsonData.tC, null); // Erfolg an den Callback weitergeben } catch (e) { callback(null, "JSON-Parsing-Fehler: " + e.message); // Parsing-Fehler } } } ); } // -- Call Read Temperatur --- readTemperatureSensor(function (myTemp, error_message) { if (error_message) { print("Fehler: " + error_message); } else { print("Die Zimmertemperatur ist: " + myTemp + " °C"); } }); -
Ok. Mein Fehler. Zur Erklärung:
Das mit dem Return funktioniert hier nicht, da es sich um ein asynchrones Script handelt.
Das heist, das die Funktion hinter dem Shelly.call(... Befehl asynchron zum rest des Codes verhält.
Es wird nämlich gewartet bis die Daten Empfangen werden und dann verarbeitet.
Da das aber Zeit kostet wird der restliche Code weiter ausgeführt. Der letzte Print Befehl
Wird schneller ausgeführt als der Rückgabewert verarbeitet wurde.Das sieht man auch im Log:
Erst Undefiniert
Dann der Temp wert vom Print in der Shelly.call(... Funktion.
Besser man ruft einfach nach dem Lesen wieder eine Funktion auf die die Daten übermittelt.
Code
Alles anzeigenfunction readTemperaturSensor() { //print ("readTemperaturSensor..."); Shelly.call( "HTTP.GET", { url: "http://192.168.178.70/rpc/Temperature.GetStatus?id=100" }, // IP von Shelly mit AddOn function(result, error_code, error_message) { if (error_code !== 0) { print('Error'); } else { let jsonData = JSON.parse(result.body); let tempHome = jsonData.tC; ausgabe(tempHome); // Call Funktion } }); } function ausgabe(myTemp) { print("Die Zimmertemperatur ist: " + myTemp + " °C"); } // --- Starte Script: readTemperaturSensor(); -
Hast du die ID bei dir überprüft. Ist sie wirklich 100?
{ url: "http://192.168.178.155/rpc/Temperature.GetStatus?id=100" },
-
Oder per Script abfragen:
Code
Alles anzeigenfunction openMetroRead() { Shelly.call( "HTTP.GET", { url: "https://api.open-meteo.com/v1/forecast?latitude=00.0000&longitude=0.0000&daily=sunrise,sunset,temperature_2m_max&timezone=Europe%2FBerlin&forecast_days=1" }, function(result, error_code, error_message) { if (error_code !== 0) { console.log('Fehler:', error_message); } else { let response = JSON.parse(result.body); DATA.sunrise = response.daily.sunrise[0].split("T")[1]; DATA.sunset = response.daily.sunset[0].split("T")[1]; DATA.maxTemperature = Number(response.daily.temperature_2m_max[0]); print("Sunrise: ", DATA.sunrise, " Sunset: ", DATA.sunset, " Max Temperature: ", DATA.maxTemperature, "°C"); DATA.newDay = true; } } ); } openMetroRead()latitude=00.0000&longitude=0.0000
Deine Position kannst du über die Seite: https://www.gpskoordinaten.de/karte/land/DE
ermitteln.
Über die Seite kommst du auf die API.
https://open-meteo.com/en/docs#latitu…forecast_days=1 -
-
Wenn man das gleiche Script in einen virtuellen Eingang/Components 20x schreiben könnte wäre das per Action auch im anderen Shelly nutzbar.
@AlexAn
ich Denke das sollte funktionieren, Ich habe mich aber noch nicht an das Thema Scripting & Components beschäftigt.
Da die API sagt, das noch alles in Beta ist und sich die API noch ändern kann oder wird.
Wäre schlecht wenn eine Update erfolgt und das Script dann nicht mehr funktioniert.
Auch sei erwähnt, das Components nur bei den neuen Gen3 oder Gen2 Pro Geräten möglich ist. -
Ein einfaches Beispiel:
Codefunction ichBinEineFunktionMitRueckgabe() { let temp = 60; // Die Variable wird 60 zugewiesen return temp; } // Aufruf der Funktion: let wieIstTemp = ichBinEineFunktionMitRueckgabe(); print("Die Temperatur ist: " + wieIstTemp + " °C");Um die Funktion aufzurufen musst du nach der function definition ein Aufruf schreiben.
let wieIstTemp = ichBinEineFunktionMitRueckgabe();
--------------
Shelly A mit dem AddOn + Temperaturfühler hat die IP 192.168.178.155
Der Shelly B hat die IP 192.168.178.150Auf Shelly B wird das Script Ausgeführt. Das Script Besteht aus einer Funktion -> function {...}. wie das einfache Beispiel Script.
Über die URL werden die Daten vom Shelly A am AddOn ausgelesen -> Rückgabe ist ein JSON Datei.
Aus der wird dann die Temperatur extrahiert.Die Funktion hat außerdem ein return Aufruf: Der gibt dir den Wert, in diesem Fall Temp als Zahl zurück. Wie das einfache Beispiel Script.
Wenn du nun auf Shelly B die Temperatur auf Shelly A abfragen willst musst du unter der function
den Aufruf ausführen.
let myTemp = readTemperaturSensor();
myTemp enthält nun den Temp Wert.
Das Script nochmal alles zusammen:Code
Alles anzeigenfunction readTemperaturSensor() { //print ("readTemperaturSensor..."); Shelly.call( "HTTP.GET", { url: "http://192.168.178.155/rpc/Temperature.GetStatus?id=100" }, // IP von Shelly mit AddOn function(result, error_code, error_message) { if (error_code !== 0) { print('Error'); } else { let jsonData = JSON.parse(result.body); let tempHome = jsonData.tC; //print ("Temp Home: " ,tempHome); return tempHome; // <--- RÜCKGABE <---- } }); } let myTemp = readTemperaturSensor(); // Funktion aufrufen mit Rückgabewert print("Die Zimmertemperatur ist: " + myTemp + " °C"); -
Der Aufruf sollte sich mit:
Shelly.call("HTTP.POST", { url: sendURL }, function()..
Per Script aufrufen lassen. -
Ich verstehe die Frage nicht ganz. Was willst du genau erreichen?
-
Ja, das ist ein Shelly Script. Das ist ein Bestandteil meines Beschattung Scripts.
Bei mir hängt der Außenfühler mit am AddOn Shelly der auch das Garagentor steuert.
Da der Shelly eh draußen ist, habe ich auch gleich den Temperaturfühler mit angeschlossen.
Um die Temperatur jetzt für die Beschattung der beiden nach Westen ausgerichteten
Fester zu steuern frage ich den Shelly per Script ab.
Ich steuere die Beschattung nach Außentemperatur, Sonnenschein über Helligkeit (Photosensor)
und aktuelle Wetterdaten aus dem Internet. Dadurch bekomme ich Daten wie Bewölkung und
die tägliche Sonnenuntergangszeit.
Daraus errechne ich die Beschattung. Ich will ja im Winter die Sonneneinstrahlung haben, aber
im Sommer nicht. Das Script ist sehr umfangreich geworden, aber es Steuert die Rollos zuverlässig. -
Einfaches Script zum auslesen vom Temperatur Sensor am AddOn von einem anderen Shelly.
Code
Alles anzeigenfunction readTemperaturSensor() { //print ("readTemperaturSensor..."); Shelly.call( "HTTP.GET", { url: "http://192.168.178.155/rpc/Temperature.GetStatus?id=100" }, function(result, error_code, error_message) { if (error_code !== 0) { print('Error'); } else { let jsonData = JSON.parse(result.body); let tempHome = jsonData.tC; //print ("Temp Home: " ,tempHome); return tempHome; } }); }Bei der ID "id=100" in der URL musst du deine ID nehmen sowie die IP vom Shelly mit dem AddOn.
Call:
let myTemp = readTemperaturSensor();
Willst du das Script auf dem Shelly mit dem AddOn benutzen musst du die IP in der URL auf 127.0.0.1 setzen.
{ url: "http://127.0.0.1/rpc/Temperature.GetStatus?id=100" }, -
-
Vielleicht hilft dir diese Code als Beispiel weiter:
Shelly mit der IP: 192.168.178.150Code
Alles anzeigenvar coverState = null; // Globale Variable zum Speichern des Cover-Zustands const allowedStates = ["closing", "opening", "open", "close","stopped"]; // Liste der erlaubten Zustände // Script auf Shelly mit der sendIP Addresse: Nr. 0 bis 2 ----> 0 = Cover L | 1 = Cover VL + VR | 2 = Cover R const indexCoverInDictionary = "1"; // = Cover VL + VR sendet const sendIP = "192.168.178.161"; const scriptPath = "script/3"; Shelly.addEventHandler(function (event) { if (event.name === "cover") { let newState = event.info.event; // Neuer Zustand des Covers // Überprüfen, ob der neue Zustand in der Liste der erlaubten Werte ist if (allowedStates.indexOf(newState) !== -1) { // Nur speichern, wenn der Zustand sich geändert hat if (coverState !== newState) { coverState = newState; // Zustand in globale Variable speichern print("Cover hat sich geändert. Neuer Zustand: " + newState); // Sende zu Register.Endpoint -> 0 = Rastore L Shelly.call("HTTP.REQUEST", { method: "GET", url: "http://" + sendIP + "/" + scriptPath + "/raffstoresZustand?" + indexCoverInDictionary + ":" + newState }); } } } });Empfänger:
Shelly IP: 192.168.178.161
Script 3Code
Alles anzeigenconst ENDPOINT = { allowedStates: ["closing", "opening", "open", "close","stopped"], } HTTPServer.registerEndpoint('raffstoresZustand', function (req, res) { let resultArray = req.query.trim().split(":"); print ("resultArray: " + resultArray); if (ENDPOINT.allowedStates.indexOf(resultArray[1]) !== -1) { print("Anfrage erhalten. Handler für 'raffstoresZustand' aufgerufen. -> req.query: " + req.query); // z.B. Jetzt eine Function aufrufen um seinen Code auszuführen.... // Melde das es Empfangen wurde... res.body = "Shelly Webserver: " + req.query; res.code = 200; res.send(); } });Das Erste Script (IP: 192.168.178.150) abonniert den EventHandler wenn sich der Zustand des Covers ändert. Also betätigt wird.
Wenn das nach den abgefragten Kriterien erfüllt ist, wird den anderen Shelly (192.168.178.161) per Register.Endpoint ein String zugesandt:
Wichtig beim ersten Script ist eigentlich nur das Senden:
CodeShelly.call("HTTP.REQUEST", { method: "GET", url: "http://" + sendIP + "/" + scriptPath + "/raffstoresZustand?" + indexCoverInDictionary + ":" + newState });Der Empfänger abonniert dann 'raffstoresZustand' und wartet darauf bis etwas gesendet wird.
Empfängt HTTPServer.registerEndpoint('raffstoresZustand' was wird die function ausgeführt.
INFO: Es ist nicht nötig den registerEndpoint in einer Timer Schleife zu setzen. der Code wird ausgeführt sobald was empfangen wird.
So kann man über zwei verschiedene Shelly´s Daten austauschen.
Das geht auch mit mehreren Shelly´s die auf dem selben Register.Endpoint senden.
Als Übertragung habe ich "1:open" gewählt.
Der String wird dann beim Empfänger aufgeschnitten "1" und "open" -> so kann ich auswerten welcher Shelly gesendet hat, in diesem Beispiel "1" und als Daten = "open"
-
Ja, das ist möglich. Gehe per IP auf den Shelly, -> Menü Scripts. Gebe oben dem Script einen Namen und speichere es. Z.B. "log".
Dann das Script anklicken und im Fenster unten in der Console -> auf > Websocket debug logs are disabled < Enable klicken.
Als letztes, oben rechts in der Console den Hacken "Only script logs" ausschalten.
Nun einmal den Shelly per App oder Taster ansteuern und schon wird in der Console alle Informationen angezeigt. -
Habe die Kombi (2PM Gen3 + AddOn) im Einsatz. Funktioniert!
-
Über den Voltmeter Eingang lassen sich auch andere Komponenten anschließen.
Der Shelly Uni Plus verfügt ausserdem noch über einen Impulseingang.