sermayoral / ha-samsungtv-encrypted

Samsung TV Encrypted Models (H & J Series) custom component for Home Assistant
Apache License 2.0
39 stars 24 forks source link

Get token UE40J5200AKXZT #21

Open dariob84 opened 4 years ago

dariob84 commented 4 years ago

Good morning, i tried to take token for my tv (UE40J5200AKXZT) but i recived this:

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080 Traceback (most recent call last): File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 156, in _new_conn conn = connection.create_connection( File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\util\connection.py", line 84, in create_connection raise err File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\util\connection.py", line 74, in create_connection sock.connect(sa) ConnectionRefusedError: [WinError 10061] Impossibile stabilire la connessione. Rifiuto persistente del computer di destinazione

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen httplib_response = self._make_request( File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 387, in _make_request conn.request(method, url, **httplib_request_kw) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1230, in request self._send_request(method, url, body, headers, encode_chunked) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1276, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1225, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1004, in _send_output self.send(msg) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 944, in send self.connect() File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 184, in connect conn = self._new_conn() File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 168, in _new_conn raise NewConnectionError( urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x00000257CA59CD00>: Failed to establish a new connection: [WinError 10061] Impossibile stabilire la connessione. Rifiuto persistente del computer di destinazione

can anyone tell me what am i doing wrong?

Thanks

sermayoral commented 4 years ago

It seems IP not reached:

ConnectionRefusedError: [WinError 10061] Impossibile stabilire la connessione. Rifiuto persistente del computer di destinazione

Do you have the TV on? Are you sure the IP is right?

dariob84 commented 4 years ago

thanks for your reply my tv is on and connected to the internet. the IP address is correct (I use a static IP address). I have two TVs of the same model and I get the same error.

dariob84 commented 4 years ago

thanks for your reply my tv is on and connected to the internet. the IP address is correct (I use a static IP address). I have two TVs of the same model and I get the same error.

Il giorno mer 15 apr 2020 alle ore 09:49 Sergio Mayoral MartΓ­nez < notifications@github.com> ha scritto:

It seems IP not reached:

ConnectionRefusedError: [WinError 10061] Impossibile stabilire la connessione. Rifiuto persistente del computer di destinazione

Do you have the TV on? Are you sure the IP is right?

β€” You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/sermayoral/ha-samsungtv-encrypted/issues/21#issuecomment-613876638, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOIFNCBDK2GRLMDR2O2NTFDRMVRKBANCNFSM4MGZ4Q7Q .

sermayoral commented 4 years ago

@dariob84 I think your TV is blocking the request in some way.

If I remember well, there was an option in the TV menu to permit one IP to control the TV. You can try it

md1980 commented 3 years ago

I have this problem: image

flostingapplesauce commented 3 years ago

Has anyone successfully received a token on a J series? I have the program running under both under Windows 10 and Debian, but neither can get a token. Weirdly, the error always shows port 8000 is being tried.

The TV is a UN40J6203 (specifically a UN40J6200AFXZA) and it IS on the net. nMap shows port 8080 open.

Crypto.SelfTest passes fine.

Linux command:

python3 ./get_token.py -i 192.168.75.210 -p 8080

Linux log:

File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1604341144630 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb5f30a10>: Failed to establish a new connection: [Errno 111] Connection refused'))

Windows 10 command: get_token.py --ip 192.168.75.210 --port 8080

Windows 10 log:

raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1604341184884 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000288FC26EB20>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it'))

Both indicate port 8000 and both show the connection being refused.

I have tried all manner of syntax, -i IP -p PORT; --i IP --p PORT; -ip IP -port PORT; --ip IP --port PORT etcetc to no avail.

Is it that I am somehow still doing something wrong, or is the J6200 series not compatible?

EPMatt commented 3 years ago

@flostingapplesauce the issue with the bad port should be fixed as of commit 2524a61. You could try executing python get_token.py --ip <your ip> --port <your port> and see what results you get.

I'm having a similar issue with a J series Smart TV too (more details here #62).

flostingapplesauce commented 3 years ago

Thanks a million, EPMatt, but I am still getting a page of errors. Same errors when attempting it from the HA box and from a Windows machine. I can see the port is open with nmap, and can hit it with SSH, so I know the IP and port are correct. Although the error is identical when I use --port 8000 and nmap and ssh show 8000 is closed.

bash-5.0# python get_token.py --ip 192.168.75.210 --port 8080 Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 169, in _new_conn conn = connection.create_connection( File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 96, in create_connection raise err File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 86, in create_connection sock.connect(sa) ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 699, in urlopen httplib_response = self._make_request( File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 394, in _make_request conn.request(method, url, **httplib_request_kw) File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 234, in request super(HTTPConnection, self).request(method, url, body=body, headers=headers) File "/usr/local/lib/python3.8/http/client.py", line 1255, in request self._send_request(method, url, body, headers, encode_chunked) File "/usr/local/lib/python3.8/http/client.py", line 1301, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/usr/local/lib/python3.8/http/client.py", line 1250, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/local/lib/python3.8/http/client.py", line 1010, in _send_output self.send(msg) File "/usr/local/lib/python3.8/http/client.py", line 950, in send self.connect() File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 200, in connect conn = self._new_conn() File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 181, in _new_conn raise NewConnectionError( urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0xb509f040>: Failed to establish a new connection: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 439, in send resp = conn.urlopen( File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 755, in urlopen retries = retries.increment( File "/usr/local/lib/python3.8/site-packages/urllib3/util/retry.py", line 573, in increment raise MaxRetryError(_pool, url, error or ResponseError(cause)) urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1606409526220 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb509f040>: Failed to establish a new connection: [Errno 111] Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "get_token.py", line 27, in main(sys.argv[1:]) File "get_token.py", line 24, in main PySmartCrypto(ip, port) File "/config/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 123, in init self._connection = self.connect() File "/config/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 95, in connect websocket_response = requests.get(step4_url) File "/usr/local/lib/python3.8/site-packages/requests/api.py", line 76, in get return request('get', url, params=params, kwargs) File "/usr/local/lib/python3.8/site-packages/requests/api.py", line 61, in request return session.request(method=method, url=url, kwargs) File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 542, in request resp = self.send(prep, send_kwargs) File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 655, in send r = adapter.send(request, kwargs) File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 516, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1606409526220 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb509f040>: Failed to establish a new connection: [Errno 111] Connection refused')) bash-5.0# ssh -p 8080 192.168.75.210

EPMatt commented 3 years ago

Hi @flostingapplesauce, you're welcome! I'm happy to help as I can. :)

Did you clone this repo as of the latest commit?

I think this could be the problem since you're passing port 8080 as a parameter to the script, but you're still getting errors related to port 8000. This issue has been completely fixed with the latest merged PR.

Regarding the HA box, the issue is that there's no new version for this integration on HACS since the latest fix, so the code on your HA box could still be the buggy one from version v3.1.

I'd suggest trying the following:

Please let us know if running the script as suggested allows you to get the token. If you still get errors, you could paste the log here. πŸ‘πŸ»

flostingapplesauce commented 3 years ago

Thanks again EPMatt, it is indeed different once I had the newest software. Now I get a 400 Bad Request, so at least it is seeing something.

Just in case it helps:

C:\Samsung>python get_token.py --ip 192.168.75.210 --port 8080 Traceback (most recent call last): File "C:\Samsung\get_token.py", line 40, in main(sys.argv[1:]) File "C:\Samsung\get_token.py", line 36, in main PySmartCrypto(ip, port) File "C:\Samsung\PySmartCrypto\pysmartcrypto.py", line 123, in init self._connection = self.connect() File "C:\Samsung\PySmartCrypto\pysmartcrypto.py", line 99, in connect connection = websocket.create_connection(websocket_url) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 515, in create_connection websock.connect(url, *options) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 226, in connect self.handshake_response = handshake(self.sock, addrs, **options) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 80, in handshake status, resp = _get_resp_headers(sock) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

dariob84 commented 3 years ago

Hi EPMatt, i tried to follow your instructions, but i can't get the token.

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080 Traceback (most recent call last): File "get_token.py", line 40, in main(sys.argv[1:]) File "get_token.py", line 36, in main PySmartCrypto(ip, port) File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 123, in init self._connection = self.connect() File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 99, in connect connection = websocket.create_connection(websocket_url) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 515, in create_connection websock.connect(url, *options) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 226, in connect self.handshake_response = handshake(self.sock, addrs, **options) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 80, in handshake status, resp = _get_resp_headers(sock) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

EPMatt commented 3 years ago

Hi @flostingapplesauce @dariob84, thank you for performing these tests, but here's where I got stuck. Unfortunately I think we have the same issue.

Just for testing purposes and be sure that our devices are behaving in the same way, try to add this after websocket_response = requests.get(step4_url) (line 95) in custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py:

print(websocket_response)

You'd probably see <Response [403]> in the output before the exception traceback.

Could you please check and confirm it?

AKuHAK commented 3 years ago

You'd probably see <Response [403]> in the output before the exception traceback.

Hi guys I have UE32H4500 I also receive Response 403 after adding websocket_response = requests.get(step4_url)

But I can successfully connect with this code (I receive PIN and it responds correctly): https://github.com/eclair4151/SmartCrypto/blob/master/PySmartCrypto/smartcrypto.py

AKuHAK commented 3 years ago

After reverting this commit: https://github.com/sermayoral/ha-samsungtv-encrypted/commit/2524a61e5dd598deb0c1eee8f9c8fb3537f4e176 Everything is ok now: We must use port 8000 for sending websocket, not the user defined port.

EPMatt commented 3 years ago

Hi @AKuHAK ,

After reverting this commit: 2524a61 Everything is ok now: We must use port 8000 for sending websocket, not the user defined port.

I'm happy to hear that you managed to get the token. πŸš€
Unfortunately our TVs are quite different. Specifically, your device is a 2014 H-Series TV, which as I can read in other issues, exposes the web service on port 8000, while ours are all part of the 2015 J-Series. If we try to perform queries on port 8000, we just get a Connection refused exception.

Just for testing purposes, could you try retrieving the token with the code at the most recent commit? Use python get_token.py --ip <your ip> --port 8000.

But I can successfully connect with this code (I receive PIN and it responds correctly): https://github.com/eclair4151/SmartCrypto/blob/master/PySmartCrypto/smartcrypto.py

Thankyou very much for pointing it out! @dariob84 @flostingapplesauce, it's a good idea to test other scripts and see if we can retrieve the token in some way. I'll definitely check it out and report any progress here. πŸ‘πŸ»

AKuHAK commented 3 years ago

Here are my tests: At latest commit: 1) python get_token.py --ip <your ip> --port 8000 After running with port 8000 I receive the correct console output:

<Response [200]>
Pin ON TV
Please enter pin from tv:

However, there is no PIN on the TV screen. 2) python get_token.py --ip <your ip> --port 8080 After running with port 8080 I receive Handshake error 400:

