[Info] fritzsoap - PHP Bibliothek für einfachen Zugriff (TR-064) auf die FRITZ!Box

Black Senator

Mitglied
Mitglied seit
13 Jul 2007
Beiträge
418
Punkte für Reaktionen
69
Punkte
28
Hallo,

für diverse Projekte/Experimente habe ich in der Vergangenheit eine PHP Klasse für den TR-064 Zugriff (SOAP) erstellt.
Zugegeben, es gibt schon ein paar davon im Netz zu finden, aber mit fritzsoap liegt nun in der Version 2.1 vor und ich denke, die Bibliothek ist nun reif genug, um sie hier vorzustellen.

Ich habe dabei den Zugriff auf die Actions so umgesetzt, dass die Verwendung so einfach wie möglich ist.

Ein Beispiel:
PHP:
$fritzbox = new x_voip($url, $user, $password);
$fritzbox->x_AVM_DE_DialNumber('#9');
oder
PHP:
$fritzbox = new hosts($url, $user, $password);
$meshList = $fritzbox->x_AVM_DE_GetMeshListPath();

Fakten in Kürze:
  • Für jeden Service besteht eine gleichnamige Klasse, in der alle Actions des Service als Funktionen enthalten sind - man muss also nur anhand der der AVM Dokumentation wissen, wie Service und Action lauten, die man benötigt.
  • Jede Klasse (=Service) ist in einer gleichlautenden PHP Datei codiert.
  • In jeder Klasse sind die jeweiligen Actions als Funktionen codiert
    (die Namen sind gleich, jedoch an PHP angepasst: erster Buchstabe klein und - als _)
  • Ebensowenig, wie man sich also um URI und Location kümmern muss, muss man sich auch nicht um die korrekte Adressierung der URL und insbesondere des SOAP Ports kümmern (siehe hier).
Es gibt jedoch eine Einschränkung!:
AVM stellt in knapp 30 Services fast 500 Actions zur Verfügung - die konnte ich unmöglich alle selbst programmieren! Die Klassen sind daher per Programm maschinell generisch erzeugt worden (Basis waren die Servicdescription-Files meine 7490er). Für jedes Action ist darin jeweils eine generische Function angelegt worden.
Beispiel (aus x_homeauto.php):
PHP:
/**
* setSwitch
*
* automatically generated; complete coding if necessary!
*
* in: NewAIN
* in: NewSwitchState
*
*/
public function setSwitch()
{
    $result = $this->client->SetSwitch();
    if (is_soap_fault($result)) {
        $this->getErrorData($result);
        error_log(sprintf("Error: %s (%s)! Could not ... from/to FRITZ!Box", $this->errorCode, $this->errorText));
        return;
    }

    return $result;
}
Rund 5% der Funktionen sind bereits auscodiert - hauptsächlich in x_contact.php (ansonsten noch in hosts.php, x_filelinks.php, x_storage.php, x_tam.php und x_voip.php).

Wenn nun ein Action benötigt wird, dessen Funktion noch generisch ist, sollte es anhand der auscodierten Beispiele und der AVM Dokumente kein Problem sein, das umzusetzen.
Wenn so weitere Funktionen nutzbar gemacht werden, dann spielt doch die Ergebnisse als PR auf GitHub zurück - dann haben zukünftig alle etwas davon.
Aus der README.md:
contributions are highly appreciated. Share your enhancements! With your PR, everyone benefits from further completion!

Grüße

Black Senator
 
Zuletzt bearbeitet:
  • Like
Reaktionen: m106
Moin,

im vergangenen Jahr sind einige Ergänzungen und Verbesserungen hinzugekommen.
Sich mit getServiceDescription() alle Services und deren Actions in einer übersichtlichen XML ausgeben zu lassen gabe es schon. Aktuell letzte Neuerung ist die Möglichkeit, sich mit getServiceDescription(true) auch die Parameter der Actions sowie die Herkunft - also aus welchem der *DESC.xml bzw. *SCPD.xml die Information ausgelesen wurden - mit ausgegeben zu lassen:
detail_xml.jpg
Darüber hinaus kann man jetzt die bereits ermittelten Service-Daten an die nächste Klassen-Instanziierung übergeben. Damit wird das zeitaufwändige Einlesen in dessen Constructor übersprungen, wenn man unterschiedliche Klassen in einen Script nutzt:EDIT: hat sich überholt (s.u.)
PHP:
$classA = new aura($url, $user, $password);
$classA->getClient();
$classA->getVersion();
...
$services = $classA->getServiceDescription();
$services->asXML('services.xml');
...
$classB = new x_contact($url, $user, $password);
$classB->getClient();
$classB->getInfo();

Grüße

Black Senator
 
Zuletzt bearbeitet:
Hallo,

