Ape / samsungctl

Remote control Samsung televisions via a TCP/IP connection
MIT License
712 stars 189 forks source link

Launch app on tv #75

Open Mcgurk125 opened 6 years ago

Mcgurk125 commented 6 years ago

Apologies, if this is not worth creating a new issue for... its more of a question.

The Samsung Smart View application - Link - has the ability to launch apps on the TV (Netflix, Plex etc.) - I was wondering if it was possible to replicate these calls?

vitalets commented 5 years ago

But I'm looking for a way to get access without installing an application on Smart TV. Do you think that's possible?

I never see that in any docs/forums, so I think it is not possible. Even if you find such way, consider that any undocumented feature can be removed at some moment.

freman commented 5 years ago

I have up trying to drive the tv, I wrote an app that is basically an iframe that opens a websocket to a server in the office for remote control. From there we make it load whatever we want.

Didn't even know API 2 existed, I wonder if I can use that to ditch the websockets

vitalets commented 5 years ago

@freman

I wonder if I can use that to ditch the websockets

WebSockets also allow to launch/close/get-state of tv app, e.g:

// launch app
ws.send(JSON.stringify({
    method: 'ms.application.start',
    id: Date.now(),
    params: {
        id: '11101200001',
    }
}));

The method can be:

They all are also from Tizen sources.

Btw @freman how did you managed to find metaTag field in https://github.com/Ape/samsungctl/issues/75#issuecomment-375164834? I don't see it in Tizen sources anywhere =)

freman commented 5 years ago

Not those websockets, the ones our app uses it connects to a websocket server on the network giving us full direct control over the app, bypassing the tv os entirely.

No never did figure out that metadata

pegatron89 commented 5 years ago

not an app but can the source of the tv be changed using the above methods? eg: HDMI1 ?

vitalets commented 5 years ago

not an app but can the source of the tv be changed using the above methods? eg: HDMI1 ?

I think it is only possible to show "select source" panel.

coasttech commented 5 years ago

I found this. Not sure if it helps. I have no clue how to use it.

https://developer.tizen.org/ko/development/articles/how-retrieve-list-installed-applications?langredirect=1

mattmickeyj commented 5 years ago

Just wanted to say how useful this info was. I use homeassistant and the Samsungctl component isn’t working (NU7100). I instead setup switches to trigger the http commands, which in turn I can use in automations and routines invoked by Alexa (via haaska).

arsaboo commented 5 years ago

@mattmickeyj Can you please point me to your switches/automations for HA? I am also trying to do the same....thanks!

pegatron89 commented 5 years ago

@arsaboo this is my switches to turn on Netflix etc.

switch:
  platform: command_line
  scan_interval: 1
  switches:
    utubeon:
      command_on: curl -X POST http://192.168.0.62:8001/api/v2/applications/111299001912
      command_off: curl -X POST http://192.168.0.62:8001/api/v2/applications/111299001912
      friendly_name: "Turn on Youtube"
      command_state: off
    netflixon:
      command_on: curl -X POST http://192.168.0.62:8001/ws/apps/Netflix
      command_off: curl -X POST http://192.168.0.62:8001/api/v2/applications/RN1MCdNq8t
      command_state: off
      friendly_name: "Turn on Netflix"
    plexon:
      command_on: curl -X POST http://192.168.0.62:8001/api/v2/applications/kIciSQlYEM.plex
      command_off: curl -X POST http://192.168.0.62:8001
      command_state: off 
      friendly_name: "Turn on Plex"

The spacing is out sorry. You don't need the scan interval or command state. I had it there to try and get my lights to dim when Plex started playing / paused but there was a delay 10 second in getting the status back and updating the state etc etc.

arsaboo commented 5 years ago

@pegatron89 That works perfectly...thanks!!

How did you obtain the app ids (e.g., 111299001912)?

pegatron89 commented 5 years ago

@arsaboo No bother atal!

Just from this thread / google

The below comment has most of the correct app ids (Use the app id the same way as i have used it under plexon)

https://github.com/Ape/samsungctl/issues/75#issuecomment-404941201

phanlam commented 5 years ago

Hi everyone! I'm searching for the document about this command {"method":"ms.remote.control","params":{"Cmd":"Move","Position":{"x":-1000,"y":1000,"Time":"1518675746190"},"TypeOfRemote":"ProcessMouseDevice"}}