If I revert to 4eab94a: 3)

git checkout --force 4eab94a
python get_token.py --ip <your ip> --port 8080

I can see the PIN on the screen and PIN is correctly handled and I can successfully get token and session ID.

So I made an assumption that the PIN request port is hardcoded to 8000, maybe I am wrong. Of course, it will be better to run the same tests on some other TV (J series for example).

dariob84 commented 3 years ago

@EPMatt

Hi, I added the code this after line 95:

print(websocket_response)

this is the response

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080 Traceback (most recent call last): File "get_token.py", line 40, in main(sys.argv[1:]) File "get_token.py", line 36, in main PySmartCrypto(ip, port) File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 123, in init self._connection = self.connect() File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 99, in connect connection = websocket.create_connection(websocket_url) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 515, in create_connection websock.connect(url, *options) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 226, in connect self.handshake_response = handshake(self.sock, addrs, **options) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 80, in handshake status, resp = _get_resp_headers(sock) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

flostingapplesauce commented 3 years ago

EPMatt: I wasn't certain whether you wanted that line appended to the end of line 95, or added after it as line 96, so here it is both ways:

Appended:

C:\samsung> python get_token.py --ip 192.168.75.210 --port 8080 Traceback (most recent call last): File "C:\samsung\get_token.py", line 4, in from PySmartCrypto.pysmartcrypto import PySmartCrypto File "C:\samsung\PySmartCrypto\pysmartcrypto.py", line 95 websocket_response = requests.get(step4_url) print(websocket_response)

Added as line 96:

C:\samsung> python get_token.py --ip 192.168.75.210 --port 8080 <Response [403]> Traceback (most recent call last): File "C:\samsung\get_token.py", line 40, in main(sys.argv[1:]) File "C:\samsung\get_token.py", line 36, in main PySmartCrypto(ip, port) File "C:\samsung\PySmartCrypto\pysmartcrypto.py", line 124, in init self._connection = self.connect() File "C:\samsung\PySmartCrypto\pysmartcrypto.py", line 100, in connect connection = websocket.create_connection(websocket_url) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 515, in create_connection websock.connect(url, *options) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 226, in connect self.handshake_response = handshake(self.sock, addrs, **options) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 80, in handshake status, resp = _get_resp_headers(sock) File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

Agreed, it looks like we have similar issues here. I am pretty sure that, at least on my end, I forgot to blow cigar smoke into the face of the sacrificial chicken last time I performed a ritual to the Python goddess, but it could be something else. ;)

EPMatt commented 3 years ago

Hi @AKuHAK, Thank you so much for performing these tests. πŸš€ So I'm trying to make a recap and guess what had happened in your situation.

At latest commit:

  1. python get_token.py --ip <your ip> --port 8000 After running with port 8000 I receive the correct console output:
<Response [200]>
Pin ON TV
Please enter pin from tv:

However, there is no PIN on the TV screen.

step4_url: using port 8000 websocket_url: using port 8000

2) python get_token.py --ip <your ip> --port 8080 After running with port 8080 I receive Handshake error 400:

step4_url: using port 8080 websocket_url: using port 8080

If I revert to 4eab94a: 3)

git checkout --force 4eab94a
python get_token.py --ip <your ip> --port 8080

I can see the PIN on the screen and PIN is correctly handled and I can successfully get token and session ID.

step4_url: using port 8000 websocket_url: using port 8000

This time the pin was displayed, and you were able to get the token. I saw similar issues, with people being able to display the pin after several attempts. So this second request on the same port probably triggered what the first one didn't.

We can then assume that H Series TVs (or at least yours) expose the service on port 8000. But it's interesting that you get a 400 when trying to connect on port 8080.

So I made an assumption that the PIN request port is hardcoded to 8000, maybe I am wrong. Of course, it will be better to run the same tests on some other TV (J series for example).

I performed the tests trying with port 8000 and also manually editing the code to make the first request to step4_url with port 8000 and the second one to websocket_url with port 8080. What I get is a Connection refused message in both situations, stuck at performing the first request.

We can then assume that J Series TVs (or at least mine) don't expose the service on port 8000.

I'm only trying to guess, I think it's really difficult to debug these issues, since every device is a little different from the others, and this integration tries to manage all of them.

By the way might be interesting and extremely helpful to add to the docs, for each tested device, which port was used for connecting and retrieving the token. πŸ‘πŸ»

EPMatt commented 3 years ago

Hi @dariob84, thank you very much for your feedback!

this is the response

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080 Traceback (most recent call last): File "get_token.py", line 40, in ..... raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

