javacript - save variable without luup restart

My target is to create a tab for a plugin which allows editing of variables without having to restart the luup engine with that annoying save-button. And I want to achieve this with javascript.

It is possible without the javascript. As for an example the wake on lan plugin allows updating it’s variables with an update function without having to restart the luup engine after changes. This is done with a simple function (called by a separate update-button) which does “luup.variable_set()” in the background.

In javascript saving variables can be done using (http://wiki.micasaverde.com/index.php/JavaScript_API):
set_device_state (deviceId, serviceId, variable, value, dynamic)

If I use this in a plugin-device’s tab and set the parameter “dynamic” to 0 I always have to push the save button after changes and the luup engine restarts.

If I set this parameter to 1 the changes seem to be stored dynamically (without having to hit the save button after changes), but not permanent, after a simple reload of the UI (just browser reload not luup) the values go back to what they were before doing any changes.

Does anyone have an idea how to achieve permanent storage of variable values using javascript without having to restart the luup engine?

Is it somehow possible to send luup stuff from javascripts, for example a simple “luup.log(“XXXXXX”)”?

My understanding is when restarting the luup engine, it needs to write the data to the user_data config and restart the daemon for the changes to take effort. It sounds like the data is just being stored in memory temporary and not being saved which would require the luup restart. I may be wrong, but I do not think it is possible. Hopefully MCVFlorin can shed some light.

  • Garrett

What I think is happening here is that luup.variable_set() also requires a SAVE, but because it was done “behind the back” of the JavaScript, the UI doesn’t know it has to display the SAVE button. So if you had one of those rare abnormal luup restarts where LuaUPnP crashes, the value won’t be saved. In other words, == Dangerous and ~= Permanent.

Does anyone have an idea how to achieve permanent storage of variable values using javascript without having to restart the luup engine?

I’ve got a feeling that setting variables has different behaviour when you make it an official service state variable, so you might get the level of permanence you want that way. But I don’t really have a proper experiment to back that up. All my variables are either SAVE-worthy or can be reconstructed cheaply in the event of a restart, so I’ve never really faced your dilemma.

You could just make your own store in a file on the Vera… but this whole SAVE business is designed to protect the flash memory from too many write cycles, so anything you do to subvert it is going to have Consequences.

Is it somehow possible to send luup stuff from javascripts, for example a simple "luup.log("XXXXXX")"?

Only via HTTP.

Thanks for your very quick replies! As already said, I am not such a high level programmer like you guys and I hope I am not asking stupid questions…

I agree, and that’s what futzle has described in the wiki too. BUT a lot of variables change all the time without luup being restarted, I can add a simple luup.variable_get() in a scene for example. When the scene is run variables are then updated, and they are stored after reloding the UI in the browser or restarting luup (or even after a complete vera reboot), and that saving all happens without the luup engine being restarted.

So this must be possible from within a device tab too…

Quote
Is it somehow possible to send luup stuff from javascripts, for example a simple "luup.log("XXXXXX")"?

Only via HTTP.


Do you mean somehting like: http://10.0.0.XX:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum=30 ?

Ho is that done for logs and setting variables?

Could you maybe please provide a practical code example?

[quote=“chixxi, post:4, topic:170293”]Ho is that done for logs and setting variables?
Could you maybe please provide a practical code example?[/quote]

Doing it through a scene (lu_action) like you suggest would definitely work. You’d have to create an action which invokes Lua code to call luup.log(), say.

Or if you used luup.reguster_handler you can get the Luup engine to call a nominated Lua function when a specific URL is invoked. If your Lua function just happened to call luup.log(), well, that’s the Lua code’s right to do if it wants.

Bedtime for me so no code examples right now, sorry. But look in my plugins (particularly the Caddx one) for Ajax that uses the register_handler thing.

luup.variable_set updates the user_data directly, and not its copy, which means that it doesn’t require restart. But this also means that the change is definitive and cannot be undone by reloading the UI.

You could use the RunLua action to call the luup.variable_set function from JS.

I am so glad there’re users like you guys! Thanks for all the ideas and inputs!! Can’t thank you enough…

I am going to try to get my javascript to run/call codes like the following as a quick solution:
https://<fwd1|fwd2>.mios.com////data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunLua&Code=luup.log(“TEEEEEEEEEESSSSSSSSSSSSST”)

This would allow to do all kind of luup things from within a javascript. But I am not exactly sure on how to achieve this. I thought for security reasons something like httpget is not possible in javascript and I have to use jquery to achieve something like this…

And I am gonna have a look at futzles plugins as soon as I got some hours left over, I guess next weekend.

So this is what I came up with (or honestly, that’s what google said):

FUNCTION:

function httpGet (theUrl) { var xmlHttp = null; xmlHttp = new XMLHttpRequest(); xmlHttp.open( "GET", theUrl, false ); xmlHttp.send( null ); return xmlHttp.responseText; }

BUTTON / CALL:

html += '<td colspan="3"><input type="button" value="SAVE" onClick="httpGet(URL)" style="margin-left:90%" /></td>';

I am updating my plugin “Variable Container” with the above information. And it basically works, I can now save variables permanently in plugin tabs without having to restart luup.

I achieve this by calling commands like this:
[size=8pt]https://<fwd1|fwd2>.mios.com////data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunLua&Code=luup.variable_set()
[/size]

The problem now is that these command are not generic. For testing I just entered my data (user, pass, serial) directly in javascript. If use a local command like the following, it works, but no when accessing the vera externally (not from loacal lan):
[size=8pt]http://10.0.0.XX:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunLua&Code=luup.variable_set()[/size]

Does anyone have an idea how these commands should look like to work from local and external connections? Is it possible to get the local IP by javascript?

I’ll let you in on a little secret: Firebug is really useful for discovering these kinds of things.

  1. Open Firebug to the Script tab.
  2. Point Firefox at Vera.
  3. Open up one of your plugin’s JavaScript tabs.
  4. Find your JavaScript tab’s *.js file in Firebug and stick a breakpoint just inside the beginning of the startup function.
  5. Click again on your plugin’s tab to trigger the breakpoint.
  6. In Firebug, go to the DOM tab. These are your global variables.

I see things like:
base_url = “http://veralite
cgi_url = “http://veralite/cgi-bin/cmh/
command_url =“http://veralite/port_49451
data_command_url =“http://veralite/port_3480
data_request_url =“http://veralite/port_3480/data_request?
and lots lots more.

(I set DNS names for my hosts; you might get IP addresses)

host_url is an object and looks particularly interesting.

Thank you futzle. I am glad you don’t just laugh about my questions, but really provide some worthy info.

It seems like everything seems to be working now. And I am sure once I publish the little script here you professionals can implement some improvements, but I really think that’s a future which a lot of plugins could use to edit their settings.

Thanks for everybody’s help. I will post the script her in a few days, got to do some code beautification before publishing.

It is working. The script is not cleaned up and I am sure some of you professional programmers would choose some different approaches. But it is enough for a proof of concept.

I think the possibility to edit all kind of settings in plugins without having to restart the luup engine is quiet a nice thing.

I will use this for the plugin “Variable Container” in version 1.2 once it’s cleaned up and tested. Attached to this post I added a beta of this version 1.2. So if you would like to test the solution, the best was is to install the plugin from apps.mios.com an then replace the 5 files with the ones attached to this post. I only tested this on UI5 on vera2.

I would be glad to get some feedback about this idea and the provided solution. Is this useful to anybody? Ideas for improvements? Any problems?