Global function / Startup Lua

Not sure what I’m doing wrong…

under

Edit Startup Lua I have

myLua = require("L_MyLUACode")

I upload a file under Luup files named L_MyLUACode.lua

that contain

[code]module(“L_MyLUACode”, package.seeall)

local PLUGIN_VERSION = ‘1.01’

local myLua_DEBUG_MODE = true

– A jump table to the various functions used by the scenes.
– Call as shown below in each scene LUUP section, where xx is the scene number:
– return myLua.executeSceneNumber(xx)
sceneFunctions = {}

local function createSceneNumberTable()
– make sure demonstration scene numbers do not conflict with yours
sceneFunctions[26] = DSC_-Partition1-Home_Entry
sceneFunctions[12] = DSC
-Partition1-_Disarm
–sceneFunctions[201] = Lounge_AV_Radio
–sceneFunctions[202] = Lounge_Standard_lamp_on_for_10_mins
–sceneFunctions[203] = Office_Printer_on_for_30_mins
–sceneFunctions[204] = Unused_TEST
end

local function debugScenes(textParm)
if myLua_DEBUG_MODE then
local text = ‘’
local theType = type(textParm)
if theType == ‘string’ then
text = textParm
else
text = 'type is: '…theType
end
luup.log('My Lua ver ‘…PLUGIN_VERSION…’ debug: '…text, 50)
end
end

local function globaliseTheseFunctions()
– Stick all the luup.call_delay targets into the Global namespace table.
– Otherwise they are not visible to luup.call_delay and won’t be executed.
– We always prefix them with ‘myLua_’ to help avoid Global namespace collisions.

end

local function f_sendLog()
– mda: wrap RexBeckett’s code with a few tweaks in a function so i can call it with a delay

– Keep snapshots of LuaUPnP.log
local snapSecs = 360 – Seconds of log to keep in snapshot.
local snapNum = 3 – Total number of snapshots to keep.
local baseFile = “/www/logsnap”
local snapFile = baseFile … “1.txt”

local snapVar = “Vera Luup Restart Log”… “\n” – mda: initialize the variable to email

– Rename the snapshot stack
if snapNum > 1 then
for i=snapNum-1,1,-1 do
os.rename(baseFile … tostring(i) … “.txt”, baseFile … tostring(i+1) … “.txt”)
end
end
– Take snapshot of current log
local dt = {}
local cut = os.time() - snapSecs
local snapF,snapE = io.open(snapFile,“w+”)
if snapF ~= nil then
local foundcut = false
for line in io.lines(“/tmp/log/cmh/LuaUPnP.log”) do
if not foundcut then
mStr,dStr,yStr,hhStr,mmStr,ssStr = string.match(line,“^%d%d.-(%d+)/(%d+)/(%d+)%s(%d+):(%d+):(%d+)”)
if mStr ~= nil then
dt.month = tonumber(mStr)
dt.year = tonumber(yStr) + 2000
dt.day = tonumber(dStr)
dt.hour = tonumber(hhStr)
dt.min = tonumber(mmStr)
dt.sec = tonumber(ssStr)
tstamp = os.time(dt)
if (tstamp >= cut) then foundcut = true end
end
end
if foundcut then
snapF:write(line … “\n”)

snapVar = snapVar .. line .. "\n" -- mda: add this log line to the variable that will be emailed

-- Following line stops snapshot at point of crash.
if string.find(line,"LuaUPnP Terminated with Exit Code:") ~= nil then break end
end

end
snapF:close()

