Ubiquiti - Unifi AP ClientListe

Moin,

ich habe mir für meine Unifi Accesspoints von Ubiquiti ein Skript gemacht, womit man sich ein paar Informationen über die angemeldeten Clients auslesen kann.
Vielleicht hat ja der ein oder andere von euch auch diese Geräte und kann mit diesem Skript etwas anfangen.

Anleitung im Skript


<?
// V1.00	07.01.2015 - Erstes Release

// Mit diesem Skript können die Daten der an den Unifi APs angemeldeten Clients
// abgerufen werden.
//
//  © by Kevin Heidrich 2015
//			kevinheidrich@me.com
//  Web: www.kh-solutions.de
//
//Vorgehensweise:
//
// - String Variable für die Ausgabe im Webfront anlegen und ID in der Config unten eintragen

$htmlBoxID = 12345 /*[Network\Ubiquiti\WLAN\Content]*/;

// Optional können noch die nächsten Tabellen gepflegt werden.
//
// Eine Lockup Tabelle für nicht ermittelbare Gerätenamen pflegen
// Über den Parameter "PresentVarID" wird eine bool Variable mit dem aktuellen
// Verfügbarkeitsstatus befüllt. Evtl. sinnvoll für Anwesenheitserkennung über das
// Handy.

$macList = array(
			array("Name" => "Belkin HomeServer", "MAC" => "de:ad:be:ef:fe:ed"),
			array("Name" => "iMac", "MAC" => "de:ad:be:ef:fe:ed"),
			array("Name" => "Handy Kevin", "MAC" => "de:ad:be:ef:fe:ed", "PresentVarID" => 20082)
			);

// Eine weitere Lockup Tabelle für die Accesspoints und deren Alias.
$apList = array(
			array("Name" => "Dachboden", "MAC" => "de:ad:be:ef:fe:ed"),
			array("Name" => "Flur unten", "MAC" => "de:ad:be:ef:fe:ed"),
			array("Name" => "Garten", "MAC" => "de:ad:be:ef:fe:ed"),
			);


// ----------------------------------------------------------------------------------
// Ab hier dann bitte nichts mehr ändern
// ----------------------------------------------------------------------------------
include "unifi.php";

$clientList = Unifi_GetClients();

$scriptResult = "";

foreach($clientList->data as $client)
{

	$scriptResult .= "<tr style='height:20px;font-size:12px;'>";
	
	// Name über MACNummer rausfinden.
	// Nicht alle Geräte senden anständig ihren Namen mit. Deswegen über Liste arbeiten
	$clientName = "";
	foreach($macList as $key => $entry)
	   if ($entry["MAC"] == $client->mac)
		{
			$clientName = $entry["Name"];
			break;
		}

	// War nicht in Liste!
	if ($clientName == "")
			$clientName = $client->hostname;

	$scriptResult .= "<td>".$clientName."</td>";

	$scriptResult .= "<td style='text-align:center'>".$client->mac."</td>";
	$scriptResult .= "<td style='text-align:center'>".$client->ip."</td>";
	
	// Accesspoints übersetzen
	$apName = "";
	
	foreach($apList as $ap)
	   if ($ap["MAC"] == $client->ap_mac)
	   {
			$apName = $ap["Name"];
			break;
		}

	// War nicht in Liste!
	if ($apName == "")
		$apName = $client->ap_mac;

	$scriptResult .= "<td style='text-align:center'>$apName</td>";
	$scriptResult .= "<td style='text-align:center'>".$client->essid."</td>";
	$scriptResult .= "<td style='text-align:center'><div style='width:100%;height:20px;overflow:hidden;'>";
	
	// Pegelumwandlung - Entspricht leider nicht dem Wert in der Webconsole. Kein Plan wie die das berechnen
	/* 100% -35 / 50% -65 / 1% -95 */
	if ($client->signal <= -95)
		$percent = 1;
	else if ($client->signal >= -35)
	   $percent = 100;
	else
		$percent = round(($client->signal + 95) / 0.6);

	if ($percent < 10)
		$levelImg = "0";
	else if ($percent <= 20)
		$levelImg = "1";
	else if ($percent <= 40)
		$levelImg = "2";
	else if ($percent <= 60)
		$levelImg = "3";
	else if ($percent <= 80)
		$levelImg = "4";
	else
		$levelImg = "5";

	$scriptResult .= "<img src='user/img/level/level$levelImg.png'> $percent% (Ch.".$client->channel.") ";

	if ($client->is_11a)
		$scriptResult .= "a";
	else if ($client->is_11ac)
		$scriptResult .= "ac";
	else if ($client->is_11b)
		$scriptResult .= "b";
	else if ($client->is_11n)
		$scriptResult .= "n";
	else
		$scriptResult .= "g";

	$scriptResult .= "</div></tr>";
	
}

