I’ve been building a wishlist since starting work with Vera & the LUA/luup extensions, a few weeks ago.
Whilst I’m new to lua, I figured I’d float these out there to start the discussion before we get too far down the road. Some of the ideas might be a little crazy, some might not even be implementable, but I wanted to float them to get the discussion going before things get locked down too much.
For the most part, they deal with solidifying/clarifying existing functionality. I specifically avoided anything adding new functionality, since those requests can be handled in other discussions.
So here’s my list, in order of what I think is needed first:
1. Use a module, instead of a prefix, to contain all of the fn defns in Micasaverde’s space.
You could use something like “[tt]luup[/tt]”, since that goes with your existing naming model and code then becomes
[tt] luup.[/tt].
This would eliminate the need for the current prefix:
[tt] lu_[/tt].
This variable could be established/setup with the appropriate:
[tt] luup = requires(‘libLuup.lua’)
[/tt]
… in the code block that’s generated for the XML defns we upload - similar to how event handlers are generated off of the <[tt]incoming>[/tt] (etc) sections of the XML.
2. [tt]lug_device[/tt] member attributes
This global has a number of attributes with varying naming conventions.
eg. [tt]DeviceType, Category_Num, ID[/tt]
I think these could be standardized to a single convention, likely in lowercase, to something more like:
[tt]room[/tt] - the Room number, or a ptr/ref to a Room structure (description, etc)
[tt]devicetype[/tt] -
[tt]category[/tt]
[tt]parentdevice[/tt] - currently an int, but see below for improvements
[tt]ipaddress[/tt]
[tt]macaddress[/tt]
[tt]id[/tt]
[tt]udn[/tt]
I don’t mind which formatting convention is used, as long as it’s done consistently throughout. I’m sure there’s a “prevailing wind” in the LUA coding conventions that can be applied here. I chose lowercase, as that seemed common (along with short, often one-word, names)
Personally, I’m not a fan of globals, but I understand this is common in LUA. If this must remain a global, then please change the name (see below for alternate)
3. Make [tt]CallFunctionTimer[/tt], [tt]CallFunctionDelay[/tt] support non-string Parameter types
The current definitions of CallFunctionTimer/Delay limit the consumer to a single “string” parameter.
Remove this restriction, and permit an arbitrary list of parameters to be specified, where any of the parameters may use the full complement of Parameter types (“string”, “number”, “table”, “function” etc).
This will help avoid having code that converts parameter lists into string form and back again for anything complex needing to be scheduled.
4. Model the sub-packages (io, jobs, child-handling)
This seems to be possible in LUA, but if would clarify things if the logical “groupings” of sub-interface were declared/used that way.
This request is a counterpart of (1), covering the sub-module groupings that exist within the APIs.
Given the current interfaces, one could imagine:
[tt]luup.io[/tt] - General IO Routines for interfacing with devices
[tt]luup.debug[/tt] - Logging and any supporting/future Debug hooks
[tt]luup.device[/tt] - Routines for Discovery, and Manipulation, of Vera's Device table.
[tt]luup.job[/tt] - Routines to handle fn and method queuing
[tt]luup.net[/tt] - routines to acquire data over the net (these should be a core/standard "module", not really part of Vera, but pre-loaded for us)
[tt]luup.ui[/tt] - stuff like registerHandler, and any routines to generate "web" output.
There could be others also, depending upon how much you want to separate Device manipulation, such as adding/removing Child devices, from data-transmission, such as setting or getting Variable values from UPnP devices.
Additionally, some of the “[tt]luup.net[/tt]” items ([tt]lu_wget[/tt], etc) could potentially be replaced by more standard OpenSource modules.
5. Model the luup IO apis on the internal lua io api naming
These names can probably be condensed down to:
[tt] luup.io.write()
luup.io.intercept()
luup.io.read()
[/tt]
I’d guess these names will be easier to read than the existing API’s of the form:
[tt] lu_iop_send()
lu_iop_intercept_incoming()
lu_iop_recv_block()
[/tt]
… at least for folks starting off. It also uses (4) to group the sub-modules, to avoid the “[tt]iop[/tt]” prefix.
6. Provide the ability to upload LUA modules, but include some more common ones
I suspect this is the intent of the “Add extra LUA file” option, but haven’t had time to use it.
I’d like to be able to upload “standard” modules like the XMLParsers and Xpath Libs, so that I can then use [tt]require(xxx)[/tt] to load/use them.
If this is the intent of the existing, write the example code to use this to let people know it can be done.
7. Add methods to the Device structure to “lookup” Child Devices
In the event handlers, our code is provided with [tt]lul_device[/tt] as an implied parameter. This is an int representing the “[tt]Device_Num[/tt]” of the device firing the event.
In the Alarm device I’m writing, I have lots of child-devices. Given the [tt]lul_device[/tt] handle, there’s no obvious way to get the [tt]Device[/tt] table of each child device.
Eventually I worked out how to traverse [tt]lug_device[/tt], skipping over all the devices that dont belong to me ([tt]parent ~= lul_device[/tt]).
This operation is something virtually every device writer is going to have to do to get “useful” information (children, or IP address) so it would be useful if you passed us the Device table (entry from the Global table) instead of [tt]lul_device[/tt].
If you did this, you could eliminate the need for a “public” l[tt]ug_device[/tt] variable (or you could add a [tt]luup.device.getroot()[/tt] function)
Additionally, extend “Device” to contain the functions:
[tt]findchild(id)[/tt] - find a specifically named-child, by it's "ID" (spec'd when creating)
[tt]childpairs()[/tt] - return an enumeration of the children, as a table of Device
If you go this route, then Device becomes a true tree-structure, with Parent (device ptr) and ChildList (table of device ptr) type members (and accessor functions)
The current flat-global-list is going to be hard to work with, particularly the more devices it gets in it. Modelling this with API’s should also cut down the lead-time to authoring new devices.
My single [Alarm] device will add ~50-300 “sub-devices”, representing all the sensors of a fully populated alarm system. Anyone with 1-2 children is going to be penalized in lookup by my “fat” device being present in the system
Anyhow, I hope this generates some healthy discussion. I’ve gotten a long way with the APIs as they stand, so most of my items here are intended to make it quicker/faster to learn, so that many more components can be built, by many more developers/scripters.