That's strange, I don't see the output which should be generated by that new line. Maybe I was wrong with the line numbers in my previous comment, please make sure the connect function looks like this:

def connect(self):
        millis = int(round(time.time() * 1000))
        step4_url = 'http://' + self._host + ':'+self._port+'/socket.io/1/?t=' + str(millis)
        websocket_response = requests.get(step4_url)
        print(websocket_response)
        websocket_url = 'ws://' + self._host + ':'+self._port+'/socket.io/1/websocket/' + websocket_response.text.split(':')[0]
        # print(websocket_url)
        # pairs to this app with this command.
        connection = websocket.create_connection(websocket_url)
        connection.send('1::/com.samsung.companion')
        return connection

If you have time please retry, so that we're sure we're having all the same issue. πŸ‘πŸ»

EPMatt commented 3 years ago

Hi @flostingapplesauce, thank you for your feedback! πŸš€

Added as line 96:

C:\samsung> python get_token.py --ip 192.168.75.210 --port 8080 <Response [403]> ... raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

There you go! I think we're definitely on the same boat.

Agreed, it looks like we have similar issues here. I am pretty sure that, at least on my end, I forgot to blow cigar smoke into the face of the sacrificial chicken last time I performed a ritual to the Python goddess, but it could be something else. ;)

Hahah maybe you're right, neither did I! πŸ˜† At least we're understanding that many people aren't able to get the token from their devices, and for the same reason.

AKuHAK commented 3 years ago

step4_url: using port 8000 websocket_url: using port 8000

Please recheck in step 3 I am using step4_url: using port 8080 websocket_url: using port 8000

EPMatt commented 3 years ago

Hi @AKuHAK,

Please recheck in step 3 I am using step4_url: using port 8080 websocket_url: using port 8000

If I'm not wrong this should be the definition of the connect function at 4eab94a:

def connect(self):
        millis = int(round(time.time() * 1000))
        step4_url = 'http://' + self._host + ':8000/socket.io/1/?t=' + str(millis)
        websocket_response = requests.get(step4_url)
        websocket_url = 'ws://' + self._host + ':8000/socket.io/1/websocket/' + websocket_response.text.split(':')[0]
        # print(websocket_url)
        # pairs to this app with this command.
        connection = websocket.create_connection(websocket_url)
        connection.send('1::/com.samsung.companion')
        return connection

So the self._port is not taken into account when constructing the URLs. Hence:

step4_url: using port 8000 websocket_url: using port 8000

AKuHAK commented 3 years ago

Yes but I am running python get_token.py --ip --port 8080 port 8080 is defined via command line so it should be used somewhere

if I run python get_token.py --ip --port 8000 I got the same behavior in the latest commit and in the previous commit: the command line responds that PIN is ok, but does not show that PIN on the screen.

EPMatt commented 3 years ago

Hi @AKuHAK,

Yes but I am running python get_token.py --ip --port 8080 port 8080 is defined via command line so it should be used somewhere

You're right, I can see the port argument is used in getFullUrl.

That's interesting. For me running the commands as you described returns Connection refused. Also, nmap detects only 8080 as open port, not 8000. So it looks like my device can't accept connections on 8000.

Just for testing purposes, could you please run nmap -PN <your_ip> to see which ports are open on your TV?

AKuHAK commented 3 years ago

Oh, I see, the port is used in 3 places, my mistake. nmap -PN output

Not shown: 994 closed ports
PORT     STATE SERVICE
7676/tcp open  imqbrokerd
8000/tcp open  http-alt
8001/tcp open  vcom-tunnel
8080/tcp open  http-proxy
8443/tcp open  https-alt
9090/tcp open  zeus-admin
flostingapplesauce commented 3 years ago

Same. Port 8000 gives me [WinError 10061] No connection could be made because the target machine actively refused it')) and port 8080 returns a 400 error, both with and without that mod to the line after 95.

EPMatt commented 3 years ago

