newAM / hisensetv

Python API to control Hisense brand TVs via their internal MQTT broker.
MIT License
37 stars 16 forks source link

Connection reset by peer #5

Open robtesch opened 4 years ago

robtesch commented 4 years ago

Thanks for your work on this package. I am trying to do the authorize command:

hisensetv 192.168.0.40 --authorize

where 192.168.0.40 is the fixed IP address of one of my 2 hisense TVs. I am getting the following error every time i try:

Traceback (most recent call last):
  File "/usr/local/bin/hisensetv", line 10, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/dist-packages/hisensetv/__main__.py", line 48, in main
    with tv:
  File "/usr/local/lib/python3.8/dist-packages/hisensetv/__init__.py", line 115, in __enter__
    self._mqtt_client.connect(self.hostname, self.port)
  File "/usr/local/lib/python3.8/dist-packages/paho/mqtt/client.py", line 937, in connect
    return self.reconnect()
  File "/usr/local/lib/python3.8/dist-packages/paho/mqtt/client.py", line 1100, in reconnect
    sock.do_handshake()
  File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ConnectionResetError: [Errno 104] Connection reset by peer

Not sure if there's any other relevant info i am omitting here, so please let me know if you need anything else.

For what it's worth, I am able to connect to and control the TV just fine using the official "RemoteNow" app on android.

newAM commented 4 years ago

Hmmmm, can you do nmap and see if anything is listening on the mqtt port? There may be a setting to enable the MQTT server on the TV.

robtesch commented 4 years ago

Unfortunately there is no such setting on the TV, but i know it is communicating and accepting mqtt commands because it works with the android app, which is MQTT based (I can watch this happening with MQTT Explorer).

newAM commented 4 years ago

Are you able to do an nmap? For example, my TV at 10.0.0.28 shows:

nmap -p 36000-37000 10.0.0.28 

