changes related to temperature and layout
[monky] / data / misc.lua
1 --
2 -- Conky Lua scripting example
3 --
4 -- Copyright (c) 2009 Brenden Matthews, all rights reserved.
5 --
6 -- This program is free software: you can redistribute it and/or modify
7 -- it under the terms of the GNU General Public License as published by
8 -- the Free Software Foundation, either version 3 of the License, or
9 -- (at your option) any later version.
10 --
11
12 function components_to_colour(r, g, b)
13         -- Take the RGB components r, g, b, and return an RGB integer
14         return ((math.floor(r + 0.5) * 0x10000) + (math.floor(g + 0.5) * 0x100) + math.floor(b + 0.5)) % 0xffffff -- no bit shifting operator in Lua afaik
15 end
16
17 function colour_to_components(colour)
18         -- Take the RGB components r, g, b, and return an RGB integer
19         return (colour / 0x10000) % 0x100, (colour / 0x100) % 0x100, colour % 0x100
20 end
21
22 function conky_top_colour(value, default_colour, lower_thresh, upper_thresh)
23         --[[
24         This function returns a colour based on a threshold, by adding more of
25         the red component and reducing the other components.  ``value'' is the
26         value we're checking the thresholds against, ``default_colour'' is the
27         original colour (before adjusting), and the ``lower_thresh'' and
28         ``upper_thresh'' parameters are the low and high values for which we
29         start applying redness.
30         ]]
31         local r, g, b = colour_to_components(default_colour)
32         local colour = 0
33         if value ~= nil and (value - lower_thresh) > 0 then
34                 if value > upper_thresh then value = upper_thresh end
35                 local perc = (value - lower_thresh) / (upper_thresh - lower_thresh)
36                 if perc > 1 then perc = 1 end
37                 -- add some redness, depending on where ``value'' lies within the
38                 -- threshhold range
39                 r = r + perc * (0xff - r)
40                 b = b - perc * b
41                 g = g - perc * g
42         end
43         colour = components_to_colour(r, g, b)
44         return string.format("${color #%06x}", colour)
45 end
46
47 -- parses the output from top and calls the colour function
48 function conky_top_cpu_colour(arg)
49         -- input is the top var number we want to use
50         local str1 = conky_parse(string.format('${top name %i}', tonumber(arg)))
51         local str2 = conky_parse(string.format('${top cpu %i}', tonumber(arg)))
52         local str3 = conky_parse(string.format('${top mem %i}', tonumber(arg)))
53         local cpu = tonumber(string.match(str2, '(%d+%.%d+)'))
54         return conky_top_colour(cpu, 0xd3d3d3, 25, 70) .. str1 .. '${goto 110}' .. str2 .. '${goto 160}' .. str3
55 end
56
57 function conky_top_mem_colour(arg)
58         -- input is the top var number we want to use
59         local str1 = conky_parse(string.format('${top_mem name %i}',  tonumber(arg)))
60         local str2 = conky_parse(string.format('${top_mem mem_res %i}', tonumber(arg)))
61         local str3 = conky_parse(string.format('${top_mem mem_vsize %i}', tonumber(arg)))
62         local mem = tonumber(string.match(str2, '(%d+%.?%d+)'))
63         -- tweak the last 3 parameters to your liking
64         -- my machine has ~8GiB of ram, so an upper thresh of 15% seemed appropriate
65         return conky_top_colour(mem, 0xd3d3d3, 64, 128) .. str1 .. '${goto 390}' .. str2 .. '${goto 440}' .. str3
66 end
67
68 function conky_top_io_colour(arg)
69         -- input is the top var number we want to use
70         local str = conky_parse(string.format('${top_io name %i}${top_io io_read %i} ${top_io io_write %i} ${top_io io_perc %i}', tonumber(arg), tonumber(arg), tonumber(arg), tonumber(arg)))
71         local ioR,ioW = string.match(str, '%w+%s+(%d+%.*%d*%w)%s+(%d+%.*%d*%w)%s+')
72         local tot = conky_parse("${to_bytes "..ioR.."}") + conky_parse("${to_bytes "..ioW.."}") --these can be bytes or mb :(
73         -- tweak the last 3 parameters to your liking
74         -- my machine has ~8GiB of ram, so an upper thresh of 15% seemed appropriate
75         str = string.gsub(str," 0B", " 0.00B")
76         return conky_top_colour(tot, 0xd3d3d3, 100, 200) .. str
77 end
78
79 function colour_transition(start, stop, position)
80         --[[
81         Transition from one colour to another based on the value of
82         ``position'', which should be a number between 0 and 1.
83         ]]
84         local rs, gs, bs = colour_to_components(start) -- start components
85         local re, ge, be = colour_to_components(stop) -- end components
86         local function tr(s, e, p)
87                 return e + (e - s) * p
88         end
89         local rr, gr, br = tr(rs, re, position), tr(gs, ge, position), tr(bs, be, position) -- result components
90         return components_to_colour(rr, gr, br)
91 end
92
93 function get_timezone_offset()
94         -- returns the number of seconds of timezone offset
95         local tz = tonumber(os.date('%z'))
96         local tzh = math.floor(tz / 100 + 0.5)
97         local tzm = math.abs(tz) % 100 / 60.
98         if tzh < 0 then tzm = -tzm end
99         return (tzh + tzm) * 3600
100 end
101
102 function julian_to_unix(J)
103         -- converts a julian date into unit time
104         return (J - 2440588) * 86400
105 end
106
107 function get_julian_now()
108         -- returns the current time in julian date format
109         local now = os.time()
110         return now / 86400. + 2440588
111 end
112
113 function calculate_sunrise_sunset(latitude, longitude)
114         --[[
115         This function returns the unix timestamps in the local time for sunrise and
116         sunset times, according to ``latitude'' and ``longitude''.  For the
117         latitude, north is positive and south is negative.  For the longitude, west
118         is negative, and east is positive.  You can usually determine the lat/long
119         for your location from Wikipedia or using some mapping tool.
120
121         In my case (Calgary, AB) the lat/long are 51.045 and -114.057222
122
123         Reference: http://en.wikipedia.org/wiki/Sunrise_equation
124         ]]
125
126         -- Negate longitude, west is positive and east is negative
127         longitude = -longitude
128
129         --  Calculate current Julian Cycle
130         local n = math.floor(get_julian_now() - 2451545 - 0.0009 - longitude / 360 + 0.5)
131
132         -- Approximate Solar Noon
133         local Js = 2451545 + 0.0009 + longitude / 360 + n
134
135         -- Solar Mean Anomaly
136         local M = (357.5291 + 0.98560028 * (Js - 2451545)) % 360
137
138         -- Equation of Center
139         local C = (1.9148 * math.deg(math.sin(math.rad(M)))) + (0.0200 * math.deg(math.sin(math.rad(2 * M)))) + (0.0003 * math.deg(math.sin(math.rad(3 * M))))
140
141         -- Ecliptic Longitude
142         local lam = (M + 102.9372 + C + 180) % 360
143
144         -- Solar Transit
145         local Jt = Js + (0.0053 * math.deg(math.sin(math.rad(M)))) - (0.0069 * math.deg(math.sin(math.rad(2 * lam))))
146
147         -- Declination of the Sun
148         local delta = math.deg(math.asin(math.sin(math.rad(lam)) * math.sin(math.rad(23.45))))
149
150         -- Hour Angle
151         local w = math.deg(math.acos((math.sin(math.rad(-0.83)) - math.sin(math.rad(delta)) * math.sin(math.rad(latitude))) / (math.cos(math.rad(latitude)) * math.cos(math.rad(delta)))))
152
153         local J_set = 2451545 + 0.0009 + ((w + longitude)/360 + n + (0.0053 * math.deg(math.sin(math.rad(M)))) - (0.0069 * math.deg(math.sin(math.rad(2 * lam)))))
154         local J_rise = Jt - (J_set - Jt)
155
156
157         local rising_t, setting_t = julian_to_unix(J_rise), julian_to_unix(J_set)
158
159         -- apply timezone offset
160         local tz_offset = get_timezone_offset()
161         rising_t = rising_t + tz_offset
162         setting_t = setting_t + tz_offset
163
164         return rising_t, setting_t
165 end
166
167 local last_sunrise_set_check = 0
168 local sunrise, sunset = 0
169
170 function conky_datey(latitude, longitude, change)
171         --[[
172         Returns a colour at or between day_sky and night_sky (see below) depending on the
173         time of day.  You must provide the ``latitude'' and ``longitude''
174         parameters for your location (see the comments for
175         calculate_sunrise_sunset() above for more info).  The ``change'' parameter
176         is the number of hours we want to start and have a transition, so a value
177         of 1 will mean the transition starts 30 minutes before, and ends 30 minutes
178         after.
179         ]]
180         local function to_hours(t)
181                 return tonumber(os.date('%k', t)) + (tonumber(os.date('%M', t)) / 60) + (tonumber(os.date('%S', t)) / 3600)
182         end
183         if last_sunrise_set_check < os.time() - 86400 then
184                 sunrise, sunset = calculate_sunrise_sunset(tonumber(latitude), tonumber(longitude))
185                 -- convert unix times into hours
186                 sunrise, sunset = to_hours(sunrise), to_hours(sunset)
187         end
188         local day_sky = 0x6698FF -- colour to use during daytime
189         local night_sky = 0x342D7E -- colour to use during nighttime
190         local hour = to_hours(os.time())
191         if hour > sunrise + change / 2 and hour < sunset - change / 2 then
192                 -- midday
193                 sky = day_sky
194         elseif hour > sunset + change / 2 or hour < sunrise - change / 2 then
195                 -- midnight
196                 sky = night_sky
197         elseif hour > sunset - change / 2 then
198                 -- sunset time
199                 sky = colour_transition(day_sky, night_sky, (hour - sunset - change / 2) / change)
200         elseif hour < sunrise + change / 2 then
201                 -- sunrise time
202                 sky = colour_transition(night_sky, day_sky, (hour - sunrise - change / 2) / change)
203         end
204         return string.format('${color #%6x}', sky)
205 end
206
207 require 'imlib2'
208