HTTP Request with Lua to server

Hi,

I’m new with Vera and Lua.

I have VerEdge with Fabiro Universal Sensor.
I’ve attached 3 x Temperature Sensors to the Universal Sensor.

I need to log the temperatures and send them to another server for processing…

The completed string need to look like this:

http://server_ip:socket/SignalTower/jsp/custom/ob/addEvent.jsp?deviceType=OWC&rawData=XXXXXXXXXXXXXXXXXXXXXVRE000011820200001E%2020160728 210748%2015.25%20%20%20%20%20%20%20%20%20%20?C%20%20%2050%20

I can confirm that this string call works.

I was able to test bits an pieces of the code using: Lua: demo
But I have not been able to test the actual retrieving of the Value, and the HTTP request I can only do on Vera.
My Vera Scene runs “Success”, but I don’t get the data on the server.

Please let me know if there is a mistake in the code, or if there is another way I can debug my code.

Here is my code:

//---------------------------

local device = 29
local prefix = [[XXXXXXXXXXXXXXXXXXXXX]]
local accountcode = [[VRE00001]]
local alarmcode = ‘202’
local zone = ‘001’

local datetime = os.date(“%Y%m%d %H%m%S”)

local qualifier = ‘E%20’
local partition = ‘00’

local value = luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor:1”,“CurrentTemperature”, device)
local units = [[?C%20%20%20]]
local signal = ‘50%20’

local page = [[http://server_ip:socket/SignalTower/jsp/custom/ob/addEvent.jsp?deviceType=OWC&rawData=]]

require(‘ltn12’)
local http = require(‘socket.http’)
socket.http.TIMEOUT = 5

local response_body = {}
local request_body = ‘’

local r, c, h = socket.http.request{
url = page…prefix…accountcode…‘18’…alarmcode…partition…zone…qualifier…datetime…‘%20’…value…units…signal,
method = “POST”,
headers = {
[“Content-Length”] = string.len(request_body),
[“Content-Type”] = “application/x-www-form-urlencoded”
}}[/color]

//---------------------------

I was able to test must of the code using:
http://www.lua.org/cgi-bin/demo

I’ve not bee able to test the following:

  1. Retrieving the value of the sensor:
    local value = luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor:1”,“CurrentTemperature”, device)

  2. HTTP request:
    require(‘ltn12’)
    local http = require(‘socket.http’)
    socket.http.TIMEOUT = 5

local response_body = {}
local request_body = ‘’

local r, c, h = socket.http.request{
url = page…prefix…accountcode…‘18’…alarmcode…partition…zone…qualifier…datetime…‘%20’…value…units…signal,
method = “POST”,
headers = {
[“Content-Length”] = string.len(request_body),
[“Content-Type”] = “application/x-www-form-urlencoded”
}}[/color]

These two lines are in error:

socket.http.TIMEOUT = 5
--- 
local r, c, h = socket.http.request{

…they should be:

http.TIMEOUT = 5
--- 
local r, c, h = http.request{

There may, of course, be other errors.

You can test this all on Vera using the code window found at Apps > Develop apps > Test Luup code (Lua)

Thank you very much for the feedback.

In my “Test Luup code (Lua)”,

I was able to test the retrieval of the current Temperature:

local value = luup.variable_get(“urn:upnp-org:serviceId:TemperatureSensor:1”,“CurrentTemperature”, device)
“Code sent successfully”

This seems to be testing the "luup.variable_get(‘’ “, device)” format only.
It does not actually retrieve any data, and show no return feedback, so I wont know if it was successful.

  1. I then tried testing the http command:

require(‘ltn12’)
local http = require(‘socket.http’)
http.TIMEOUT = 5

local response_body = {}
local request_body = ‘’

local r, c, h = http.request{
url = page…prefix…accountcode…‘18’…alarmcode…partition…zone…qualifier…datetime…‘%20’…value…units…signal,
method = “POST”,
headers = {
[“Content-Length”] = string.len(request_body),
[“Content-Type”] = “application/x-www-form-urlencoded”
}}

“Code failed”

Then I replace the url string build command with the actual string:

local r, c, h = http.request{
url = “http://server_ip:port/SignalTower/jsp/custom/ob/addEvent.jsp?deviceType=OWC&rawData=XXXXXXXXXXXXXXXXXXXXXVRE000011820200001E%2020160728 210748%2015.25%20%20%20%20%20%20%20%20%20%20?C%20%20%2050%20”,
method = “POST”,
headers = {
[“Content-Length”] = string.len(request_body),
[“Content-Type”] = “application/x-www-form-urlencoded”
}}

“Code sent successfully”

There is thus still something wrong with this part of the format:

url = page…prefix…accountcode…‘18’…alarmcode…partition…zone…qualifier…datetime…‘%20’…value…units…signal,

If I print() both options out, they are identical.
Thus I assume the problem is with my actual function…maybe missing ’ ’ or " " I dont know

I really appreciate the assistance.

Your datetime string generation is incorrect.

In your ‘hard-wired’ example you have:

202016072821074

however, your code produces something like this:

2020160729 070701

So instead of:

local datetime = os.date("%Y%m%d %H%m%S")

you probably mean:

local datetime = os.date("%Y%m%d%H%m%S")

I’m also a bit confused as to why you’re generating a POST request with a zero-length body… will a simple GET not work?

You don’t need this line:

require('ltn12')

… you’re not using it.

Also, this is a horrible way to build a long multi-part URL-encoded string. There are better ways, but this will work just to get things going.

Thanks again for the assistance.
Im new at Vera and Lua, so I do apologies if my code is not as optimal as could be.

I was able to find the error.

  1. It seems like Lua does not automatically convert spaces to %20.
    This space between my date and time gave the error.
    As my sever protocol requires the space I had do 2 os.date calls and them combine them again with a ‘20%’
    (Im sure there is a better way to do this)

local datez = os.date(“%Y%m%d”)
local timez = os.date(“%H%m%S”)

local date = tostring(datez)
local time = tostring(timez)

local datetime = date…‘%20’…time

2.Regarding the debugging:
I added luup.log(variable) throughout my code.
I used ssh to open the LuaUPnP.Log file.
After running the code in Test Luup code (Lua), I would then watch the LuaUPnP.Log file and make sure all my strings are converter the way I wanted.
Also added the luup.log on the r, c and h at HTTP call.
I was then able to see the 505 error which meant a space in the code, and was able to locate it.

I now get the 200 return, and the message is getting to the server.

Thanks you very much for the assistance.

You’re very welcome.

Im new at Vera and Lua, so I do apologies if my code is not as optimal as could be.

I have no problem with that at all! However, I think it’s always worthwhile to point out that there may be better ways. Lua is definitely worth learning well (and easy to do so, since it’s a very small language.) This is the book to read: Programming in Lua and this is the reference manual for the full details: Lua: reference manuals

It seems like Lua does not automatically convert spaces to %20. [...] (Im sure there is a better way to do this)

Indeed there is. There is a module which has routines to do url escaping and unescaping…

local url = require "socket.url"
local text = "A space or two"
local enc = url.escape (text)
print (enc)

local dec = url.unescape (enc)
print (dec)

…will produce the output:

A%20space%20or%20two
A space or two
I now get the 200 return, and the message is getting to the server.

Excellent - good luck!

Thank you so much.
The escaping function will really help a lot. :slight_smile: