Fritz!Box API für PHP (inkl. Login-Sessions)

spackmat

Neuer User
Mitglied seit
25 Jul 2009
Beiträge
94
Punkte für Reaktionen
2
Punkte
6
Hallo allerseits,

inspiriert durch verschiedene Einträge hier im Forum habe ich eine PHP Klasse geschrieben, mit der man Scripte zur automatisierten Steuerung der Fritz!Box über die Weboberfläche bauen kann. Jede über die Weboberfläche konfigurierbare Option lässt sich damit ebenfalls einstellen.

Hintergrund ist, dass ich an der Box selber nichts modifizieren wollte, aber dringend eine Zeitsteuerung für den Anrufbeantworter benötige. Mit cURL wäre das im Grunde in ein paar Zeilen erledigt, aber ich habe bei der Gelegenheit gleich eine generische Klasse gebaut, die (im Moment nur) die sichere Login-Methode der neueren Firmwares und das Absetzen der Befehle via cURL kapselt und für andere Scripte bereit stellt. Diese sichere Login-Methode ist übrigens sehr spaßig, wie man auch im Thread zur Outlook-Wählhilfe nachlesen kann.

Dazugelegt habe ich das eigentliche Kommandozeilen-Script, das sich um den Anrufbeantworter kümmert und eine Logdatei führt (oder auf der Konsole oder gar nichts ausgibt). In der Logdatei werden auch aussagekräftige Fehlermeldungen vermerkt, wenn etwas schief gelaufen ist, was mir besonders wichtig ist, muss doch mein Kunde täglich damit hantieren. Das Ganze wird bei diesem Kunden über den Taskplaner eines Windows Servers morgens, zur Mittagspause und an verschiedenen Tagen nochmal Nachmittags ausgeführt.

PHP habe ich gewählt, weil ich (freiberuflicher) Webentwickler bin und die Sprache beherrsche. Aber auch andere können meine Scripte dadurch (und durch meine durchgängige Dokumentation) leicht anpassen. Ich denke PHP wird von mehr Leuten verstanden, als jede andere Scriptsprache. Vortzeilhaft ist aber auch, dass solche Scripte prima unter Windows und UNIX (inkl. Mac OSX) laufen und mit ein paar Anpassungen sogar auf einem Webserver. Unter Windows muss dazu nur die PHP-Distibution entpackt und vier Zeilen in der php.ini bearbeitet werden (ist alles in der README.txt dokumentiert). Danach ist PHP ohne weitere Anpassungen lauffähig und kann das Script ausführen.

Die aktuelle Version des Scripts bekommt ihr im Anhang dieser Nachricht. Das Script steht unter einer Creative Commons cc-by-sa Lizenz, Anpassungen und Feedback sind willkommen. Support gebe ich keinen dafür (bzw. nur gegen Geld, ist ja mein Job), Feedback und insbes. Bug-Reports sind aber natürlich sehr willkommen.

Auch seid ihr herzlich eingeladen, auf Basis meines Scripts weitere Scripte zu bauen und wieder an die Community zurückzugeben.

Getestet habe ich es unter Windows mit je einer FritZ!Box 7270 und einer 7390 und PHP 5.3 und 5.4 und es funktioniert sehr stabil.

Viel Spaß damit.


0.5.0b7 2013-01-02:
---

