Seite 1 von 2

Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 15. Okt 2020 17:20
von DrJJ
Ich wollte im Openhab eine schöne Tabelle mit einer Anrufliste aus meiner Fritzbox die unbekannte Rufnummern per dasoertliche auflöst und bei Anrufen in Abwesenheit mich per Pushover informiert.

Im Netz habe ich zwar schöne Anleitungen und Möglichkeiten gefunden aber keine erfüllte meine Anforderungen. Da ich etwas PHP Programmieren kann habe ich mir ein eigenes Script erstellt was genau meine Wünsche erfüllt und eine HTML Datei erstellt die ich per Webview einbinden kann.

Voraussetzung ist, dass auf dem Gerät wo Openhab läuft auch PHP installiert ist.

Hier mein Script welches unter /etc/openhab2/scripts/fritzbox.php abgelegt wird

Code: Alles auswählen

<?php
/**
 * Skript welches von der Fritzbox die Callliste lädt und eine HTML Datei erstellt
 * die in Openhab als Webview eingebunden werden kann.
 * 
 * Zusätzlich werden Telefonnummern die nicht über das Fritztelefonbuch aufgelöst werden über dasoertliche.de aufgelöst
 * Diese Anfragen werden in einer Cache Datei zwischengespeichert um mehrfach abfragen der gleichen Nr zu unterbinden.
 * 
 * Einstellungen ab hier anpassen:
 */
// Url zur Fritzbox
$fb_url = 'http://172.16.10.2:49000';
// Benutzer für Fritzbox
$fb_user = 'openhab';
// Passwort für Fritzbox
$fb_pass = 'openhabpw';
// Anzahl der Anrufe die dargestellt werden sollen
$rows_cl = 6;

// Speicherort für Cache File
$call_cache = '/etc/openhab2/scripts/CacheReverseCallSearch.txt';
// Speicherort für HTML Datei die erstellt wird
$html_file = '/etc/openhab2/html/fb_calls.html';

// Datei die als Template zum erstellen der HTML Datei dient
$html_tmpl = '/etc/openhab2/html/fb_list.tmpl.html';
// Datei die als Template für eine Telefonzeile dient
$item_tpl = '/etc/openhab2/html/fb_item.tmpl.html';

// Icons für die Unterschiedlichen Calls als html
$icons['1'] = '<svg viewBox="0 0 100 100"><use xlink:href="/static/fritzbox.svg#phone-in_100"></use></svg>';
// 2 missed
$icons['2'] = '<svg viewBox="0 0 100 100"><use xlink:href="/static/fritzbox.svg#phone-missed_100"></use></svg>';
// 3 outgoing
$icons['3'] = '<svg viewBox="0 0 100 100"><use xlink:href="/static/fritzbox.svg#phone-out_100"></use></svg>';
// 9 active incoming
$icons['9'] = '';
// 10 rejected incoming
$icons['10'] = '';
// 11 active outgoing
$icons['11'] = '';

/**
 * Ende Einstellungen
 */
$calls = get_calls($fb_url, $fb_user, $fb_pass, $rows_cl);
$html = get_HTML($calls);
//Letzten Anruf ausgeben
$string = '{%TYPE%}|{%DATE%}|{%NAME%}|{%TEL%}';
echo parse_html($string, $calls[0]);

function get_calls($fb_url, $fb_user, $fb_pass, $rows_cl) {
    $client = new SoapClient(
            null,
            array(
        'location' => $fb_url . '/upnp/control/x_contact',
        'uri' => 'urn:dslforum-org:service:X_AVM-DE_OnTel:1',
        'noroot' => True,
        'login' => $fb_user,
        'password' => $fb_pass
            )
    );
    $result = $client->GetCallList();
    $xml = @simplexml_load_file($result);
    $i = 0;
    foreach ($xml->children() as $child) {
        if ($child->Id) {
            $list[$i] = (array) $child;
            //Löschen unnötige Einträge
            unset($list[$i]['Device']);
            unset($list[$i]['Count']);
            unset($list[$i]['Path']);
            if (strpos($list[$i]['Name'], $list[$i]['Caller']) !== false) {
                $list[$i]['Name'] = getDasOertliche($list[$i]['Caller']);
            }
            if ($list[$i]['Type'] == 3) {
                $list[$i]['Tel'] = $list[$i]['Called'];
            } else {
                $list[$i]['Tel'] = $list[$i]['Caller'];
            }
            $i++;
            if ($i == $rows_cl)
                break;
        }
    }
    return $list;
}

