Scene running a xxx.lua file on mapped drive. ? (Lua Test)

Hi

Hopefully a quick one for someone to answer …

I have a mapped drive (CIFS) set up on my Vera and I use the great Lua Test tool a lot to try out bits of code I’m learning etc via dedicated xxxxx.lua files.

My question is - is it possible to have vera execute (e.g via a scene) the code that is held in a .lua file/document ?

How would you do that ?
Would this be an os.execute command ?

Yes, it is.

Would this be an os.execute command ?

No, it wouldn’t.

How would you do that ?

It slightly depends on what type of code this is. Would it need to be run in the Vera context (using luup.xxx calls) or is it otherwise stand-alone.

If this is really a vanilla Lua question, then take a look at: Lua dofile

For a more readable introduction (and reference) to the Lua language, see here: Progamming in Lua

Hi @akbooer

Thanks - as it has luup calls in it, so what would need to be done differently for that ?

Vera file location (used for Lua Test) = /nas/luatest/bedtime-countdown2.lua

You’d probably need to read the file into a string, use loadstring(), instead of dofile(), and use setfenv() to set the environment to the scene’s _G variable, before calling it.

I don’t know for sure, since I’ve never tried in the context of Vera itself, but this is generally the way to approach it.

The openLuup loader does much the same for .lua files. You can see the relevant function compile_lua() here: https://github.com/akbooer/openLuup/blob/master/openLuup/loader.lua#L382

If the file is not changed dynamically between invocations, you could, instead, simply use require() to load it as a regular module (which actually does similar to the previous list of functions I gave.)

What’s not clear is your use-case, ie. WHY the file is external and what it does.

Lots to look at there.

The file is external so it’s something that I can then work on from multiple places / devices etc. and I can make changes on the fly (there is a lot of text (TTS) in this first one) which would not require any access to or reload of Vera

As it is a mapped drive - i’m just thinking out loud but is this the right file io.open and read command to use ?

[code]
function readAll(file)
local f = io.open(file, “rb”)
local content = f:read("*all")
f:close()
return content
end

readAll(/nas/luatest/bedroom-countdown.lua)[/code]

At last some progress…

After some googling this seems to take me a little further as the code within the lua file is executed this time.

[code]function readAll(file)
local f = io.open(file, “rb”)
local content = f:read("*all")
f:close()
return content
end

script = readAll("/nas/luatest/polly_kitchen.lua")
print (readAll("/nas/luatest/polly_kitchen.lua"))
test = loadstring(script)
test()[/code]

I have also added the above to a scene (in the luup section) and while it seems to work - it takes a while to run compared to running it via Lua Test? Any ideas why it takes longer ??

Also I should add

@akbooer if you are reading this still I did not understand what you meant by the following - therefore i was not able to include it into the script inposted just earlier .

Whats does that mean / do ?
Where do I need to put it ?

Depending on the context, you may not need this. An example of how/where it’s used is in the code I pointed to. It’s called before the invocation of the load function. If your test code works, then forget it.

Yes, I thought you would be changing it on the fly. It is also possible to do this with the require statement, but you have to explicitly clear the loaded module before using require again.

Out of interest how would you use setfenv() if you needed it? Is it used instead of loadstring()

Also.

If I recall correctly don’t the require statements get added into the lua start up process ?

I’m probably getting way a head of myself now - but if that so - does that mean I could ‘load’ various lua files at start up which can be reference working a scene (I assume they are loaded into memory)?

An then within a scene before it runs somehow check if it’s the latest version e.g have the scene check the last modified date of the file with the last start up time ? ?

This suggests there is a third party library to do that ?

@akbooer youre probably getting to know me a bit now (over the years) - so I’m probably completely overreaching here :slight_smile: but as I’ve got a load of Lua (luup) scripts on my NAS which has its folder mapped to Vera - it’ll be interesting to be able to pre-load , update and execute externally hosted scripts at the touch of a button.

(I used Textastic on my iPad/iPhone for much of my coding now and that maps to the same share Vera does )

The code example I pointed to on GitHub shows exactly how this is done. The other Lua documentation explains in more detail. In a nutshell, it allows you to construct a ‘sandbox’ which completely defines the global environment (ie. other variables and functions) available to it. It’s actually nothing to do with loadstring() and can be used quite separately.

If I recall correctly don't the [b]require[/b] statements get added into the lua start up process ?

No, they can be used anywhere. If the module has already been loaded, it will not be loaded again (once again, unless you explicitly purge it from the list of loaded modules.) I really do encourage you to look more closely at the Lua documentation to understand how these things really work.

does that mean I could 'load' various lua files at start up which can be reference working a scene (I assume they are loaded into memory)?

Absolutely. That’s a really good way of doing so. I load a large number of modules in this way so that I can use them in scenes.

An then within a scene before it runs somehow check if it's the latest version e.g have the scene check the last modified date of the file with the last start up time ? ?

This suggests there is a third party library to do that ?

Well, that would be slightly clunky, but one way of doing it. You might have a separate scene which check every 10 minutes or so, … or something else. Your individual scene code needs to be entirely focused on the logic of the scene, not extraneous mechanisms to do with the system.

The luafilesystem, documented here https://keplerproject.github.io/luafilesystem/manual.html, can get all sorts of file attributes included the last modified date. It’s on the standard Vera system and can be loaded with:

local lfs = require "lfs"

lfs.attributes() is the call you need.