FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: sprudelverduenner am 01 November 2016, 16:01:45

Titel: attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: sprudelverduenner am 01 November 2016, 16:01:45
Hallo liebe FHEM Gemeinde,

ich stehe vor folgendem Problem:

Ich habe ein Gerät, dass ich mit dem Kommando {fhem ("attr Gerät room Raum1")} z.B. in den Raum1 setzen kann.
Möchte ich dieses Gerät nun noch in einen 2. Raum setzen so geht dies natürlich mit  {fhem ("attr Gerät room Raum1,Raum2")}.

Wie sieht aber die Lösung aus, wenn ich das Gerät unabhängig davon, ob es in Raum1 drin ist oder nicht, zum Raum2 hinzufügen möchte??

Oder auch den Raum2 dem Gerät wieder wegnehme - und eine Zugehörigkeit von z.B. Raum1 und Raum3 erhalten bleibt??

Gibt es dafür Befehle ?? Meine Suche danach blieb bisher erfolglos.

Liebe Grüße, Sprudelverduenner
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 16:15:28
Bordmittel sind mir nicht bekannt...

Zufügen würde so gehen:
{fhem "attr <name> room RaumNEU,".AttrVal("<name>","room","")}

Wegnehmen ist einiges komplexer, aber auch das geht...


Gruß
Dan
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: sprudelverduenner am 01 November 2016, 16:33:56
@ DeeSPe

TOP: das geht so schon mal  - danke für den Code...

also an dem Wegnehmen eines Raumes wäre ich auch sehr dran interessiert ...
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: justme1968 am 01 November 2016, 16:38:11
http://www.fhemwiki.de/wiki/Cmdalias#roomadd (http://www.fhemwiki.de/wiki/Cmdalias#roomadd) und folgende.

gruss
  andre
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 17:05:01
Ich hätte noch zwei Funktionen für die 99_myUtils.pm zu bieten die etwas genauer arbeiten:

EDIT: Beste Version (bisher) in diesem Beitrag (https://forum.fhem.de/index.php/topic,60018.msg513782.html#msg513782).

Gruß
Dan

EDIT: Das funktioniert immer nur mit einem angegebenen Raum. Hierbei könnten aber die hinzuzufügenden/zu entfernenden Räume auch ähnlich heißen, z.B. Badezimmer und Badezimmerkammer.
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 17:41:06
Habe die beiden Funktionen nochmals angepasst.
Nun wird auch das Attribut room gelöscht sobald der letzte Raum entfernt wurde.

Gruß
Dan
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: justme1968 am 01 November 2016, 17:42:11
warum arbeitet deine version genauer?

gruss
  andre
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: sprudelverduenner am 01 November 2016, 17:53:42
Hallo Andre,

deine Version des Raumhinzufügenhabe ich ebenfalls probiert - und die Einbindung gefällt mir sogar noch besser.

Allerdings habe ich so mein Problem mit dem löschen des Raums.
Ich habe mal die Funktion roomdelete getestet - wenn ich alles richtig verstanden löscht diese Funktion grundsätzlich den komletten Raum.

Ich möchte allerdings bei einem Device das z.B. im 3 Räumen eingetragen sein kann dann den z.B. 2 Raum deaktivieren....

Oder habe ich eine andere Funktion Deiner verlinkten Seite übersehen ??


Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 18:00:54
Zitat von: justme1968 am 01 November 2016, 17:42:11
warum arbeitet deine version genauer?

gruss
  andre

Weil beim roomadd z.B. nur mittels index der String geprüft wird. Somit könnten auch Räume matchen die den selben Wortanfang haben. Das passiert bei mir nicht.
Oder habe ich was übersehen?

Gruß
Dan

P.S. Daraus kann man genauso einen cmdAlias machen.
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 19:26:25
Hier nochmal die beiden Funktionen überarbeitet damit auch DevSpec und mehrere Räume gleichzeitig funktionieren.
Und dazu passendem cmdalias.

Damit geht dann z.B. sowas:
roomadd dev1,dev2,dev3 room,room1,room2
oder analog dazu:
roomremove dev1,dev2,dev3 room,room1,room2

Code für die 99_myUtils.pm:
sub roomsAdd($$)
{
  my ($devspec,$arooms) = @_;
  my $rooms = $arooms =~ /\!$/ ? (split("!",$arooms))[0] : $arooms;
  foreach my $dev (devspec2array("$devspec"))
  {
    my @oldrooms = split(",",AttrVal($dev,"room",""));
    my $nrooms = $rooms;
    if ($arooms !~ /\!$/)
    {
      foreach my $room (split(",",$rooms))
      {
        push @oldrooms,$room if (!grep(/^$room$/,@oldrooms));
      }
      $nrooms = join(",",sort @oldrooms);
    }
    fhem "attr $dev room $nrooms";
  }
}

sub roomsRemove($$)
{
  my ($devspec,$rrooms) = @_;
  foreach my $dev (devspec2array("$devspec"))
  {
    my @newrooms;
    foreach my $room (split(",",AttrVal($dev,"room","")))
    {
      push @newrooms,$room if (!grep(/^$room$/,split(",",$rrooms)));
    }
    my $nrooms = join(",",sort @newrooms);
    scalar @newrooms ? fhem "attr $dev room $nrooms" : fhem "deleteattr $dev room";
  }
}


2x cmdalias definieren:
define ca_roomadd cmdalias roomadd .* AS {roomsAdd($EVTPART0,$EVTPART1)}
define ca_roomremove cmdalias roomremove .* AS {roomsRemove($EVTPART0,$EVTPART1)}


Das gefällt mir so gut dass ich das bei mir selbst verwenden werde. 8)

