You are not logged in.
So i've added weather to my conky display using wttr.in: https://github.com/chubin/wttr.in
Super cool service, only had to install curl for it to work. It will display full info in terminal, but i'm using it with conky and don't need all the details it gives in terminal. It can be a bit tricky to get it to work for your area, it tries by default to do it based on your IP, which wouldn't work quite right for my location so it defaulted to some other area. Play around with it by running in terminal:
curl wttr.in/(add your city, county or lat/long)
You can add a location to the command, in my case again my city is too small and remote for it, but it did recognize me when I typed in my county name, which is great because my county is very small and weather is consistent across it. You can also do it by latitude/longitude.
I set mine to update every 20 minutes, but will probably change to every 30 minutes, the less calls the better as it will freak out on you for too many calls.
You will likely need to use your system's fixed width font to get the arrows in the wind output to work, mine is Monospace Regular:
${voffset -7}${font Monospace Regular:pixelsize=12}${alignc}
Here's the code I used to stack some simple results in my conky:
${execi 1800 curl wttr.in/(enter your city or county or latitude-longitude here, no parentheses)?format="Condition:+%C\n""Temperature:+%t\n""Wind+chill:+%f\n""Humidity:+%h\n""Pressure:+%P\n""Wind:+%w\n""Precipitation:+%p\n"}
And this is the result (ignore the Exaile output below it, lol):
You can add or subtract as you see fit, here is a list of the params you can call up:
To specify your own custom output format, use the special %-notation:
c Weather condition,
C Weather condition textual name,
x Weather condition, plain-text symbol,
h Humidity,
t Temperature (Actual),
f Temperature (Feels Like),
w Wind,
l Location,
m Moon phase 🌑🌒🌓🌔🌕🌖🌗🌘,
M Moon day,
p Precipitation (mm/3 hours),
P Pressure (hPa),
u UV index (1-12),
D Dawn*,
S Sunrise*,
z Zenith*,
s Sunset*,
d Dusk*,
T Current time*,
Z Local timezone.
(*times are shown in the local timezone)
That's it, works great, simple small solution, just how I like 'em!
Last edited by greenjeans (2023-12-06 01:53:50)
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
Redundant post, issue solved, conserving site resources.
Last edited by greenjeans (2023-12-06 01:46:51)
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
I use weather-util to get the weather and dump it in a file. Then I let conky pick lines from the file.
wrapper script: (get-weather)
#!/usr/bin/env bash
if [ -n "$1" ] ; then
station="$1"
else
station="klax"
fi
weather -v "$station"
~/.conkyrc lines
{color}${execi 1800 /home/fred/bin/get-weather > .current_weather} ${execi 1800 awk '/Temperature/ { print $0 }' .current_weather } ${execi 1800 awk '/Humidity/ { print $0 }' .current_weather}
or
${color}${execi 1800 /home/fred/bin/get-weather.sh > .current_weather} ${color}${execi 1800 cat .current_weather | grep -E "United|Wind|Sky|Temperature|Dew|Humidity|Pressure"}
Hmm... that first one isn't working right for me. Something wrong with my alighment or width. Play with the output if you want. I'm using the second one.
If you want to see the whole .conkyrc, I'll show you, but I think you can find multiple examples somewhere on this forum. I'm sure there have been some discussions.
Offline
I think that perhaps I should add my set of Conky to my GitHib repository. Anyway, here is the first of a bunch of scripts:
conky.config = {
-- ~/.conky/conkyrc
-- Conky settings #
background = false,
update_interval = 1,
cpu_avg_samples = 4,
net_avg_samples = 2,
override_utf8_locale = true,
double_buffer = true,
no_buffers = true,
text_buffer_size = 2048,
--imlib_cache_size 0
temperature_unit = 'fahrenheit',
-- Window specifications #
own_window = true,
-- If own_window is yes, you may use type normal, desktop or override
-- 2015-12-10 commented-out settings below are ordinarily fine
-- current SLiM+xfce4 4.8 require desktop + own_window_argb_visual + _value
-- xfce require compositing ON ((menu):Settings→Windows Manager Tweaks)
-- else not transparent or SLiM background shows under
-- own_window_type normal
own_window_type = 'desktop',
-- own_window_transparent yes
own_window_argb_visual = true,
own_window_argb_value = 0,
own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
own_window_hints = 'below',
border_inner_margin = 0,
border_outer_margin = 0,
minimum_width = 200, minimum_height = 250,--# width, height
maximum_width = 200,
--## top_left, top_right, top_middle, bottom_left, bottom_right, bottom_middle
--## middle_left, middle_middle, middle_right, or none
alignment = 'top_right',
gap_x = 20,
gap_y = 20,
-- Graphics settings #
draw_shades = false,
draw_outline = false,
draw_borders = false,
draw_graph_borders = false,
-- Text settings #
use_xft = true,
font = 'ubuntu:size=8',
xftalpha = 0.5,
uppercase = false,
temperature_unit = 'celsius',
default_color = '#FFFFFF',
-- Lua Load #
-- Note: clock + gauges are hard-coded graphics in clock_rings.lua
-- whilst text is within this file (thus possible disjunction)
-- cpu cpu1 : x=50, y=300, radius=25
-- cpu cpu2 : x=50, y=300, radius=20
-- memperc : x=75, y=350, radius=25
-- swapperc : x=100, y=400, radius=25
-- fs_used_perc: x=125, y=450, radius=25
-- downspeedf : x=150, y=500, radius=25
-- upspeedf : x=150, y=500, radius=20
lua_load = '~/.lua/scripts/clock_rings.lua',
lua_draw_hook_pre = 'clock_rings',
};
conky.text = [[
${voffset 8}${color 9f440d}${font ubuntu:size=16}${time %A}${font}${voffset -8}${alignr}${color FFFFFF}${font ubuntu:size=38}${time %e}${font}
${color FFFFFF}${voffset -30}${color FFFFFF}${font ubuntu:size=18}${time %b}${font}${voffset -3} ${color FFFFFF}${font ubuntu:size=20}${time %Y}${font}${color 9f440d}${hr}
# ${voffset 140}${font ubuntu:size=10}${alignr}HOME${font}
${voffset 150}${font ubuntu:size=10}${alignr}East Midlands Airport:${font}
# local weather in minutes
# EGNX = East Midlands
# EGXW = Waddington
# see http://www.aviationweather.gov/metar?zoom=8&lat=53.24716&lon=-1.11957&layers=B00FTTFFTFFTT&plottype=model&scale=1&density=all&metric=true&decoded=false&taf=true
# or see http://weather.noaa.gov/weather/GB_cc.html
${font ubuntu:size=12}${color FFFFFF}
# 2016-08-03 http://weather.noaa.gov/pub/data/observations/metar/stations/ withdrawn; now gives 404
# 2018-05-13 http://tgftp.nws.noaa.gov/data/observations/metar/stations/ works
# 2021-09-28 http://tgftp.nws.noaa.gov/data/observations/metar/stations/ fails after update to chimaera
# 2023-10-16 https://www.aviationweather.gov/metar/ fails after site update
${alignr}${execi 300 /home/alexk/.conky/weather.pl EGNX TEMP_C } °C${font}${font ubuntu:size=8}
${alignr}${execi 300 /home/alexk/.conky/weather.pl EGNX TIME }:
# 2021-09-28 original gave mysterious continuous 'ARRAY' result with SKY, now ok ???
${alignr}Sky: ${execi 300 /home/alexk/.conky/weather.pl EGNX SKY }
${alignr}RH: ${execi 300 /home/alexk/.conky/weather.pl EGNX RH }%
${alignr}Vis: ${execi 300 /home/alexk/.conky/weather.pl EGNX VISIBILITY }
${alignr}${execi 300 /home/alexk/.conky/weather.pl EGNX ALT_HP } mBar
${alignr}Wind: ${execi 300 /home/alexk/.conky/weather.pl EGNX WIND_KTS } knots
${alignr}${execi 300 /home/alexk/.conky/weather.pl EGNX WIND_DIR_ENG }
${alignr}${execi 300 /home/alexk/.conky/weather.pl EGNX WIND_DIR_DEG } °
#
# 2021-09-28 below replaced by above due to 'TODO..' response:
# ${alignr}${weather http://tgftp.nws.noaa.gov/data/observations/metar/stations/ EGNX temperature 30} °C${font}${font ubuntu:size=8}
# ${alignr}${weather http://tgftp.nws.noaa.gov/data/observations/metar/stations/ EGNX cloud_cover 30}
# ${alignr}RH: ${weather http://tgftp.nws.noaa.gov/data/observations/metar/stations/ EGNX humidity 30}%
# ${alignr}${weather http://tgftp.nws.noaa.gov/data/observations/metar/stations/ EGNX pressure 30} mBar
# ${alignr}Direction: ${weather http://tgftp.nws.noaa.gov/data/observations/metar/stations/ EGNX wind_dir 30}
# ${alignr}${weather http://tgftp.nws.noaa.gov/data/observations/metar/stations/ EGNX weather 30}${font}
#
# ${image ~/.conky/avlinux.png -p 58,115 -s 85x48}
#
# ${color FFFFFF}${goto 25}${voffset 35}${cpu cpu0}%
${color FFFFFF}${goto 25}${voffset -58}${cpu cpu0}%
${color 9f440d}${goto 25}CPU
${color FFFFFF}${goto 50}${voffset 23}${memperc}%
${color 9f440d}${goto 50}RAM
${color FFFFFF}${goto 75}${voffset 23}${swapperc}%
${color 9f440d}${goto 75}Swap
${color FFFFFF}${goto 100}${voffset 23}${fs_used_perc /}%
${color 9f440d}${goto 100}Disk
${color FFFFFF}${goto 125}${voffset 25}${downspeed eth0}
${color FFFFFF}${goto 125}${upspeed eth0}
${color 9f440d}${goto 125}Net
${color FFFFFF}${font ubuntu:size=8}Uptime: ${uptime_short}
${color FFFFFF}${font ubuntu:size=8}Processes: ${processes}
${color FFFFFF}${font ubuntu:size=8}Running: ${running_processes}
${color 9f440d}${font ubuntu:size=8}${nodename}
# ${pre_exec} has been removed in v1.10.6 conky used in devuan ascii
${execi 65000 lsb_release -ds} $machine
Kernel: ${kernel}
]];
...and here are the clock-rings:
~/.lua/scripts/clock_rings.lua:
--[[
~/.lua/scripts/clock_rings.lua
Clock Rings by Linux Mint (2011) reEdited by despot77
This script draws percentage meters as rings, and also draws clock hands if you want! It is fully customisable; all options are described in the script. This script is based off a combination of my clock.lua script and my rings.lua script.
IMPORTANT: if you are using the 'cpu' function, it will cause a segmentation fault if it tries to draw a ring straight away. The if statement on line 145 uses a delay to make sure that this doesn't happen. It calculates the length of the delay by the number of updates since Conky started. Generally, a value of 5s is long enough, so if you update Conky every 1s, use update_num>5 in that if statement (the default). If you only update Conky every 2s, you should change it to update_num>3; conversely if you update Conky every 0.5s, you should use update_num>10. ALSO, if you change your Conky, is it best to use "killall conky; conky" to update it, otherwise the update_num will not be reset and you will get an error.
To call this script in Conky, use the following (assuming that you save this script to ~/scripts/rings.lua):
lua_load ~/scripts/clock_rings.lua
lua_draw_hook_pre clock_rings
Changelog:
+ v1.0 -- Original release (30.09.2009)
v1.1p -- Jpope edit londonali1010 (05.10.2009)
*v 2011mint -- reEdit despot77 (18.02.2011)
]]
settings_table = {
{
-- Edit this table to customise your rings.
-- You can create more rings simply by adding more elements to settings_table.
-- "name" is the type of stat to display; you can choose from 'cpu', 'memperc', 'fs_used_perc', 'battery_used_perc'.
name='time',
-- "arg" is the argument to the stat type, e.g. if in Conky you would write ${cpu cpu0}, 'cpu0' would be the argument. If you would not use an argument in the Conky variable, use ''.
arg='%I.%M',
-- "max" is the maximum value of the ring. If the Conky variable outputs a percentage, use 100.
max=12,
-- "bg_colour" is the colour of the base ring.
bg_colour=0xffffff,
-- "bg_alpha" is the alpha value of the base ring.
bg_alpha=0.1,
-- "fg_colour" is the colour of the indicator part of the ring.
fg_colour=0x0D151D,
-- "fg_alpha" is the alpha value of the indicator part of the ring.
fg_alpha=0.2,
-- "x" and "y" are the x and y coordinates of the centre of the ring, relative to the top left corner of the Conky window.
x=100, y=150,
-- "radius" is the radius of the ring.
radius=50,
-- "thickness" is the thickness of the ring, centred around the radius.
thickness=5,
-- "start_angle" is the starting angle of the ring, in degrees, clockwise from top. Value can be either positive or negative.
start_angle=0,
-- "end_angle" is the ending angle of the ring, in degrees, clockwise from top. Value can be either positive or negative, but must be larger than start_angle.
end_angle=360
},
{
name='time',
arg='%M.%S',
max=60,
bg_colour=0xffffff,
bg_alpha=0.1,
fg_colour=0x0D151D,
fg_alpha=0.4,
x=100, y=150,
radius=56,
thickness=5,
start_angle=0,
end_angle=360
},
{
name='time',
arg='%S',
max=60,
bg_colour=0xffffff,
bg_alpha=0.1,
fg_colour=0x0D151D,
fg_alpha=0.6,
x=100, y=150,
radius=62,
thickness=5,
start_angle=0,
end_angle=360
},
{
name='time',
arg='%d',
max=31,
bg_colour=0xffffff,
bg_alpha=0.1,
fg_colour=0x0D151D,
fg_alpha=0.8,
x=100, y=150,
radius=70,
thickness=5,
start_angle=-90,
end_angle=90
},
{
name='time',
arg='%m',
max=12,
bg_colour=0xffffff,
bg_alpha=0.1,
fg_colour=0x0D151D,
fg_alpha=1,
x=100, y=150,
radius=76,
thickness=5,
start_angle=-90,
end_angle=90
},
{
name='cpu',
arg='cpu1',
max=100,
bg_colour=0xffffff,
bg_alpha=0.2,
fg_colour=0x0D151D,
fg_alpha=0.8,
x=50, y=300,
radius=25,
thickness=4,
start_angle=-90,
end_angle=180
},
{
name='cpu',
arg='cpu2',
max=100,
bg_colour=0xffffff,
bg_alpha=0.2,
fg_colour=0x0D151D,
fg_alpha=0.8,
x=50, y=300,
radius=20,
thickness=4,
start_angle=-90,
end_angle=180
},
{
name='memperc',
arg='',
max=100,
bg_colour=0xffffff,
bg_alpha=0.2,
fg_colour=0x0D151D,
fg_alpha=0.8,
x=75, y=350,
radius=25,
thickness=5,
start_angle=-90,
end_angle=180
},
{
name='swapperc',
arg='',
max=100,
bg_colour=0xffffff,
bg_alpha=0.2,
fg_colour=0x0D151D,
fg_alpha=0.8,
x=100, y=400,
radius=25,
thickness=5,
start_angle=-90,
end_angle=180
},
{
name='fs_used_perc',
arg='/',
max=100,
bg_colour=0xffffff,
bg_alpha=0.2,
fg_colour=0x0D151D,
fg_alpha=0.8,
x=125, y=450,
radius=25,
thickness=5,
start_angle=-90,
end_angle=180
},
{
name='downspeedf',
arg='eth0',
max=100,
bg_colour=0xffffff,
bg_alpha=0.2,
fg_colour=0x0D151D,
fg_alpha=0.8,
x=150, y=500,
radius=25,
thickness=4,
start_angle=-90,
end_angle=180
},
{
name='upspeedf',
arg='eth0',
max=100,
bg_colour=0xffffff,
bg_alpha=0.2,
fg_colour=0xff3300,
fg_alpha=0.8,
x=150, y=500,
radius=20,
thickness=4,
start_angle=-90,
end_angle=180
},
}
-- Use these settings to define the origin and extent of your clock.
clock_r=65
-- "clock_x" and "clock_y" are the coordinates of the centre of the clock, in pixels, from the top left of the Conky window.
clock_x=100
clock_y=150
show_seconds=true
require 'cairo'
function rgb_to_r_g_b(colour,alpha)
return ((colour / 0x10000) % 0x100) / 255., ((colour / 0x100) % 0x100) / 255., (colour % 0x100) / 255., alpha
end
function draw_ring(cr,t,pt)
local w,h=conky_window.width,conky_window.height
local xc,yc,ring_r,ring_w,sa,ea=pt['x'],pt['y'],pt['radius'],pt['thickness'],pt['start_angle'],pt['end_angle']
local bgc, bga, fgc, fga=pt['bg_colour'], pt['bg_alpha'], pt['fg_colour'], pt['fg_alpha']
local angle_0=sa*(2*math.pi/360)-math.pi/2
local angle_f=ea*(2*math.pi/360)-math.pi/2
local t_arc=t*(angle_f-angle_0)
-- Draw background ring
cairo_arc(cr,xc,yc,ring_r,angle_0,angle_f)
cairo_set_source_rgba(cr,rgb_to_r_g_b(bgc,bga))
cairo_set_line_width(cr,ring_w)
cairo_stroke(cr)
-- Draw indicator ring
cairo_arc(cr,xc,yc,ring_r,angle_0,angle_0+t_arc)
cairo_set_source_rgba(cr,rgb_to_r_g_b(fgc,fga))
cairo_stroke(cr)
end
function draw_clock_hands(cr,xc,yc)
local secs,mins,hours,secs_arc,mins_arc,hours_arc
local xh,yh,xm,ym,xs,ys
secs=os.date("%S")
mins=os.date("%M")
hours=os.date("%I")
secs_arc=(2*math.pi/60)*secs
mins_arc=(2*math.pi/60)*mins+secs_arc/60
hours_arc=(2*math.pi/12)*hours+mins_arc/12
-- Draw hour hand
xh=xc+0.7*clock_r*math.sin(hours_arc)
yh=yc-0.7*clock_r*math.cos(hours_arc)
cairo_move_to(cr,xc,yc)
cairo_line_to(cr,xh,yh)
cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND)
cairo_set_line_width(cr,5)
cairo_set_source_rgba(cr,1.0,1.0,1.0,1.0)
cairo_stroke(cr)
-- Draw minute hand
xm=xc+clock_r*math.sin(mins_arc)
ym=yc-clock_r*math.cos(mins_arc)
cairo_move_to(cr,xc,yc)
cairo_line_to(cr,xm,ym)
cairo_set_line_width(cr,3)
cairo_stroke(cr)
-- Draw seconds hand
if show_seconds then
xs=xc+clock_r*math.sin(secs_arc)
ys=yc-clock_r*math.cos(secs_arc)
cairo_move_to(cr,xc,yc)
cairo_line_to(cr,xs,ys)
cairo_set_line_width(cr,1)
cairo_stroke(cr)
end
end
function conky_clock_rings()
local function setup_rings(cr,pt)
local str=''
local value=0
str=string.format('${%s %s}',pt['name'],pt['arg'])
str=conky_parse(str)
value=tonumber(str)
pct=value/pt['max']
draw_ring(cr,pct,pt)
end
-- Check that Conky has been running for at least 5s
if conky_window==nil then return end
local cs=cairo_xlib_surface_create(conky_window.display,conky_window.drawable,conky_window.visual, conky_window.width,conky_window.height)
local cr=cairo_create(cs)
local updates=conky_parse('${updates}')
update_num=tonumber(updates)
if update_num>5 then
for i in pairs(settings_table) do
setup_rings(cr,settings_table[i])
end
end
draw_clock_hands(cr,clock_x,clock_y)
end
Last edited by alexkemp (2023-12-03 22:35:14)
Offline
This is a barometer:
~/.conky/conkyrc.weather:
conky.config = {
-- .conky/conkyrc.weather
-- draw barometer
-- Conky settings #
background = false,
update_interval = 1,
cpu_avg_samples = 2,
net_avg_samples = 2,
override_utf8_locale = true,
double_buffer = true,
no_buffers = true,
text_buffer_size = 2048,
--imlib_cache_size 0
temperature_unit = 'fahrenheit',
-- Window specifications #
own_window = true,
-- If own_window is yes, you may use type normal, desktop or override
-- 2015-12-10 commented-out settings below are ordinarily fine
-- current SLiM+xfce4 4.8 require desktop + own_window_argb_visual + _value
-- xfce require compositing ON ((menu):Settings→Windows Manager Tweaks)
-- else not transparent or SLiM background shows under
-- own_window_type normal
own_window_type = 'normal',
-- own_window_transparent yes
own_window_argb_visual = true,
own_window_argb_value = 0,
own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
border_inner_margin = 6,
border_outer_margin = 3,
minimum_width = 250, minimum_height = 250,--# width, height
maximum_width = 250,
--## top_left, top_right, top_middle, bottom_left, bottom_right, bottom_middle
--## middle_left, middle_middle, middle_right, or none
alignment = 'bottom_left',
gap_x = 0,
gap_y = 30,
-- Graphics settings #
draw_shades = false,
draw_outline = false,
draw_borders = false,
draw_graph_borders = false,
-- Text settings #
use_xft = true,
font = 'ubuntu:size=8',
xftalpha = 0.5,
uppercase = false,
temperature_unit = 'celsius',
default_color = '#FFFFFF',
-- Lua Load #
lua_load = '~/.lua/scripts/weather.lua',
lua_draw_hook_pre = 'conky_draw_test',
};
conky.text = [[
# No TEXT in weather config #
]];
...and here the actual draw-barometer script:
~/.lua/scripts/weather.lua:
--[[ ~/.lua/scripts/weather.lua
analogue barometer
2020-11-17 v 1.1 added CSV export for graphs
2015-06-21 v 1.0 edited by Alex Kemp
2011-05-27 original from Tim CowChip @ http://forum.salixos.org/viewtopic.php?p=26545
A good Conky/Lua HowTo:-
http://crunchbang.org/forums/viewtopic.php?id=17246
]]
require 'cairo'
require 'imlib2'
static=0 --value for barometer static pointer
old_pressure=0 --value to trip csv updates
update=nil
--[[ barometer()
Display an analogue barometer
@param cr cairo resource
@param pr pressure (mBar or inches Mercury)
@param px x centre-position, pixels
@param py y centre-position, pixels
@return (none)
]]
function barometer(cr,pr,px,py)
--setup table; change barometer appearance
--htm2col(col,alpha) available for html colour conversion
local st={
ctCOL ={htm2col(0x68441b,1)}, --circle txt colour
ctFNT ="URW Chancery L", --circle txt font name
ctSize =20, --circle txt font size
ctSLNT =CAIRO_FONT_SLANT_ITALIC, --circle txt font slant
ctChang="Change", --circle txt 'CHANGE' text
ctFair ="Fair", --circle txt 'FAIR' text
ctRain ="Rain", --circle txt 'RAIN' text
ctStorm="Stormy", --circle txt 'STORM' text
ctVDry ="Very Dry", --circle txt 'V DRY' text
ctWT =CAIRO_FONT_WEIGHT_BOLD, --circle txt font weight
lw =5, --outer line-width (added to ro)
ro =100, --radius to outer rim
bkCOL ={htm2col(0xf5f5f5,1)}, --background colour
roCOL ={htm2col(0x31200d,1)}, --outer rim colour
pbCOL ={0,0,0,0}, --ptr back colour
pfCOL ={1,0,0,1}, --ptr fore colour
ppCOL ={0,0,0,1}, --ptr pivot colour
psCOL ={htm2col(0x68441b,1)}, --ptr static colour
--psCOL ={htm2col(0xcdc674,1)}, --ptr static colour
text ="Pressure", --text text
txCOL ={0,0,0,1}, --text colour
}
--[[ barometer 27 inches to 32 inches = 5 inches
940 Mbar to 1060 millibar
'ro*<some-number:0,1>' appears regularly below
all calcs are based on original radius=100px
they allow the barometer to be re-sized (within limits)
eg 'ro*0.75'==a ring at 75 pixels based on orig 100px radius
circle-text: 87px
pointer: 7px inner, 75px outer
Pressure txt: 90px
text : rad outer : radius inner
inch scale: 77px : 75,70,68px : 65px
mbar scale: 37px : 60px : 55,50px
line basics: cairo_set_line_cap(cr,CAIRO_LINE_CAP_BUTT) default
cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND)
cairo_set_line_cap(cr,CAIRO_LINE_CAP_SQUARE)
arc basics: cairo_arc(cr,centre_x,centre_y,radius,start_angle,end_angle)
angles are in radians
centre + radius are in pixels
radians=degrees*(math.pi/180)
0 radians = East (RHS)
= 2*math.pi (360 degrees)
]]
--draw outer rim; fill + stroke
local lw =st.lw or 1 -- line-width of outer rim
local ro =st.ro or 100 -- radius of outer rim
local r =st.bkCOL[1] or 0.1 -- red component of background colour
local g =st.bkCOL[2] or 0.1 -- green component of background colour
local b =st.bkCOL[3] or 0.1 -- blue component of background colour
local a =st.bkCOL[4] or 1 -- alpha component of background colour
local ARC=2*math.pi -- 360 degrees
local D2R=math.pi/180 -- degrees to radians conversion ratio
cairo_set_line_width(cr,lw)
cairo_set_source_rgba(cr,r,g,b,a)
cairo_arc(cr,px,py,ro+lw,0,ARC)
cairo_fill (cr)
local r =st.roCOL[1] or 1 -- red component of outer rim colour
local g =st.roCOL[2] or 1 -- green component of outer rim colour
local b =st.roCOL[3] or 1 -- blue component of outer rim colour
local a =st.roCOL[4] or 1 -- alpha component of outer rim colour
cairo_set_source_rgba(cr,r,g,b,a)
cairo_arc(cr,px,py,ro+lw,0,ARC)
cairo_stroke(cr)
--draw inch + mbar scales
local r =st.txCOL[1] or 1 -- red component of text colour
local g =st.txCOL[2] or 1 -- green component of text colour
local b =st.txCOL[3] or 1 -- blue component of text colour
local a =st.txCOL[4] or 1 -- alpha component of text colour
--draw inch scale; rout==outer radius; rin==inner radius
local rout1=ro*0.75
local rin1=rout1-(ro*0.10)
for i=0,40 do
if i==5 or i==15 or i==25 or i==35 then
rout=rout1-(ro*0.07)
cairo_set_source_rgba(cr,r,g,b,a)
cairo_set_line_width(cr,3)
elseif i==0 or i==10 or i==20 or i==30 or i==40 then
rout=rout1
cairo_set_line_width(cr,1)
else
rout=rout1-(ro*0.05)
cairo_set_line_width(cr,1)
end
arc=D2R*(210+(i*(300/40)))
ppx=0+rout*(math.sin(arc))
ppy=0-rout*(math.cos(arc))
arc=D2R*(210+(i*300/40))
pix=0+rin1*(math.sin(arc))
piy=0-rin1*(math.cos(arc))
cairo_move_to(cr,px+ppx,py+ppy)
cairo_line_to(cr,px+pix,py+piy)
cairo_stroke(cr)
end
--draw inch text
inch={28,29,30,31}
local rout=rout1+2
for i=1,4 do
arc=D2R*(210+(300/8)+((i-1)*(300/4)))
ppx=0+rout*(math.sin(arc))
ppy=0-rout*(math.cos(arc))
text=inch[i]
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
width=extents.width
height=extents.height
cairo_move_to(cr,px+ppx-(width/2),py+ppy+(height/2))
cairo_show_text(cr,text)
cairo_stroke(cr)
end
--942 to 1056
--27.5=931.25
--31.5=1066.70
--draw mbar scale; rout==outer radius; rin==inner radius
cairo_set_line_width(cr,1)
local m1=300/135.45
local m2=m1*8.75--931.25+8.75=940
local rout2=(ro*0.60)
local rin2=rout2-(ro*0.05)
local num=60
for i=0,num do
if i==0 or i==5 or i==10 or i==15 or i==20 or i==25 or i==30 or i==35 or i==40 or i==45 or i==50 or i==55 or i==60 or i==65 then
rin=rin2-(ro*0.05)
else
rin=rin2
end
-- arc=D2R*(210+m2+(i*((m1*(num*2))/num)))
arc=D2R*(210+m2+(i*m1*2))
ppx=0+rout2*(math.sin(arc))
ppy=0-rout2*(math.cos(arc))
pix=0+rin*(math.sin(arc))
piy=0-rin*(math.cos(arc))
cairo_move_to (cr,px+ppx,py+ppy)
cairo_line_to (cr,px+pix,py+piy)
cairo_stroke (cr)
end
--draw mbar text
inch={940,960,980,1000,1020,1040,1060}
local rout=rin2-(ro*0.18)
local maxW=0
for i=1,7 do
arc=D2R*(210+m2+((i-1)*(m1*20)))
ppx=0+rout*(math.sin(arc))
ppy=0-rout*(math.cos(arc))
text=inch[i]
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
width=extents.width
height=extents.height
if width>maxW then maxW=width end
cairo_move_to(cr,px+ppx-(width/2),py+ppy+(height/2))
cairo_show_text(cr,text)
cairo_stroke(cr)
end
--scale labels
local text="inches hg"
local extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to(cr,px-(width/2),py+rin1)
cairo_show_text(cr,text)
cairo_stroke(cr)
local text="millibars"
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to(cr,px-(width/2),py+rin2-height)
cairo_show_text(cr,text)
cairo_stroke(cr)
local text=st.text or "Pressure";
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to(cr,px-(width/2),py+rin2+(ro*0.35))
cairo_show_text(cr,text)
cairo_stroke(cr)
--[[ draw pointer
psx,psy static tip, rout1 radius
ptx,pty pointer tip, rout1 radius
pbx,pby pointer base, rout radius w/adjust for inner text width
pex,pey pb end cap, rout radius
static pointer has value set at first value of pressure>0
expects pressure in inches Hg
1 inch Hg == 33.8638866667 mBar
]]
pr=tonumber(pr)
local pres=1
if pr==nil or pr<1 then pr=27.5 end--account for nil/zero value
if pr>500 then
-- it's in mBar; convert to inches
pres=(pr/33.8638867) - 27.5
else
-- it's in inches, or we're all dead
pres=pr-27.5
end
if static<1 and pres>0 then
--static pointer value
static=pres
end
local m1=300/4 -- top part of ptr
local m2=pres*m1
local arc=D2R*(210+m2)
local sin=math.sin(arc)
local cos=math.cos(arc)
local ptx=px+rout1*sin
local pty=py-rout1*cos
------------------------------
arc=D2R*(210+m2+180) -- bottom part of ptr
sin=math.sin(arc)
cos=math.cos(arc)
local pbx=px+((rout-maxW)*sin)
local pby=py-((rout-maxW)*cos)
local pex=px+((rout-(2*maxW/3))*sin)
local pey=py-((rout-(2*maxW/3))*cos)
--------------------------------
local psx,psy,arb -- static ptr
if ((static<1) or (static==pres)) then
psx,psy=ptx,pty
else
m2=static*m1
arb=D2R*(210+m2)
sin=math.sin(arb)
cos=math.cos(arb)
psx=px+rout1*sin
psy=py-rout1*cos
end
--------------------------------
local r =st.pfCOL[1] or 0 -- red component of ptr fore colour
local g =st.pfCOL[2] or 0 -- green component of ptr fore colour
local b =st.pfCOL[3] or 0 -- blue component of ptr fore colour
local a =st.pfCOL[4] or 1 -- alpha component of ptr fore colour
cairo_set_source_rgba(cr,r,g,b,a)
cairo_set_line_width(cr,3)
cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND)
cairo_arc(cr,pex,pey,maxW/3,arc,arc-math.pi)
cairo_move_to(cr,ptx,pty)
cairo_line_to(cr,pbx,pby)
cairo_move_to(cr,px,py)
cairo_arc(cr,px,py,ro*0.04,0,ARC)
cairo_stroke(cr)
--------------------------------
local r =st.bkCOL[1] or 0.1 -- red component of background colour
local g =st.bkCOL[2] or 0.1 -- green component of background colour
local b =st.bkCOL[3] or 0.1 -- blue component of background colour
local a =st.bkCOL[4] or 1 -- alpha component of background colour
cairo_set_source_rgba(cr,r,g,b,a)
cairo_arc(cr,px,py,ro*0.02,0,ARC)
--cairo_arc(cr,px,py,ro*0.03,0,ARC)
cairo_fill(cr)
--------------------------------
local r =st.psCOL[1] or 0 -- red component of static ptr colour
local g =st.psCOL[2] or 0 -- green component of static ptr colour
local b =st.psCOL[3] or 0 -- blue component of static ptr colour
local a =st.psCOL[4] or 1 -- alpha component of static ptr colour
cairo_set_source_rgba(cr,r,g,b,a)
cairo_set_line_width(cr,1)
cairo_move_to(cr,psx,psy)
cairo_line_to(cr,px,py)
cairo_stroke(cr)
cairo_arc(cr,px,py,ro*0.02,0,ARC)
--cairo_arc(cr,px,py,ro*0.04,0,ARC)
cairo_fill(cr)
--[[ original pointer
-- begin speedo-type pointer (alpha=0 - no bottom part of pointer)
-- or magnet-type pointer (alpha=1 for top&bottom)
local m1=300/4
local m2=pres*m1
local rout1=rout1
local arc=D2R*(210+m2)
local ppx=0+rout1*(math.sin(arc))
local ppy=0-rout1*(math.cos(arc))
------------------------------
local arc=D2R*(210+m2+180)
local ppox=0+rout1*(math.sin(arc))
local ppoy=0-rout1*(math.cos(arc))
-------------------------------
local rin3=(ro*0.07)
local arc=D2R*(210+m2-90)
local pilx=0+rin3*(math.sin(arc))
local pily=0-rin3*(math.cos(arc))
local arc=D2R*(210+m2+90)
local pirx=0+rin3*(math.sin(arc))
local piry=0-rin3*(math.cos(arc))
--------------------------------
local r =st.pfCOL[1] or 1 -- red component of ptr fore colour
local g =st.pfCOL[2] or 0 -- green component of ptr fore colour
local b =st.pfCOL[3] or 0 -- blue component of ptr fore colour
local a =st.pfCOL[4] or 1 -- alpha component of ptr fore colour
cairo_move_to(cr,px+pilx,py+pily)
cairo_line_to(cr,px+ppx,py+ppy)
cairo_line_to(cr,px+pirx,py+piry)
cairo_line_to(cr,px+pilx,py+pily)
cairo_set_source_rgba(cr,r,g,b,a)
cairo_fill(cr)
cairo_arc(cr,px,py,rin3,0,ARC)
cairo_fill(cr)
---------------------------------
local r =st.pbCOL[1] or 1 -- red component of ptr back colour
local g =st.pbCOL[2] or 1 -- green component of ptr back colour
local b =st.pbCOL[3] or 1 -- blue component of ptr back colour
local a =st.pbCOL[4] or 1 -- alpha component of ptr back colour
cairo_move_to (cr,px+pilx,py+pily)
cairo_line_to (cr,px+ppox,py+ppoy)
cairo_line_to (cr,px+pirx,py+piry)
cairo_line_to (cr,px+pilx,py+pily)
cairo_set_source_rgba (cr,r,b,g,a)
cairo_fill (cr)
local r =st.pfCOL[1] or 1 -- red component of ptr fore colour
local g =st.pfCOL[2] or 0 -- green component of ptr fore colour
local b =st.pfCOL[3] or 0 -- blue component of ptr fore colour
local a =st.pfCOL[4] or 1 -- alpha component of ptr fore colour
cairo_set_source_rgba (cr,r,g,b,a)
cairo_arc (cr,px,py,rin3,0,ARC)
cairo_fill (cr)
-----------------------------------
local r =st.ppCOL[1] or 0 -- red component of ptr pivot colour
local g =st.ppCOL[2] or 0 -- green component of ptr pivot colour
local b =st.ppCOL[3] or 0 -- blue component of ptr pivot colour
local a =st.ppCOL[4] or 1 -- alpha component of ptr pivot colour
cairo_set_source_rgba (cr,r,g,b,a)
cairo_arc (cr,px,py,rin3-1,0,ARC)
cairo_fill (cr)
-- end car -type pointer (alpha=0 so no bottom part of pointer) ]]
----circle text
local horiz=px
local verti=py
local radi=(ro*0.87)
local font=st.ctFNT or "Mono";
local text=st.ctStorm or "STORMY";
local size=st.ctSize or 12;
local fsize=(ro*size/100)
local start=250
local finish=start+((string.len(text))*5)
circlewriting(cr, text, font, fsize, radi, horiz, verti, start, finish,st)
local text=st.ctRain or "RAIN";
local start=300
local finish=start+((string.len(text))*5)
circlewriting(cr, text, font, fsize, radi, horiz, verti, start, finish,st)
local text=st.ctChang or "CHANGE";
local start=340
local finish=start+((string.len(text))*5)
circlewriting(cr, text, font, fsize, radi, horiz, verti, start, finish,st)
local text=st.ctFair or "FAIR";
local start=395
local finish=start+((string.len(text))*5)
circlewriting(cr, text, font, fsize, radi, horiz, verti, start, finish,st)
local text=st.ctVDry or "VERY DRY";
local start=435
local finish=start+((string.len(text))*5)
circlewriting(cr, text, font, fsize, radi, horiz, verti, start, finish,st)
end-- function barometer
------------------------------------------------------------------------------
function circlewriting(cr, text, font, fsize, radi, horiz, verti, start, finish, st)
local r =st.ctCOL[1] or 1 -- red component of circle txt colour
local g =st.ctCOL[2] or 1 -- green component of circle txt colour
local b =st.ctCOL[3] or 1 -- blue component of circle txt colour
local a =st.ctCOL[4] or 1 -- alpha component of circle txt colour
local s =st.ctSLNT or CAIRO_FONT_SLANT_NORMAL -- font slant setting
local w =st.ctWT or CAIRO_FONT_WEIGHT_NORMAL -- font weight setting
cairo_select_font_face (cr, font, s, w);
cairo_set_font_size (cr, fsize)
cairo_set_source_rgba (cr,r,g,b,a);
local inum=string.len(text)
local deg=(finish-start)/(inum-1)
local degrads=(math.pi/180)
local textcut=string.gsub(text, ".", "%1|")
texttable=string.split(textcut, "|")
for i=1,inum do
interval=(degrads*(start+(deg*(i-1))))
txs=0+radi*(math.sin(interval))
tys=0-radi*(math.cos(interval))
cairo_move_to (cr, txs+horiz, tys+verti);
cairo_rotate (cr, interval)
cairo_show_text (cr, (texttable[i]))
cairo_stroke (cr)
cairo_rotate (cr, -interval)
end
end--function circlewriting
------------------------------------------------------------------------------
--[[ savecsv()
Save barometer stats as a CSV file
@param dt datetime (YYYY-MM-DD (ISO 8601) + HH:DD UTC)
@param lo location of CSV file in filesystem
@param pr pressure (mBar or inches Mercury)
@return (none)
update always = 1 at entry to this function
lo may NOT exist at entry if first-time save
]]
function savecsv(dt,lo,pr)
-- first check if lo exists & create if not
local f, err = io.open(lo, "r")
local file
if f~=nil then
-- file exists; now open in append-mode
f:close()
file, err = io.open(lo, "a+")
if file==nil then
print("Error opening file "..lo..":"..err)
end
else
-- file NOT exist; create in append-mode
local header="'Time','Barometer'\n"
file, err = io.open(lo, "a+")
if file then
file:write(header)
else
print("Error creating new file "..lo..":"..err)
end
end
if file then
file:write("'"..dt.."','"..pr.."'\n")
file:close()
end
end-- function savecsv
------------------------------------------------------------------------------
function string:split(delimiter)
local result = { }
local from = 1
local delim_from, delim_to = string.find( self, delimiter, from )
while delim_from do
table.insert( result, string.sub( self, from , delim_from-1 ) )
from = delim_to + 1
delim_from, delim_to = string.find( self, delimiter, from )
end
table.insert( result, string.sub( self, from ) )
return result
end
--------------------------------------------------------------------------------
function wspeed_dial(ws,px,py)
--0 to 60 mph
--draw circle
cairo_set_line_width (cr,1)
local router=110
cairo_set_source_rgba (cr,0.1,0.1,0.1,1)
cairo_arc (cr,px,py,router,0,(2*math.pi))
cairo_fill (cr)
cairo_set_source_rgba (cr,1,1,1,1)
cairo_arc (cr,px,py,router,0,(2*math.pi))
cairo_stroke (cr)
-------------------------------------------
--mph scale
local rout1=80
local rin1=rout1-10
for i=0,60 do
if i==5 or i==15 or i==25 or i==35 or i==45 then
rin=rin1--set line length for 5s
cairo_set_line_width (cr,1)
elseif i==0 or i==10 or i==20 or i==30 or i==40 or i==50 or i==60 then
rin=rin1+7--set line length for 10's
cairo_set_line_width (cr,3)
else
rin=rin1+5--set other lines
cairo_set_line_width (cr,1)
end--if i==
arc=(math.pi/180)*(210+(i*(300/60)))
ppx=0+rout1*(math.sin(arc))
ppy=0-rout1*(math.cos(arc))
arc=(math.pi/180)*(210+(i*300/60))
pix=0+rin*(math.sin(arc))
piy=0-rin*(math.cos(arc))
cairo_move_to (cr,px+ppx,py+ppy)
cairo_line_to (cr,px+pix,py+piy)
cairo_stroke (cr)
end--for i=
--mph reading
mph={0,10,20,30,40,50,60}
local rin=rin1-2
for i=1,#mph do
arc=(math.pi/180)*(210+((i-1)*(300/6)))
ppx=0+rin*(math.sin(arc))
ppy=0-rin*(math.cos(arc))
text=mph[i]
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
width=extents.width
height=extents.height
cairo_move_to (cr,px+ppx-(width/2),py+ppy+(height/2))
cairo_show_text (cr,text)
cairo_stroke (cr)
end--for i= print inches
--kmh lines and numbers
--60kmh=96.5606
cairo_set_line_width (cr,1)
local m1=300/96.5606
local rout2=60
local rin2=rout2-5
local num=95
--print lines---------------
for i=0,num do
if i==0 or i==10 or i==20 or i==30 or i==40 or i==50 or i==60 or i==70 or i==80 or i==90 then
rin=rin2-5--set length for 10s
elseif i==5 or i==15 or i==25 or i==35 or i==45 or i==55 or i==65 or 1==75 or i==85 or i==95 then
rin=rin2-2--set length for 5's
else
rin=rin2
end--if i=
---------------------------------------------------
arc=(math.pi/180)*(210+(i*m1))
ppx=0+rout2*(math.sin(arc))
ppy=0-rout2*(math.cos(arc))
arc=(math.pi/180)*(210+(i*m1))
pix=0+rin*(math.sin(arc))
piy=0-rin*(math.cos(arc))
cairo_move_to (cr,px+ppx,py+ppy)
cairo_line_to (cr,px+pix,py+piy)
cairo_stroke (cr)
end--for i --line drawing
--kmh reading
kmh={0,10,20,30,40,50,60,70,80,90}
local rout=rin2-18
for i=1,#kmh do
arc=(math.pi/180)*(210+((i-1)*(m1*10)))
ppx=0+rout*(math.sin(arc))
ppy=0-rout*(math.cos(arc))
text=kmh[i]
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
width=extents.width
height=extents.height
cairo_move_to (cr,px+ppx-(width/2),py+ppy+(height/2))
cairo_show_text (cr,text)
cairo_stroke (cr)
end--kmh lines and numbers
--knots
--60kmh=52.1386
cairo_set_line_width (cr,1)
local m1=300/52.1386
local rout3=90
local rin3=rout3-5
local num=50
--print lines---------------
for i=0,num do
if i==0 or i==10 or i==20 or i==30 or i==40 or i==50 then
rout=rout3-1--set length for 10s
cairo_set_line_width (cr,3)
elseif i==5 or i==15 or i==25 or i==35 or i==45 then
rout=rout3+4--set length for 5's
cairo_set_line_width (cr,1)
else
rout=rout3
cairo_set_line_width (cr,1)
end--if i=
---------------------------------------------------
arc=(math.pi/180)*(210+(i*m1))
ppx=0+rout*(math.sin(arc))
ppy=0-rout*(math.cos(arc))
arc=(math.pi/180)*(210+(i*m1))
pix=0+rin3*(math.sin(arc))
piy=0-rin3*(math.cos(arc))
cairo_move_to (cr,px+pix,py+piy)
cairo_line_to (cr,px+ppx,py+ppy)
cairo_stroke (cr)
end--for i --line drawing
--kmh reading
knot={0,10,20,30,40,50}
local rout=rin3+15
for i=1,#kmh do
arc=(math.pi/180)*(210+((i-1)*(m1*10)))
ppx=0+rout*(math.sin(arc))
ppy=0-rout*(math.cos(arc))
text=knot[i]
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
width=extents.width
height=extents.height
cairo_move_to (cr,px+ppx-(width/2),py+ppy+(height/2))
cairo_show_text (cr,text)
cairo_stroke (cr)
end
--scale labels
local text="mph"
local extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to (cr,px-(width/2),py+rin1)
cairo_show_text (cr,text)
cairo_stroke (cr)
local text="kmh"
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to (cr,px-(width/2),py+rin2)
cairo_show_text (cr,text)
cairo_stroke (cr)
local text="knots"
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to (cr,px-(width/2),py+rin3)
cairo_show_text (cr,text)
cairo_stroke (cr)
local text="Wind Speed"
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to (cr,px-(width/2),py+rin3+16)
cairo_show_text (cr,text)
cairo_stroke (cr)
--pointer
if ws==nil then ws=0 end
local wspd=ws
local m1=300/60
local m2=wspd*m1
local rout1=rout3
local arc=(math.pi/180)*(210+m2)
local ppx=0+rout1*(math.sin(arc))
local ppy=0-rout1*(math.cos(arc))
------------------------------
local arc=(math.pi/180)*(210+m2+180)
local ppox=0+rout1*(math.sin(arc))
local ppoy=0-rout1*(math.cos(arc))
-------------------------------
local rin3=7
local arc=(math.pi/180)*(210+m2-90)
local pilx=0+rin3*(math.sin(arc))
local pily=0-rin3*(math.cos(arc))
local arc=(math.pi/180)*(210+m2+90)
local pirx=0+rin3*(math.sin(arc))
local piry=0-rin3*(math.cos(arc))
--------------------------------
cairo_move_to (cr,px+pilx,py+pily)
cairo_line_to (cr,px+ppx,py+ppy)
cairo_line_to (cr,px+pirx,py+piry)
cairo_line_to (cr,px+pilx,py+pily)
cairo_set_source_rgba (cr,1,0,0,1)
cairo_fill (cr)
cairo_arc (cr,px,py,rin3,0,(2*math.pi))
cairo_fill (cr)
---------------------------------
cairo_move_to (cr,px+pilx,py+pily)
cairo_line_to (cr,px+ppox,py+ppoy)
cairo_line_to (cr,px+pirx,py+piry)
cairo_line_to (cr,px+pilx,py+pily)
cairo_set_source_rgba (cr,1,1,1,1)
cairo_fill (cr)
cairo_set_source_rgba (cr,1,0,0,1)
cairo_arc (cr,px,py,rin3,0,(2*math.pi))
cairo_fill (cr)
-----------------------------------
cairo_set_source_rgba (cr,0,0,0,1)
cairo_arc (cr,px,py,rin3-1,0,(2*math.pi))
cairo_fill (cr)
end--wspeed_dial function
------------------------------------------------------------------------------
function humidity(x,y,hval1)
hval=hval1*1.5
yt=y-1
rh=151
rw=30
local pat = cairo_pattern_create_linear (0,yt,0,yt+rh);
cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 1, 0);
cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 1, 1);
cairo_rectangle (cr,x,yt,rw, rh);
cairo_set_source (cr, pat);
cairo_fill (cr);
cairo_pattern_destroy (pat);
----------
for i=1,11 do
lwid=-1
cairo_set_source_rgba (cr,1,1,1,1)
cairo_move_to (cr,x+rw,(y+150)-((i-1)*15))
cairo_rel_line_to (cr,lwid,0)
cairo_stroke(cr)
end
----------
cairo_set_source_rgba (cr,1,1,1,1)
hh=5
hw1=19
hw2=hw1+10
if hval==nil then hval=0 end
tx,ty=x+hw1,(y+150)-(hval+hh)
ix,iy=x+hw2,(y+150)-hval
bx,by=x+hw1,(y+150)-(hval-hh)
cairo_move_to (cr,tx,ty)
cairo_line_to (cr,ix,iy)
cairo_line_to (cr,bx,by)
cairo_line_to (cr,tx,ty)
cairo_fill (cr)
cairo_set_source_rgba (cr,1,1,1,1)
font="Mono"
fsize=12
cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, fsize)
cairo_move_to (cr,x+hw2+3,(y+150)-(hval-hh))
cairo_show_text (cr,hval1.."%")
cairo_stroke (cr)
label="Relative Humidity"
cairo_move_to (cr,x+12,y+150)
cairo_rotate (cr,(math.pi/180)*(-90))
cairo_show_text (cr,label)
cairo_stroke (cr)
cairo_rotate (cr,(math.pi/180)*(90))
end--humidity
------------------------------------------------------------------------------
function txt(text,xpos,ypos,font,fsize,red,green,blue,alpha)
cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, fsize)
cairo_set_source_rgba (cr,red,green,blue,alpha)
cairo_move_to (cr,xpos,ypos)
cairo_show_text (cr,text)
cairo_stroke (cr)
end--function txt
------------------------------------------------------------------------------
function compass(wx,wy,rout,wdeg,w,wg)
local rin=rout-((rout/100)*10)
cairo_set_source_rgba (cr,0.1,0.1,0.1,1)
cairo_arc (cr,wx,wy,rout,0,(2*math.pi))
cairo_fill (cr)
cairo_set_source_rgba (cr,1,1,1,1)
cairo_arc (cr,wx,wy,rout,0,(2*math.pi))
cairo_stroke (cr)
for i=1,36 do
arc=(math.pi/180)*(i*10)
wpx=0+rout*(math.sin(arc))
wpy=0-rout*(math.cos(arc))
arc=(math.pi/180)*(i*10)
wix=0+rin*(math.sin(arc))
wiy=0-rin*(math.cos(arc))
cairo_move_to (cr,wx+wpx,wy+wpy)
cairo_line_to (cr,wx+wix,wy+wiy)
cairo_stroke (cr)
end
--print directions
local font="Mono"
local fsize=10
cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, fsize)
dirs={"N","NE","E","SE","S","SW","W","NW"}
local rdir=rout-((rout/100)*25)
for i=1,8 do
arc=(math.pi/180)*((i-1)*(360/8))
wdx=0+rdir*(math.sin(arc))
wdy=0-rdir*(math.cos(arc))
text=dirs[i]
extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
width=extents.width
height=extents.height
cairo_move_to (cr,wx+wdx-(width/2),wy+wdy+(height/2))
cairo_show_text (cr,text)
cairo_stroke (cr)
end
--indicator
local npr=rout-((rout/100)*15)
if wdeg==nil then wdeg=0 end
local arc=(math.pi/180)*(wdeg)
local npx=0+npr*(math.sin(arc))
local npy=0-npr*(math.cos(arc))
cairo_move_to (cr,wx+npx,wy+npy)
local nprm=rout-((rout/100)*88)
local arc=(math.pi/180)*(wdeg+90)
local npmrx=0+nprm*(math.sin(arc))
local npmry=0-nprm*(math.cos(arc))
local arc=(math.pi/180)*(wdeg-90)
local npmlx=0+nprm*(math.sin(arc))
local npmly=0-nprm*(math.cos(arc))
cairo_line_to (cr,wx+npmrx,wy+npmry)
cairo_line_to (cr,wx+npmlx,wy+npmly)
cairo_line_to (cr,wx+npx,wy+npy)
cairo_set_source_rgba (cr,1,0,0,1)
cairo_fill (cr)
cairo_set_source_rgba (cr,1,1,1,1)
---------------------------------
local arc=(math.pi/180)*(wdeg-180)
local spx=0+npr*(math.sin(arc))
local spy=0-npr*(math.cos(arc))
cairo_move_to (cr,wx+spx,wy+spy)
local sprm=nprm
local arc=(math.pi/180)*(wdeg+90-180)
local spmrx=0+sprm*(math.sin(arc))
local spmry=0-sprm*(math.cos(arc))
local arc=(math.pi/180)*(wdeg-90-180)
local spmlx=0+sprm*(math.sin(arc))
local spmly=0-sprm*(math.cos(arc))
cairo_line_to (cr,wx+spmrx,wy+spmry)
cairo_line_to (cr,wx+spmlx,wy+spmly)
cairo_line_to (cr,wx+spx,wy+spy)
cairo_fill (cr)
--------------------------------------
cairo_set_source_rgba (cr,0,0,0,1)
cairo_arc (cr,wx,wy,nprm,0,(2*math.pi))
cairo_fill (cr)
cairo_set_source_rgba (cr,1,0,0,1)
cairo_arc (cr,wx,wy,nprm,0,(2*math.pi))
cairo_stroke (cr)
------------------------
cairo_set_source_rgba (cr,1,1,1,1)
local text="Wind Direction"
local extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to (cr,wx-(width/2),wy-rout-5)
cairo_show_text (cr,text)
cairo_stroke (cr)
end--compass
------------------------------------------------------------------------------
function thermometer(mx,my,temp,label,scale,mid,units)
--by mrpeachy 2011
if scale==nil then scale=1 end
if units=="F" then height=150 elseif units=="C" then height=160 end
local mx=mx*(1/scale)
local my=my*(1/scale)
local font="Mono"
local fsize=10
cairo_scale (cr,scale,scale)
cairo_set_line_width (cr,1)
cairo_set_source_rgba (cr,1,1,1,1)
--graphics outer
--bottom circle
r_outer=25
local lang_outer=335
local rang_outer=0+(360-lang_outer)
local h_outer=height-4--maybe make this a percentage?###########
cairo_arc (cr,mx,my,r_outer,(math.pi/180)*(rang_outer-90),(math.pi/180)*(lang_outer-90))
--coordinates,left line
local arc=(math.pi/180)*lang_outer
local lxo=0+r_outer*(math.sin(arc))
local lyo=0-r_outer*(math.cos(arc))
cairo_line_to (cr,mx+lxo,my+lyo-h_outer)
--coordinates,left line
local arc=(math.pi/180)*rang_outer
local rxo=0+r_outer*(math.sin(arc))
local ryo=0-r_outer*(math.cos(arc))
--top circle
cairo_arc (cr,mx+lxo+((rxo-lxo)/2),my+lyo-h_outer,(rxo-lxo)/2,(math.pi/180)*(270-90),(math.pi/180)*(90-90))
--right line
cairo_line_to (cr,mx+lxo+((rxo-lxo)),my+lyo)
cairo_stroke (cr)
----------------------------------------------
--graphics inner
--####################################################
if units=="F" then
local str,stg,stb,sta=0,1,1,1
local mr,mg,mb,ma=1,1,0,1
local fr,fg,fb,fa=1,0,0,1
local nd=150
if temp==nil then temp=0 end
local tadj=temp+30
local middle=mid+30
if tadj<(middle) then
colr=((mr-str)*(tadj/(middle)))+str
colg=((mg-stg)*(tadj/(middle)))+stg
colb=((mb-stb)*(tadj/(middle)))+stb
cola=((ma-sta)*(tadj/(middle)))+sta
elseif tadj>=(middle) then
colr=((fr-mr)*((tadj-(middle))/(nd-middle)))+mr
colg=((fg-mg)*((tadj-(middle))/(nd-middle)))+mg
colb=((fb-mb)*((tadj-(middle))/(nd-middle)))+mb
cola=((fa-ma)*((tadj-(middle))/(nd-middle)))+ma
end
cairo_set_source_rgba (cr,colr,colg,colb,cola)
--bottom circle
r_inner=r_outer-6
local lang_inner=lang_outer+9
local rang_inner=0+(360-lang_inner)
local h_inner=temp+30
cairo_arc (cr,mx,my,r_inner,(math.pi/180)*(rang_inner-90),(math.pi/180)*(lang_inner-90))
--coordinates,left line
local arc=(math.pi/180)*lang_inner
lxi=0+r_inner*(math.sin(arc))
local lyi=0-r_inner*(math.cos(arc))
cairo_line_to (cr,mx+lxi,my+lyi-h_inner)
--coordinates,left line
local arc=(math.pi/180)*rang_inner
rxi=0+r_inner*(math.sin(arc))
local ryi=0-r_inner*(math.cos(arc))
--top circle
cairo_arc (cr,mx+lxi+((rxi-lxi)/2),my+lyi-h_inner,(rxi-lxi)/2,(math.pi/180)*(270-90),(math.pi/180)*(90-90))
--right line
cairo_line_to (cr,mx+lxi+((rxi-lxi)),my+lyi)
cairo_fill (cr)
----------------------------
if label~="none" then
--scale lines
cairo_set_line_width (cr,1)
cairo_set_source_rgba (cr,1,1,1,0.5)
local grad=10
local lnn=15
local lnx=mx+lxo
local lnw=(rxo-lxo)
for i=1,lnn do
lny=my-r_inner-(10+((i-1)*grad))-((rxi-lxi)/2)
if i==lnn then
lnx=lnx+2
lnw=lnw-4
end
cairo_move_to (cr,lnx,lny)
cairo_rel_line_to (cr,lnw,0)
cairo_stroke (cr)
end
--numbers
cairo_set_source_rgba (cr,1,1,1,1)
cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, fsize)
local grad=20
local lnn=8
local lnx=mx+lxo+(rxo-lxo)+4
num={-20,"0°"..units,20,40,60,80,100,120}
for i=1,lnn do
lny=my-r_inner-(10+((i-1)*grad))-((rxi-lxi)/2)+(fsize/3)
cairo_move_to (cr,lnx,lny)
cairo_show_text (cr,num[i])
cairo_stroke (cr)
end
end--if label=none
end--if units=F
--#################################################
if units=="C" then
--from -30 to 50 C
local str,stg,stb,sta=0,1,1,1
local mr,mg,mb,ma=1,1,0,1
local fr,fg,fb,fa=1,0,0,1
local nd=160
if temp==nil then temp=0 end
local tadj=(temp*2)+60
local middle=(mid*2)+60
if tadj<(middle) then
colr=((mr-str)*(tadj/(middle)))+str
colg=((mg-stg)*(tadj/(middle)))+stg
colb=((mb-stb)*(tadj/(middle)))+stb
cola=((ma-sta)*(tadj/(middle)))+sta
elseif tadj>=(120) then
colr=((fr-mr)*((tadj-(middle))/(nd-middle)))+mr
colg=((fg-mg)*((tadj-(middle))/(nd-middle)))+mg
colb=((fb-mb)*((tadj-(middle))/(nd-middle)))+mb
cola=((fa-ma)*((tadj-(middle))/(nd-middle)))+ma
end
cairo_set_source_rgba (cr,colr,colg,colb,cola)
--cairo_set_source_rgba (cr,0,1,1,1)
--bottom circle
r_inner=r_outer-6
local lang_inner=lang_outer+9
local rang_inner=0+(360-lang_inner)
local h_inner=(temp*2)+60
cairo_arc (cr,mx,my,r_inner,(math.pi/180)*(rang_inner-90),(math.pi/180)*(lang_inner-90))
--coordinates,left line
local arc=(math.pi/180)*lang_inner
lxi=0+r_inner*(math.sin(arc))
local lyi=0-r_inner*(math.cos(arc))
cairo_line_to (cr,mx+lxi,my+lyi-h_inner)
--coordinates,left line
local arc=(math.pi/180)*rang_inner
rxi=0+r_inner*(math.sin(arc))
local ryi=0-r_inner*(math.cos(arc))
--top circle
cairo_arc (cr,mx+lxi+((rxi-lxi)/2),my+lyi-h_inner,(rxi-lxi)/2,(math.pi/180)*(270-90),(math.pi/180)*(90-90))
--right line
cairo_line_to (cr,mx+lxi+((rxi-lxi)),my+lyi)
cairo_fill (cr)
----------------------------
if label~="none" then
--scale lines
cairo_set_line_width (cr,1)
cairo_set_source_rgba (cr,1,1,1,0.5)
local grad=10
local lnn=17
local lnx=mx+lxo
local lnw=(rxo-lxo)
for i=1,lnn do
lny=my-r_inner-(((i-1)*grad))-((rxi-lxi)/2)
if i==lnn then
lnx=lnx+2
lnw=lnw-4
end
cairo_move_to (cr,lnx,lny)
cairo_rel_line_to (cr,lnw,0)
cairo_stroke (cr)
end
--numbers
cairo_set_source_rgba (cr,1,1,1,1)
cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, fsize)
local grad=20
local lnn=9
local lnx=mx+lxo+(rxo-lxo)+4
num={-30,-20,-10,"0°"..units,10,20,30,40,50}
for i=1,lnn do
lny=my-r_inner-(((i-1)*grad))-((rxi-lxi)/2)+(fsize/3)
cairo_move_to (cr,lnx,lny)
cairo_show_text (cr,num[i])
cairo_stroke (cr)
end
end--if label=none
end--if units=C
--#################################################
--label
if label~="none" then
local font="Mono"
local fsize=12
cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, fsize)
local lbx=mx+lxo-5
local lby=my-r_inner-10-((rxi-lxi)/2)
cairo_move_to (cr,lbx,lby)
cairo_rotate (cr,(math.pi/180)*(-90))
cairo_show_text (cr,label)
cairo_stroke (cr)
cairo_rotate (cr,(math.pi/180)*(90))
--temperature readout
cairo_set_source_rgba (cr,0,0,0,1)
local text=temp.."°"..units
local extents=cairo_text_extents_t:create()
cairo_text_extents(cr,text,extents)
local width=extents.width
local height=extents.height
cairo_move_to (cr,mx-(width/2),my+(height/2))
cairo_show_text (cr,text)
cairo_stroke (cr)
end--if label
------------------------------------
cairo_scale (cr,1/scale,1/scale)
end--thermometer function
------------------------------------------------------------------------------
function conky_draw_bg(r,x,y,w,h,color,alpha)
if conky_window == nil then return end
if cs == nil then cairo_surface_destroy(cs) end
if cr == nil then cairo_destroy(cr) end
local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height)
local cr = cairo_create(cs)
cairo_set_source_rgba (cr,htm2col(color,alpha))
--top left mid circle
local xtl=x+r
local ytl=y+r
--top right mid circle
local xtr=(x+r)+((w)-(2*r))
local ytr=y+r
--bottom right mid circle
local xbr=(x+r)+((w)-(2*r))
local ybr=(y+r)+((h)-(2*r))
--bottom right mid circle
local xbl=(x+r)
local ybl=(y+r)+((h)-(2*r))
-----------------------------
cairo_move_to (cr,xtl,ytl-r)
cairo_line_to (cr,xtr,ytr-r)
cairo_arc(cr,xtr,ytr,r,((2*math.pi/4)*3),((2*math.pi/4)*4))
cairo_line_to (cr,xbr+r,ybr)
cairo_arc(cr,xbr,ybr,r,((2*math.pi/4)*4),((2*math.pi/4)*1))
cairo_line_to (cr,xbl,ybl+r)
cairo_arc(cr,xbl,ybl,r,((2*math.pi/4)*1),((2*math.pi/4)*2))
cairo_line_to (cr,xtl-r,ytl)
cairo_arc(cr,xtl,ytl,r,((2*math.pi/4)*2),((2*math.pi/4)*3))
cairo_close_path(cr)
cairo_fill (cr)
-----------------------------
cairo_surface_destroy(cs)
cairo_destroy(cr)
return ""
end-- conky_draw_bg function
--[[ htm2col()
Parse a HTML-colour + return lua/cairo-suitable colours.
This function parses colours like 0xrrggbb + alpha in the range [0, 1]
For example, htm2col(0x00ff00,1.0) would return 0, 1, 0, 1.
obtained from clock_rings
@param colour The colour to parse eg 0xffffff (white)
@param alpha The alpha to parse eg 0.5
@return 4 values which each are in the range [0, 1].
]]
function htm2col(colour,alpha)
return ((colour / 0x10000) % 0x100) / 255., ((colour / 0x100) % 0x100) / 255., (colour % 0x100) / 255., alpha
end
------------------------------------------------------------------------------
function conky_draw_test()
if conky_window==nil then return end
local cs=cairo_xlib_surface_create(conky_window.display,conky_window.drawable,conky_window.visual,conky_window.width,conky_window.height)
local cr=cairo_create(cs)
local date=conky_parse('${execi 300 /home/alexk/.conky/weather.pl EGNX DATE}')
local pressure=conky_parse('${execi 300 /home/alexk/.conky/weather.pl EGNX ALT_HP}')
pressure=tonumber(pressure)
local time=conky_parse('${execi 300 /home/alexk/.conky/weather.pl EGNX TIME}')
local location=conky_parse('${execi 300 /home/alexk/.conky/weather.pl EGNX CSV}')
local datetime=date.." "..time
-- local pressure=tonumber(conky_parse('${weather http://weather.noaa.gov/pub/data/observations/metar/stations/ EGNX pressure 30}'))
-- check all local are NOT nil
if date==nil then
print("date is nil in conky_draw_test()")
return
end
if pressure==nil then
print("pressure is nil in conky_draw_test()")
return
end
if time==nil then
print("time is nil in conky_draw_test()")
return
end
if location==nil then
print("location is nil in conky_draw_test()")
return
end
-- update CSV file only if barometer pressure has changed
if old_pressure==nil or old_pressure<1 then
update=1
else
if old_pressure==pressure then update=0 else update=1 end
end
barometer(cr,pressure,120,150)
if update==1 then
savecsv(datetime,location,pressure)
old_pressure=pressure
end
-----------------------------
cairo_surface_destroy(cs)
cairo_destroy(cr)
return ""
end-- function conky_draw_test
Offline
The NOAA keep changing the access methods for weather access from the airport of your choice. I therefore place the access method into a PERL script together with caching (to substantially reduce the hammer from these scripts on the chosen Airport). Here is the latest script (although the Id has NOT yet been updated) (23:06: just updated):
~/.conky/weather.pl:
#!/usr/bin/perl
# $Id: weather.pl,v 1.3 2023/10/17 14:23:49 +0100 alexkemp Exp $
# Brief Description
# =================
#
# utility to replace conky weather using aviationweather.gov (US Govt)
# conky weather stopped working 2016 August
# (weather.noaa.gov/pub/data/observations/metar/stations/ withdrawn)
#
# Given an airport site code on the command line, weather.pl
# fetches the weather and displays it on the command-line.
# Requires libgeo-metar-perl
# (and others)
# Here are some example airports:
# East Midlands : EGNX
# LA : KLAX
# Dallas : KDFW
# Detroit : KDTW
# Chicago : KMDW
#
# 2023-10-16 v 1.3 url update following aviationweather.gov site update
# 2020-11-19 v 1.2 added $DATE + $CSV (store barometer csv)
# changed $ERR to "" (empty string)
# changed order: check cache timeout first (reduce remote accesses)
# 2018-05-02 v 1.1 added file caching (reduce hammer on remote site)
# 2016-09-18 v 1.0 started
my $HELP = "
USAGE: $0 <locationCode> <responseType>
example: $0 EGNX ALT_HP
(East Midlands for barometer-in-mbar)
list of location codes:
http://weather.rap.ucar.edu/surface/stations.txt
METAR source code:
http://jeremy.zawodny.com/perl/Geo-METAR/METAR.html
list of possible responses (date_time: 2020/11/08 22:20):
ALT (eg '30.061522694' inches)
ALT_HP (eg '1018' millibars)
CSV (eg '~/.conky/barometer.csv' )
DATE (eg '2020-11-08' UTC)
DEW_C (eg '11' temperature °C)
DEW_F (eg '51.8' temperature °F)
RH (eg '100' relative humidity %)
SKY (eg 'Sky Clear' )
TEMP_C (eg '11' temperature °C)
TEMP_F (eg '51.8' temperature °F)
TIME (eg '22:20 UTC' )
TYPE (eg 'Routine Weather Report' )
VISIBILITY (eg '0600 meters' )
WEATHER (eg 'No significant weather' )
WIND_DIR_ABB (eg 'S' )
WIND_DIR_DEG (eg '170' )
WIND_DIR_ENG (eg 'South' )
WIND_KTS (eg '03' knots )
WIND_MPH (eg '3.45233835' mph )
WIND_MS (eg '1.543333332' m/sec )
WIND_VAR (eg '' )
METAR (eg 'EGNX 082220Z 17003KT 0600 R27/P1500 RA FG BKN002 OVC010 11/11 Q1018')
Version: v1.3 2023-10-16\n";
# remote site(s) providing metar info
my $REMOTE = "https://aviationweather.gov/api/data/metar";
#my $REMOTE = "https://www.aviationweather.gov/metar/data";
#my $REMOTE = "https://tgftp.nws.noaa.gov/data/observations/metar/stations";
# Get the site code requested
my ($LOCATION,$TYPE) = @ARGV;
# cache parameters
# file location
my $CACHE = "~/.conky/.metar_cache";
# update interval, secs
my $CACHE_UI = 1200;
# file location
my $CSV = "~/.conky/barometer.csv";
die $HELP unless ($LOCATION && $TYPE);
# Get the modules we need.
use strict;
use utf8;
use Capture::Tiny ':all';
use Date::Calc ':all';
use Geo::METAR;
use LWP::UserAgent;
use POSIX qw(strftime);
use Switch;
use Time::Local;
# expand the tilde (file-open will NOT auto-expand it)
$CACHE =~ s{ ^ ~ ( [^/]* ) }
{ $1
? (getpwnam($1))[7]
: ($ENV{HOME} || $ENV{LOGDIR} || (getpwuid($>))[7])
}ex;
# hash array
my %CACHE_HASH;
# expand the tilde (file-open will NOT auto-expand it)
$CSV =~ s{ ^ ~ ( [^/]* ) }
{ $1
? (getpwnam($1))[7]
: ($ENV{HOME} || $ENV{LOGDIR} || (getpwuid($>))[7])
}ex;
# get cache-file mod timestamp + time-now (secs since Epoch)
my $NOW = time();
my $CACHE_MTIME = (stat $CACHE)[9];
my $SKY;
my $WEATHER;
my $tmp;
my $ERR = "";
if(!$CACHE_MTIME) {
# cache is removed
# create value that will cause file re-create
$CACHE_MTIME = $NOW - $CACHE_UI - 1;
}
# 2020-10-17 $REMOTE url has changed yet again
# $data re is now failing, so we switch to $response->decoded_content
# 2020-11-19 change order to check cache timeout first
# this is to save many HEAD-checks on remote
# if cache has timed out then refresh the cache from remote
# else provide response from cache
if(($NOW - $CACHE_UI) > $CACHE_MTIME) { # cache has timed-out
# update cache from remote unless remote site unavailable
# first a HEAD request to make sure site is up
my $ua = new LWP::UserAgent;
my $req = new HTTP::Request HEAD => "$REMOTE?ids=$LOCATION";
#my $req = new HTTP::Request HEAD => "$REMOTE/$LOCATION.TXT";
my $response = $ua->request($req);
if($response->is_success) { # true; remote site is responding
# print "\$REMOTE?ids=\$LOCATION=$REMOTE?ids=$LOCATION\n";
# print $response->headers()->as_string;
# aviationweather.gov does not send Last-Modified (tsk tsk)
# tgftp.nws.noaa.gov DOES send Last-Modified
# refresh local cache from remote site
# get the remote data and find the METAR.
my $ua = new LWP::UserAgent;
my $req = new HTTP::Request GET => "$REMOTE?ids=$LOCATION";
#my $req = new HTTP::Request GET => "$REMOTE/$LOCATION.TXT";
my $response = $ua->request($req);
if($response->is_success) {
# get the data and find the METAR.
my $m = new Geo::METAR;
my $data = $response->decoded_content;
my $METAR = $data;
# my $data = $response->as_string; # grab response
# $data =~ s/\n//go; # remove newlines
# $data =~ m/($LOCATION\s\d+Z.*?)</go; # find the METAR string
# my $METAR = $1; # keep it
# Sanity check
if( length( $METAR ) < 10 ) {
die "METAR is too short! Something went wrong.";
}
# pass the data to the METAR module.
$m->metar($METAR);
# $m->dump;
#
# $m->SKY, $m->WEATHER + $m->WEATHER_LOG are arrays
# (see https://idefix.net/~koos/perl/Geo-METAR/METAR.html)
# DUMP shows 1st array, but a bug affects each individual access
my $stdout = capture_stdout { $m->dump; };
$stdout =~ /SKY: (.*)/; # find the SKY string
$SKY = $1; # keep it
$stdout =~ /WEATHER: (.*)/; # find the WEATHER string
$WEATHER = $1; # keep it
#
# Relative Humidity (RH) (accurate for RH > 50%)
# https://en.wikipedia.org/wiki/Dew_point#Simple_approximation
# 100 - 5*(TEMP_C - DEW_C)
# 100*(6.1094^((17.625*TD)/(243.04+TD))/6.1094^((17.625*T)/(243.04+T))) ??
my $RH = 100 - (5*($m->TEMP_C - $m->DEW_C));
#
# handle midnight (METAR-day may actually be yesterday):
my $DATE;
my $gmt = 1; # true
my ($year,$month,$today) = Today($gmt);
my $day = $m->DATE; # actually UTC day of month, 2-digits
if($day != $today) { # METAR-day is yesterday
($year,$month,$day) = Add_Delta_Days($year,$month,$today, -1);
$DATE = "$year-$month-$day";
} else {
$DATE = strftime "%F", gmtime; # ISO 8601 GMT/UTC date (YYYY-MM-DD, no DST)
}
$CACHE_HASH{'ALT' } = $m->ALT;
$CACHE_HASH{'ALT_HP' } = $m->ALT_HP;
$CACHE_HASH{'CSV' } = $CSV;
$CACHE_HASH{'DATE' } = $DATE;
$CACHE_HASH{'DEW_C' } = $m->DEW_C;
$CACHE_HASH{'DEW_F' } = $m->DEW_F;
$CACHE_HASH{'SKY' } = $SKY;
$CACHE_HASH{'RH' } = $RH;
$CACHE_HASH{'TEMP_C' } = $m->TEMP_C;
$CACHE_HASH{'TEMP_F' } = $m->TEMP_F;
$CACHE_HASH{'TIME' } = $m->TIME;
$CACHE_HASH{'TYPE' } = $m->TYPE;
$CACHE_HASH{'VISIBILITY' } = $m->VISIBILITY;
$CACHE_HASH{'WEATHER' } = $WEATHER;
$CACHE_HASH{'WIND_DIR_ABB'} = $m->WIND_DIR_ABB;
$CACHE_HASH{'WIND_DIR_DEG'} = $m->WIND_DIR_DEG;
$CACHE_HASH{'WIND_DIR_ENG'} = $m->WIND_DIR_ENG;
$CACHE_HASH{'WIND_KTS' } = $m->WIND_KTS;
$CACHE_HASH{'WIND_MPH' } = $m->WIND_MPH;
$CACHE_HASH{'WIND_MS' } = $m->WIND_MS;
$CACHE_HASH{'WIND_VAR' } = $m->WIND_VAR;
$CACHE_HASH{'METAR' } = $m->METAR;
# Some result array values may contain errors of indeterminate length. Each is
# checked & placed in a hash for current & future access via file.
for(keys %CACHE_HASH) {
$tmp = $CACHE_HASH{$_};
if($tmp =~ m/error/i) { $CACHE_HASH{$_} = $ERR; }
if(ref($tmp) eq "ARRAY") { $CACHE_HASH{$_} = $ERR; }
}
#print "dumping contents of \$m:\n";
#$m->dump;
#print "dump complete.\n\n";
# store $CACHE_HASH built from remote into cache
use Storable qw( nstore_fd );
use Fcntl qw(:DEFAULT :flock);
sysopen( DF, $CACHE, O_RDWR|O_CREAT, 0666)
or die "can't open $CACHE: $!";
flock( DF, LOCK_EX)
or die "can't lock $CACHE: $!";
nstore_fd( \%CACHE_HASH, *DF )
or die "can't store hash\n";
truncate( DF, tell( DF ));
close( DF );
} else { # if($response->is_success) (GET succeeded)
print $response->error_as_HTML;
my $err_msg = $response->error_as_HTML;
warn "$err_msg\n\n";
die "$!";
} # if($response->is_success) else
} # if($response->is_success) (HEAD succeeded)
} else { # if(($NOW - $CACHE_UI) > $CACHE_MTIME) cache has timed-out
# use local cache of remote site
use Storable qw( fd_retrieve );
use Fcntl qw(:DEFAULT :flock);
open(DF, "< $CACHE")
or die "can't open $CACHE: $!";
flock(DF, LOCK_SH)
or die "can't lock $CACHE: $!";
%CACHE_HASH = %{ fd_retrieve(*DF)};
close(DF);
} # if(($NOW - $CACHE_UI) > $CACHE_MTIME) else
#for(keys %CACHE_HASH) {
# print "$_ = $CACHE_HASH{$_}\n";
#}
switch ($TYPE) {
case "ALT" { print $CACHE_HASH{'ALT' };}
case "ALT_HP" { print $CACHE_HASH{'ALT_HP' };}
case "CSV" { print $CACHE_HASH{'CSV' };}
case "DATE" { print $CACHE_HASH{'DATE' };}
case "DEW_C" { print $CACHE_HASH{'DEW_C' };}
case "DEW_F" { print $CACHE_HASH{'DEW_F' };}
case "SKY" { print $CACHE_HASH{'SKY' };}
case "RH" { print $CACHE_HASH{'RH' };}
case "TEMP_C" { print $CACHE_HASH{'TEMP_C' };}
case "TEMP_F" { print $CACHE_HASH{'TEMP_F' };}
case "TIME" { print $CACHE_HASH{'TIME' };}
case "TYPE" { print $CACHE_HASH{'TYPE' };}
case "VISIBILITY" { print $CACHE_HASH{'VISIBILITY' };}
case "WEATHER" { print $CACHE_HASH{'WEATHER' };}
case "WIND_DIR_ABB" { print $CACHE_HASH{'WIND_DIR_ABB'};}
case "WIND_DIR_DEG" { print $CACHE_HASH{'WIND_DIR_DEG'};}
case "WIND_DIR_ENG" { print $CACHE_HASH{'WIND_DIR_ENG'};}
case "WIND_KTS" { print $CACHE_HASH{'WIND_KTS' };}
case "WIND_MPH" { print $CACHE_HASH{'WIND_MPH' };}
case "WIND_MS" { print $CACHE_HASH{'WIND_MS' };}
case "WIND_VAR" { print $CACHE_HASH{'WIND_VAR' };}
else { print $CACHE_HASH{'METAR' };}
} # switch ($TYPE)
exit;
__END__
Last edited by alexkemp (2023-12-03 23:06:33)
Offline
Redundant post, issue solved, conserving site resources.
Last edited by greenjeans (2023-12-06 01:44:23)
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
FYI MATE weather (part of the clock preferences) doesn't work and hasn't in some time
I appreciate that you haven't read all the scripts.
What I've posted *does* work, and all in one call. I do NOT use the CONKY calls. I've written my own PERL script and that collects all stats in one call, put them into a cache, and then collects from the cache on every call until refreshed.
Offline
Redundant post, issue solved, conserving site resources.
Last edited by greenjeans (2023-12-06 01:44:52)
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
Oh and while talking conky, another little tidbit:
I use the Exaile music player, it's my favorite, not too complex, does internet radio and seamlessly integrates with streamripper. It's not in the repo so i'm likely the only user, lol, but if you do, it works with conky, it's not on the list of music/media players that conky works with, but it does work. Here's my lines, all I want it to do is display artist name and track but i'm sure you could add more if desired:
${if_running exaile}${font BankGothic Md BT:pixelsize=14}now playing : ${execi 10 exaile --get-title} – ${execi 10 exaile --get-artist}$endif
I put it at the bottom of the display, since when it's not running that line closes up to the one above, if you stick it between sections somewhere it has to add a new line and that freaks conky out sometimes.
Last edited by greenjeans (2023-12-04 01:13:26)
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
Hint: "\n" means newline.
$ curl wttr.in/Miner?format="Condition:+%C\nTemperature:+%t\n"
Condition: Overcast
Temperature: -2°C
Offline
Redundant post, issue solved, conserving site resources.
Last edited by greenjeans (2023-12-06 01:45:17)
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
Redundant post, issue solved, conserving site resources.
Last edited by greenjeans (2023-12-06 01:46:01)
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
Thanks nixer, that's good news!
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline
Offline
Updated original post to detail the solution.
https://sourceforge.net/projects/vuu-do/
Vuu-do GNU/Linux, minimal Devuan-based openbox systems to build on, maximal versions if you prefer your linux fully-loaded.
Please donate to support Devuan and init freedom! https://devuan.org/os/donate
Offline