* added a parameter to the constructor of the api to load a different config file (i.e. new frizbox_api('alt') loads fritzbox_user_alt.conf.php
* fixed the logfile-logging in all bundled scripts


0.5.0b6 2012-12-23:
---

* added a username config item to login with a local user, when user-based login is enabled in the box config


0.5.0b5 2012-12-18:
---

* fixed the remoteconfig login code to work with new user system
* fixed the logger calls to echo the message, when the logger is not initialized


0.5.0b4 2012-12-16:
---

* fixed a typo in the remoteconfig login code


0.5.0b3 2012-12-09:
---

* changed fritzbox_get_foncallslist.php to work with new firmwares, moved old method to fritzbox_get_foncallslist_xml.php


0.5.0b3 2012-12-07:
---

* fixed internal SID login/logut-handling


0.5.0b1 2012-12-05:
---

* added support for the new .lua-loginpage in newest Fritz Labor firmwares
* refactored the whole codebase, introduced a new autoloaded config object, so check the new config file fritzbox_user.conf.php


0.4.1 2012-03-15:
---

* added a new script fritzbox_guestlan_on_off.php to switch the new Guest-LAN on and off
* tested all builtin scripts with new FRITZ!OS 05.20


0.4 2011-05-15:
---

* added support for the new .lua forms like the WLAN guest access settings


0.3 2010-05-19:
---

* added a doGetRequest method in the API
* some minor changes
* a new module for downloading the foncalls list


0.2 2010-04-07:
---

* added a capability to use the Fritz!Box remote admin mode
Important limitation: does not check the certificate, so the password is sent to any computer responding at the configured address.
Feel free to hack the cURL calls to accept only a given certrificate


0.1:
---

* First release
 

Anhänge

  • fritzbox_api_php_v0.5.0b7.zip
    15.8 KB · Aufrufe: 3,425
Zuletzt bearbeitet:
Klasse gemacht! Danke! Ich würde gerne auch eine Rufumleitung setzen/löschen per CLI. Hab mir dein TAM Beispielscript mal angeschaut, aber ehrlich gesagt steige ich da noch nicht durch.

Die eigentlich wichtigen Zeilen um den AB an/auszuschalten sind doch folgende:
Code:
  $formfields = array(
    'getpage'                             => '../html/de/menus/menu2.html',
    'tam:settings/TAM' . $tam . '/Active' => $mode,
  );
  $fritz->doPostForm($formfields);

Woher kommen die Infos welche Parameter in das Array müssen? Sorry für die vielleicht blöde Frage, aber ich bin noch nicht per Du mit PHP und der Fritzbox.

Wie komme ich an die richtigen Input Parameter um eine bereits eingerichtete Rufumleitung ein/auszuschalten?

Wenn dir das schon zuviel der Fragen sind für ein Script welches du angekündigterweise nicht supportest, dann sag es frei raus.
 
Genau, das ist schon mal der richtige Befehl. Das zuständige Feld bekommst Du heraus, indem Du einfach den Quelltext des Frames anguckst, wo die Einstellung veränderbar ist. Ich bin dazu auf die Übersichtsseite mit den Rufumleitungen gegangen und habe testhalber eine Rufumleitung eingerichtet.

Im Quelltext des Frames habe ich dann nach den versteckten Input-Feldern gesucht, diese haben die Form:

<input type="hidden" name="SETTING" value="WERT" id="IDDESSETTINGS">

Mit etwas Sucharbeit findet man dann das Feld

<input type="hidden" name="telcfg:settings/Diversity0/Active" value="0" id="uiPostActivDiversity0">

für die erste Rufumleitung, die aktuell ausgeschaltet (value="0") ist. Das können wir benutzen, um den aktuellen Status auszulesen (weiter unten in meinem Script). Um den Wert zu setzen, muss jetzt folgendes gemacht werden:

PHP:
  $formfields = array(
    'getpage'                             => '../html/de/menus/menu2.html',
    'telcfg:settings/Diversity' . $diversity . '/Active' => $mode,
  );
  $fritz->doPostForm($formfields);

Vorher im Script müssen dann irgendwie $diversity auf die ID der Rufumleitung und $mode auf den gewünschten Modus (aus oder an) gesetzt werden. Das einfachstmögliche Script mit hartcodierten Einstellungen und ohne Überprüfung auf Erfolg und ohne Logging würde dann so aussehen:

PHP:
<?php
// load the config
require_once('fritzbox.conf.php');
 
// load the fritzbox_api class
require_once('fritzbox_api.class.php');

$diversity = 0; // set to the internal ID of the call diversion, the first one has ID 0;
$mode = 0; // set the mode to 0 or 1 do disable or enable the call diversion

// do the job
try
{
  $fritz = new fritzbox_api($password, $fritzbox_ip);
  
  // update the setting
  $formfields = array(
    'getpage'                             => '../html/de/menus/menu2.html',
    'telcfg:settings/Diversity' . $diversity . '/Active' => $mode,
  );
  $fritz->doPostForm($formfields);
  $fritz = null; // destroy the object to log out
}
catch (Exception $e)
{
  echo $e->getMessage();
}
?>

Wenn Du also keine Lust hast, Dir PHP genauer anzugucken, kannst Du zwei Scripte bauen, die nur diesen Inhalt haben, und dann jeweils nur die Einstellung bei $mode anpassen. Das eine schaltet dann aus, das andere ein. Fertig. Das läuft dann sogar ohne weitere Anpassungen auf einem PHP5 fähigen Webserver im internen Netz.

Das ist zwar wenig elegant, funktioniert aber ohne großen Aufwand. Ansonsten kann man sich mein Script für den Anrufbeantworter entsprechend anpassen, das Logging kann man so lassen und muss nur die Fehlermeldungen und die Bedingungen anpassen. Das mit den Regulären Ausdrücken bei Auslesen des aktuellen Status ist für Fortgeschrittene, wobei das hier ja eigentlich noch recht simplel ist.
 
Zuletzt bearbeitet:
Danke für die Antwort. Prinzip verstanden! RegEx sind nicht wirklich ein Problem für mich, bin alter Perlhase ;).