/**
 * Suche im dasoertliche nach dem Anrufer
 * wenn kein Treffer gefunden wurde, wird Unbekannt zurückgegeben.
 *
 * @param string Telefonnummer
 * @return string Anrufer
 */
function getDasOertliche($number) {
    global $call_cache;
    //im Cache suchen
    $cache = file($call_cache);
    foreach ($cache as $line) {
        // prüfen ob die Nummer in der Zeile gefunden wird
        if (strpos($line, $number) !== false) {
            $match = explode("|", $line);
            return $match[1];
        }
    }
    $url = "https://www.dasoertliche.de/Controller?form_name=search_inv&ph=" . $number;
    $page = file_get_contents($url);
    if (preg_match('/<span class="st-treff-name">(.*?)<\/span>/', $page, $match) == 1) {
        file_put_contents($call_cache, PHP_EOL . $number . "|" . $match[1], FILE_APPEND);
        return $match[1];
    } else {
        return 'Unbekannt';
    }
}

/**
 * Erstellt und speichert die HTML Datei
 *
 * @param array Liste der Anrufe
 */
function get_HTML($calls) {
    global $html_tmpl, $item_tpl, $icons, $html_file;
    $tmpl = file_get_contents($html_tmpl);
    $tmpl_item = file_get_contents($item_tpl);
    $items = '';
    foreach ($calls as $line) {
        $line['icon'] = $icons [$line['Type']];
        $items .= parse_html($tmpl_item, $line);
    }
    $out = parse_html($tmpl, array('callist' => $items));
    file_put_contents($html_file, $out);
}

function parse_html($html, $args) {
    foreach ($args as $key => $val) {
        $html = str_replace("{%" . strtoupper($key) . "%}", $val, $html);
    }
    return $html;
}


Datei für Template: /etc/openhab2/html/fb_list.tmpl.html

Code: Alles auswählen

<!doctype html>
<html>

