It is currently September 17th, 2021, 1:56 pm

Passing data to a LUA script (and back)

Discuss the use of Lua in Script measures.
Afaflix
Posts: 5
Joined: May 13th, 2011, 1:20 am

Passing data to a LUA script (and back)

Post by Afaflix »

Hello again,
after using the numerous manuals and references I think I know barely enough to get myself into trouble with LUA. yet I managed it anyways.

Since making a countdown script in rainmeter straight is very taxing on the system I was hopeing to make a simpler one in LUA. And it seems it has all the tools needed, but I seem to fail to pass the variables TO the script.

here is my little test setup:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1

[Variables]
MeasureYear1Num=2011
MeasureMonth1Num=6
MeasureDay1Num=15
MeasureHour1Num=12
MeasureMinute1Num=30
MeasureSecond1Num=45

MeasureYear2Num=2011
MeasureMonth2Num=7
MeasureDay2Num=15
MeasureHour2Num=10
MeasureMinute2Num=15
MeasureSecond2Num=15

[MeasureScript1]
Measure=script
ScriptFile=#CURRENTPATH#countdown.lua
TableName=opdate
year=#MeasureYear1Num#
month=#MeasureMonth1Num#
day=#MeasureDay1Num#
hour=#MeasureHour1Num#
min=#MeasureMinute1Num#
sec=#MeasureSecond1Num#

[MeterString1]
Meter=string
MeasureName=MeasureScript1
X=0
Y=0
H=100
FontName=Trebuchet MS
FontColor=255,64,0,255
FontSize=12
StringStyle=Bold
AntiAlias=1
Text=Countdown 1: %1

[MeasureScript2]
Measure=script
ScriptFile=#CURRENTPATH#countdown.lua
TableName=opdate
year=#MeasureYear2Num#
month=#MeasureMonth2Num#
day=#MeasureDay2Num#
hour=#MeasureHour2Num#
min=#MeasureMinute2Num#
sec=#MeasureSecond2Num#

[MeterString2]
Meter=string
MeasureName=MeasureScript2
X=0
Y=35
H=100
FontName=Trebuchet MS
FontColor=255,64,0,255
FontSize=12
StringStyle=Bold
AntiAlias=1
Text=Countdown 2: %1

and the countdown.lua script

Code: Select all

opdate = {year=0, month=0, day=0, hour=0, min=0, sec=0}

function Initialize()

	local TimeToGo = os.difftime (opdate,os.time())
	local daysleft = trunc(TimeToGo/864000)
	local hoursleft = trunc((TimeToGo-daysleft*864000)/3600)
	local minutesleft = trunc((TimeToGo-daysleft*864000-hoursleft*3600)/60)
	local secondsleft = trunc(TimeToGo-daysleft*864000-hoursleft*3600-minutesleft*60)
	
	timeleft = string.format (daysleft, 'd', hoursleft, 'h', minutesleft, 'm', secondsleft, 's')

	return (timeleft)
end
Since it stopped crashing on me and actually produces a '0' as output I assume I have the syntax right now, but everything I do seems to tell me that the variables don't get passed on to the script.
I have seen other countdown scripts and they use seemingly exactly this method ...

again, any help in this is greatly appreciated
User avatar
santa_ryan
Posts: 397
Joined: June 22nd, 2010, 4:11 am

Re: Passing data to a LUA script (and back)

Post by santa_ryan »

The lua script might be reading the passed variables from rainmeter as strings. Use tonumber on all of the variables and see if that works.

Plus, although im not sure about this, where are you even initilizating the variables??? Even if you have the keys in the rainmeter skin, you still have to initilize them....
Have you just stripped this part out of the code, because you know it works? Or are you not doing it at all?

Also, using print() you can easily see if your variables are even being passed properly. Then after each "Step" in the process use a print function to print out the results. When the rainmeter log finally comes up with a 0. Then whatever is right before the print function is the culprit.
Last edited by santa_ryan on May 16th, 2011, 8:30 pm, edited 2 times in total.
I have three rules when I'm trying to help you.
  • Don't get mad when you don't understand something
  • Be VERY specific with what you ask for.
    The more specific you are, the higher the quality of support you receive.
  • Do not just copy and paste what I put in examples and come back saying it doesn't work.
    It does work, but I purposely left blanks that you need to fill for your specific needs.
