Hallo zusammen,
ich möchte gerne meinen Heizstab beim Warmwasser einschalten sobald ich freie Kapazitäten bei meiner PV habe.
Da ich nicht möchte das bei jeden Reading alle paar Sekunden geschalten wird, möchte ich mit einen gleitenden Mittelwert über 5min arbeiten.
Folgendes Reading habe ich erstellt:
attr SolarEdge userReadings MittelwertFreieKapa.av {movingAverage("MittelwertFreieKapa","X_Meter_1_M_AC_Power",1800)}
jetzt bekomme ich im Reading folgende Meldung:
MittelwertFreieKapa.av Error evaluating SolarEdge userReading MittelwertFreieKapa.av: Undefined subroutine &main::movingAverage called at (eval 1203) line 1.
Ich kann jetzt nicht genau deuten was das Problem ist.
Kann mir jemand helfen ?
Vorab Danke
Ich mach das nicht mit einem Mittelwert, sondern einfach mit einer Zeitverzögerung im DOIF:
defmod Doif_Solar_Warmwasser DOIF (\
(\
([my_rct_device:battery_soc] >= 95) ## ...Entweder die Batterie ist schon voll\
|| ([my_rct_device:battery_soc] >= 40 && [my_rct_device:power_solarCombined] > 4000) ## ...oder morgens wird erst eingespeist und spaeter die Batterie geladen...\
|| ([my_rct_device:battery_soc] >= 10 && [my_rct_device:power_solarCombined] > 6000) ## ...oder morgens wird erst eingespeist und spaeter die Batterie geladen... \
)\
&& [ESP_Heizung_WW_Temp:temperature] <= 59 ## ...das Wasser noch nicht heiss ist\
&& [ESP_Heizung_WW_Temp:temperature] > 46 ## ...aber auch nich so kalt, dass ohnehin der Kessel an geht\
&& [UG_Shelly_Heizung_Kessel:power] < 40 ## ...Heizung ist gerade aus\
&& [EG_Eingang_TempHumid:temperature] >= 19 ## ...und die Heizung nicht ohnehin schon an ist... \
&& [Wetter_Muenchen_ProPlanta:fc0_temp09] >= 10 ## ...und heute um 9:00 die Mindesttemperatur x Grad ist.\
&& ($month >= 4 and $month <= 10)\
)\
(\
## Heizstab an\
set UG_Shelly_Heizstab on,,\
setreading UG_Shelly_Heizstab SmartHeating 1,,\
)\
DOELSEIF\
(\
[ESP_Heizung_WW_Temp:temperature] <= 35 ## ...das Wasser noch nicht heiss ist\
&& [UG_Shelly_Heizung_Kessel:power] < 40 ## ...Heizung ist gerade aus\
)\
(\
### Notheizen...\
set pushmsg msg device='AlexPhone11' message='Warmwasser Notheizung angesprungen - Heizung überprüfen!',,\
\
## Heizstab an\
set UG_Shelly_Heizstab on,,\
setreading UG_Shelly_Heizstab SmartHeating 1,,\
)\
DOELSE\
(\
## Heizstab aus\
set UG_Shelly_Heizstab off,,\
setreading UG_Shelly_Heizstab SmartHeating 0,,\
\
)
attr Doif_Solar_Warmwasser group Solarsteuerung
attr Doif_Solar_Warmwasser room Automatisierung
attr Doif_Solar_Warmwasser wait 30
Das Wait 30 verzögert sowohl ein- als auch ausschalten ("Lücken" werden von meiner Batterie gepuffert). Quasi ein bisschen Hysterese... Klappt ganz wunderbar.
Die Logik hat noch ein paar andere Aspekte, die ich bei mir eingebaut habe.
Sollte soweit selbsterklärend sein, bzw. mit den Kommentaren...
Zu den Geräten:
- der ESP hat einen Temperatur-Sensor, der wiederum im Warmwasserspeicher steckt.
- der Shelly steuert den Heizstab (ist ein einfacher 40 EUR 1500 Watt Heizstab - der Thermostat am Stab ist etwas höher als mein DOIF-Schwellwert - damit habe ich quasi eine Fallback-"Temperatur-Sicherung"
- my_rct ist der Wechselrichter, der mir die Leistung ausgibt
- Der Temperatur-Sensor ist neben dem Heizungsfühler draußen
- Das Wetter-Modul gibt mir die Temperatur am Morgen zurück :-)
Hintergrund der Schaltung ist: ich kann meinen Kessel nicht aktiv steuern, d.h. ich habe die untere Schwelle Warmwasser niedriger das den Heizstab gestellt. Wenn der Kessel aber ohnehin anläuft (ist ein Pellets-Kessel), dann brauch ich auch nicht mit dem Heizstab Energie verschwenden... Das ist immer der Fall im Winter, wenn der Schwellwert unterschritten wird oder wenn es draussen so kalt ist, dass ohnehin der Kessel demnächst anspringen wird (wg. Heizung)...
Zitat von: Mellowback am 28 September 2022, 10:19:22
Ich kann jetzt nicht genau deuten was das Problem ist.
"Undefined subroutine &main::movingAverage called at (eval 1203) line 1." bedeutet: Perl kann die angegebene Funktion nicht finden.
Vermutlich hast du nichts in 99_myUtils.pm stehen bzw. jedenfalls nicht das, was z.B. im Wiki zu finden ist: https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen
Ansonsten bin ich sehr skeptisch, ob die Idee gut ist, ein ungetriggerten userReadings-Code dazu zu verwenden, Infos aus einem entfernten Gerät zu holen. Kommt mir eher unsauber vor...
die 99_MyUtils.pm habe ich im Ordner FEHM erstellt und den Baustein aus wiki.fhem eingefügt.
Dann sollte es doch eigentlich funktionieren, oder ?
@Nogga:
wie würde das ganze ohne Batterie und Heizkessel aussehen ?
Zitat von: Mellowback am 28 September 2022, 13:39:42
die 99_MyUtils.pm habe ich im Ordner FEHM erstellt und den Baustein aus wiki.fhem eingefügt.
Dann sollte es doch eigentlich funktionieren, oder ?
Dann sollte erst mal der Fehler weg sein.
Der andere Punkt bleibt aber mAn.:
Zitat von: Beta-User am 28 September 2022, 13:18:19
Ansonsten bin ich sehr skeptisch, ob die Idee gut ist, ein ungetriggerten userReadings-Code dazu zu verwenden, Infos aus einem entfernten Gerät zu holen. Kommt mir eher unsauber vor...
Vielleicht schaust du mal im Event-Monitor, wann/wie oft das aktualisiert wird...
Ich habe vermutlich kein Gerät, das das Modul verwendet, das hinter "SolarEdge" steht und kann daher nicht beurteilen, ob das alles paßt. Im Wiki war nur (ungetriggerter...) Code zu finden, der auf Readings im "eigenen" Device verweist, leider nicht als $name geschrieben (was das deutlicher hervorheben würde).
Zitat von: Mellowback am 28 September 2022, 13:39:42
wie würde das ganze ohne Batterie und Heizkessel aussehen ?
Öhh, ich kenne ja Deine Umgebung nicht - aber aber das einfachste ist einfach nur den Wechselrichter beobachten. Damit sollte er erst anschalten, wenn mindestens 30 Sekunden 1800 Watt anliegen und abschalten, wenn 30 Sekunden lang weniger als 1800 Watt anliegen. Spitzen und Dellen innerhalb der 30 Sekunden resetten einfach den Timer...
So in etwa:
defmod Doif_Solar_Warmwasser DOIF (\
([SolarEdge:X_Meter_1_M_AC_Power] >= 1800) ## ...WR über 1800 Wattl\
)\
(\
## Heizstab an\
set UG_Shelly_Heizstab on,,\
)\
DOELSE\
(\
## Heizstab aus\
set UG_Shelly_Heizstab off,,\
\
)
attr Doif_Solar_Warmwasser group Solarsteuerung
attr Doif_Solar_Warmwasser room Automatisierung
attr Doif_Solar_Warmwasser wait 30
@Beta-User:
event-Monitor bringt folgendes:
2022-09-28 14:25:32 SolarEdge SolarEdge X_Meter_1_M_AC_Power: 7008
2022-09-28 14:26:33 SolarEdge SolarEdge X_Meter_1_M_AC_Power: 3665
2022-09-28 14:27:34 SolarEdge SolarEdge X_Meter_1_M_AC_Power: 7046
@Nogga: Werde ich später auch mal testen, möchte aber gerne noch mit dem mttelwert arbeiten
Danke Euch beiden schon mal
Aha. Also ist das Ausgangsreading doch "beim Device" und es kommt nicht allzu häufig...
Damit käme ich eher dann auf folgenden Code:
attr SolarEdge userReadings MittelwertFreieKapa.av:X_Meter_1_M_AC_Power:.* {movingAverage($name,'X_Meter_1_M_AC_Power',1800)}
leider immer noch das Problem:
MittelwertFreieKapa.av Error evaluating SolarEdge userReading MittelwertFreieKapa.av: Undefined subroutine &main::movingAverage called at (eval 3821) line 1.
sind denn das die richtigen Daten für die 99_MyUtils.pm ?
package main;
use strict;
use warnings;
sub
MyUtils_Initialize($$)
{
my ($hash) = @_;
}
###############################################################################
#
# Moving average
#
# Aufruf: movingAverage(devicename,readingname,zeitspanne in s)
#
###############################################################################
sub movingAverage($$$){
my ($name,$reading,$avtime) = @_;
my $hash = $defs{$name};
my @new = my ($val,$time) = ($hash->{READINGS}{$reading}{VAL},$hash->{READINGS}{$reading}{TIME});
my ($cyear, $cmonth, $cday, $chour, $cmin, $csec) = $time =~ /(\d+)-(\d+)-(\d+)\s(\d+):(\d+):(\d+)/;
my $ctime = $csec+60*$cmin+3600*$chour;
my $num;
my $arr;
#-- initialize if requested
if( ($avtime eq "-1") ){
$hash->{READINGS}{$reading}{"history"}=undef;
}
#-- test for existence
if( !$hash->{READINGS}{$reading}{"history"}){
#Log 1,"ARRAY CREATED";
push(@{$hash->{READINGS}{$reading}{"history"}},\@new);
$num = 1;
$arr=\@{$hash->{READINGS}{$reading}{"history"}};
} else {
$num = int(@{$hash->{READINGS}{$reading}{"history"}});
$arr=\@{$hash->{READINGS}{$reading}{"history"}};
my $starttime = $arr->[0][1];
my ($syear, $smonth, $sday, $shour, $smin, $ssec) = $starttime =~ /(\d+)-(\d+)-(\d+)\s(\d+):(\d+):(\d+)/;
my $stime = $ssec+60*$smin+3600*$shour;
#-- correct for daybreak
$stime-=86400
if( $stime > $ctime);
if( ($num < 25)&&( ($ctime-$stime)<$avtime) ){
#Log 1,"ARRAY has $num elements, adding another one";
push(@{$hash->{READINGS}{$reading}{"history"}},\@new);
}else{
shift(@{$hash->{READINGS}{$reading}{"history"}});
push(@{$hash->{READINGS}{$reading}{"history"}},\@new);
}
}
#-- output and average
my $average = 0;
for(my $i=0;$i<$num;$i++){
$average+=$arr->[$i][0];
Log 4,"[$name moving average] Value = ".$arr->[$i][0]." Time = ".$arr->[$i][1];
}
$average=sprintf( "%5.3f", $average/$num);
#--average
Log 4,"[$name moving average] calculated over $num values is $average";
return $average;
}
1;
Hmm, vermutlich hast du die myUtils-Datei direkt im Dateisystem erstellt und FHEM nicht neu gestartet?
Falls das zutrifft: Bitte die Rechte der Datei kontrollieren (User fhem muss sie lesen können!) und ein relaod derselben ausführen (oder FHEM neu starten).
Ob das inhaltlich hinhaut, kann ich nicht sagen, gehe aber davon aus.
Es waren mal wieder die Rechte, Tausend Dank :)
allerdings ändert sich der wert jetzt alle 1-2min. Müsste dsich doch erst nach 5min ändern oder habe ich einen Denkfehler ?
Nachtrag: Hättest du es über FHEMWEB gemacht, hätten die Rechte gepaßt, und es wäre gleich noch eine Syntaxprüfung drübergegangen, Anleitung wäre in https://wiki.fhem.de/wiki/99_myUtils_anlegen (https://wiki.fhem.de/wiki/99_myUtils_anlegen) zu finden gewesen...
Ansonsten ist es ein Denkfehler: es wird ja immer was zurückgegeben, und wenn was zurückgegeben wird, gibt es eine Aktualisierung im userReading ;) .
Vermutlich suchst du eher nach dem hier: https://wiki.fhem.de/wiki/Event-aggregator (https://wiki.fhem.de/wiki/Event-aggregator)
ich habe jetzt DEF entsprechend hinterlegt und es funktioniert alles soweit.
Allerdings habe ich jetzt das Problem das er sobald er über 1800watt kommt und einschalt gleich wieder abschaltet.
logisch da Bsp. bei einer Einspeisung von 4000watt der Heizstab ca. 3000watt zieht under er dann wieder unter dem schwellwert von 1800watt liegt.
Irgendwie komme ich aber gerade nicht auf den Lösungsansatz.
Hat jemand eine Idee ?
(
([MittelwertFreieLeistung] >= 2800) ## ...WR über 2800 Wattl
)
(
## Heizstab an
set Heizstab on,,
)
DOELSE
(
## Heizstab aus
set Heizstab off,,
)
Müsste doch so passen, oder ?
(
([SolarEdge:MittelwertFreieLeistung] >= 1800) ## ...WR über 1800 Wattl
)
(
## Heizstab an
set Heizstab on,,
)
DOELSE
(
([SolarEdge:MittelwertFreieLeistung] <= 500) ## ...WR unter 500 Wattl
)
(
## Heizstab aus
set Heizstab off,,
)
Hallo,
damit das ohne ständiges Ein/Aus funktioniert, muss in die Berechnung von MittelwertFreieLeistung der Heizstab mit einbezogen werden.
D.h. wenn der Heizstab an ist, die Leistung des Heizstabes zur "freien Leistung" addieren.
Dann ist auch kein else/doelse notwendig.
wäre aber auch nicht effektiv da ja auch andere Geräte wie Waschmaschine den Wert übersteigen können.
Das müsste doch aber mit dem DOELSE funktionieren, oder ?
Man muss das mit der freien Leistung nur anders interpretieren. Selbst wenn der Heizstab schon eingeschalten ist, ist das noch "freie Leistung", da sie bei Bedarf zu/abschaltbar ist.
Der Heizstab hat 3000W
Der Schwellwert zum Schalten liegt bei 3100. Er darf nicht weniger als die Leistung des Heizstabes sein. Außer "freie Leistung" kann negativ werden.
Frei 4000. Heizstab schalten ein. Frei sind weiterhin 4000(1000+3000). Heizstab bleibt an.
Waschmaschine kommt dazu(2000W). Frei 3000(0+3000). Heizstab schaltet ab. Frei 2000(4000-2000+0)Heizstab bleibt aus.
Ich hoffe, es ist einigermaßen rübergekommen. Mit dem Erklären hab ich es nicht so. :-[
Die Logik habe ich verstanden. Mir ging es nur noch darum ob mein DEF korrekt ist.
Vorab Danke
Ich habe meinem meinem SML Stromzähler Device ein User Reading verpasst, das die aktuelle Einspeisung mit den aktuellen Leistungen meiner 2 Ölradiatoren, die ich zum verheizen benutze, verrechnet.
Auf dieses Reading das ich noch mit dem Aggregator auf Mittelwert alle 60 Sekunden gezähmt habe, triggert mein Stufen DOIF zum zuschalten der Radiatoren.
So ich der Wert auf den ich reagiere immer der aktuelle Überschuss, egal welche Leistung gerade verheizt wird.
userReading:
Ueberschuss {sprintf "%.0f",((ReadingsVal($NAME,"SML_Watt_Summe",0) - ReadingsVal("Radiator1","power",0) - ReadingsVal("Radiator2","power",0)))}
DOIF:
defmod Heizen_mit_PV_Ueberschuss DOIF ([Stromzaehler:Ueberschuss] > -490)\
(set Radiator1 off, set Radiator2 off) \
\
DOELSEIF ([Stromzaehler:Ueberschuss] <= -490 and [Stromzaehler:Ueberschuss] > -740)\
(set Radiator1 on, set Radiator2 off) \
\
DOELSEIF ([Stromzaehler:Ueberschuss] <= -740 and [Stromzaehler:Ueberschuss] > -1330)\
(set Radiator1 off, set Radiator2 on)\
\
DOELSEIF ([Stromzaehler:Ueberschuss] <= -1330)\
(set Radiator1 on, set Radiator2 on)
Die Schaltstufen sind auf die Leistungen der Radiatoren abgestimmt und um 100 W nach oben verschoben. Die Überlegung ist das es auch günstiger ist als Gas wenn ich nur ca 70 % der Nennleistung aus der Einspeisung nehme.
Hallo,
bin so etwas ähnliches am bauen.
Idee ist es den Überschuss an erzeugtem Strom in den Heizkessel zu speisen. Als Rücklaufanhebung.
Hardware:
Einen Bypass im Rücklauf aus 1 1/2" Zoll rohr.
Eine kleine Zirkulationspumpe
2 Heizstäbe, jeweils 150 Watt
2 Heizstäbe, jeweils 100 Watt
3 Temperatursensoren DS18b20
3 kurze 1/2" Zoll Tauchhülsen
evt. Magnetventil und oder Rückflussverhinderer
Relaiskarte mit 8 Relais
Finder Hutschienen Relais 220V
Software:
([stromzaehler:power] > -100)
(set relais1 off, set relais2 off, set relais3 off, set relais4 off)
DOELSEIF ([stromzaehler:power] <= -100 and [stromzaehler:power] > -150)
(set relais1 off, set relais2 off, set relais3 on, set relais4 off)
DOELSEIF ([stromzaehler:power] <= -150 and [stromzaehler:power] > -200)
(set relais1 on, set relais2 off, set relais3 off, set relais4 off)
DOELSEIF ([stromzaehler:power] <= -200 and [stromzaehler:power] > -250)
(set relais1 off, set relais2 off, set relais3 on, set relais4 on)
DOELSEIF ([stromzaehler:power] <= -250 and [stromzaehler:power] > -300)
(set relais1 on, set relais2 off, set relais3 on, set relais4 off)
DOELSEIF ([stromzaehler:power] <= -300 and [stromzaehler:power] > -400)
(set relais1 on, set relais2 on, set relais3 off, set relais4 off)
DOELSEIF ([stromzaehler:power] <= -350 and [stromzaehler:power] > -400)
(set relais1 off, set relais2 on, set relais3 on, set relais4 on)
DOELSEIF ([stromzaehler:power] <= -400 and [stromzaehler:power] > -500)
(set relais1 on, set relais2 on, set relais3 on, set relais4 off)
DOELSEIF ([stromzaehler:power] <= -500 and [stromzaehler:power] > -800)
(set relais1 on, set relais2 on, set relais3 on, set relais4 on)
Tempsensor 1 soll vor den Bypass
Tempsensor 2 soll hinter den Bypass
Tempsensor 3 soll in den Bypass
Wenn Tempsensor 3 z.b. 50°C misst, soll relais5 "Pumpe" für gewisse Zeit eingeschaltet werden, und drückt erwärmtes Wasser in den Rücklauf von Kessel.
So ist mal der Plan.