MagentaTV Binding for Deutsche Telekom MR 4xx

making progress

In my case, the binding ist not working. I have a MR401B, UPNP is active but no things are created.
events.log:
2018-08-09 17:24:12.693 [INFO ] [tv.internal.EntertainTVNotifyServlet] - EntertainTV servlet started at ‘/entertaintv/notify’

Thats it.

image

Hi, sorry for the late reply. I hadn’t the time over the last weeks to work much on the binding,
Status is:

  • Discovery works for the old MR400 as well as the MR401B (UPnP) incl. reading the device information (http)
  • Pairing works (that’s where the servlet comes into the game)

I still habe problems to get the send-key function working (with uses various hashed codes), so you should be able to see the discovered devices in PaperUI, but the binding currently doesn’t provide the functionality to control the receiver.

Best regards, Markus

Hi Markus,

i have installed the binding org.openhab.binding.entertaintv-2.4.0-SNAPSHOT.

I have an Entertain MR401B receiver.

But i get an error:

2018-08-24 12:37:43.315 [INFO ] [tv.internal.EntertainTVConfiguration] - EntertainTV: Thing configuration: udn='Entertain', host='', Receiver='192.168.2.100':8081, MAC=; pairingCode='', userId='MyUserId', localIP='':'', localMAC=''
2018-08-24 12:37:43.341 [ERROR] [ertaintv.internal.EntertainTVNetwork] - EntertainTV: Unable to get local IP / MAC address: null!
2018-08-24 12:37:47.359 [ERROR] [tertaintv.handler.EntertainTVHandler] - EntertainTV: Device initialisation failed: Unable to initialize thing: class java.lang.Exception - Error sending HTTP GET http://192.168.2.100:49152/description.xmlfailed: connect timed out

This is strange, because I configurated the port to 8081, but the binding wants to connect to 49152.

Thanks for your time to make this!

PS: Maybe it is helpfull, I run openHAB on a synology NAS

Hi all, I did found some time to work on the binding and got the 1st version working

  • auto discovery (using UPnP)
  • pairing (with given userID)
  • send keys (a bunch are already defined, but not all are verified yet)

You still need to follow the instructions to discover userID (using Wireshark or tcpdum). I still couldn’t find out how this is computed (a hash of something).

@hmerk, @scha, @Norman_Sens, @TF1rst Please give it a try https://github.com/markus7017/org.openhab.binding.entertaintv/blob/master/target/org.openhab.binding.entertaintv-2.4.0-SNAPSHOT.jar

After copying the jar to the /addons you should get a new item in the Inbox. While adding the thing you will be prompted for the user id. Copy&paste the one you got from the wireshark trace. You should start having the receiver powered on, the thing should become online. Define an item for the sendKey, using the control panel you should be able to send keys like MENU, ChanUp, ChanDown.

In the thing configuration you could click on [Shore More], which gives you access to all discover attributes (some of them are very technical and will be hidden in upcoming versions).

I no longer have a MR400, so no clue if this one still works.

Happy to support. If you have problems set the debugging to TRACE and post the debug log

  • open OH console
  • enter “log:set TRACE org.openhab.binding.entertaintv”

Have fun.

2 Likes

Using HABpanel I was able to create a virtual remote. In addition I’m able to include comtrol with other scenes.

All the buttons send the approprivate value to EntertainTV_Key. The PIP selection list allows to switch channels using the digit keys (need to add support for chan > 9)