Nur wie komme ich an den Quelltext vom Frame? Ich versuche das unter Safari und bekomme nur sowas
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

Liegt das an Safari ;)? Habe gerade im IE mal probiert und komme auch nicht an Quelltext eines Formulars ;).
 
In Firefox ist es Strg+U um den Quelltext zu sehen.

Oft mußte das Frame erst in einem neuen Fenster extra geöffnet werden. Und beliebter Trick von AVM, erst am Ende der Seite den eigentlichen Code stehen zu haben. Scroll einfach mal runter

Happy computing!
R@iner
 
Ja genau. Also im Firefox im Kontextmenü "Aktueller Frame -> Frame-Quelltext anzeigen", dann hat man die richtige Seite. AVM hat da über 100 Leerzeilen am Anfang des eingefügt Quelltextes, warum auch immer.

Wenn Du Perlhase bist, sollte das die Anpassung des restlichen Scipts dann kein Thema mehr für Dich sein.

Viel Erfolg damit.
 
Warum die das machen? Um Deppen wie mich zu überlisten ;). Habs jetzt gefunden und mache mich mal dran. LG und DANKE!
 
Hallo,

ich ziehe mit

Code:
require_once('fritzbox.conf.php');
require_once('fritzbox_api.class.php');
  $fritz = new fritzbox_api($password, $fritzbox_ip);

   $formfields = array(
    'getpage'                             => '../html/de/FRITZ!Box_Anrufliste.csv',
  );
  $output = $fritz->doPostForm($formfields);

die Anruferliste in $output rein. Das funktioniert auch. Allerdings bekomme ich immer die Anruferliste wie sie vor dem letzten Login an der Fritzbox war. Neue Anrufe sind nicht dabei. Was mache ich falsch?

Dennis
 
Das gleiche Problem hatte jemand anderes ebenfalls, der Trick besteht darin, die Seite vorher erst einmal abzurufen. Glücklicherweise hat derjenige mich dafür bezahlt, das Problem zu lösen und nochmal glücklicherweise findet er es selbstverständlich, den Code dafür weiterzugeben. Ich habe die aktuelle Version 0.3 mal an den ersten Post angehängt.

Nebenbei kann das Skript jetzt auch wahlweise über die Fernwartungsfunktion in die Box gelangen, falls das jemand benötigt.

Viel Spaß damit.
 
Wohoooo! Funkt einwandfrei.

1000 Dank!

Dennis
 
Gute Nachricht: Die API funktioniert offenbar auch mit der neuen Oberfläche der .86er Firmware, getestet habe ich Anrufbeantworter ein- und ausschalten, sowie Anrufliste holen.
 
Super, vielen Dank für die API.
Habe sie auch gerade auf der .86 Firmware am laufen.
Habe noch ein Skript hinzugefügt um Rechner per wol zu starten.
 
Ich habe mal ein Script für den WLAN-Gastzugang ergänzt. Man kann den Gastzugang ausschalten, einschalten und dabei mit einem optionalen zweiten Parameter ein neues WPA-Passwort vergeben. Alle anderen Einstellungen bleiben erhalten, wie sie sind. Das Passwort wird auf der Kommandozeile bzw. in der Logdatei beim Einschalten angezeigt.

Das Script braucht einige RegEx-Zaubereien, um die bestehenden Einstellungen auszulesen und wieder setzen zu können. Das Problem dabei ist, dass AVM in Zukunft möglicherweise neue Einstellungsoptionen hinzufügt, die eine Anpassung des Scripts notwendig machen. Wenn das Script also irgendwann Eure Einstellungen zum Gastzugang killt, muss es angepasst werden. Das ist ärgerlich, aber leider so.
 