User avatar
jsmorley
Developer
Posts: 22270
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Passing data to a LUA script (and back)

Post by jsmorley »

1) I don't see where you are retrieving the variables you set up in [Variables] in the skin in the .lua at all.

See "ReplaceVariables()" in the Lua for Rainmeter section of the manual at http://rainmeter.net/cms/LuaScripting

2) As to the values you are passing to the .lua in the Measure=Script measure, those also need to be initialized in the .lua before you can use them.

From the manual:

**********************************************
PROPERTIES
This is actually a Lua "table", used to hold the settings (Key=Value, like MySetting="SomeSetting" in the example above) you wish to pass from Rainmeter to the Lua script. You simply tell it the name of the key from the measure in the skin, and initialize it with any value. The format is:

PROPERTIES =
{
MyTextSetting = "";
MyNumberSetting = 0;
}

You can then later use these settings in your script, with PROPERTIES.MyTextSetting for example, a standard Lua way of reference a table index by value.

Notes:
PROPERTIES passed from Rainmeter are actually always strings. I initialized the MyNumberSettings variable above as a number just to remind myself that I will be using the value as a number later, and will need to use "tonumber" on it.
Remember that Lua is always "case sensitive". This table is PROPERTIES, not Properties.
While the trailing semi-colon is optional in Lua in almost all other circumstances, they are required on each setting to initialize this table.
This can be an empty table, (PROPERTIES = {}) if you are not passing any settings, but should be present.
******************************************

Skin:

[MeasureScript1]
Measure=script
ScriptFile=#CURRENTPATH#countdown.lua
TableName=opdate
year=#MeasureYear1Num#
month=#MeasureMonth1Num#
day=#MeasureDay1Num#
hour=#MeasureHour1Num#
min=#MeasureMinute1Num#
sec=#MeasureSecond1Num#

.lua script:

PROPERTIES =
{
year = "";
month = "";
day = "";
hour = "";
min = "";
sec = "";
}

function Initialize()
CurrentYear = tonumber(PROPERTIES.year)
.... etc, etc...
end -- function Initialize

function Update()
NextYear = CurrentYear + 1
end -- function Update

function GetStringValue()
return tostring(NextYear)
end -- function GetStringValue
User avatar
Chewtoy
Moderator
Posts: 995
Joined: June 10th, 2009, 12:44 pm
Location: Sweden

Re: Passing data to a LUA script (and back)

Post by Chewtoy »

Instead of trunc I would recommend using math.floor as that seems to work better (did for me when I made my countdown skin).
You also need to retrieve the variables you pass to Lua.
In this case it's quite easy to just add PROPERTIES = {year=0, month=0, day=0, hour=0, minute=0, second=0} to the top of the Lua-script (name is important) and use that.
Then in function Update() I you could use TimeLeft = os.time(PROPERTIES) - os.time()

That will give you the time, but you've yet to pass them back to the skin. You need to call the meter you want to set and then use the MyMeter:SetText(SomeTime).

Just my two cents.
If you want I can give you an already made countdown-skin you can toy with.


Edit. Js beat me to it. But you don't need to use tonumber() though. Lua is clever and will figure out what you want as long as you give it nice things to play with.
I don't think, therefore I'm not.
User avatar
jsmorley
Developer
Posts: 22270
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Passing data to a LUA script (and back)

Post by jsmorley »

"But you don't need to use tonumber() though. Lua is clever and will figure out what you want as long as you give it nice things to play with"

Mostly true, but you need to be careful. Lua is very clever about type casting automatically, but you can get in trouble too, especially when going back and forth to Rainmeter. I find it pays to cast things, even if it is only to remind me of what I am using the value for.

It's not like you need to know 50 different data types like C++, there is basically tonumber() and tostring() :-)
User avatar
Chewtoy
Moderator
Posts: 995
Joined: June 10th, 2009, 12:44 pm
Location: Sweden

