Ape/samsungctl

Library no longer functions for websocket commands since firmware update. "Invalid opcode"

Opened this issue ยท 66 comments

My Samsung M series TV updated to firmware 1250 last night. They must have changed the websocket protocol because now this library and every other 3rd party Samsung app no longer works.

Traceback (most recent call last):
File "C:/Users/tomer/PycharmProjects/samsung/main.py", line 15, in
with samsungctl.Remote(tv_config) as remote:
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\samsungctl\remote.py", line 10, in init
self.remote = RemoteWebsocket(config)
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\samsungctl\remote_websocket.py", line 25, in init
self._read_response()
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\samsungctl\remote_websocket.py", line 62, in _read_response
response = self.connection.recv()
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\websocket_core.py", line 293, in recv
opcode, data = self.recv_data()
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\websocket_core.py", line 310, in recv_data
opcode, frame = self.recv_data_frame(control_frame)
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\websocket_core.py", line 323, in recv_data_frame
frame = self.recv_frame()
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\websocket_core.py", line 357, in recv_frame
return self.frame_buffer.recv_frame()
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\websocket_abnf.py", line 362, in recv_frame
frame.validate(self.skip_utf8_validation)
File "C:\Users\tomer\AppData\Local\Programs\Python\Python35-32\lib\site-packages\websocket_abnf.py", line 173, in validate
raise WebSocketProtocolException("Invalid close opcode.")
websocket._exceptions.WebSocketProtocolException: Invalid close opcode.

Here is the crash although it most likely isn't very helpful. I will work on reverse engineering the official Samsung smart view app tomorrow which still works fine.

I got a NU8000 recently and even SmartView app doesn't work (It doesn't find the TV). Only Smartthings seems to find and be able to control the TV with wifi...

SamsungCTL gives the {u'event': u'ms.channel.unauthorized'} error.

Same issue, occurred after TV firmware update.
root@raspberrypi:~/AlexaControlledSamsungTV# /usr/bin/python3 /root/AlexaControlledSamsungTV/alexasmartcli.py start -m
starting server...
server running. Pres CTRL + C to stop
Failed to send message to TV: Invalid close opcode.

'tv_model' : 'UN82MU8000',

root@raspberrypi:~/AlexaControlledSamsungTV# uname -a
Linux raspberrypi 4.9.80-v7+ #1098 SMP Fri Mar 9 19:11:42 GMT 2018 armv7l GNU/Linux

root@raspberrypi:~/AlexaControlledSamsungTV# samsungctl --version
samsungctl 0.7.1

Ran into the same issue yesterday morning. Tried a number of ways and it just wouldn't go.

I'll add a "me too" to this one. *New user, so I can't confirm if it ever worked. New install, fresh out of the box TV, model UN32N5300. Dump from "api/v2/":
{"device":{"FrameTVSupport":"false","GamePadSupport":"true","ImeSyncedSupport":"true","OS":"Tizen","TokenAuthSupport":"true","VoiceSupport":"false","countryCode":"US","description":"Samsung DTV RCR","developerIP":"0.0.0.0","developerMode":"0","duid":"uuid:77298b13-353d-4849-85bf-2267744cf696","firmwareVersion":"Unknown","id":"uuid:77298b13-353d-4849-85bf-2267744cf696","ip":"192.168.0.150","model":"18_KANTS_FHD","modelName":"UN32N5300","name":"[TV] Samsung 5 Series (32)","networkType":"wired","resolution":"1920x1080","smartHubAgreement":"true","type":"Samsung SmartTV","udn":"uuid:77298b13-353d-4849-85bf-2267744cf696","wifiMac":"c0:48:e6:d7:c2:5d"},"id":"uuid:77298b13-353d-4849-85bf-2267744cf696","isSupport":"{\"DMP_DRM_PLAYREADY\":\"false\",\"DMP_DRM_WIDEVINE\":\"false\",\"DMP_available\":\"true\",\"EDEN_available\":\"true\",\"FrameTVSupport\":\"false\",\"ImeSyncedSupport\":\"true\",\"TokenAuthSupport\":\"true\",\"remote_available\":\"true\",\"remote_fourDirections\":\"true\",\"remote_touchPad\":\"true\",\"remote_voiceControl\":\"false\"}\n","name":"[TV] Samsung 5 Series (32)","remote":"1.0","type":"Samsung SmartTV","uri":"http://192.168.0.150:8001/api/v2/","version":"2.0.25"}

And the error:
[19:10:57] openhabian@openHABianPi:~$ python3 -m samsungctl --host 192.168.0.150 --port 8001 --method websocket Traceback (most recent call last): File "/usr/lib/python3.4/runpy.py", line 170, in _run_module_as_main "__main__", mod_spec) File "/usr/lib/python3.4/runpy.py", line 85, in _run_code exec(code, run_globals) File "/usr/local/lib/python3.4/dist-packages/samsungctl/__main__.py", line 133, in <module> main() File "/usr/local/lib/python3.4/dist-packages/samsungctl/__main__.py", line 110, in main with Remote(config) as remote: File "/usr/local/lib/python3.4/dist-packages/samsungctl/remote.py", line 11, in __init__ self.remote = RemoteWebsocket(config) File "/usr/local/lib/python3.4/dist-packages/samsungctl/remote_websocket.py", line 30, in __init__ self._read_response() File "/usr/local/lib/python3.4/dist-packages/samsungctl/remote_websocket.py", line 72, in _read_response raise exceptions.UnhandledResponse(response) samsungctl.exceptions.UnhandledResponse: {'event': 'ms.channel.unauthorized'}