Anhänge

  • fritzbox_guestwlan_on_off.zip
    1.8 KB · Aufrufe: 274
Ich bin planlos ;-)

Hallo zusammen,

ich habe diese tolle Möglichkeit gefunden, die Fritzbox anzusprechen und möchte es gerne nutzen, um im Alarmfall (Rauchmelder löst aus / HW/SW dafür bereits fertig) einen Anruf bei mir auf dem Handy zu initiieren. Ich nutze einen Synology NAS, auf dem meine ganze Hausautomation mit FHEM läuft. Daher würde ich den PHP Code gerne unter Linux ausführen. Ich habe auch einen Webserver laufen, der mein Portal für mein komplettes Haus bereitstellt, aber irgendwie habe ich noch nicht verstanden, wie ich die API nun einsetzen muss. Es wäre supernett, wenn mir mal jemand einen Einstieg unter Linux geben könnte:

- Wo müssen die Files aus dem Zip hingelegt werden?
- Was muss ich noch anpassen (Passwort etc.)?
- Wie erfolgt dann ein Aufruf?
- Muss ich bestimmte Paket installiert haben, um die API überhaupt zu nutzen?


Vielen Dank und viele Grüsse
alochter
 
Zuletzt bearbeitet:
Erster Teilerfolg!!! Ich hatte php-mbstring nicht installiert. Die foncallsdaten.xml ist nun wie von Geisterhand auf meinem Server;-)

Wie kann ich nun das Script so umbauen, dass bei Ausführung eine bestimmte Nummer gewählt wird?

Gruss,
alochter
 
Für andere Interessierte, die Antworten zu den Fragen zwei Posts weiter oben ergeben sich beim Lesen der README.txt, da steht drin, dass PHP 5.2 mit den Extensions für mbstring und curl benötigt wird. Scheinbar klappt das ja bei Synology-NAS-Servern.

Zu der letzten Frage: Wie oben schon erwähnt, muss man im Webinterface beobachten, was bei der gewünschten Aktion passiert. Ältere Funktionen schicken ein POST-Request mit den Änderungen an ein zentrales Skript (etwa die Anrufbeantwortersteuerung). Neue Funktionen arbeiten mit einem speziellen LUA-Script (etwa die WLAN-Gastzugang). Man muss sich also mit dem Firebug oder ähnlichem auf die Lauer legen und schauen, was für POST-Request im Hintergrund ablaufen, während man die gewünschte Funktion im Webinterface benutzt. Das baut man dann mit einem entsprechenden Script nach. Die API hilft da nur so weit, dass sie die Sessionverwaltung übernimmt und vereinfachte Methoden für POST und GET anbietet. Den Rest schreibt man sich nach Wunsch in ein spezialisiertes Script bzw. passt eins der bestehenden entsprechend an. Nicht jeder braucht zum Beispiel ein Logging oder möchte den Erfolg der Aktion überprüfen.

Wenn man nicht weiß, was POST, GET oder Firebug ist, wird man allerdings nicht weit kommen. Auch als PHP-Anfänger wird man Schwierigkeiten bekommen. Dann ist da noch das Problem, dass AVM die Funktionen mitunter eigenartig implementiert, wie zum Beispiel bei der Anrufliste, die veraltet ist, wenn man nicht vorher einmal die Seite aufgerufen hat. Da hilft dann nur ausprobieren. Jedenfalls ist die API für Leute gedacht, die eine profunde Vorbildung in Sachen Webentwicklung haben, zumindest wenn man eigene Funktionserweiterungen schreiben will.
 
Hi,

vielen Dank für die Antwort. Ich muss aber leider gestehen, dass Dein letzter Post nicht wirklich hilfreich war. Klar muss man gewisses Know How auch voraussetzen, aber man muss auch den "Anfängern" die Chance geben, sich entspr. Wissen anzueignen. Ich verstehe Foren genau als dieses Hilfsmittel, wo man sich gegenseitig hilft und damit dann seine Fähigkeiten erweitert und evtl. auch für andere nützliche Dinge weitergibt. Ja, ich bin kein PHP Profi, aber ich habe bis jetzt noch alles hinbekommen und das wird auch bei diesem Projekt wieder der Fall sein;-)
Wäre schön gewesen, wenn ich von dem "Profi" weitere hilfreiche Tips bekommen hätte, aber wenn nicht, kommt bestimmt ein weiterer "Profi" und schlaut mich auf.
So ist das nunmal im Netz.