Hi @AKuHAK, it looks like your device has lots of opened ports. Did you tweak any specific setting on your TV for enabling remote control? Can you find any setting related to remote control in the configuration menus?

flostingapplesauce commented 3 years ago

FWIW, mine has:

7011 7676 8080

open.

AKuHAK commented 3 years ago

Hi @AKuHAK, it looks like your device has lots of opened ports. Did you tweak any specific setting on your TV for enabling remote control? Can you find any setting related to remote control in the configuration menus?

Yes, I am logged in with a Samsung account and get Samsung smartthings token as described here: https://github.com/balmli/com.samsung.smart#smartthings-api

EPMatt commented 3 years ago

FWIW, mine has:

7011 7676 8080

open.

@flostingapplesauce thank you very much, we could check which services our devices expose on the network.

@flostingapplesauce @dariob84 could you please post the entire output of nmap <your_ip> just as @AKuHAK did? So we can compare exposed services and opened ports.

For my device (UE32J5200):

PORT     STATE SERVICE
7676/tcp open  imqbrokerd
8080/tcp open  http-proxy
estevez-dev commented 3 years ago

I feel that I need to move my report here from #62 because we already have a lot of similar issues here. So my TV is UE55H6203AK Executing

python3 ./get_token.py --ip 192.168.2.23 --port 8080

Gives me this output (I've added print(websocket_response) to see a response):

<Response [403]>
Traceback (most recent call last):
  File "./get_token.py", line 40, in <module>
    main(sys.argv[1:])
  File "./get_token.py", line 36, in main
    PySmartCrypto(ip, port)
  File "/home/estevez/src/ha-samsungtv-encrypted/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 124, in __init__
    self._connection = self.connect()
  File "/home/estevez/src/ha-samsungtv-encrypted/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 100, in connect
    connection = websocket.create_connection(websocket_url)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_core.py", line 515, in create_connection
    websock.connect(url, **options)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_core.py", line 226, in connect
    self.handshake_response = handshake(self.sock, *addrs, **options)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_handshake.py", line 80, in handshake
    status, resp = _get_resp_headers(sock)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_handshake.py", line 165, in _get_resp_headers
    raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

I'm getting Connection refused when trying to use 8000 in any case. I tried this:

python3 ./get_token.py --ip 192.168.2.23 --port 8000

I also tried to hardcode 8000 in connect function for step4_url, for websocket_url and for both. The answer is always the same:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.2.23', port=8000): Max retries exceeded with url: /socket.io/1/?t=1606845620690 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7ae57b664748>: Failed to establish a new connection: [Errno 111] Connection refused'))

So looks like 8000 is not an option for my TV as well. The list of opened ports (nmap -PN 192.168.2.23):

PORT     STATE SERVICE
4443/tcp open  pharos
7676/tcp open  imqbrokerd
8080/tcp open  http-proxy
8443/tcp open  https-alt

I don't have an option to use API token anywhere on TV, but I logged in with Samsung account. Also, I found "Remote control" under "Support" menu. It displays a PIN on the screen to pass it to Samsung Support to enable remote control for them. Not sure if this is the same functionality, but I tried to use that PIN with SmartCrypto by eclair4151 and no luck. Actually, that script always gives me the same output:

Current state: stopped
Pin NOT on TV
Please enter pin from tv: 

And no PIN on TV is displayed.

EPMatt commented 3 years ago

Hi @estevez-dev, Your device doesn't have port 8000 opened. Unfortunately, that's the same issue we're having here. For now we've proof that only @AKuHAK managed to get that port opened on his TV.

I can confirm the same behaviour with the SmartCrypto by eclair4151 script.

EPMatt commented 3 years ago

Yes, I am logged in with a Samsung account and get Samsung smartthings token as described here: https://github.com/balmli/com.samsung.smart#smartthings-api

@AKuHAK how did you use that token?

AKuHAK commented 3 years ago

