2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-26 04:24:53 +00:00

74_Unifi.pm: added get poeMode and set poeState commands, _utilization and _poePower readings

git-svn-id: https://svn.fhem.de/fhem/trunk@14391 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
justme-1968 2017-05-27 20:20:30 +00:00
parent 799e2db8c3
commit 56517958e9
2 changed files with 145 additions and 7 deletions

@ -1,5 +1,7 @@
# 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_Unifi.pm: added get poeMode and set poeState commands
added _utilization and _poePower readings
- feature: 93_DbRep: v4.16.1, json as option of sqlResultFormat
- feature: 31_PLAYBULB: add support for ssh remote control
- change: 42_Nextion: fault tolerance in reader / fixes

@ -143,7 +143,7 @@ sub Unifi_Notify($$) {
sub Unifi_Set($@) {
my ($hash,@a) = @_;
return "\"set $hash->{NAME}\" needs at least an argument" if ( @a < 2 );
my ($name,$setName,$setVal) = @a;
my ($name,$setName,$setVal,$setVal2,$setVal3) = @a;
Log3 $name, 5, "$name: set called with $setName " . ($setVal ? $setVal : "") if ($setName ne "?");
@ -156,12 +156,13 @@ sub Unifi_Set($@) {
my $clientNames = Unifi_ClientNames($hash);
my $apNames = Unifi_ApNames($hash);
if($setName !~ /archiveAlerts|restartAP|setLocateAP|unsetLocateAP|disconnectClient|update|clear/) {
if($setName !~ /archiveAlerts|restartAP|setLocateAP|unsetLocateAP|disconnectClient|update|clear|poeMode/) {
return "Unknown argument $setName, choose one of update:noArg "
." clear:all,readings,clientData "
."clear:all,readings,clientData "
.((defined $hash->{alerts_unarchived}[0] && scalar @{$hash->{alerts_unarchived}}) ? "archiveAlerts:noArg " : "")
.(($apNames && Unifi_CONNECTED($hash)) ? "restartAP:all,$apNames setLocateAP:all,$apNames unsetLocateAP:all,$apNames " : "")
.(($clientNames && Unifi_CONNECTED($hash)) ? "disconnectClient:all,$clientNames" : "");
.(($clientNames && Unifi_CONNECTED($hash)) ? "disconnectClient:all,$clientNames " : "")
."poeMode";
}
else {
Log3 $name, 4, "$name: set $setName";
@ -181,6 +182,72 @@ sub Unifi_Set($@) {
Unifi_DisconnectClient_Send($hash,keys(%{$hash->{clients}}));
}
}
elsif ($setName eq 'poeMode') {
return "usage: $setName <name|mac|id> <port> <off|auto|passive|passthrough|restart>" if( !$setVal3 );
my $apRef;
for my $apID (keys %{$hash->{accespoints}}) {
my $ap = $hash->{accespoints}->{$apID};
next if( !$ap->{port_table} );
next if( $ap->{type} ne 'usw' );
next if( $setVal ne $ap->{mac} && $setVal ne $ap->{device_id} && $ap->{name} !~ $setVal );
return "multiple switches found for $setVal" if( $apRef );
$apRef = $ap;
}
return "no switch $setVal found" if( !$apRef );
if( $setVal2 !~ m/\d+/ ) {
for my $port (@{$apRef->{port_table}}) {
next if( $port->{name} !~ $setVal2 );
$setVal2 = $port->{port_idx};
last;
}
}
return "port musst be numeric" if( $setVal2 !~ m/\d+/ );
return "port musst be in [1..". scalar @{$apRef->{port_table}} ."] " if( $setVal2 < 1 || $setVal2 > scalar @{$apRef->{port_table}} );
return "switch '$apRef->{name}' has no port $setVal2" if( !defined(@{$apRef->{port_table}}[$setVal2-1] ) );
return "port $setVal2 of switch '$apRef->{name}' is not poe capable" if( !@{$apRef->{port_table}}[$setVal2-1]->{port_poe} );
my $port_overrides = $apRef->{port_overrides};
my $idx;
my $i = 0;
for my $entry (@{$port_overrides}) {
if( $entry->{port_idx} eq $setVal2 ) {
$idx = $i;
last;
}
++$i;
}
if( !defined($idx) ) {
push @{$port_overrides}, {port_idx => $setVal2+0};
$idx = scalar @{$port_overrides};
}
if( $setVal3 eq 'off' ) {
$port_overrides->[$idx]{poe_mode} = "off";
Unifi_RestJson_Send($hash, $apRef->{device_id}, {port_overrides => $port_overrides });
} elsif( $setVal3 eq 'auto' || $setVal3 eq 'poe+' ) {
#return "port $setVal2 not auto poe capable" if( @{$apRef->{port_table}}[$setVal2-1]->{poe_caps} & 0x03 ) ;
$port_overrides->[$idx]{poe_mode} = "auto";
Unifi_RestJson_Send($hash, $apRef->{device_id}, {port_overrides => $port_overrides });
} elsif( $setVal3 eq 'passive' ) {
#return "port $setVal2 not passive poe capable" if( @{$apRef->{port_table}}[$setVal2-1]->{poe_caps} & 0x04 ) ;
$port_overrides->[$idx]{poe_mode} = "pasv24";
Unifi_RestJson_Send($hash, $apRef->{device_id}, {port_overrides => $port_overrides });
} elsif( $setVal3 eq 'passthrough' ) {
#return "port $setVal2 not passthrough poe capable" if( @{$apRef->{port_table}}[$setVal2-1]->{poe_caps} & 0x08 ) ;
$port_overrides->[$idx]{poe_mode} = "passthrough";
Unifi_RestJson_Send($hash, $apRef->{device_id}, {port_overrides => $port_overrides });
} elsif( $setVal3 eq 'restsart' ) {
Unifi_ApJson_Send($hash,{cmd => 'power-cycle', mac => $apRef->{mac}, port_idx => $setVal2+0});
} else {
return "unknwon poe mode $setVal3";
}
}
elsif ($setName eq 'archiveAlerts' && defined $hash->{alerts_unarchived}[0]) {
Unifi_ArchiveAlerts_Send($hash);
undef @{$hash->{alerts_unarchived}};
@ -254,11 +321,36 @@ sub Unifi_Get($@) {
my $clientNames = Unifi_ClientNames($hash);
if($getName !~ /events|clientData|unarchivedAlerts/) {
if($getName !~ /events|clientData|unarchivedAlerts|poeState/) {
return "Unknown argument $getName, choose one of "
.((defined $hash->{events}[0] && scalar @{$hash->{events}}) ? "events:noArg " : "")
.((defined $hash->{alerts_unarchived}[0] && scalar @{$hash->{alerts_unarchived}}) ? "unarchivedAlerts:noArg " : "")
.(($clientNames) ? "clientData:all,$clientNames" : "");
.(($clientNames) ? "clientData:all,$clientNames " : "")
."poeState";
}
elsif ($getName eq 'poeState') {
my $poeState;
for my $apID (keys %{$hash->{accespoints}}) {
my $apRef = $hash->{accespoints}->{$apID};
next if( $apRef->{type} ne 'usw' );
next if( !$apRef->{port_table} );
next if( $getVal && $getVal ne $apRef->{mac} && $getVal ne $apRef->{device_id} && $apRef->{name} !~ $getVal );
$poeState .= "\n" if( $poeState );
$poeState .= sprintf( "%-20s (mac:%-17s, id:%s)\n", $apRef->{name}, $apRef->{mac}, $apRef->{device_id} );
$poeState .= sprintf( " %2s %-15s", "id", "name" );
$poeState .= sprintf( " %s %s %-6s %-4s %-10s", "", "on", "mode", "", "class" );
$poeState .= "\n";
for my $port (@{$apRef->{port_table}}) {
#next if( !$port->{port_poe} );
$poeState .= sprintf( " %2i %-15s", $port->{port_idx}, $port->{name} );
$poeState .= sprintf( " %s %s %-6s %-4s %-10s", $port->{poe_caps}, $port->{poe_enable}, $port->{poe_mode}, defined($port->{poe_good})?($port->{poe_good}?"good":""):"", defined($port->{poe_class})?$port->{poe_class}:"" ) if( $port->{port_poe} );
$poeState .= sprintf( " %5.2fW %5.2fV %5.2fmA", $port->{poe_power}?$port->{poe_power}:0, $port->{poe_voltage}, $port->{poe_current}?$port->{poe_current}:0 ) if( $port->{port_poe} );
$poeState .= "\n";
}
}
$poeState = "====================================================\n". $poeState;
$poeState .= "====================================================\n";
return $poeState;
}
elsif ($getName eq 'unarchivedAlerts' && defined $hash->{alerts_unarchived}[0] && scalar @{$hash->{alerts_unarchived}}) {
my $alerts = "====================================================\n";
@ -883,8 +975,19 @@ sub Unifi_SetAccesspointReadings($) {
readingsBulkUpdate($hash,'-AP_'.$apName.'_state',($apRef->{state} == 1) ? 'ok' : 'error');
readingsBulkUpdate($hash,'-AP_'.$apName.'_clients',$apRef->{'num_sta'});
readingsBulkUpdate($hash,'-AP_'.$apName.'_essid',$essid);
if( $apRef->{type} eq 'uap' ) {
readingsBulkUpdate($hash,'-AP_'.$apName.'_essid',$essid);
readingsBulkUpdate($hash,'-AP_'.$apName.'_utilizationNA',$apRef->{'na_cu_total'}) if( defined($apRef->{'na_cu_total'}) );
readingsBulkUpdate($hash,'-AP_'.$apName.'_utilizationNG',$apRef->{'ng_cu_total'}) if( defined($apRef->{'ng_cu_total'}) );
}
readingsBulkUpdate($hash,'-AP_'.$apName.'_locate',(!defined $apRef->{locating}) ? 'unknown' : ($apRef->{locating}) ? 'on' : 'off');
my $poe_power;
for my $port (@{$apRef->{port_table}}) {
next if( !$port->{port_poe} );
$poe_power += $port->{poe_power} if( defined($port->{poe_power}) );
}
readingsBulkUpdate($hash,'-AP_'.$apName.'_poePower', $poe_power) if( defined($poe_power) );
# readingsBulkUpdate($hash,'-AP_'.$apName.'_guests',$apRef->{'guest-num_sta'});
# readingsBulkUpdate($hash,'-AP_'.$apName.'_users',$apRef->{'user-num_sta'});
# readingsBulkUpdate($hash,'-AP_'.$apName.'_last_seen',$apRef->{'last_seen'});
@ -956,6 +1059,35 @@ sub Unifi_ApCmd_Send($$@) { #cmd: 'set-locate', 'unset-locate', 'restart'
} );
return undef;
}
sub Unifi_ApJson_Send($$) {
my ($hash,$data) = @_;
my ($name,$self) = ($hash->{NAME},Unifi_Whoami());
my $json = encode_json( $data );
Log3 $name, 5, "$name ($self) - executed with $json.";
HttpUtils_NonblockingGet( {
%{$hash->{httpParams}},
url => $hash->{unifi}->{url}."cmd/devmgr",
callback => \&Unifi_ApCmd_Receive,
aps => [],
data => $json,
} );
return undef;
}
sub Unifi_RestJson_Send($$$) {
my ($hash,$id,$data) = @_;
my ($name,$self) = ($hash->{NAME},Unifi_Whoami());
my $json = encode_json( $data );
Log3 $name, 5, "$name ($self) - executed with $json.";
HttpUtils_NonblockingGet( {
%{$hash->{httpParams}},
method => "PUT",
url => $hash->{unifi}->{url}."rest/device/".$id,
callback => \&Unifi_ApCmd_Receive,
aps => [],
data => $json,
} );
return undef;
}
###############################################################################
sub Unifi_ApCmd_Receive($) {
my ($param, $err, $data) = @_;
@ -1293,6 +1425,8 @@ Or you can use the other readings or set and get features to control your unifi-
<br>
<li><code>set &lt;name&gt; unsetLocateAP &lt;all|_id|name|ip&gt;</code><br>
Stop 'locate' on one or all accesspoints. </li>
<li><code>set &lt;name&gt; poeMode &lt;name|mac|id&gt; &lt;port&gt; &lt;off|auto|passive|passthrough|restart&gt;</code><br>
Set PoE mode for &lt;port&gt;. </li>
</ul>
@ -1308,6 +1442,8 @@ Or you can use the other readings or set and get features to control your unifi-
<br>
<li><code>get &lt;name&gt; unarchivedAlerts</code><br>
Show all unarchived Alerts.</li>
<li><code>get &lt;name&gt; poeState [name|mac|id]</code><br>
Show port PoE state.</li>
</ul>