You are not logged in.
I like boughtonp's 2nd one better. For some reason "adult" reads sour in my eyes. Perhaps it's because of terms such as "adult films".
Perhaps
Responsible behaviour based on a foundation of mutual respect is expected from visitors to this forum.
Your sources differ slightly from what is advised (missing non-free). I have zero idea how important that may be, but for the record (and thanks for the inxi snippet):
$ head -5 /etc/apt/sources.list
deb http://deb.devuan.org/merged daedalus main non-free-firmware non-free contrib
deb http://deb.devuan.org/merged daedalus-updates main non-free-firmware non-free contrib
deb http://deb.devuan.org/merged daedalus-security main non-free-firmware non-free contrib
deb http://deb.devuan.org/merged daedalus-proposed-updates main non-free-firmware non-free contrib
deb http://deb.devuan.org/merged daedalus-backports main non-free-firmware non-free contrib
If you are *really* paranoid, don't try this one:
$ grep ^[^#] /etc/apt/sources.list /etc/apt/sources.list.d/*
/etc/apt/sources.list:deb http://deb.devuan.org/merged daedalus main non-free-firmware non-free contrib
/etc/apt/sources.list:deb http://deb.devuan.org/merged daedalus-updates main non-free-firmware non-free contrib
/etc/apt/sources.list:deb http://deb.devuan.org/merged daedalus-security main non-free-firmware non-free contrib
/etc/apt/sources.list:deb http://deb.devuan.org/merged daedalus-proposed-updates main non-free-firmware non-free contrib
/etc/apt/sources.list:deb http://deb.devuan.org/merged daedalus-backports main non-free-firmware non-free contrib
/etc/apt/sources.list.d/josm.list:deb https://josm.openstreetmap.de/apt/ alldist universe
$ inxi -b
Gimp did not appear in my Menu at all
In that case your sources.list is broken.
What's your problem with using neofetch or inxi?
Here's an alternative information gatherer; also operated from a terminal; show results from one of these & others will understand better your system & be able to give better help & advice:
$ inxi -b
System:
Host: ng3 Kernel: 6.1.0-17-amd64 arch: x86_64 bits: 64 Desktop: Xfce
v: 4.18.1 Distro: Devuan GNU/Linux 5 (daedalus)
Machine:
Type: Desktop System: LENOVO product: 90BJ008CUK v: Lenovo H30-05
serial: <superuser required>
Mobo: LENOVO model: N/A v: SDK0J40700 WIN serial: <superuser required>
UEFI: LENOVO v: O1WKT25AUS date: 10/29/2015
CPU:
Info: quad core AMD A8-7410 APU with AMD Radeon R5 Graphics [MCP]
speed (MHz): avg: 999 min/max: 1000/2200
Graphics:
Device-1: AMD Mullins [Radeon R4/R5 Graphics] driver: radeon v: kernel
Display: x11 server: X.Org v: 1.21.1.7 driver: X: loaded: radeon
unloaded: fbdev,modesetting,vesa dri: radeonsi gpu: radeon
resolution: 1366x768~60Hz
API: OpenGL v: 4.5 Mesa 22.3.6 renderer: KABINI ( LLVM 15.0.6 DRM 2.50
6.1.0-17-amd64)
Network:
Device-1: Qualcomm Atheros QCA9565 / AR9565 Wireless Network Adapter
driver: ath9k
Device-2: Realtek RTL810xE PCI Express Fast Ethernet driver: r8169
Drives:
Local Storage: total: 931.51 GiB used: 785.39 GiB (84.3%)
Info:
Processes: 200 Uptime: 3d 13h 58m Memory: 7.18 GiB used: 2.89 GiB (40.2%)
Shell: Bash inxi: 3.3.26
What exactly is this "Software Manager" that you are talking about? There are so many variations for Daedalus that it is almost impossible to know what you are talking about unless you specify things exactly. Here is a way for you to do some of that:
Open a terminal & type the following (you may need to do a $ sudo apt install neofetch first) (the '$' assumes that you are using a non-root terminal; if sudo is not installed on your system and/or you do not know how to use it, you will need to become root to install anything since all such operations require you to be root). Copy the results & post them in a [ code ] block here:
$ neofetch
..,,;;;::;,.. alexk@ng3
`':ddd;:,. ---------
`'dPPd:,. OS: Devuan GNU/Linux 5 (daedalus) x86_64
`:b$$b`. Model: 90BJ008CUK Lenovo H30-05
'P$$$d` Kernel: 6.1.0-17-amd64
.$$$$$` Uptime: 3 days, 10 hours, 49 mins
;$$$$$P Packages: 3068 (dpkg)
.:P$$$$$$` Shell: bash 5.2.15
.,:b$$$$$$$;' Resolution: 1366x768
.,:dP$$$$$$$$b:' DE: Xfce 4.18
.,:;db$$$$$$$$$$Pd'` WM: Xfwm4
,db$$$$$$$$$$$$$$b:'` WM Theme: Default
:$$$$$$$$$$$$b:'` Theme: Clearlooks-Phenix-Sapphire [GTK2]
`$$$$$bd:''` Icons: oxygen [GTK2]
`'''` Terminal: xfce4-terminal
Terminal Font: Monospace 12
CPU: AMD A8-7410 APU with AMD Radeon R5 Graphics (4) @ 2.200GHz
GPU: AMD ATI Radeon R4/R5 Graphics
Memory: 2542MiB / 7356MiB
What's wrong with 7z ('7-Zip') (Website / Wiki)? Teeny tiny and with the best compression on the 'net. Downside is that it does not do any encryption, nor even store Linux file attributes. What you have to do is store as "file.tar.7z" (like gzip, but a separate tar operation, then 7-zip it). Y'know, small apps that each do one thing, chained together. The Linux way.
@Aliz24:
Stop full-post quoting. It is damn annoying, and especially when there are only two of you in the thread.
Refer to this sticky for more info.
Interesting, on my browser it's showing up as rendered from a Chinese font (fonts-wqy-zenhei)./
Further down the page, under "Preview", it is shown rendered under Times New Roman, Arial & Courier New. No problems with any of that on my system.
As you have discovered, it is blooming hard to be able to identify the precise reason for your kind of problem. The reason for that is the web of inter-connecting processes & config files that can lead to a problem.
Even fixing locale problems can be a nightmare. To get a fuller picture of that, look at this Debian Wiki page on Locales. Here's my default locale ($LANG) + all available locales (locale -a in my system):
$ echo $LANG
en_GB.UTF-8
$ locale -a
C
C.utf8
en_GB.utf8
POSIX
The classic situation for your issue is that someone has a C-locale but is trying to print/show non-ASCII characters. However, you appear to have a suitable locale (en_US.UTF-8), but is your file manager (caja) using a utf8 font for display characters? This forum thread suggests that the font is chosen by your DM in a similar manner to Thunar.
We now know your FM (caja) but have zero idea of your DM.
I use XFCE 4.18 as my DM (it describes itself as a "Desktop Environment") and Thunar as the FM. Changing the font is made via menu:Settings | Appearance. At "Style" I discover that all of the XFCE settings are in GTK3 (which gives yet another place where fonts may be set)). The fonts tab allows both the default font + the size to be changed (menu:Settings | File Manager Settings does not have any font settings available, and neither does menu:Settings | Settings Editor | thunar).
So, I cannot give a definitive answer, but hopefully the info given gets you one step closer to a solution.
OK, done it.
Removing all openjdk-8 packages allowed the certificates to auto-update & be auto-removed from being held back. Now to find what is hiding that needs those jdk-8 packages!
$ sudo apt-get remove openjdk-8-*
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'openjdk-8-doc' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jdk' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jre' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-demo' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jre-headless' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-source' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jdk-headless' for glob 'openjdk-8-*'
Package 'openjdk-8-demo' is not installed, so not removed
Package 'openjdk-8-source' is not installed, so not removed
The following packages will be REMOVED:
openjdk-8-doc openjdk-8-jdk openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless
0 upgraded, 0 newly installed, 5 to remove and 1 not upgraded.
After this operation, 432 MB disk space will be freed.
Do you want to continue? [Y/n] Y
(Reading database ... 285417 files and directories currently installed.)
Removing openjdk-8-doc (8u252-b09-1~deb9u1) ...
Removing openjdk-8-jdk:amd64 (8u252-b09-1~deb9u1) ...
Removing openjdk-8-jdk-headless:amd64 (8u252-b09-1~deb9u1) ...
Removing openjdk-8-jre:amd64 (8u252-b09-1~deb9u1) ...
Removing openjdk-8-jre-headless:amd64 (8u252-b09-1~deb9u1) ...
Processing triggers for hicolor-icon-theme (0.17-2) ...
Processing triggers for doc-base (0.11.1) ...
Processing 1 removed doc-base file...
Processing triggers for libc-bin (2.36-9+deb12u3) ...
Processing triggers for ca-certificates-java (20230620~deb12u1) ...
done.
Processing triggers for mailcap (3.70+nmu1) ...
Processing triggers for desktop-file-utils (0.26-1) ...
$ ~/.local/sbin/update
Get:1 https://josm.openstreetmap.de/apt alldist InRelease [5,606 B]
Get:2 https://josm.openstreetmap.de/apt alldist/universe amd64 Packages [1,097 B]
Hit:3 http://deb.devuan.org/merged daedalus InRelease
Get:4 http://deb.devuan.org/merged daedalus-updates InRelease [32.5 kB]
Get:5 http://deb.devuan.org/merged daedalus-security InRelease [32.5 kB]
Get:6 http://deb.devuan.org/merged daedalus-proposed-updates InRelease [32.7 kB]
Get:7 http://deb.devuan.org/merged daedalus-backports InRelease [32.6 kB]
Fetched 137 kB in 3s (53.1 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
2 packages can be upgraded. Run 'apt list --upgradable' to see them.
W: https://josm.openstreetmap.de/apt/dists/alldist/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
ca-certificates-java josm-latest
2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 15.9 MB of archives.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://deb.devuan.org/merged daedalus/main amd64 ca-certificates-java all 20230710~deb12u1 [11.9 kB]
Get:2 https://josm.openstreetmap.de/apt alldist/universe amd64 josm-latest all 1.5.svn18911 [15.9 MB]
Fetched 15.9 MB in 5s (3,520 kB/s)
Reading changelogs... Done
(Reading database ... 272305 files and directories currently installed.)
Preparing to unpack .../ca-certificates-java_20230710~deb12u1_all.deb ...
Unpacking ca-certificates-java (20230710~deb12u1) over (20230620~deb12u1) ...
Preparing to unpack .../josm-latest_1.5.svn18911_all.deb ...
Unpacking josm-latest (1.5.svn18911) over (1.5.svn18907) ...
Setting up josm-latest (1.5.svn18911) ...
Setting up ca-certificates-java (20230710~deb12u1) ...
done.
Processing triggers for mailcap (3.70+nmu1) ...
Processing triggers for desktop-file-utils (0.26-1) ...
Processing triggers for hicolor-icon-theme (0.17-2) ...
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for shared-mime-info (2.2-1) ...
Processing triggers for menu (2.1.49) ...
OK. I now believe it (should be) safe to remove all 1.8 java versions:
$ java -version
openjdk version "17.0.9" 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+9-Debian-1deb12u1)
OpenJDK 64-Bit Server VM (build 17.0.9+9-Debian-1deb12u1, mixed mode, sharing)
$ update-java-alternatives -l
java-1.11.0-openjdk-amd64 1111 /usr/lib/jvm/java-1.11.0-openjdk-amd64
java-1.17.0-openjdk-amd64 1711 /usr/lib/jvm/java-1.17.0-openjdk-amd64
java-1.8.0-openjdk-amd64 1081 /usr/lib/jvm/java-1.8.0-openjdk-amd64
Will removing them allow the certificates to be upgraded? Hey ho.
Well, it *seems* that removing them all will have zero side-effects. I wonder if that is actually accurate?
$ apt-get remove -s openjdk-8-*
NOTE: This is only a simulation!
apt-get needs root privileges for real execution.
Keep also in mind that locking is deactivated,
so don't depend on the relevance to the real current situation!
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'openjdk-8-doc' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jdk' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jre' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-demo' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jre-headless' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-source' for glob 'openjdk-8-*'
Note, selecting 'openjdk-8-jdk-headless' for glob 'openjdk-8-*'
Package 'openjdk-8-demo' is not installed, so not removed
Package 'openjdk-8-source' is not installed, so not removed
The following packages will be REMOVED:
openjdk-8-doc openjdk-8-jdk openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless
0 upgraded, 0 newly installed, 5 to remove and 1 not upgraded.
Remv openjdk-8-doc [8u252-b09-1~deb9u1]
Remv openjdk-8-jdk [8u252-b09-1~deb9u1]
Remv openjdk-8-jdk-headless [8u252-b09-1~deb9u1]
Remv openjdk-8-jre [8u252-b09-1~deb9u1]
Remv openjdk-8-jre-headless [8u252-b09-1~deb9u1]
Looks like the single package is the certificates, so I should be safe (?) to remove all the -8:
$ apt-cache rdepends --installed openjdk-8-*
openjdk-8-jre-headless
Reverse Depends:
openjdk-8-jre
openjdk-8-jdk-headless
openjdk-8-jre
openjdk-8-jdk-headless
openjdk-8-jdk-headless
ca-certificates-java
openjdk-8-jre
Reverse Depends:
openjdk-8-jdk
openjdk-8-doc
Reverse Depends:
openjdk-8-jdk
Reverse Depends:
openjdk-8-jdk-headless
openjdk-8-doc
openjdk-8-jdk-headless
Reverse Depends:
openjdk-8-jdk
<openjdk-8-demo>
<openjdk-8-source>
Good point, delgado; there is also both -11 and -17. What on earth is -8 doing in there (or, indeed, -11)?
$ apt list --installed | grep openjdk
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
openjdk-11-jre-headless/now 11.0.20+8-1~deb11u1 amd64 [installed,local]
openjdk-11-jre/now 11.0.20+8-1~deb11u1 amd64 [installed,local]
openjdk-17-jre-headless/stable,stable-security,now 17.0.9+9-1~deb12u1 amd64 [installed,automatic]
openjdk-17-jre/stable,stable-security,now 17.0.9+9-1~deb12u1 amd64 [installed,automatic]
openjdk-8-doc/now 8u252-b09-1~deb9u1 all [installed,local]
openjdk-8-jdk-headless/now 8u252-b09-1~deb9u1 amd64 [installed,local]
openjdk-8-jdk/now 8u252-b09-1~deb9u1 amd64 [installed,local]
openjdk-8-jre-headless/now 8u252-b09-1~deb9u1 amd64 [installed,local]
openjdk-8-jre/now 8u252-b09-1~deb9u1 amd64 [installed,local]
(I'm trying to find how to find what reverse-depends on it)
I'm going to wait for the changes in Debian to feed-through to Devuan. That way I do not need to pollute my already-complex sources-list.
Thanks for the suggestion. The result is identical:
# apt dist-upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be REMOVED:
openjdk-8-jdk openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless
The following packages will be upgraded:
ca-certificates-java
1 upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
Need to get 11.9 kB of archives.
After this operation, 142 MB disk space will be freed.
Do you want to continue? [Y/n] n
Abort.
Does anyone know the way to proceed in a case like this?
$ inxi -b
System:
Host: ng3 Kernel: 6.1.0-15-amd64 arch: x86_64 bits: 64 Desktop: Xfce
v: 4.18.1 Distro: Devuan GNU/Linux 5 (daedalus)
Machine:
Type: Desktop System: LENOVO product: 90BJ008CUK v: Lenovo H30-05
serial: <superuser required>
Mobo: LENOVO model: N/A v: SDK0J40700 WIN serial: <superuser required>
UEFI: LENOVO v: O1WKT25AUS date: 10/29/2015
CPU:
Info: quad core AMD A8-7410 APU with AMD Radeon R5 Graphics [MCP]
speed (MHz): avg: 999 min/max: 1000/2200
Graphics:
Device-1: AMD Mullins [Radeon R4/R5 Graphics] driver: radeon v: kernel
Display: x11 server: X.Org v: 1.21.1.7 driver: X: loaded: radeon
unloaded: fbdev,modesetting,vesa dri: radeonsi gpu: radeon
resolution: 1366x768~60Hz
API: OpenGL v: 4.5 Mesa 22.3.6 renderer: KABINI ( LLVM 15.0.6 DRM 2.50
6.1.0-15-amd64)
Network:
Device-1: Qualcomm Atheros QCA9565 / AR9565 Wireless Network Adapter
driver: ath9k
Device-2: Realtek RTL810xE PCI Express Fast Ethernet driver: r8169
Drives:
Local Storage: total: 931.51 GiB used: 785.08 GiB (84.3%)
Info:
Processes: 218 Uptime: 50m Memory: 7.18 GiB used: 2.5 GiB (34.8%)
Shell: Bash inxi: 3.3.26
Seems maybe due to bad interaction between openjdk-8-jdk & the certificates. I have backports included, and that may be a causation. This is what happens if I try to update them:
$ sudo apt install ca-certificates-java
...
The following packages will be REMOVED:
openjdk-8-jdk openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless
The following packages will be upgraded:
ca-certificates-java
1 upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
Need to get 11.9 kB of archives.
After this operation, 142 MB disk space will be freed.
Do you want to continue? [Y/n] n
Abort.
Here a 9 Dec post for Bookworm saying is fixed. I'm not certain how to proceed!
System upgrade for me just now, and mostly involved Chromium. However, a message that one is kept back:
The following packages have been kept back:
ca-certificates-java
The following packages will be upgraded:
chromium chromium-common chromium-l10n chromium-sandbox linux-compiler-gcc-12-x86 linux-kbuild-6.1 linux-libc-dev
7 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
I'm not fully certain what is happening here, but suspect the problem has arisen at Debian's end.
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.
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__
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
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
Interesting USA-predominant history lesson:
As industrialisation got it's feet under the human table, the ability to extract "roughage" from wheat & other foods lead to an easy labour-free separation of the different parts of the kernel. That started during the Industrial Revolution, became dominant from the end of the 18th Century through to the 1920s/30s & lead to the dominance of white bread amongst many other foods. This fact plays a huge part in America's weight crisis, bad health & all the rest of it.
3 parts make up a kernel of wheat:
Endosperm
That is the floury middle of each kernel, and the principal part (83%) of the kernel & the source of white flour. It was the industrial ability to reliably remove the other two parts of the kernel from the Endosperm - which other bits could then be sold as animal feed - that lead to the dominance of white flour.
Bran
This is the woody part of the kernel which also results in whole-grain flour being much darker. It is about 14.5% of the whole kernel. Our bodies find this part much harder to digest, and that actually leads to a healthier gut (white bread is digested far too quickly).
Germ
This is the bit that is supposed to grow a new plant. It is only about 2.5% of the kernel weight, but contains a lot of fat.