Posts: 120 
	Threads: 15 
	Joined: Nov 2019
	
 Reputation: 
 6
	 
 
	
	
		Hello, 
I found this Python script to control a Samsung Smart TV.  
Can someone help me to modify this Python script to a Lua script? 
Source:  https://github.com/vrachieru/samsung-tv-.../remote.py
Thanks in advance.
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		This API uses websocket/JSON. You can use this example as a starting point:  https://forum.logicmachine.net/showthrea...1#pid16331
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 120 
	Threads: 15 
	Joined: Nov 2019
	
 Reputation: 
 6
	 
 
	
	
		 (24.02.2023, 14:13)admin Wrote:  This API uses websocket/JSON. You can use this example as a starting point: https://forum.logicmachine.net/showthrea...1#pid16331 
Got this so far but i'm strugling with the payload. What's the correct way to send the commands?
 Code: host = '192.168.126.54' 
port = 8001 
name = 'SamsungTvRemote' 
 
if not client then 
  ws = require('user.websocket') 
  json = require('json') 
 
  url = 'ws://'..host..':'..port..'/api/v2/channels/samsung.remote.control?name='..name 
 
  client, err = ws.client('sync', 10) 
  res, err = client:connect(url) 
    log( res, err) 
   
  if res then 
    client:send(json.encode({ 
      payload = [[ 
        'method': 'ms.remote.control', 
              'params': { 
                    'Cmd': 'Click', 
                    'DataOfCmd': key, 
                    'Option': 'false', 
                    'TypeOfRemote': 'SendRemoteKey' 
                } 
              ]] 
    }))  
     
    client:send(json.encode({ 
      payload = [['KEY_VOLUP']] 
    })) 
     
  else 
    log('connection failed: ' .. tostring(err)) 
    client:close() 
    client = nil 
  end 
   
else 
  data, _, _, opcode, err = client:receive() 
 
  if data then 
    data = json.pdecode(data) 
 
    if data then 
      log(data) 
    end 
  else 
    log('receive failed: ' .. tostring(err)) 
    client:close() 
    client = nil 
  end 
end
  
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 377 
	Threads: 70 
	Joined: Dec 2019
	
 Reputation: 
 15
	 
 
	
	
		 (24.02.2023, 13:59)Joep Wrote:  Hello, 
 
I found this Python script to control a Samsung Smart TV.  
Can someone help me to modify this Python script to a Lua script? 
Source: https://github.com/vrachieru/samsung-tv-.../remote.py 
 
Thanks in advance. 
Hi Joep, 
have you tried with API cloud? 
best regards Cristian
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		Try this: 
Code: host = '192.168.126.54' 
port = 8001 
name = 'SamsungTvRemote' 
 
b64 = require('encdec').base64enc 
ws = require('user.websocket') 
json = require('json') 
 
url = 'ws://' .. host .. ':' .. port .. '/api/v2/channels/samsung.remote.control?name=' .. b64(name) 
 
client, err = ws.client('sync', 10) 
res, err = client:connect(url) 
 
if not res then 
  log('connection failed', err) 
  return 
end 
 
data, _, _, opcode, err = client:receive() 
resp = json.pdecode(data) 
if type(resp) ~= 'table' or resp.event ~= 'ms.channel.connect' then 
  log('invalid response', data, err) 
  client:close() 
  return 
end 
 
key = 'KEY_VOLUP' 
payload = json.encode({ 
  method = 'ms.remote.control', 
  params = { 
    Cmd = 'Click', 
    DataOfCmd = key, 
    Option = 'false', 
    TypeOfRemote = 'SendRemoteKey' 
  } 
}) 
 
client:send(payload) 
client:close()
  
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 120 
	Threads: 15 
	Joined: Nov 2019
	
 Reputation: 
 6
	 
 
	
	
		It's not working as i got an 'unautorized' reply. I know you first need to submit each remote control by a popup that appears a the the tv screen. 
So for that i just tested with a basic url:  
url = 'ws://' .. host .. ':' .. port .. '/api/v2/'
 
And then i got this response: 
Samsung TV websocket 27.02.2023 14:08:28 
* table: 
 ["data"] 
  * table: 
   ["clients"] 
    * table: 
     [1] 
      * table: 
       ["isHost"] 
        * bool: false 
       ["id"] 
        * string: f996fa65-4b22-4021-8f30-56df2da9a983 
       ["attributes"] 
        * table: 
         ["name"] 
          * userdata: NULL 
       ["deviceName"] 
        * string: Smart Device 
       ["connectTime"] 
        * number: 1677503304615 
   ["id"] 
    * string: f996fa65-4b22-4021-8f30-56df2da9a983 
 ["event"] 
  * string: ms.channel.connect
 
