FreeBSD Desktop – Part 11 – Key Components – Blue Light Spectrum Suppress
FreeBSD Desktop – Part 11 – Key Components – Blue Light Spectrum Suppress

			In the Part 11 of the FreeBSD Desktop series I would like to describe key components of self made custom desktop environment such as:

Window Manager
Status Bar
Task Bar
Wallpaper Handling
Application Launcher
Keyboard/Mouse Shortcuts
Locking Solution
Blue Light Spectrum Suppress

Today we will focus on the Blue Light Spectrum Suppress component. In the next series each of these components configuration would also be described along with eventual needed scripts.

You may want to check other articles in the FreeBSD Desktop series on the FreeBSD Desktop – Global Page where you will find links to all episodes of the series along with table of contents for each episode’s contents.
Latest versions of popular operating systems like Mac OS X (macOS) and Windows (or up-to-date Android based devices) already provide a feature to automatically adjusts color temperature of the screen according to your current time in your location. In short when then Sun is up the color temperature should be closer to about 5500K and when the Sun is down (evening/night) it should be around 3700K.
If You have never heard about Circadian Rhythm then check Wikipedia page for details. Basically its kind of 24 hour internal clock that is runs in the background of your brain and switches between sleepiness and alertness at regular intervals, also known as sleep/awake cycle.
Light, and especially temperature of this light, directly affects this cycle, if You use blue spectrum light when the Sun is down, then You are disrupting the Circadian Rhythm, to cite Wikipedia – “Studies have also shown that light has a direct effect on human health because of the way it influences the circadian rhythms.” and also – “Blue LED lighting suppresses melatonin production five times more than the orange-yellow high-pressure sodium (HPS) light.” If your body produces melatonin, then you become more sleepy, if something it preventing that production – like blue light spectrum – then you are not getting sleepy and Circadian Rhythm gets broken.
When You put two images side by side, one with about 3700K color temperature and one with about 5500K color temperature you will be able to spot the difference between them, but the tools that manage these temperatures make transition smooth and unwatchable, only if you kill the application in the night/evening you will be able to spot the difference.
Daily temperature.

Nightly temperature.

I know two tools that resolve that problem on X11 environment:

F.lux (closed source) – https://justgetflux.com/
Redshift (open source) – http://jonls.dk/redshift/

F.lux
Why would you want to run closed source software while You can use open source and it does the same thing? Personally I use Redshift but I want to mention F.lux here as Redshift project itself admits that their program is inspired by F.lux.
To cite the F.lux page it “makes the color of your computer’s display adapt to the time of day, warm at night and like sunlight during the day.”
While F.lux does not provide a native binary for FreeBSD it does offer such binary for Linux and as FreeBSD provides Linux Binary Compatibility its possible to use it on FreeBSD. That Linux binary of F.lux is available to download as tar archive xflux.tgz from the https://justgetflux.com/linux.html page.
Here is how it looks under FreeBSD.
% uname -mro
FreeBSD 11.2-RELEASE amd64

% file ~/scripts/bin/xflux
/home/vermaden/xflux: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.15, BuildID[sha1]=0b2094d4f1fd64100ceba2f61a7ff606f6f1cc8c, not stripped

To use F.lux just start it in the ~/.xinitrc or ~/.xsession file like that.
~/path/to/bin/xflux -l 33.54321 -g 11.12345 &

Of course 33.54321 is latitude and 11.12345 is longitude of your localization.
Redshift
This is the solution that I propose to use as open source blue light spectrum suppressor. To cite the project site “Redshift adjusts the color temperature of your screen according to your surroundings.”
Similarly like with the F.lux to start Redshift just put it in the ~/.xinitrc or ~/.xsession file like that.
% redshift -l 33.54321:11.12345 -g 0.9 &

Like earlier 33.54321 is latitude and 11.12345 is longitude of your localization.
Difference
How one can tell the difference with or without using application that suppress blue light spectrum when the Sun is down? You will not be able to tell the difference instantly, but leave it enabled and think about that a month later.
When I did not used such app I was able to choose to stay up and do something till very late, like go to sleep at 3:00 AM for example or I could choose to ‘make good sleep’ and go to bed at about 0:00. After I started to use such application (first F.lux and lately Redshift) I become sleepy/tired at about 23:30 and its harder to stay up late. I think that my sleep become better and overall ‘attitude/awareness/energy/…’ are better now, but your millage may vary, check it for yourself.
UPDATE 1 – The sctd Daemon
Some people suggested using sct for lighter way of setting up the color temperature. Its is indeed lighter but it does not do ‘transparent’ transition between day and night mode as for example redshift does.
Someone else suggested trying sctd which is sct but rewritten/modified to be a daemon that will automatically change the color temperature during the day (or night).
The sct is available in the FreeBSD Ports as accessibility/sct but sctd it is not.
Below I will show you how to build it from source.
TL;DR
Not all people have time for my long boring stories so this is meritum of this article.
# pkg install -y rust wget
% wget https://github.com/amir/sctd/archive/0.2.0.tar.gz
% tar -xzf 0.2.0.tar.gz
% cd sctd-0.2.0
% cargo build
% cargo install --path .
% ~/.cargo/bin/sctd -h

