home
erste Version am 16.11.2014
letzte Änderung am 10.02.2017

Fritzbox Callmonitor v1.2a


Eine Client/Server-Anwendung zur Speicherung und zur Anzeige von Verbindungsdaten zu Telefonaten, die über die Fritzbox geführt werden bzw. wurden.


Achtung!
Offenbar hat sich die Webseite von 11880 etwas geändert, weshalb die Rückwärtssuche keine Namen zu Nummern mehr gefunden hat.
Die Version 1.2 ist entsprechend angepasst.


Inhalt

  1. Kurzbeschreibung
  2. Voraussetzungen
  3. Notwendige Anpassungen
  4. Aufruf des Server-Scripts
  5. Bedienung des Client-Scripts
  6. Das Menü des CallMon-Clients
  7. Weitere Optionen im Setup-Dialog
  8. Service-Tools



Kurzbeschreibung

Das CallMonServer-Script läuft 24x7 auf einem entsprechenden System (z.B. einem Raspberry Pi).
Es verbindet sich beim Start mit dem Fritzbox-Callmonitor (der auf einem an die Fritzbox angeschlossenen Telefon vorab einmalig mit der Tastenfolge #96*5* aktiviert worden sein muss - siehe dazu auch wehavemorefun.de) und speichert dessen Meldungen in einer Datenbank.
Weiterhin nimmt das CallMonServer-Script Verbindungen von CallMonClient-Scripten an.

Alle verbundenen CallMon-Clients werden vom CallMon-Server bei neu eintreffenden Meldungen vom Fritzbox-Callmonitor sofort informiert und sind damit in der Lage, die aktuell offenen Verbindungen anzuzeigen.
Die Clients fragen aber auch die Daten von bereits beendeten Telefonaten beim CallMon-Server an, um diese dann ebenfalls anzuzeigen.
Dadurch wird erreicht, dass mehrere CallMon-Clients auf unterschiedlichen Rechnern laufen können und trotzdem alle dasselbe anzeigen, obwohl sie jeweils zu unterschiedlichen Zeitpunkten gestartet wurden.
Auch kann der CallMon-Server vom Client angewiesen werden, Telefonbuch-Daten von der Fritzbox neu einzulesen und sie in der Datenbank zu speichern. Dazu muss der Client dem Server das Fritzbox-Passwort übermitteln (erfolgt verschlüsselt).


Voraussetzungen

Für den CallMon-Server und den CallMon-Client wird ein Python-Interpreter in der Version 2.7.x benötigt.

Das GUI des CallMon-Clients benötigt wxWidgets (bzw. wxPython) in der Version 2.8.
Ebenfalls benötigt wird:
    python-pycrypto (python-pycrypto-2.5-3.1.2.x86_64) oder auch python-crypto

Der CallMon-Server benötigt:
    sqlite3 (sqlite3-3.7.12.1-2.1.2.x86_64)
    python-lxml (python-lxml-2.3.4-2.1.2.x86_64)
    python-requests (python-requests-0.12.1-2.1.2.noarch)
    python-pycrypto (python-pycrypto-2.5-3.1.2.x86_64) oder auch python-crypto
    python-cssselect (python-cssselect-0.8-4.1.2.noarch) sofern es nicht automatisch bei python-lxml mitkommt

Der CallMon-Client legt eine Datei im Home-Verzeichnis an:
.CallMonClient.conf
In dieser Datei werden die Fenstergröße, Fensterposition und die Breiten der Spalten sowie mögliche Aliasse gespeichert.

Der CallMon-Server legt ebenfalls eine Datei im Home-Verzeichnis an:
.callmon.sqlite
In dieser Datenbank-Datei werden die Daten der geführten Telefonate sowie Kopien der Fritzbox-Telefonbuch-Einträge und, sofern aktiviert (s.u.), weitere über www.11880.com ermittelte Telefonnummer/Name-Relationen gespeichert.

Und hier das ZIP mit dem Programmcode.
Sowohl auf Server- wie auch auf Client-Seite sollte jeweils das komplette Verzeichnis callmon vorliegen.

Kleiner Nachtrag: irgend ein Update hat dazu geführt, dass das Telefonbuch der Fritzbox nicht mehr erfolgreich ausgelesen werden konnte. Um das zu fixen, ist in "GetPhonebook.py" die Zeile 89 zu ändern nach:
    response=requests.get(url, verify=False)


Notwendige Anpassungen

Am Anfang der Datei CallMonServer.py sind folgende Parameter anzupassen:
OWN_AREA_CODE Hier ist die eigene Vorwahlnummer einzustellen (sie wird Nummern aus dem Telefonbuch ohne führende Null vorangestellt).
FRITZBOX_IP Unter der hier eingestellten IP-Adresse oder dem Hostname wird die Fritzbox erwartet.
CALLMON_SERVER_SOCKET Auf dem hier eingestellten Port lauscht das Script und wartet auf Verbindungen von CallMon-Clients.
FRITZBOX_CALLMON_PORT
Dieser Wert sollte üblicherweise nicht geändert werden. Auf dem Port lauscht der Fritzbox-Callmonitor (1012).
USE_11880_QUERIES
Wird hier der Wert True durch False ersetzt, fragt der CallMon-Server nicht mehr bei 11880 nach Namen zu unbekannten Telefonnummern an.
STATUS_TO_TERMINAL
Bei dem Wert True werden Status-Meldungen ausgegeben, bei False nur Fehlermeldungen.

Am Anfang der Datei CallMonClient.py ist ggf. folgender Parameter anzupassen:
FRAME_NO_TASKBAR Wird hier der Wert False durch True ersetzt, erscheint der CallMon-Client nicht mehr in der Taskbar. In diesem Fall kann er mittels  wmctrl -a CallMonClient  in den Vordergrund geholt werden (was primär dann Sinn macht, wenn man in der Taskbar ein Starter hat, der dies tut).



Aufruf des Server-Scripts

Nachdem die notwendigen Anpassungen an den Variablen im Script vorgenommen wurden, kann es mit ./CallMonServer.py gestartet werden.

Weil es so gedacht ist, dass das Script rund um die Uhr läuft, sollte es entweder auf einem System eingesetzt werden, das ohnehin immer an ist - oder es sollte ein stromsparendes System (wie etwa ein Raspberry Pi, CubieTruck oder wie sie alle heißen) gewählt werden.
Für einen ersten Funktionstest kann der CallMon-Server aber natürlich auch auf dem gleichen System gestartet werden, auf dem der erste CallMon-Client laufen soll. Es können sich durchaus mehrere CallMon-Server am Callmonitor einer Fritzbox anmelden.

Das CallMon-Server-Script benötigt kein GUI - es werden nur Textmeldungen angezeigt.
Gegebenenfalls muss der eingestellte Port (CALLMON_SERVER_SOCKET) in der Firewall freigegeben werden, damit sich CallMon-Clients dazu verbinden können.

Nach dem Start sollte es folgendermaßen aussehen (sofern STATUS_TO_TERMINAL auf True eingestellt ist):
dede@c2q:~/callmon> ./CallMonServer.py
2014.11.28-17:45:42 Anweisungs-Sockets=0  Meldungs-Sockets=0  Clients=[]
2014.11.28-17:45:42 Die Verbindung zum CallMonitor der Fritzbox wurde hergestellt!
Will heißen: keine geöffneten Sockets zu Clients, aber eine offene Verbindung zum Fritzbox-Callmonitor.

Sobald sich der erste CallMon-Client mit dem CallMon-Server verbindet, kommen Meldungen hinzu:
2014.11.28-17:48:10 connect: 192.168.178.23:60185 alias Client[0]
2014.11.28-17:48:10 Anweisungs-Sockets=1  Meldungs-Sockets=0  Clients=[0]
2014.11.28-17:48:10 connect: 192.168.178.23:60185 alias Client[0]
2014.11.28-17:48:10 Anweisungs-Sockets=1  Meldungs-Sockets=1  Clients=[0]
2014.11.28-17:48:10 Anweisung von Client[0] empfangen: ['GET_OWN_AREA_CODE']
2014.11.28-17:48:10 Anweisung von Client[0] empfangen: ['GET_FINISHED_CALLS', '42']
2014.11.28-17:48:10 Anweisung von Client[0] empfangen: ['GET_OPEN_CALLS']
2014.11.28-17:51:24 Anweisung von Client[0] empfangen: ['READ_PHONEBOOKS', 'C82tfHrfkIFSYYqgYGES9ctm4g1ydhtGTaldMpXHc7iC562k3z4atpWniCrCTIKL4QxFNa2Ru/C9\ncK6JMjeCHBu/MX/iYnFWDyDH46mt9G7V+nINgOSy10G+LVoG9xiiUB0RQzpYoYUWgvuJvnznw8zG\njb8fpQSQhUW/8YN/YNg=']
Es wurde ein Anweisungs- und ein Meldungs-Socket geöffnet, dann die eigene Ortsvorwahl, die Liste von bereits beendeten Telefonaten und danach die Liste der aktuell offenen Telefonate vom Client angefragt. Etwas später (um 17:51) wurde der Server vom Client noch angewiesen, das Telefonbuch der Fritzbox in die Datenbank zu übertragen. Der Buchstaben-Salat ist das verschlüsselte Passwort der Fritzbox, das am Client abgefragt wurde.

Bei einem zeitweisen Ausfall der Fritzbox (hier war es der Update von FRITZ!OS 06.20 auf 06.23) geht der CallMon-Server zurück zum Verbindungsaufbau und versucht so lange die Verbindung zum Fritzbox-Callmonitor wiederherzustellen, bis er damit (hoffentlich irgendwann) erfolgreich war:
2015.02.08-10:58:19 Die Verbindung zum CallMonitor der Fritzbox ist abgebrochen!
socket.error [Errno 111] Connection refused
socket.error [Errno 111] Connection refused
socket.error [Errno 111] Connection refused
socket.gaierror [Errno -3] Temporary failure in name resolution
socket.gaierror [Errno -3] Temporary failure in name resolution
socket.gaierror [Errno -3] Temporary failure in name resolution
socket.gaierror [Errno -3] Temporary failure in name resolution
socket.gaierror [Errno -3] Temporary failure in name resolution
socket.gaierror [Errno -3] Temporary failure in name resolution
2015.02.08-11:01:34 Die Verbindung zum CallMonitor der Fritzbox wurde hergestellt!
An verbundenen CallMon-Clients wird der Ausfall mit einer Popup-Meldung signalisiert:
Popup-Meldung bei Fritzbox-Ausfall
....die Verbindung zum CallMon-Server bleibt bestehen.


Bedienung des Client-Scripts

Nachdem das Server-Script gestartet wurde, kann der CallMon-Client mittels ./CallMonClient.py geöffnet werden.
Da dem CallMon-Client die IP-Adresse und die Portnummer des CallMon-Servers noch nicht bekannt sind, erscheint zunächst der Setup-Dialog:
Setup-Dialog

In der Box "CallMon-Server" sind die Daten des CallMon-Servers einzustellen.
Hinter "IP-Adresse oder Hostname" ist der Systemname einzutragen, auf dem CallMonServer.py läuft. Laufen CallMon-Server und CallMon-Client auf dem selben System, lautet dieser localhost oder auch 127.0.0.1.
Hinter "Socketnummer" ist der Wert einzustellen, der in CallMonServer.py in der Variable CALLMON_SERVER_SOCKET eingestellt ist.
Weil sich die Daten für den CallMon-Server geändert haben, erscheint nach Auswahl von Ok folgendes PopUp-Fenster:
PopUp-Fenster

Nach Neustart des CallMon-Clients können jetzt bereits Telefonate angezeigt werden, sofern diese seit dem Start des CallMon-Servers eröffnet wurden.
CallMon-Client (ohne Telefonate)

Da dem CallMon-Server das Telefonbuch der Fritzbox aber noch nicht bekannt ist, würden in den Spalten "Nebenstelle Name" und "Name (ext)" keine Namen zu den Telefonnummern angezeigt werden.
Daher sollte gleich als erster Schritt das Telefonbuch der Fritzbox in die Datenbank des CallMon-Servers übertragen werden.

Dazu ist im Kontextmenü des CallMon-Clients der Eintrag "Telefonbuch von Fritzbox einlesen" auszuwählen und im daraufhin erscheinenden Dialogfenster das Passwort der Fritzbox (welches auch für das Web-GUI verwendet wird) einzugeben.
CallMon-Client (Menue offen)

Nach Auswahl von OK erscheint entweder ein Popup-Fenster mit der Meldung "Die Telefonbücher wurden neu eingelesen!" oder aber "Das Einlesen der Telefonbücher ist fehlgeschlagen!", wenn das Passwort falsch war.
Anmerkung: Das Passwort der Fritzbox wird nirgendwo im Dateisystem gespeichert.
Immer dann, wenn es benötigt wird, fragt der CallMon-Client dessen Nutzer nach dem Passwort und überträgt es verschlüsselt zum CallMon-Server. Dieser meldet sich damit einmalig an der Fritzbox an, um die vom CallMon-Client beauftragte Aktion auszuführen.
Derzeit wird das Fritzbox-Passwort ausschließlich zum Einlesen des Telefonbuches benötigt.
Weil das Fritzbox-Telefonbuch auf den CallMon-Server übertragen wurde, muss nicht jeder weitere Client das Telefonbuch ebenfalls einlesen.
Es sollte lediglich dann neu eingelesen werden, wenn Änderungen am Fritzbox-Telefonbuch vorgenommen wurden.
Für jede anrufende oder angerufene Telefonnummer, die sich nicht in der Kopie des Fritzbox-Telefonbuchs auf dem CallMon-Server befindet, wird der zugehörige Name per Inverssuche bei 11880.com angefragt und ebenfalls in der Datenbank des CallMon-Servers abgelegt. Die Namen, die nicht aus dem Fritzbox-Telefonbuch stammen, bleiben für 30 Tage gültig. Nach diesem Zeitraum wird der Name zur Telefonnummer in dem Moment neu angefragt bzw.  aktualisiert, in dem die Telefonnummer angerufen wird oder anruft.

Nachdem das Telefonbuch der Fritzbox eingelesen ist und ein paar Telefonate geführt wurden, erhält man etwa folgende Anzeige:
CallMon-Client

Neu eintreffende oder ausgehende Telefonate oder Änderungen an deren Status werden auf allen mit dem CallMon-Server verbundenen CallMon-Clients angezeigt. Und zwar einerseits mit einem Popup-Text, der in der rechten unteren Ecke des primären Bildschirms erscheint und (unter XFCE) im Maximal-Fall z.B. so aussieht:
PopUps1        PopUps2
Diese Popup-Texte werden immer im Vordergrund angezeigt, klauen einem aber nicht den Fokus der Anwendung, in der man sich gerade befindet.
Jeder einzelne Popup-Text verschwindet nach jeweils einer Minute Anzeige-Dauer oder bei einem Links-Klick mit der Maus.
Sofern über einem verschwundenen Popup-Text weitere Popup-Texte angezeigt werden, sacken diese danach entsprechend weit nach unten.

Natürlich wird ein neues Telefonat auch im CallMon-Client hervorgehoben - und zwar farblich:
CallMon-Client (Telefonat offen)

Der Spalte "Richtung" kann entnommen werden, in welchem Status sich das Telefonat befindet.
Inhalt
Bedeutung
->
ausgehendes Telefonat
<-
ankommendes Telefonat
bla
es wird gesprochen ... bzw. eine Verbindung ist zustande gekommen
-X
das Telefonat ist beendet

Folgende Kombinationen können sich ergeben:
Inhalt
Bedeutung
->
Es wurde eine Nummer angerufen, dort aber noch nicht abgehoben.
-> bla
Es wurde eine Nummer angerufen und auf der Gegenseite abgehoben.
-> -X
Es wurde eine Nummer angerufen, es ist keine Verbindung zustande gekommen, dann wurde aufgelegt.
-> bla -X
Es wurde eine Nummer angerufen, ein Gespräch geführt und die Verbindung beendet.
<-
Ein ankommender Anruf, den noch niemand angenommen hat.
<- bla
Ein Anruf wurde angenommen und die Verbindung ist noch offen.
<- -X
Ein Anruf kam an, wurde nicht angenommen und der Anrufer hat aufgelegt.
<- bla -X
Ein Anruf wurde angenommen und ist bereits beendet.

Wem diese Notation nicht gefällt, der kann sie in der Datei MsgTyp.py ändern.


Das Menü des CallMon-Clients

Kontextmenü

Der oberste Punkt im Menü "Nummer (ext) in die Zwischenablage" kopiert (wie der Name vermuten läßt) die externe Telefonnummer der selektierten Zeile in die Zwischenablage des Betriebssystems.

Nach Auswahl von "Nummer (ext) oder Name (ext) suchen" wird zunächst in einem Popup-Fenster der Suchbegriff abgefragt, der in den Spalten "Nummer (ext)" und "Name (ext)" in der Datenbank-Tabelle mit den beendeten Gesprächen gesucht werden soll. Dieser Suchbegriff darf die Zeichen "_" und "%" als Joker verwenden. Wobei "_" für genau ein beliebiges Zeichen und "%" für kein oder beliebig viele beliebige Zeichen steht. Zwischen Groß- und Kleinbuchstaben wird (außer bei Umlauten) nicht unterschieden. Danach werden die 100 jüngsten, auf den Suchbegriff passenden Sätze im Dialog-Fenster "Gesprächshistorie" (s.u.) angezeigt.

Die Funktion des Menüpunktes "Telefonbuch von Fritzbox einlesen" wurde oben schon erläutert.

Mit "Einstellungen" wird das Setup-Fenster (s.o.) geöffnet.

Bei Auswahl von "Spalten anzeigen/verbergen" öffnet sich ein weiteres Menü, in dem die Spalten an- oder ausgeschaltet werden können. Soll die Spalte auch nach einem Neustart des Programmes weiterhin an- oder ausgeschaltet bleiben, ist nach der Änderung noch die nächste Menü-Option "Fensterdaten speichern" auszuwählen.

Mit "Fensterdaten speichern" wird die aktuelle Position des CallMon-Client-Fensters, dessen Größe und die jeweilige Breite und Sichtbarkeit aller Spalten gespeichert, um sie beim nächsten Start des Programmes wieder genauso einstellen zu können.

Bei der Auswahl von "Über CallMon-Client" öffnet sich ein kleines Fenster mit Lizenz und Versionsnummer des Programms.


Zwei weitere Features bietet der CallMon-Client abseits des Menüs.
Zum einen kann die Sortierung der Spalten dadurch geändert werden, dass mit der Maus die jeweilige Spalten-Überschrift angeklickt wird. Einmal Klicken sortiert in die eine Richtung, nochmal die selbe Spalte angeklickt sortiert andersrum.

Und bei Doppelklick auf einer Zeile öffnet sich das Fenster "Gesprächshistorie", in dem die maximal 100 letzten Telefonate mit der externen Telefonnummer angezeigt werden, die in der doppelgeklickten Zeile steht.
Fenster Historie


Weitere Optionen im Setup-Dialog

Neben den Daten des CallMon-Servers können im Setup-Dialog noch folgende Einstellungen vorgenommen werden:
Die eigenen externen Telefonnummern stehen üblicherweise nicht im Telefonbuch der Fritzbox.
Daher wird der Inhalt der Spalte "Nummer (int)" auch gar nicht gegen das Telefonbuch geprüft. Um in dieser Spalte trotzdem Namen statt Nummern anzuzeigen, können diese Aliasse verwendet werden. Sie werden ebenfalls in die Spalte "Name (ext)" eingesetzt - auch dann, wenn dort bereits über das Telefonbuch ein Name gefunden wurde.
Alias-Telefonnummern aus dem eigenen Ortsnetz können mit oder ohne Vorwahl eingegeben werden. Das Programm erzeugt intern einen weiteren Alias ohne bzw. mit Ortsvorwahl.



Service-Tools

Im callmon-Verzeichnis befinden sich zwei Dateien, mit denen auf Server-Seite administrative Tätigkeiten durchgeführt werden können.

Mit der Datei exportFinishedCallsFromDB.py kann der gesamte Inhalt der Tabelle mit den beendeten Telefonaten im csv-Format auf dem Terminal ausgegeben werden - oder die Ausgabe in eine Datei umgeleitet werden. Die Terminal-Ausgabe ist dann sehr praktisch, wenn man von Ferne bzw. per ssh-Session z.B. die verpassten Telefonate sehen möchte. In diesem Fall sollte dem Befehl sinnigerweise ein  |less  oder auch ein  |head -n 20  angehängt werden.

Mit der Datei deleteFinishedCallsFromDB.py können beendete Telefonate aus der Datenbank gelöscht werden. Die zu löschenden Telefonate können entweder über ihr relatives Alter zum Tagesdatum oder über das absolute Datum des Telefonates (Jahr und Monat) vorgegeben werden. Bei Aufruf ohne Parameter wird eine Hilfe-Seite angezeigt, die auch Beispiele enthält.