The same url  http://192.168.126.54:8001/api/v2/ in the webbrowser is giving me more information back: 
{ 
  "device": { 
    "FrameTVSupport": "true", 
    "GamePadSupport": "true", 
    "ImeSyncedSupport": "true", 
    "OS": "Tizen", 
    "TokenAuthSupport": "true", 
    "VoiceSupport": "true", 
    "countryCode": "NL", 
    "description": "Samsung DTV RCR", 
    "developerIP": "0.0.0.0", 
    "developerMode": "0", 
    "duid": "uuid:ab728320-b477-48f8-9728-dee89aa3b37c", 
    "firmwareVersion": "Unknown", 
    "id": "uuid:ab728320-b477-48f8-9728-dee89aa3b37c", 
    "ip": "192.168.126.54", 
    "model": "18_KANTM2_FRAME", 
    "modelName": "UE43LS03N", 
    "name": "[TV] Samsung Frame Series (43)", 
    "networkType": "wired", 
    "resolution": "3840x2160", 
    "smartHubAgreement": "true", 
    "type": "Samsung SmartTV", 
    "udn": "uuid:ab728320-b477-48f8-9728-dee89aa3b37c", 
    "wifiMac": "64:1c:ae:e3:3b:af" 
  }, 
  "id": "uuid:ab728320-b477-48f8-9728-dee89aa3b37c", 
  "isSupport": "{\"DMP_DRM_PLAYREADY\":\"false\",\"DMP_DRM_WIDEVINE\":\"false\",\"DMP_available\":\"true\",\"EDEN_available\":\"true\",\"FrameTVSupport\":\"true\",\"ImeSyncedSupport\":\"true\",\"TokenAuthSupport\":\"true\",\"remote_available\":\"true\",\"remote_fourDirections\":\"true\",\"remote_touchPad\":\"true\",\"remote_voiceControl\":\"true\"}\n", 
  "name": "[TV] Samsung Frame Series (43)", 
  "remote": "1.0", 
  "type": "Samsung SmartTV", 
  "uri": "http://192.168.126.54:8001/api/v2/", 
  "version": "2.0.25" 
}
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		It seems that you need to send KEY_HOME first to get the access token. Then add this token to the query string for further calls: ...samsung.remote.control?name=NAME&token=TOKEN 
Add another client:receive() after sending the key and log the results.
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 120 
	Threads: 15 
	Joined: Nov 2019
	
 Reputation: 
 6
	 
 
	
	
		 (27.02.2023, 13:40)admin Wrote:  It seems that you need to send KEY_HOME first to get the access token. Then add this token to the query string for further calls: ...samsung.remote.control?name=NAME&token=TOKEN 
Add another client:receive() after sending the key and log the results. 
This is the script so far:
 Code: host = '192.168.126.54' 
port = 8001 
name = 'SamsungTvRemote' 
b64 = require('encdec').base64enc 
ws = require('user.websocket') 
json = require('json') 
url = 'ws://' .. host .. ':' .. port .. '/api/v2/channels/samsung.remote.control?name=' .. b64(name) 
client, err = ws.client('sync', 10) 
res, err = client:connect(url) 
if not res then 
  log('connection failed', err) 
  return 
end 
data, _, _, opcode, err = client:receive() 
resp = json.pdecode(data) 
log(resp) 
if type(resp) ~= 'table' or resp.event ~= 'ms.channel.connect' then 
  log('invalid response', data, err) 
  client:close() 
  return 
end 
key = 'KEY_HOME' 
payload = json.encode({ 
  method = 'ms.remote.control', 
  params = { 
    Cmd = 'Click', 
    DataOfCmd = key, 
    Option = 'false', 
    TypeOfRemote = 'SendRemoteKey' 
  } 
}) 
client:send(payload) 
data, _, _, opcode, err = client:receive() 
resp = json.pdecode(data) 
log(resp) 
client:close()
 
The result is this:
 
Samsung TV websocket 27.02.2023 15:54:54 
* table: 
["event"] 
  * string: ms.channel.unauthorized
 
-----------------------------------------------------
 
Samsung TV websocket 27.02.2023 15:54:54 
* arg: 1 
  * string: invalid response 
* arg: 2 
  * string: {"event":"ms.channel.unauthorized"}
 
* arg: 3 
  * nil
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		Comment out this check before the key is sent and try again.
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 120 
	Threads: 15 
	Joined: Nov 2019
	
 Reputation: 
 6
	 
 
	
	
		 (27.02.2023, 14:58)admin Wrote:  Comment out this check before the key is sent and try again. 
