mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-26 10:34:52 +00:00
74_Unifi.pm:new Submodule 74_UnifiSwitch
git-svn-id: https://svn.fhem.de/fhem/trunk@16845 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
24525b51c2
commit
f6d9cc5639
@ -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,
|
||||
|
@ -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 <name|mac|id> <port> <off|auto|passive|passthrough|restart>" 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-
|
||||
<br>
|
||||
<li><code>set <name> unsetLocateAP <all|_id|name|ip></code><br>
|
||||
Stop 'locate' on one or all accesspoints. </li>
|
||||
<br>
|
||||
<li><code>set <name> poeMode <name|mac|id> <port> <off|auto|passive|passthrough|restart></code><br>
|
||||
Set PoE mode for <port>. </li>
|
||||
<br>
|
||||
<li><code>set <name> blockClient <clientname></code><br>
|
||||
Block the <clientname></li>
|
||||
Block the <clientname>. Can also be called with the mac-address of the client.</li>
|
||||
<br>
|
||||
<li><code>set <name> unblockClient <clientname></code><br>
|
||||
Unblocks the <clientname></li>
|
||||
Unblocks the <clientname>. Can also be called with the mac-address of the client.</li>
|
||||
<br>
|
||||
<li><code>set <name> disableWLAN <ssid></code><br>
|
||||
Disables WLAN with <ssid></li>
|
||||
<br>
|
||||
<li><code>set <name> enableWLAN <ssid></code><br>
|
||||
Enables WLAN with <ssid></li>
|
||||
<br>
|
||||
<li><code>set <name> switchSiteLEDs <on|off></code><br>
|
||||
Enables or disables the Status-LED settings of the site.</li>
|
||||
<br>
|
||||
<li><code>set <name> createVoucher <expire> <n> <quota> <note></code><br>
|
||||
Creates <n> vouchers that expires after <expire> minutes, are usable <quota>-times with a <note>no spaces in note allowed</li>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
|
||||
@ -2261,14 +2290,19 @@ Or you can use the other readings or set and get features to control your unifi-
|
||||
<br>
|
||||
<li><code>get <name> unarchivedAlerts</code><br>
|
||||
Show all unarchived Alerts.</li>
|
||||
<br>
|
||||
<li><code>get <name> poeState [name|mac|id]</code><br>
|
||||
Show port PoE state.</li>
|
||||
<br>
|
||||
<li><code>get <name> voucher [note]</code><br>
|
||||
Show next voucher-code with specified note. If <note> is used in voucherCache the voucher will be marked as delivered</li>
|
||||
<br>
|
||||
<li><code>get <name> voucherList [all|note]</code><br>
|
||||
Show list of vouchers (all or with specified note only).</li>
|
||||
<br>
|
||||
<li><code>get <name> showAccount</code><br>
|
||||
Show decrypted user and passwort.</li>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
|
||||
@ -2329,6 +2363,7 @@ Or you can use the other readings or set and get features to control your unifi-
|
||||
<ul>
|
||||
Note: All readings generate events. You can control this with <a href="#readingFnAttributes">these global attributes</a>.
|
||||
<li>Each client has 7 readings for connection-state, SNR, uptime, last_seen-time, connected-AP, essid and hostname.</li>
|
||||
<li><code>UC_newClients</code> shows nameof a new client, could be a comma-separated list. Will be set to empty at next interval.</li>
|
||||
<li>Each AP has 3 readings for state (can be 'ok' or 'error'), essid's and count of connected-clients.</li>
|
||||
<li>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. </li>
|
||||
<li>The Unifi-device reading 'state' represents the connection-state to the unifi-controller (can be 'connected', 'disconnected', 'initialized' and 'disabled').</li>
|
||||
|
334
fhem/FHEM/74_UnifiSwitch.pm
Executable file
334
fhem/FHEM/74_UnifiSwitch.pm
Executable file
@ -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 <port> <off|auto|passive|passthrough|restart>" 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: <NAME> <MODULNAME> <ADDRESSE>
|
||||
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
|
||||
|
||||
<a name="UnifiSwitch"></a>
|
||||
<h3>UnifiSwitch</h3>
|
||||
<ul>
|
||||
|
||||
UnifiSwitch is the FHEM module for the Ubiquiti Networks (UBNT) Switch - USW.<br>
|
||||
<br>
|
||||
You can use the readings or set features to control your unifi-switch.
|
||||
<br>
|
||||
<h4>Prerequisites</h4>
|
||||
<ul>
|
||||
<li>
|
||||
A connected Unifi-Device as IODev.
|
||||
</li>
|
||||
<li>
|
||||
The Perl module JSON is required. <br>
|
||||
On Debian/Raspbian: <code>apt-get install libjson-perl </code><br>
|
||||
Via CPAN: <code>cpan install JSON</code>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Define</h4>
|
||||
<ul>
|
||||
<code>define <name> UnifiSwitch <ip> <nameOfSwitch></code>
|
||||
<br>Normaly this device will be autocreated!<br>
|
||||
<br>
|
||||
<name>:
|
||||
<ul>
|
||||
<code>The FHEM device name for the device.</code><br>
|
||||
</ul>
|
||||
<nameOfSwitch>:
|
||||
<ul>
|
||||
<code>The name of the switch in unifi-controller.</code><br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h4>Set</h4>
|
||||
<ul>
|
||||
<li><code>set <name> clear <readings|all></code><br>
|
||||
Clears the readings or all. </li>
|
||||
<br>
|
||||
<li><code>set <name> poeMode <name|mac|id> <port> <off|auto|passive|passthrough|restart></code><br>
|
||||
Set PoE mode for <port>. </li>
|
||||
</ul>
|
||||
|
||||
<h4>Readings</h4>
|
||||
<ul>
|
||||
Note: All readings generate events. You can control this with <a href="#readingFnAttributes">these global attributes</a>.
|
||||
<li>Each port has the readings name and state. POE-ports have more readings.</li>
|
||||
<li>name
|
||||
<ul>The name of the port as defined in UnifiController.</ul>
|
||||
</li>
|
||||
<li>state
|
||||
<ul>The connection state of the port. Can be disconnected or in Mbps/Gbps.</ul>
|
||||
</li>
|
||||
<li>poe_current
|
||||
<ul>The current power-usage.</ul>
|
||||
</li>
|
||||
<li>poe_mode
|
||||
<ul>The poe-mode of the port.</ul>
|
||||
</li>
|
||||
<li>poe_power
|
||||
<ul>The power of the port.</ul>
|
||||
</li>
|
||||
<li>poe_voltage
|
||||
<ul>The voltage of the port.</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
|
||||
# Ende der Commandref
|
||||
=cut
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user