Hi all,
just wanted to make a short tutorial about my fritzbox call overview i presented few months ago:
So all the magic is done by this things:
- A script downloading the latest information from your fritzbox
- A rule triggering the script as often as you want
- A html page with a bit of javascript code which transforms the data in a webpage
- A simple habpanel template widget which displays the html page
1. The script downloading the information from your fritzbox
This script is a mixture of some scripts I found.
All in all it requests a challenge from the fritzbox so you can get an SID, which is necessary to download the calllist information in .csv format.
I placed it here: openhabfolder/conf/scripts
!/bin/sh -x
IP="fritz.box"
UID="YOURFRITZBOXNAME"
SECRET="YOURPASSWORD"
# Challenge abholen
CHALLENGE=`wget -O - "http://$IP/login_sid.lua" 2>/dev/null | sed 's/.*<Challenge>\(.*\)<\/Challenge>.*/\1/'`
# login aufbauen und hashen
CPSTR="$CHALLENGE-$SECRET"
MD5=`echo -n $CPSTR | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}'`
RESPONSE="$CHALLENGE-$MD5"
URL_PARAMS="username=$UID&response=$RESPONSE"
# login senden und SID herausfischen
SID=`wget -O - "http://$IP/login_sid.lua?$URL_PARAMS" 2>/dev/null | sed 's/.*<SID>\(.*\)<\/SID>.*/\1/'`
echo SID=$SID
echo TEMP = "http://$IP/fon_num/foncalls_list.lua?sid=$SID&csv="
wget -O /your/path/where/the/file/should/be/saved/name_of_file.txt "http://$IP/fon_num/foncalls_list.lua?sid=$SID&csv="
- The rule triggering the script
In this case I created a rule, which executes the download script every minute
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.scripts.actions.*
rule "update calllist"
when
Time cron "0 0/3 * * * ?" //every minute
then
logInfo("Fritzbox"," Calllist wird neu geladen")
executeCommandLine("sudo /path/to/your/script/name_of_your_script.sh")
end
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CallList</title>
<style>
.call-table {
font-family: Segoe UI;
-webkit-font-smoothing: antialiased;
font-size: 100%;
width: auto;
overflow: auto;
display: block;
border-collapse: collapse;
width: 100%;
}
.call-table th
{
background-color: transparent;
font-weight: normal;
color: white;
padding: 5px 30px;
text-align: center;
font-size: 115%;
}
.call-table td
{
background-color: transparent;
padding: 5px 5px;
color: white;
text-align:center;
}
.call-table tr {
border-bottom: 1px solid white;
}
</style>
<script language="javascript" type="text/javascript" src="jquery-3.1.1.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function ()
{
read();
});
function read()
{
//Getting the downloaded txt-file from the fritzbox
//Adapt the path to match your requirements
xmlHttp = new window.XMLHttpRequest();
xmlHttp.open("GET", "../relative/path/to/your/file/you/downloaded/name_of_your_file.txt", false);
xmlHttp.send(null);
xmlDoc = xmlHttp.response;
var calls = new Array();
var lines = xmlDoc.split('\n');
//read each line
//for(var i = lines.length - 1;i >= 0;i--)
for(var i = 0; i < lines.length; i++)
{
if(lines[i])
{
console.log("->" + lines[i]);
//split the string by ;
singleValues = lines[i].split(";");
//to skip the first lines (header) we ignore every line not beginning with a number
if(!isNaN(singleValues[0]))
{
//Loggings
/*console.log(singleValues[0]); //CallType
console.log(singleValues[1]); //Date
console.log(singleValues[2]); //ResolvedCallerName (if known)
console.log(singleValues[3]); //Called number or calling number
console.log(singleValues[4]); //*Nebenstelle*?!
console.log(singleValues[5]); //Called Number (If you have more than one phone number activated you can see which one was called or was calling)
console.log(singleValues[6]); //Duration
*/
//create a call-object
var call = new Object();
call.calltype = singleValues[0];
call.date = singleValues[1];
call.resolvedname = singleValues[2];
call.externnumber = singleValues[3];
call.nebenstelle = singleValues[4];
call.internnumber = singleValues[5];
call.duration = singleValues[6];
//add single call to array
calls.push(call);
}
}
}
var jsonArray = JSON.parse(JSON.stringify(calls))
createTable(jsonArray);
}
//Creates the html table with the content
function createTable(json)
{
//config
var myNumber = 123456; //at our home we use two different phone numbers. I just want to have my calls displayed. Therefore I'll filter for this number
//in case you don't want to filter don't use it or insert a number which does not exist
//consts
var trstart = "<tr>";
var trend = "</tr>"
//Every call in the json object
$.each(json, function (index, value)
{
//checking if the number is the one you want the data is filtered for
//if you don't want to filter please delete the following 2 lines
if (value.internnumber.indexOf(myNumber) == -1)
return;
var calltype = createTableCell("calltype", value.calltype);
var date = createTableCell("date", value.date);
var resolvedname = createTableCell("resolvedname", value.resolvedname);
var externnumber = createTableCell("externnumber", value.externnumber);
var nebenstelle = createTableCell("nebenstelle", value.nebenstelle);
var internnumber = createTableCell("internnumber", value.internnumber);
internnumber = internnumber.replace("Internet: ", "");
var duration = createTableCell("duration", value.duration);
//Icon
if (value.calltype == "1") //Type 1 = Eingehender Anruf
calltype = createTableCell("calltype", '<img src="callin.gif" />');
else if (value.calltype == "2") //Type 2 = Nicht angenommener eingehender Anruf
calltype = createTableCell("calltype", '<img src="callinfailed.gif" />');
else if (value.calltype == "4") //Type 4 = Ausgehender Anruf
calltype = createTableCell("calltype", '<img src="callout.gif" />');
//Add the concatenated string at the end of our table
$('#call-table tr:last').after(trstart + calltype + date + resolvedname + externnumber + nebenstelle + internnumber + duration + trend);
});
}
//returns a table cell (td) with css class and content. cssclass if you want to customize your table
function createTableCell(cssclass, content)
{
if(cssclass)
{
return "<td class=\"" + cssclass + "\">" +
content +
"</td>";
}
return "<td>" +
content +
"</td>";
}
</script>
</head>
<body>
<table id="call-table" class="call-table">
<thead>
<th></th>
<th>Datum</th>
<th>Name</th>
<th>Rufnummer</th>
<th>Nebenstelle</th>
<th>Eigene Rufnummer</th>
<th>Dauer</th>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>
3.The showed html page takes the downloaded data and transforms it to a html layout. At this point you can do better than me and make a prettier layout. I’m curious. Place it in the html folder under conf:
openhabfolder/conf/html
-I use jQuery (v 3.1.1). So please locate an appropriate file in the same folder. Find a version on jQuery Core – All Versions | jQuery CDN
-Sorry for the css in the same file
-Sorry for the bad code
- Create a template widget in habpanel, referring the created html page
<div>
<iframe style=" width: 100%;height: 500px;" src="static/path/to/your/html/page.html">
</iframe>
</div>
I hope the instructions are complete and everyone who is interested can rebuild this little helper.
If not I’m willing to do my best to help you
(Sorry for the bad formatting. Between 3. and 4. there is a little formatting problem )