Those are the key values:

                <option value="POWER">POWER</option>
                <option value="MENU">Menu</option>
                <option value="INFO">Info</option>
                <option value="EPG">EPG</option>
                <option value="RADIO">Radio</option>
                <option value="MOVIE">Movies</option>
                <option value="MEDIA">Media</option>
                <option value="TTEXT">TeleText</option>
                <option value="TV">TV</option>
                <option value="0">0</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
                <option value="9">9</option>
                <option value="SPACE">|_|</option>
                <option value="OK">Ok</option>
                <option value="ENTER ">Enter</option>
                <option value="EXIT">Exit</option>
                <option value="DELETE">Delete</option>
                <option value="OPTION">Opt</option>
                <option value="UP">Up</option>
                <option value="DOWN">Down</option>
                <option value="LEFT">Left</option>
                <option value="RIGHT">Right</option>
                <option value="BACK">Back</option>
                <option value="NEXT">Next</option>
                <option value="VOLUP">VolUp</option>
                <option value="VOLDOWN">VolDown</option>
                <option value="MUTE">Mute</option>
                <option value="CHUP">ChanUp</option>
                <option value="CHDOWN">ChanDown</option>
                <option value="NEXTCH">ChanNext</option>
                <option value="LASTCH">ChanPrev</option>
                <option value="RED">redv</option>
                <option value="GREEN">greenv</option>
                <option value="YELLOW">yellow</option>
                <option value="BLUW">blue</option>
                <option value="PLAY">Play</option>
                <option value="PAUSE">Pause</option>
                <option value="REV">REV</option>
                <option value="FWD">FWD</option>
                <option value="PREVCHAP">ChapPrev</option>
                <option value="NEXTCHAP">ChapNext</option>
                <option value="STOP">Stop</option>
                <option value="RECORD">Record</option>

(use the upper case strings and send them to EntertainTV_Key)

Looks great, where did you get all the fancy icons ?

google :wink:

1 Like

Hey!

First of all: Thank you!

But something is not working:

  • Turn on Receiver
  • Copied the jar to addons
  • Got the Receiver as Thing through the Inbox.
  • Set UserID and Location
  • Linked Power and Key

But it is not working. The Power is “off” but the Receiver is on. Send Key does not make a change to my receiver.

I have openHAB on my Synology NAS

Log (I blanket out my userid):

