Wiederholende Prozeduren auslagern?

Begonnen von stobor, 24 Dezember 2021, 11:51:14

Vorheriges Thema - Nächstes Thema

stobor

Hallo,

ich habe immer wieder auftretende Prozeduren, die durch unterschiedliche Sensoren ausgelöst werden. Bisher schreibe ich die Abläufe für jedes Gerät separat. So wie hier:

define PIR_SuedHM_aus notify Bewegungsmelder_Sued_HM:motion:.on.* {\
if ((Value("PIR_Automatik") eq "on") && (Value("isNACHT") eq "on") && ((Value("Arduino_Pin4_Licht_Sued") eq "off") || (defined(InternalVal('Arduino_Pin4_Licht_Sued','TIMED_OnOff',undef)) eq "1"))) {\
fhem "set Arduino_Pin4_Licht_Sued on-for-timer 320";;\
if (Value("UeberwachungEG") eq "on") {\
fhem "set HM_Sw_Kueche_Sued on-for-timer 120";;\
}\
fhem "delete PIR_SD_aus";;\
fhem "define PIR_SD_aus at +00:05:00 set Bewegungsmelder_Sued_West,Bewegungsmelder_Sued_HM off";;\
} else {\
fhem "delete PIR_SD_aus";;\
fhem "define PIR_SD_aus at +00:05:00 set Bewegungsmelder_Sued_West,Bewegungsmelder_Sued_HM off";;\
}\
if (Value("UeberwachungEG") eq "on") {\
  my $date = strftime "%a %e.%m.%Y %H.%M.%S", localtime;;\
  fhem "attr SSCam.Sued snapEmailTxt subject => Bewegungsalarm PIR Sued Ost, body => $date - Kamera Sued";;\
  fhem "set SSCam.Sued snap 6 2";;\
  fhem "attr SSCam.Ost snapEmailTxt subject => Bewegungsalarm PIR Sued Ost, body => $date - Kamera Ost";;\
  fhem "set SSCam.Ost snap 6 2";;\
  fhem "attr SSCam.Nord_Ost snapEmailTxt subject => Bewegungsalarm PIR Sued Ost, body => $date - Kamera Nord_Ost";;\
  fhem "set SSCam.Nord_Ost snap 6 2";;\
}\
}


Kann man das irgendwie zentral auslagern? Wie? Was müsste ich genau tun?
Wie kann ich ggf. Parameter mitgeben, da zum Teil etwas andere Abläufe innerhalb der Prozedur erfolgen sollen - je nach auslösendem Gerät sollen bspw. andere Kamerabilder gesendet werden?
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Wernieman

Eine Funktion in myUtils anlegen
https://wiki.fhem.de/wiki/99_myUtils_anlegen

Per Perl-Parameterübergabe sind auch Variablenübergabe möglich.

Hinweis:
Sind das Ausgaben direkt aus der fhem.cfg? Besser innerhalb von fhem bearbeiten ....
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

stobor

Zitat von: Wernieman am 24 Dezember 2021, 11:55:06
Eine Funktion in myUtils anlegen
https://wiki.fhem.de/wiki/99_myUtils_anlegen

Per Perl-Parameterübergabe sind auch Variablenübergabe möglich.

Hinweis:
Sind das Ausgaben direkt aus der fhem.cfg? Besser innerhalb von fhem bearbeiten ....

Wie würde der Code denn innerhalb von FHEM aussehen?

Wie würde das denn in Pearl aussehen Aufrufe mit Parameter) - sowohl in Pearl (Funktionskopf) als auch der Aufruf selber?
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Wernieman

Hast Du Dir den Link durchgelesen? Sind doch Beispiele drin ...
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

MadMax-FHEM

Zitat von: Wernieman am 24 Dezember 2021, 13:33:23
Hast Du Dir den Link durchgelesen? Sind doch Beispiele drin ...

Eben, hier z.B.: https://wiki.fhem.de/wiki/99_myUtils_anlegen#Eigene_Routinen_einf.C3.BCgen

Für dein Beispiel dann:


define PIR_SuedHM_aus notify Bewegungsmelder_Sued_HM:motion:.on.* {meineSub($NAME)}


so wird dann eben das auslösende Device übergeben...

In der Sub dann entweder mittels "shift" oder eben (wie im Wiki) my ($obj) = @_; dann steht in $obj eben der Devicename...