Re: Passing data to a LUA script (and back)

Post by Chewtoy »

jsmorley wrote:"But you don't need to use tonumber() though. Lua is clever and will figure out what you want as long as you give it nice things to play with"

Mostly true, but you need to be careful. Lua is very clever about type casting automatically, but you can get in trouble too, especially when going back and forth to Rainmeter. I find it pays to cast things, even if it is only to remind me of what I am using the value for.

It's not like you need to know 50 different data types like C++, there is basically tonumber() and tostring() :-)
Indeed. You need to watch your back. Oh the fun with trying to figure out why the hell something is not working, and all you need to add is one simple command. Just as fun as chopping your toe tips of with tip-ex (try that one).
Another good command to know is loadstring("return " .. MyVar) in case you are dealing with calcs you get from rainmeter.
I don't think, therefore I'm not.
Afaflix
Posts: 5
Joined: May 13th, 2011, 1:20 am

Re: Passing data to a LUA script (and back)

Post by Afaflix »

Chewtoy wrote: If you want I can give you an already made countdown-skin you can toy with.
I think I already have gotten a hold of that one, sacrificed at the sacred terminal and divined my future as a programmer from it's entrails.
I saw starvation, sickness and an angry mob with pitchforks.
But until that comes to pass ...

math.floor ... I have seen it used, but didn't immediately understand it. I guess I have to read up on that one.
I guess the part that I couldn't solve was how to make a single string in this format "00d 00h 00m 00s" from it. That's why I used trunc() and simply attached the pieces to each other.

here is the lua with the copy/pasted math.floor part ... and a failed attempt to make a string from it.

Code: Select all

PROPERTIES =
{
year = "";
month = "";
day = "";
hour = "";
min = "";
sec = "";
}

function Initialize()
dif = 0;
timeleft = {};
timeleftstring = ""
end -- function Initialize

function Update()

		local dif = os.time(PROPERTIES) - os.time()
		local timeleft = {
		[1] = math.floor(dif/60/60/24),	--day
		[2] = math.floor(dif/60/60)%24,	--hour
		[3] = math.floor(dif/60)%60,	--minute
		[4] = math.floor(dif)%60		--second
		}
	
	timeleftstring = string.format (timeleft.1,"d ",timeleft.2,"h ",timeleft.3,"m ",timeleft.4,"s")

end

function GetStringValue()
	return (timeleftstring)
end
jsmorley wrote: 1) I don't see where you are retrieving the variables you set up in [Variables] in the skin in the .lua at all.
That was the top line "opdate = {year=0, month=0, day=0, hour=0, min=0, sec=0}" which I stole from another script. but I changed PROPERTIES to opdate not realizing that PROPERTIES is actually needed as is.
santa_ryan wrote: Also, using print()
ah .. gold right here


Thank you all kind gentlemen ... I think this will keep me entertained until the pitchfork mob arrives.
User avatar
santa_ryan
Posts: 397
Joined: June 22nd, 2010, 4:11 am

Re: Passing data to a LUA script (and back)

Post by santa_ryan »

Afaflix wrote: ah .. gold right here


Thank you all kind gentlemen ... I think this will keep me entertained until the pitchfork mob arrives.
using Print() with a key/value called Debug=1 (or 0) in the script measure or a variable, allows all of my scripts to easily enable debugging functionality via print function. It's an extremely useful function. While lua automatically writes to the log on error, its sometimes not an "error" that's causing the problem. I have SciTE do all of that syntax checking nonsense, as all of my lua scripts are obscenely long, and so ill never see a general error when the script is ran. My "Errors" come in the form of doing a wrong calculation, or using the wrong bang, and other things, that generalized error checking cant pickup. Just a tip from someone who's be there, done that, came back, and found out he forgot something, etc. etc. etc. ;)
I have three rules when I'm trying to help you.
  • Don't get mad when you don't understand something
  • Be VERY specific with what you ask for.
    The more specific you are, the higher the quality of support you receive.
  • Do not just copy and paste what I put in examples and come back saying it doesn't work.
    It does work, but I purposely left blanks that you need to fill for your specific needs.