Whole Story
The sctd is hosted on GitHub so we will take sources from there. We will also need Rust to built it.
# pkg install -y rust wget
% wget https://github.com/amir/sctd/archive/0.2.0.tar.gz
% tar -xzvf 0.2.0.tar.gz
x sctd-0.2.0/
x sctd-0.2.0/.github/
x sctd-0.2.0/.github/workflows/
x sctd-0.2.0/.github/workflows/release.yml
x sctd-0.2.0/.gitignore
x sctd-0.2.0/Cargo.lock
x sctd-0.2.0/Cargo.toml
x sctd-0.2.0/LICENSE
x sctd-0.2.0/README.md
x sctd-0.2.0/src/
x sctd-0.2.0/src/bin/
x sctd-0.2.0/src/bin/sctd.rs
x sctd-0.2.0/src/lib.rs
% cd sctd-0.2.0
% cargo build

This is how it looks on the screen.

We will now install it into the /home/vermaden/.cargo/bin directory.
% cargo install --path .
% file /home/vermaden/.cargo/bin/sctd | tr ',' '\n'
/home/vermaden/.cargo/bin/sctd: ELF 64-bit LSB pie executable
 x86-64
 version 1 (FreeBSD)
 dynamically linked
 interpreter /libexec/ld-elf.so.1
 for FreeBSD 12.2
 FreeBSD-style
 with debug_info
 not stripped
% /home/vermaden/.cargo/bin/sctd --help
sctd 0.2.0
set color temperature daemon

USAGE:
    sctd [FLAGS] [OPTIONS]

FLAGS:
    -h, --help       Prints help information
        --reset      
    -V, --version    Prints version information

OPTIONS:
        --latitude       
        --longitude     

Here is the install process.

As suggested by cargo you may want to either put that sctd binary to a directory that is already in your ${PATH} or add /home/vermaden/.cargo/bin dir to your ${PATH} shell variable.
To run it start it like that.
% sctd --latitude 51.80 --longitude 19.60
[2020-11-17T12:45:38Z INFO  sctd] setting temperature to 5500

Lets see how sctd compares to redshift in the memory usage.
% ps aux | grep -E 'RSS|redshift|sctd' | grep -v grep
USER       PID  %CPU %MEM      VSZ    RSS TT  STAT STARTED        TIME COMMAND
vermaden  7594   0.0  0.0    14812   5280  6  S+   13:46       0:00.01 sctd --latitude 51.80 --longitude 19.60
vermaden  7112   0.0  0.0    18000   7576  7  S+   13:46       0:00.08 redshift -l 51.80:19.60 -g 0.9

Not a big difference. The sctd daemon consumes about 5 MB RAM while redshit uses 7 MB RAM.
Lets compare the dependencies now. First the small sctd daemon. It has 11 dependencies as shown below by ldd(1) command. The total size of these dependencies is less then 1.5 MB. Of course is ‘stupid’ to calculate it like that because sctd daemon may only need one or two functions from each of those libraries but we will do it anyway 🙂
% ldd sctd
sctd:
	libX11.so.6 => /usr/local/lib/libX11.so.6 (0x80114d000)
	libXrandr.so.2 => /usr/local/lib/libXrandr.so.2 (0x801296000)
	libthr.so.3 => /lib/libthr.so.3 (0x8012a3000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x8012d0000)
	libc.so.7 => /lib/libc.so.7 (0x8012ea000)
	libm.so.5 => /lib/libm.so.5 (0x8016e0000)
	libxcb.so.1 => /usr/local/lib/libxcb.so.1 (0x801712000)
	libXext.so.6 => /usr/local/lib/libXext.so.6 (0x80173f000)
	libXrender.so.1 => /usr/local/lib/libXrender.so.1 (0x801753000)
	libXau.so.6 => /usr/local/lib/libXau.so.6 (0x801760000)
	libXdmcp.so.6 => /usr/local/lib/libXdmcp.so.6 (0x801765000)