Could you please share this document to me I can not find this document, 2 days searching, no result Please help Thanks

freman commented 5 years ago

Hi @phanlam I'm afraid I have no documentation about this function, I got it sort of working by capturing debug logs, network traffic and decompiling the APK. I know it works as relative updates so you have to send it at least 2 copies of the commands to get it moving

phanlam commented 5 years ago

Hi @freman Thank you for your rely. I'm looking for the "scroll up/down" (mouse) method. Could you please help me? Thanks!

alirazabutt commented 5 years ago

This has been very helpful. On my 2018 Samsung frame, I am unable to connect due to authorization failure, but am able to launch apps a suggested above (curl post...). Any suggestions on how to turn on Art Mode on the frame. I suspect it is an app, but given my authentication problem I am unable to list all apps to then try running the art one. Any ideas?

shakabra commented 5 years ago

Hi @vitalets , this works very well for me! Thank you very much!!! Because for my TV (QE55Q6FNA) samsungctl seems not working, do you know a method to change channels and poweroff the TV? Thanks in advance...

vitalets commented 5 years ago

Hi @vitalets , this works very well for me! Thank you very much!!! Because for my TV (QE55Q6FNA) samsungctl seems not working, do you know a method to change channels and poweroff the TV? Thanks in advance...

You may setup websocket connection to ws://${tvIP}:8001/api/v2/channels/samsung.remote.control and send remote keys:

{
     method: 'ms.remote.control',
     params: {
       TypeOfRemote: 'SendRemoteKey',
       Cmd: 'Click',
       Option: 'false',
       DataOfCmd: 'KEY_POWER',
     }
 }
shakabra commented 5 years ago

Hi @vitalets Sorry, but I'm new to samsungctl and websockect. I wrote this simple test.js following your indication, but I'm not sure to be right :

const WebSocket = require('ws'); ws = new WebSocket('ws://192.168.2.100:8001/api/v2/channels/samsung.remote.control'); ws.onopen = function() {ws.send('{"method":"ms.remote.control","params":{"TypeOfRemote": "SendRemoteKey", "Cmd":"Click", "Option":"false", "DataOfCmd": "KEY_CHUP"}}')}; ws.onmessage = function(e) {console.log(e)}

But the command node test.js returns:

MessageEvent { target: WebSocket { domain: null, _events: { open: [Object], message: [Object] }, _eventsCount: 2, _maxListeners: undefined, readyState: 1, protocol: '', _binaryType: 'nodebuffer', _closeFrameReceived: false, _closeFrameSent: false, _closeMessage: '', _closeTimer: null, _closeCode: 1006, _extensions: {}, _isServer: false, _receiver: Receiver { _writableState: [Object], writable: true, domain: null, _events: [Object], _eventsCount: 6, _maxListeners: undefined, _binaryType: 'nodebuffer', _extensions: {}, _maxPayload: 104857600, _bufferedBytes: 0, _buffers: [], _compressed: false, _payloadLength: 36, _mask: undefined, _fragmented: 0, _masked: false, _fin: true, _opcode: 1, _totalPayloadLength: 0, _messageLength: 0, _fragments: [], _state: 4, _loop: true, [Symbol(websocket)]: [Circular] }, _sender: Sender { _extensions: {}, _socket: [Object], _firstFragment: true, _compress: false, _bufferedBytes: 0, _deflating: false, _queue: [] }, _socket: Socket { connecting: false, _hadError: false, _handle: [Object], _parent: null, _host: null, _readableState: [Object], readable: true, domain: null, _events: [Object], _eventsCount: 5, _maxListeners: undefined, _writableState: [Object], writable: true, allowHalfOpen: false, _bytesDispatched: 404, _sockname: null, _pendingData: null, _pendingEncoding: '', server: null, _server: null, parser: null, _httpMessage: null, _idleNext: null, _idlePrev: null, _idleTimeout: -1,

    [Symbol(bytesRead)]: 0,
    [Symbol(websocket)]: [Circular] },
 url: 'ws://192.168.2.100:8001/api/v2/channels/samsung.remote.control',
 _req: null },

type: 'message', data: '{"event":"ms.channel.unauthorized"}\n' } events.js:183 throw er; // Unhandled 'error' event ^

