CallFunction_Startup_1 attempt to call a nil value

I am working on my first plugin. Everything works under openLuup, but when I try to install it on Vera, I get following error:

LuaInterface::CallFunction_Startup-1 device 91 function myplugin_init failed attempt to call a nil value

The lua file as well as the startup function is specified in the interface file like this:

<files>L_MyPlugin1.lua</files>
<startup>myplugin_init</startup>

I am able to run test code:

myPlugin = require "MyPlugin1"

but this fails with similar error:

myPlugin:myplugin_init(91)

the init function is declared inside L_MyPlugin1.lua as:

function myplugin_init( dev )
...
end

I am out of ideas.

Delighted to hear it! :wink:

Do you have a module statement at the start of your code?

This might be a global scope problem. You could try adding the line:

_G.myplugin_init = myplugin_init

Definitely a scope problem, as @akbooer has said. You need to expose the module function (myplugin_init) into the global scope. You also need to similarly expose any callback functions used in call_delay or call_timer and similar calls.

Another approach is something like this:

function myplugin_init( dev )
    myPlugin = require "MyPlugin1"
    gTimerCallback = myPlugin.timerCallback
    return myPlugin.myplugin_init( dev )
end

A couple of things to note: first, I’m not using colon : as a qualifier for the functions here, I’m using dot. Colon is for objects, and loaded modules are just tables, not objects. Second, I’m making a global called gTimerCallback that is a reference to the module’s function of the same name, which allows me to luup.call_delay( "gTimerCallback", 5 ). Personally I don’t normally use Hungarian notation, but I did it here to make it more clear what’s going on. Finally, don’t forget that your module startup function can return boolean success (it actually can return three values – see the docs).

You should also be aware that if you put your module file in <files>, Luup will run it, not as a module, it will just load it and compile it. But the way you are using it (as a module using require), that’s no benefit, it just makes busy work. I would just remove the <files> tag entirely.

I did and commenting it out resolved the problem. I am still not clear on scoping when it comes to vera, openLuup, or as can be seen lua. Why did the module statement matter for Vera, but not openLuup?

I am assuming that this would go into the <functions> section of the interface file? I have noticed that you prefer using it this way in your plugins, is there any benefit to doing one way or the other?

Style is individual. I prefer not to use the _G approach because it kind of breaks encapsulation if you do it in the module itself, and it’s not necessary if you do it in the <startup> code that loads the module. It’s just a preference.

By the way, this is another possibility:

<functions>
    myPlugin = require "MyPlugin1"
    function timer_wrapper( param )
        myPlugin.timerCallback( param )
    end
    function myplugin_init( dev )
        return myPlugin.myplugin_init( dev )
    end
</functions>

In this version, you’re just creating a wrapper function to call the module’s function. You would use it like this luup.call_delay( 'timer_wrapper', 5 )

There are lots of ways to do it. Just do what you find most agreeable that, of course, actually works.

I saw your other comment to @akbooer. If you’re going to do plugin development, and in particularly development for both Vera Luup and openLuup, you really need to wrap your head around scoping and what it all means and how it works. It’s not easy, but it’s time well-invested, as proper scoping and use of scope will prevent a lot of latent bugs and weird behaviors. Lua is very permissive, so things that another language would flag as dangerous get not so much as a whimper from Lua, but the bill comes due in runtime.

Best Home Automation shopping experience. Shop at getvera!

© 2020 Vera Control Ltd., All Rights Reserved. Terms of Use | Privacy Policy | Forum Rules