Yes, I am logged in with a Samsung account and get Samsung smartthings token as described here: https://github.com/balmli/com.samsung.smart#smartthings-api

@AKuHAK how did you use that token?

I didn't get it to work, unfortunately.

flostingapplesauce commented 3 years ago

bash-5.0# nmap -p- 192.168.75.210 Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-02 09:59 EST Nmap scan report for 192.168.75.210 Host is up (0.018s latency). Not shown: 65532 closed ports PORT STATE SERVICE 7011/tcp open talon-disc 7676/tcp open imqbrokerd 8080/tcp open http-proxy MAC Address: 38:01:95:01:xx:xx (Samsung Electronics)

Nmap done: 1 IP address (1 host up) scanned in 39.87 seconds bash-5.0#

dariob84 commented 3 years ago

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080 <Response [403]> Traceback (most recent call last): File "get_token.py", line 40, in main(sys.argv[1:]) File "get_token.py", line 36, in main PySmartCrypto(ip, port) File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 124, in init self._connection = self.connect() File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 100, in connect connection = websocket.create_connection(websocket_url) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 515, in create_connection websock.connect(url, *options) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 226, in connect self.handshake_response = handshake(self.sock, addrs, **options) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 80, in handshake status, resp = _get_resp_headers(sock) File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers) websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

i ran nmap

C:\temp\samsungtv_encrypted>nmap -PN 192.168.1.31 Not shown: 998 closed ports PORT STATE SERVICE 7676/tcp open imqbrokerd 8080/tcp open http-proxy

EPMatt commented 3 years ago

Hi everyone, while doing a little research I came across this mobile app which allows to control Samsung Smart TVs with a phone or a smartwatch. In their manual they provide a list of compatible devices, which clearly states:

Interestingly, it states that @AKuHAK's TV series, H4xxx should not be compatible, but he managed to succesfully retrieve the token, since it's device provides the service on port 8000, while ours don't.

As stated in the app manual, below the list of compatible devices:

It’s important to understand that not all models within a Series are supported, as indicated in the last column. If your H or J-Series TV doesn’t show a PIN code when myTifi requests for it, your TV is not compatible.

For H and J-Series they provide additional info here:

When connecting to your H or J-Series, myTifi requests a PIN code. ... If your TV doesn’t show a PIN code, your TV is probably not compatible. These are TVs like J5200, J5300, J5205, J6203, J620D, etc. See the list of compatible models.

These are mid-range Smart TVs which are build with less powerful hardware. Therefor it’s not capable anymore to run all software features. As a result the feature for remote network control is disabled by Samsung. Please note that this is not a limitation of myTifi, but a limited feature set of your Samsung TV.

I think that we can assume that our TVs don't support the remote control feature. We could perform other attempts, trying somehow to open port 8000, but I really doubt this is possible.

The only way I can imagine this could work is by editing some settings in the service menu (dangerous, especially without proper documentation) or upgrading the firmware to a version for a supported model (really bad things could happen, and the device could be easily bricked this way).

