From f6d9cc5639df9ec96083432b6f7f2f407e1ffa71 Mon Sep 17 00:00:00 2001 From: wuehler <> Date: Sun, 10 Jun 2018 15:42:35 +0000 Subject: [PATCH] 74_Unifi.pm:new Submodule 74_UnifiSwitch git-svn-id: https://svn.fhem.de/fhem/trunk@16845 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 4 + fhem/FHEM/74_Unifi.pm | 143 +++++++++------ fhem/FHEM/74_UnifiSwitch.pm | 334 ++++++++++++++++++++++++++++++++++++ fhem/MAINTAINER.txt | 1 + 4 files changed, 428 insertions(+), 54 deletions(-) create mode 100755 fhem/FHEM/74_UnifiSwitch.pm diff --git a/fhem/CHANGED b/fhem/CHANGED index 22bcfa0ca..e01015154 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,9 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 74_UnifiSwitch: initial version + - feature: 74_Unifi: new child-Module UnifiSwitch + new reading UC_newClients for new clients + block clients by mac-address - change: 98_dewpoint: new attribute legacyStateHandling - feature: 93_DbRep: V7.18.0, possible use of y:(\d) in timeDiffToNow, timeOlderThan, delEntries considers executeBeforeDump, diff --git a/fhem/FHEM/74_Unifi.pm b/fhem/FHEM/74_Unifi.pm index bb877fb97..e23e08fbe 100644 --- a/fhem/FHEM/74_Unifi.pm +++ b/fhem/FHEM/74_Unifi.pm @@ -1,4 +1,4 @@ -############################################################################## + ############################################################################## # $Id$ # CHANGED @@ -26,6 +26,11 @@ # - fixed: 74_Unifi: Cookies for UnifiController 5.9.4 # V 2.2.4 # - fixed: 74_Unifi: import encode_json for newest libs +# V 3.0 +# - feature: 74_Unifi: new child-Module UnifiSwitch +# V 3.0.1 +# - feature: 74_Unifi: new reading UC_newClients for new clients +# - feature: 74_Unifi: block clients by mac-address package main; @@ -45,6 +50,7 @@ sub Unifi_Notify($$); sub Unifi_Set($@); sub Unifi_Get($@); sub Unifi_Attr(@); +sub Unifi_Write($$); sub Unifi_DoUpdate($@); sub Unifi_Login_Send($); sub Unifi_Login_Receive($); @@ -76,9 +82,9 @@ sub Unifi_Cmd_Receive($); sub Unifi_ClientNames($@); sub Unifi_ApNames($@); sub Unifi_SSIDs($@); -sub Unifi_BlockClient_Send($@); +sub Unifi_BlockClient_Send($$); sub Unifi_BlockClient_Receive($); -sub Unifi_UnblockClient_Send($@); +sub Unifi_UnblockClient_Send($$); sub Unifi_UnblockClient_Receive($); sub Unifi_UpdateClient_Send($$); sub Unifi_UpdateClient_Receive($); @@ -105,6 +111,7 @@ sub Unifi_Whowasi(); sub Unifi_Initialize($$) { my ($hash) = @_; $hash->{DefFn} = "Unifi_Define"; + $hash->{WriteFn} = "Unifi_Write"; $hash->{UndefFn} = "Unifi_Undef"; $hash->{SetFn} = "Unifi_Set"; $hash->{GetFn} = "Unifi_Get"; @@ -119,6 +126,9 @@ sub Unifi_Initialize($$) { ."deprecatedClientNames:1,0 " ."voucherCache " .$readingFnAttributes; + + $hash->{Clients} = "UnifiSwitch"; + $hash->{MatchList} = { "1:UnifiSwitch" => "^UnifiSwitch" }; } ############################################################################### @@ -153,13 +163,6 @@ sub Unifi_Define($$) { loglevel => AttrVal($name,"httpLoglevel",5), sslargs => { SSL_verify_mode => 0 }, }; - #if($hash->{unifi}->{version} == 3) { - # ( $hash->{httpParams}->{loginUrl} = $hash->{unifi}->{url} ) =~ s/api\/s.+/login/; - # $hash->{httpParams}->{loginData} = "login=login&username=".$a[4]."&password=".$a[5]; - #}else { - # ( $hash->{httpParams}->{loginUrl} = $hash->{unifi}->{url} ) =~ s/api\/s.+/api\/login/; - # $hash->{httpParams}->{loginData} = '{"username":"'.$a[4].'", "password":"'.$a[5].'"}'; - #} my $username = Unifi_encrypt($a[4]); my $password = Unifi_encrypt($a[5]); @@ -253,31 +256,31 @@ sub Unifi_Set($@) { } } elsif ($setName eq 'blockClient') { - if ($setVal && $setVal ne 'all') { - $setVal = Unifi_ClientNames($hash,$setVal,'makeID'); - if (defined $hash->{clients}->{$setVal}) { - Unifi_BlockClient_Send($hash,$setVal); - } - else { - return "$hash->{NAME}: Unknown client '$setVal' in command '$setName', choose one of: all,$clientNames"; - } + my $id = Unifi_ClientNames($hash,$setVal,'makeID'); + my $mac = "x"; + if (defined $hash->{clients}->{$id}) { + $mac = $hash->{clients}->{$id}->{mac}; + }elsif($setVal =~ m/^[a-fA-F0-9:]{17}$/g){ + $mac = $setVal; } - elsif (!$setVal || $setVal eq 'all') { - Unifi_BlockClient_Send($hash,keys(%{$hash->{clients}})); + if($mac ne "x"){ + Unifi_BlockClient_Send($hash,$mac); + }else { + return "$hash->{NAME}: Unknown client '$setVal' in command '$setName', use mac or choose one of: $clientNames"; } } elsif ($setName eq 'unblockClient') { - if ($setVal && $setVal ne 'all') { - $setVal = Unifi_ClientNames($hash,$setVal,'makeID'); - if (defined $hash->{clients}->{$setVal}) { - Unifi_UnblockClient_Send($hash,$setVal); - } - else { - return "$hash->{NAME}: Unknown client '$setVal' in command '$setName', choose one of: all,$clientNames"; - } + my $id = Unifi_ClientNames($hash,$setVal,'makeID'); + my $mac = "x"; + if (defined $hash->{clients}->{$id}) { + $mac = $hash->{clients}->{$id}->{mac}; + }elsif($setVal =~ m/^[a-fA-F0-9:]{17}$/g){ + $mac = $setVal; } - elsif (!$setVal || $setVal eq 'all') { - Unifi_UnblockClient_Send($hash,keys(%{$hash->{clients}})); + if($mac ne "x"){ + Unifi_UnblockClient_Send($hash,$mac); + }else { + return "$hash->{NAME}: Unknown client '$setVal' in command '$setName', use mac or choose one of: $clientNames"; } } elsif ($setName eq 'switchSiteLEDs') { @@ -314,6 +317,7 @@ sub Unifi_Set($@) { Unifi_UpdateClient_Send($hash,$setVal); } elsif ($setName eq 'poeMode') { + Log3 $name, 2, "$name: deprecated use of set poeMode. Use same feature in autocreated UnifiSwitch-Device."; return "usage: $setName " if( !$setVal3 ); my $apRef; for my $apID (keys %{$hash->{accespoints}}) { @@ -508,6 +512,7 @@ sub Unifi_Get($@) { ."poeState voucherList:all,$voucherNotes voucher:$voucherNotes showAccount"; } elsif ($getName eq 'poeState') { + Log3 $name, 2, "$name: deprecated use of get poeState. Use readings in autocreated UnifiSwitch-Device instead."; my $poeState; for my $apID (keys %{$hash->{accespoints}}) { my $apRef = $hash->{accespoints}->{$apID}; @@ -714,6 +719,19 @@ sub Unifi_Attr(@) { } return undef; } + +############################################################################### +sub Unifi_Write($$){ + my ( $hash, $type, $ap_id, $port_overrides) = @_; #TODO: ap_id und port_overrides in @a, damit es für andere $type auch geht. + + my ($name,$self) = ($hash->{NAME},Unifi_Whoami()); + Log3 $name, 1, "$name ($self) - executed with ".$type; + if($type eq "Unifi_RestJson_Send"){ + Unifi_RestJson_Send($hash, $ap_id, {port_overrides => $port_overrides }); + } + + return undef; +} ############################################################################### sub Unifi_DoUpdate($@) { @@ -1129,6 +1147,16 @@ sub Unifi_GetAccesspoints_Receive($) { for my $h (@{$data->{data}}) { $hash->{accespoints}->{$h->{_id}} = $h; + #TODO: Switch-Modelle anders festlegen ? Oder passt usw? + if (defined $h->{model} && $h->{type} eq "usw"){ + my $usw_name=""; + if (defined $h->{name}){ + $usw_name=makeDeviceName($h->{name}); + }else{ + $usw_name=makeDeviceName($h->{ip}); + } + Dispatch($hash,"UnifiSwitch_".$usw_name.encode_json($h),undef); + } } } else { Unifi_ReceiveFailure($hash,$data->{meta}); } @@ -1180,10 +1208,15 @@ sub Unifi_SetClientReadings($) { my $ignoreWireless = AttrVal($name,"ignoreWirelessClients",undef); my ($apName,$clientName,$clientRef); + my $sep=""; + my $newClients=""; for my $clientID (keys %{$hash->{clients}}) { $clientRef = $hash->{clients}->{$clientID}; $clientName = Unifi_ClientNames($hash,$clientID,'makeAlias'); - + if (! defined ReadingsVal($hash->{NAME},$clientName,undef)){ + $newClients.=$sep.$clientName; + $sep=","; + } next if( $ignoreWired && $clientRef->{is_wired} ); next if( $ignoreWireless && !$clientRef->{is_wired} ); @@ -1209,6 +1242,7 @@ sub Unifi_SetClientReadings($) { readingsBulkUpdate($hash,$clientName,'disconnected'); } } + readingsBulkUpdate($hash,"UC_newClients",$newClients); return undef; } @@ -1431,17 +1465,15 @@ sub Unifi_UpdateClient_Receive($) { return undef; } ############################################################################### -sub Unifi_BlockClient_Send($@) { - my ($hash,@clients) = @_; +sub Unifi_BlockClient_Send($$) { + my ($hash,$mac) = @_; my ($name,$self) = ($hash->{NAME},Unifi_Whoami()); - Log3 $name, 5, "$name ($self) - executed with count:'".scalar(@clients)."', ID:'".$clients[0]."'"; - my $id = shift @clients; + Log3 $name, 5, "$name ($self) - executed with mac: '".$mac."'"; HttpUtils_NonblockingGet( { %{$hash->{httpParams}}, url => $hash->{unifi}->{url}."cmd/stamgr", callback => \&Unifi_BlockClient_Receive, - clients => [@clients], - data => "{'mac': '".$hash->{clients}->{$id}->{mac}."', 'cmd': 'block-sta'}", + data => "{'mac': '".$mac."', 'cmd': 'block-sta'}", } ); return undef; @@ -1469,26 +1501,19 @@ sub Unifi_BlockClient_Receive($) { } } - if (scalar @{$param->{clients}}) { - Unifi_BlockClient_Send($hash,@{$param->{clients}}); - } - return undef; } ############################################################################### -sub Unifi_UnblockClient_Send($@) { - my ($hash,@clients) = @_; +sub Unifi_UnblockClient_Send($$) { + my ($hash,$mac) = @_; my ($name,$self) = ($hash->{NAME},Unifi_Whoami()); - Log3 $name, 5, "$name ($self) - executed with count:'".scalar(@clients)."', ID:'".$clients[0]."'"; - - my $id = shift @clients; + Log3 $name, 5, "$name ($self) - executed with mac: '".$mac."'"; HttpUtils_NonblockingGet( { %{$hash->{httpParams}}, url => $hash->{unifi}->{url}."cmd/stamgr", callback => \&Unifi_UnblockClient_Receive, - clients => [@clients], - data => "{'mac': '".$hash->{clients}->{$id}->{mac}."', 'cmd': 'unblock-sta'}", + data => "{'mac': '".$mac."', 'cmd': 'unblock-sta'}", } ); return undef; @@ -1515,10 +1540,6 @@ sub Unifi_UnblockClient_Receive($) { } } - if (scalar @{$param->{clients}}) { - Unifi_UnblockClient_Send($hash,@{$param->{clients}}); - } - return undef; } @@ -2232,20 +2253,28 @@ Or you can use the other readings or set and get features to control your unifi-
  • set <name> unsetLocateAP <all|_id|name|ip>
    Stop 'locate' on one or all accesspoints.
  • +
  • set <name> poeMode <name|mac|id> <port> <off|auto|passive|passthrough|restart>
    Set PoE mode for <port>.
  • +
  • set <name> blockClient <clientname>
    - Block the <clientname>
  • + Block the <clientname>. Can also be called with the mac-address of the client. +
  • set <name> unblockClient <clientname>
    - Unblocks the <clientname>
  • + Unblocks the <clientname>. Can also be called with the mac-address of the client. +
  • set <name> disableWLAN <ssid>
    Disables WLAN with <ssid>
  • +
  • set <name> enableWLAN <ssid>
    Enables WLAN with <ssid>
  • +
  • set <name> switchSiteLEDs <on|off>
    Enables or disables the Status-LED settings of the site.
  • +
  • set <name> createVoucher <expire> <n> <quota> <note>
    Creates <n> vouchers that expires after <expire> minutes, are usable <quota>-times with a <note>no spaces in note allowed
  • +
    @@ -2261,14 +2290,19 @@ Or you can use the other readings or set and get features to control your unifi-
  • get <name> unarchivedAlerts
    Show all unarchived Alerts.
  • +
  • get <name> poeState [name|mac|id]
    Show port PoE state.
  • +
  • get <name> voucher [note]
    Show next voucher-code with specified note. If <note> is used in voucherCache the voucher will be marked as delivered
  • +
  • get <name> voucherList [all|note]
    Show list of vouchers (all or with specified note only).
  • +
  • get <name> showAccount
    Show decrypted user and passwort.
  • +
    @@ -2329,6 +2363,7 @@ Or you can use the other readings or set and get features to control your unifi-
      Note: All readings generate events. You can control this with these global attributes.
    • Each client has 7 readings for connection-state, SNR, uptime, last_seen-time, connected-AP, essid and hostname.
    • +
    • UC_newClients shows nameof a new client, could be a comma-separated list. Will be set to empty at next interval.
    • Each AP has 3 readings for state (can be 'ok' or 'error'), essid's and count of connected-clients.
    • The unifi-controller has 6 readings for event-count in configured 'timePeriod', unarchived-alert count, accesspoint count, overall wlan-state (can be 'ok', 'warning', or other?), connected user count and connected guest count.
    • The Unifi-device reading 'state' represents the connection-state to the unifi-controller (can be 'connected', 'disconnected', 'initialized' and 'disabled').
    • diff --git a/fhem/FHEM/74_UnifiSwitch.pm b/fhem/FHEM/74_UnifiSwitch.pm new file mode 100755 index 000000000..7ecdb80a2 --- /dev/null +++ b/fhem/FHEM/74_UnifiSwitch.pm @@ -0,0 +1,334 @@ +############################################################################## +# $Id$ +# 74_UnifiSwitch.pm + +# CHANGED +############################################################################## +# V 0.1 +# - feature: 74_UnifiSwitch: initial version +# V 0.11 +# - feature: 74_UnifiSwitch: state des USW wird gesetzt +# Port-Nummern < 9 mit führender 0 +# Model als Internal +# port-state als reading hinzugefügt +# V 0.90 +# - feature: 74_UnififSwitch: setter for poe-Mode +# added commandref +# +# TODOs: +# - state des USW korrekt setzen (aktuell nur connected und provisioning) + +package main; +# Laden evtl. abhängiger Perl- bzw. FHEM-Module +use strict; +use warnings; +use POSIX; +use JSON qw(decode_json); + +### Forward declarations ####################################################{ +sub UnifiSwitch_Initialize($$); +sub UnifiSwitch_Define($$); +sub UnifiSwitch_Undef($$); +sub UnifiSwitch_Attr(@); +sub UnifiSwitch_Set($@); +sub UnifiSwitch_Get($@); +sub UnifiSwitch_Parse($$); +sub UnifiSwitch_Whoami(); +sub UnifiSwitch_Whowasi(); + +my $version="0.90"; + +sub UnifiSwitch_Initialize($$) { + my ($hash) = @_; + $hash->{DefFn} = "UnifiSwitch_Define"; + $hash->{UndefFn} = "UnifiSwitch_Undef"; + $hash->{ParseFn} = "UnifiSwitch_Parse"; + $hash->{AttrFn} = "UnifiSwitch_Attr"; + $hash->{SetFn} = "UnifiSwitch_Set"; + $hash->{GetFn} = "UnifiSwitch_Get"; + $hash->{AttrList} = $readingFnAttributes; + # TODO: notwendig? + $hash->{Match} = "^UnifiSwitch"; + # TODO ATTR wird nicht übernommen + $hash->{AutoCreate}={"UnifiSwitch.*" => { ATTR => "event-on-change-reading:.* event-min-interval:.*:300", + FILTER => "%NAME", + autocreateThreshold => "1:1"} }; +} + +sub UnifiSwitch_Define($$) { + my ( $hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + my $name = $a[0]; + Log3 $name, 3, "UnifiSwitch_Define - executed. 0 "; + # zweites Argument ist die eindeutige Geräteadresse + my $address = $a[2]; + + if(defined($modules{UnifiSwitch}{defptr}{$address})){ + return "Switch with name $address already defined in ".($modules{UnifiSwitch}{defptr}{$address}{NAME}); + } + $hash->{CODE}=$address; + $hash->{VERSION}=$version; + # Adresse rückwärts dem Hash zuordnen (für ParseFn) + $modules{UnifiSwitch}{defptr}{$address} = $hash; + + Log3 $name, 3, "UnifiSwitch_Define - Adress: ".$address; + AssignIoPort($hash); +} + +sub UnifiSwitch_Undef($$){ + my ($hash, $name) = @_; + Log3 $name, 3, "$name (UnifiSwitch_Undef) - executed.".$hash->{CODE}; + if(defined($hash->{CODE}) && defined($modules{UnifiSwitch}{defptr}{$hash->{CODE}})){ + delete($modules{UnifiSwitch}{defptr}{$hash->{CODE}}); + } + return undef; +} + +sub UnifiSwitch_Attr(@){ + my @a = @_; + + return undef; +} + + +sub UnifiSwitch_Set($@){ + my ($hash,@a) = @_; + my ($name,$setName,$setVal,$setVal2) = @a; + Log3 $name, 5, "$name: set called with $setName " . ($setVal ? $setVal : "")." ". ($setVal2 ? $setVal2 : "") if ($setName ne "?"); + + # TODO: ggf. auf disabled des Unifi-devices prüfen?! Wie bekomme ich den io_hash? + #if(Unifi_CONNECTED($hash) eq 'disabled' && $setName !~ /clear/) { + # return "Unknown argument $setName, choose one of clear:all,readings"; + # Log3 $name, 5, "$name: set called with $setName but device is disabled!" if($setName ne "?"); + # return undef; + #} + if($setName !~ /clear|poeMode/) { + return "Unknown argument $setName, choose one of " + ."clear:readings poeMode "; #TODO: PortNamen sowie die Modes als Auswahl anhängen + } else { + Log3 $name, 4, "$name: set $setName"; + if ($setName eq 'poeMode') { + return "usage: $setName " if( !$setVal ); + my $apRef; + my $ap = $hash->{usw}; + return "switch has no poe-ports!" if( !$ap->{port_table} ); + $apRef = $ap; + if( $setVal !~ m/\d+/ ) { + for my $port (@{$apRef->{port_table}}) { + next if( $port->{name} !~ $setVal ); + $setVal = $port->{port_idx}; + last; + } + } + return "port-ID musst be numeric" if( $setVal !~ m/\d+/ ); + return "port musst be in [1..". scalar @{$apRef->{port_table}} ."] " if( $setVal < 1 || $setVal > scalar @{$apRef->{port_table}} ); + return "switch '$apRef->{name}' has no port $setVal" if( !defined(@{$apRef->{port_table}}[$setVal-1] ) ); + return "port $setVal of switch '$apRef->{name}' is not poe capable" if( !@{$apRef->{port_table}}[$setVal-1]->{port_poe} ); + + my $port_overrides = $apRef->{port_overrides}; + my $idx; + my $i = 0; + for my $entry (@{$port_overrides}) { + if( $entry->{port_idx} eq $setVal ) { + $idx = $i; + last; + } + ++$i; + } + if( !defined($idx) ) { + push @{$port_overrides}, {port_idx => $setVal+0}; + $idx = scalar @{$port_overrides}; + } + + if( $setVal2 eq 'off' ) { + $port_overrides->[$idx]{poe_mode} = "off"; + IOWrite($hash, "Unifi_RestJson_Send", $apRef->{device_id}, $port_overrides); + + } elsif( $setVal2 eq 'auto' || $setVal2 eq 'poe+' ) { + #return "port $setVal not auto poe capable" if( @{$apRef->{port_table}}[$setVal-1]->{poe_caps} & 0x03 ) ; + $port_overrides->[$idx]{poe_mode} = "auto"; + IOWrite($hash, "Unifi_RestJson_Send", $apRef->{device_id}, $port_overrides ); + + } elsif( $setVal2 eq 'passive' ) { + #return "port $setVal not passive poe capable" if( @{$apRef->{port_table}}[$setVal-1]->{poe_caps} & 0x04 ) ; + $port_overrides->[$idx]{poe_mode} = "pasv24"; + IOWrite($hash, "Unifi_RestJson_Send", $apRef->{device_id}, $port_overrides); + + } elsif( $setVal2 eq 'passthrough' ) { + #return "port $setVal not passthrough poe capable" if( @{$apRef->{port_table}}[$setVal-1]->{poe_caps} & 0x08 ) ; + $port_overrides->[$idx]{poe_mode} = "passthrough"; + IOWrite($hash, "Unifi_RestJson_Send", $apRef->{device_id}, $port_overrides); + + } elsif( $setVal2 eq 'restart' ) {#TODO: Was wir hier gemacht? Funktioniert das noch? + IOWrite($hash, "Unifi_RestJson_Send", {cmd => 'power-cycle', mac => $apRef->{mac}, port_idx => $setVal+0}); + + } else { + return "unknwon poe mode $setVal2"; + } + }elsif ($setName eq 'clear') { + if ($setVal eq 'readings' || $setVal eq 'all') { + for (keys %{$hash->{READINGS}}) { + delete $hash->{READINGS}->{$_} if($_ ne 'state'); + } + } + } + } + return undef; +} + + +sub UnifiSwitch_Get($@){ + my @a = @_; + + return undef; +} + +sub UnifiSwitch_Parse($$) { + my ($io_hash, $message) = @_; + my ($name,$self) = ($io_hash->{NAME},UnifiSwitch_Whoami()); + my $i1=index($message,"_")+1; + my $i2=index($message,"{")-$i1; + my $address = substr($message, $i1, $i2); + Log3 $name, 5, "$name ($self) - executed. UnifiSwitch: Adress: ".$address; + my $message_json=substr($message,$i1+$i2); + Log3 $name, 5, "$name ($self) - executed. UnifiSwitch: message_json: ".$message_json; + + # wenn bereits eine Gerätedefinition existiert (via Definition Pointer aus Define-Funktion) + if(my $hash = $modules{UnifiSwitch}{defptr}{$address}){ + # Nachricht für $hash verarbeiten + my $apRef = decode_json($message_json); + $hash->{usw} = $apRef; + if( $apRef->{type} eq 'usw' ){ + if ($apRef->{state} eq "1"){ + $hash->{STATE} = "connected"; + }elsif($apRef->{state} eq "5"){ + $hash->{STATE} = "provisioning"; + }else{ + $hash->{STATE} = "unknown: ".$apRef->{state}; # TODO: Weitere states setzen wenn state-id bekannt + } + $hash->{MODEL}=$apRef->{model}; + readingsBeginUpdate($hash); + if( $apRef->{port_table} ){ + for my $port (@{$apRef->{port_table}}) { + my $port_id=$port->{port_idx} > 9 ? "port_".$port->{port_idx} : "port_0".$port->{port_idx}; + readingsBulkUpdate($hash,$port_id."_name",$port->{name}); + if(defined $port->{speed} && looks_like_number($port->{speed})){ + readingsBulkUpdate($hash,$port_id."_state",$port->{speed} > 0 ? $port->{speed}." Mbps" : "disconnected"); + }else{ + readingsBulkUpdate($hash,$port_id."_state","unknown"); + } + if( $port->{port_poe} ){ + readingsBulkUpdate($hash,$port_id."_poe_mode",$port->{poe_mode}); + readingsBulkUpdate($hash,$port_id."_poe_power",$port->{poe_power}); + readingsBulkUpdate($hash,$port_id."_poe_voltage",$port->{poe_voltage}); + readingsBulkUpdate($hash,$port_id."_poe_current",$port->{poe_current}); + } + } + } + readingsEndUpdate($hash,1); + } + Log3 $name, 5, "$name ($self) - return: ".$hash->{NAME}; + return $hash->{NAME}; # Rückgabe des Gerätenamens, für welches die Nachricht bestimmt ist. + } + else{ + # Keine Gerätedefinition verfügbar + # Daher Vorschlag define-Befehl: + Log3 $name, 3, "$name ($self) - return: UNDEFINED UnifiSwitch_".$address." UnifiSwitch $address"; + return "UNDEFINED ".$address." UnifiSwitch $address"; + } +} + +############################################################################### + +sub UnifiSwitch_Whoami() { return (split('::',(caller(1))[3]))[1] || ''; } +sub UnifiSwitch_Whowasi() { return (split('::',(caller(2))[3]))[1] || ''; } + +# Eval-Rückgabewert für erfolgreiches +# Laden des Moduls +1; + + +# Beginn der Commandref + +=pod +=item device +=item summary Show info and control UnifiSwitch (USW) (Unifi-Device required) +=item summary_DE Zeigt Infos zum UnifiSwitch (USW) an und steuert diesen. + +=begin html + + +

      UnifiSwitch

      +
        + +UnifiSwitch is the FHEM module for the Ubiquiti Networks (UBNT) Switch - USW.
        +
        +You can use the readings or set features to control your unifi-switch. +
        +

        Prerequisites

        +
          +
        • + A connected Unifi-Device as IODev. +
        • +
        • + The Perl module JSON is required.
          + On Debian/Raspbian: apt-get install libjson-perl
          + Via CPAN: cpan install JSON +
        • +
        + +

        Define

        +
          + define <name> UnifiSwitch <ip> <nameOfSwitch> +
          Normaly this device will be autocreated!
          +
          + <name>: +
            + The FHEM device name for the device.
            +
          + <nameOfSwitch>: +
            + The name of the switch in unifi-controller.
            +
          +
        + +

        Set

        +
          +
        • set <name> clear <readings|all>
          + Clears the readings or all.
        • +
          +
        • set <name> poeMode <name|mac|id> <port> <off|auto|passive|passthrough|restart>
          + Set PoE mode for <port>.
        • +
        + +

        Readings

        +
          + Note: All readings generate events. You can control this with these global attributes. +
        • Each port has the readings name and state. POE-ports have more readings.
        • +
        • name +
            The name of the port as defined in UnifiController.
          +
        • +
        • state +
            The connection state of the port. Can be disconnected or in Mbps/Gbps.
          +
        • +
        • poe_current +
            The current power-usage.
          +
        • +
        • poe_mode +
            The poe-mode of the port.
          +
        • +
        • poe_power +
            The power of the port.
          +
        • +
        • poe_voltage +
            The voltage of the port.
          +
        • +
        +
        + +
      + +=end html + +# Ende der Commandref +=cut \ No newline at end of file diff --git a/fhem/MAINTAINER.txt b/fhem/MAINTAINER.txt index 6104daf9d..1de3d7598 100644 --- a/fhem/MAINTAINER.txt +++ b/fhem/MAINTAINER.txt @@ -347,6 +347,7 @@ FHEM/74_Nmap.pm igami Unterstuetzende Dienste FHEM/74_XiaomiBTLESens CoolTux Sonstige Systeme FHEM/74_THINKINGCLEANER.pm loredo Unterstuetzende Dienste FHEM/74_Unifi.pm rapster/Wuehler Automatisierung +FHEM/74_UnifiSwitch.pm Wuehler Automatisierung FHEM/74_UnifiVideo.pm justme1968 Sonstiges FHEM/75_MSG.pm loredo Automatisierung FHEM/75_msgConfig.pm loredo Automatisierung