Fritzbox Binding (TR064) - getting (and staying) last caller in openHAB

I know, there are a few threads concerning this topic, but as they are shattered across the forum and time, I guess it’s best to consolidate the information floating around.

At first, please see the documentation of the binding itself:
https://docs.openhab.org/addons/bindings/fritzboxtr0641/readme.html

I figured, my Fritz!Box 6360 Cable (v06.54) didn’t give out all the information, which is described in the binding (e.g. all the “DSL Statistics” and the “WanIP”), which is fine as it is a cable router and not a DSL router - and I’m not so sure, what all those statistics are worth doing something with them… :wink:

What I did encounter is what I like to do with the Call Monitor. I’d like to have a “lastCaller” item, which I can use to display or to send notifications with. But there are two obstacles here

  1. the callmonitor_ringing item is only active while the call is active and Returns a blank, when the caller hung up
  2. the information for Call Monitor Comes with the (undocumented?) itemtype Call.

So to have the last caller Handy within OH2 after the caller hung up, you have to create an proxy item for it, which is filled, when the call is active. and for the second you have to extract the information.

So, this is my fritzbox.items:

/* Call Monitor */
Switch  Fritz_Ringing	"eingehender Anruf [%s]"		{fritzboxtr064="callmonitor_ringing" }
Switch  Fritz_RingOut	"ausgehender Anruf [%s]"		{fritzboxtr064="callmonitor_outgoing" }
Call    Fritz_Incoming	"eingehende Nummer: [%1$s to %2$s]"	{fritzboxtr064="callmonitor_ringing" } 
Call    Fritz_Outgoing	"ausgehende Nummer: [%1$s to %2$s]"	{fritzboxtr064="callmonitor_outgoing" }
Call    Fritz_IncomingResolved	"eingehender Anrufe: [%1$s to %2$s]" {fritzboxtr064="callmonitor_ringing:resolveName" } 

// last Call items
Number  Fritz_MissedCalls		"Anrufe in Abwesenheit [%s]"		{fritzboxtr064="missedCallsInDays:5"}
String  Fritz_LastIncoming		"letzter eingehender Anruf [%s]"	
String  Fritz_LastIncomingDest		"letzter Anruf an [%s]"		
String  Fritz_LastIncomingResolved	"letzter eingehender Anrufer [%s]"

now to the fritzbox.rules

rule "Telefon klingelt"
when
    Item Fritz_Ringing changed to ON 
then
	/* read out CallType */
	val TmpCall = Fritz_Incoming.state as StringListType 		// change Call Itemtype for numbers only
	val CallerNumber = TmpCall.getValue(1) 				// Number of Caller is Value 1
	val CallTo = TmpCall.getValue(0) 				// internal number called (useful, if you have more than one number)
	val TmpCall2 = Fritz_IncomingResolved.state as StringListType	// Change Call Itemtype for resolved name from phonebook
	val CallerName = TmpCall2.getValue(1)				// This is the equivalent name from the phonebook (or again the caller number if nomatch)
	var String CallToName = "-"					// prepare the name of the caller
	
	// who was called
	if (CallTo == "12345") { CallToName = "xxx" }		// first number
	if (CallTo == "67890") { CallToName = "yyy" }		// second number
	Fritz_LastIncomingDest.sendCommand(CallToName)		// Name of number called 
	
	// If entry was not found in phonebook - shorten CallerName
	if(CallerName.startsWith("Name not found for")) {
		// fill the name with unknown
		CallerName = "unknown"
	}
	// Update the proxy items
	Fritz_LastIncoming.sendCommand(CallerNumber)
	Fritz_LastIncomingResolved.sendCommand(CallerName)

	var String text = "call saved: " + CallerNumber + " (" + CallerName + ")" + " to " + CallToName + "."
	logInfo("Fritz Call", "Fritz!Box says: "+text)
end

rule "verpasster Anruf"
when
    Item Fritz_MissedCalls changed  // if you didnt pick up, the missedcall item will increment
then
	// log the entry
	var String text = Fritz_LastIncomingDest.state + ": Missed Call from " + Fritz_LastIncomingResolved.state + ", " + Fritz_LastIncoming.state
	logInfo("Fritz Call", "Fritz!Box says: "+text)
end
2 Likes

note:
As I didn’t find a decent documentation on “StringListType”, which was the only itemtype I could attach the Call-type to, I don’t know how to avoid an ERROR, if the caller used CLIR (Calling Line Identification Restriction), meaning she isn’t presenting her number. So getValue(1) will fail, because there’s only one list… If someone knows how to Count the values in StringListType we can avoid this error.

Nice tutorial! Is there a reason why you use “sendCommand” and not “postUpdate” to update your proxy items?

Cheers,
Bernd

first reason: I’m used to it! :wink:
and yes, basically it won’t matter, because my proxy items aren’t bound to some external hardware (binding). so postUpdate would also do.
I don’t know, if you’re familiar with the difference, but yes, simplified:

  • sendCommand: not only the item, but the binding gets the command
  • postUpdate: the item gets updated without telling the binding explicitly

I think, it’s explained in a bit more detail here:

Really nice tutorial. Many thanks!

Do you know if there are any requirements to the entries in the address book of the FB in order to resolve phone numbers to names? I mean, does it only work with local entries, or also with entries from google address book which is connected to the FB? Can it be each number (mobile, home, business) of an entry or has it to be any particular one? What about the format? Is a country prefix (+49, 0049) required or not?

Best Regards
Matthias

Just a small hint, if you have problems with unknown callers and handling of the StringListType. With missing caller number, the List contains only one item. As far as I can see it is not possible to find out how many elements the list contains. So I did the following:

try {
	callerNumber = incCall.getValue(1)
		if (!incCallResolved.getValue(1).startsWith("Name not found for")) {
			callerName = incCallResolved.getValue(1)
		}      	
} catch (IllegalArgumentException e) {
	logDebug ("Telefon", "Keine Rufnummer übermittelt.")
}

There will be a real fix https://github.com/eclipse/smarthome/pull/5994

What about persistence with mapdb? I use Openhab 2.4. When i try activate it, i get error messages in the log and after the restart the values are null:

2019-02-16 10:41:59.867 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model ‘mapdb.persist’
2019-02-16 10:41:59.888 [ERROR] [pse.smarthome.core.items.GenericItem] - Tried to set invalid state null#null (StringType) on item Fritz_IncomingResolved of type CallItem, ignoring it

How can i save the last value?

Thank you.

Best regards

Michael