% ldd sctd | sed 1d | awk '{print $3}' | xargs du -skc
1	/usr/local/lib/libX11.so.6
1	/usr/local/lib/libXrandr.so.2
73	/lib/libthr.so.3
61	/lib/libgcc_s.so.1
1169	/lib/libc.so.7
145	/lib/libm.so.5
1	/usr/local/lib/libxcb.so.1
1	/usr/local/lib/libXext.so.6
1	/usr/local/lib/libXrender.so.1
1	/usr/local/lib/libXau.so.6
1	/usr/local/lib/libXdmcp.so.6
1450	total


Now lets see how redshift compares. It uses 19 libraries but sum of all these libraries space is also less then 1.5 MB in size as shown below.
% ldd redshift 
redshift:
	libintl.so.8 => /usr/local/lib/libintl.so.8 (0x80025b000)
	libdrm.so.2 => /usr/local/lib/libdrm.so.2 (0x800269000)
	libwayland-client.so.0 => /usr/local/lib/libwayland-client.so.0 (0x800280000)
	libxcb.so.1 => /usr/local/lib/libxcb.so.1 (0x800292000)
	libxcb-randr.so.0 => /usr/local/lib/libxcb-randr.so.0 (0x8002bf000)
	libgio-2.0.so.0 => /usr/local/lib/libgio-2.0.so.0 (0x8002d1000)
	libgobject-2.0.so.0 => /usr/local/lib/libgobject-2.0.so.0 (0x80049e000)
	libglib-2.0.so.0 => /usr/local/lib/libglib-2.0.so.0 (0x8004f5000)
	libm.so.5 => /lib/libm.so.5 (0x80062b000)
	libthr.so.3 => /lib/libthr.so.3 (0x80065d000)
	libc.so.7 => /lib/libc.so.7 (0x80068a000)
	libepoll-shim.so.0 => /usr/local/lib/libepoll-shim.so.0 (0x800a80000)
	libffi.so.7 => /usr/local/lib/libffi.so.7 (0x800a8c000)
	libXau.so.6 => /usr/local/lib/libXau.so.6 (0x800a98000)
	libXdmcp.so.6 => /usr/local/lib/libXdmcp.so.6 (0x800a9d000)
	libgmodule-2.0.so.0 => /usr/local/lib/libgmodule-2.0.so.0 (0x800aa4000)
	libz.so.6 => /lib/libz.so.6 (0x800aab000)
	libpcre.so.1 => /usr/local/lib/libpcre.so.1 (0x800ac7000)
	libiconv.so.2 => /usr/local/lib/libiconv.so.2 (0x800b6a000)

% ldd redshift | sed 1d | awk '{print $3}' | xargs du -skc
1	/usr/local/lib/libintl.so.8
1	/usr/local/lib/libdrm.so.2
1	/usr/local/lib/libwayland-client.so.0
1	/usr/local/lib/libxcb.so.1
1	/usr/local/lib/libxcb-randr.so.0
1	/usr/local/lib/libgio-2.0.so.0
1	/usr/local/lib/libgobject-2.0.so.0
1	/usr/local/lib/libglib-2.0.so.0
145	/lib/libm.so.5
73	/lib/libthr.so.3
1169	/lib/libc.so.7
25	/usr/local/lib/libepoll-shim.so.0
1	/usr/local/lib/libffi.so.7
1	/usr/local/lib/libXau.so.6
1	/usr/local/lib/libXdmcp.so.6
1	/usr/local/lib/libgmodule-2.0.so.0
69	/lib/libz.so.6
1	/usr/local/lib/libpcre.so.1
1	/usr/local/lib/libiconv.so.2
1486	total

By all measures the sctd daemon is smaller, it uses smaller amount of RAM memory, uses less libraries and size of these libraries is smaller then what redshfit needs.
The only (temporary) drawback sctd has is that is not available in FreeBSD Ports but as you have seen above it requires only several easy commands to build it.
Its not up to me to force you into any of these solutions. Find the one that works best for you and use it.
Regards.
UPDATE 2 – The sctd Daemon is Now in FreeBSD Ports
I have good news. The sctd daemon – as reported by @mpts from mastodon.social – has just been added to the FreeBSD Ports tree as accessibility/sctd port.
It will take little less then quarter for ‘quarterly’ packages branch and and less then a week for its package appear in the ‘latest’ pkg(8) branch.
Enjoy.
EOF
					