Yep, same as above for me. Additionally, here is the output of /logs when running samsungctl --host <host> -i --method=websocket:

DEBUG | "IPC callRPC : result : true\n" | "timestamp: 1540948125873, file: IpcClient.cpp, func: transceive_cb_ : 190"
-- | -- | --
DEBUG | "IPC callRPC : result : true\n" | "timestamp: 1540948125863, file: IpcClient.cpp, func: transceive_cb_ : 190"
DEBUG | "## notifyRemoteNumbers ##" | "timestamp: 1540948125858, file: TizenDevice.cpp, func: notifyRemoteNumbers : 649"
DEBUG | "Client(id:) has disconnected" | "timestamp: 1540948125858, file: RemoteChannel.cpp, func: onSocketClose : 1027"
ERROR | "error(GetSocketInfo) : can't find socket info" | "timestamp: 1540948125858, file: RemoteChannel.cpp, func: GetSocketInfo : 370"

Got this half figured out. Swap the port to 8002 and encapsulate it in SSL. Then, commands work. However, they require manual approval on the TV for every connection, multiple commands can be issued in one connection, but the moment you establish a new connection, you need to manually approve again.

So basically Samsung added "token auth" which you can see in their UPnP advertisement. Whatever that is. So they reply with this when you establish the websocket after you approve it on the TV:

{
"data": {
"clients": [
{
"attributes": {
"name": "fooBase64=="
},
"connectTime": 1541354167097,
"deviceName": "fooBase64==",
"id": "xy123",
"isHost": false
}
],
"id": "xy123",
"token": "65811577"
},
"event": "ms.channel.connect"
}

So obviously the solution is to figure out how to use "token" such that the next time you connect, the TV knows you've already been approved. Since I don't have anything to reverse engineer at the moment that does it correctly, I'm not sure what the correct way to do that is. It could be as simple as adding ?token=xyxyxz to the initial apiv2 GET, but I haven't tried anything yet.

Tried adding ?token=xyxyxz to the GET /api/v2/channels/samsung.remote.control?name=foo and that did not work. For the moment, stumped. My random guess is they hash the connectTime with the token or something like that. Reverse engineering would be the best course if anyone has something that works.

Has anyone been able to run a wireshark capture on the smart view app? For some reason i am unable to get my wire shark instance to pick up any websocket messages between the app and TV. I tried turning my pc into a hotspot and running the websockets through it but the app is unable to find the tv when i do that

In my testing, SmartView2 does not support any 2018 model. I don't think it has been updated for this token auth. There are third party vendors that are supposedly compatible with 2018 models, but I don't have those products.

Hmm yea but SmartView2 works fine for my 2017 TV model with the updated firmware, so it must have some updated compatibility.

Doing a capture on that sounds highly useful. I have 2 models from 2018 and they are not detected by it while a 2016 model works fine the old way. The first questions would be if it uses port 8002 SSL like the 2018 models, and inside that, does it use the token auth. Figuring out the right response for subsequent connections once we have a token is all that is needed here.

To capture SmartView, I use an old '90s era Ethernet Hub connected to a 90s era WiFi router and plug my WireShark machine into that Hub which is all promiscuous. Or, use a managed Ethernet switch with port mirroring. Or, for extreme cases, a dedicated tap:
https://www.amazon.com/midBit-Technologies-LLC-100-1000/dp/B0175EODCE

Side note the app MyTifi just had an iOS update to support the TV's again. I have talked to him before and he is very secretive about his code but at least this shows it cant be to hard to fix the issue if he did it in like 5 days

MyTifi does not work. It does exactly what I said above. Connects once, gets manual approval, commands work, and then it can't connect again without manual approval.

Ah ok. i should have probably actually tested it before saying anything haha

When connection is established to:
wss://@ip:8002/api/v2/channels/samsung.remote.control?name=base64Name

and token is returned. You can use this token:
wss://@ip:8002/api/v2/channels/samsung.remote.control?name=base64Name&token=THETOKEN
on next reconnects.

Withouth this token - the TV is asking me to Allow/Deny the device that is trying to connect every time - no matter that previously i choosed Allow (the name, device and tv ips are the same).

When i add the token to the wss url as parameter - i dont get Allow/Deny action (even when TV ip is different).

For now , this is the only way i found useful for this token.

ill try this when i get home today. If that really is that easy then it would be great

I can confirm that works. It was just an error in my REST API syntax yesterday.

Thanks for getting this hammered out so quickly.

I have another brainstorm scenario that i want to understand.
The coap:// protocol that tv exposes.
If you make coap reqest to
coap://239.255.255.250:5683/oic/res
You get bunch of resources.
When i try to call this resources i get 4.01 unauthorized.
Maybe if someone of you guys is more familiar with coap architecture can give some clue on that?

i have made a pull request to support everything!
#94

@Ape this pr supports new tv firmware, and uses a new config method "websocketssl" which also will need port 8002

