Frage zum belegen einer Variable mit unterschiedlichem Inhalt

Begonnen von skydns, 15 Januar 2017, 12:33:39

Vorheriges Thema - Nächstes Thema

skydns

Variablen bieten ja viele Möglichkeiten, hier brauche ich Hilfe von jemandem der sich sehr gut mit dem setzten von Variablen auskennt.

Für die Übergabe von Anwesenheitszuständen an das Modul Residents habe ich den folgenden Code geschrieben:

### RESIDENTS
sub Anwesenheit_check_resi($) {
my ($NAME) = @_;
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIASNAME des GTAGs auslesen
my $RESIUSER = "rr_"; # rr_ Residents Roommate rg_ für Residents Guest
my $ROOMMATE = ("$RESIUSER" . "$ALIASNAME"); # Residentsname zusammenbauen

if (ReadingsVal($NAME,'presence',$NAME) eq "absent") {
fhem("set $ROOMMATE absent"); # Resistenten Status von Roommates setzen
}
elsif(ReadingsVal($NAME,'presence',$NAME) eq "present") {
fhem("set $ROOMMATE home"); # Resistenten Status von Roommates setzen
}
}


Mein Problem bezieht sich auf diesen Bereich:
sub Anwesenheit_check_resi($) {
my ($NAME) = @_;
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIASNAME des GTAGs auslesen
my $RESIUSER = "rr_"; # rr_ Residents Roommate rg_ für Residents Guest
my $ROOMMATE = ("$RESIUSER" . "$ALIASNAME"); # Residentsname zusammenbauen


Da die Bewohnernamen im Residenzmodul mit rr_ beginnen und Gäste mit rg_ muss die Variable $RESIUSER unterschiedlich belegt werden.

Ich habe es schon mit if und elsif probiert.

Mein versuch als Beispiel (nicht funktionsfähig!):

sub Anwesenheit_check_resi($) {
my ($NAME) = @_;
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIASNAME des GTAGs auslesen

if(($NAME eq "gtag_rot") xor ($NAME eq "gtag_schwarz)){
my $RESIUSER = "rr_";
}
elsif{
my $RESIUSER = "rg_";
}

my $ROOMMATE = ("$RESIUSER" . "$ALIASNAME"); # Residentsname zusammenbauen


Das Problem ist das die Variable gesetzt wird, auch wenn die Bedingung nicht erfüllt ist, da sie dann doppelt gesetzt wird führt es zu Fehlermeldungen. Hat jemand eine Idee wie man es besser schreiben könnte?

Danke für eure Hilfe.
Gruß Marco
NUC - CUL868Mhz V3 culfwV1.67 - Zigbee2MQTT Sonoff 2.0 - Ubuntu 22.04 - FHEM 6.1 zum Schalten von Licht+Steckdosen (Sonoff,Shelly,MQTT,Tasmota,Zigbee) und Überwachung von diversen Homematic/Homematic IP Kontakten/Sensoren mit Anwesenheitserkennung

UliM

Beim elseif fehlt ne Bedingung, ist also eigentlich ein else. Erstaunlich dass das ohne Fehlermeldung durchgeht.
Also bei elsif die Bedingung einfügen und außerdem einen else-Zweig anhängen, in dem der Variablenwert nicht oder explizit auf leer gesetzt wird.
Oder habe ich falsch verstanden was du erreichen willst?
Gruß, Uli

PS: warum hast du das im Homematic-Board gepostet?
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

skydns

#2
Ich dachte das Board passt gut, weil man sehr viele Skripte schreibt bei Homematic.

sub Anwesenheit_check_resi($) {
my ($NAME) = @_;
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIASNAME des GTAGs auslesen

if(($NAME eq "gtag_rot") xor ($NAME eq "gtag_schwarz") xor ($NAME eq "gtag_gruen")){
my $RESIUSER = "rr_";
}
elsif(($NAME eq "gtag_orange") xor ($NAME eq "gtag_weis")){
my $RESIUSER = "rg_";
}
else{
my $RESIUSER = "";
}

my $ROOMMATE = ("$RESIUSER" . "$ALIASNAME"); # Residentsname zusammenbauen


Ja stimmt, elsif erfordert ja auch eine Bedingung. Ich habe das korrigiert wie oben zu sehen, ich erhalte dann aber folgenden Fehler:

Global symbol "$RESIUSER" requires explicit package name at ./FHEM/99_myUtils.pm line 64.
Zeile 64 ist oben im Code die letzte Zeile, in der quasi die Variable ausgelesen wird.

Der Fehler entsteht meiner Meinung, wie schon oben erwähnt durch Mehrfachbelegung der Variable.
NUC - CUL868Mhz V3 culfwV1.67 - Zigbee2MQTT Sonoff 2.0 - Ubuntu 22.04 - FHEM 6.1 zum Schalten von Licht+Steckdosen (Sonoff,Shelly,MQTT,Tasmota,Zigbee) und Überwachung von diversen Homematic/Homematic IP Kontakten/Sensoren mit Anwesenheitserkennung

DeeSPe

Deine Herangehensweise ist m.E. völlig falsch!

Mit Alias würde ich schon mal gar nichts machen, da der schnell verändert werden kann.
Also entweder gibst Du den Tags eindeutigere Namen, so dass ein Bestandteil den Namen des zu schaltenden ROOMMATE/GUEST enthält! Oder Du musst die Tags anders eindeutig zuweisen.
Entweder fest im Code hinterlegen ala:
my $resident = "rr_bla";
$resident = "rg_blub" if ($tagname eq "gtag_schwarz");
$resident = "rr_boris" if ($tagname eq "gtag_gruen");


Oder Du gibst den Tags ein userattr mit ala:
attr <GTAG> userattr resdev
Dort kannst Du dann für jeden Tag das zu schaltende ROOMMATE/GUEST Device eintragen und im Code mit AttrVal($tagname,"resdev",$tagname) wieder auslesen.

So wird eher ein Schuh draus.
In meinem Modul HOMEMODE muss der Name des PRESENCE Devices an irgendeiner Stelle den Namen des zu schaltenden ROOMMATE/GUEST enthalten und wird darüber eindeutig erkannt. Ohne Hardcoding und ohne userattr. Darfst Dir das Modul gerne mal runterladen und schauen wie ich das gemacht habe.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

skydns

#4
Danke für deine Korrektur. Auch wenn dir die Programmierung so nicht gefällt ist es für mich dank deines Tipps funktionsfähig. Da mir FHEM noch recht neu ist versuche ich die Programmierung schlicht zu halten und nehme erstmal, was mir FHEM so anbietet. Da ist Alias für mich erstmal das Einfachste.

Kompliziert wird es dann später von selbst. Die Programmierung wächst ja immer weiter. Wenn ich mit den userattr vertrauter bin werde ich es vielleicht später mal ändern.
Die GTAG Namen sind erstmal eindeutig, in meinem Fall:
gtag_rot
gtag_schwarz
gtag_gruen
gtag_orange
gtag_weis

Da ich gerne mit Variablen arbeite, ist das mit dem Alias nur eine Option einen schöneren Namen im Log zu sehen oder bei Benachrichtigung. Da will ich dann nicht gtag_rot sehen. Ein Klartextname über Alias ist dann "Alltagstauglich".

my ($NAME) = @_;
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIASNAME des GTAGs auslesen

my $RESIDENT = "rr_"; # rr_ Residents Roommate rg_ für Residents Guest
$RESIDENT = "rg_" if (($NAME eq "gtag_orange") xor ($NAME eq "gtag_weis"));
my $ROOMMATE = ("$RESIDENT" . "$ALIASNAME"); # Residentsname zusammenbauen


Das ist nur ein Auszug aus dem großen ganzen, daher fehlt hier etwas der Zusammenhang. Ist aber gerade die stelle im Code die ich noch verbessern wollte. Das hat nun mit deiner Hilfe geklappt.

Alles im Zusammenhang ist im Wiki zu finden:
https://wiki.fhem.de/wiki/Anwesenheitserkennung#Anwesenheitserkennung_.2F_Anwesenheitsbenachrichtigung_mit_G-Tags

Wenn ich Verbesserungen vornehme wird es auch da aktualisiert. Für einen geübten Programmierer sind hier und da bestimmt Verbesserungen möglich um den Code zu reduzieren.

Danke, Gruß Marco
NUC - CUL868Mhz V3 culfwV1.67 - Zigbee2MQTT Sonoff 2.0 - Ubuntu 22.04 - FHEM 6.1 zum Schalten von Licht+Steckdosen (Sonoff,Shelly,MQTT,Tasmota,Zigbee) und Überwachung von diversen Homematic/Homematic IP Kontakten/Sensoren mit Anwesenheitserkennung