Skip to content

Using Lua scripts (Part 07): Alarm colors and complex if statements

lasers edited this page Jan 4, 2019 · 3 revisions

vii: Alarm colors and complex if statements

we were jazzing up our bar meter we added an optional border as feature 1 and we are going to have the bar change color for feature 2

To get the color change we I'll need to add a few more settings! most likely if you are going to set an alarm color, you'll think of red (as i did) so we would have to re-color our background bar also (which is also currently red) I'm feeling a little lazy so im going to go for some shorter string names, particularly for all the reds green blue and alphas coming up :)

--set alarm value, this is the value at which bar color will change
alarm_value=80
--set alarm bar color, 1,0,0,1 = red fully opaque
ar,ag,ab,aa=1,0,0,1

we already have a base bar color so we want the bar to be our base color unless the cpu% reading equals or goes above 80%

we are going to be using another IF to get the colors to change as with most code, there are multiple ways we could go about doing things lets first remind ourselves of the code that is drawing the indicator part of the bar it is that part that we will be editing as it is that part which will change color

cairo_set_source_rgba (cr,bar_in_red,bar_in_green,bar_in_blue,bar_in_alpha)--set indicator color
scale=bar_height/bar_max_value
indicator_height=scale*bar_value
cairo_rectangle (cr,bar_bottom_left_x,bar_bottom_left_y,bar_width,-indicator_height)
cairo_fill (cr)

to apply our if statement to colors we could do the following: remember, bar_value is the name of the string holds the value of cpu% and we set alarm_value above to 80

if bar_value<alarm_value then
    cairo_set_source_rgba (cr,bar_in_red,bar_in_green,bar_in_blue,bar_in_alpha)
else
    cairo_set_source_rgba (cr,ar,ag,ab,aa)
end

hopefully it should be quite self explanatory what is going on in the above code :D if the string named bar_value has a value of less than 80 then the color is set to the base indicator color (which we have set to white in settings) -all code between then and else is done if the value of bar_value is not less than 80 (ie equal to or greater than 80) then color is set to the alarm color -all the code between then and else is skipped and everything between else and end is done

this would have also worked

if bar_value>=80 then
    cairo_set_source_rgba (cr,ar,ag,ab,aa)
else
    cairo_set_source_rgba (cr,bar_in_red,bar_in_green,bar_in_blue,bar_in_alpha)
end

How do we know its working? We think that we have our code right and we expect that if our cpu% gets to 80% or more that our bar color will change from white to red but its always a good idea to check that things are working the way we expect.

We could do something on the computer that would drive the actual CPU% reading up to 80 or above but there is an easier way in our settings we have the line that sets the value of bar_value bar_value=tonumber(conky_parse("${cpu}"))

just edit that line and "hard code" bar_value to a test value like this bar_value=80--tonumber(conky_parse("${cpu}"))

I don't like to completely replace the line with our test value as it simply harder to reinstate the line afterwards with the test value in place and the rest of the line commented out, once we are sure our feature is working we just delete the test value and the comments and everything is back to being operational

now we like the color change, and we want to implement another color change we want the bar to be one color when cpu% is low, say green up to 50% then we want the color to change to a different color, yellow for example, between 50% and 80% then if our reading gets to 80 or over it goes to red

so back to the settings we already have our alarm (or high cpu usage) value and color

--set value for first color change, low cpu usage to mid cpu usage
mid_value=50
--set "low" cpu usage color and alpha, ie bar color below 50% - 0,1,0,1=fully opaque green
lr,lg,lb,la=0,1,0,1
--set "mid" cpu usage color, between 50 and 79 - 1,1,0,1=fully opaque yellow
mr,mg,mb,ma=1,1,0,1

while we could reuse our base bar color settings, and just change the numbers to green or yellow

bar_in_red=1
bar_in_green=1
bar_in_blue=1
bar_in_alpha=1

since we are making some significant changes to how our colors are working i would just go ahead and delete them and replace them with the new low mid and alarm values I tend to like to stick to a single naming convention also which helps me to remember what i have named strings (and maybe because of some mild OCD)) but again, that's just me, you can call your string whatever you want to!

so now we need to think about how to set up our if statement when CPU is between 0 and 49 we want green when CPU is between 50 and 79 we want yellow and when CPU is 80 or above we want red

so lets put them into a statement

if bar_value>=mid_value then --ie if value is greater or equal to 50
    cairo_set_source_rgba (cr,mr,mg,mb,ma)--yellow (mid color)
elseif bar_value>=alarm_value then --ie if bar_value is greater or equal to 80
    cairo_set_source_rgba (cr,ar,ag,ab,aa)--red (alarm color)
else
    cairo_set_source_rgba (cr,lr,lg,lb,la)--green (low color)
end

we use an elseif, because it is no longer an either or situation, there are 3 possibilities we need to sort out

test the setup by setting bar_value to some test value we set bar_value=49 and we get a green bar, and it is green for any number below 50 we set bar_value=50 and we get a yellow bar then try bar_value=80 and the bar is still yellow! and it is yellow all the way up to 100

Our statement seems entirely logical, but this is one of the pitfalls you can get stuck in to understand it we need to think about how our if statement works and we can see that the problem is in the order of our comparisons

if bar_value>=mid_value then --ie if value is greater or equal to 50
    cairo_set_source_rgba (cr,mr,mg,mb,ma)--yellow (mid color)

This first line does indeed match any number from 50 to 100 and so any cpu value from 50 to 100 will result in a yellow bar.

The script comes to the line, takes the value of bar_value calculates if it is greater or equal to the value of mid_value if it passes the comparison, the script runs the corresponding code and then its done with the if statement

only if bar_value is less than 50 then the first comparison will fail and the script will move on to the next comparison but of course this comparison will fail also as if a value is not greater or equal to 50 then it wont be greater or equal to 80

once past the if and the following elseif the script automatically runs the code following else which doesn't require a comparison again there are plenty of ways we can fix this we can try and reorder our comparisons like so

if bar_value>=alarm_value then --ie if value is greater or equal to 80
    cairo_set_source_rgba (cr,ar,ag,ab,aa)--red (alarm color)
elseif bar_value>=mid_value then --ie if bar_value is greater or equal to 50
    cairo_set_source_rgba (cr,mr,mg,mb,ma)--yellow (mid color)
else
    cairo_set_source_rgba (cr,lr,lg,lb,la)--green (low color)
end

take a value of say 90 check 1) is 90 greater or equal to 80? yes -> pass the first comparison and run the code to set color to red done!

set a value of 60 check 1) is 60 greater or equal to 80? no -> fail the first comparison, move onto the next check 2) is 60 greater or equal to 50? yes -> pass the second comparison and run the code to set color to yellow done!

set a value of 48 check 1) is 48 greater or equal to 80? no -> fail the first comparison, move onto the next check 2) is 48 greater or equal to 50? no -> fail the second comparison, move onto the next no more checks, run code following else and set color to green done!

Clone this wiki locally