Code zum Auschschalten und Telegramm Nachricht schreiben

Begonnen von netpirat, 18 August 2024, 08:37:54

Vorheriges Thema - Nächstes Thema

netpirat

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

betateilchen

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) = @_;
  ..
}
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

netpirat

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



betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

erwin

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 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
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...

netpirat

#5
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


betateilchen

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...
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

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...
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

netpirat

#8
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)}

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

netpirat

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.

 


TomLee

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.

netpirat

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
  {
 
  }
}