Trying to make a scene that will control my Sony Bravia

So basically I have these 2 curl commands that will trigger an android app on my Sony Bravia tv in order to see my front camera when someone press the ringer and than revert to another input after 10 sec…

The commands works well in shell but I couldn’t figure how to translate that appropriately in lua… I tried both with osexecute and http.request

I think there is too many bracket or something :frowning:
Any idea ?

curl -v -XPOST http://XXX.XXX.XXX.XXX/sony/appControl -H ‘X-Auth-PSK:ZZZ’ -d ‘{“method”:“setActiveApp”,“params”:[{“uri”:“com.sony.dtv.com.alexvas.dvr.pro.com.alexvas.dvr.activity.TvMainActivity”}],“id”:10, “version”:“1.0”}’

luup.call_delay(10)

curl -v -XPOST http://XXX.XXX.XXX.XXX/sony/avContent -H ‘X-Auth-PSK:ZZZ’ -d ‘{“method”:“setPlayContent”,“params”:[{“uri”:“extInput:hdmi?port=1”}],“id”:101, “version”:“1.0”}’

This is based on Sony Bravia rest-Api:

You likely have two problems with this, although without the exact syntax you tried, it’s hard to tell.

  1. Your curl string contains both type of quotes, so you need to use the extended quote option in Lua
  2. luup.call_delay() does not work inline in the way that you are expecting and has to be coded differently

You would need something like:

os.execute [[curl -v -XPOST http://XXX.XXX.XXX.XXX/sony/appControl -H ‘X-Auth-PSK:ZZZ’ -d ‘{“method”:“setActiveApp”,“params”:[{“uri”:“com.sony.dtv.com.alexvas.dvr.pro.com.alexvas.dvr.activity.TvMainActivity”}],“id”:10, “version”:“1.0”}’]]

function delayed_callback ()
  os.execute [[curl -v -XPOST http://XXX.XXX.XXX.XXX/sony/avContent -H ‘X-Auth-PSK:ZZZ’ -d ‘{“method”:“setPlayContent”,“params”:[{“uri”:“extInput:hdmi?port=1”}],“id”:101, “version”:“1.0”}’]]
end

luup.call_delay("delayed_callback", 10, "")

Thanks :slight_smile: That worked :slight_smile:

Now I am trying with another method in order to get the response to a command I send… maybe you can help me ?
I’m looking to see if my tv is on or not…
I can do this with a curl command as such :
curl -v -XPOST http://XXX.XXX.XXX.XXX/sony/system -H 'X-Auth-PSK:ZZZ' -d '{"method":"getPowerStatus","params":[],"id":50, "version":"1.0"}'

Doing this curl command from a shell will return the following :

> POST /sony/system HTTP/1.1
> User-Agent: curl/7.38.0
> Host: XXX.XXX.XXX.XXX
> Accept: */*
> X-Auth-PSK:ZZZ
> Content-Length: 64
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 41
< Connection: keep-alive
<
{"result":[{"status":"standby"}],"id":50}

OR

{"result":[{"status":"active"}],"id":50} if it’s on.

Itried to catch this il Lua with the following code : (testing in luatest)

    local http=require("socket.http")
    local siteurl = "http://XXX.XXX.XXX.XXX/sony/system"
    local payload = [[ {"method":"getPowerStatus","params":[],"id":50, "version":"1.0"} ]]
    local respback = { }
    local res, code, response_headers, status = http.request
    {
    url = siteurl,
    method = "POST",
    headers =
    {
    ["X-Auth-PSK"] = "ZZZ",
    ["Content-Type"] = "application/json",
    ["Content-Length"] = payload:len()
    },
    source = ltn12.source.string(payload),
    sink = ltn12.sink.table(respback)
    }
    print (status)

But I only get “HTTP/1.1 200 OK” as output…

Do you know how I could return to a variable the value “standby” or “active” in order to do something else after ?

Thanks :slight_smile:

Ok… I made a step forward by reading the response_body table…
Is there any easy way to make a variable that would only have “active” or “standby” as value ?

added :

function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end
print("Result:", dump(response_body))

and that returns :

Result: { [1] = {"result":[{"status":"standby"}],"id":50},}

I have to say that your dump() function is quite the worst piece of code I have seen for a while. Where did you get it? It does nothing for you. Throw it away.

The response body is simply an array of strings, and in your case this seems to be in JSON syntax. Use a proper decoder to get your result.

local json = require "dkjson"
local reply = json.decode (table.concat(response_body))

The reply variable is now a Lua table, from which you can directly access your required result.

print(pretty(reply))

will show you the structure (assuming you’re using AltUI.)


PS: in this case, the answer you need is in reply.result[1].status

ok :slight_smile:
found an easier way :

local dst = "xxx.xxx.xxx.xxx"
local url = 'http://'.. dst ..'/sony/system'
local headername = 'X-Auth-PSK'
local headervalue = 'xxxxxxx'
local jsonbodygetstatus = '{\\"id\\":2,\\"method\\":\\"getPowerStatus\\",\\"version\\":\\"1.0\\",\\"params\\":[]}'
local runcommand = 'curl -v -H \"Content-Type:application/json\" -H \"' .. headername .. ':' .. headervalue .. '\" -d \"' .. jsonbodygetstatus .. '\" ' .. url .. ''

ping_success = os.execute('ping -c1 '.. dst)

if ping_success <= 10 then
   print('Device responded')
   
   local h=io.popen(runcommand)
   local response=h:read("*a")
   h:close()
  
  if string.find(response, '{"status":"active"}') then
    print('TV is active')

  elseif string.find(response, '{"status":"standby"}') then
    print('TV is in standby')
  else
    print('TV is in an unknowned state')
  end

else

print ("Device didn't respond")

end

Finally !!! I had it all working… posting here if it can help someone !

local dst = "xxx.xxx.xxx.xxx"
local url = 'http://'.. dst ..'/sony/system'
local headername = 'X-Auth-PSK'
local headervalue = 'xxxxxx'
local jsonbodygetstatus = '{\\"id\\":2,\\"method\\":\\"getPowerStatus\\",\\"version\\":\\"1.0\\",\\"params\\":[]}'
local runcommand = 'curl -v -H \"Content-Type:application/json\" -H \"' .. headername .. ':' .. headervalue .. '\" -d \"' .. jsonbodygetstatus .. '\" ' .. url .. ''
local h=io.popen(runcommand)
local response=h:read("*a")
h:close()
  
if string.find(response, '{"status":"active"}') then
luup.call_delay("turn_tv_cam_app_on", 0, "")
luup.call_delay("turn_tv_input_appletv_on", 30, "")

   
elseif string.find(response, '{"status":"standby"}') then
print('TV is in standby')
luup.call_delay("turn_tv_on", 0, "")
luup.call_delay("turn_tv_cam_app_on", 3, "")
luup.call_delay("turn_tv_off", 30, "")
end

function turn_tv_on()
print ("I'm turning the TV on")
local jsonbodygetstatus = '{"method":"setPowerStatus","params":[{"status":true}],"id":50, "version":"1.0"}'.."'" ..']]'
os.execute ('curl -v -XPOST ' .. url .. ' -H '.. "'" .. headername .. ':' .. headervalue .. "'" .. ' -d '.. "'" .. jsonbodygetstatus)
print ('curl -v -XPOST ' .. url .. ' -H '.. "'" .. headername .. ':' .. headervalue .. "'" .. ' -d '.. "'" .. jsonbodygetstatus)

end

function turn_tv_off()
print ("I'm turning the TV off")
local jsonbodygetstatus = '{"method":"setPowerStatus","params":[{"status":false}],"id":50, "version":"1.0"}'.."'" ..']]'
os.execute ('curl -v -XPOST ' .. url .. ' -H '.. "'" .. headername .. ':' .. headervalue .. "'" .. ' -d '.. "'" .. jsonbodygetstatus)
end

function turn_tv_cam_app_on()
local url = 'http://'.. dst ..'/sony/appControl'
local jsonbodygetstatus = '{"method":"setActiveApp","params":[{"uri":"com.sony.dtv.com.alexvas.dvr.pro.com.alexvas.dvr.activity.TvMainActivity"}],"id":10, "version":"1.0"}'.."'" ..']]'
os.execute ('curl -v -XPOST ' .. url .. ' -H '.. "'" .. headername .. ':' .. headervalue .. "'" .. ' -d '.. "'" .. jsonbodygetstatus)
end

function turn_tv_input_appletv_on()
local url = 'http://'.. dst ..'/sony/avContent'
local jsonbodygetstatus = '{"method":"setPlayContent","params":[{"uri":"extInput:hdmi?port=1"}],"id":1, "version":"1.0"}'.."'" ..']]'
os.execute ('curl -v -XPOST ' .. url .. ' -H '.. "'" .. headername .. ':' .. headervalue .. "'" .. ' -d '.. "'" .. jsonbodygetstatus)
end

Yes, glad that works. Looks a bit convoluted, though.

Since you discovered how to do POST requests with the http module, you could probably replace your curl commands with their http equivalents and ditch the delay functions, which are a bit of a kludge.

Still, you have something which works for you, and that’s the thing.