Wish I knew how to incorporate this fix into HomeAssistant myself

it's pretty easy actually.

download the modified library from here
https://github.com/eclair4151/samsungctl/tree/websocketssl

copy the file remote_websocket.py in that new package to your site-packages\samsungctl folder.

you will need to edit the config for samsungctl and change the port to 8002

but that should be all that is needed.

@galinkyuchukov

When connection is established to:
wss://@ip:8002/api/v2/channels/samsung.remote.control?name=base64Name
and token is returned.

Wonderful! Btw, how did you find that?

@vitalets

nmap -p1-65535 ip

I got as result bunch of open ports , including 8001 and 8002.

Since , before firmware update i used ws:// on 8001. I thought 8002 will be the secure version. First tested with all ports and ws .. and then with all on wss:// actualy. :)

After connection the token was just there.

I have another brainstorm scenario that i want to understand.
The coap:// protocol that tv exposes.
If you make coap reqest to
coap://239.255.255.250:5683/oic/res
You get bunch of resources.
When i try to call this resources i get 4.01 unauthorized.
Maybe if someone of you guys is more familiar with coap architecture can give some clue on that?

Interesting..
can you post an request/response sample ?

it's pretty easy actually.

download the modified library from here
https://github.com/eclair4151/samsungctl/tree/websocketssl

copy the file remote_websocket.py in that new package to your site-packages\samsungctl folder.

you will need to edit the config for samsungctl and change the port to 8002

but that should be all that is needed.

I did this and the TV just continues to ask me to authorise it, no matter how many times i say yes. I imagine this has to do with what @galinkyuchukov said. You need to add &token=THETOKEN however I don't know what i'd edit to do this or how to get the token!

it's pretty easy actually.
download the modified library from here
https://github.com/eclair4151/samsungctl/tree/websocketssl
copy the file remote_websocket.py in that new package to your site-packages\samsungctl folder.
you will need to edit the config for samsungctl and change the port to 8002
but that should be all that is needed.

I did this and the TV just continues to ask me to authorise it, no matter how many times i say yes. I imagine this has to do with what @galinkyuchukov said. You need to add &token=THETOKEN however I don't know what i'd edit to do this or how to get the token!

@DemiMelfice Set the timeout parameter to something like 5. I had the same problem and this gave me enough time to hit "allow" on the tv remote and get his working.

ok cool we need to make a modification to cause the program to stall if this is a new connection to a TV. (meaning there is no token being passed the first time) that is fairly easy to make the modifications for. I also wanted to change how the whole timeout thing works anyway but I would need someone that has a newer TV to test something for me.

in the remote_websocket.py file change

def _read_response(self):
    response = self.connection.recv()
    response = json.loads(response)

    if response["event"] != "ms.channel.connect":
        self.close()
        raise exceptions.UnhandledResponse(response)

    logging.debug("Access granted.")

to read

def _read_response(self):
    response = self.connection.recv()
    response = json.loads(response)
    print(json.dumps(response, indent=4))

    if response["event"] != "ms.channel.connect":
        self.close()
        raise exceptions.UnhandledResponse(response)

    logging.debug("Access granted.")

I am interested in knowing what the response is after a key is sent. or if there even is one. If there is one then we can use a threading.Event() object to handle the timeout. because right now the timeout is something that gets set to the maximum amount of time the TV is going to take to process a key request. which can be variable based on TV model and year and also by what button it is that has been pressed. by using that event object we can have the program stall with a default timeout value and the stall would be release if either a response comes in or the default takes place. which ever is first. this would be a far better mechanism and also allow for much faster key presses. and having that feature like that we would be able to force a longer timeout if a token was not provided in the config. and produce an exception if that timeout expires before a response has come in.

But first thing is first. I need to know what the data is that comes in after a key press. actually if someone would be willing to unpair/unauthorize and start the process from scratch and paste all of the output to me that would be really helpful. pair the remote and also a bunch of keypresses. It is going to print out the data to the console window.

I really wish I left this until now! I've just managed to get it working by changing the timeout to = 5 as @Murph24 suggested (also thanks for the help).

I'm using Home Assistant as well in a docker and here is what I did and the results:

remote_websocket.py
line 23 if config["timeout"] == 5: <- this was 0 before

samsungtv.py (this is the components folder in Home-Assistant)

line 30 DEFAULT_TIMEOUT = 5 <- this was 1 before

I think that this acts like your samsungctl.conf

Sorry about my ignorance, i'm quite new to a lot of home-assistant and the components like this samsungctl that its using.

It didn't work when I changed the remote_websocket.py to 5 on its own so I don't think that change made any difference and was the update to the DEFAULT_TIMEOUT = 0 that made it work.

fbnts commented

it's pretty easy actually.

download the modified library from here
https://github.com/eclair4151/samsungctl/tree/websocketssl

copy the file remote_websocket.py in that new package to your site-packages\samsungctl folder.

you will need to edit the config for samsungctl and change the port to 8002

but that should be all that is needed.

I have updated remote_websocket.py from the above library but when I run samsungctl -i --host 192.168.99.209 --port 8002 --method websocket --timeout 5 I get the error:

Traceback (most recent call last):
  File "/usr/local/bin/samsungctl", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.6/dist-packages/samsungctl/__main__.py", line 110, in main
    with Remote(config) as remote:
  File "/usr/local/lib/python3.6/dist-packages/samsungctl/remote.py", line 11, in __init__
    self.remote = RemoteWebsocket(config)
  File "/usr/local/lib/python3.6/dist-packages/samsungctl/remote_websocket.py", line 28, in __init__
    self.connection = websocket.create_connection(url, config["timeout"])
  File "/usr/local/lib/python3.6/dist-packages/websocket/_core.py", line 511, in create_connection
    websock.connect(url, **options)
  File "/usr/local/lib/python3.6/dist-packages/websocket/_core.py", line 223, in connect
    self.handshake_response = handshake(self.sock, *addrs, **options)
  File "/usr/local/lib/python3.6/dist-packages/websocket/_handshake.py", line 79, in handshake
    status, resp = _get_resp_headers(sock)
  File "/usr/local/lib/python3.6/dist-packages/websocket/_handshake.py", line 150, in _get_resp_headers
    status, resp_headers, status_message = read_headers(sock)
  File "/usr/local/lib/python3.6/dist-packages/websocket/_http.py", line 298, in read_headers
    line = recv_line(sock)
  File "/usr/local/lib/python3.6/dist-packages/websocket/_socket.py", line 102, in recv_line
    c = recv(sock, 1)
  File "/usr/local/lib/python3.6/dist-packages/websocket/_socket.py", line 94, in recv
    "Connection is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.

All was working fine until the recent TV firmware update.

Is there something else I need to do to get it to work?

It's the same for me. Doesn't working anymore, neither on port 8001 , nor on the 8002 one.

Connection is already closed.

Usually means that this device was already Allowed (Paired) with the TV once. You know that top-right Allow the device to connect on the TV screen.

Bear in mind that once device is Allowed when connected to the tv on LAN, if the TV and device are now communicating on Wifi ... the old token will not work and most probably the old pairing is gone.

To bypass this i had to manually select my device from Devices list in the TV and delete it.
Then next attempt to ......8002 is successful and i have token in the response.

fbnts commented

I have just checked and I don't have any devices on my TV's Device List. I had to reset my TV to try and solve a locking up issue.

Running TCP Dump I can see the request:

GET /api/v2/channels/samsung.remote.control?name=c2Ftc3VuZ2N0bA== HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.99.209:8002
Origin: http://192.168.99.209:8002
Sec-WebSocket-Key: SuNCpWcCNJPQHN9pbJAekg==
Sec-WebSocket-Version: 13

Shouldn't the request be encrypted?

I have just checked and I don't have any devices on my TV's Device List.

I'm also getting "connection already closed", even though I have nothing in my TV's device list. Any options?

@jpmassena I was going crazy over why my NU8000 is not detected by SmartView (customer service was useless, as expected). I am glad I am not the only one.

Hello !
Before the upgrade to the 1250 firmware, I was able to control my Samsung TV with samsungctl through Domoticz.
Since I've download the new remote_websocket.py file, there isn't error messages anymore when I try a samsungctl command, but I obtain a "permission denied" even if I select "authorise" on my TV.
I guess I have to create a token.txt file somewhere, but I don't know exactly where, and I can't find how to obtain this token... I tried to access to the "wss://@tvip:8002/..." as mentioned sooner with several browser, but I have no response from the TV...
I need some help...
Thanks for reading !

Hello please move all discussion about websocket issues to kdschlosser#2

The fix for the websockets stuff is in the repo on the websocket branch. Try to clone it and see if that helps you out.

Gday, Ive got the fix listed above working manually. Will this eventually be merged into master so it makes it into home assistant?

Hello please move all discussion about websocket issues to kdschlosser#2

The fix for the websockets stuff is in the repo on the websocket branch. Try to clone it and see if that helps you out.

Does this mean that it will be included in hass.io releases? Or will I have te manually do something?

I am getting a error when running @eclair4151 and @kdschlosser version with my recenlt updated MU7000. Commands do not work. Below is the error:

~/samsungctl$ samsungctl --host 192.168.123.203 --method websocket --port 8002 KEY_HDMI
Traceback (most recent call last):
File "/usr/local/bin/samsungctl", line 9, in
load_entry_point('samsungctl==0.7.0+1', 'console_scripts', 'samsungctl')()
File "build/bdist.linux-x86_64/egg/samsungctl/main.py", line 112, in main
File "build/bdist.linux-x86_64/egg/samsungctl/remote.py", line 11, in init
File "build/bdist.linux-x86_64/egg/samsungctl/remote_websocket.py", line 25, in init
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_core.py", line 494, in create_connection
websock.connect(url, **options)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_core.py", line 220, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_handshake.py", line 69, in handshake
status, resp = _get_resp_headers(sock)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_handshake.py", line 133, in _get_resp_headers
status, resp_headers, status_message = read_headers(sock)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_http.py", line 236, in read_headers
line = recv_line(sock)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_socket.py", line 102, in recv_line
c = recv(sock, 1)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_socket.py", line 94, in recv
"Connection is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.

Can anyone shed some light on the "Connection already closed" error?

I am getting a error when running @eclair4151 and @kdschlosser version with my recenlt updated MU7000. Commands do not work. Below is the error:

~/samsungctl$ samsungctl --host 192.168.123.203 --method websocket --port 8002 KEY_HDMI
Traceback (most recent call last):
File "/usr/local/bin/samsungctl", line 9, in
load_entry_point('samsungctl==0.7.0+1', 'console_scripts', 'samsungctl')()
File "build/bdist.linux-x86_64/egg/samsungctl/main.py", line 112, in main
File "build/bdist.linux-x86_64/egg/samsungctl/remote.py", line 11, in init
File "build/bdist.linux-x86_64/egg/samsungctl/remote_websocket.py", line 25, in init
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_core.py", line 494, in create_connection
websock.connect(url, **options)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_core.py", line 220, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_handshake.py", line 69, in handshake
status, resp = _get_resp_headers(sock)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_handshake.py", line 133, in _get_resp_headers
status, resp_headers, status_message = read_headers(sock)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_http.py", line 236, in read_headers
line = recv_line(sock)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_socket.py", line 102, in recv_line
c = recv(sock, 1)
File "/home/tw/.local/lib/python2.7/site-packages/websocket/_socket.py", line 94, in recv
"Connection is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.

Can anyone shed some light on the "Connection already closed" error?

I'm getting the same Connection already closed using the ssl_websocket_only branch on my NU7100. I'm running samsungctl --host 192.168.1.102 --port 8002 --method websocket KEY_VOLDOWN

Am I doing it wrong? Any confirmation that this model does/doesn't work?

I just tried again with @kdschlosser latest master commit and it works!

Me too it work as last post! Ty so much, was following this issue since 2 months, since last tv firmware update. It's like a Christmas gift thanks for all your work!

Right now I'm obsessed with adding some functionality from your samsungctl to my samsungtv.py for home assistant, but don't know if it's possible ยฏ/"/ยฏ

Me too it work as last post! Ty so much, was following this issue since 2 months, since last tv firmware update. It's like a Christmas gift thanks for all your work!

Right now I'm obsessed with adding some functionality from your samsungctl to my samsungtv.py for home assistant, but don't know if it's possible ยฏ/"/ยฏ

Yep. Working on homeassistant too. Ive got basic on/off working in HA but trying to figure ot how to send keys. Also then which keys to send, as the KEY_HDMI just selects the last HDMI input you had. Do you know how to select a specific one?

if you post issues on my repository it would be better. I can assist you in getting whatever it is you need. I have all of the discrete codes for the source buttons added to the master branch of my repo.

https://github.com/kdschlosser/samsungctl

here is the list of the key codes supported by the original version of the samsungctl program.

Key code Description
KEY_POWEROFF Power off
KEY_UP Up
KEY_DOWN Down
KEY_LEFT Left
KEY_RIGHT Right
KEY_CHUP P Up
KEY_CHDOWN P Down
KEY_ENTER Enter
KEY_RETURN Return
KEY_CH_LIST Channel List
KEY_MENU Menu
KEY_SOURCE Source
KEY_GUIDE Guide
KEY_TOOLS Tools
KEY_INFO Info
KEY_RED A / Red
KEY_GREEN B / Green
KEY_YELLOW C / Yellow
KEY_BLUE D / Blue
KEY_PANNEL_CHDOWN 3D
KEY_VOLUP Volume Up
KEY_VOLDOWN Volume Down
KEY_MUTE Mute
KEY_0 0
KEY_1 1
KEY_2 2
KEY_3 3
KEY_4 4
KEY_5 5
KEY_6 6
KEY_7 7
KEY_8 8
KEY_9 9
KEY_DTV TV Source
KEY_HDMI HDMI Source
KEY_CONTENTS SmartHub

and here is the list of the supported keycodes in the updated version in my repository I only added a few more ๐Ÿ˜Ž

Power Keys


KEY_POWEROFF                    Power OFF
KEY_POWERON                     Power On
KEY_POWER                       Power Toggle

Input Keys


KEY_SOURCE                      Source
KEY_COMPONENT1                  Component 1
KEY_COMPONENT2                  Component 2
KEY_AV1                         AV 1
KEY_AV2                         AV 2
KEY_AV3                         AV 3
KEY_SVIDEO1                     S Video 1
KEY_SVIDEO2                     S Video 2
KEY_SVIDEO3                     S Video 3
KEY_HDMI                        HDMI
KEY_HDMI1                       HDMI 1
KEY_HDMI2                       HDMI 2
KEY_HDMI3                       HDMI 3
KEY_HDMI4                       HDMI 4
KEY_FM_RADIO                    FM Radio
KEY_DVI                         DVI
KEY_DVR                         DVR
KEY_TV                          TV
KEY_ANTENA                      Analog TV
KEY_DTV                         Digital TV

Number Keys


KEY_1                           Key1
KEY_2                           Key2
KEY_3                           Key3
KEY_4                           Key4
KEY_5                           Key5
KEY_6                           Key6
KEY_7                           Key7
KEY_8                           Key8
KEY_9                           Key9
KEY_0                           Key0

Misc Keys


KEY_PANNEL_CHDOWN               3D
KEY_ANYNET                      AnyNet+
KEY_ESAVING                     Energy Saving
KEY_SLEEP                       Sleep Timer
KEY_DTV_SIGNAL                  DTV Signal

Channel Keys


KEY_CHUP                        Channel Up
KEY_CHDOWN                      Channel Down
KEY_PRECH                       Previous Channel
KEY_FAVCH                       Favorite Channels
KEY_CH_LIST                     Channel List
KEY_AUTO_PROGRAM                Auto Program
KEY_MAGIC_CHANNEL               Magic Channel

Volume Keys


KEY_VOLUP                       Volume Up
KEY_VOLDOWN                     Volume Down
KEY_MUTE                        Mute

Direction Keys


KEY_UP                          Navigation Up
KEY_DOWN                        Navigation Down
KEY_LEFT                        Navigation Left
KEY_RIGHT                       Navigation Right
KEY_RETURN                      Navigation Return/Back
KEY_ENTER                       Navigation Enter

Media Keys


KEY_REWIND                      Rewind
KEY_STOP                        Stop
KEY_PLAY                        Play
KEY_FF                          Fast Forward
KEY_REC                         Record
KEY_PAUSE                       Pause
KEY_LIVE                        Live
KEY_QUICK_REPLAY                fnKEY_QUICK_REPLAY
KEY_STILL_PICTURE               fnKEY_STILL_PICTURE
KEY_INSTANT_REPLAY              fnKEY_INSTANT_REPLAY

Picture in Picture


KEY_PIP_ONOFF                   PIP On/Off
KEY_PIP_SWAP                    PIP Swap
KEY_PIP_SIZE                    PIP Size
KEY_PIP_CHUP                    PIP Channel Up
KEY_PIP_CHDOWN                  PIP Channel Down
KEY_AUTO_ARC_PIP_SMALL          PIP Small
KEY_AUTO_ARC_PIP_WIDE           PIP Wide
KEY_AUTO_ARC_PIP_RIGHT_BOTTOM   PIP Bottom Right
KEY_AUTO_ARC_PIP_SOURCE_CHANGE  PIP Source Change
KEY_PIP_SCAN                    PIP Scan

Modes


KEY_VCR_MODE                    VCR Mode
KEY_CATV_MODE                   CATV Mode
KEY_DSS_MODE                    DSS Mode
KEY_TV_MODE                     TV Mode
KEY_DVD_MODE                    DVD Mode
KEY_STB_MODE                    STB Mode
KEY_PCMODE                      PC Mode

Color Keys


KEY_GREEN                       Green
KEY_YELLOW                      Yellow
KEY_CYAN                        Cyan
KEY_RED                         Red

Teletext


KEY_TTX_MIX                     Teletext Mix
KEY_TTX_SUBFACE                 Teletext Subface

Aspect Ratio


KEY_ASPECT                      Aspect Ratio
KEY_PICTURE_SIZE                Picture Size
KEY_4_3                         Aspect Ratio 4:3
KEY_16_9                        Aspect Ratio 16:9
KEY_EXT14                       Aspect Ratio 3:4 (Alt)
KEY_EXT15                       Aspect Ratio 16:9 (Alt)

Picture Mode


KEY_PMODE                       Picture Mode
KEY_PANORAMA                    Picture Mode Panorama
KEY_DYNAMIC                     Picture Mode Dynamic
KEY_STANDARD                    Picture Mode Standard
KEY_MOVIE1                      Picture Mode Movie
KEY_GAME                        Picture Mode Game
KEY_CUSTOM                      Picture Mode Custom
KEY_EXT9                        Picture Mode Movie (Alt)
KEY_EXT10                       Picture Mode Standard (Alt)

Menus


KEY_MENU                        Menu
KEY_TOPMENU                     Top Menu
KEY_TOOLS                       Tools
KEY_HOME                        Home
KEY_CONTENTS                    Contents
KEY_GUIDE                       Guide
KEY_DISC_MENU                   Disc Menu
KEY_DVR_MENU                    DVR Menu
KEY_HELP                        Help

OSD


KEY_INFO                        Info
KEY_CAPTION                     Caption
KEY_CLOCK_DISPLAY               ClockDisplay
KEY_SETUP_CLOCK_TIMER           Setup Clock
KEY_SUB_TITLE                   Subtitle

Zoom


KEY_ZOOM_MOVE                   Zoom Move
KEY_ZOOM_IN                     Zoom In
KEY_ZOOM_OUT                    Zoom Out
KEY_ZOOM1                       Zoom 1
KEY_ZOOM2                       Zoom 2

Other Keys