Starting Nmap 7.60 ( https://nmap.org )
Nmap scan report for 10.0.0.28
Host is up (0.0043s latency).
Not shown: 999 closed ports
PORT      STATE SERVICE
36668/tcp open  unknown
36669/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.15 seconds

If those ports are open are you able to get a wireshark capture of communications between your TV and the app, and the TV and the API?

Also, what TV model are you using?

Nils3311 commented 4 years ago

Hi, thanks for your repository!

I have exactly the same problem. It shows me:

hisensetv 192.168.178.54 --authorize
Traceback (most recent call last):
  File "/Users/nils/opt/anaconda3/bin/hisensetv", line 10, in <module>
    sys.exit(main())
  File "/Users/nils/opt/anaconda3/lib/python3.7/site-packages/hisensetv/__main__.py", line 48, in main
    with tv:
  File "/Users/nils/opt/anaconda3/lib/python3.7/site-packages/hisensetv/__init__.py", line 115, in __enter__
    self._mqtt_client.connect(self.hostname, self.port)
  File "/Users/nils/opt/anaconda3/lib/python3.7/site-packages/paho/mqtt/client.py", line 937, in connect
    return self.reconnect()
  File "/Users/nils/opt/anaconda3/lib/python3.7/site-packages/paho/mqtt/client.py", line 1100, in reconnect
    sock.do_handshake()
  File "/Users/nils/opt/anaconda3/lib/python3.7/ssl.py", line 1139, in do_handshake
    self._sslobj.do_handshake()
ConnectionResetError: [Errno 54] Connection reset by peer

With your nmap command the response is:

nmap -p 36000-37000 192.168.178.54
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-11 01:16 CEST
Nmap scan report for 192.168.178.54
Host is up (0.011s latency).
Not shown: 1000 closed ports
PORT      STATE SERVICE
36669/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 6.78 seconds

EDIT: Even with Python 3.8 same results...

newAM commented 4 years ago

Hmmm... I wonder if SSL is not enabled on your TVs.

Can one of you run this code and let me know if it works?

import paho.mqtt.client as mqtt
import uuid

# put your TV hostname or IPv4 in here.
HOSTNAME = ""

client_id = str(uuid.uuid4())

mqtt_client = mqtt.Client(client_id)
mqtt_client.username_pw_set(
    username="hisenseservice", password="multimqttservice"
)
mqtt_client.connect(HOSTNAME, 36669)
print("hello world")
robtesch commented 4 years ago

Ran the code above in interactive mode (sorry, i'm a PHP dev, not a python dev so my python knowledge is very limited):

>>> import paho.mqtt.client as mqtt
>>> import uuid
>>> HOSTNAME = "192.168.0.40"
>>> client_id = str(uuid.uuid4())
>>> mqtt_client = mqtt.Client(client_id)
>>> mqtt_client.username_pw_set(
...     username="hisenseservice", password="multimqttservice"
... )
>>> mqtt_client.connect(HOSTNAME, 36669)
0
>>> print("hello world")
hello world
>>> exit()

NMAP output:

nmap -p 36000-37000 192.168.0.40

Starting Nmap 7.60 ( https://nmap.org ) at 2020-04-11 12:21 UTC
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.12 seconds

And if i try it with the -Pn option, it just sits there and does nothing.

However, ping output:

 ping 192.168.0.40
PING 192.168.0.40 (192.168.0.40) 56(84) bytes of data.
64 bytes from 192.168.0.40: icmp_seq=1 ttl=63 time=3.10 ms
64 bytes from 192.168.0.40: icmp_seq=2 ttl=63 time=2.37 ms
64 bytes from 192.168.0.40: icmp_seq=3 ttl=63 time=2.89 ms
64 bytes from 192.168.0.40: icmp_seq=4 ttl=63 time=3.62 ms
64 bytes from 192.168.0.40: icmp_seq=5 ttl=63 time=4.37 ms
64 bytes from 192.168.0.40: icmp_seq=6 ttl=63 time=2.35 ms
64 bytes from 192.168.0.40: icmp_seq=7 ttl=63 time=2.42 ms
^C
--- 192.168.0.40 ping statistics ---
7 packets transmitted, 7 received, 0% packet loss, time 6028ms
rtt min/avg/max/mdev = 2.350/3.020/4.375/0.703 ms

I have 2 Hisense TVs, but for now just trying to connect to the newest of the 2, which is a 2019 model H43A6250UK.

Again, using the official app seems to work fine.

newAM commented 4 years ago

I made a debug branch with an alpha release of 0.0.8, can you try it out?

git clone https://github.com/newAM/hisensetv.git -b issue-5
cd hisensetv
python3.8 -m pip install .
hisensetv --authorize --no-ssl

Python 3.6 / 3.7 are also fine, 3.8 is just an example here.

Nils3311 commented 4 years ago

Hello newAM,

thanks for your fast response! Your python code runs without any errors and gives back hello world like expected.

I followed your second step and was able to pull your alpha release and start it with my host ip. There another error showed up:

hisensetv 192.168.178.54 --authorize --no-ssl
Traceback (most recent call last):
  File "/Users/nils/opt/anaconda3/envs/python38/lib/python3.8/site-packages/hisensetv/__init__.py", line 187, in _wait_for_response
    return self._queue.get(block=True, timeout=self.timeout)
  File "/Users/nils/opt/anaconda3/envs/python38/lib/python3.8/queue.py", line 178, in get
    raise Empty
_queue.Empty

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/nils/opt/anaconda3/envs/python38/bin/hisensetv", line 8, in <module>
    sys.exit(main())
  File "/Users/nils/opt/anaconda3/envs/python38/lib/python3.8/site-packages/hisensetv/__main__.py", line 63, in main
    tv.start_authorization()
  File "/Users/nils/opt/anaconda3/envs/python38/lib/python3.8/site-packages/hisensetv/__init__.py", line 55, in wrapper
    return func(self, *args, **kwargs)
  File "/Users/nils/opt/anaconda3/envs/python38/lib/python3.8/site-packages/hisensetv/__init__.py", line 428, in start_authorization
    self._wait_for_response()
  File "/Users/nils/opt/anaconda3/envs/python38/lib/python3.8/site-packages/hisensetv/__init__.py", line 189, in _wait_for_response
    raise HisenseTvTimeoutError(
hisensetv.HisenseTvTimeoutError: failed to recieve a response in 10.000s

Edit 1: By the way I have the Model Hisense U7A (50 Inch, HE50U7A1WTS) Edit 2: Even when raising the timeout time to 30 seconds: hisensetv.HisenseTvTimeoutError: failed to recieve a response in 30.000s Edit 3: With the remote app and MQTTBOX on my Mac it is possible to connect with no problem:

image
robtesch commented 4 years ago

Hi there @newAM thanks for trying to help us out here. I am getting the same error as @Nils3311 when trying out your debug build:

 hisensetv 192.168.0.40 --authorize --no-ssl
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/hisensetv/__init__.py", line 187, in _wait_for_response
    return self._queue.get(block=True, timeout=self.timeout)
  File "/usr/lib/python3.8/queue.py", line 178, in get
    raise Empty
_queue.Empty

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/hisensetv", line 10, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/dist-packages/hisensetv/__main__.py", line 63, in main
    tv.start_authorization()
  File "/usr/local/lib/python3.8/dist-packages/hisensetv/__init__.py", line 55, in wrapper
    return func(self, *args, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/hisensetv/__init__.py", line 428, in start_authorization
    self._wait_for_response()
  File "/usr/local/lib/python3.8/dist-packages/hisensetv/__init__.py", line 189, in _wait_for_response
    raise HisenseTvTimeoutError(
hisensetv.HisenseTvTimeoutError: failed to recieve a response in 10.000s
newAM commented 4 years ago

This is a step in the right direction then! We can open the socket and connect to the broker, it just looks like the response topic is not sending anything back.

Thanks for sticking with the debug! We will get to the bottom of this :+1:

Before using the hisensetv command are you able to subscribe to all topics and see what comes out of the TV?

mosquitto_sub -h 10.0.0.28 -t "#" -p 36669 -u hisenseservice -P multimqttservice --debug

Also, when you used the app did you have to enter a 4-digit code that appeared on the screen? I am wondering if that part is new.

robtesch commented 4 years ago

@newAM thanks for your help so far. Can't do too much today because i have work deadlines, but to answer your last question, no, I've never been asked to do a 4 digit code by the TV, so that must only be on some newer models (although, the one i am using for this testing is a 2019 model so not exactly ancient). For the app to work you just open it up and it seems to work, picks up all the tvs you have on the network and just allows you to control them.

Nils3311 commented 4 years ago

Hi @newAM,

I was not asked to type in any code before connecting to the TV with the app. After installing mosquitto I am able to get the current Information:

hisensetv git:(issue-5) ✗ mosquitto_sub -h 192.168.178.54 -t "#" -p 36669 -u hisenseservice -P multimqttservice --debug
Client mosq-8sSNsln1qNUI81tCR7 sending CONNECT
Client mosq-8sSNsln1qNUI81tCR7 received CONNACK (0)
Client mosq-8sSNsln1qNUI81tCR7 sending SUBSCRIBE (Mid: 1, Topic: #, QoS: 0, Options: 0x00)
Client mosq-8sSNsln1qNUI81tCR7 received SUBACK
Subscribed (mid: 1): 0
Client mosq-8sSNsln1qNUI81tCR7 received PUBLISH (d0, q0, r1, m0, '/remoteapp/mobile/broadcast/ui_service/state', ... (458 bytes))
{"statetype":"livetv","list_param":"2#0","channel_num":"6","eventid":"","progname":"Die Höhle der Löwen","starttime":1586888100,"endtime":1586896800,"detail":"\nGerhard Pletschacher und Dustin Weidenhiller haben ein Problem von Fahrzeug-Enthusiasten erkannt und mit \"GentleMonkeys\" Nasstücher entwickelt, die in einer Anwendung Oberflächen reinigen, polieren und versiegeln sollen.","channel_param":"2#33554561#7#0","channel_name":"VOX","sourceid":"0"}

Any ideas?

newAM commented 4 years ago

Since authorization is not required on the app then it shouldn't be required for this either, what kind of trace-back do you get from --get volume or --get sources, do any of the --key commands work either? A mosquitto_sub trace from these would be helpful as well if possible :)

midiland commented 4 years ago

Hello everyone, Thanks for your work. I have the same issue, with my h58AE6000,

i can connect with mosquitto_sub :

± % mosquitto_sub -h 192.168.2.225 -t "#" -p 36669 -u hisenseservice -P multimqttservice --debug                                                                                                                                      
Client mosq-f5XZNZVFaKsYasEagG sending CONNECT
Client mosq-f5XZNZVFaKsYasEagG received CONNACK (0)
Client mosq-f5XZNZVFaKsYasEagG sending SUBSCRIBE (Mid: 1, Topic: #, QoS: 0, Options: 0x00)
Client mosq-f5XZNZVFaKsYasEagG received SUBACK
Subscribed (mid: 1): 0
Client mosq-f5XZNZVFaKsYasEagG received PUBLISH (d0, q0, r1, m0, '/remoteapp/mobile/broadcast/ui_service/state', ... (132 bytes))
{"statetype":"sourceswitch","sourceid":"4","sourcename":"HDMI1","is_signal":1,"is_lock":0,"hotel_mode":0,"displayname":"android tv"}
Client mosq-f5XZNZVFaKsYasEagG received PUBLISH (d0, q0, r0, m0, '/remoteapp/mobile/broadcast/platform_service/actions/volumechange', ... (42 bytes))
{
    "volume_type":  0,
    "volume_value": 40
}
Client mosq-f5XZNZVFaKsYasEagG received PUBLISH (d0, q0, r0, m0, '/remoteapp/mobile/broadcast/platform_service/actions/volumechange', ... (42 bytes))
{
    "volume_type":  0,
    "volume_value": 39
}

when i use : hisensetv 192.168.2.225 --get volume --no-ssl I have a timeout :

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/hisensetv/__init__.py", line 187, in _wait_for_response
    return self._queue.get(block=True, timeout=self.timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/queue.py", line 172, in get
    raise Empty
queue.Empty

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/bin/hisensetv", line 8, in <module>
    sys.exit(main())
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/hisensetv/__main__.py", line 74, in main
    output = func()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/hisensetv/__init__.py", line 55, in wrapper
    return func(self, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/hisensetv/__init__.py", line 402, in get_volume
    return self._wait_for_response()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/hisensetv/__init__.py", line 191, in _wait_for_response
    ) from e
hisensetv.HisenseTvTimeoutError: failed to recieve a response in 10.000s

but when i use --get source is works

hisensetv 192.168.2.225 --get sources --no-ssl                                                                                                                                                                                     
[2020-05-16 19:07:21,916] [INFO    ] sources: [
    {
        "sourceid": "4",
        "sourcename": "HDMI1",
        "displayname": "android tv",
        "is_signal": "1",
        "is_lock": "0",
        "hotel_mode": "0"
    },
    {
        "sourceid": "5",
        "sourcename": "HDMI2",
        "displayname": "HDMI2",
        "is_signal": "0",
        "is_lock": "0",
        "hotel_mode": ""
    },
    {
        "sourceid": "6",
        "sourcename": "HDMI3",
        "displayname": "HDMI3",
        "is_signal": "0",
        "is_lock": "0",
        "hotel_mode": ""
    },
    {
        "sourceid": "0",
        "sourcename": "TV",
        "displayname": "TV",
        "is_signal": "0",
        "is_lock": "0",
        "hotel_mode": ""
    },
    {
        "sourceid": "1",
        "sourcename": "AV",
        "displayname": "AV",
        "is_signal": "0",
        "is_lock": "0",
        "hotel_mode": ""
    }
]

and when i use --key is works too

 hisensetv 192.168.2.225 --key power --no-ssl
[2020-05-16 19:09:14,902] [INFO    ] sending keypress: power

I need use --no-ssl every time.

newAM commented 4 years ago

That is good data @midiland, thank you!

For the volume problem, are you able to do a mosquitto_sub and see what comes out of the TV when doing a mosquitto_pub -h <TV_IP> -p 36669 -P multimqttservice -u hisenseservice -t /remoteapp/tv/platform_service/XX:XX:XX:XX:XX:XY$normal/actions/getvolume -m ""?

newAM commented 4 years ago

Since --no-ssl seems to work for some people I merged this change into the master branch. Will keep the issue open until all the problems are chased down.