Gruß
Dan

EDIT: Mal eben schnell alle meine Steckdosen in einen zusätzlichen Raum stecken:
roomadd (ku|bz|sz|wz|fl)_SD\d Steckdosen
Oder alle ZWave Geräte in einen zusätzlichen Raum:
roomadd TYPE=ZWave ZWave

EDIT2: Force ergänzt für roomadd. Damit werden nun nur noch die angegebenen Räume hinzugefügt und alle anderen entfernt. Einfach ein ! ans Ende stellen:
roomadd TYPE=ZWave ZWave!
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 20:23:52
Ich habe oben bei der "sub addRooms" noch force ergänzt.
Damit werden nun nur noch die angegebenen Räume hinzugefügt und alle anderen entfernt. Einfach ein ! ans Ende stellen:
roomadd dev1,dev2,dev3 room,room1,room2!

Gruß
Dan
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: sprudelverduenner am 01 November 2016, 21:07:33
Hallo Dan,

Du entwickelst Dich zu meinem persönlichen Helden ! ;-)

roomremove klappt perfekt.

Allerdings scheint in der Routine für roomadd noch ein Fehler drinne zu sein.
Hier wird anscheinend nur der force durchgeführt, das heisst alle anderen Räume ausser dem zuzufügendem werden gelöscht....

LG, Sprudelverduenner
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 21:08:43
Zitat von: sprudelverduenner am 01 November 2016, 21:07:33
Allerdings scheint in der Routine für roomadd noch ein Fehler drinne zu sein.
Hier wird anscheinend nur der force durchgeführt, das heisst alle anderen Räume ausser dem zuzufügendem werden gelöscht....

Habe ich vor zwei Minuten gefixt und oben geändert! 8)

Gruß
Dan
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: sprudelverduenner am 01 November 2016, 21:17:18
ich will nicht nörgeln.....

aber jetzt passiert bei beiden Aktionen gar nichts mehr .... ich habe nur die 99-myUtils aktualisiert .... richtig ?!?
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 21:20:38
Zitat von: sprudelverduenner am 01 November 2016, 21:17:18
ich will nicht nörgeln.....