Wenn du nun das notify "weiter" gestaltest und eine gute Namensgebung deiner Devices hast, dann hast du in der Sub doch alles was du brauchst... ;)

Wenn z.B. bestimmte Device-Typen im selben Raum dann "zusammengehören", dann kannst du ja z.B. den Raum des triggernden Devices abfragen und dich so durch die dazu gehörenden anderen Devices "hangeln" etc.
Gibt viele weitere Möglichkeiten...
Stichwort: devspec

Anmerkungen: nimm nicht Value!! Sondern ReadingsVal/ReadingsNum! (Value "frägt" STATE das INTERNAL!! ab nicht state! Und: STATE kann/wird z.B. durch stateFormat beeinflusst)

Und warum setzt du attribute?
Gibt das "unschöne" Fragezeichen und bei shutdown/restart sind die "weg"...
(gut evtl. kann das das Modul nicht anders: ist aber unschön)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Prof. Dr. Peter Henning


stobor

Muss ich tatsächlich alle Werte, die ich irgendwie abprüfen möchte als Parameter mit übergeben?
Ich werte ja bspw.

  • Value("PIR_Automatik")
  • Value("isNACHT")
  • Value("Arduino_Pin4_Licht_Sued")
aus.

Würde das dann so aussehen:
define PIR_SuedHM_aus notify Bewegungsmelder_Sued_HM:motion:.on.* { myCode($NAME , Value("PIR_Automatik") , Value("isNACHT") , Value("Arduino_Pin4_Licht_Sued") , InternalVal('Arduino_Pin4_Licht_Sued','TIMED_OnOff',undef)) }

mit
sub myCode($$$$){
   my ($object , $Automatik , $Nacht , $LichtSued , $LichtSuedInt) = @_;
   ...
}

Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Beta-User

Zitat von: stobor am 08 Juni 2022, 10:26:42
Muss ich tatsächlich alle Werte, die ich irgendwie abprüfen möchte als Parameter mit übergeben?
Jein!

a) Wenn du dich mit Prototypen so "einmauerst", musst du die als zwingend gemarkterten Parameter ("sub myCode($$$$)") auch tatsächlich angeben. Man kann das aber auch anders machen.

b) Alles, was geprüft werden soll, muss _ermittelbar_ sein. Ob du das als Parameter-Übergabe machst, oder die (ggf: jeweils) erforderlichen Parameter im Code ermittelst, ist teilweise eine Geschmacksfrage, und zu einem guten Teil auch eine Frage der Übung...

Wenn du beispielsweise wirklich immer "PIR_Automatik" und "isNACHT" auswerten willst, kannst du das ja auch direkt in den Code schreiben (wobei ich empfehlen würde, auf Value() zu verzichten und stattdessen das "stabilere" "state" auszuwerten).

