Hi, thank you for that tutorial and all your work!
I changed the script for me to use items (updated via REST api). By that, I do not need the extra html file and also not the habpanel-reload.js for the reload. And for me it get’s easier to understand what happens
Another advantage (and the reason I changed it) is that I can use my standard widget with 4 rows, which you can see here:
New messages are shown by a blinking icon, playback works and after playing, the icon stops blinking and gets grey.
I only want to show the missed calls and the recorded messages (the last 4 events).
Here are the items:
String AbMessage
Call fboxIncomingCall "Incoming call: [%1$s to %2$s]" {fritzboxtr064="callmonitor_ringing" }
Call fboxOutgoingCall "Outgoing call: [%1$s to %2$s]" {fritzboxtr064="callmonitor_outgoing" }
String Anruf_1_Name "Anruf 1 Name [%s]"
String Anruf_2_Name "Anruf 2 Name [%s]"
String Anruf_3_Name "Anruf 3 Name [%s]"
String Anruf_4_Name "Anruf 4 Name [%s]"
String Anruf_1_DatumZeit "Anruf 1 Zeit [%s]"
String Anruf_2_DatumZeit "Anruf 2 Zeit [%s]"
String Anruf_3_DatumZeit "Anruf 3 Zeit [%s]"
String Anruf_4_DatumZeit "Anruf 4 Zeit [%s]"
String Nachricht_1_Datei "Nachricht 1 Datei [%s]"
String Nachricht_2_Datei "Nachricht 2 Datei [%s]"
String Nachricht_3_Datei "Nachricht 3 Datei [%s]"
String Nachricht_4_Datei "Nachricht 4 Datei [%s]"
Switch Nachricht_1_Neu "Nachricht 1 Neu"
Switch Nachricht_2_Neu "Nachricht 2 Neu"
Switch Nachricht_3_Neu "Nachricht 3 Neu"
Switch Nachricht_4_Neu "Nachricht 4 Neu"
Here’s the script:
#!/bin/bash
#
# Check and adapt the following environment variables to your needs:
# fritzbox URL for tr-064 calls
BASEURL="http://fritz.box:49000"
# user:password used to authenticate
USER="user:pw"
# openhab directory containing sounds subdirectory
OPENHAB_DIR=/etc/openhab2
# temporary directory
TMP=/tmp
# number of calls to show
COUNT=40
# number of answering machines
TAM_COUNT=1
### Function definitions ###
function getElement() {
text=$1
name=$2
echo "$text" | sed -e "s/.*<$name>//" -e "s#</$name>.*##"
}
function arrayContains() {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
function soapCall() {
URL=$1
URN=$2
ACTION=$3
ELEMENT=$4
PARAMETERS=${5:-}
cat >$TMP/soapEnvelope-$$ <<EOF
<?xml version='1.0' encoding='utf-8'?>
<s:Envelope s:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'>
<s:Body>
<u:$ACTION xmlns:u='$URN'>${PARAMETERS}</u:$ACTION>
</s:Body>
</s:Envelope>
EOF
RESPONSE=$(curl -s --anyauth --user $USER $URL -H 'Content-Type: text/xml; charset="utf-8"' -H "SoapAction:$URN#$ACTION" --data @$TMP/soapEnvelope-$$)
rm $TMP/soapEnvelope-$$
if [ "x${ELEMENT}x" != "xx" ]; then
echo $RESPONSE | grep $ELEMENT | sed -e "s/.*<$ELEMENT>//" -e "s#</$ELEMENT>.*##"
else
echo $RESPONSE
fi
}
function removeTamMessages() {
rm $TMP/tam${1:-[0-9]}.xml 2>/dev/null
}
function downloadMissingTamMessages() {
tamidx=0
while [ $tamidx -lt $TAM_COUNT ]; do
if [ ! -f $TMP/tam${tamidx}.xml ]; then
echo -n "downloading message list for TAM $tamidx..."
URL=$(soapCall "$BASEURL/upnp/control/x_tam" "urn:dslforum-org:service:X_AVM-DE_TAM:1" GetMessageList NewURL "<NewIndex>${tamidx}</NewIndex>")
wget --quiet -O - $URL | awk '/<Message>/,/<\/Message>/ { printf $0 } /<\/Message>/ { print }'>$TMP/tam${tamidx}.xml
echo "$(stat -c%s $TMP/tam${tamidx}.xml) bytes."
fi
tamidx=$(expr $tamidx + 1)
done
}
function getTamMsg() {
mdate=$1
for tamxml in $TMP/tam${2:-[0-9]}.xml; do
while read message; do
date=$(getElement "$message" Date)
if [ "${date}" == "${mdate}" ]; then
echo "$message"
return 0
fi
done < $tamxml
done
return 1
}
function updateCallOverview() {
downloadMissingTamMessages
URL=$(soapCall "$BASEURL/upnp/control/x_contact" "urn:dslforum-org:service:X_AVM-DE_OnTel:1" GetCallList NewCallListURL)
callidx=0
echo -n "downloading call list..."
wget --quiet -O - $URL | grep Call > $TMP/calls.xml
echo "$(stat -c%s $TMP/calls.xml) bytes."
zaehler=0
while read call; do
type=$(getElement "$call" Type)
caller=$(getElement "$call" Caller)
called=$(getElement "$call" Called)
name=$(getElement "$call" Name)
date=$(getElement "$call" Date)
duration=$(getElement "$call" Duration)
path=$(getElement "$call" Path)
message=$(getTamMsg "$date")
[ "x${message}x" != "xx" ] && isTamMsg=1 || isTamMsg=0
[ "x$(getElement "$message" New)x" == "x1x" ] && isNewTamMsg=1 || isNewTamMsg=0
echo "processing call $date (isTamMsg=$isTamMsg isNewTamMsg=$isNewTamMsg)..."
if [ "$path" == "$call" ]; then
path=""
# in case this call has no associated recording, check if there is a TAM message with the
# same time and skip this call
if [ $isTamMsg -eq 1 ]; then
echo "skipped (also has a TAM message)."
continue
fi
else
soundfile=${OPENHAB_DIR}/sounds/`basename $path`.wav
soundfilename=`basename $path`
# collect all current soundfiles to be able to delete the old ones
files[callidx]=$soundfile
if [ ! -f $soundfile ]; then
echo -n "fetching ${soundfile}..."
curl -o $soundfile "${BASEURL}$path&$SID"
echo "$(stat -c%s $soundfile) bytes."
fi
fi
# 1 incoming
# 2 missed
# 3 outgoing
# 9 active incoming
#10 rejected incoming
#11 active outgoing
if [ "x${path}x" != "xx" ]; then
zaehler=$((zaehler+1))
if [ $isNewTamMsg -eq 1 ]; then
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "ON" "http://openhabianpi:8080/rest/items/Nachricht_${zaehler}_Neu/state"
else
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "OFF" "http://openhabianpi:8080/rest/items/Nachricht_${zaehler}_Neu/state"
fi
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$soundfilename" "http://openhabianpi:8080/rest/items/Nachricht_${zaehler}_Datei/state"
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "${name:-$caller}" "http://openhabianpi:8080/rest/items/Anruf_${zaehler}_Name/state"
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$date" "http://openhabianpi:8080/rest/items/Anruf_${zaehler}_DatumZeit/state"
elif [ $type -eq 2 ]; then
zaehler=$((zaehler+1))
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "OFF" "http://openhabianpi:8080/rest/items/Nachricht_${zaehler}_Neu/state"
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "none" "http://openhabianpi:8080/rest/items/Nachricht_${zaehler}_Datei/state"
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "${name:-$caller}" "http://openhabianpi:8080/rest/items/Anruf_${zaehler}_Name/state"
curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$date" "http://openhabianpi:8080/rest/items/Anruf_${zaehler}_DatumZeit/state"
fi
callidx=$(expr $callidx + 1)
if [ $callidx -eq $COUNT ]; then
break
fi
if [ $zaehler -eq 4 ]; then
break
fi
done < $TMP/calls.xml
rm $TMP/calls.xml
echo $zeile
# remove old files
for file in ${OPENHAB_DIR}/sounds/rec.[0-9].[0-9][0-9][0-9].wav; do
arrayContains "$file" "${files[@]}"
if [ $? -ne 0 -a -f $file ]; then
rm ${file} 2>/dev/null
echo "removed old recording $file."
fi
done
}
function mark() {
file=${OPENHAB_DIR}/sounds/$1
tam=$(echo $1 | cut -d "." -f 2)
index=$(echo $1 | cut -d "." -f 3)
soapCall "$BASEURL/upnp/control/x_tam" "urn:dslforum-org:service:X_AVM-DE_TAM:1" MarkMessage dummy "<NewIndex>$tam</NewIndex><NewMessageIndex>$index</NewMessageIndex>"
}
### the fun starts here ###
source `dirname $0`/lockRoutines
exlock_now || exit 1
echo "lock obtained"
SID=$(soapCall "$BASEURL/upnp/control/deviceconfig" "urn:dslforum-org:service:DeviceConfig:1" "X_AVM-DE_CreateUrlSID" NewX_AVM-DE_UrlSID)
removeTamMessages
if [ $# -eq 1 -a "$1" == "update" ]; then
updateCallOverview
elif [ $# -eq 2 -a "$1" == "mark" ]; then
mark $2
updateCallOverview
else
echo "`basename $0` update | mark <file>"
exit 1
fi
removeTamMessages
And I needed to change the “play recorded call” rule:
rule "Play recorded call"
when
Item AbMessage received command
then
if (receivedCommand.toString == "1") {
playSound(Nachricht_1_Datei.toString)
executeCommandLine("/etc/openhab2/scripts/fritzbox.sh mark " + Nachricht_1_Datei.toString)
}
if (receivedCommand.toString == "2") {
playSound(Nachricht_2_Datei.toString)
executeCommandLine("/etc/openhab2/scripts/fritzbox.sh mark " + Nachricht_2_Datei.toString)
}
if (receivedCommand.toString == "3") {
playSound(Nachricht_3_Datei.toString)
executeCommandLine("/etc/openhab2/scripts/fritzbox.sh mark " + Nachricht_3_Datei.toString)
}
if (receivedCommand.toString == "4") {
playSound(Nachricht_4_Datei.toString)
executeCommandLine("/etc/openhab2/scripts/fritzbox.sh mark " + Nachricht_4_Datei.toString)
}
end
And the items are shown in a widget:
anrufe.widget.json (4.5 KB)
(preview please see my first link in this post)
Maybe that helps one of you… Have fun