– mda: clean up the log text in the variable before emailing it; i bet this could be done with a gsub table if i knew how to do that
snapVar = snapVar:gsub(“%[1;00m”,“”)
snapVar = snapVar:gsub(“%[0m”,“”)
snapVar = snapVar:gsub(“%[35;1m”,“”)
snapVar = snapVar:gsub(“%[33;1m”,“”)
snapVar = snapVar:gsub(“%[33;1”,“”)
snapVar = snapVar:gsub(“%[32;1m”,“”)
snapVar = snapVar:gsub(“%[34;1m”,“”)
snapVar = snapVar:gsub(“%[36;1m”,“”)
snapVar = snapVar:gsub(“%[7;36m”,“”)

luup.call_action(“urn:richardgreen:serviceId:VeraAlert1”, “SendAlert”, {Message = snapVar, Recipients = “SMTP-Mail”}, vera_alerts_device) – mda: email the snapVar variable contents using Vera Alert

end
end – function

local function initialiseMyLuaCode()
– luup.call_delay( ‘f_sendLog’, 20) – mda: delay it (to give Vera Alerts time to initialize?)
– debugScenes(‘testing’)
– createSceneNumberTable()
globaliseTheseFunctions()
end

local function DSC_-Partition1-Home_Entry()
– Scene 26
debugScenes('DSC
-Partition1-_Home_Entry is starting’)

myLua_sonosSay("Bon retour, je pr?pare la maison.",15,"Living Room,Kitchen")

debugScenes('DSC_-_Partition1_-_Home_Entry is finished')

end

local function DSC_-Partition1-Disarm()
– Scene 12
debugScenes('DSC
-Partition1-_Disarm is starting’)

myLua_sonosSay("Le syst?me d'alarme est d?sarm?.",15,"Living Room,Kitchen")

debugScenes('DSC_-_Partition1_-_Disarm is finished')

end

function executeSceneNumber(sceneNumber)
– example usage: return executeSceneNumber(xx)
if (sceneNumber == nil)
then
debugScenes(‘sceneNumber is nil’)
return false
end

local roomDescription = luup.rooms[luup.scenes[sceneNumber].room_num] or 'unnamed room'
debugScenes('executing scene '..tostring(sceneNumber)..': "'..luup.scenes[sceneNumber].description..'" in room: "'..roomDescription..'"')

if (sceneFunctions[sceneNumber])
then
    local result = sceneFunctions[sceneNumber]()
	if result then
	    debugScenes('rest of scene '..tostring(sceneNumber)..' was executed')
	else
	    debugScenes('rest of scene '..tostring(sceneNumber)..' was aborted')
	end
    return result
else
    debugScenes('no associated function found for scene number: '..tostring(sceneNumber))
    return false
end

end

function checkTime(time1,time2)
local pStart = time1 – Start of time period
local pEnd = time2 – End of time period
local allow = true – true runs scene during period, false blocks it
local hS, mS = string.match(pStart,“(%d+)%:(%d+)”)
local mStart = (hS * 60) + mS
local hE, mE = string.match(pEnd,“(%d+)%:(%d+)”)
local mEnd = (hE * 60) + mE
local tNow = os.date(“*t”)
local mNow = (tNow.hour * 60) + tNow.min
if mEnd >= mStart then
return (((mNow >= mStart) and (mNow <= mEnd)) == allow)
else
return (((mNow >= mStart) or (mNow <= mEnd)) == allow)
end
end

function checkSwitch(dID, allow)
–local dID = 66 – Device ID of your Z-Wave Switch
–local allow = true – true runs scene if switch is on, false blocks it
local status = luup.variable_get(“urn:upnp-org:serviceId:SwitchPower1”,“Status”,dID)
return ((status == “1”) == allow)
end

function checkWWN_status()
–local dID = 66 – Device ID of your Z-Wave Switch
–local allow = true – true runs scene if switch is on, false blocks it
local status = luup.variable_get(“urn:upnp-org:serviceId:SwitchPower1”,“ModeStatus”,50)
return (status)
end

function sonosSay(text2say, dID, zones)
status = checkTime(“23:30”,“08:00”)
if (status == true) then volume=20
else volume=40
end
if (zones == “”) then
–debugScenes(‘SONOS is talking…’)
luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”,
{Text=text2say, Language=“fr”, Volume=volume},
dID)
else
–debugScenes(‘SONOS is talking…’)
luup.call_action(“urn:micasaverde-com:serviceId:Sonos1”, “Say”,
{Text=text2say, Language=“fr”, Volume=volume, SameVolumeForAll=true, GroupZones=zones},
dID)
end

end

initialiseMyLuaCode()[/code]

But I’m unable to call the global function from anywhere. I test my function in “local” mode to make sure my code is good. Got no error at all.

The problem is to call the “global” function!

I try

sonosSay(“This is a test”,18)

and

myLua.sonosSay(“This is a test”,18)

and both of them are not working.

Did you upload using APPS → Develop Apps → Lua Files ?

yep!

Are you trying to test this by putting the:

myLua.sonosSay("This is a test",18)

In the Startup LUA ?

Devices may not be ready in the Startup LUA … You may need to delay the execution until initialization is complete.

I’m trying to do this into scene or using the “TEST LUUP CODE”…

Does the following work in the “TEST LUUP CODE”…

myLua = require(“L_MyLUACode”)
myLua.sonosSay(“This is a test”,18)

Nope!

Got this:

08 08/22/15 9:19:47.439 JobHandler_LuaUPnP::HandleActionRequest device: 0 service: urn:micasaverde-com:serviceId:HomeAutomationGateway1 action: RunLua <0x72802520>
08 08/22/15 9:19:47.440 JobHandler_LuaUPnP::HandleActionRequest argument Code=myLua = require(“L_MyLUACode”)
myLua.sonosSay(“This is a test”,18) <0x72802520>
20 08/22/15 9:19:47.441 LuaInterface::StartEngine 0x14386f0 device 0 <0x72802520>
02 08/22/15 9:19:47.442 luup_require duplicate L_MyLUACode <0x72802520>
01 08/22/15 9:19:47.443 LuaInterface::StartEngine failed run: 0 [string “myLua = require(“L_MyLUACode”)…”]:2: attempt to call field ‘sonosSay’ (a nil value) <0x72802520>
01 08/22/15 9:19:47.443 JobHandler_LuaUPnP::RunLua failed: myLua = require(“L_MyLUACode”)
myLua.sonosSay(“This is a test”,18) <0x72802520>

Is it better to use the NEW way…

http://lua-users.org/wiki/ModulesTutorial

Hi DesT,

I am not a LUA guru by far and I know Vera should have version 5.1, but not sure it supports the new declaration.

Have you tried making the function global using this statement in the lua file:
_G.sonosSay = sonosSay

Other option I have on an other piece of code is in the startup LUA, but that seems more so I can use them in luup_timer and luup_delay.
sonosSay = myLua.sonosSay

Cheers Rene

I have also been experiencing issues with loading modules via “Startup LUA”. Sometimes it will work at boot, only to disappear after anywhere from minutes to days. I have been going back and forth with Vera support for some time now. I had been hoping to keep loading some LUA this way until I’d finished porting things to proper Plugins, but alas.

The problem is that on UI7 there have been a lot of problems with maintaining the user_data.json file (MCV bugs).
When this happens they roll back to a previous version and you may loose your changes.

I consider these types of bugs seriously FATAL … and is one of the main reasons I will not move up to UI7.