Sorry but i don't understand what you mean with ' Comment out this check '
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		Add comments to this check: 
Code: -- if type(resp) ~= 'table' or resp.event ~= 'ms.channel.connect' then 
--   log('invalid response', data, err) 
--   client:close() 
--   return 
-- end
  
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 120 
	Threads: 15 
	Joined: Nov 2019
	
 Reputation: 
 6
	 
 
	
	
		 (27.02.2023, 15:49)admin Wrote:  Add comments to this check: 
Code: -- if type(resp) ~= 'table' or resp.event ~= 'ms.channel.connect' then 
--   log('invalid response', data, err) 
--   client:close() 
--   return 
-- end
  
I have a working script now using wss over port 8002. Only issue is that the TV keeps asking to accept the connection and it seems the token is changing all the time as i got a new one so now and then while testing.
 Code: host = '192.168.126.54' 
port = 8002 
name = 'MyRemote' 
token = 16687249 
 
b64 = require('encdec').base64enc 
ws = require('user.websocket') 
json = require('json') 
 
url = 'wss://' .. host .. ':' .. port .. '/api/v2/channels/samsung.remote.control?name=' .. b64(name) .. '&token=' .. token 
 
 
client, err = ws.client('sync', 10) 
res, err = client:connect(url) 
 
 
key = 'KEY_MUTE' 
payload = json.encode({ 
  method = 'ms.remote.control', 
  params = { 
    Cmd = 'Click', 
    DataOfCmd = key, 
    Option = 'false', 
    TypeOfRemote = 'SendRemoteKey' 
  } 
}) 
 
client:send(payload) 
 
data, _, _, opcode, err = client:receive() 
resp = json.pdecode(data) 
log(resp) 
 
client:close()
  
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 29 
	Threads: 7 
	Joined: Jul 2019
	
 Reputation: 
 0
	 
 
	
	
		Hi there, 
 
I am in the same situation as Joep. 
 
websocket library working and comunicating with Samsung IP, but each time i send a KEY command the TV send us a new Token string and ask us to confirm the device. 
 
Anyone have improved this?  
 
And the wol packet i tried several scripts to switch ON the TV without success.... any idea about?
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 120 
	Threads: 15 
	Joined: Nov 2019
	
 Reputation: 
 6
	 
 
	
		
		
		23.02.2024, 11:16 
(This post was last modified: 23.02.2024, 11:17 by Joep.)
		
	 
	
		 (23.02.2024, 11:00)j.martinez@t-ingeniamos.com Wrote:  Hi there, 
 
I am in the same situation as Joep. 
 
websocket library working and comunicating with Samsung IP, but each time i send a KEY command the TV send us a new Token string and ask us to confirm the device. 
 
Anyone have improved this?  
 
And the wol packet i tried several scripts to switch ON the TV without success.... any idea about? 
Here's a working WOL script. I just tested with my Samsung tv and it works. Also for my pc and i believe many other devices.
 Code: function wol(mac) 
local m = '' 
  for w in string.gmatch(mac, "[0-9A-Za-z][0-9A-Za-z]") do 
    m = m .. string.char(tonumber(w, 16)) 
  end 
  local udp = require("socket").udp() 
  udp:settimeout(1) 
  udp:setoption("broadcast", true) 
  udp:sendto(string.char(0xff):rep(6) .. m:rep(16) , '255.255.255.255', 9) 
end 
wol('60:2D:BE:C3:4A:BC') -- MAC address of your device
  
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 29 
	Threads: 7 
	Joined: Jul 2019
	
 Reputation: 
 0
	 
 
	
	
		 (23.02.2024, 11:16)Joep Wrote:   (23.02.2024, 11:00)j.martinez@t-ingeniamos.com Wrote:  Hi there, 
 
I am in the same situation as Joep. 
 
websocket library working and comunicating with Samsung IP, but each time i send a KEY command the TV send us a new Token string and ask us to confirm the device. 
 
Anyone have improved this?  
 
And the wol packet i tried several scripts to switch ON the TV without success.... any idea about?  
Here's a working WOL script. I just tested with my Samsung tv and it works. Also for my pc and i believe many other devices. 
 
 
Code: function wol(mac) 
local m = '' 
  for w in string.gmatch(mac, "[0-9A-Za-z][0-9A-Za-z]") do 
    m = m .. string.char(tonumber(w, 16)) 
  end 
  local udp = require("socket").udp() 
  udp:settimeout(1) 
  udp:setoption("broadcast", true) 
  udp:sendto(string.char(0xff):rep(6) .. m:rep(16) , '255.255.255.255', 9) 
end 
wol('60:2D:BE:C3:4A:BC') -- MAC address of your device
  
Thank you very much Joep. I will try it later.
	  
	
	
	
		
	 
 
 
	 
 |