aber jetzt passiert bei beiden Aktionen gar nichts mehr .... ich habe nur die 99-myUtils aktualisiert .... richtig ?!?

Ohhh verdammt!
Sorry, da habe ich beim kopieren wohl eine Zeile unterschlagen!  ::)
Hab's ausgebessert!!! 8)

Gruß
Dan
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: sprudelverduenner am 01 November 2016, 21:27:28
So passt es perfekt .... Herzlichen Dank  :D
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 21:31:09
Bitte gerne!!! 8)

Das mit dem Force ist zwar "nice to have" aber eigentlich Quatsch, denn es entspricht ja einem:
attr dev1,dev2,dev3 room room1,room2,room3

Gruß
Dan

P.S. Ich lerne ja auch immer noch dazu mit diesem Perl und bin selbst immer begeistert wie man hier in FHEM etwas lösen kann.
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 01 November 2016, 21:52:50
Eine kleine Code Vereinfachung habe ich noch vorgenommen um es für die Nachwelt "perfekt" zu haben.  8)
Habe die Funktionen auch noch einmal umbenannt (auch im cmdalias) damit die Namen noch eindeutiger sind.

Es wäre nett wenn Du dann noch dieses Thema mit Verlinkung auf diesen Beitrag (https://forum.fhem.de/index.php/topic,60018.msg513782.html#msg513782) als gelöst kennzeichnen würdest. ;)

Gruß
Dan
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: Master_Nick am 23 Februar 2017, 23:10:53
Dieses wundervolle cmd funktionierte bei mir bis FHEM 5.8 (oder ich habe was verbrochen...)

Nun kommt beim Befehl:
roomadd Anubis.State,Anubis.Taster,FTP.Schalter,NoIP.State,NoIP.Taster,PiTaster,Romy_PC.State,Romy_PC.Taster Technikraum

Der Fehler:
Undefined subroutine &main::roomsAdd called at (eval 2558) line 1.

Nach dem Update hatte ich es aber wieder in die 99_Util datei gepackt...

*EDIT*: Fehler gefunden... hatte es nicht nach einer Passage sondern IN eine eingefügt.... DOh!

Soll diese tolle Erweiterung nicht mal den Weg ins Hauptprogramm finden? ;-)
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: Master_Nick am 10 Juni 2017, 10:20:11
Moin,

ich habe eine Frage zu dem was DesSPe hier vorgestellt hat. Bei mir fliegt das jedes Mal nach einem Update aus der 99_Util raus. Kann man das für sich in eine Datei packen oder mache ich das Update falsch?
*EDIT* Ah er sagt 99_myUtils und nicht die Datei die schon vorhanden ist...... :-D

Zitat von: DeeSPe am 01 November 2016, 19:26:25
Hier nochmal die beiden Funktionen überarbeitet damit auch DevSpec und mehrere Räume gleichzeitig funktionieren.
Und dazu passendem cmdalias.

Damit geht dann z.B. sowas:
roomadd dev1,dev2,dev3 room,room1,room2
oder analog dazu:
roomremove dev1,dev2,dev3 room,room1,room2

Code für die 99_myUtils.pm:
sub roomsAdd($$)
{
  my ($devspec,$arooms) = @_;
  my $rooms = $arooms =~ /\!$/ ? (split("!",$arooms))[0] : $arooms;
  foreach my $dev (devspec2array("$devspec"))
  {
    my @oldrooms = split(",",AttrVal($dev,"room",""));
    my $nrooms = $rooms;
    if ($arooms !~ /\!$/)
    {
      foreach my $room (split(",",$rooms))
      {
        push @oldrooms,$room if (!grep(/^$room$/,@oldrooms));
      }
      $nrooms = join(",",sort @oldrooms);
    }
    fhem "attr $dev room $nrooms";
  }
}

