openLuup: Tips & Tricks

[quote=“akbooer, post:11, topic:189397”]Using AltUI to back up your user_data.json file

The latest build of AltUI (1608) adds a ‘backup’ button to the Controllers page. On Vera, this backs up your configuration to a file on your browsing machine by running a CGI file. Under openLuup, you can make this do anything you want by writing the appropriate WSAPI CGI Lua script.

The script file should go into [tt]/etc/cmh-ludl/cgi-bin/cmh/backup.sh[/tt] and here’s an example which simply backs up to a file in [tt]/etc/cmh-ludl/backups/[/tt]. The filename has the format [tt]backup.openLuup-00000000-2016-05-01[/tt], so only unique once a day. The “00000000” is replaced by whatever [tt]PK_AccessPoint[/tt] you’ve given your machine.

#!/usr/bin/env wsapi.cgi

module(..., package.seeall)

ABOUT = {
  NAME          = "backup.sh",
  VERSION       = "2016.04.30",
  DESCRIPTION   = "user_data backup script /etc/cmh-ludl/cgi-bin/cmh/backup.sh",
  AUTHOR        = "@akbooer",
  DOCUMENTATION = "https://github.com/akbooer/openLuup/tree/master/Documentation",
}

local DIRECTORY     = "backup"      -- change this if you want to backup elsewhere

-- WSAPI Lua implementation of backup.sh
-- backup written to ./backups/backup.openLuup-00000000-2015-01-21

local userdata = require "openLuup.userdata"
local lfs = require "lfs"

local _log    -- defined from WSAPI environment as wsapi.error:write(...) in run() method.


-- global entry point called by WSAPI connector

--[[

The environment is a Lua table containing the CGI metavariables (at minimum the RFC3875 ones) plus any 
server-specific metainformation. It also contains an input field, a stream for the request's data, 
and an error field, a stream for the server's error log. 

The input field answers to the read([n]) method, where n is the number
of bytes you want to read (or nil if you want the whole input). 

The error field answers to the write(...) method.

return values: the HTTP status code, a table with headers, and the output iterator. 

--]]

function run (wsapi_env)
  _log = function (...) wsapi_env.error:write(...) end      -- set up the log output, note colon syntax -- 2016.02.26
  
  lfs.mkdir (DIRECTORY)
   
  local PK = userdata.attributes.PK_AccessPoint or "XXXXXXXX"
  local DATE = os.date "%Y-%m-%d" or "0000-00-00"
  local fmt = "%s/backup.openLuup-%s-%s"
  local fname = fmt: format (DIRECTORY, PK, DATE)  
  _log ("Backing up user_data to " .. fname)
  
  local ok, msg = userdata.save (nil, fname)   -- save current luup environment
  
  local status, return_content
  if ok then 
    status, return_content  = 200, "backup completed"
  else
    status, return_content  = 500, "backup failed: " .. msg
  end
  
  local headers = {["Content-Type"] = "text/plain"}
  
  local function iterator ()     -- one-shot iterator, returns content, then nil
    local x = return_content
    return_content = nil 
    return x
  end

  return status, headers, iterator
end

-----

You’ll also need the latest commit from the openLuup GitHub development branch to make this work.[/quote]

Got the backup script to work but… how to recover the configuration from the backup?

See, for example

http://forum.micasaverde.com/index.php/topic,61958.msg355170.html#msg355170

I really should provide a button for that from the backup page…

For those developing plugins on openLuup:

Yes, this is certainly the case. The caching significantly improves startup performance and reduces disk I/O for frequently read service and device files. Lua files are not cached, since they’re almost always uniquely read once, and in fact, are the most likely ones to be changed during development.

ALWAYS reload if you hack the device files of already-loaded devices.

Monitoring openLuup Plugin Global Variables

Although I’m not generally a fan of global variables in code, I’ve added a “Globals” menu item on the openLuup Console page which displays, for each plugin, a list of its global variables.

This might be useful in monitoring/debugging as a snapshot of key variables, which don’t otherwise need to be exposed as device variables, or attributes.

At the moment, a manual refresh is needed to update the page, although I might consider auto-refresh. Another potential future enhancement could be a spreadsheet-like table which allows manual updating of these globals on the fly.

Great. Now easy to find vars that should be local. I always check my plugin code for the little rats but they often sneak by. As an aside, I have three RGB controller devices that according to the console report unnecessarily expose the following:

RGBDeviceTypes 	table: 0x13b3df8
aliasToColor 	table: 0x139ed68
colorToCommand 	table: 0x139ee98
isTransitionInProgress 	false
primaryColorPos 	table: 0x13b3dd0
primaryColors 	table: 0x13b0690

Still being unsure how threads/namespaces/globals/plugins are organised, does the above mean there could be unwanted interactions between the devices??

I see some bizarre globals that I’m gonna hack/squash. Good feature AK.

BTW, the Async is working very well, and seems to be more responsive. And my Network dependent plugins are behaving better. However, every once in a blue moon, a luup reload on my openluup will cause a luup reload on my vera-lite. The logs on both machines don’t show anything informative though. Just " LuaUPnP Terminated with Exit Code: 250" on my veralite.

Excellent! I’ve also seen a few more globals appear during the course of running a plugin, as new functions are called.

No, absolutely not. They’re only ‘globals’ within the context of each plugin. I have, for example, three copies of VeraBridge running, each with their own (intentional) globals, but all called the same thing, of course.

I go to extreme lengths to protect the plugins from one another. The hardest one to crack was the unforgivable habit that some developers have in adding new functions on the fly to the system string library. The Sandbox console page lists the offenders, which are safely isolated from one another.

I’ve seen this once. Wondering if it is related to the recently reported MiOS bug of a browser refresh causing a Luup reload?

https://community.getvera.com/t/hard-refresh-of-browser-causes-luup-reload-7-0-29/207760

I’ve actually refactored some of the asynchronous code to avoid using Vera’s data_request MinimumDelay parameter, since I had some evidence that this may be at least partially to blame, and it allows a longer delay between receiving a status response and asking for another one. All less strain on poor old Vera.

Perhaps, but I have not upgraded my firmware (vera lite), so if anything, a change on the vera servers. I’m using latest openluup development version.