The officially official Devuan Forum!

You are not logged in.

#101 Re: News & Announcements » The dev1galaxy.org (almost) No Code of Conduct » 2024-01-09 15:22:32

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".

#102 Re: News & Announcements » The dev1galaxy.org (almost) No Code of Conduct » 2024-01-09 10:57:04

Perhaps

Responsible behaviour based on a foundation of mutual respect is expected from visitors to this forum.

#103 Re: Other Issues » [SOLVED] Software MGR Doesn't Update Software & Software Isn't Found » 2024-01-09 10:46:08

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

#104 Re: Other Issues » [SOLVED] Software MGR Doesn't Update Software & Software Isn't Found » 2024-01-08 09:37:42

Aliz24 wrote:

$ 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?

#105 Re: Other Issues » [SOLVED] Software MGR Doesn't Update Software & Software Isn't Found » 2024-01-08 00:41:38

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

#106 Re: Other Issues » [SOLVED] Software MGR Doesn't Update Software & Software Isn't Found » 2024-01-07 21:40:57

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

#107 Re: Desktop and Multimedia » [Solved] xarchiver 0.5.4.14 issue » 2024-01-06 16:36:37

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.

#108 Re: Installation » [SOLVED] Fresh Installation of Devuan Wifi Not Working & Grub Issue » 2024-01-03 12:46:44

@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.

#109 Re: Other Issues » [SOLVED] How to fix unicode text, it's showing as a box » 2024-01-03 12:37:55

quickfur wrote:

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.

#110 Re: Other Issues » [SOLVED] How to fix unicode text, it's showing as a box » 2024-01-01 14:18:38

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.

#111 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-14 04:46:27

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) ...

#112 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-14 04:37:16

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.

#113 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-14 04:25:42

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]

#114 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-14 04:16:38

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>

#115 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-14 04:04:09

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)

#116 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-13 03:45:03

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.

#117 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-13 00:14:13

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?

#118 Re: Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-11 15:34:09

$ 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!

#119 Other Issues » [SOLVED] Problem with ca-certificates-java » 2023-12-10 08:54:18

alexkemp
Replies: 12

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.

#121 Re: DIY » [SOLVED] Weather display in conky, a simple one-line-of-code solution » 2023-12-03 23:11:29

greenjeans wrote:

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.

#122 Re: DIY » [SOLVED] Weather display in conky, a simple one-line-of-code solution » 2023-12-03 22:46:08

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__

#123 Re: DIY » [SOLVED] Weather display in conky, a simple one-line-of-code solution » 2023-12-03 22:32:46

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

#124 Re: DIY » [SOLVED] Weather display in conky, a simple one-line-of-code solution » 2023-12-03 22:17:04

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

#125 Re: Off-topic » USA Foods » 2023-12-02 02:46:54

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.

A Kernel of Wheat

3 parts make up a kernel of wheat:

  1. 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.

  2. 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).

  3. 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.

Board footer

Forum Software