angeregt durch eine lebhafte private Unterhaltung mit @MightGuy habe ich noch einiges an der Klassenstruktur geschraubt und verbessert. Wie so oft übernimmt man manchmal die (Teil-)Lösungen früherer Versionen, ohne die Sinnhaftigkeit zu hinterfragen: z.B. das mit jeder Instanziierung einer Subklasse die Services wieder bzw. überhaupt eingelesen werden. Irgendwann ist mir aufgefallen, dass das ja nur (noch) für die Ermittlung von (Beispiel)
<serviceType>urn:schemas-any-com:service:aura:1</serviceType>
<controlURL>/upnp/control/aura</controlURL>
notwendig geworden war. Das wurde jetzt geändert und das zeitaufwändige Auslesen der FRITZ!Box entfällt damit.
Die Funktion an sich ist selbstverständlich noch vorhanden und auch sinnvoll, wenn man z.B. in komprimierter Form alle Services der eingenen Box überblicken möchte.
Darüber hinaus habe ich das Code-Generierungs-Script noch mal optimiert und die Funktionen der Klassen sind hinsichtlich der Ein- und Ausgabeargumente und der SOAP-Parameter nun vervollständigt. Die unmittelbare Gebrauchsfähigkeit der programm-erzeugten Funktionen (SOAP-Actions) ist jetzt "fast" ohne weiteres Zutun gegeben.

Grüße

Black Senator
 
Zuletzt bearbeitet:
  • Like
Reaktionen: MightGuy
Hallo,

angeregt durch eine Nutzer-Rückfrage habe ich vor geraumer Zeit festgestellt, dass der Code noch weiter "user-friendly" vereinfacht werden kann:

PHP:
$fritzbox = new x_voip($url, $user, $password);
$fritzbox->x_AVM_DE_DialNumber('#9');
oder
PHP:
$fritzbox = new hosts($url, $user, $password);
$meshList = $fritzbox->x_AVM_DE_GetMeshListPath();

Die vorher (siehe oben) notwendige Funktion $fritzbox->getClient(); nach jeder Inztanziierung ist jetzt bereits im Constructor enthalten.
Trotzdem ist die Funktion noch erhalten und kann aufgerufen werden. Dies ist z.B. erfoderlich, wenn ein länger laufendes Programm mit der Box interagiert und zwischenzeitlich die SID des Client nicht mehr gültig ist (AVM gibt in den Dokumenten sowohl 15 wie auch 10 min an).
Mit $fritzbox->getClient(); kann dann wiederholt der Client "refreshed" werden.
Dies ist beispielsweise bei meinem Spam-Filter erforderlich, der nicht nur 24/7 auf die Callmonitor-Schnittstelle lauscht, sondern auch die notwendigen Telefonbücher wiederkehrend einliest und bei Bedarf Spammer in die entsprechenden Listen zum Blockieren einträgt.

Beste Grüße

Black Senator
 
Zuletzt bearbeitet:
Moin!

Alle paar Monate beschäftige ich mich immer ´mal wieder zum Zeitvertreib mit der fritzsoap Bibliothek. Nach zuletzt anregendem Austausch von Erkenntnissen mit @Kruemelino habe ich wieder Lust gehabt ein paar Funktionen auszucodieren.

Anders als zu Beginn meiner Beschäftigun damit hält die TR-064 Schnittstelle leider keine neuen positiven Überraschungen mehr parat :(. Ich will damit sagen, dass ich die nutzbringenden der 500 Actions wohl soweit alle kenne und es keine neuen netten überraschenden Entdeckungen mehr gibt. Zudem ist es auch so, dass sich am Funktionsumfang generell kaum etwas ändert. Es wäre cool, wenn AVM kontinuierlich den Funktionsumfang um weitere Services und Actions erweitern würde - so dass das, was man i.d.R. per GUI lesen/schreiben kann auch per SOAP-Schnittstelle lesen/ändern könnte.

Warum nun dieses Update?
Ich bin noch einmal die diversen Klassen (= Services) der Bibliothek durchgegangen und habe einige Funktionen (= Actions) weiter auscodiert (wie beschrieben gab es schon pro Action eine entsprechende Funktion - aber eben i.d.R. im Programm-generierter - d.h. generischer Form). Meist war, wie gehabt, nur ein wenig Finishing nötig.

Darüber hinaus habe ich ein paar zusätzliche Funktionen ergänzt, um nutzerfreundlich zu ermöglichen mit z.B. Rückgabewerten zu arbeiten: einige Actions liefern z.B. nur eine *.lua-Pfad zurück und eben nicht das, was dort einzulesen ist. Beispiel: getDectListPath() gibt nur den Pfad inkl. SID zurück. Schema und Host inkl. Port der URL fehlen, stehen aber innerhalb der Klasse sowieso schon direkt mit einer generischen Funktion der fritzsoap Elternklasse zur Verfügung.
Die ergänzte Funktion getDectList() dagegen liefert direkt das Ergebnis - eine XML-Datei - als SimpleXMLElement zurück:
PHP:
/**
 * getDectList
 *
 * returns the list of DECT devices available from the location given with
 * getDectListPath()
 *
 * @return simpleXMLElement
 */
public function getDectList()
{
    $url = $this->getServerAdress() . $this->getDectListPath();

    return simplexml_load_file($url);
}
Pretty simple - zeigt aber, dass mit entsprechender Nutzung bereits in der Klasse gekapselter und geerbter Informationen wertige Ergebnisse einfach zugänglich gemacht werden können.

Beste Grüße

Black Senator
 
  • Like
Reaktionen: Kruemelino
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.