<head>
    <title>Anrufliste</title>
    <link rel="manifest" href="/basicui/manifest.json">
    <link rel="stylesheet" type="text/css" href="/basicui/mdl/material.min.css" />
    <link rel="stylesheet" type="text/css" href="/basicui/material-icons.css" />
    <link rel="stylesheet" type="text/css" href="/basicui/roboto.css" />
    <link rel="stylesheet" type="text/css" href="/basicui/smarthome.css" />
    <style>
        body {
            background-color: white !important;
        }

        table {
            margin-left: auto;
            margin-right: auto;
            border-collapse: collapse;
            width: 98%;
        }

        th,
        td {
            border-bottom: 1px solid #ccc;
            text-align: left;
            color: var(--container-text-color, #616161) !important;
        }

        svg {
            height: 32px;
            width: 32px;
        }
    </style>
</head>

<body>
    <table>
        <tr>
            <th>Typ</th>
            <th>Datum</th>
            <th>Name</th>
            <th>Nummer</th>
            <th>Dauer</th>
        </tr>
        {%CALLIST%}
    </table>
</body>

</html>
Datei für /etc/openhab2/html/fb_item.tmpl.html

Code: Alles auswählen

<tr>
    <td>{%ICON%}</td>
    <td>{%DATE%}</td>
    <td>{%NAME%}</td>
    <td>{%TEL%}</td>
    <td>{%DURATION%}</td>
</tr>
Meine Rule die alles Steuert:

Code: Alles auswählen

rule "Anrufliste"
when
   Item fboxIncomingCall changed or
   Item fboxOutgoingCall changed 
then
   if ((fboxIncomingCall.state.toString == ",") && (fboxOutgoingCall.state.toString == ",") && (previousState.toString != ",")) {
      Thread::sleep(3000) //Zeit für die Fritzbox zum updaten der XML
      val output = executeCommandLine("php /etc/openhab2/scripts/fritzbox.php", 30000)
      //Format Antwort: Type|Datum|Name|Tel
      var CallData = output.toString.split('\\|')
      if (CallData.get(0) == "2") {
        sendPushoverMessage(pushoverBuilder("Anruf verpasst von: "+ CallData.get(2) +" Tel: "+ CallData.get(3)).withTitle("Telefon"))
      }
   }
end
In der Sitemap:

Code: Alles auswählen

Frame label="Anrufliste" { 
		Webview url="/static/fb_calls.html" height=7 icon=none
	}
Falls jemand es Testet und Verbesserungen sieht gerne melden.

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 15. Okt 2020 20:57
von udo1toni
Sehr schick! Vielen Dank dafür!

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 14. Nov 2020 17:17
von Hoggle
Hallo DrJJ.
Kurze Frage, da PHP für mich so ist, als wenn es da in chinesisch stehen würde: wird die fb_calls.html automatisch angelegt, also über das PHP-Script, oder muß ich die anlegen und noch mit content füllen?
Bei mir stand erst ein Fehler (File not found) und nachdem ich eine leere fb_calls.html angelegt hatte, ist der Bereich leer.
Anbei ein kleines "Bildchen"
Anrufliste.png
Was kann ich tun?

Müssen die items als dummy angelegt werden?

php7.3 ist installiert.

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 17. Nov 2020 09:21
von DrJJ
Die HTML Datei wird in der Regel angelegt, ich denke der Benutzer unter dem dein Openhab läuft hat keine schreibrechte auf die Datei.

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 25. Nov 2020 16:58
von MGI
Hallo Zusammen

versuche aktuell auch die Telefonliste zum Laufen zu bekommen. Habe allerdings das gleiche Problem. ANgenommen es ist wirklich ein Berechtigungsproblem (nutze ebenfalls openhabian), was wäre denn der richtige Weg das zu fixen?

Danke im Voraus
Michael

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 22. Dez 2020 14:12
von DrJJ
ich habe der Datei per Winscp die Berechtigung 777 gegeben, damit darf alles und jeder diese ändern.

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 22. Dez 2020 20:15
von steinadler
hi
leider bei mir auch keinen erfolg
datei wird nicht vom programm angelegt
alle berechtigung auf 777 gesetzt, überprüft, stehen auch
manuell die datei angelegt, bleibt leer(aber erscheint)

selbst neuen benutzer angelegt, ordner(mit inhalt) übergeben, attribute auf 777, brachte alles keinen erfolg
könntest du nochmal helfen ???
danke schon im vorraus...

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 22. Dez 2020 20:59
von DrJJ
Wenn du in einer Console direkt den Befehl: php /etc/openhab2/scripts/fritzbox.php ausführst was wird dir da angezeigt? Kommen da irgendwelche Fehler?

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 23. Dez 2020 07:50
von steinadler
hi
meine fehlermeldung

[07:48:26] openhabian@openhab:~$ php /etc/openhab2/scripts/fritzbox.php
PHP Fatal error: Uncaught Error: Call to undefined function simplexml_load_file() in /etc/openhab2/scripts/fritzbox.php:65
Stack trace:
#0 /etc/openhab2/scripts/fritzbox.php(47): get_calls('http://192.168....', 'openhabian', 'xxxxxxx', 6)
#1 {main}
thrown in /etc/openhab2/scripts/fritzbox.php on line 65

dann den port geändert in 49443

PHP Fatal error: Uncaught SoapFault exception: [HTTP] Error Fetching http headers in /etc/openhab2/scripts/fritzbox.php:65
Stack trace:
#0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'http://192.168....', 'urn:dslforum-or...', 1, 0)
#1 /etc/openhab2/scripts/fritzbox.php(65): SoapClient->__call('GetCallList', Array)
#2 /etc/openhab2/scripts/fritzbox.php(48): get_calls('http://192.168....', 'openhabian', 'xxxxxxx', 6)
#3 {main}
thrown in /etc/openhab2/scripts/fritzbox.php on line 65

die datei kann nicht angelegt werden(port wieder zurückgestellt, war nur ein versuch)

Re: Fritzbox Anrufliste mit online Rufnummerabfrage

Verfasst: 23. Dez 2020 10:05
von DrJJ
Dir fehlen die PHP Module für XML und Soap, diese kannst du mit folgendem Befehl installieren.

sudo apt-get install php-xml php-soap