RangeError: Invalid WebSocket frame: invalid status code 1005 at Receiver.controlMessage (/root/node_modules/ws/lib/receiver.js:441:18) at Receiver.getData (/root/node_modules/ws/lib/receiver.js:329:42) at Receiver.startLoop (/root/node_modules/ws/lib/receiver.js:133:22) at Receiver._write (/root/node_modules/ws/lib/receiver.js:69:10) at doWrite (_stream_writable.js:396:12) at writeOrBuffer (_stream_writable.js:382:5) at Receiver.Writable.write (_stream_writable.js:290:11) at Socket.socketOnData (/root/node_modules/ws/lib/websocket.js:794:35) at emitOne (events.js:116:13) at Socket.emit (events.js:211:7)

Any idea? Thanks in advance

vitalets commented 5 years ago

@shakabra

  1. You should wait for ms.channel.connect response before sending command
  2. I see ms.channel.unauthorized in the response. Maybe you should allow access on the TV: there can appear panel with buttons allow|deny.

Here is the full working code:

const WebSocket = require('ws');

const tvIP = '192.168.2.100';
const ws = new WebSocket(`ws://${tvIP}:8001/api/v2/channels/samsung.remote.control`);

ws.onopen = () => console.log('opened.');
ws.onclose = () => console.log('closed.');
ws.onmessage = message => {
  console.log('<--', message.data);
  const data = JSON.parse(message.data);
  if (data.event === 'ms.channel.connect') {
    ws.send(JSON.stringify({
      method: 'ms.remote.control',
      params: {
        TypeOfRemote: 'SendRemoteKey',
        Cmd: 'Click',
        Option: 'false',
        DataOfCmd: 'KEY_MUTE',
      }
    }));
    setTimeout(() => ws.close(), 1000);
  }
};
shakabra commented 5 years ago

@vitalets Thank you very much for your reply! You are very patient. My device is correctly authorized because the first time that I issued the command: curl -X POST http://192.168.2.100:8001/api/v2/applications/111299001912 it asked me for the authorization and I confirmed. Now the curl command works very well without asking me some other confirmation. Unfortunately the problem persist and it drives me crazy...

node test.js

opened. <-- {"event":"ms.channel.unauthorized"}

events.js:183 throw er; // Unhandled 'error' event ^

RangeError: Invalid WebSocket frame: invalid status code 1005 at Receiver.controlMessage (/root/node_modules/ws/lib/receiver.js:441:18) at Receiver.getData (/root/node_modules/ws/lib/receiver.js:329:42) at Receiver.startLoop (/root/node_modules/ws/lib/receiver.js:133:22) at Receiver._write (/root/node_modules/ws/lib/receiver.js:69:10) at doWrite (_stream_writable.js:396:12) at writeOrBuffer (_stream_writable.js:382:5) at Receiver.Writable.write (_stream_writable.js:290:11) at Socket.socketOnData (/root/node_modules/ws/lib/websocket.js:794:35) at emitOne (events.js:116:13) at Socket.emit (events.js:211:7)

vitalets commented 5 years ago

For some reason you are unauthorized. Try to remove your device from authorized (it's somewhere in menu) and try re-run script.

cyphers commented 5 years ago

samsungctl does not work with 2018 models (like the QE55Q6FNA you referenced). In early August, Samsung changed something in a firmware update and now all third-party integrations are broken due to that authorization error. Have not found a workaround yet.

shakabra commented 5 years ago

@cyphers @vitalets Thanks for the reply, infact, it does not work neither if I remove my device from authorized... The strange thing is that rather if I send this command:

curl -X POST http://192.168.2.100:8001/api/v2/applications/111299001912 it work correctly asking the authorization and executing youtobe... At this point for me it's a mystery, because the authentication should be the same... or I'm missing something...

alirazabutt commented 5 years ago

@cyphers thank you for that info. Much appreciated. Another thing of note is that the smart view app doesn't work with new 2018 models (at least not my 2018 frame), instead the new smart things app is the only one that recognizes the the TV and works with it.

For now, I have switched to Ex-link/USB via RasPi for control. Even Ex-Link over IP (port 1515) does not work.

shakabra commented 5 years ago

Hi @alirazabutt what model of 2018 do you have? Because I am not able to find the ex-link connection on my model QE55Q6FNA, if there is, it's well-hidden.

alirazabutt commented 5 years ago

@shakabra I have UN43LS03NA, its 43" Samsung Frame, which comes with a one-connect box (single optical wire connection to TV). The physical Ex-link is like a stereo jack on the corner of the one-connect box. If you have one connect box look on the back or on the side (near optical audio connection), otherwise it should be on the back. It may be labeled service port.

vitalets commented 5 years ago

Another thing of note is that the smart view app doesn't work with new 2018 models (at least not my 2018 frame), instead the new smart things app is the only one that recognizes the the TV and works with it.

@alirazabutt thanks for the info! It would be great if somebody with TV of 2018 catch the requests.

shakabra commented 5 years ago

@alirazabutt I think that in 2018 model of QE55Q6FNA they removed the ex-link and the one-connect box that was present in 2017 model... I know how is made the ex-link because I'm using it on my 2013 samsung TV that I power on with it because it haven't WOL function.

vitalets commented 5 years ago

@shakabra Could you post the result of curl http://TV_IP:8001/api/v2/ of your 2018 TV? And the user agent of browser - to know the exact version of Tizen. The simplest way I know is to open https://whatsmyua.info in TV browser. Thanks in advance!

shakabra commented 5 years ago

@vitalets Thanks for the reply! This is the result of http://TV_IP:8001/api/v2/:

   
device  
FrameTVSupport "false"
GamePadSupport "true"
ImeSyncedSupport "true"
OS "Tizen"
TokenAuthSupport "true"
VoiceSupport "true"
countryCode "IT"
description "Samsung DTV RCR"
developerIP "192.168.2.180"
developerMode "1"
duid "uuid:df830908-990a-4710-b2c0-5d18c1522f4e"
firmwareVersion "Unknown"
id "uuid:df830908-990a-4710-b2c0-5d18c1522f4e"
ip "192.168.2.100"
model "18_KANTM2_QTV"
modelName "QE55Q6FNA"
name "[TV] Samsung Q6 Series (55)"
networkType "wired"
resolution "3840x2160"
smartHubAgreement "true"
type "Samsung SmartTV"
udn "uuid:df830908-990a-4710-b2c0-5d18c1522f4e"
wifiMac "70:2a:d5:8f:5a:0d"
id "uuid:df830908-990a-4710-b2c0-5d18c1522f4e"
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\":\"true\"}\n"
name "[TV] Samsung Q6 Series (55)"
remote "1.0"
type "Samsung SmartTV"
uri "http://192.168.2.100:8001/api/v2/"
version "2.0.25"

Useragent reports: major: 2 minor: 1 patch: 0 Thanks!

awaska commented 5 years ago

can you create a alexa skill for this code and lamba aws intance for hosting please!!! or command can i use with home assistant

mStirner commented 5 years ago

Is there a "full" "documentation" about the WS/HTTP API ? Has anyone get some more advanced commands?, like:

Any documentation is welcome.

freman commented 5 years ago

@mStirner all the documentation I know of is in this thread.

Not sure if you can get a full channel list, probably can if the samsung app can AFIK the only way to change settings is to navigate like a pleb Only app I've ever installed is our hand crafted upgrade on the build in web browser and that was via Developer mode

kdschlosser commented 5 years ago

anyone willing to try sending this down their websocket connection

{
    "method": "ms.channel.emit",
    "params": {
        "event": "ed.appStateRequest.get",
        "to":"host"
    }
}
vitalets commented 5 years ago

anyone willing to try sending this down their websocket connection

{
    "method": "ms.channel.emit",
    "params": {
        "event": "ed.appStateRequest.get",
        "to":"host"
    }
}

On Tizen 2.4:

--> {"method":"ms.channel.emit","params":{"event":"ed.appStateRequest.get","to":"host"}}
<-- {"event":"ed.appStateRequest.get","from":"host"}
kdschlosser commented 5 years ago

I will say this folks. I got my hands on the Tizen source code. so with that I should be able to really expand the websocket functionality.

I located these methods thus far. I do not know if they wiill work or not. I do not know that params just yet. but I am getting there,

I am sure that these will need a param AppID or AppId something along those lines.

"method": "ms.application.get "method": "ms.application.stop "method": "ms.application.install "method": "ms.application.start "method": "ms.webapplication.get "method": "ms.webapplication.stop "method": "ms.webapplication.start

I did find the TypeOfRemote param but I have to follow the code path to see what can be used there.

here are over 23K files to the OS so trying to follow the code path is not that easy. especially when trying to work backwards. but all I have are specific things to look for which is at the end of the chain. then I have to search for object calls through all of the files. it's a lot of work.

I have not managed to locate ms.channel.emit or any piece of it. There has to be something for it.

I did discover this out tho. the same OS is used on the TV's the soundbars the wearables almost everything Samsung that is made now uses this OS. and if it doesn't then it probably will because there are subsets for each of the various devices that Samsung makes.

freman commented 5 years ago

@kdschlosser I'm not going to lie, I'm a little bit turned on right now.

freman commented 5 years ago

Just going to show off a project I'm hoping to open source soon (basically the reason I started down this path)

We have quite a few of these samsung tv's in the building, but those remotes suck.

image

image

The image icon launches our custom grafana app.

kdschlosser commented 5 years ago

@freman

here is a link to a slack chat I created for samsungctl. https://join.slack.com/t/samsungtvcontrol/shared_invite/enQtNTA0Nzc2MjY4MTgxLWNjNWI5ZjQwYTMzNzYxNjlkYTI5NTk1ZmJmMDU5ZjRmMDRhYTg4NGIzYWVjMzU3YzlmMzM5NWNjNWQ5MzU3NjA you seem to have a really good grasp of how the websocket portion of this works. as well as discovering new functionality. I want to share the Tizen source code with ya. It is to much for a single person to dig through to find the websocket commands. they are all over the place. The source is written in C and Java mostly. not sure if you are familiar with, but you will know what to look for anyway. the source is for Tizen versions 1.0 to 5.0 and includes subsets for TV's, wearables, phones and many other Samsung products. if you are interested join that slack chat and send me a message. My alias is drschlosser on the slack chat.

xxKeoxx commented 5 years ago

hey all... so from reading through this, it shows examples of how to launch an app. Unfortunately I am not a real developer and didn't fully understand everything I've read. I am familiar with python, so would someone be willing to point me toward some examples using python to launch vudu on a samsung smart TV?

kdschlosser commented 5 years ago

I do not know if this repository is being maintained anymore. I have set up a fork and have been adding to the library. I have added an easy way to launch apps (depending on the year your TV was made)

https://github.com/kdschlosser/samsungctl

mcgurdan commented 5 years ago

What’s the easy way? I didn’t really see reference in the readme

kdschlosser commented 5 years ago

you have to look at the combination branch. there is information in there about how to launch applications.

lucarasp commented 5 years ago

So, to identify if a particular application is installed you can use the call : curl -X GET -i 'yourIP:8001/ws/apps/Netflix' and and you will receive the answer : Netflixrunning6.0.003 OR Netflixstopped6.0.003

Hello, I need to get the "PLAY", "PAUSE" and "STOP" status from videoplayer apps like Netflix to change lights and blinds of the room accordingly. I've tried the above call as well as http://yourIP:8001/api/v2/applications/11101200001 but I can only get the "running" and "visible" state that are independent from the player status. Do you have any hint on how to get such information?

kdschlosser commented 5 years ago

I have not come across anything that will inform us of the "playing" state. I do not know if possibly that state will show in the DLNA information that is available via UPNP. I am currently working on adding thee UPNP components now. so we will be able to answer that question soon enough.

lucarasp commented 5 years ago

Tested with upnprenderer: DLNA information seems to be related to DLNA player only.

kdschlosser commented 5 years ago

well that really stinks! I do want you to try something tho. If you send a UPNP stop command to the DNLA player.. does it stop playing? How crooked would that be if it did LOL.

lucarasp commented 5 years ago

I hope I got what you're asking Tested with:

kdschlosser commented 5 years ago

OK so now we have an answer to that. stop from UPNP will not stop the Netflix playback.

on another note II did manage to get the unittests functioning properly. and that helped me iron out all of the bugs in the application portion of samsungctl. so now that is working. I will push the code as soon as I am done.