Last (mit Shelly) dynamich zuschalten ohne Internet

Hi!

Ich habe eingentlich eine ganz einfache Aufgabe. Verstehe nur nicht ob man sie lokal auch einfach umsetzten kann.

Wir haben ein Gebäude ohne Internet.
Eine Balkonkraftwerk ohne speicher (1800 kWp, Hoymilies 1600 HMS gedrosselt auf 800W)
Einen digitalen Stromzähler
Einen Luftentfeuchter

Ich möchte einen Luftentfeuchter anschalten wenn am Hausanschluss 600W Überschuss anliegen. Und ausschalten nachdem sie nicht mehr anliegen. (Ich schätze um flackern zu vermeinden wäre die logik dann 5min, Bezug > 50W = aus)

Noch ist nichts bestellt.
Ich würde gerne eine gute Mischung aus nicht so kompiziert / Preiswert haben.
Selbsteinschätzung der technichen Fähikeiten: Fortgeschritten

Hätten wir Internet wäre mein Lösungsansatz einen Shelly Pro 1 mit einem Ecotracker zu verbinden. So wie ich das verstanden habe findet aber die schaltlogik in der Cloud statt, damit wäre diese Lösung raus.

Hatte jemand schonmal so eine Fall / Lösung?

Beste Danke und Grüße!

Prinzipell funktioniert so etwas - ich mach das mit ioBroker und Blockly.
Den Wert hole ich mir über einen Hitchi Lesekopf nach ioBroker und das Blockly schaltet den Shelly.

Dann fehlt nur noch ein z.B. Shelly Pro 3EM in der Unterverteilung.
Dieses Teil kommuniziert (auch ohne "Internet" und Cloud) mit dem Shelly Pro 1 (das ist ein Schaltrelais) über die lokale Shelly "Funkwelt".

Hi!

Ich weiß das es iobroker gibt, hab sowas bis jetzt noch nicht benutzt.
Für mich ist das die große Lösung die viele weitere Anwendungsmöglichkeiten eröffnet… die ich (sehr wahrscheinlich) nicht benutzten werde.
Ich würde gerne heraus finden ob es für meine Aufgabe: 1Messwert, 2 Bedingungen eine simplere Lösung gibt.

Beide Shellys haben eine auf mJS Basierende mini skripting engine.
An welchem der beiden geräte du das machst ist erstmal egal.

Programmflow wäre:
Check alle 5 min
Ist Leistung vom ShellyEM > 600W
dann schalte Shelly Pro 1 oder anderen Shelly ein
wenn nicht dann aus

Handelsübliche LLMs helfen bei so was einfachem in der Regel schon ganz gut.

Hi!

(Sorry, zuerst auf den flaschen Beitrag geantwortet…)

Die Anwort hat mich etwas verwirrt.
Der Pro 3EM ist das Leistungsmessgerät
Der Shelly Pro 1 der Schalter
Aber in welchem der beiden Gerät steckt jetzt die schalt logik?

Last dynamich zuschalten ohne Internet

Dafür braucht es nicht viel. Ein digitaler Stromzähler liefert einmal pro Sekunde alle relevanten Daten. Die Daten entsprechen dem SML-Protokoll.

Fertige IR-Leseköpfe gibt für 5-10 Eur im WWW zu kaufen.

Mit einem µP lassen sich die Daten auslesen und mit einem Solid-State Relais die Last schalten.

Hinweis: Hier im Forum hat ein Mitglied eine solche Steuerung realisiert und auch vorgestellt → mal suchen.

Hallo Pisafox,
der Pro 3EM hat den Überblick über deinen Hausverbrauch (über die 3 Phasen, er saldiert "fast" korrekt).

Wenn er einen Überschuss feststellt... dann kann er über dein lokales Hausnetz den Pro 1 Schalter ansteuern.

Ich würde aber lieber einen Shelly Plug S Steckdosenadapter nehmen, in diesen den Luftentfeuchter stecken.

Wie das einzurichten ist?
Das erkärt die google Gemini KI ganz gut.

  1. Eingabe: "shelly ohne cloud"
  2. Eingabe: "ja, eine lokale Einrichtung eines Shelly Pro 3em und eines Shelly Plug S"

Zum Beispiel im Shelly Pro 3EM. Du kannst dafür Skripte schreiben und damit steuern.
Siehe https://www.shelly.com/de/blogs/scripts-library und Tutorial | Shelly Technical Documentation

Gibt massig Steuerungssysteme, die man verwenden kann. Wenn Du lokal steuern willst und keine Cloud willst, musst Du Dich irgendwann mal für eine der vielen Alternativen entscheiden.