// ------------------------------------------------
// Anwesenheitserkennung (Testinstallation)
// ------------------------------------------------
foreach($macList as $key => $entry)
{
      $macList[$key]["Present"] = false;
}

foreach($clientList->data as $client)
{

	// Name über MACNummer rausfinden.
	// Nicht alle Geräte senden anständig ihren Namen mit. Deswegen über Liste arbeiten
	$found = false;
	foreach($macList as $key => $entry)
	{
	   if ($entry["MAC"] == $client->mac)
	      $macList[$key]["Present"] = true;
	}
}

foreach($macList as $key => $entry)
{
	// Nur einen Wert setzen, wenn auch ein Target vorhanden ist
	if (isset($entry["PresentVarID"]))
		SetValue($entry["PresentVarID"],$entry["Present"]);
}

// ------------------------------------------------
// ------------------------------------------------

$htmlBox = "";
$htmlBox .= "<table style='width:100%;font-size:14px;'>";
$htmlBox .= "<tr><td style='text-align:left;font-size:12px;' colspan='10'>Letzte Aktualisierung: ".date("H:i:s d.m.Y")."</td></tr>";
$htmlBox .= "<tr style='height:1px;'><td style='background-color:#aaaaaa;' colspan='10'></td></tr>";

if ($scriptResult == "")
	$htmlBox .= "<tr><td style=''>Keine Clients im WLAN</td></tr>";
else
{
   $htmlBox .= "<tr><th>Name</th><th>MAC</th><th>IP</th><th>AP</th><th>WLAN</th><th>Pegel</th></tr>";
	$htmlBox .= $scriptResult;
}

SetValue($htmlBoxID,$htmlBox);

?>

Dann gibt es noch eine Funktionslib, die ich angefangen habe. (Siehe Anhang) Da könnte ich demnächst noch ein paar andere nette Features wie „AuthorizeDevice“ über Mac Adresse, Blockieren von Devices, Abfrage und erstellen von Vouchers.
In der Lib musst Du dann noch Login+Pass+IP der Unifi Software eintragen. Das ganze dann entsprechend in …/IP-Symcon/scripts/unifi.php kopieren.

Dazu gibt es dann noch ein paar Grafiken für die Signalstärke. (Selbstgemacht - Also gerne benutzen)
Diese bitte in …/IP-Symcon/webfront/user/img/verkehr/… kopieren.

Wenn Interesse besteht, mach ich da mal weiter. Derzeit habe ich nur das eingebaut, was ich derzeit dringend brauche.

Freu mich über Kommentare

Gruß
Kevin

unifi.php.zip (1.26 KB)

level.zip (15.5 KB)

Super hab ich auf jeden Fall Interesse.
Habe letztens das 3er Pack mit den Long range AP’s gekauft, 2 müssen noch montiert werden…

Gesendet von meinem Amazon Tate mit Tapatalk 4

Prima Sache das. Auch Anwesenheiten sind abgedeckt.

Wie geil ist das denn … Super - kopiert, eingerichtet und funktioniert!

DANKE!

super Skript

habe noch eine Frage
wenn sich ein Teilnehmer anmeldet den ich nicht in der Liste habe wird der dann auch angezeigt
oder anders wenn sich einer einloggt der nicht in der Liste Vorkommt ne warn Bool ansteuern ist das denkbar

ich frage weil wenn wer das Wlan Password kennt aber nicht (mehr) berechtigt ist kann man warnen
oder wenn man ein Gastnetz hat könnte man schauen ob sich einer einloggt (und dann nach Möglichkeit wer)

gruss Roman

@rkoster
Bitte überprüfe mal Deine Tastatur, da scheint etwas mit den Satzzeichen nicht zu stimmen.

Grus,
Christoph

Kann nicht sein ich habe gar keine Satzzeichen

Gesendet von meinem Gedanken-Maschine Interface mit einem digital Technik Konverter

subtil, aber die Message kommt an: er will gar keine Hilfe!

:smiley:

Was?
Habe ich die Antwort falsch verstanden?
Verstand die Antwort als Spitze Reaktion auf mein Schreibstil und nicht als Antwort auf meine Frage
Und so spitzig kommentierte ich zurück
Sollte weder böse noch undankbar (für hilfreiche Antworten) rüberkommen

Gesendet von meinem Gedanken-Maschine Interface mit einem digital Technik Konverter

Ja nö… zurück vom Ausflug in die Rechtschreibprüfung.

wenn sich ein Teilnehmer anmeldet den ich nicht in der Liste habe wird der dann auch angezeigt