Wenn du "Querbeziehungen" zwischen Devices zu solchen Auswertezwecken herstellen willst, ginge das auch über Readings oder Attribute. Ich verwende z.B. Attribute (zugelassen als userattr), um aus Fenster- oder Türöffnungs-Events abzuleiten, ob/welcher virtuelle Fensterkontakt (nur bei Heizperiode) "auf- oder zugemacht" werden soll. (Anwendungsbeispiel siehe https://forum.fhem.de/index.php/topic,97430.msg1223653.html#msg1223653).
Mein Angang dabei ist in der Regel, dass Funktionen in myUtils "devicelos" sein sollen, sich also alles relevante aus den übergebenen Parametern (und ggf. der Auswertung dauaus abzuleitender Infos aus dem laufenden FHEM) ergibt. Ist in der Erstellung mehr Aufwand, kann dann aber auch leichter geteilt (und geändert!) werden.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

stobor

ich würde natürlich lieber die Zustände im Code ermitteln, damit die Aufrufe übersichtlicher werden.

D.h. ich kann in der Perl Prozedur auch direkt die verschiedenen Geräte/Zustände erfragen?
Einfach per Value("PIR_Automatik") ?

Wie werte ich denn state aus? Wäre das bspw. ReadingsVal("PIR_Automatik","state",0) - in Perl also:
my $myVariable = ReadingsVal("PIR_Automatik","state",0);
So komme ich dann an die Zustände, ohne dass das Objekt mit im Aufruf übergeben wurde?
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Beta-User

Im Prinzip: 3x "ja"...
Zitat von: Beta-User am 08 Juni 2022, 11:10:50
und zu einem guten Teil auch eine Frage der Übung...
Das gilt auch für's Austesten. Im Zweifel logs schreiben und/oder Test-Readings setzen.

Schnelles Stichwort noch: "Quotes in Perl" - alles, was nicht evaluiert werden muss, kommt in einfache Quotes (oder das "harte" q). In deinem letzten Beitrag wäre das _alles_:
ReadingsVal('PIR_Automatik','state',0)

Und wenn du dir beim Code-Kenntlichmachen einfach die code-Tags merkst, wird nicht nur das Formatieren schneller, sondern v.a. auch das Lesen einfacher...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

DetlefR

Hallo,

als erstes musst Du die Namensgebung für die Geräte überdenken. Dann kannst Du ein Notify anlegen das für alle Bewegungsmelder passt.
define PIR_all notify Bewegungsmelder.*:motion:.* .
Das passt für alle Geräte die "Bewegungsmelder..." heißen. Und reagiert auf alles was "motion" ausgibt. Es ist natürlich hilfreich, dass alle PIR auch "motion" als Reading benutzen.
Dann rufst du im Notify deine Funktion auf.
meineFunktion($NAME,$EVTPART1);
In $NAME steht der Name des PIR ersetzt und in $EVTPART1 on oder off.https://wiki.fhem.de/wiki/Notify
Das wird dann an deine Funktion übergeben. Die Funktion fängt dann so ansub meineFunktion($$){
my ($name,$motion)= @_;

ZitatD.h. ich kann in der Perl Prozedur auch direkt die verschiedenen Geräte/Zustände erfragen?
Einfach per Value("PIR_Automatik") ?
würde dann Value($name)lauten.
Wobei ich ReadingsVal immer Value vorziehen würde. ;)

Beta-User

Aha, noch einer, der von Prototypen überzeugt ist ::) und shift nicht "kann" oder kennt...
Zitat von: DetlefR am 08 Juni 2022, 12:29:50
würde dann Value($name)lauten.
Da wette ich im gezeigten Schnippsel dagegen :P ...
(Jedenfalls habe ich arge Schwierigkeiten, "Bewegungsmelder.*" (übeegeben nach $name) und "PIR_Automatik" zur Deckung zu bringen).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

stobor

Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Beta-User

#13
Zitat von: stobor am 08 Juni 2022, 13:15:59
Was wäre dann der Vorschlag?
Es gibt viele Möglichkeiten. Da du scheinbar sowas wie einen "allgemeinen Hauptschalter" zu haben scheinst (!), der einen ganz bestimmten Namen hat, kannst du den auch direkt "vercoden" (wie bereits von dir vorgeschlagen):
my $autoison = ReadingsVal('PIR_Automatik','state',0)

Das "Problem" bei sowas ist nur, dass sich dann irgendwo quer durch den Code verteilt plötzlich irgendwelche Device-Namen finden, von denen ein "Unbedarfter" nicht weiß, warum die grade da auftauchen, und was sie zu bedeuten haben könnten...

Zitat von: Beta-User am 08 Juni 2022, 12:08:22
Das gilt auch für's Austesten. Im Zweifel logs schreiben und/oder Test-Readings setzen.
Im Zweifel musst du selbst rausfinden, welcher Weg der übersichtlichste für dich ist...

Hier noch ein paar Möglichkeiten:
- an das jeweilige auslösende Device ein Attribut hängen, in dem der für dieses Device relevante Automatik-Anzeiger hängt;
- dto. für ein Reading, wobei da auch gleich stehen könnte, ob die Automatik an oder aus ist;
- eine komplexere Auswertung aufrufen (weitere Perl-Sub), die z.B. erst nach dem Reading schaut, wenn das nicht da ist, das Attribut liest, und sich dann, wenn da dann da auch nichts steht auf den "allgemeinen Hauptschalter" schaut...
- in %data die entsprechenden Infos zentral hinterlegen (das ist ein zentraler Hash, in dem User-Daten gespeichert und für den allgemeinen Zugriff vorgehalten werden können).

Nur der von DetlevR vorgeschlagene Weg wird nicht funktionieren, weil die Variable $name eben nicht auf das für diese Info relevante Device zeigt (jedenfalls nicht in deinem aktuellen setup).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

kjmEjfu

Um mal einen neuen Gedanken in diesen Thread zu werfen: man könnte sowas auch mit einem DOIF-Template lösen https://wiki.fhem.de/wiki/DOIF/Automatisierung
Migriere derzeit zu Home Assistant