sub roomsRemove($$)
{
  my ($devspec,$rrooms) = @_;
  foreach my $dev (devspec2array("$devspec"))
  {
    my @newrooms;
    foreach my $room (split(",",AttrVal($dev,"room","")))
    {
      push @newrooms,$room if (!grep(/^$room$/,split(",",$rrooms)));
    }
    my $nrooms = join(",",sort @newrooms);
    scalar @newrooms ? fhem "attr $dev room $nrooms" : fhem "deleteattr $dev room";
  }
}


2x cmdalias definieren:
define ca_roomadd cmdalias roomadd .* AS {roomsAdd($EVTPART0,$EVTPART1)}
define ca_roomremove cmdalias roomremove .* AS {roomsRemove($EVTPART0,$EVTPART1)}


Das gefällt mir so gut dass ich das bei mir selbst verwenden werde. 8)

Gruß
Dan

EDIT: Mal eben schnell alle meine Steckdosen in einen zusätzlichen Raum stecken:
roomadd (ku|bz|sz|wz|fl)_SD\d Steckdosen
Oder alle ZWave Geräte in einen zusätzlichen Raum:
roomadd TYPE=ZWave ZWave

EDIT2: Force ergänzt für roomadd. Damit werden nun nur noch die angegebenen Räume hinzugefügt und alle anderen entfernt. Einfach ein ! ans Ende stellen:
roomadd TYPE=ZWave ZWave!
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 10 Juni 2017, 10:22:08
Das gehört in die "99_myUtils.pm"!

Nicht in die "99_Utils.pm"!

Gruß
Dan
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: Master_Nick am 10 Juni 2017, 10:24:15
Jep - Danke ;-) Hatte es gerade gelesen nachdem ich es geschrieben hatte....  :-X
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: Thomas41587 am 24 Februar 2018, 13:10:58
Gibt es eigentlich die Möglichkeit, das roomadd/roomremove auch mit Leerzeichen in Räumen zu verwenden? Ich habe z.B. einen Raum namens "10 Wohnzimmer". Aber egal ob ich es in einfache oder doppelte Anführungszeichen setze, es wird nicht richtig erkannt. Was ist hier die richtige escape-sequenz für das Leerzeichen?
Titel: Antw:attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen
Beitrag von: DeeSPe am 14 März 2019, 16:31:33
Zitat von: Thomas41587 am 24 Februar 2018, 13:10:58
Gibt es eigentlich die Möglichkeit, das roomadd/roomremove auch mit Leerzeichen in Räumen zu verwenden? Ich habe z.B. einen Raum namens "10 Wohnzimmer". Aber egal ob ich es in einfache oder doppelte Anführungszeichen setze, es wird nicht richtig erkannt. Was ist hier die richtige escape-sequenz für das Leerzeichen?

Leider etwas spät die Antwort, aber hier ist sie.
Hier zwei geänderte cmdalias (roomadd, roomrem). Leerzeichen in Räumen bitte wie in URL-Encode mit %20 ersetzen.
Die Funktionen in der 99_myUtils.pm werden nicht mehr benötigt da der entsprechende Code nun direkt im cmdalias steckt:

Code (roomadd) Auswählen
defmod ca_roomadd cmdalias roomadd .* AS {\
  my ($s,$r) = ($EVTPART0,$EVTPART1);;\
  $r =~ s/%20/ /g;;\
  foreach (devspec2array($s))\
  {\
    my @rooms = split(",",AttrVal($_,"room",""));;\
    if (!grep(/^$r$/,@rooms))\
    {\
      push @rooms,$r;;\
      CommandAttr(undef,"$_ room ".join(",",@rooms));;\
      Log3 $_,2,"Adding room '$r' to device '$_'";;\
    }\
  }\
}

