It is currently March 28th, 2024, 8:41 am

[Help] Help with Lua Scripting

Discuss the use of Lua in Script measures.
Post Reply
User avatar
eXAKR
Posts: 30
Joined: January 11th, 2012, 12:22 pm

[Help] Help with Lua Scripting

Post by eXAKR »

Posted this in the Rainmeter Reddit but am getting no response there, so I'm trying here...

I will cut to the chase: I'm currently writing a Rainmeter skin here that will measure the amount of network activity, using the Net measures. I'm intending the skin to just display a graph of the network usage (with the maximum arbitrarily set at 1 gigabit), and then display the exact amount in a tooltip when you hover over the entire skin (a background image). Problem is, the Net measures return the network usage value only in bytes, and Autoscale doesn't work on Image meters; I have resorted to attempting to use this piece of Lua code to do the scaling, but I'm no good with Lua (never tried it before in my own Rainmeter skins) and I have no idea how to make it work. In particular, I'm not sure how I can pass the value of the Net measure into the Lua script, and then have the tooltip display the returned result of the Lua script.

This is what my current Rainmeter code looks like:

Code: Select all

[Rainmeter]
 AccurateText=1

[MeasureNetIn]
 ; This measures the amount of incoming (receiving) network traffic, with MaxValue set at 1Gb as the maximum on the Y axis for the graph.
 ; Measurement is done across all network adapters on the system to give an overall value of incoming network traffic to the system as a whole,
 ; instead of focusing on any one specific or "best" network adapter.
 ; Hence, Interface is set to 0 for this purpose.
 Measure=NetIn
 Interface=0
 ; 1000000000 bits = 1 gigabit
 ; Rainmeter will always use bits instead of bytes for MaxValue, and internally recalculate the measure result to bytes automatically,
 ; regardless of how UseBits is set.
 MaxValue=1000000000
 
[NetInScaled]
 Measure=Script
 Script=#@#\AutoScale.lua
 NetValue=[MeasureNetIn]
 
[BG]
 ; This defines the size of the skin itself.
 ; The image used is defined in the variant skins themselves.
 Meter=Image
 ImageName=#@#\BG.png
 Tile=1
 W=200
 H=50
 TooltipText="Network activity (receiving): [NetInScaled]."
 DynamicVariables=1

[Label]
 ; This is the background text on the widget.
 Meter=STRING
 X=13
 Y=1
 FontColor=58,58,58
 FontFace=Segoe UI Light
 FontSize=25
 StringAlign=Left
 StringStyle=NORMAL
 AntiAlias=1
 DynamicVariables=1
 Text="Net (In)"

; The graph consists of two parts: a Line meter and a Histogram meter.
; The Line meter is used to visually display the peaks of the graphs, while the Histogram meter is used to "fill in" the graph beneath the Line meter.
[NetInGraphMax]
 Meter=Line
 MeasureName=MeasureNetIn
 X=0
 Y=0
 W=200
 H=50
 AntiAlias=1
 LineColor=255,255,255
 GraphStart=Right
 Autoscale=0
 DynamicVariables=1

[NetInGraph]
 Meter=Histogram
 MeasureName=MeasureNetIn
 X=0
 Y=0
 W=200
 H=50
 AntiAlias=1
 PrimaryColor=255,255,255, 48
 GraphStart=Right
 Autoscale=0
 DynamicVariables=1
And this is how my AutoScale.lua looks like right now:

Code: Select all

function Update()
	iNetUnScaled = SELF:GetValue('NetValue')
	NetScaled = AutoScale(iNetUnscaled, 2)
	return NetScaled
end

function AutoScale(num, idp)
	assert(tonumber(num), 'AutoScale expects a number.')
	local scales = {'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'}
	local places = idp or 0
	local scale = ""
	local scaled = 0

	for i, v in ipairs(scales) do
		if (num < (1024 ^ i)) or (i == #scales) then
			scale = v
			scaled = Round(num / 1024 ^ (i - 1), places)
			break
		end
	end

	return scaled, scale
end

function Round(num, idp)
	assert(tonumber(num), 'Round expects a number.')
	local mult = 10 ^ (idp or 0)
	if num >= 0 then
		return math.floor(num * mult + 0.5) / mult
	else
		return math.ceil(num * mult - 0.5) / mult
	end
end
Again, I'm new to Lua scripting with Rainmeter, and I have not much idea how much of this works; the documentation I'm seeing has been confusing to me as well, and I am struggling to make heads or tails of it. Any help/explanation on what I'm doing wrong and what I should do would be deeply appreciated, as I want to use this as a learning opportunity as well.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2588
Joined: March 23rd, 2015, 5:26 pm
Contact:

Re: [Help] Help with Lua Scripting

Post by SilverAzide »

eXAKR wrote: August 28th, 2020, 6:17 pm
Since no one has responded to your question yet, I will chime in here.

None of what you are doing with Lua is needed, as far as I can tell. First, the NetIn/NetOut/NetTotal measures report in bytes by default, but by setting UseBits=1, you can get the value in bits. Alternatvely, you can simply create a Calc measure to multiply the result of the [MeasureNetIn] measure by 8 and do the same thing, but the UseBits option is way simpler.

Secondly, you seem to be wanting to autoscale the graph, but you have the meters AutoScale options turned off and you are trying to autoscale with code. This doesn't really make a whole lot of sense. Simply set AutoScale=1 on both the Line meter and Histogram meters and you are done, no Lua needed.

If you want your tooltips to autoscale so values are shown in KB/MB/etc, that's easily done by setting the AutoScale option on the string meter that shows the tooltip. Leave the data alone, and autoscale only the text you want to display.

Some extra info you didn't ask for:
If you use Interface=0 on your Net measures, you are not going to get accurate results. The reason is that this option reports the sum total of all network activity on ALL network interfaces including virtual network adapters. Windows almost always has virtual adapters active, and if you use a VPN, virtual machines, certain AV software, etc., you may have many of them and all may be active. The result is the amount of data reported by the measure can be 2, 3, 4 or more times the actual value. Instead of using Interface=0, use Interface=Best (along with DynamicVariables=1, which is required when using "Best"). This will report the activity of the single "best" active network interface (usually your Ethernet or WiFi adapter).
User avatar
eXAKR
Posts: 30
Joined: January 11th, 2012, 12:22 pm

Re: [Help] Help with Lua Scripting

Post by eXAKR »

Aha. Thanks for providing me a simpler alternative to what was an over-engineered solution for my problem, as well as your tips. Decided to try your suggestions and things are working fine here now.

Thanks a lot!
Post Reply