Schöne Grüsse
alochter


P.S.: So unpraktisch finde ich meine Idee eigentlich nicht. Also wenn sich jemand mit Ahnung berufen fühlt, hier ein Code-Beispiel für das Anklingeln per Fritzbox zu liefern, würde mich das total freuen.
 
Die Idee ist tatsächlich nicht unspannend. Wenn also jemand sich die Mühe macht, das zu bauen, würden sich sicher auch andere darüber freuen.

@alochter: Wie willst Du eigentlich Du einen Anruf auslösen? Gibt es im Webinterface einen Knopf "Anruf auslösen"? Ich kenne nur die Wählhilfe, aber die wählt ja erst raus, wenn am angegebenen internen Telefon jemand abgehoben hat, das hilft uns hier ja nicht weiter (davon abgesehen, dass sie auch noch immer nicht mit IP-Nebenstellen zusammenarbeitet). Mit der API kann man nur Aktionen auslösen, die im Webinterface der Box möglich sind. "Externen Anruf auslösen" und womöglich irgendeine Nachricht abspielen gehört meines Wissens nach nicht dazu. Oder habe ich mir da was spannendes entgehen lassen?

Nachtrag: Für das Nutzungsszenario könnte ich mir vorstellen, dass die Box da ein unnötiger Umweg ist, selbst wenn das funktionieren würde. Viel einfacher ist es doch, eine Mail zu versenden und damit sonstwas anzustoßen, etwa einen SMS-Versand bei einem Dienstleister. Oder direkt eine externe API anzusprechen. Das wäre eine Zeile PHP-Code bzw. ein paar mehr, wenn die mail()-Funktion auf dem Gerät nicht von sich aus funktioniert.
 
Zuletzt bearbeitet:
Jup, genau die Wahlhilfe. Wenn man die nutzt bzw. auf die Nummer klickt und einfach wartet, klingelt das entfernte Telefon nach ein paar Sekunden:)
 
Die Header, die beim Klick auf den "Telefon testen" Button übertragen werden, sind folgende:

Code:
sid:9a7d0aa2c6e8449b
getpage:../html/de/menus/menu2.html
errorpage:../html/de/menus/menu2.html
var%3Apagename:dial
var%3Aerrorpagename:dial
var%3Amenu:fon
var%3Apagemaster:
time%3Asettings%2Ftime:1311176980,-120
var%3ATestPort:60
var%3AOldDialPort:50
telcfg%3Asettings%2FUseClickToDial:1
telcfg%3Asettings%2FDialPort:50
telcfg%3Acommand%2FDial:**610

Wie ich die Box kenne, braucht man davon nicht alle. Wenn man dann im Popup auf OK klickt, kommt noch ein Request, der das Klingen wieder stoppt:

Code:
sid:9a7d0aa2c6e8449b
getpage:../html/de/menus/menu2.html
errorpage:../html/de/menus/menu2.html
var%3Apagename:dial
var%3Aerrorpagename:dial
var%3Amenu:fon
var%3Apagemaster:
time%3Asettings%2Ftime:1311177144,-120
var%3ATestPort:
var%3AOldDialPort:
telcfg%3Asettings%2FDialPort:60
telcfg%3Acommand%2FHangup:
var%3AWaehlhilfeVon:

Daraus lässt sich leicht ein Script bauen, etwa so:

PHP:
<?php
// load the config
require_once('fritzbox.conf.php');
 
// load the fritzbox_api class
require_once('fritzbox_api.class.php');

$dial = '**610'; // set to the number to dial

// do the job
try
{
  $fritz = new fritzbox_api($password, $fritzbox_ip);
  
  // update the setting
  $formfields = array(
    'getpage'                             => '../html/de/menus/menu2.html',
    'telcfg:command/Dial'                 => $dial,
  );
  $fritz->doPostForm($formfields);
  $fritz = null; // destroy the object to log out
}
catch (Exception $e)
{
  echo $e->getMessage();
}
?>

Damit klingelt die Nebenstelle **610, bis man ablehnt. Es klappt sogar, hier externe Nummern anzugeben, aber damit beginnt das Chaos, weil man damit ggf. Nebeneffekte wie dauerhaft durchklingelnde Telefone verursachen könnte. Das war ja einfach.
 
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.