So in the end, I don't think it's worth it. My suggestion is to add an entry in the documentation clearly stating that unfortunately our devices are not compatible. :(

EPMatt commented 3 years ago

@AKuHAK after looking at eclair4151's SmartCrypto implementation I can notice that the code uses the hardcoded port 8000 for connecting to the TV. So it seems intentional, and also as you reported, that was the only way you managed to get the pin displayed on the device. That was my mistake, I'm sorry. I'm submitting a PR for reverting the changes in 4eab94aaa8e112c7eda1d02ea88a3c03144e83cd.

Btw, did you manage to get the Home Assistant integration to work with your device, after you had retrieved the token?

AKuHAK commented 3 years ago

@AKuHAK after looking at eclair4151's SmartCrypto implementation I can notice that the code uses the hardcoded port 8000 for connecting to the TV. So it seems intentional, and also as you reported, that was the only way you managed to get the pin displayed on the device. That was my mistake, I'm sorry. I'm submitting a PR for reverting the changes in 4eab94aaa8e112c7eda1d02ea88a3c03144e83cd.

Btw, did you manage to get the Home Assistant integration to work with your device, after you had retrieved the token?

Yes, integration runs just fine, volume control works, source switch works. The only thing that doesnt work is power button, but it is no necessary cause I have broadlink RM.

I also integrated curl command that launch YouTube application on my TV.

I will later post all modifications that I made with my TV. Maybe some of them will open desired port for you too. I dont think that my tv is so unique in that terms.

EPMatt commented 3 years ago

Hi @AKuHAK, amazing, that could be very helpful, yep maybe there's a way to make this work also on our TVs. Thank you so much, we'll wait before closing this issue then. πŸ‘πŸ»

flostingapplesauce commented 3 years ago

Thank you EPMatt for all of your work.

This is likely not related, but there is an interesting community who work to root some Samsung televisions. Because, of course there would be πŸ˜†

https://www.samygo.tv

estevez-dev commented 3 years ago

Hi @EPMatt . Thanks for your investigation. I've manager to enter service menu and found "Smart control" option that was disabled. Just want to inform you that enabling it didn't help =) I need new TV ))

AKuHAK commented 3 years ago

Hi @AKuHAK, amazing, that could be very helpful, yep maybe there's a way to make this work also on our TVs. Thank you so much, we'll wait before closing this issue then. πŸ‘πŸ»

I probably found the solution: You need to disable the Watchdog in the Service menu. Details here: https://wiki.samygo.tv/index.php?title=Main_Page#Safety_Measures_.28which_you_shouldn.27t_start_without.29 Just press Info-Menu-Mute-Power while TV is off, navigate using up, down and select: Control -> Sub Option -> Watchdog -> [ on | off ]. Set it to off (by pressing Left or right) and reboot TV. You can also set RS-232 Jack to debug but it didn't make any changes for me. nmap output with watchdog on:

PORT     STATE SERVICE
7676/tcp open  imqbrokerd
9090/tcp open  zeus-admin

nmap output with watchdog off:

PORT     STATE SERVICE
7676/tcp open  imqbrokerd
8000/tcp open  http-alt
8001/tcp open  vcom-tunnel
8080/tcp open  http-proxy
8443/tcp open  https-alt
9090/tcp open  zeus-admin
estevez-dev commented 3 years ago

Hi @AKuHAK I tried this as well. No luck for my TV =( Setting RS232 to debug is needed to be able to resurrect your TV once you'll kill it with some wrong Service Menu settings ;-)

AKuHAK commented 3 years ago

Try to log in with developer account: Login: develop, password: any For me, ports opened only after a minute or two after login

AKuHAK commented 3 years ago

if port 8001 is opened this command will launch YouTube on your TV: curl -X POST http://192.168.1.109:8001/ws/apps/YouTube

AKuHAK commented 3 years ago

Hi @AKuHAK I tried this as well. No luck for my TV =( Setting RS232 to debug is needed to be able to resurrect your TV once you'll kill it with some wrong Service Menu settings ;-)

Ok here is my setup (at least what I can remember so far).

AKuHAK commented 3 years ago

BTW I performed Smart Hub reset and now I can use both ports: 8080 and 8001 for pairing. Maybe this will help people that have port 8001 closed. But you still need port 8000 opened for WebSocket requests.

tcp/7676 UPNP tcp/8000 Main webservice port tcp/8080 Secure Pairing port

Small tip: I managed how to get never expired tokens. Just use any session-id greater than 1.

epenet commented 2 years ago

Small tip: I managed how to get never expired tokens. Just use any session-id greater than 1.

@AKuHAK I am working on implementing the SamsungTV J/H model functionnality into Home Assistant core, and I have just now stumbled upon this thread. I am interested to understand what you mean about the session-id. My understanding is that the session-id is given to you by the pairing process, so how do you force a session-id greater than 1?