Benutzung (einen Raum zu einem Device hinzufügen):
roomadd Dummy1 Testraum
Benutzung (einen Raum mit einem Leerzeichen zu einem Device hinzufügen):
roomadd Dummy1 Test%20Raum
Benutzung (einen Raum zu mehreren Devices hinzufügen):
roomadd Dummy1,Dummy2 Test%20Raum
Benutzung (mehrere Räume zu mehreren Devices hinzufügen):
roomadd Dummy1,Dummy2 Test%20Raum,Test%20Raum%202




Code (roomrem) Auswählen
defmod ca_roomrem cmdalias roomrem .* AS {\
  my ($s,$rr) = ($EVTPART0,$EVTPART1);;\
  $rr =~ s/%20/ /g;;\
  foreach my $d (devspec2array($s))\
  {\
    my @rn;;\
    foreach my $r (split(",",AttrVal($d,"room","")))\
    {\
      push @rn,$r if (!grep(/^$r$/,split(",",$rr)));;\
    }\
    my $rooms = join(",",sort @rn);;\
    $rooms ? CommandAttr(undef,"$d room $rooms") : CommandDeleteAttr(undef,"$d room");;\
  }\
}

Benutzung (einen Raum bei einem Device entfernen):
roomrem Dummy1 Testraum
Benutzung (einen Raum mit Leerzeichen bei einem Device entfernen):
roomrem Dummy1 Test%20Raum
Benutzung (einen Raum bei mehreren Devices entfernen):
roomrem Dummy1,Dummy2 Test%20Raum
Benutzung (mehrere Räume bei mehreren Devices entfernen):
roomrem Dummy1,Dummy2 Test%20Raum,Test%20Raum%202




Und hier noch ein "neuer" cmdalias um einen oder mehrere Räume aus FHEM zu entfernen (die angegebenen Räume werden bei allen Devices entfernt):
Code (roomdel) Auswählen
defmod ca_roomdel cmdalias roomdel .* AS {\
  my $rs = $EVTPART0;;\
  $rs =~ s/%20/ /g;;\
  foreach my $d (devspec2array(".*"))\
  {\
    my @s;;\
    my $ro = AttrVal($d,"room","");;\
    foreach my $r (split(",",$ro))\
    {\
      Log3 $d,2,"Removing room '$r' from device '$d'" if (grep(/^$r$/,split(",",$rs)));;\
      push @s,$r if (!grep(/^$r$/,split(",",$rs)));;\
    }\
    my $rn = join(",",@s);;\
    CommandAttr(undef,"$d room $rn") if (@s && $rn ne $ro);;\
  }\
}

Benutzung (einen Raum bei allen Devices entfernen):
roomdel Testraum
Benutzung (einen Raum mit Leerzeichen bei allen Devices entfernen):
roomdel Test%20Raum
Benutzung (mehrere Räume bei allen Devices entfernen):
roomdel Test%20Raum,Test%20Raum%202



Und hier noch ein "neuer" cmdalias um einen bestimmten Raum bei allen Devices zu ersetzen:
Code (roomrep) Auswählen
defmod ca_roomrep cmdalias roomrep .* AS {\
  my ($ro,$rr) = ($EVTPART0,$EVTPART1);;\
  $ro =~ s/%20/ /g;;\
  $rr =~ s/%20/ /g;;\
  foreach my $d (devspec2array(".*"))\
  {\
    my @s;;\
    my $rs = AttrVal($d,"room","");;\
    foreach my $r (split(",",$rs))\
    {\
      if ($r eq $ro)\
      {\
        Log3 $d,2,"Replacing room '$r' with room '$rr' on device '$d'";;\
        push @s,$rr;;\
      }\
      push @s,$r if ($r ne $ro);;\
    }\
    my $rn = join(",",@s);;\
    CommandAttr(undef,"$d room $rn") if (@s && $rn ne $rs);;\
  }\
}

Benutzung (einen Raum bei allen Devices ersetzen):
roomrep Testraum Testraum2
Benutzung (einen Raum mit Leerzeichen bei allen Devices ersetzen):
roomrep Test%20Raum Test%20Raum%202

Gruß
Dan