attr room - einem Gerät per Befehl Räume hinzufügen / entnehmen

Begonnen von sprudelverduenner, 01 November 2016, 16:01:45

Vorheriges Thema - Nächstes Thema

sprudelverduenner

FHEM @ RaspberryPi 3, HMLAN, HMUART + HMRS485, Homematic, ESPEasy @ Sonoff / Shelly / ESP8266, ZigBee @ CC2531
Echo Dot, Dreambox, Yamaha MusicCast, Logitech Hub, LW-12, LD382
FRITZ!Box 7590 AX, Mesh @ FRITZ!Repeater 2400, FRITZ!Fon, iPhone 13, iPad Air 5, AppleWatch 8

DeeSPe

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.
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

DeeSPe

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 als gelöst kennzeichnen würdest. ;)

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

Master_Nick

#18
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? ;-)
Rancher K8s Cluster mit nanoCUL (a-culfw) | IObroker | IT(V1&V3), IT-PIR, THGR122NX |Co² | alexa-fhem | WOL | NFC | Harmony UltimateHub | Anwesenheitserkennnung | Roomba | 10" Touch mit Node-Red | SonOff S20 | SonOff Touch | SonOff Dual | Rolladen | Und ganz viel anderes tolles Gerödel.... ;-)

Master_Nick

#19
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!
Rancher K8s Cluster mit nanoCUL (a-culfw) | IObroker | IT(V1&V3), IT-PIR, THGR122NX |Co² | alexa-fhem | WOL | NFC | Harmony UltimateHub | Anwesenheitserkennnung | Roomba | 10" Touch mit Node-Red | SonOff S20 | SonOff Touch | SonOff Dual | Rolladen | Und ganz viel anderes tolles Gerödel.... ;-)

DeeSPe

Das gehört in die "99_myUtils.pm"!

Nicht in die "99_Utils.pm"!

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

Master_Nick

Jep - Danke ;-) Hatte es gerade gelesen nachdem ich es geschrieben hatte....  :-X
Rancher K8s Cluster mit nanoCUL (a-culfw) | IObroker | IT(V1&V3), IT-PIR, THGR122NX |Co² | alexa-fhem | WOL | NFC | Harmony UltimateHub | Anwesenheitserkennnung | Roomba | 10" Touch mit Node-Red | SonOff S20 | SonOff Touch | SonOff Dual | Rolladen | Und ganz viel anderes tolles Gerödel.... ;-)

Thomas41587

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?

DeeSPe

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