I wanted to post some tips on when creating plugins and have others share their tips as well. This topic should be used as a guide on the do’s and don’ts.
Use the standard device types and service id’s where ever possible. This will allow for better 3rd party app integration and support.
Limit setting variables unless the value has changed. So only use variable_set if a value has changed from previous value.
Sample code that shows how to use a function to check if a new value is different from the current value and use variable_set if value is different. Credit goes to guessed for creating this function.
function setIfChanged(serviceId, name, value, deviceId)
local curValue = luup.variable_get(serviceId, name, deviceId)
if ((value ~= curValue) or (curValue == nil)) then
luup.variable_set(serviceId, name, value, deviceId)
return true
else
return false
end
end
Check your xml code against a xml validation tool like: http://www.xmlvalidation.com/ or others online. (D_xxx.xml, S_xxx.xml, etc).
Check your json against a json validator tool like http://www.jsonlint.com (D_xxx.json files).
Add a Debug state-variable to your plugin. Check it during plugin initialization and set a variable according to its value. E.g:
[code]
local debug
local debSV = luup.variable_get("urn:dcineco-com:serviceId:KiraRx1","Debug", lul_device)
if debSV == nil then
debSV = "0"
luup.variable_set("urn:dcineco-com:serviceId:KiraRx1","Debug",debSV,lul_device)
end
debug = (tonumber(debSV) > 0)[/code]
Add log statements in strategic parts of your code where problems are likely to arise - particularly where values are read from devices, other plugins or over the network:
if debug then luup.log("KiraRx: From:"..ip.." Read:"..newrx ) end
...
if debug then luup.log("KiraRx: Learn job entered. Timeout:"..timeout) end
...
if debug then luup.log("KiraRx: Learn timed out.") end
If anybody has problems with your plugin, you can get them to set the Debug state-variable to “1” and send you the section of their log where the error occurs.
If your plugin communicates with external hardware via IP, use the device’s ip attribute to allow the IP address and port to be specified. Check the values during plugin initialization and flag problems on the console display by calling luup.task(…).
Here’s an example that will also provide a default port number (8899) if it is not specified in ip:
[code]
local ipaddr
local ipport
local ip = luup.attr_get("ip",lul_device)
if (ip == nil) or (#ip == 0) then
luup.task("ip address not entered!", 2, "yourplugin", -1)
luup.log("yourplugin: ip address not set.")
return false
end
ip = string.gsub(ip," “,”“)
ipaddr, ipport = string.match(ip,”(%d+%.%d+%.%d+%.%d+)%:?(%d*)")
if (ipaddr == nil) or (#ipaddr == 0) then
luup.task("Invalid ip address: " … ip, 2, “yourplugin”, -1)
luup.log("yourplugin: Invalid ip address: " … ip)
return false
end
if (ipport == nil) or (#ipport == 0) then
ipport = 8899
luup.attr_set(“ip”,ipaddr … “:” … ipport,lul_device)
luup.log(“yourplugin: Port not specified, " … ipport … " assumed.”)
end[/code]
For simple plugins, it is usual to place all the Lua/Luup code in the Implementation file (I_.xml). Because this file must contain valid xml, you can get an error with a deceptively simple statement:
if x < 10 then ...
The < is a special character in xml and will throw a syntax error when you use it for Lua in an Implementation file. There are two solutions:
Simply invert the expression to use a greater-than operator:
if 10 > x then ...
or
Use an xml escape sequence in place of the less-than operator:
if x < 10 then ...
Best Home Automation shopping experience. Shop at Ezlo!