Der wird angezeigt… aber evtl. als androidxyz oder sonstwas… siehe Screenshot oben.

oder anders wenn sich einer einloggt der nicht in der Liste Vorkommt ne warn Bool ansteuern ist das denkbar

Alsooo… da kann man sicher etwas einbauen. ABER, das was du beschreibst kann das Unifi Dings doch schon von sich aus. Dafür benutze ich die Vouchers. Passwörter die jeweils nur 1 Tag gültig sind. Ich hab mir n Haufen ausgedruckt, und hier hin gelegt. Kann man sich bedienen!

Wenn ich das Skript noch n bisl erweitere kann man diese vllt. auch Webfront anzeigen.

PS: Ey Schnecke, nur weil ich an deinen Skripten rummecker, musst du mich doch nicht gleich aus deiner Liste werfen. :smiley:

Danke für die Information
Das mit den vouchers muss ich noch mal nachlesen
Aber thx

Gesendet von meinem Gedanken-Maschine Interface mit einem digital Technik Konverter

Vielen Dank fürs Teilen, coole Sache! Da das ganze auch schon eine Weile auf meiner ToDo Liste stand, musste ich natürlich auch grad testen.
Dabei ist mir aufgefallen, dass die API im aktuellen 4er Zweig der UniFi Software etwas angepasst wurde (getestet mit 4.2.0).

Es braucht dafür in der Funktionslib unifi.php folgende Anpassung:

    # authenticate against unifi controller
    #curl_setopt($ch, CURLOPT_URL, "$baseurl/login");
    curl_setopt($ch, CURLOPT_URL, "$baseurl/api/login");
    curl_setopt($ch, CURLOPT_POST, 1);
    #curl_setopt($ch, CURLOPT_POSTFIELDS, "login=login&username=$username&password=$password");
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array("username" => $username, "password" => $password)).":");

Die Abfrage des verwendeten Verbindungsstandards hat sich wohl auch geändert. Der Block

    if ($client->is_11a) 
        $scriptResult .= "a"; 
    else if ($client->is_11ac) 
        $scriptResult .= "ac"; 
    else if ($client->is_11b) 
        $scriptResult .= "b"; 
    else if ($client->is_11n) 
        $scriptResult .= "n"; 
    else 
        $scriptResult .= "g"; 

müsste gegen etwas wie

    if ($client->radio_proto == "a")
        $scriptResult .= "a";
    else if ($client->radio_proto == "ac")
        $scriptResult .= "ac";
    else if ($client->radio_proto == "b")
        $scriptResult .= "b";
    else if ($client->radio_proto == "ng")
        $scriptResult .= "n";
    else if ($client->radio_proto == "g")
        $scriptResult .= "g";

ersetzt werden. Achtung: in Ermangelung an geeigneter Hardware ist der letzte Block nur für „g“ und „n“ getestet…

Hallo meson,

bist Du sicher, dass es mit der 4.2 funktioniert?
Ich habe den Login Teil der unifi.php angepasst, aber leider bekomme ich diesen Fehler „api.err.LoginRequired“

So sieht der Inhalt von $clientList aus:
stdClass Object
(
[data] => Array
(
)

[meta] =&gt; stdClass Object
    (
        [msg] =&gt; api.err.LoginRequired
        [rc] =&gt; error
    )

)

Es braucht dafür in der Funktionslib unifi.php folgende Anpassung:

    # authenticate against unifi controller
    #curl_setopt($ch, CURLOPT_URL, "$baseurl/login");
    curl_setopt($ch, CURLOPT_URL, "$baseurl/api/login");
    curl_setopt($ch, CURLOPT_POST, 1);
    #curl_setopt($ch, CURLOPT_POSTFIELDS, "login=login&username=$username&password=$password");
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array("username" => $username, "password" => $password)).":");

Sorry, hatte wohl Tomaten auf den Augen. Ich hatte das „curl_exec ($ch);“ nach dem Login vergessen.
Jetzt funktioniert es auch mit der 4.2.0

Besten Dank für das Tolle Skript. Funktioniert einwandfrei :):slight_smile:

Gruess Dani

Ich hab auch noch was für die Ubiquiti Cams im Angebot. Interesse?

Hallo

Ich habe zwar noch keine, aber die dinger sind interessant. Ich hätte interesse :slight_smile:

Danke

Okay, für die Interessierten - hier die Unifi Video Skripte

Ubiquiti - Unifi Video

Cool,
Das interessier mich auch mit den APs.
Sieht ja richtig gut aus!
Läuft das auch auf dem Pi?
Und ist das Skript im ersten Beitrag angepasst oder muss ich da noch etwas ändern.

Ich liebe:loveips:

Hab IPS nicht aufm PI laufen. Einfach mal ausprobieren!