Hallo,
ich versuche gerade immer wieder kehrende Codezeilen in die 99_myUtils.pm auszulagern.
Ich möchte gerne für meine Steckdosen (Namensstrucktur STK_XXX_SCH) testen lassen ob ich diese Ausschalten kann.
Dafür benötige ich natürlich das Device.
Der Code soll folgendes machen,
Wenn Device mit Reading Stromwert < als Device mit Reading Schaltwert
-> Schalte Device aus, warte 2 Sekunden, und schicke eine Telegramm Nachricht
Ansonsten
- Lasse Device an und schicke ebenfalls eine Telegramm Nachricht.
Da ich nun neu einsteige und versuche mich diesem Thema zu nähern habe ich mal etwas geschrieben was bislang noch nicht funktioniert.
Mir ist nicht ganz klar ob ich hiermit wiklich das Reading des devices als Variable speichern kann.
my $Schaltwert = ReadingsVal ($name, 'Schaltwert' ,0);
Auch hadere ich damit ob ich wirklich genug Variablen aufrufe oder nicht. Habe das auch schon mal verändert von ($$) auf ($$$$) aber bislang ohne Erfolg.
sub Ausschalten($$) {
my ($name, $device ) = @_;
my $Schaltwert = ReadingsVal ($name, 'Schaltwert' ,0);
my $Stromwert = ReadingsVal ($name, 'Watt' ,0);
if($Stromwert < $Schaltwert)
{
fhem( "set $device off" );
sleep(2);
fhem( "set Telegram message @XXXXXXXXXX Spuehlmaschine wurde gestartet");
}
else {
fhem( "set $device on" );
fhem( "set Telegram message @XXXXXXXXXX Spuehlmaschine wurde gestartet");
}
}
Als letztes ist es mir nicht ganz klar ob mein Notify auch wirklich richtig angelegt ist. Es soll auf das Sub Ausschalten hören.
{ Ausschalten( ReadingsVal($NAME,'Watt','')) }
Profis sehen sicherlich gleich die Fehler. Vielleicht kann wer helfen.
Gruß
Tim
Die Befehlskette mit dem sleep muss in einen einzigen fhem() Aufruf, damit sie funktioniert.
fhem("set $device off;; sleep 2;; set Telegram message ...");
Das prototyping kannst Du komplett weglassen:
sub Ausschalten() {
my ($name,$device) = @_;
..
}
Hallo betateilchen,
habe den Code entsprechend verändert;
sub Ausschalten() {
my ($name,$device) = @_;
my $Schaltwert = ReadingsNum ($name, 'Schaltwert' ,0);
my $Stromwert = ReadingsNum ($name, 'Watt' ,0);
if($Stromwert < $Schaltwert)
{
fhem("set $device off;; sleep 2;; set Telegram message @XXXXXXXXXX Spuehlmaschine fertig und ausgeschaltet");
}
else {
fhem( "set $device on ;; sleep 2;; set Telegram message @XXXXXXXXXX Spuehlmaschine wurde gestartet" )
}
}
Nun habe ich auch das Notify verändert (kann man später für alle STK anpassen), beide Versionen laufen leider nicht:
STK_EG_KU_Spuehlmaschine_SCH:.* Ausschalten( ReadingsVal($NAME,'Watt',''))
{ STK_EG_KU_Spuehlmaschine_SCH:.* Ausschalten( ReadingsVal($NAME,'Watt',''))}
Nun bekomme ich schon mal die TriggerEvents:
Readings
state active 2024-08-18 09:16:34
triggeredByDev STK_EG_KU_Spuehlmaschine_SCH 2024-08-18 09:17:08
triggeredByEvent Watt: 6.67 2024-08-18 09:17:08
Aber weder die Steckdose wird ausgeschaltet noh bekomme ich eine Telegramm Message.
Meldungen im EventMonitor kommen so an:
2024-08-18 09:19:24 KNX STK_EG_KU_Spuehlmaschine_SCH Watt: 12.65
2024-08-18 09:19:28 KNX STK_EG_KU_Spuehlmaschine_SCH Watt: 6.67
Vom notify oder ausfeführtem Script sehe ich nichts.
Das Schaltwertreading liegt bei 8
Schaltwert
8
Zitat von: netpirat am 18 August 2024, 09:29:05beide Versionen laufen leider nicht:
Naja, das ist mehr oder weniger logisch, dass das nicht funktioniert.
Ist Dir eigentlich bewusst, was Du da tust?
Du definierst eine Funktion, in der Du zwei Gerätenamen verwenden möchtest ($name und $device)
Aber Du rufst die Funktion stattdessen mit einem Meßwert auf:
Ausschalten( ReadingsVal($NAME,'Watt',''))
Abgesehen davon, dass ich an der Stelle ReadingsNum() sinnvoller fände, ist der Aufruf halt komplett falsch. Du musst die Funktion mit den zwei Werten (für $name und für $device) aufrufen, die Du dann IN der Funktion auch verwenden möchtest.
Das sind übrigens Basics der verwendeten Programmiersprache (egal welcher!) und hat erstmal überhaupt nichts mit FHEM an sich zu tun.
Hi Netpirat,
dein notify hat noch andere Fehler:
statt:STK_EG_KU_Spuehlmaschine_SCH:.* Ausschalten( ReadingsVal($NAME,'Watt',''))
besser:
STK_EG_KU_Spuehlmaschine_SCH:Watt:.* {Ausschalten($NAME)}
1) Aufgerufen sollte das notify nur werden, falls sich der Wert von Watt ändert, daher ein Trigger darauf!
2) "Ausschalten" ist bei dir eine perl-funktion, daher in {} zu setzen....
3) Du brauchst nur den Device-namen als Parameter in deiner sub...
die perl funktion könnte so aussehen:
sub Aussschalten {
my $name = shift;
my $Schaltwert = ReadingsNum ($name, 'Schaltwert' ,0);
my $Stromwert = ReadingsNum ($name, 'Watt' ,0);
....
fhem("set $name off;; sleep 2;; set Tele......
.....
}
PS: nachdem es sich um ein KNX-device handelt, gäbe es noch andere Möglichkeiten, ohne notify....siehe wiki (https://wiki.fhem.de/wiki/KNX_Device_Definition_-_Beispiele) stateCmd.
PPS: Die Logik ist nicht ganz fertig gedacht: Falls device off ist, wird nie wieder durch das notify eingeschaltet! (off -> Watt=0), daher ist "set $name on" unnötig...., die Telegram msg kommt bei jeder Änderung des Watt Wertes...
l.g. erwin
Hallo Erwin,
danke für deine Nachricht. Ich lese mich tatsächlich hier so etwas weiter durchs Forum.
Das Notify habe ich bereits geändert gehabt.
Aber ich war tatsächlich bei $Device = Name des Devices in der Sub, aber es muss $name sein genauergesagt my $name = shift; was dann im Notify über $NAME aufgerufen wird.
Also Notify auf
STK_EG_KU_Spuehlmaschine_SCH:Watt:.* {Ausschalten($NAME)}
Sub entsprechend angepasst
sub Ausschalten {
my $name = shift;
my $Schaltwert = ReadingsNum ($name, 'Schaltwert' ,0);
my $Stromwert = ReadingsNum ($name, 'Watt' ,0);
if( $Stromwert < $Schaltwert )
{
fhem("set $name off;; sleep 2;; set Telegram message @5XXXXXXX Spuehlmaschine wurde beendet");
}
else {
fhem( "set Telegram message @XXXXXXXX Spuehlmaschine wurde gestartet" );
}
}
Leider keine Verbesserung. Keine active Ausführung des Sub. Ich weiß nicht was ich falsch mache....
Vielleicht helfen die Lists der beiden Devices:
nternals:
DEF STK_EG_KU_Spuehlmaschine_SCH:Watt:.* {Ausschalten($NAME)}
FUUID 66c1b12f-f33f-335d-9cc1-595e0d8407383c47
NAME lampe_untoggle
NOTIFYDEV STK_EG_KU_Spuehlmaschine_SCH
NR 662
NTFY_ORDER 50-lampe_untoggle
REGEXP STK_EG_KU_Spuehlmaschine_SCH:Watt:.*
STATE 2024-08-18 12:06:03
TRIGGERTIME 1723975563.62441
TYPE notify
eventCount 6
READINGS:
2024-08-18 12:02:27 state active
2024-08-18 12:06:03 triggeredByDev STK_EG_KU_Spuehlmaschine_SCH
2024-08-18 12:06:03 triggeredByEvent Watt: 6.67
Attributes:
STK_EG_KU_Spuehlmaschine_SCH:
Internals:
DEF 1/0/192:dpt1.001:Schalten:nosuffix
1/1/192:dpt1.011:Status:nosuffix
1/2/192:dpt1.003:Sperren:nosuffix
1/3/192:dpt7.007:Betriebsstunden:nosuffix
1/4/192:dpt1.003:ResetBTK:nosuffix
1/5/192:dpt9.021:Stromwert:nosuffix
1/6/192:dpt1.003:ResetSZ:nosuffix
2/0/192:dpt1.005:Fehlestrom:nosuffix
1/7/192:dpt13.010:Wattstunde:nosuffix
2/1/192:dpt1.011:Lastunterschreitung:nosuffix
2/2/192:dpt1.011:Lastueberschreitung:nosuffix
FUUID 638c3c05-f33f-335d-c7d0-93d63ebfcab22da1
IODev KNX
KNX_MSGCNT 119
KNX_TIME 2024-08-18 12:06:58
LASTInputDev KNX
MSGCNT 119
NAME STK_EG_KU_Spuehlmaschine_SCH
NR 227
STATE Status: on , K: 86.59 €, Strom: 6 watt, Verbrauch 262.4 KWh, Stunden 9289 h
TYPE KNX
eventCount 105
model dpt1
GADDETAILS:
Betriebsstunden:
CODE 013c0
MODEL dpt7.007
NO 4
OPTION
RDNAMEGET Betriebsstunden
RDNAMESET Betriebsstunden
SETLIST
Fehlestrom:
CODE 020c0
MODEL dpt1.005
NO 8
OPTION
RDNAMEGET Fehlestrom
RDNAMESET Fehlestrom
SETLIST :no_alarm,alarm
Lastueberschreitung:
CODE 022c0
MODEL dpt1.011
NO 11
OPTION
RDNAMEGET Lastueberschreitung
RDNAMESET Lastueberschreitung
SETLIST :inactive,active
Lastunterschreitung:
CODE 021c0
MODEL dpt1.011
NO 10
OPTION
RDNAMEGET Lastunterschreitung
RDNAMESET Lastunterschreitung
SETLIST :inactive,active
ResetBTK:
CODE 014c0
MODEL dpt1.003
NO 5
OPTION
RDNAMEGET ResetBTK
RDNAMESET ResetBTK
SETLIST :disable,enable
ResetSZ:
CODE 016c0
MODEL dpt1.003
NO 7
OPTION
RDNAMEGET ResetSZ
RDNAMESET ResetSZ
SETLIST :disable,enable
Schalten:
CODE 010c0
MODEL dpt1.001
NO 1
OPTION
RDNAMEGET Schalten
RDNAMESET Schalten
SETLIST :on,off,toggle
Sperren:
CODE 012c0
MODEL dpt1.003
NO 3
OPTION
RDNAMEGET Sperren
RDNAMESET Sperren
SETLIST :disable,enable
Status:
CODE 011c0
MODEL dpt1.011
NO 2
OPTION
RDNAMEGET Status
RDNAMESET Status
SETLIST :inactive,active
Stromwert:
CODE 015c0
MODEL dpt9.021
NO 6
OPTION
RDNAMEGET Stromwert
RDNAMESET Stromwert
SETLIST
Wattstunde:
CODE 017c0
MODEL dpt13.010
NO 9
OPTION
RDNAMEGET Wattstunde
RDNAMESET Wattstunde
SETLIST
GADTABLE:
010c0 Schalten
011c0 Status
012c0 Sperren
013c0 Betriebsstunden
014c0 ResetBTK
015c0 Stromwert
016c0 ResetSZ
017c0 Wattstunde
020c0 Fehlestrom
021c0 Lastunterschreitung
022c0 Lastueberschreitung
READINGS:
2024-08-18 11:10:11 Betriebsstunden 9289 h
2024-08-18 09:06:34 GestrigeKosten 0.05 €
2024-08-18 11:30:14 IODev KNX
2024-08-18 09:06:34 Jahreskosten 86.59 €
2024-08-13 07:11:31 Lastunterschreitung inactive
2024-08-18 09:06:34 LetzterMonat 84.24 €
2024-08-18 09:06:34 Monatskosten 2.35 €
2024-08-18 09:06:34 Rechenwert 262.392
2024-08-16 18:29:31 Schalten on
2024-08-18 08:06:26 Schaltwert 8
2024-08-18 09:27:14 Status active
2024-08-18 12:06:58 Stromwert 28 mA
2024-08-18 09:06:34 Tageskosten 0.00 €
2024-08-18 12:06:58 Watt 6.44
2024-08-17 18:32:33 Wattstunde 262392 Wh
2024-08-16 18:29:31 cycle 112
2022-10-02 19:01:58 last-sender fhem
2024-07-23 23:51:52 lastChange 1668018767.96056
2024-08-15 23:06:21 operatingTime 89288
2024-07-23 23:51:52 schalten-get on
2024-07-23 23:51:52 schalten-set off
2024-08-18 12:06:58 statRechenwert Hour: 0.000 Day: 0.000 Month: 7.120 Year: 262.392 (since: 2024-07-24 )
2024-08-18 12:06:58 statRechenwertDay 0.000
2024-08-17 23:59:59 statRechenwertDayLast 0.157
2024-08-18 11:59:56 statRechenwertLast Hour: 0.000 Day: 0.157 Month: 255.272 Year: - (since: 2024-07-24 )
2024-08-18 12:06:58 statRechenwertMonth 7.120
2024-08-01 00:00:03 statRechenwertMonthLast 255.272
2024-08-18 12:06:58 statRechenwertYear 262.392
2024-08-18 12:06:58 state 28 mA
2024-08-16 18:29:31 timestamp 1723825771
helper:
_98_statistics STA_AL_AL_Stromverbrauch_WER
Attributes:
event-on-change-reading .*
eventMap 0
group Steckdose
room Kueche
stateFormat {sprintf("Status: %s , K: %.2f €, Strom: %.0f watt, Verbrauch %.1f KWh, Stunden %.0f h", ReadingsVal($name,"Schalten",0), ReadingsVal($name,"Jahreskosten",0), ReadingsVal($name,"Watt",0), ReadingsVal($name,"Rechenwert",0), ReadingsVal($name,"Betriebsstunden",0))}
suppressReading last-sender
userReadings Stromwert:Stromwert.* {(ReadingsNum($name,"Stromwert",0))},
Rechenwert:Wattstunde.* {((ReadingsNum($name,"Wattstunde",0)/1000))} ,
Watt:Stromwert.* {(((ReadingsNum($name,"Stromwert",0)/1000)*230))} ,
cycle
Zitat von: erwin am 18 August 2024, 11:05:56Hi Netpirat,
dein notify hat noch andere Fehler:
statt:STK_EG_KU_Spuehlmaschine_SCH:.*
Ja, man schreibt spülen nicht mit h...
Zitat von: netpirat am 18 August 2024, 12:04:24Keine active Ausführung des Sub. Ich weiß nicht was ich falsch mache....
Zum Testen kannst Du die Funktion ja auch manuell in der FHEM Befehlszeile aufrufen, um herauszufinden, ob sie überhaupt das tut, was Du möchtest.
{Ausschalten("STK_EG_KU_Spuehlmaschine_SCH")}
Und nimm erstmal die sinnfreien event-on-irgendwas Attribute aus dem device raus, solange Du Deine Aufgabe noch nicht erfolgreich gelöst hast. Das notify wird nur ausgelöst, wenn auch ein event kommt...
Hallo Betateilchen,
Du hast mich auf die richtige Spur gebracht.
1. Habe ich ein Leerzeichen hinter dem off eingefügt, nun geht es.
2. Habe ich es nicht geschafft den Telegramm Befehl und den Schaltbefehl in eine Zeile zu bekommen. Aber mit zwei Zeilen funktioniert es.
Was nun noch passiert war, ist das bei jeder Meldung einer neuen Wattzahl, eine neue Meldung aufs Handy (Telegramm) kam. Das ist natürlich suboptimal und so nicht gewollt. Ich habe mir über die Userreadings (siehe Unten - einen Trigger gebaut, der nur bei Überschreiten bzw. Unterschreiten der Wattzahl auslöst). Das geht sicherlich für die Profis auch im Sub direkt aber erstmal piersche ich mich langsam ran, bin leider noch kein Profi. Falls es hier eine einfachere Lösung gibt bin ich immer bereit dazuzulernen.
Hier das Sub:
UPDATE! Nun auch mit Alias Namen
sub Ausschalten {
my $name = shift;
my $alias = AttrVal ($name,"alias",$name);
my $Schaltwert = ReadingsNum ($name, 'Ausschalten' ,0);
if( $Schaltwert == 1 )
{
fhem ("set $name Schalten off ;; sleep 2;;") ;
fhem ("set Telegram send $alias wurde abgeschaltet") ;
}
else {
fhem ("set Telegram send $alias wurde gestartet") ;
}
}
Hier das Userreading:
Stromwert:Stromwert* {(ReadingsNum($name,"Stromwert",0))},
Rechenwert:Wattstunde.* {((ReadingsNum($name,"Wattstunde",0)/1000))} ,
Watt:Stromwert.* {(((ReadingsNum($name,"Stromwert",0)/1000)*230))} ,
Ausschalten { if ( (ReadingsNum($name,'Watt',0)) < (ReadingsNum($name,'Schaltwert',0)) ) { 1 }
else { 2 } },
cycle,timestamp,operatingTime,lastChange
Das Notify hört nun auch auf das Reading Ausschalten:
STK_EG_KU_Spuehlmaschine_SCH:Ausschalten:.* {Ausschalten($NAME)}
Zitat von: netpirat am 18 August 2024, 13:46:502. Habe ich es nicht geschafft den Telegramm Befehl und den Schaltbefehl in eine Zeile zu bekommen. Aber mit zwei Zeilen funktioniert es.
Nein, tut es nicht (Du merkst es nur nicht). Wenn hinter dem FHEM Befehl "sleep..." kein weiterer FHEM Befehl mehr kommt, ist das sleep an der Stelle einfach sinnlos und sollte sogar eine Fehlermeldung im Log produzieren. Wenn Du mit zwei Zeilen arbeitest und fhem() zweimal aufrufst, kannst Du das sleep einfach weglassen.
Und das Leerzeichen hinter "off" hat auch keinen sinnvollen Grund - das dadurch irgendwas funktionieren soll, was es vorher nicht tut, ist nicht nachvollziehbar.
Dass Dein Telegram geflutet wird, solange Deine Spülmaschine läuft, ist logisch. Du prüfst halt in Deiner Funktion nur auf "($Stromwert < $Schaltwert)", alles andere bedeutet in Deiner Logik "einschalten". Hier müsstest Du nochmal eine sinnvollere Fallunterscheidung einbauen.
Die userReadings sind vermutlich komplett entbehrlich. Letztendlich ist ein userReading die Sonderform eines notify. Alles was dort an code drinsteckt, könnte man also auch in dem code machen, den man aus einem bereits existierenden notify ohnehin schon aufruft.
Hallo Betateilhen,
danke für die Antwort und deine Geduld mit einem Anfänger wie mir. Werde mich damit die Tage nochmal intensiver befassen und versuchen den Code (Userreadings) dann das Sub zu basteln. Sollte nicht ganz so schwer sein.
Würde dann den Code entsprechend wieder hier posten.
Hallo,
wenn du die Lust für heute noch nicht ganz verloren hast, dann mach aus den doppelten Semikolon mal einfache:
{
fhem("set $name off; sleep 2; set Telegram message @5XXXXXXX Spuehlmaschine wurde beendet");
}
else {
fhem( "set Telegram message @XXXXXXXX Spuehlmaschine wurde gestartet" );
}
Dazu gab es auch eine Meldung im Logfile.
Hallo,
habe den Code heute nochmal überarbeitet und nun die Prüfung mit eingearbeitet.
Das Reading Wait muss dann entsprechen im Device gesetzt werden.
Damit ist das Userreading Ausschalten überflüssig und wird über das Sub befüllt.
sub Ausschalten {
my $name = shift;
my $alias = AttrVal ($name,"alias",$name);
my $Stromwert = ReadingsNum ($name, 'Watt' ,0);
my $Schaltwert = ReadingsNum ($name, 'Schaltwert' ,0);
my $Wait = ReadingsNum ($name, 'Wait' ,0);
my $Wert = 0 ;
my $OldWert = ReadingsNum ($name, 'Ausschalten' ,0);
if( $Stromwert < $Schaltwert )
{
$Wert = 1 ;
fhem ("setreading $name Ausschalten 1") ;
}
else {
$Wert = 2 ;
fhem ("setreading $name Ausschalten 2") ;
}
if( $Wert == 1 && $Wert != $OldWert)
{
fhem ("set Telegram send $alias Stromwert unterschritten. $Wait Sekunden wird gewartet. Danach wird $alias stromlos geschaltet ") ;
fhem ("sleep $Wait; set $name Schalten off ") ;
}
if ( $Wert == 2 && $Wert != $OldWert)
{
fhem ("set Telegram send $alias wurde gestartet") ;
}
else
{
}
}