need help for http post and lua lib

hi,

Please, I swim a little, I read many topics and plugins, I’m young with my vera2 and don’t find examples.

I want to make an http post with my vera to my “home” server to get one wire temperature.

I have to use http.socket in my lua script.

Could someone help me.

I don’t know what options and what writing.

fo example, I want to post to the php: http://example.org/temperature.php

gilles,

Would you know how to do it in another language? I’m asking because I don’t know if you have one problem (how to code it in Lua) or two (how HTTP POST works in general).

An example of what exactly you are intending to post and what you expect to get back would help, so that I can include relevant code snippets. The more precisely you describe what you’re doing, the more precisely I can answer the specific problem.

Finally, I’m going to ask you to run pieces of Lua from the command line, so that you can focus on the luasocket code and you’re not simultaneously having to get your head around Luup plugins. It doesn’t matter if that’s a desktop computer that you’ve installed a Lua interpreter on, or the root shell on Vera.

Tell me when you’re ready.

Futzle, thank you replying me,

Would you know how to do it in another language?
No I have installed a lua5.1 interpreter on my ubuntu system. I read some post and doc from lua site. I think that I have to read lua manual so that I could use some right code.
how HTTP POST works in general)
I've got my ubuntu home server installed with LAMP, For th efirst time I follow a tuto on the net and implanted a simple soap server to send answer depending the request. But from now after doing some tests, I think a simple php is what I need.
An example of what exactly you are intending to post and what you expect to get back would help, so that I can include relevant code snippets. The more precisely you describe what you're doing, the more precisely I can answer the specific problem.

For now, what I want to do is get or send information from vera to my server.
My project is to get alarm from my zondeminder system (a great program which can trigger alarms from zones of an ip camera). One another difficulty for me will be that I have to catch alarm from zoneminder the more rapidly I can with my vera.
And get temperature from my one wire system (just temperature for the near futur). In general, I wanted to do some exchange (post/get) between my vera2 and my server.

Finally, I'm going to ask you to run pieces of Lua from the command line, so that you can focus on the luasocket code and you're not simultaneously having to get your head around Luup plugins. It doesn't matter if that's a desktop computer that you've installed a Lua interpreter on, or the root shell on Vera.

For writing php code, I have installed eclipse indigo with php plugins and some more stuff. I try to install lua eclipse plugin, but it seems to be be buggy. So for lua scripts I use on my desktop Gedit which can Hilight my syntaxe and I test lua scripts.
For my server I’ve got LAMP and page which is for the moment:

<?php
/*
 * Created on 17 août 2011
 *
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
$commande="cat /mnt/1wire/28.A0B17B020000/temperature"; 
$result=shell_exec($commande);
echo $result;
 
 ?>

For me but perhaps I’m wrong I have to master post and get from my server to do what I want. Or using a rest server but there are less example than soap server.

For information I found a lua code for request and that works:

local http = require("socket.http")
result, statuscode, content = socket.http.request("http://XXXXXXXXX/cat_temp.php")
print (result)

The have some difficulties to found exact informations like possible variables for socket.http.xxxx

Sorry my explanations are a bit longer, but I hope It’s more clear for you.

So we can go when you want.

Hi gilles,

If you control both ends (Vera and your Ubuntu server) then you can choose whatever protocol you like. SOAP is rather heavyweight. I agree with your sentiment that something simpler might be better. Is it acceptable for the server to use a simple HTTP GET with parameters? If so, the Lua code becomes very easy.

For the sake of this discussion I will continue to consider only pushing data from Vera to server. It’s possible to have server pull data from the Vera (i.e., polling), but the mechanisms are completely different.

[quote=“gilles, post:3, topic:168995”]My project is to get alarm from my zondeminder system (a great program which can trigger alarms from zones of an ip camera). One another difficulty for me will be that I have to catch alarm from zoneminder the more rapidly I can with my vera.
And get temperature from my one wire system (just temperature for the near futur). In general, I wanted to do some exchange (post/get) between my vera2 and my server.[/quote]

Ok. Can we focus on the temperature first? It’s a simpler problem, and one I’ve done myself (using I2C rather than 1Wire). Do you already have a plugin that reads the temperature, or is that another unsolved part of the problem? I’m assuming you’ve got your 1Wire system connected, somehow, to your Vera. More information here would be helpful.

For writing php code, I have installed eclipse indigo with php plugins and some more stuff. I try to install lua eclipse plugin, but it seems to be be buggy. So for lua scripts I use on my desktop Gedit which can Hilight my syntaxe and I test lua scripts.

I’ve similarly had no luck with making Eclipse+Lua work. I’m back to running vim in one window, and lua from the shell in another window.

For me but perhaps I'm wrong I have to master post and get from my server to do what I want. Or using a rest server but there are less example than soap server.

REST is also kind of complicated, especially if you are coding the server side too. But not as complicated as SOAP. It sounds like you’re learning HTTP web services and Lua and Luup plugins all at once here, and that’s a lot to digest at once.

I suggest a plan of attack like this:

  1. Make your server accept something simple, like your example PHP code, and learn how to inject data into it from the command line with curl. All on your Ubuntu machine.
  2. Code up a Lua equivalent to your curl command line, using luasocket. Still on the Ubuntu machine.
  3. On the Vera, make or get a satisfactory standalone plugin for your 1Wire temperature sensor.
  4. Adapt your Lua code from #2 into your plugin from #3.
For information I found a lua code for request and that works:
local http = require("socket.http")
result, statuscode, content = socket.http.request("http://XXXXXXXXX/cat_temp.php")
print (result)

The have some difficulties to found exact informations like possible variables for socket.http.xxxx

I assume you already found this page?

Hi Futzle,

thank you again “showing me the road”.

Is it acceptable for the server to use a simple HTTP GET with parameters? If so, the Lua code becomes very easy

It’s not a problem for me to use http get (I can do what I want on my server, until it’s free and on linux). I think more it’s simple more it’s efficient. If I do that, and if I’m not wrong I can make some label and call some strings or what else.

Ok. Can we focus on the temperature first? It's a simpler problem, and one I've done myself (using I2C rather than 1Wire). Do you already have a plugin that reads the temperature, or is that another unsolved part of the problem? I'm assuming you've got your 1Wire system connected, somehow, to your Vera. More information here would be helpful.

Yes this is what I want too. On linux this is very simple, I’m using OWFS OneWireFileSystem. So we’ve got all what we need on a mounted file system like : “/mnt/1wire/28.A0B17B020000/temperature”
Here we can see that my mounted owfs is /mnt/1wire and my first 1wire temperature sensor is 28.A0B17B020000 and if I want to read my temperature I just have to read the file temperature.
I don’t want to connect my 1wire Controller on my vera, I prefer using, like today, on my server. And for information, I already use a usb port with a usb key, I 've got only 1 usb port available.
To be more clearer I think we can use my apache2 server with php code to give temperature information fisrt for my vera2.

suggest a plan of attack like this: 1. Make your server accept something simple, like your example PHP code, and learn how to inject data into it from the command line with curl. All on your Ubuntu machine. 2. Code up a Lua equivalent to your curl command line, using luasocket. Still on the Ubuntu machine. 3. On the Vera, make or get a satisfactory standalone plugin for your 1Wire temperature sensor. 4. Adapt your Lua code from #2 into your plugin from #3.

Do you think point number 1 is necessary, because I can from my vera get the temperature on a php page of my server. Perhaps you’v got a best solution than my code.

Number 2 if I understand is for preparing a good code in lua for a futut use in vera ?

Ok with number 3, I was trying to modify a temperature sensor device to convert it in virtual one. Wrong ?

My reflexion is: has I want to finally use a virtual temperature sensor, why not modifying a real temperature sensor and keeping what is necessary.

ok for number 4.

assume you already found this page?

Yes I found this page, but there are some things which are not clear. Why my get socket don’t work whereas my request does.
and what are the variables available, I found somewhere on an other page that there are many possibilities. Like: result, content, etc …

So let’s rock, I’m very happy to continue …

Hi gilles,

Oh, that is so cool. Thanks for mentioning that. Now I have a new toy to desire.

I don't want to connect my 1wire Controller on my vera, I prefer using, like today, on my server. And for information, I already use a usb port with a usb key, I 've got only 1 usb port available.

Ok, I misunderstood. I thought you wanted to send the temperature from Vera to Linux. In that case, cancel most of what we’ve talked about so far.

My reflexion is: has I want to finally use a virtual temperature sensor, why not modifying a real temperature sensor and keeping what is necessary.

Perfect plan.

Here’s a plugin I made (my first ever…) which reads temperature from my I2C network. In between the I2C network and the Vera is an Arduino running an HTTP server, so it’s pretty similar to your setup. You can see the HTTP get calls in the source (luup.inet.wget()).

How I use this file:

  1. Create a new device (MiOS developers > Create Device).
  2. Enter the filename I_TMP102Temperature.xml in the “UpnpImpFilename” field.
  3. Enter the filename D_TemperatureSensor1.xml in the “UpnpDevFilename” field (this file is already on all Veras).
  4. Go.

Do you think you can change the URL in the I_TMP102Temperature.xml to point to your PHP service running on the Ubuntu machine?

(This is using luup.inet.* instead of luasocket. It’s quite a bit simpler to code, but it’s much less flexible.)

Folks,
I am new to Luup and having trouble launching.

As part of a scene, I’d like to control a process that can only be triggered by an HTTP POST request. I am not sure if I am doing this right… but here is the code I placed under the Luup section of the test scene that I created:

local http=require(“socket.http”)
result = socket.http.post(“http://192.168.0.113/runprocess.htm","run=run”)
return result

This works fine when I am running this in FireBug / Firefox. But nothing appears to happen when I run the scene. Frankly, I don’t even know if I can run this in a scene.

Any thoughts on how to properly code and test this? I have looked at some of the other threads here, so I don’t think this is a syntax issue.

Hi Futzle,

Need some more help, but I’m near final plugin.
I do what you say and modify your file (if you are agree).

here is the code:

[code] function refreshCache()
luup.log(“Refreshing temperature.”)
– Get temperature sensor value.
local result, status, content = luup.inet.wget(“http://XXXXXXX/cat_temp.php”)
luup.log(“Status:” … status)
if (status == 200) then
– recordTemperature(result)
luup.log("Temperature: " … result)

  luup.variable_set("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", result, onewire_DEVICE)
  end
  luup.call_timer("refreshCache", 1, "60", "", "")
end[/code]

I don’t understand why in your code you use

if (status == 0) then recordTemperature(content) end

The status is 200 when a request page is ok and the content isn’t where the data is getting. I had result to see the temperature.
edit: Forget my remark on status it’s different to call luup.int.* than socket.http.request.

How to check that? What I 've done is a lua test like that to be sure it’s working:

-- Get temperature sensor value. local http = require("socket.http") local result, status, content = socket.http.request("http://10.10.1.2/cat_temp.php") print (status) print (content) print(result)

Unfortunatly I can’t get the device working, You’ve got an Idea.

Hu well done !!!

Thank you futzle, I do my first Onewire device on my vera !!!

So here is the right code (I 've made one error for the declaration of the require socket)

[code]function startup(lul_device)
luup.log("Starting Onewire device: " … tostring(lul_device))

 onewire_DEVICE = lul_device
 onewire_SLAVEADDRESS = luup.variable_get("urn:gilles-org:serviceId:OnewireTemperature1", "SlaveAddress", onewire_DEVICE) 
 if (onewire_SLAVEADDRESS == nil) then
   luup.variable_set("urn:gilles-org:serviceId:OnewireTemperature1", "SlaveAddress", 72, onewire_DEVICE)
    onewire_SLAVEADDRESS = "72"
  end
  luup.log("Scheduled: " .. luup.call_timer("refreshCache", 1, "1", "", ""))
end

function refreshCache()
  luup.log("Refreshing temperature.")
  -- Get temperature sensor value.
local http = require ("socket.http")
local result, status, content = socket.http.request("http://XXXXXX/cat_temp.php")

– local result, status, content = luup.inet.wget(“http://XXXXXXX/cat_temp.php”)
luup.log(“Status:” … status)
if (status == 200) then
– recordTemperature(result)
luup.log("Temperature: " … result)

  luup.variable_set("urn:upnp-org:serviceId:TemperatureSensor1", "CurrentTemperature", result, onewire_DEVICE)
  end
  luup.call_timer("refreshCache", 1, "60", "", "")
end[/code]

A really big thank you, from now I’ll have to improve this device to be more powerfull.

@txautomator,
In your example, using the simplistic form of LuaSocket’s HTTP, it should be [tt]http.request(…)[/tt].

The function returns 2 values, the result/content and the status.

If you were testing this using command line Lua, it would look like:

[code]local http=require(“socket.http”)

print(string.format(“Starting…timeout=%d, agent=%s”, http.TIMEOUT, http.USERAGENT))
http.TIMEOUT=5
result, status = http.request(“http://192.168.0.113/runprocess.htm”, “run=run”)

print(string.format(“HTTP Call returned status=%s, body=%s”, (status or 0), (result or “”)))
[/code]

The default timeout is very long, and can do bad things to Vera during shutdown operations, so I shortened it. Not sure what you’re planning to do with it in a scene though as you cannot just return the result

In a Scene, Vera expects you to return [tt]true[/tt] or [tt]false[/tt], indicating whether to continue running the scene. Returning a string (HTTP Result) doesn’t make sense.

[quote=“txautomator, post:7, topic:168995”]Folks,
I am new to Luup and having trouble launching.

As part of a scene, I’d like to control a process that can only be triggered by an HTTP POST request. I am not sure if I am doing this right… but here is the code I placed under the Luup section of the test scene that I created:

local http=require(“socket.http”)
result = socket.http.post(“http://192.168.0.113/runprocess.htm","run=run”)
return result

This works fine when I am running this in FireBug / Firefox. But nothing appears to happen when I run the scene. Frankly, I don’t even know if I can run this in a scene.

Any thoughts on how to properly code and test this? I have looked at some of the other threads here, so I don’t think this is a syntax issue.[/quote]

Hi @gilles,

FYI… There are two competing libraries for doing HTTP GET.

  1. luup.inet.wget(), which returns 0 on success.
  2. socket.http.request(), which returns 200 on success.
    Hence the difference you were seeing. You’re using #2 now, which I think is better.

That stuff about slaveaddress at the top of the startup() function, you can probably delete. It was to let me specify which I2C device to query, but you’ve got that logic in your PHP script instead. Probably your startup() function now only needs to contain the call to luup.call_timer().

Congratulations on your first plugin!

@guessed
Thanks !! I modified the code based on this and it now works.
I was also able to test it by looking at the log files @
http://192.168.x.x/cgi-bin/cmh/log.sh?Device=LuaUPnP

I now want to proceed and build a device around the HTTP interface.

[quote=“guessed, post:10, topic:168995”]@txautomator,
In your example, using the simplistic form of LuaSocket’s HTTP, it should be [tt]http.request(…)[/tt].

The function returns 2 values, the result/content and the status.

If you were testing this using command line Lua, it would look like:

[code]local http=require(“socket.http”)

print(string.format(“Starting…timeout=%d, agent=%s”, http.TIMEOUT, http.USERAGENT))
http.TIMEOUT=5
result, status = http.request(“http://192.168.0.113/runprocess.htm”, “run=run”)

print(string.format(“HTTP Call returned status=%s, body=%s”, (status or 0), (result or “”)))
[/code]

The default timeout is very long, and can do bad things to Vera during shutdown operations, so I shortened it. Not sure what you’re planning to do with it in a scene though as you cannot just return the result

In a Scene, Vera expects you to return [tt]true[/tt] or [tt]false[/tt], indicating whether to continue running the scene. Returning a string (HTTP Result) doesn’t make sense.

[quote=“txautomator, post:7, topic:168995”]Folks,
I am new to Luup and having trouble launching.

As part of a scene, I’d like to control a process that can only be triggered by an HTTP POST request. I am not sure if I am doing this right… but here is the code I placed under the Luup section of the test scene that I created:

local http=require(“socket.http”)
result = socket.http.post(“http://192.168.0.113/runprocess.htm","run=run”)
return result

This works fine when I am running this in FireBug / Firefox. But nothing appears to happen when I run the scene. Frankly, I don’t even know if I can run this in a scene.

Any thoughts on how to properly code and test this? I have looked at some of the other threads here, so I don’t think this is a syntax issue.[/quote][/quote]

@ Futzle,
Sorry for my late answer, but it’s ok for the slave parameters.
Thank you again.