Wenn Du doch keine Probleme hast Deine Logik ins Internet auszulagern kannst Du auch in dem Haus einen kleinen mobilen LTE-WLAN-Router (ab ca. 40 EUR) aufbauen und damit ins Internet gehen. Damit bekommt man fast alle Gebäude ins Internet. Und mit Starlink auch an fast jedem Ort der Welt.

Ich persönlich setze auf Homeassistant und auch auf Node-Red. Jeder wie er will. Hätte keine Lust mich in die Shelly-Skript-Sprache einzuarbeiten.

Hi!

Danke für die ganzen Rückmeldungen!
Ich möchte schonmal einen Zwischenstand geben.

Ich werde versuchen die Aufgabe mit einem Shelly Pro 3EM und einem Shelly Pro 2 PM zu lösen.

Warum nicht mehr Ecotracker?
Das Gebäude ist quasi ein “StupidHome”, es gibt keine Digital infrastruktur auf die am aufbauen könnte. Eigentlicht hatte ich den Ecotracker wegen dem einfacherere Einbau ausgewählt.
Da die beiden Shellys aber einen Lan Port haben, kann ich damit eine Peer to Peer Verbindung aufbauen.
Shelly→Cat Kabel →Shelly, was mir am betriebssichersten erscheint.
(Da die Schaltlogik auch in dem Shelly Pro 2PM ausgelöst werden kann und eine MQTT abfrage vom Ecotracker möglich sein sollte, müsste das auch mit dem Ecotracker gehen. Dieser muss aber über WLAN eingebunden werden)

Der Vorschalg von Berny IR Lesekopf→µP→Relai ist mir etwas zu komplex.

Warum Shelly PRO 2 PM
”PRO” weil LAN Anschluss
”2” da ich vlt in der Zukunft zwei Verbraucher abwechselt schalten will.
”PM” Die idee ist, dass die Schaltlogik besser arbeiten kann wenn ich weiß was meine geschalteten Lasten in dem Moment wirklich verbrauchen.
Was über den Pro 3EM am Hausanschluss nicht erfasst werden kann.
Außer man würde es schaffen, dass nur die Schaltlasten auf einer Phase sind.
(Bei uns nicht möglich)

Ich experimentiere jetzt erstmal mit dem Shelly Script rum und melde mich nochmal mit den Ergebnissen.

Besten danke und Grüße

Hi!

Abschlussbericht:

Die Schaltung leuft jetzt PRO3EM über LAN verbunden an PRO2PM.

Im PRO3EM läuft jetzt ein Scritp zur Lasterfassung mit einer Werteglättung.
Die Steuerung soll träge sein, daher auch der auslösende Wert.
(Kompressoren mögen es nicht dauernt an und aus geschaltet zu werden.

Shelly Pro3EM Script

	
	// Konfiguration
	let CONFIG = {
	    // Kurzes Intervall für präzise Glättung (5 Sek)
	    interval_erfassung: 5000,
	    // Wie viele Messungen warten, bis gesendet wird (6 * 5s = 30s)
	    send_intervall_faktor: 6,
	    // Leistung über alle 3 Phasen
	    totalPower: 0.00,
	    // Zähler für Sende-Intervall
	    tick: 0
	};
	
	function checkPower() {
	    Shelly.call("EM.GetStatus", { id: 0 }, function (result, error_code, error_msg) {
	        if (error_code !== 0) {
	            //console.log("Fehler beim Auslesen des 3EM");
	            return;
	        }
	
	        // 1. Glättung (Exponentieller Durchschnitt)
	        CONFIG.totalPower = (result.total_act_power * 0.1 + CONFIG.totalPower * 0.9);
	        let roundedPower = Math.round(CONFIG.totalPower * 100) / 100;
	        
	        //console.log("Messung läuft... Glättungswert: " + roundedPower + " W");
	
	        // 2. Sende-Logik (nur jedes X-te Mal)
	        CONFIG.tick++;
	        if (CONFIG.tick >= CONFIG.send_intervall_faktor) {
	            CONFIG.tick = 0; // Zähler zurücksetzen
	            
	            Shelly.call(
	                "Number.Set",
	                { id: 200, value: roundedPower },
	                function(res, err, msg) {
	                    if (err === 0) {
	                        //print(">>> Wert alle 30s an ID 200 übertragen:", roundedPower);
	                    } else {
	                        //print("Fehler beim Senden an Virtual Component:", msg);
	                    }
	                }
	            );
	        }
	    });
	}
	
	// Skript-Intervall starten (alle 5 Sekunden)
	Timer.set(CONFIG.interval_erfassung, true, checkPower);

Shellys verfügen über eine local speicher für variablen die von anderen Shellys abgrufen werden können.
Dazu wurde von mir im Fenster “Components” des PRO3EM ein “Component”
Name: Leistung
Typ: Field
number:200
angelegt.
Dort schreibt der PRO3EM alle 30s den neuen geglätteten Wert rein und der PRO2PM ruft diesen ab.

Hier nun die Schaltlogik für den PRO2PM

Es gibt 2 Anschlüssel
Das Script ruft den Componet des PRO3EM ab
und prüft mit einer Kette von “If” Abfragen alle 15min ob einer der beiden Lasten zu oder aufgeschaltet werden soll.
Ziel dabei ist es nur den Überschuss abzufangen aber den Kompressor zu schonen.
Dabei wird davon ausgegagen, dass der erste Ausgang weniger Last hat als der zweite.
Nach jedem Einschaltvorgang wird die Last neu bestimmt.

	
	// Konfiguration
	let V = {
	    // IP des Shelly Pro3EM
	    Pro3EM: "84.84.84.232",
	    // Ab welchem Überschuss soll die Anschaltlogik gestartet werden? (Den kleinensten Wert eintragen. Entweder P_0 oder P_1 - P_0)
	    MIN_ON: -5,
	    // Vergleichwert für die Abschaltlogik
	    MIN_OFF: 0,
	    // Ab welchem Bezug soll die Abschaltlogik gestartet werden
	    MAX_OFF: 100,
	    // Leistungs_Durschnitt übermittelt vom PRO3EM
	    P_D: 0,
	    // Leistung am ersten Ausgang: Start Wert 5
	    P_0: 5,
	    // Leistung am zweiten Ausgang: Start Wert 10
	    P_1: 10,
	    // 5Sekunden warten = 5000ms
	    WAIT: 5000,
	    // Alles 15 Minuten Loopen = 900000ms
	    LOOP: 900000,
	    // Status switch 0 ersten Ausgang:
	    SW_0: false,
	    // Status switch 1 zweiten Ausgang
	    SW_1: false
	    
	    
	};
	
	//###################################################################
	// Fragt die Components TYP Number, id 200 des Shelly Pro 3EM mit der hinter V.Pro3EM hinterlegten IP
	
	function DREIemABFRAGE(){
	Shelly.call(
	    "HTTP.GET", 
	    { url: "http://" + V.Pro3EM  + "/rpc/Number.GetStatus?id=200"},
	    function(result, error_code, error_message) {
	        if (error_code === 0 && result !== null) {
	            let data = JSON.parse(result.body);
	            V.P_D = data.value;
	            print("Aktuelle Leistung:", V.P_D);
	            Timer.set(V.WAIT, false, schalten);
	        } else {
	            print("Fehler beim Abruf:", error_message);
	        } //if (error_code === 0 && result !== null)
	    } //function(result, error_code, error_message)
	); //Shelly.call
	
	}// function DREIemABFRAGE
	 
	 
	//###################################################################
	
	function schalten(){
	  //Status Ausgang 1
	  V.SW_0 = Shelly.getComponentStatus("switch:0").output;
	  console.log("SW_0:", V.SW_0);
	  //Status Ausgang 2
	  V.SW_1 = Shelly.getComponentStatus("switch:1").output;
	  console.log("SW_1:", V.SW_1);
	  // Haben wir einen Überschuss?    
	  if (V.P_D <= V.MIN_ON){
	    // Läuft das erste Gerät schon?
	    if (V.SW_0 === true){
	      //Läuft das zweite Gerät schon?
	      if (V.SW_1 === true){
	        // Wir haben überschuss aber nichts mehr zum zuschalten, fertig
	        return;
	        } else {
	          // Das zweite Gerät läuft noch nicht haben wir genug Überschuss um es zu zu schalten
	          if (V.P_D + V.P_1 <= V.MIN_ON){
	            Shelly.call("Switch.Set", { id: 1, on: true });
	            Timer.set(V.WAIT,false,SET_P_1);
	            return; //Zugeschaltet und fertig
	            } else {
	              // Bei mir ist die zweite Leistung größer als die erste also schau ich jetzt ob ich sie STATT der ersten einschalten kann ohne in BEZUG zu kommen
	              if (V.P_D + V.P_1 - V.P_0 <= V.MIN_ON){
	                Shelly.call("Switch.Set", { id: 0, on: false });
	                Shelly.call("Switch.Set", { id: 1, on: true });
	                Timer.set(V.WAIT,false,SET_P_1);
	                return; // erste aus, zweite an, fertig
	                } else {
	                  return; //wir können die Last werder tauschen noch Zuschalten, fertig 
	              } //if (V.P_D + V.P_1 - V.P_0 <= V.MIN_ON)
	          } // if (V.P_D + V.P_1 <= V.MIN_ON)      
	      } // if (V.SW_1 === true)
	    } else {
	      // Ist die Last vom ersten Ausgang kleiner aus der Überschuss?
	      if (V.P_D + V.P_0 <= V.MIN_ON){
	        // Ist der Zweite Ausgang AN?
	        if (V.SW_1 === true){
	          Shelly.call("Switch.Set", { id: 0, on: true });
	          Timer.set(V.WAIT,false,SET_P_0);
	          return; // Schalte den ersten Ausgang ein, fertig
	          } else {
	            // Ist die Last vom zweiten Ausgang kleiner aus der Überschuss?
	            if (V.P_D + V.P_1 <= V.MIN_ON){
	              Shelly.call("Switch.Set", { id: 1, on: true });
	              Timer.set(V.WAIT,false,SET_P_1);
	              return; // Schalte den zweiten Ausgang ein, fertig
	              } else {
	                Shelly.call("Switch.Set", { id: 0, on: true });
	                Timer.set(V.WAIT,false,SET_P_0);
	                return; // Schalten den ersten Ausgang ein, fertig
	            } //if (V.P_D + V.P_1 <= V.MIN_ON)
	        } //if (V.SW_1 === true)
	      } else {
	        return; // Die Last vom ersten Ausgang ist größer als der Überschuss, mach nix, fertig
	      } //if (V.P_D + V.P_0 <= V.MIN_ON)
	    } // if (V.SW_0 === true)
	  } else {
	    // Wir haben einen Bezug definiert der beidem wir Anfangen Lasten abzuschalten 
	    if (V.P_D >= V.MAX_OFF){
	      // Ist der erste Ausgang geschaltet?
	      if (V.SW_0 === true){
	        // Ist der zweite Ausgang geschaltet?
	        if (V.SW_1 === true){
	          // Wenn wir nur Ausgang 1 ausschalten haben wir immer noch Netzbezug?
	          if (V.P_D - V.P_0 >= V.MIN_OFF){
	            // Wenn wir nur Ausgang 2 ausschalten haben wir immer noch Netzbezug?
	            if (V.P_D - V.P_1 >= V.MIN_OFF){
	              Shelly.call("Switch.Set", { id: 0, on: false });
	              Shelly.call("Switch.Set", { id: 1, on: false });
	              return; // Da Ausgang 2 bei mir viel mehr Leistung hat als 1 schaltet ich an dieser stelle bei aus um aus dem Netzbezug zu kommen, fertig
	              } else{
	                Shelly.call("Switch.Set", { id: 1, on: false });
	                return; //Schalte Ausgang 2 aus, fertig
	            } //if (V.P_D - V.P_1 >= V.MIN_OFF)
	          } else {
	            Shelly.call("Switch.Set", { id: 0, on: false });
	            return; //Schalte Ausgang 1 aus,fertig
	          } //if (V.P_D - V.P_0 >= V.MIN_OFF)
	        }else {
	          Shelly.call("Switch.Set", { id: 0, on: false });
	          return; // Da Ausgang 2 schon aus ist, schalte Ausgang 1 aus , ferig
	        } //if (V.SW_1 === true)
	      } else {
	        //Ausgang 1 ist aus, trotzdem gibt es noch netzbezug ist Ausgang 2 geschaltet?
	        if (V.SW_1 === true){
	          Shelly.call("Switch.Set", { id: 1, on: false });
	          return; //Schalte Ausgang 2 aus, fertig
	          } else {
	            return;// Beide Ausgänge sind schon aus es gibt nichts mehr zum ausschalten, fertig
	        } //if (V.SW_1 === true)
	      } //if (V.SW_0 === true)
	    } //if (V.P_D >= V.MAX_OFF)
	  } //if (V.P_D <= V.MIN_ON)    
	} // function schalten
	
	//###################################################################
	// Abfrage Leitsung von Ausgang 1
	function SET_P_0(){
	  let stat = Shelly.getComponentStatus("switch:0");
	  if (stat) V.P_0 = stat.apower;
	  console.log("P_0:", V.P_0,"Watt")
	} 
	
	//###################################################################
	// Abfrage Leistung von Ausgang 2
	function SET_P_1(){
	  let stat = Shelly.getComponentStatus("switch:1");
	  if (stat) V.P_1 = stat.apower;
	  console.log("P_1:", V.P_1,"Watt")
	} 
	
	
	
	//###################################################################
	DREIemABFRAGE(); // Sofortiger Start beim Speichern/Reboot
	Timer.set(V.LOOP, true, DREIemABFRAGE); // Dann in schleife alle X Minuten je nach der "LOOP" definierung

Bis jetzt siehts gut aus.
Danke an alle.
Und für die, die das hier lesen und denken “nett, passt für mich aber nicht”.
Ich hatte auch keine Ahnung von Shelly script.
Das schreiben hat mit Gemini ca 5. Stunden gedauert.

Beste Grüße