KEY_WHEEL_LEFT                  Wheel Left
KEY_WHEEL_RIGHT                 Wheel Right
KEY_ADDDEL                      Add/Del
KEY_PLUS100                     Plus 100
KEY_AD                          AD
KEY_LINK                        Link
KEY_TURBO                       Turbo
KEY_CONVERGENCE                 Convergence
KEY_DEVICE_CONNECT              Device Connect
KEY_11                          Key 11
KEY_12                          Key 12
KEY_FACTORY                     Key Factory
KEY_3SPEED                      Key 3SPEED
KEY_RSURF                       Key RSURF
KEY_FF_                         FF_
KEY_REWIND_                     REWIND_
KEY_ANGLE                       Angle
KEY_RESERVED1                   Reserved 1
KEY_PROGRAM                     Program
KEY_BOOKMARK                    Bookmark
KEY_PRINT                       Print
KEY_CLEAR                       Clear
KEY_VCHIP                       V Chip
KEY_REPEAT                      Repeat
KEY_DOOR                        Door
KEY_OPEN                        Open
KEY_DMA                         DMA
KEY_MTS                         MTS
KEY_DNIe                        DNIe
KEY_SRS                         SRS
KEY_CONVERT_AUDIO_MAINSUB       Convert Audio Main/Sub
KEY_MDC                         MDC
KEY_SEFFECT                     Sound Effect
KEY_PERPECT_FOCUS               PERPECT Focus
KEY_CALLER_ID                   Caller ID
KEY_SCALE                       Scale
KEY_MAGIC_BRIGHT                Magic Bright
KEY_W_LINK                      W Link
KEY_DTV_LINK                    DTV Link
KEY_APP_LIST                    Application List
KEY_BACK_MHP                    Back MHP
KEY_ALT_MHP                     Alternate MHP
KEY_DNSe                        DNSe
KEY_RSS                         RSS
KEY_ENTERTAINMENT               Entertainment
KEY_ID_INPUT                    ID Input
KEY_ID_SETUP                    ID Setup
KEY_ANYVIEW                     Any View
KEY_MS                          MS
KEY_MORE
KEY_MIC
KEY_NINE_SEPERATE
KEY_AUTO_FORMAT                 Auto Format
KEY_DNET                        DNET

Auto Arc Keys


KEY_AUTO_ARC_C_FORCE_AGING
KEY_AUTO_ARC_CAPTION_ENG
KEY_AUTO_ARC_USBJACK_INSPECT
KEY_AUTO_ARC_RESET
KEY_AUTO_ARC_LNA_ON
KEY_AUTO_ARC_LNA_OFF
KEY_AUTO_ARC_ANYNET_MODE_OK
KEY_AUTO_ARC_ANYNET_AUTO_START
KEY_AUTO_ARC_CAPTION_ON
KEY_AUTO_ARC_CAPTION_OFF
KEY_AUTO_ARC_PIP_DOUBLE
KEY_AUTO_ARC_PIP_LARGE
KEY_AUTO_ARC_PIP_LEFT_TOP
KEY_AUTO_ARC_PIP_RIGHT_TOP
KEY_AUTO_ARC_PIP_LEFT_BOTTOM
KEY_AUTO_ARC_PIP_CH_CHANGE
KEY_AUTO_ARC_AUTOCOLOR_SUCCESS
KEY_AUTO_ARC_AUTOCOLOR_FAIL
KEY_AUTO_ARC_JACK_IDENT
KEY_AUTO_ARC_CAPTION_KOR
KEY_AUTO_ARC_ANTENNA_AIR
KEY_AUTO_ARC_ANTENNA_CABLE
KEY_AUTO_ARC_ANTENNA_SATELLITE

Panel Keys


KEY_PANNEL_POWER
KEY_PANNEL_CHUP
KEY_PANNEL_VOLUP
KEY_PANNEL_VOLDOW
KEY_PANNEL_ENTER
KEY_PANNEL_MENU
KEY_PANNEL_SOURCE
KEY_PANNEL_ENTER

Extended Keys


KEY_EXT1
KEY_EXT2
KEY_EXT3
KEY_EXT4
KEY_EXT5
KEY_EXT6
KEY_EXT7
KEY_EXT8
KEY_EXT11
KEY_EXT12
KEY_EXT13
KEY_EXT16
KEY_EXT17
KEY_EXT18
KEY_EXT19
KEY_EXT20
KEY_EXT21
KEY_EXT22
KEY_EXT23
KEY_EXT24
KEY_EXT25
KEY_EXT26
KEY_EXT27
KEY_EXT28
KEY_EXT29
KEY_EXT30
KEY_EXT31
KEY_EXT32
KEY_EXT33
KEY_EXT34
KEY_EXT35
KEY_EXT36
KEY_EXT37
KEY_EXT38
KEY_EXT39
KEY_EXT40
KEY_EXT41

@cnschulz you said:

Working on homeassistant too.

Is this now included in the component of Homeassistant or is there anything specific I should do?

Thomas

Can we expect this patch to be merged sometime soon?

@cnschulz Can you please indicate how you integrated the latest changes in HA? I would love to test it out.

I have it in a custom component already, just not sure how to link it to the new package. What do you have in REQUIREMENTS? In fact, can you hastebin your samsungtv.py file?

@arsaboo Check this link out. You can also put the new library as a custom component as well.

home-assistant/core#17802 (comment)

Things have changed a lot with this new library, so the guide is somewhat outdated. The basic idea is there, but you'll have to look over the new import statements and make adjustments as necessary

Thanks @Murph24

I updated the samsungtv.py and added the files from combination_branch to the samsungctl folder.

