Here is the reason why tonumber(luup.variable_get(…)) fails:
luup.variable_get() returns a list of two values. At index [1] is the variable’s value (a string). At index [2] is the Unix timestamp of when the variable last changed (an integer around 1.3 billion). If you assign this list to one variable, the timestamp is just discarded: that’s how Lua works.
tonumber() takes a list of two values. At index [1] is the string that contains the digits to be converted. At index [2] is the base to use when converting the string. The base can be any number >= 2 and <= 36. Typically it is 2 or 8 or 16 because in IT you tend to get numbers written out in binary or octal or hex. If the base is nil (or omitted entirely, which is the same as passing nil) then Lua assumes the human-centric base of 10.
A Unix timestamp of 1.3 billion is not in the range 2 to 36. So you get an unhelpful error.
Typical code like this:
local v = luup.variable_get(serviceID, name)
local i = tonumber(v)
is more explicitly written:
local v, t = luup.variable_get(serviceID, name)
local i = tonumber(v, 10)
where t is assigned to but never used, and the 10 pops up out of nowhere.
This wrong code:
-- Wrong!
local i = tonumber(luup.variable_get(serviceID, name))
is the same as this wrong code:
-- Wrong!
local v, t = luup.variable_get(serviceID, name)
local i = tonumber(v, t)
If you were desperate to avoid the temporary variable you could construct an anonymous table and then index it:
-- But don't.
local i = tonumber(({luup.variable_get(serviceID, name)})[1])
I bet that is quite a bit less efficient too.