openLuup: programmatic change of scene schedule

Hi akbooer,

do you know, in an openluup/ALTUI environment, a method/solution to change the schedule time of a scene programmatically ?

tnks

donato

The standard way to do this, on openLuup or Vera, is to use these HTTP requests:

http://wiki.micasaverde.com/index.php/Luup_Requests#scene

Essentially, you read, decode the JSON, change it, and write it back to the same scene. This is what the GUIs (UI5/7 or AltUI) all use to modify scenes.

Internally, it’s quite complex since you have to cancel scheduled timer jobs and restart them with the new timings.

Hi akbooer,

so to change a scene schedule time I read it for example with :

http://ip_address:3480/data_request?id=scene&action=list&scene=5

then decode and modify the “time” item , encode again and write the scene with :

http://ip_address:3480/data_request?id=scene&action=create&json=[valid json data]

tnks

donato

Yes, that’s right.

Hi akbooer,

With lua code I read the scene, changed the time schedule but I can’t write it back. With the browser copying and pasting the json string is OK.

I’m using dkjson library to decode/encode json. To write I’m using this code :

function WriteData(sdata)
local path = “http://localhost:3480/data_request?id=scene&action=create&json=
local encoded, err = json.encode(sdata)
path = path … encoded
local msg, retcode = http.request(path)
local err = (retcode ~=200)
if err then – something wrong happpened (website down)
msg = nil – to do: proper error handling
else

end
return err

end

where sdata is the JSON decoded.

Have you any idea on error ?

tnks

donato

You can’t use http.request(), you must use luup.inet.wget()… assuming you are running this on the same machine.

Ok tnks I?ll try

Hi akbooer,

sorry to bother you. I’ve tried with luup.inet.wget : I can decode the JSON scene and can change the schedule time with this instruction :

jsondecoded.timers[1].time = “17:0:0”

where jsondecoded is the scene json decoded. I’m using “dkjson” library that seems included in Vera Controller.

But when I re-write the JSON encoded , the items seems not in the same initial order so the write fails.

I searched about dkjson library but I found very poor documentation.

Have you any suggestion ?

tnks

donato

dkjson is fine and is included in the openLuup distribution for compatibility, although it doesn’t use it itself.

The only functions of any note really are encode() and decode().

Order in JSON is of no account (unless elements in a simple array) so changing the order in the scene structure doesn’t matter.

local json = require "dkjson"
local j = [[{"pi":3.1415926535898, "a":"the letter A"} ]]
print (j)
x = json.decode (j)
x.a = "lowercase a"
print (json.encode(x))

gives:

{"pi":3.1415926535898, "a":"the letter A"} 
{"a":"lowercase a","pi":3.1415926535898}

What error status do you get when the write ‘fails’?

Are you using openLuup, or Vera?

I’m using Vera.

This is the error :

01 10/29/17 10:36:49.968 e[31;1mMongoose Error 400: Bad Request
e[0m <0x71eba520>
01 10/29/17 10:36:49.970 e[31;1mFileUtils::ReadURL 0/resp:400 user: pass: size 52 http://localhost:3480/data_request?id=scene&action=create&json={ “timers”: [ { “enabled”: 1, “type”: 2, “time”: “17:0:0”, “id”: 1, “days_of_week”: “1,2,3,4,5,6,7”, “last_run”: 1509170400, “next_run”: 1509296400 } ], “id”: 59, “triggers_operator”: “OR”, “modeStatus”: “0”, “room”: 0, “users”: “”, “name”: “Prova Accensione Lavatrice”, “groups”: [ { “delay”: 0, “actions”: [ { “device”: “188”, “service”: “urn:upnp-org:serviceId:SwitchPower1”, “action”: “SetTarget”, “arguments”: [ { “name”: “newTargetValue”, “value”: “1” } ] } ] } ], “Timestamp”: 1509124831, “last_run”: 1509170400, “triggers”: [ ] } response: Error 400: Bad Request
Can not parse request: [GET]e[0m <0x730ba520>

The same http request via browser is OK and the JSON encoded is OK (I’ve verified on JSONLint site)

Well, of course, the json string has to be url encoded too, since it’s a normal GET request parameter.

Hi akbooer,

I’m using this function to send json scene but I get the same error :

function WriteData(sdata)
local path = “http://localhost:3480/data_request?id=scene&action=create&json=
local encoded, err = json.encode(sdata)
urlencode(encoded)
path = path … encoded
local status, result = luup.inet.wget(path)
end

function urlencode(encoded)
if (encoded) then
encoded = string.gsub (encoded, “\n”, “\r\n”)
encoded = string.gsub (encoded, “([^%w %-%_%.%~])”,
function (c) return string.format (“%%%02X”, string.byte(c)) end)
encoded = string.gsub (encoded, " ", “+”)
end
return encoded
end

where “sdata” is the scene json decoded.

Do you see the error ?

tnks

[quote=“d55m14, post:12, topic:197517”]I’m using this function to send json scene but I get the same error
[…]
Do you see the error ?[/quote]

Yes, you’re not doing the url encode correctly.

function WriteData(sdata)
  local path = "http://localhost:3480/data_request?id=scene&action=create&json="
  local encoded, err = json.encode(sdata)
  local u = urlencode(encoded)
  path = path .. u
  local status, result = luup.inet.wget(path)
end

tnks akbooer as usual

you’re the best…