MagentaTV Binding for Deutsche Telekom MR 4xx

please check the /etc/hosts file if it contains an entry for Diskstation

what’s the address 10.8.0.1? Does the system has a vpn connection (tun0)?

I did implement some more error checking.

#!/bin/bash
# requires "curl jq" - https://stedolan.github.io/jq/

USER_AGENT="Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 (400962928)"
UUID=$(uuidgen | tr "A-Z" "a-z")
CNONCE=$(echo -n $UUID | md5sum)
DEBUG=1


urlencode() {
	# https://gist.github.com/cdown/1163649
	local LANG=C i c e=''
	for ((i=0;i<${#1};i++)); do
                c=${1:$i:1}
		[[ "$c" =~ [a-zA-Z0-9\.\~\_\-] ]] || printf -v c '%%%02X' "'$c"
                e+="$c"
	done
        echo "$e"
}

function host_part() {
	host=`echo $1 | awk -F/ '{print $3}'`
}

function fail() {
	echo "*******************"
	echo $1
	echo "*******************"
	echo "Usage: $0 <Benutzername> <Passwort>"
	exit 1
}

function registerDeviceID() {
	local json msg

	msg="Registering DeviceID $UUID"
	printf "[?] $msg"

	APP_URL="https://slbedmfk11100.prod.sngtv.t-online.de:33428"
	host_part $APP_URL

	json=$(curl -L -b cookies.tmp -c cookies.tmp -s -H 'Cache-Control: no-cache' -H 'Host: '"$host"'' -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 (358080496)' -H 'Accept-Language: de-de' -H 'Accept: */*' --compressed ''"$APP_URL"'/EDS/JSON/Login?UserID=Guest')
	epghttpsurl=`echo $json | jq -r '.epghttpsurl'`

	host_part epghttpsurl
	json=$(curl -L -b cookies.tmp -c cookies.tmp -s -H 'Cache-Control: no-cache' -H 'Host: '"$host"'' -H 'Content-Type: text/plain;charset=UTF-8' -H 'Accept-Language: de-de' -H 'Accept: */*' -H 'User-Agent: '"$USER_AGENT"'' --data-binary '{"terminalid":"'"$UUID"'","mac":"'"$UUID"'","terminaltype":"Iphone","utcEnable":1,"timezone":"Europe/Berlin","userType":3,"terminalvendor":"iPhone5","osversion":"iOS10.3.3","softwareVersion":"2.3.10.26","terminalDetail":[{"key":"HardwareSupplier","value":"MyPhone"},{"key":"DeviceClass","value":"IPhone"},{"key":"DeviceStorage","value":"1"},{"key":"DeviceStorageSize","value":12475},{"key":"GUID","value":"'"$UUID"'"}],"connectType":1,"isFirst":true,"cnonce":"'"$CNONCE"'","preSharedKeyID":"NGTV000001"}' --compressed ''"$epghttpsurl"'/EPG/JSON/Authenticate?SID=firstup&T=Iphone')

	if [ $DEBUG == 1 ]; then
		echo
		echo $json | jq '.'
	fi

	printf "\r[+] $msg\n"
}

function gettingOAuthCredentials() {
	local json msg

	msg="Getting oAuthCredentials"
	printf "[?] $msg"

	APP_URL="https://slbedmfk11100.prod.sngtv.t-online.de:33428"
	host_part $APP_URL

	json=$(curl -L -b cookies.tmp -c cookies.tmp -H 'Cache-Control: no-cache' -H 'Host: '"$host"'' -H 'User-Agent: '"$USER_AGENT"'' -H 'Accept-Language: de-de' -H 'Accept: */*' -s --compressed ''"$APP_URL"'/EDS/JSON/Login?UserID=Guest')
	oAuthScope=`echo $json | jq -r '.sam3Para[] | select(.key|test("OAuthScope"))|.value'`
	oAuthService=`echo $json | jq -r '.sam3Para[] | select(.key|test("SAM3ServiceURL"))|.value'`
	oAuthClientSecret=`echo $json | jq -r '.sam3Para[] | select(.key|test("OAuthClientSecret"))|.value'`
	oAuthClientId=`echo $json | jq -r '.sam3Para[] | select(.key|test("OAuthClientId"))|.value'`
	epghttpsurl=`echo $json | jq -r '.epghttpsurl'`

	if [ $DEBUG == 1 ]; then
		echo
		echo $json | jq '.'
	fi

	if [ -z $oAuthScope ] || [ -z $oAuthService ] || [ -z $oAuthClientSecret ] || [ -z $oAuthClientId ]; then
		echo
		fail "Getting oAuth-Credentials failed!"
	fi

	printf "\r[+] $msg\n"

}


function gettingOAuthToken() {
	local json msg

	msg="Getting oAuthToken"
	printf "[?] $msg"

	host_part $oAuthService
	json=$(curl -b cookies.tmp -c cookies.tmp -H 'Cache-Control: no-cache' -H 'Host: '"$host"'' -H 'Accept-Language: de-de' -H 'Accept: */*' -H 'User-Agent: '"$USER_AGENT"'' -s --data "grant_type=password&username=$USERNAME&password=$PASSWORD&scope=$oAuthScope%20offline_access&client_id=$oAuthClientId&client_secret=$oAuthClientSecret&x_telekom.access_token.format=CompactToken&x_telekom.access_token.encoding=text%2Fbase64" --compressed ''"$oAuthService"'/oauth2/tokens')
	accessToken=`echo $json | jq -r '.access_token'`

	if [ $DEBUG == 1 ]; then
		echo
		echo $json | jq '.'
	fi

	if [ -z $accessToken ] || [ $accessToken == null ]; then
		echo
		fail "Getting oAuth-AccessToken failed!"
	fi

	printf "\r[+] $msg\n"
}


function authenticateDevice() {
	local json msg

	msg="Authenticate MobileDevice"
	printf "[?] $msg"

 	host_part $epghttpsurl

 	UUID=""
	json=$(curl -b cookies.tmp -c cookies.tmp -s -H 'Cache-Control: no-cache' -H 'Host: '"$host"'' -H 'Content-Type: text/plain;charset=UTF-8' -H 'Accept-Language: de-de' -H 'Accept: */*' -H 'User-Agent: '"$USER_AGENT"'' --data-binary '{"userType":1,"terminalid":"'"$UUID"'","mac":"'"$UUID"'","terminaltype":"Iphone","utcEnable":1,"timezone":"Europe/Berlin","terminalvendor":"iPhone5","osversion":"iOS10.3.3","softwareVersion":"2.3.10.26","terminalDetail":[{"key":"HardwareSupplier","value":"MyPhone"},{"key":"DeviceClass","value":"IPhone"},{"key":"DeviceStorage","value":"1"},{"key":"DeviceStorageSize","value":12475},{"key":"GUID","value":"'"$UUID"'"}],"connectType":1,"reconnect":true,"accessToken":"'"$accessToken"'","cnonce":"'"$CNONCE"'","caDeviceInfo":[{"caDeviceType":6,"caDeviceId":"'"$UUID"'"}],"preSharedKeyID":"NGTV000001"}' --compressed ''"$epghttpsurl"'/EPG/JSON/DTAuthenticate?SID=user&T=Iphone')
	userID=$(echo $json | jq -r '.userID')
	userIDMD5=$(echo -n $userID | md5sum | tr "a-z" "A-Z")

	if [ $DEBUG == 1 ]; then
		echo
		echo $json | jq '.'
	fi

	printf "\r[+] $msg\n"
}

#
# main:
#

USERNAME=$(urlencode $1)
PASSWORD=$(urlencode $2)

if [ -z $USERNAME ]; then
	fail "Bitte Benutzername eingeben!"
fi

if [ -z $PASSWORD ]; then
	fail "Bitte Passwort eingeben!"
fi


	echo
	echo
	echo Telekom Entertain UserID
	echo --------------------------------
	echo

	registerDeviceID
	gettingOAuthCredentials
	gettingOAuthToken
	authenticateDevice

	echo 
	echo --------------------------------
	echo

	echo "UserID: $userID"
	echo "UserID (MD5ed): $userIDMD5"
	echo

	rm cookies.tmp

@markus7017 weird is that in the last step “Authenticate MobileDevice” it is not producing any output in your test. Looks like the JSON request in that step is not send. If it would be there should at least be some output.

I added -v to the curl call and it shows a 404

> POST /EPG/JSON/DTAuthenticate?SID=user&T=Iphone HTTP/1.1
> Host: appepmfk20003.prod.sngtv.t-online.de:33207
> Accept-Encoding: deflate, gzip
> Content-Type: text/plain;charset=UTF-8
> Accept-Language: de-de
> Accept: */*
> User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 (400962928)
> Content-Length: 1010
> 
* upload completely sent off: 1010 out of 1010 bytes
< HTTP/1.1 404 Not Found
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Headers: accept, origin, content-type,Authorization,authorization,X_CSRFToken,*
< Access-Control-Allow-Methods: *
< Access-Control-Allow-Credentials: true
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 0
< Date: Sat, 13 Oct 2018 15:58:26 GMT
< 
* Curl_http_done: called premature == 0
* Connection #0 to host appepmfk20003.prod.sngtv.t-online.de left intact

Yes, the hosts file:

127.0.0.1   Diskstation
::1     Diskstation

I commented out the lines but still same error

2018-10-13 18:13:11.290 [ERROR] [ertaintv.internal.EntertainTVNetwork] - EntertainTV: Unable to get local IP / MAC address: Diskstation: Diskstation: Name or service not known!

after that I add the IP Adress to the hostname Diskstation

192.168.2.99 Diskstation

Now it worked! I can connect and control the Media Receiver!

The only thing that not is working is the “Power On” status. It always showed me that the receiver is “ON”. Is that normal?

yep, goog shot:+1:
for whatever reasons the jvm get local ip tries to resolve the hostname locally, which usually results in 127.0.0.1; so you replaced this with the correct ip

However, I’m looking for more stable way by processing the local interface list and getting the ip from there.

I’ve rewritten the initialization code and it runs on my system. However, I’m not able to produce a build

Disappointing, but first I need to get the dev environment running again - not the first time :frowning:

Even automatic travis builds are failing atm, so you are not alone with your issue.

You are right, the Power channel doesn’t toggles the receiver’s power as you might expect. Instead send the key “POWER” to the EntertainTV_Key channel. See my notes here: EntertainTV Binding

sit and wait :slight_smile:

@hmerk Did you tried the binding? As I remember you still have a MR400. Would be interesting to see if it’s still running. The version in the repo is ok to test.

@Mat_Ias did you saw my last reply indicating 404?

I am now sitting at my computer to change some openHAB stuff and try the binding.
Will post results later this evening.

@TF1rst Could you please try this version, it has a revised detection logic (filters tunnel interfaces, v6 addresses etc.).

Please note: that’s a 2.3 build, so you need to delete the 2.4 jar before placing the new one in the addons folder (my 2.4 build environment is massed up at the moment). Also remove the entry in /etc/hosts

org.openhab.binding.entertaintv-2.3.0-SNAPSHOT.jar.pdf (45.2 KB)

This version has also the fixed key codes.

Hello,

i have one MR400 and one MR401.

I am very interested at the binding.

If I can try the binding or can support, let me know.

With kind regards Tobias

Hi @ibot1989 , welcome to the club :slight_smile:

Please go ahead a give the last build (see abobe) a try. Start with 401 and the. 400. @hmerk reported problems that the send key doesn’t work. would be helpful if you could supply a direct comparable result.

I’m working on the next beta, which includes more key codes and event processing show title information etc., but the release posted above is good for the basic testing.

Hi, I have a new version ready to test.
https://github.com/markus7017/org.openhab.binding.entertaintv/blob/master/target/org.openhab.binding.entertaintv-2.4.0-SNAPSHOT.jar

To install the binding you need to remove the current thing and re-add it by running a new discovery. OH should keep the channel/item linkage.

It includes new channels, some of them are marked as advanced, you need to click on [Show More] to see them. The activation code property has been removed from the binding config (now computed automatically).

Most important: The binding listens to the stb events. So every time you switch the program or start a on-demand video the binding gets events and will update the channels.

The binding supplies channels for power, chan-up, chan-down, vol-up and vol-down. Those are simplifications instead of sending the appropriate key codes to the _Key item (e.g. “CHUP”). Once the switch is activated the binding sends the keycode and puts the switch back in the OFF position. Using the _Key channel provides access to all keys on the remote.

Please give it a try and provide feedback.

Hello Markus,

Can you build a version for OpenHAB 2.3?
I think the version 2.4-SNAPSHOT is not compatible with my 2.3 installation.

Edit: I will testing with the Version 2.3-SNAPSHOT in the posting two days ago and give feedback in the evening.

Hello,
Can someone tell me how I get to the “User ID”. Unfortunately, I have no FritzBox and with WireShark I get only a GET command. The POST command with the user ID is missing.
Thank you

you could use tcpdump to create the eth file, which then can get loaded in Wireshark
@Mat_Ias is working on an automation of that process (script for now, which then could be implemented in the binding)

@markus7017 Thanks for the info with the 404-error. I was unable to reproduce the error. I changed the script so that in debug-mode it outputs the POST-Payload in the last step “Authenticate MobileDevice”. Could you give it a try and send me the output of the last step, including the POST-Payload?

getEntertainTVUserID.sh.pdf (5.2 KB)

1 Like

@markus7017 I installed your updated version. How do I get to see the status informations like in your screenshot: “Description”, “Play mode” oder “Program”? I only the see the attached channels