@arsaboo does this new code you posted above work on your NU8000 series? I am getting a connection failed message. :(

@keatontaylor Yes, I am able to see the TV status and turn on the TV from HA. Nothing else is working for me at the moment.

You can copy/paste the structure that I have and it should work for you. I did manually update the firmware to 1202 on my TV (not sure if it makes a difference).

Get this. samsungtv.py and samsungctl in custom_components

2019-01-10 21:15:15 INFO (MainThread) [homeassistant.loader] Loaded media_player.samsungtv from custom_components.media_player.samsungtv
2019-01-10 21:15:15 WARNING (MainThread) [homeassistant.loader] You are using a custom component for media_player.samsungtv which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you do experience issues with Home Assistant.
2019-01-10 21:15:20 INFO (MainThread) [homeassistant.components.media_player] Setting up media_player.samsungtv
2019-01-10 21:15:21 ERROR (MainThread) [homeassistant.components.media_player] Error while setting up platform samsungtv
File "/config/custom_components/media_player/samsungtv.py", line 81, in setup_platform
File "/config/custom_components/media_player/samsungtv.py", line 93, in init
from custom_components.samsungctl import exceptions

fbnts commented

Not sure if this belongs on this issue thread or the library referenced above, I have just tried the new files but get errors in the log when trying to send any remote codes like vol up/down:

2019-01-09 00:50:54 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/homeassistant/helpers/service.py", line 279, in _handle_service_platform_call
    await func(entity, data)
  File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/media_player/samsungtv.py", line 237, in mute_volume
    self.send_key('KEY_MUTE')
  File "/home/homeassistant/.homeassistant/custom_components/media_player/samsungtv.py", line 166, in send_key
    self.get_remote().control(key)
  File "/home/homeassistant/.homeassistant/custom_components/media_player/samsungtv.py", line 151, in get_remote
    self._remote = self._remote_class(self._config)
  File "/home/homeassistant/.homeassistant/custom_components/samsungctl/remote.py", line 11, in __init__
    self.remote = RemoteLegacy(config)
  File "/home/homeassistant/.homeassistant/custom_components/samsungctl/remote_legacy.py", line 39, in __init__
    self._read_response(True)
  File "/home/homeassistant/.homeassistant/custom_components/samsungctl/remote_legacy.py", line 71, in _read_response
    tv_name_len = int(codecs.encode(header[1:3], 'hex'), 16)
ValueError: invalid literal for int() with base 16: b

I'm trying to get the changes for this added to HA and having a load of grief. Can someone clarify please if you have to add a token parameter to a config file somewhere? Mine was complaining about an unknown key 'token' in the config dict.

Also, once this is working should it continue working without re-auth once the TV has been restarted. or do you need to allow it every time you turn it back on?

Is there any updates on this? Would be great if this gets merged and we can get our Samsung TVs working again :) :)

@skynet01 check out this fork that is still actively maintained and has been updated for all TV's
https://github.com/kdschlosser/samsungctl

Thanks @eclair4151, I am setting this up right now. Too bad it's not included in the official build since no new Samsung TVs will work with the current HA implementation

For anyone trying to add Samsung TV to Home Assistant, I've created a simple custom component: https://github.com/marysieek/smart_home/tree/master/custom_components/samsungtv_custom

I can test the code only with UE55MU6102K. The component communicates through WSS, over :8002 port and does not require re-auth with token - I'm still working on making the experience easier. Please note it is not a professional solution - just a result of weekend coding.

For anyone trying to add Samsung TV to Home Assistant, I've created a simple custom component: https://github.com/marysieek/smart_home/tree/master/custom_components/samsungtv_custom

How can we do this on Hass.OS ?

Thanks for addon @marysieek, On hassio i can't seem to install samsung-api requirement since hassio comes with pytho2.7 and it needs at least 3 to install it. Unless i am doing something wrong

So I'm new to samsungctl, just started using it last night... Its been an effort but now the TV is responding and asking me to allow, deny the device meaning my laptop. the problem is I get a permission denied and when I run the command again it simply re-asks me to allow/deny it again followed by command Traceback to permission denied again.
Samsung Model QN65Q9FNA

Here is the output any help would be appreciated
$ samsungctl --host 192.168.1.27 --port 8002 --method websocket KEY_POWEROFF { "data": { "token": "81994378", "clients": [ { "isHost": false, "attributes": { "name": "c2Ftc3VuZ2N0bA==" }, "id": "40876f0-826a-4c27-acb4-649ef4d8d6d", "connectTime": 1572803997333, "deviceName": "c2Ftc3VuZ2N0bA==" } ], "id": "40876f0-826a-4c27-acb4-649ef4d8d6d" }, "event": "ms.channel.connect" } Traceback (most recent call last): File "/usr/local/bin/samsungctl", line 11, in <module> load_entry_point('samsungctl==0.7.1+1', 'console_scripts', 'samsungctl')() File "/usr/local/lib/python2.7/dist-packages/samsungctl-0.7.1+1-py2.7.egg/samsungctl/__main__.py", line 110, in main with Remote(config) as remote: File "/usr/local/lib/python2.7/dist-packages/samsungctl-0.7.1+1-py2.7.egg/samsungctl/remote.py", line 11, in __init__ self.remote = RemoteWebsocket(config) File "/usr/local/lib/python2.7/dist-packages/samsungctl-0.7.1+1-py2.7.egg/samsungctl/remote_websocket.py", line 55, in __init__ self._read_response() File "/usr/local/lib/python2.7/dist-packages/samsungctl-0.7.1+1-py2.7.egg/samsungctl/remote_websocket.py", line 100, in _read_response with open(self.token_file, "w") as token_file: IOError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/samsungctl-0.7.1+1-py2.7.egg/samsungctl/token.txt'