2018-10-09 16:49:22.391 [ERROR] [very.EntertainTVDiscoveryParticipant] - EntertainTV: Unable to create thing: null
2018-10-09 16:49:22.402 [INFO ] [g.discovery.internal.PersistentInbox] - Added new thing 'entertaintv:receiver:33ad68ef-5476-5198-9303-AC6FBB500D3D' to inbox.
2018-10-09 16:49:22.457 [INFO ] [tv.internal.EntertainTVNotifyServlet] - EntertainTV servlet started at '/entertaintv/notify'
2018-10-09 16:49:58.283 [ERROR] [ertaintv.internal.EntertainTVNetwork] - EntertainTV: Unable to get local IP / MAC address: null!
2018-10-09 16:49:58.826 [INFO ] [ertaintv.internal.EntertainTVControl] - EntertainTVControl: Send Pairing Request (firendlyName='PAD:OPENHAB_OH2', deviceID='D41D8CD98F00B204E9800998ECF8427E', userID='hereIsMyUserId)
2018-10-09 16:49:58.840 [ERROR] [ertaintv.internal.EntertainTVNetwork] - EntertainTV: Unable to get local IP / MAC address: null!
2018-10-09 16:49:59.384 [INFO ] [ertaintv.internal.EntertainTVControl] - EntertainTVControl: Send Pairing Request (firendlyName='PAD:OPENHAB_OH2', deviceID='D41D8CD98F00B204E9800998ECF8427E', userID='hereIsMyUserId')

which platform are you using? Java has known issues to detect the local ip address. I added code to implement a 2nd way, but ibviously this is not enough.

Could you please post info om your environment + ifconfig output. I could add some additional debugging at that stage.

Hi Timon,

I made one change to the network initialization and added some more infos in TRACE mode (use log:set TRACE org.openhab.binding.entertaintv in the openHAB console).
https://github.com/markus7017/org.openhab.binding.entertaintv/blob/master/target/org.openhab.binding.entertaintv-2.4.0-SNAPSHOT.jar

If the binding is not able to detect the local IP settings it can’t receive the pairing code from the back channel = everything else will not work. I need to work on error handling (e.g. reflecting this to the thing state), but for know I’m focusing on the functionality.

I found the following hint in a different post:

"is your jvm built with ipv6 enabled? I've got many problems with this (not only with FreeBSD).
Try to run your java program with the jvm flag -Djava.net.preferIPv4Stack=true"

Please check if IPv6 is enabled and also run “hostname” on the console.

Hey Markus,

thanks for your reply.

The good news is, that with the changed SNAPSHOT the thing can now connect.
I see on my TV that “OPENHAB_OH2” remote is connected.
The only thing that is not working is sending keys, or see if it is on/off, it shows always on.

ifconfig:

eth0      Link encap:Ethernet  HWaddr 00:11:32:2D:16:40  
          inet addr:192.168.2.99  Bcast:192.168.2.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1455501 errors:0 dropped:0 overruns:0 frame:0
          TX packets:879920 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:453577606 (432.5 MiB)  TX bytes:910702493 (868.5 MiB)

hardware:
Synology Diskstation ds214play
DSM 6.2.1-23824
java: 8.0.161.-0015
openHAB: 2.3.0.003
Entertain: MR401B

Here you can see the full new creation of the thing in my log:

2018-10-12 11:50:22.837 [INFO ] [ertaintv.internal.EntertainTVControl] - EntertainTVControl: Send Pairing Request (firendlyName='PAD:OPENHAB_OH2', deviceID='D41D8CD98F00B204E9800998ECF8427E', userID='F0F54AF36C002C66FED6AEE1884DAD7D')
2018-10-12 11:50:22.850 [INFO ] [g.discovery.internal.PersistentInbox] - Added new thing 'entertaintv:receiver:33ad68ef-5476-5198-9303-AC6FBB500D3D' to inbox.
2018-10-12 11:50:52.030 [ERROR] [ertaintv.internal.EntertainTVNetwork] - EntertainTV: Unable to get local IP / MAC address: null!
2018-10-12 11:50:52.614 [INFO ] [ertaintv.internal.EntertainTVControl] - EntertainTVControl: Send Pairing Request (firendlyName='PAD:OPENHAB_OH2', deviceID='D41D8CD98F00B204E9800998ECF8427E', userID='XXXXXX')
2018-10-12 11:51:17.704 [ERROR] [ertaintv.internal.EntertainTVNetwork] - EntertainTV: Unable to get local IP / MAC address: null!
2018-10-12 11:51:18.231 [INFO ] [ertaintv.internal.EntertainTVControl] - EntertainTVControl: Send Pairing Request (firendlyName='PAD:OPENHAB_OH2', deviceID='D41D8CD98F00B204E9800998ECF8427E', userID='XXXXXX')
2018-10-12 11:51:26.666 [INFO ] [ertaintv.internal.EntertainTVControl] - EntertainTVControl: Send Key 'POWER' (keyCode='0x0100')
2018-10-12 11:51:26.677 [INFO ] [tertaintv.handler.EntertainTVHandler] - EntertainTV: Power ON

I also deactivated IPv6 on my Diskstation, but no changes.

good: the pairing was completed succussful
problem: the pairing result is not received by the binding due to the fact that the binding is not able to detect the local ip and as a resilt it registrrs a malformed event url and doesn’t receive the pairing result.
Sending keys fail, because you need to include the pairing resulr in the hash

so: why the hack Java is not able to detect the local ip even I already have 2 fallbacks.

please provide the full log in TRACE mode. there should be loh messages showing the detection steps/results

is that the complete ifconfig output?

what’s the output of the hostname command?

Hi, I have been following this topic for a while now, since I also want to integrate my MR 401 and MR 201 into my OpenHAB2 setup.

I found a way to get/generate the UserID. It is the MD5ed UserID == ProfileID == SubscriberID, that is connected to your EntertainTV-Account. When you use the EntertainTV-Mobil-App it authenticates the MobilDevice with the EntertainBackend. In this course the app is provided with the UserID == ProfileID == SubscriberID which is then later used in the Pairing-Process.

I attach a PoC bashscript that retrieves the UserID needed for the pairing process by just supplying T-Com username and password. So no more need to retrieve the UserID from capturing network traffic. Perhaps this process can be integrated into the OpenHAB-binding?

The script was written on MacOS. So you might need to change some bash commands. It requires jq (https://stedolan.github.io/jq/) for JSON parsing and has no error checking.

Usage: ./getEntertainTVUserID.sh

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

APP_URL="https://appepmfk20003.prod.sngtv.t-online.de:33207"
USER_AGENT="Mozilla/5.0 (iPhone; CPU iPhone OS 12_0_1 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 (400962928)"

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 $1
	echo "*******************"
	echo "Usage: $0 <Benutzername> <Passwort>"
	exit 1
}

function gettingOAuthCredentials() {
	local json msg

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

	host_part $APP_URL

	json=$(curl -H 'Host: '"$host"'' -H 'User-Agent: '"$USER_AGENT"'' -H 'Accept-Language: de-de' -H 'Accept: */*' -s --compressed ''"$APP_URL"'/EPG/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'`

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

}


function gettingOAuthToken() {
	local json msg

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

	host_part $oAuthService
	json=$(curl -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'`

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


function authenticateDevice() {
	local json msg uuid

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

 	host_part $APP_URL
 	uuid=$(uuidgen | tr "A-Z" "a-z")
 	cnonce=$(echo -n $uuid | md5sum)
	json=$(curl -s -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":"iPhone10","osversion":"iOS12.0.1","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","areaid":"1","templatename":"NGTV","usergroup":"IPTV_DT","subnetId":"4901"}' --compressed ''"$APP_URL"'/EPG/JSON/DTAuthenticate?SID=user&T=Iphone')
	userID=$(echo $json | jq -r '.userID')
	userIDMD5=$(echo -n $userID | md5sum | tr "a-z" "A-Z")

	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

	gettingOAuthCredentials
	gettingOAuthToken
	authenticateDevice

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

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

sounds cool, would be the missing piece in the puzzle

I run the script with my credentials, but the output is not what I expected

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

[+] Getting oAuthCredentials
[+] Getting oAuthToken
[+] Authenticate MobileDevice

--------------------------------

UserID: 
UserID (MD5ed): D41D8CD98F00B204E9800998ECF8427E  -

even when chaging the user id I get the same MD5

Did you already tried the binding?

No, I am just trying to install the binding. Will report later. As I said, there is so far no error checking in the processing of the JSON response.

Just tested. I integrated the JAR and configured the thing with the UserID form my script. I added two items VolumeUp and VolumeDown. They both work, except that VolumeDown raises the Volume :slight_smile: But that another question 


I will implement some more error checking into the script to find the reason why it is not working for you.

:+1: The channels should be easy to fix
which models did you tested?

I workey on the Key channel. The version in github already support most common ones. I between I found the key code table in the Huawai dev forum and added most of them - next update will have them.

I’m also working in decoding the STB events, which allows to get the info on player status, title and channel.

Another open topic is: How to detect if the receiver is running. The POWER button is a toggle, which means that you can’t force ON or OFF. Including a POWER in a scene requires that the receiver is in sync and nobody used the remote. In standby mode the eth interface is action and the stb replies to any valid http requests. The returned xml includes device data (like model, wol enabled etc), but no status information.

I found https://developer.huawei.com/en/ict/Products/TelecoSoftware/VideoExperienceCapbility/MEM-API/SDK%20Detail. This might include additional information.

It describes the interface to the EPG/backend and e.g. also allows to query the channel list. This might be useful to switch easier between programs or implement your own recording schedule.