It is currently June 25th, 2019, 6:30 am

Using lua to load values from .txt file to variables in rainmeter

Discuss the use of Lua in Script measures.
MrStiltskins
Posts: 4
Joined: May 3rd, 2017, 7:18 pm

Using lua to load values from .txt file to variables in rainmeter

MrStiltskins » May 3rd, 2017, 7:31 pm

Here is my code:

Base was dr-dolittle's Iron man skin but the code has for the most part been removed.

Code: Select all

[rainmeter]
by Nicholas Parrell
-weather

VARIABLES============================================

[variables]

temp_f = 15
feelslike_f = 15
City = Philadelphia
;updating = !Execute ["C:\Users\Nick\Documents\Python\testing.py"]


[background]
meter=image
imagename=#skinspath#dr-dolittle\shared\weather.png
x=0
y=0


[luaScript]
Measure = script
ScriptFile = "C:\\Users\\Nick\\Documents\\Rainmeter\\Skins\\dr-dolittle\\@include\\getWeather.lua"
UpdateRate = 1000



[meterTemp]
measurename=luaScript
meter=string
x=120
y=35
fontcolor=0,255,255,150
fontsize=10
stringalign=center
stringstyle=BOLD
fontface=electrofied
;text = 0
text = #temp_f#
antialias=1
DynamicVariables = 1

[meterCity]
measurename=luaScript
meter = String
x = 215
y = 25
stringstyle=normal
fontcolor=00fff6
fontsize=10
stringalign=center
stringstyle=BOLD
fontface=ALGERIAN
antialias=1
;text = 0
text = #City#
DynamicVariables = 1
;postfix="f"

[meterFeelsLiketemp]
measurename=luaScript
meter=string
x=225
y=86
stringstyle=normal
fontcolor=00fff6
fontsize=40
stringalign=center
stringstyle=BOLD
fontface=ALGERIAN
antialias=1
;text = 0
text = #feelslike_f#
postfix="f"
DynamicVariables = 1



lua file

Code: Select all

function ReadFile()
  --FilePath = SKIN:MakePathAbsolute(FilePath)
  FileP = "C:\\Users\\Nick\\Documents\\Rainmeter\\Skins\\dr-dolittle\\@resources\\weather.txt"
  --print(io.open(FileP, "r"))
  local File = io.open(FileP, "r")
  --print(File)
  if not File then
    print('ReadFile: unable to open file at ' ..FileP )
    return
  end

  local contents = {}
  for Line in File:lines() do
    table.insert(contents, Line)
  end
  print(contents[1])
  print(contents[2])
  print(contents[3])
  SKIN:Bang('!SetVariable', 'temp_f', contents[2])
  SKIN:Bang('!SetVariable', 'feelslike_f', contents[3])
  SKIN:Bang('!SetVariable', 'City', contents[1])
  return
end

ReadFile()
Text File

Philadelphia, PA
62.8
62.8

I want to be able to take the values from the text file and set them as the variables temp_f, feelslike_f, and city.

I am just starting to use lua so I am not exactly sure how it integrates with Rainmeter.

As of right now I know that lua is getting the correct values from the file but I am not sure how to set them in Rainmeter file nor if the Rainmeter file in running the lua script.
User avatar
balala
Rainmeter Sage
Posts: 8308
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Using lua to load values from .txt file to variables in rainmeter

balala » May 3rd, 2017, 8:37 pm

Here is an updated code of the lua script file:

Code: Select all

function ReadFile()
	local contents = {}
	FileP = SKIN:MakePathAbsolute('@Resources\\weather.txt')
	local File = io.open(FileP, 'r')
	for Line in File:lines() do
		if Line ~= '' then
			table.insert(contents, Line)
		end
	end
	File:close()
	return contents
end

function Update()
	local MyVar = ReadFile()
	SKIN:Bang('!SetVariable', 'temp_f', MyVar[2])
	SKIN:Bang('!SetVariable', 'feelslike_f', MyVar[3])
	SKIN:Bang('!SetVariable', 'City', MyVar[1])
end
Note the followings:
  • I've introduced a new variable (MyVar), which keeps the values returned by the ReadFile() function. Unlike in your initial code, this function, in the above code, returns an array variable.
  • You forgot to close the read text file, which I did with the File:close() command.
  • I added the Update() function, which is executed on each update of the Rainmeter skin. If the text file doesn't change, you can move all the content of the Update() function, to the Initialize() function, which is executed just once, when the skin is refreshed.
  • Instead of the FileP = 'C:\\Users\\Nick\\Documents\\Rainmeter\\Skins\\dr-dolittle\\@resources\\weather.txt' command, I better choice would be the following command: FileP = SKIN:MakePathAbsolute('@Resources\\weather.txt'). This way you don't have to give the absolute path of the file, it'll be determined automatically, by the skin, along with the script file.
  • Be careful you have the weather.txt file coded as ANSI. Otherwise you can have troubles.
MrStiltskins
Posts: 4
Joined: May 3rd, 2017, 7:18 pm

Re: Using lua to load values from .txt file to variables in rainmeter

MrStiltskins » May 3rd, 2017, 10:49 pm

So I made the changes but I am still not seeing the rainmeter updating with the values from the lua script.
User avatar
balala
Rainmeter Sage
Posts: 8308
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Using lua to load values from .txt file to variables in rainmeter

balala » May 4th, 2017, 5:26 am

MrStiltskins wrote:So I made the changes but I am still not seeing the rainmeter updating with the values from the lua script.
Then please pack both files (the ini and the lua file), along with the text file and upload the package. I'd like to check them.
MrStiltskins
Posts: 4
Joined: May 3rd, 2017, 7:18 pm

Re: Using lua to load values from .txt file to variables in rainmeter

MrStiltskins » May 4th, 2017, 1:06 pm

I have attached the skin that I am working with.

The .ini file I am trying to use is the weather.ini in the weather folder.

The Lua script is in the @include folder.

The .txt file the the lua script is getting its values from is in the @resources folder.
You do not have the required permissions to view the files attached to this post.
User avatar
balala
Rainmeter Sage
Posts: 8308
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Using lua to load values from .txt file to variables in rainmeter

balala » May 4th, 2017, 7:08 pm

One of the biggest problems of the getWeather.lua file resides in its last line (Update()), placed after the end of the Update() function. There also are some other minor problems, too. Eg the used print function won't properly return the values to the appropriate variables of the skin. I'd be tempted to replace for example the print(MyVar[1]) command (Update() function), with the much better SKIN:Bang('!SetVariable', 'temp_f', MyVar[2]). With this command, you're very precise, telling the script which variable of the skin should get which variable calculated (read) by the lua script.

Neither the print('ReadFile: unable to open file at ' ..FileP ) command isn't a good one, but finally I couldn't decide which variable of the skin should show the "Unable to open file..." message, so finally I let it in peace. Maybe it would be a good idea to replace it with a SKIN:Bang('!SetVariable', ... command.

Another important problem is that due to the fact that the ini file isn't placed into the root folder of your config, but into a subfolder of this (I mean that it is not in the dr-dolittle folder, but in its Weather subfolder), the SKIN:MakePathAbsolute doesn't work. I had to find another method to get the path of the @Resources folder. I finally did it with the following function:

Code: Select all

function GetResources()
	return tostring(SKIN:GetVariable('@'))
end
This function returns the path of the Resources folder, so you can use it into the rest of the lua code. This is done by the FileP = GetResources() .. 'weather.txt' command of the ReadFile() function.

Furtherly, the encoding of the Weather.ini file was wrong, I updated it to ANSI.

I also have updated a few other things in the code of the skin, for example I've moved the getWeather.lua file into the @Resources folder (where it has a much better place) and rewrote the ScriptFile option of the [luaScript] as: ScriptFile=#@#getWeather.lua, telling Rainmeter, to look for the getWeather.lua file within the @Resources folder.

Note that by Nicholas Parrell is not a valid option for none section (it is placed into the [Rainmeter] one). I let it there, but you should remove it, or at least comment it out. Even the Author is a deprecated option in to the [Rainmeter] section, newly belonging to the [Metadata] section, but by definitely isn't a valid option.
Attached you'll find the repacked config. Please check it and let me know if it is working well.
You do not have the required permissions to view the files attached to this post.
MrStiltskins
Posts: 4
Joined: May 3rd, 2017, 7:18 pm

Re: Using lua to load values from .txt file to variables in rainmeter

MrStiltskins » May 15th, 2017, 3:29 pm

Thanks it is working and I think that I was able to understand the changes you had made. The reason I had some of the code in there that was not helpful on the rainmeter side was to trouble shoot the actual lua script to make sure it was doing what I was wanting it to do. It is working now though.

Thanks again.

P.S.
If you wouldn't mind explaining in alittle more detail the steps you took to trouble shoot the application that would be most appreciated. :)
User avatar
balala
Rainmeter Sage
Posts: 8308
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Using lua to load values from .txt file to variables in rainmeter

balala » May 15th, 2017, 4:05 pm

MrStiltskins wrote:If you wouldn't mind explaining in alittle more detail the steps you took to trouble shoot the application that would be most appreciated. :)
First you have to know I moved the weather.txt file (which contains the data) into the @Resources folder. I did this because usually lately we prefer to have all this kind of resources, along with the image, sound, etc. files there.
Due to this, in the code of lua, I had to create a method to get the exact path of this file. This is done by the GetResources function:

Code: Select all

function GetResources()
	return tostring(SKIN:GetVariable('@'))
end
This function reads the value of the @ variable, which represents the path of the @Resources folder.
The next function (ReadFile) gets the path of the weather.txt file, concatenating the result of the GetResources function, with the name of the file itself: FileP = GetResources() .. 'weather.txt'. Having the exact path of the file, the next step is to open this file for read, with the io.open function and read its content. The for Line in File:lines() do command will do this read, storing the lines of the file into the contents array variable. This variable was created empty, into the local contents = {} line. Then the file is closed and as last step, the function returns the read value (the contents variable).
The Update function of the script, is executed on each update of the [luaScript] script measure, of the skin. When a such update is done, the read values are returned to the skin, by the three SKIN:Bang('!SetVariable',... lines. These returned values are used through the temp_f, feelslike_f and City variables, into the skin, which shows them.
I hope I succeeded explaining what the script does. If you have any further questions, please feel free to ask.