blueshift -- The grand unified dynamic colour adjustment framework
******************************************************************

Copyright © 2014 Mattias Andrée

     Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''.

Overview
********

Inspired by Redshift, Blueshift adjusts the colour temperature of your monitor according to brightness outside to reduce eye strain and make it easier to fall asleep when going to bed. It can also be used to increase the colour temperature and make the monitor bluer, this helps you focus on your work.

Blueshift is not user friendly and it is not meant to be. Blueshift does offer limited use of command line options to apply settings, but it is really meant for you to have configuration files (written in Python 3) where all the policies are implemented, Blueshift is only meant to provide the mechanism for modifying the colour curves. Blueshift neither provides any means of automatically getting your geographical position; the intention is that you should implement that in the policy yourself using library which can do that. Additionally Blueshift provides not safe guards from making your screen unreadable or otherwise miscoloured; and Blueshift will never, officially, add support specifically for any proprietary operating system. Blueshift is fully extensible so it is possible to make extensions that make it usable under unsupported systems, the base code is written in Python 3 without calls to any system dependent functions. If Blueshift does not work for you for any of these reasons, you should take a look at Redshift.

Invoking
********

Blueshift uses argparser to read options from the commnad line. It inherits a few properaties from this: abbreviations are supported, you only need to type the beginning of the long options so that the rest can be filled in unambiguously by the program; -- can be used, as usual, to make all following options being parsed as just arguments; and ++ works like --, except it only allied to the next option. Any argument that is not parsed as an option for Blueshift is passed onto the configuration script.

Blueshift recognises the following options:

-c
--configurations FILE
     Select configuration script. This defaults to the first file of the following the exists:

       * $XDG_CONFIG_HOME/blueshift/blueshiftrc

       * $HOME/.config/blueshift/blueshiftrc

       * $HOME/.blueshiftrc

       * /etc/blueshiftrc

     Blueshift does not check the user home, rather it checks HOME which should be the user home, unless you change it yourself.

     You update the configuration file you can send a SIGUSR1 signal to reload it.

-p
--panic-gate
--panicgate
     Applies the settings directly instead of transitioning into the initial settings. There is not option for doing this when the program exists. But you press Control+c twice, or send SIGTERM twice, to skip transition into default settings.

-h
-?
--help
     Prints help information.

-C
--copying
--copyright
     Prints copyright information.

-W
--warranty
     Prints non-warranty information, included in the copyright information.

-v
--version
     Prints the name of the program and the installed version of the program

Blueshift also supports a few options for ad-hoc settings. These are ignored (unless fetched by the configuration file) if -c (--configurations) is used.

-g
--gamma RGB
     Apply gamma correction to the colour curves. All values in the three colour curves are raised to the power of 1 divided by RGB. Assuming no values in the curves are larger than 1 (100 %) the curves are bent upwards if RGB is larger than 1.

-g
--gamma R:G:B
     This works as --gamma RGB, except the gamma is applied separately for the three colour curves. If we want to apply the 0,9 gamma to the red colour component, and 1,1 and 1,2 for the green and blue colour components, respectively use -g 0.9:1.1:1.2 or -gamma 0.9:1.1:1.2.

-b
--brightness RGB
     This multiplies all values in the colour curves with RGB, effectively making the display RGB times as bright. Values larger than 1, will be clipped to 1. This is indented to be used to make the screen slightly darker during the night.

-b
--brightness R:G:B
     This option is to --brightness RGB as --gamma R:G:B is to --gamma RGB.

+b
++brightness Y
     This option works as --brightness RGB, except the CIE xyY colour spaces is used instead of sRGB and will probably make the colour curves look better.

-t
--temperature TEMP
     Changes the colour tempurature to TEMP Kelvin. The standard colour tempurature is 6500 K (Or actually 6504 K using revised constants in Planck's law). If not specified, the colour temperature will be 3700 K during high night and 6500 K during the high day.

-l
--location LAT:LON
     Specify your geographical coordinates. This is used to determine how dark it is outside. LAT is the latitude, floating point measured in degrees celestial northwards from the equator. It is negative if you are on the southern hemisphere. LON is the longitude, floating point measured in degrees eastwards from Greenwich. Negative if you are on the west side of the Earth.

-r
--reset
     Transition from the specified settings to normal, clean, settings.

-o
--output
--crtc CRTC
     Select CRTC to apply changes to. This is comma separated list, and multiple options may be used. It is best to start one instance per monitor with colour calibration.

     Be aware than under X — using RandR — the primary monitor is reported to have the zeroth CRTC. But under TTY — using DRM — this is no concept of primary monitors, and thus the CRTC indices can slightly different.

-g, -b, +b, and -t can be use twice, each, to use different settings during the night and during the day. While this is possible for gamma, it is not recommended. The purpose of gamma is to adjust the same error that are present in minors and make all colours look correct in relation to each other.

Signals
*******

blueshift, by default in continuous mode, implements special support for three signals:

SIGTERM
     Fades out the settings and exits the first time SIGTERM is received. If SIGTERM is received again, Blueshift immediately resets effects and exits.

     Control+c is treated as SIGTERM.

SIGTSTP
SIGCONT
     Blueshift does implement special handling of the termporary stop signal (SIGTSTP), or continue signal (SIGCONT). So if you send SIGTSTP to Blueshift it pause until you send SIGCONT.

     With usual TTY settings, the terminal sends SIGTSTP when Control+z is processed. Shells can send SIGCONT if you type either of %, fg, %blueshift or fg blueshift. bg or bg blueshift can be used to continue in the background instead of in the foreground.

SIGUSR1
     Reloads the configuration script.

SIGUSR2
     Disables or enables Blueshift.

Configuration API
*****************

Configuration variables
=======================

Blueshift has three colour curves:

r_curve
     The curve for the red colour component.

g_curve
     The curve for the green colour component.

b_curve
     The curve for the blue colour component.

These are i_size sized floating point lists, where 0 is the darkest colour and 1 is the brightest colour. Values outside this range are clipped unless clip_result is set to False. By calling clip this clipping is done independently of the value of clip_result. clip optionally takes one or three arguments, if one, nothing will happen if it is False, if three, nothing will happen for the red, green and blue colour curves if the first, second and third arguments, respectively, is False. When applied these values are automatically translated to appropriate integer values: [0, o_size - 1].

Additionally if the variable panicgate is True, there is no fading when the program starts. And conf_opts is a list of command line arguments passed onto the configuration script; and conf_storage is a dictionary can be used to store information is required to survive a configuration reload, such as replaced functions.

If you want to use the settings intended for ad-hoc mode, set uses_adhoc_opts to True. This lets you use parser, which is an instance of ArgParser (from the argparser library) which parser and support_alternatives already invoked, without a warning being printed. If you do not do this, parser will be None at the time periodically is first invoked by Blueshift.

Colour curve manipulators
=========================

Blueshift provides a set of functions to manipulate these curves:

rgb_contrast(rgb)
     Adjusts the contrast to rgb. This function assumes the black is 0, and white is 1, so you should apply this before brightness.

     Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point.

rgb_contrast(r, g, b)
     Adjusts the contrast to r, g and b on the red, green and blue colour curves, respectively. This function assumes the black is 0, and white is 1, so you should apply this before brightness.

     Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point.

cie_contrast(rgb)
     Adjusts the contrast to rgb. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space. This function assumes the black is 0, and white is 1, so you should apply this before brightness.

     Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point.

cie_contrast(r, g, b)
     Adjusts the contrast to r, g and b on the red, green and blue colour curves, respectively. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space. This function assumes the black is 0, and white is 1, so you should apply this before brightness.

     Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point.

rgb_brightness(rgb)
     Adjusts the brightness to rgb. Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point.

     Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point.

rgb_brightness(r, g, b)
     Adjusts the brightness to r, g and b on the red, green and blue colour curves, respectively.

     Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point.

cie_brightness(rgb)
     Adjusts the brightness to rgb. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space.

     Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point.

cie_brightness(r, g, b)
     Adjusts the brightness to r, g and b on the red, green and blue colour curves, respectively. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space.

     Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point.

linearise()
     Converts the colour curves from sRGB to linear RGB. sRGB is the default colour space.

linearise(rgb)
     Converts the colour curves from sRGB to linear RGB if rgb is True. sRGB is the default colour space.

linearise(r, g, b)
     Converts the colour curves from sRGB to linear RGB, but only for the red, green and blue colour curves if red, green, blue is True, respectively. sRGB is the default colour space.

standardise()
     Converts the colour curves from linear RGB to sRGB, the default colour space.

standardise(rgb)
     Converts the colour curves from linear RGB to sRGB, the default colour space, if rgb is True.

standardise(r, g, b)
     Converts the colour curves from linear RGB to sRGB, the default colour space, but only for the red, green and blue colour curves if red, green, blue is True, respectively.

gamma(rgb)
     Adjusts the gamma to rgb.

gamma(r, g, b)
     Adjusts the gamma to r, g and b on the red, green and blue colour curves, respectively.

negative()
     Reverse the colour curves on the encoding axis. This creates a negative image with preserved gamma.

negative(rgb)
     Reverse the colour curves on the encoding axis if rgb is True.

negative(r, g, b)
     Reverse the red, green and blue colour curves on the encoding axis if r, g and b are True, respectively.

rgb_invert()
     Inverts the all values on the colour curves. This creates a negative image with inverted gamma.

rgb_invert(rgb)
     Inverts the all values on the colour curves if rgb is True.

rgb_invert(r, g, b)
     Inverts the all values on the red, green and blue colour curves if r, g and b are True, respectively.

cie_invert()
     Inverts the all values on the colour curves using the CIE xyY colour space instead of sRGB.

cie_invert(rgb)
     Inverts the all values on the colour curves using the CIE xyY colour space instead of sRGB, if rgb is true.

cie_invert(r, g, b)
     Inverts the all values on the red, green and blue colour  curves using the CIE xyY colour space instead of sRGB if r, g and b are True, respectively.

sigmoid(rgb)
     An inverted sigmoid curve function is applied to the values of in colour curves if rgb is not None, rgb is the sigmoid curve multiplier.

sigmoid(r, g, b)
     An inverted sigmoid curve function is applied to the values of in the red, green and blue colour curves if r, g and b are not None, respectively. r, g and b are the sigmoid curve multipliers for the red, green and blue colour curves, respectively.

rgb_limits(rgb_min, rgb_max)
     Changes the black point to rgb_min, and the white point to rgb_max.

     rgb_min corresponds to the brightness on monitor control panels used to calibrate the black point. rgb_max corresponds to the contrast on monitor control panels used to calibrate the white point.

rgb_limits(r_min, r_max, g_min, g_max, b_min, b_max)
     Changes the black point to (r_min, g_min, b_min), and the white point to (r_max, g_max, b_max).

cie_limits(rgb_min, rgb_max)
     Changes the black point to rgb_min, and the white point to rgb_max, using the CIE xyY colour space instead of sRGB.

cie_limits(r_min, r_max, g_min, g_max, b_min, b_max)
     Changes the black point to (r_min, g_min, b_min), and the white point to (r_max, g_max, b_max), using the CIE xyY colour space instead of sRGB.

manipulate(rgb)
     Applies the function rgb : float -> float to the colour curves. Nothing is done if rgb is None.

manipulate(r, g, b)
     Applies the functions r, g and b : float -> float to the red, green and blue colour curves, respectively. Nothing is done for the red, green and blue colour curves if red, green and blue are None, respectively.

cie_manipulate(rgb)
     Applies the function rgb : float -> float to Y component (illumination) of the colour curves when converted to CIE xyY. Nothing is done if rgb is None.

cie_manipulate(r, g, b)
     Applies the function r, g and b : float -> float to Y component (illumination) of the red, green and blue colour curves, respectively, when converted to CIE xyY. Nothing is done for the red, green and blue colour curves if red, green and blue are None, respectively.

temperature(temperature, algorithm)
     Applies the a blackbody colour temperature of temperature (Actually multiplied by 1,000556328, due to revisions of natural constants.) Kelvin. Where the white point for that temperature is calculates by the function algorithm : temperature -> (red, green, blue). When the white point has been calculates, its components are used as parameters in a componentwise brightness adjustment.

     There are a few algorithm for calculating the white point included:

     series_d(temperature)
          Can only calculate the white point correctly for temperatures inside [4000, 7000]. The CIE illuminant series D is used to calculate the white point.

     simple_whitepoint(temperature)
          Can only calculate the white point accurately for temperatures inside [1000, 40000]. A mathematical model of the cmf_10deg function is used.

     cmf_2deg(temperature)
          Uses a lookup table with linear interpolation to calculate temperatures inside [1000, 40000]. CIE 1931 2 degree CMF is used.

     cmf_10deg(temperature)
          Uses a lookup table with linear interpolation to calculate temperatures inside [1000, 40000]. CIE 1964 10 degree CMF is used. This is the preferred algorithm.

     redshift(temperature, old_version, linear_interpolation = False)
          Uses the lookup table from Redshift with linear interpolation. If old_version is True the table Redshift<=1.8 is used, which is limited to [1000, 10000], and is not that accurate. Otherwise (the default) the table from Redshift>1.8 is used, which is limited to [1000, 25100], and is accurate.

          If linear_interpolation is False (the default) the sRGB colour space is used for interpolation, otherwise linear RGB is used.

     Some of these algorithms (including cmf_10deg) are not very good by themself and should be wrapped with divide_by_maximum or clip_whitepoint ((red, green, blue) -> (red, green, blue) functions.) For example, instead of using cmf_10deg, you can use lambda t : divide_by_maximum(cmf_10deg(t)).

lower_resolution(x, y)
     Emulate low resolution. x is the number of colours to emulate that each subpixel can have. y does the same thing as x, except on the output axis rather than the encoding axis. For arguments taht are set to None, the default value will be used.

lower_resolution(rx, ry, gx, gy, bx, by)
     This works the same way as lower_resolution(x, y), except the subpixels are controlled individually. rx and ry are x and y for the red subpixel, and analogously for gx and gy for green, and bx and by for blue. For arguments taht are set to None, the default value will be used.

Keep in mind that the order your call the function matters. For example, adjusting the gamma before the brightness does not yeild the same result as in the reverse order, the latter is the correct way to apply gamma correction.

Before performing adjusts you must (not required the very first time) reset the curves by invoking start_over (no parameters.) Otherwise the adjustments will accumulate.

Custom colour curve manipulators
================================

If you want to write your own functions curves(r, g, b) returns a tuple containing the tuples (r_curve, r), (g_curve, g) and (b_curve, b). To make this easier Blueshift provies a set of functions used to convert colour space:

linear_to_standard(r, g, b)
     Convert [0, 1] linear RGB to [0, 1] sRGB

standard_to_linear(r, g, b)
     Convert [0, 1] sRGB to [0, 1] linear RGB

ciexyy_to_ciexyz(x, y, Y)
     Convert CIE xyY to CIE XYZ

ciexyz_to_ciexyy(X, Y, Z)
     Convert CIE XYZ to CIE xyY

ciexyz_to_linear(X, Y, Z)
     Convert CIE XYZ to [0, 1] linear RGB

linear_to_ciexyz(r, g, b)
     Convert [0, 1] linear RGB to CIE XYZ

srgb_to_ciexyy(r, g, b)
     Convert [0, 1] sRGB to CIE xyY

ciexyy_to_srgb(x, y, Y)
     Convert CIE xyY to [0, 1] sRGB

ciexyz_to_cielab(x, y, z)
     Convert CIE XYZ to CIE L*a*b*

cielab_to_xiexyz(l, a, b)
     Convert CIE L*a*b* to CIE XYZ

All these functions return lists with the three colour components, not tuples. Input and output is one colour instance.

If you want to calculated the distance (difference) between two colours, you can use delta_e. It has two parameters, each is red–green–blue-tuple of an sRGB colour. The just notice difference is circa 2,3.

Preexisting adjustments
=======================

If you have an ICC profile for calibration (applied last) or want to use one for as a video filter (applied first), the function load_icc can be used to load an ICC profile file. load_icc takes one argument, the pathname of the ICC profile file; the function returns a fuction that can be invoked to apply the profile.

Alternatively, you can use either of the functions:

parse_icc(data)
     Parse raw (series of bytes) ICC profile data into a function that applies the profile when invoked.

get_current_icc_raw()
     Load the raw data for the currently applied ICC profiles, stored on the X server. This function returns a list of 3-tuples, each tuple contains the index of a screen, the index of a monitor and the raw data (series of bytes) of the ICC profile for indicated monitor on the indicated screen. Monitors without profiles are not listed. Associated ICC profile is mapped as properties of the root window of X screens. The ICC profile of a primary monitor in a screen is saved as a property named _ICC_PROFILE, the secondary monitor is stored as _ICC_PROFILE_1, the tertiary monitor is stored as _ICC_PROFILE_2, and so on.

get_current_icc()
     This function works like get_current_icc_raw, except rather than returning raw profile data it returns functions that apply the profiles when invoked.

If you have multiple profiles you want to interpolate or want to, possible with an interpolation, apply a profile partially, that is, interpolate between it an an identity profile, you can use the function make_icc_interpolation. It takes your profiles as one argument, as a list, and outputs a function that applies an interpolation of the profiles, it takes to arguments: the timepoint and the filter alpha. The timepoint is normally a [0, 1] floating point of the dayness level, this means that you only have two ICC profiles, but you have multiple profiles, in such case profile the floor of the timepoint value is takes as the index of the first profile to use in the interpolation as well as  the following profile (first profile if the last profile was select). They are interpolated linearly. The filter alpha is a [0, 1] floating point of the degree to which the profile should be applied.

If you want to apply your adjustments on top of the current colour adjustments, you can use the functions randr_get or vidmode_get. randr_get and vidmode_get have optional two parameters, crtc and screen, which are the CRTC of the monitor to read from, and the screen to which the monitor belongs, respectively. The functions return a parameterless function that applies adjustsments that were applied at the time of invokation of randr_get or vidmode_get to the current working curves.

Applying colour curves
======================

To apply a colour curve to the display server, invoke the randr function, or vidmode (vidmode has the same API as randr, but it only supports using the zeroth CRTC.); print_curves can be used to print the curves to stdout instead (for debugging). These functions apply the curves to all monitors in the default screen (screen 0), put you can also use select monitors by specifying each monitor in as separate arguments. The monitors are indexed from zero. The screen by can be selected by adding the argument screen = X, where X is the index of the screen. print_curves has a third optional parameters: compact, if it is set to True, the curves will be printed with run-length encoding.

If you want to write your own curve flushing fucntion translate_to_integers can be used, it returned the colour curves converted from floating point lists to integer lists in a tuple of three (red, green and blue.) Replace the parameterless function close_c_bindings to make it free all used resource, this is invoked when Blueshift exits.

When Blueshift exists, it invoked the parameterless function reset which you should replace. By default it resets the colour curves and flushes it to all monitors. To restrict which monitors it applies the changes to replace monitor_controller with a parameterless function that sends the colour curves to the desired monitors to the display server. This is only done if Blueshift runs in continuous mode.

Hardware detection
==================

To support multiple monitors in a dynamic way, the function list_screens can be used. list_screens has one optional parameter and returns the an instance of the class Screens. Instances of Screens have one variable: screens, a list of instances of the class Screen. The index of each screens is their index in screens. list_screens's parameter, method, selects the method and defaults to `randr', it also supports the method `drm'.

Instances of the class Screen have two variables: crtc_count, the number of CRT controllers used within the screen, and outputs, a list of all output ports as instances of the class Output. Instances of Output have six variables:

name
     The name of the output port.

connected
     Whether the output is known to be connected to a monitor.

widthmm
     The physical width of the monitor, measured in millimetres. None if unknown or if not connected.

heightmm
     The physical height of the monitor, measured in millimetres. None if unknown or if not connected.

crtc
     The CRT controller index. None if not connected.

screen
     The screen index. None if not used.

edid
     The extended display identification data of the monitor in lower case hexadecimal representations. None if not used or not found. If the monitor is used it is probably found because it is needed for plug and play support of the monitor.

Screens and Screen provide a set of functions for finding the output, and traversal the CRTC and screen, a monitor is connected to:

find_by_crtc(index)
     Matches outputs by CRTC index. If index is None, it will find unused outputs.

find_by_name(name)
     Matches outputs by output name.

find_by_size(widthmm, heightmm)
     Matches outputs by physical size of the monitor. widthmm and heightmm are the monitor's physical width and heigth, respectively, measured in millimetres. IF widthmm and heightmm are None it will find unused outputs and outputs whether the monitor's size is unknown.

find_by_connected(status)
     Matches outputs that are known to be in used (if status is True) or outputs that are either unused or not known whether they are used or not (if status is False.)

find_by_edid(name)
     Matches outputs by monitor extended display identification data.

These functions returns a list of matching Output:s. The list is empty if non are found.

Backlight
=========

blueshift offers support for adjusting the backlight on monitors through Linux's sysfs. When available this preferable to adjusting the brightness. It does however have two drawbacks: it interferes with manual adjustments and depending on the backlight controller you may have very few backlight levels available.

To list the available backlight controllers, run the function list_backlights, it has mo parameters and returns a list of controller names.

To use a backlight controller, invoke the contructor of the class Backlight. It takes one manditory argument, the backlight controller either by name or path, and two optional arguments: adjbacklight and minimum. adjbacklight is booleanic, if True the command adjbacklight from the package with the same name will be used to set the backlight, rather than blueshift setting it by itself; this lets you adjust the backlight without root permissions and without the administrator justing the permission of /sys/class/backlight/*/brightness files. minimum is an integer and is zero by default, which is the lowest logical value to have. minimum raises the minimum value from zero to avaoid the backlight from getting stuck at zero when reached, as happens on some controllers.

Instances of the class Backlight have one variable: maximum. maximum is an integer and is the highest inclusive brightness level. Instances also have two properties: actual and brightness. actual is read-only and gets the current actual backlight level. brightness can both be read and write and gets or sets the current backlight level. Both are integer properties.

Continuous mode
===============

In continuous mode, there are some interesting variables you can adjust at any time:

wait_period
     The number of seconds to wait before updating the colour curves again. This is a floating point variable.

fadein_time
     he number of seconds used to fade in on start, None for no fading. This is a floating point variable.

fadeout_time
     The number of seconds used to fade out on exit, None for no fading. This is a floating point variable.

fadein_steps
     The number of steps in the fade in phase, if any.

fadeout_steps
     The number of steps in the fade out phase, if any.

running
     Set to False to exit the program. This is normally done when Control+c is pressed or a SIGTERM signal has been received.

panic
     This variable only have effect if running is False. If this variable is set to True, the program will immediately run reset and exit. This is normally done the second time Control+c is pressed or the second time a SIGTERM signal has been received. (Or if both has happend.)

The parameterless function continuous_run, may replace if you want to do something very special, is invoked to run the continuous mode, it the program shall run in continuous mode. Which is determined by whether the function periodically is defined. Updates to continuous_run are ignored when SIGUSR1 signals are received.

You can also replace the function signal_SIGTERM. continuous_run sets up the program to run it when the program receive a SIGTERM signal. continuous_run also invokes it when Control+c is pressed. signal_SIGTERM has two parameters, the second can be ignored as it is normally None; the first parameter is the signal that is received (an integer), and zero if Control+c has been pressed.

Similarly signal_SIGUSR1 and signal_SIGUSR2 are invoked when the programs received a SIGUSR1 signal or a SIGUSR2 signal, respectively. SIGUSR1 reloads the configurations and SIGUSR2 enables or disables Blueshift.

To run in continuous mode, you must implement the function periodically. It takes 8 positional arguments:

year
     The year.

month
     The month, 1 = January, 12 = December.

day
     The day, minimum value is 1, probable maximum value is 31. Theoretically, but most probably not, a change in the calender system could happen and the month's could length could be increased. This has happend once, giving us 1712-(02)Feb-30.

hour
     The hour, minimum value is 0, maximum value is 23.

minute
     The minute, minimum value is 0, maximum value is 59.

second
     The second, minimum value is 0, probable maximum value is 60. We can get 60, or even higher (but that has never happend yet) due to leapseconds. A minutes length could also be shortend, but that has never happend yet either.

weekday
     The weekday, 1 = Monday, 7 = Sunday.

fade
     Normally, periodically is invoked with fade set to None. This is note the case when the program starts or exits. When fade is not None, wait_period is not honoured.

     Blueshift can use periodically to fade into a state when it start or exits. fade can either be negative, zero or positive or None, but the magnitude of value cannot exceed 1. When Blueshift starts, the function will be invoked multiple with the time parameters of the time it is invoked and each time fade will increase towards 1, starting at 0, when the value is 1, the settings should be applied to 100 %. After this this function will be invoked once again with fade being None. When Blueshift exits the same behaviour is used except, fade decrease towards -1 but start slightly below 0, when -1 is reached all settings should be normal. Then Blueshift will not invoke this function with fade being None, instead it will by itself revert all settings, by calling reset and quit.

Python does not specify that the exceptions can happen, but do not could on them not. Python's documentation could be work, or the API could change.

If you want higher time precision --- the time parameters are integers --- you are welcome to use Python's time API. periodically will never be invoked with fake time. Just do not mix as you could theoretically get on two different seconds, minutes, hours, or even days, months or years, the delay between Blueshift's timestamp and yours could overlap an increase in the second.

Solar time
==========

Blueshift includes a simple way to get the Sun's position. The function sun(latitude, longitude) returns the visibility of the Sun as an [0, 1] floating point. It has three optional, additional, parameters:

t = None
     The time in Julian Centuries.

low = -6.0
     The Suns elevation at the limit to high night, that is, the highest possible position (measured in degrees) of the Sun before it becomes visible.

high = 3.0
     The Suns elevation at the limit to high day, that is, the lowest possible position (measured in degrees) of the before it starts becoming less visible (twilight.)

To convert a time to Julian Centuries, you can use the function epoch_to_julian_centuries. It takes one argument, the POSIX time, that is, the number of seconds that have elapsed since 1970-(01)Jan-01 00:00:00 UTC, not counting leap seconds.

A set of functions that are used to calculate the Sun's are provided:

julian_day_to_epoch(t)
     Converts a Julian Day timestamp to a POSIX time timestamp.

epoch_to_julian_day(t)
     Converts a POSIX time timestamp to a Julian Day timestamp.

julian_day_to_julian_centuries(t)
     Converts a Julian Day timestamp to a Julian Centuries timestamp.

julian_centuries_to_julian_day(t)
     Converts a Julian Centuries timestamp to a Julian Day timestamp.

epoch_to_julian_centuries(t)
     Converts a POSIX time timestamp to a Julian Centuries timestamp.

julian_centuries_to_epoch(t)
     Converts a Julian Centuries timestamp to a POSIX time timestamp.

epoch()
     Returns the current time in POSIX time.

julian_day()
     Returns the current time in Julian Day time.

julian_centuries()
     Returns the current time in Julian Centuries time (100 Julian days since J2000.)

radians(deg)
     Converts from degrees to radians.

degrees(rad)
     Converts from radians to degrees.

sun_geometric_mean_longitude(t)
     Calculates the Sun's geometric mean longitude, in radians.

sun_geometric_mean_anomaly(t)
     Calculates the Sun's geometric mean anomaly, in radians.

earth_orbit_eccentricity(t)
     Calculates the Earth's orbit eccentricity.

sun_equation_of_centre(t)
     Calculates the Sun's equation of the centre, the difference between the true anomaly and the mean anomaly, in radians.

sun_real_longitude(t)
     Calculates the Sun's real longitudinal position, in radians.

sun_apparent_longitude(t)
     Calculates the Sun's apparent longitudinal position, in radians.

mean_ecliptic_obliquity(t)
     Calculates the mean ecliptic obliquity, in radians, of the Sun's apparent motion without variation correction.

corrected_mean_ecliptic_obliquity(t)
     Calculates the mean ecliptic obliquity, in radians, of the Sun's apparent motion with variation correction.

solar_declination(t)
     Calculates the Sun's declination, in radians.

equation_of_time(t)
     Calculates the equation of time, the discrepancy between apparent and mean solar time, in degrees.

hour_angle_from_elevation(latitude, declination, elevation)
     Calculates the solar hour angle from the Sun's elevation.

elevation_from_hour_angle(latitude, declination, hour_angle)
     Calculates the Sun's elevation from the solar hour angle.

time_of_solar_noon(t, longitude)
     Calculates the time of the closest solar noon.

time_of_solar_elevation(t, noon, latitude, longitude, elevation)
     Calculates the time the Sun has the apparent elevation elevation, in degrees, at the geographical position (latitude, longitude). noon is the time the closest the solar noon.

solar_elevation_from_time(t, latitude, longitude)
     Calculates the Suns elevation, in degrees, as apparent from the geographical position (latitude, longitude).

solar_elevation(latitude, longitude, t = None)
     Calculates the same thing as solar_elevation_from_time, except the time is optional and defaults to the current time.

For all functions beneath degrees, t is the time in Julian Centuries. All parameters are floating point and may not be None, except for in solar_elevation, as specified.

Blueshift provides constants with important elevations of the Sun during twilight.

SOLAR_ELEVATION_SUNSET_SUNRISE
     The Sun's elevation at sunset and sunrise, measured in degrees.

SOLAR_ELEVATION_CIVIL_DUSK_DAWN
     The Sun's elevation at civil dusk and civil dawn, measured in degrees.

SOLAR_ELEVATION_NAUTICAL_DUSK_DAWN
     The Sun's elevation at nautical dusk and nautical dawn, measured in degrees.

SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN
     The Sun's elevation at astronomical dusk and astronomical dawn, measured in degrees.

SOLAR_ELEVATION_RANGE_TWILIGHT
     The Sun's lowest and highest elevation during all periods of twilight, measured in degrees.

SOLAR_ELEVATION_RANGE_CIVIL_TWILIGHT
     The Sun's lowest and highest elevation during civil twilight, measured in degrees.

SOLAR_ELEVATION_RANGE_NAUTICAL_TWILIGHT
     The Sun's lowest and highest elevation during nautical twilight, measured in degrees.

SOLAR_ELEVATION_RANGE_ASTRONOMICAL_TWILIGHT
     The Sun's lowest and highest elevation during astronomical twilight, measured in degrees.

Weather
=======

Blueshift includes the function whether which gives a brief weather report. whether takes one argument: the International Civil Aviation Organization (ICAO) code of your closest airport. If Blueshift is unable to download the latest METAR (Meteorological Aerodrome Report) whether will return None. If successful it will return the sky conditions (assumed clear if not included in the report,) the visiblity range and the weather. These components are returned as a 3-tuple with the components in the same order as mentioned.

The sky condition is returned as a string. And can be either of: `clear', `mostly clear', `partly cloudy', `mostly cloudy', `overcast' and `obscured'.

If the visibility range is not included in the report it will be None; if it is included in the report it will be an int–float-tuple. The first element in the tuple will be either -1, 0 or 1, and the second element will be an approximate visibility range measured in kilometers. If the first element is -1 this measurement is an upper bound, if it it 1 the measurement is an lower bound, and if it is 0 the measurement is approximate.

The weather is reported as an string list, that can and often is empty.

Running without X
=================

Blueshift has the capability of operating, in fullness, without a display server like X. Using Direct Rendering Manager (DRM), in Linux, Blueshift is able to get monitor information and get and set the colour curves for each monitor, just as it is under X using RandR; except this only works if the active VT does not have a display server.

There are however a few differences:

  * DRM returns more exact physical monitor dimensions. For example, my CRT:s have a visible area of slightly (off by a millimeter or two) larger than 400 mm by 300 mm, but RandR returns 364 mm by 291 mm which is an aspect ratio of 5:4 rather than 4:3.

  * DRM does not have the concept of primary monitors, which RandR has. RandR changes the indices of the CRTC:s so that the primary monitors have zero as their indices.

  * DRM does not have a concept of screens, but it does have the concept of graphic cards which is missing from RandR. In practice, these are however equivalent, and therefore the DRM methods which have a RandR version caps the parameters for graphic cards for screen rather than card to maintain API compatibility with the RandR versions.

Unless your system administator have change the requires permissions of devices in /dev/dri, you need to be a member of the group video.

Blueshift checks for you whether you are running in a TTY by checking the DISPLAY environment variable, and sets the variable ttymode. That is Blueshift will set the variable ttymode to True if it thinks that it is not connected to a display server, and False otherwise. Not that it is still possible to use the DRM functions when connected to a display server: nothing will happen because, all requests to change the colour curves will be rejected. However if you switch VT to a TTY, the requests will be accepted and the requests to the display server will be ignored until you reenter the VT with that display.

The DRM equivalent to the RandR functions randr (applying colour curves) and randr_get (reading current colour curves) are drm and drm_get, respectively. The paramers are exactly the same for the DRM functions as they are for the RandR functions.

The function list_screens, which lists all screens, CRTC:s and outputs, runs list_screens_randr by default. By invoking list_screens with the argument `drm' it will instead run list_screens_drm. It will return equivalent data, except with it calls screens are actually graphics cards, and as mentioned, the CRTC:s may have different indices and the monitors may have different physical sizes. But the names of the outputs (which are called connectors in DRM contected, but for this function it will still be called outputs for API compatibility with the RandR version) by be different.

Optimising
==========

If you have adjustments that reused, perhaps between adjustments or shared between monitors. You can reduce the amount of calculates your script needs to do my reusing made adjustments.

To snapshot the current state of the working colour curves (those that are not applied yet) you can use the function store. It is parameterless and returns a 3-tuple of the colour curves. To reset the to curves stored by store you can use the function restore:

     stored = store()
     # To stuff ...
     restore(stored)

You can also make a function of the stored settings. A function like this will apply the adjustments on top of current adjustments. To do this input the output of store into the function functionise:

     brightness(0.75)
     stored = functionise(store())
     stored()
     stored()
     # Now the brightness is 0,75 to the power of 3 = 0,421875.

Note that the functionise(stored)() might be heavier than applying the adjustments by invoking them.

Configuration examples
**********************

The Blueshift packages comes with a set of example configuration scripts. These are installed to /usr/share/doc/blueshift/examples. These examples include:

backlight
     This example demonstrates how to use adjust backlight without interfering to much with manual adjustments. The example with oscillate the backlight between 50 % and 100 % but include any manual adjustments.

battery
     This is a small example that inverts the colours when the battery's capacity is low. It includes very little from the configuration API but uses Linux's sysfs to determine the battery's capacity an charging status.

comprehensive
     This example includes most of Blueshift's features and lets you use them very generically. It does include all basic features of Blueshift.

crtc-detection
     This is a small example that identifies which monitors you have plugged in to the computer, and applied their proper calibration.

crtc-searching
     This example uses option parsing and CRTC searching. Screens.find_by_crtc and Screen.find_by_crtc, are not used, those are not useful for anything. They can be used for seaching the number of connected monitors, but Screen.crtc_count is much more effective.

current-settings
     This is a small example demonstrates how the currents settings can be read and transitioned from.

darkroom
     This is a samll example inverts the colours and then makes the monitors red and dim. It is exited by running again with Blueshift's -r (--reset) option.

icc-profile-atoms
     This is a tiny example that demonstrates how to read and use the _ICC_PROFILE(_N) atoms for X screens.

logarithmic
     A very small example that uses free function modifier and temporary curve linearisation to make the colour curves logarithmic.

modes
     This example can be used to name a mode you want to use, without having to use Blueshift's -c option and give a pathname. You will only need to give a filename. In this example, those modes are installed in the directory $XDG_CONFIG_HOME/blueshift-modes, and the default mode is named default.

sleepmode
     This example graciously fades out the screen on start and in on exit. It is a nice alternative to turning off the monitor, just press Control+c when you wake up.

stored-settings
     This example demonstrates how settings can be stored and be transition from later.

textconf
textconf.conf
     This example uses a text based configuration file to make it easier for non-programmers to use Blueshift. It will read a file with the same pathname just with .conf appended (textconf.conf in this case.) However, if the filename of this file ends with with rc, that part will be removed, for example, if you rename this script to ~/.blueshiftrc it will read ~/.blueshift.conf rather than ~/.blueshiftrc.conf.

threaded
     This is an example demonstrates how you can make a multithreaded configurations script.

weather
     This is a samll example demonstrates how to include weather conditions in your configuration scripts.

xmobar
     This example can be used in xmobar to display the Sun's elevation and to what degree it is day time.

xmonad
     This configuration scripts read the xmonad log to detect which workspace you are viewing. It can also disable adjustments when you are in selected programs such as The GIMP and Inkscape.

xpybar
     This example can be used in xpybar to display the Sun's elevation and to what degree it is day time.

Related software
****************

blueshift by itself have a wide range of feature, but it can be extended further by additional software:

blueshift-tray
     A wrapper for Blueshift that makes it easy to temporarily activate and deactivate Blueshift by placing it in the X system tray.

blueshift-curse
     (Under development)

     blueshift-curse is an extension for Blueshift that can be used by configuration scripts to make it possible for other applications, included an ncurses interface that comes with it, to do modifications to the configurations. blueshift-curse uses domain sockets for interprocess communication.

blueshift-vt-cues
     (Development planned)

     blueshift-vt-cues is an extension for Blueshift that, with the support of a daemon, can listen for virtual terminal (VT) switching events. blueshift-vt-cues uses domain sockets for interprocess communication between the daemons and users. It provides information about the currently active VT such as VT number, wich user has ownership of the VT and either it is a text (or framebuffer) session or a graphical session (such as X, Wayland and Mir.) blueshift-vt-cues also provides the capability of informing the Blueshift configuration scripts whether or not they should reset the the adjustments to make sure that one user's adjustments does not interfere with another user's adjustments.

If you want to extend the capabilities of Blueshift for your configuration scripts there are some library packages that can be of particular interest:

python3-xlib
     X library for Python based on the Xlib library.

xpyb
     (Not ported to Python 3)

     X library for Python based on the XCB library.

xpybutil
     (Not ported to Python 3)

     A Python rendition of xcb-util including EWMH, ICCCM, key binding, Xinerama, &c.

ooxcb
     (Not ported to Python 3)

     An object-oriented X library for Python based on xpyb.

pygtk
     (Not ported to Python 3)

     GTK+ 2 bindings for Python.

python-gobject
     GTK+ 3 bindings for Python.

python2-geoclue
     (Not ported to Python 3)

     GeoClue library for Python, can be used to get your geographical position. GeoClue uses D-Bus, and can use multiple position providers:

       * GPS: Position information from a Global Positioning System receiver via gpsd and gypsy.

       * GSM: Position information from cellular network connection.

       * Plazes: Position information from the Plazes Wi-Fi location service.

       * Hostip: Position information based on IP address.

       * Manual: User-provided position information.

python-dbus
     Python bindings for D-Bus.

python-networkmanager
     Python interface to NetworkManager.

locateme
     (Under development)

     A command to get your geographical position.

Terminology
***********

Terminology related to Blueshift:

Ad-hoc mode
One time mode
     Running Blueshift without a configuration script.

Configuration mode
     Running Blueshift with a configuration script.

Configuration script
     Blueshift provides a mechanism for adjusting colours on the monitors. Configuration scripts, invoked by Blueshift, implements the policy for doing so.

Continuous mode
     Running Blueshift such at it applies adjustments but than continues to run and applies now (time dependent) adjustments every now and then until the user terminates Blueshift.

One shot mode
     Running Blueshift such at it applies adjustments and than exits.

Panicgate
     Applying adjustments immediately without transitioning. This terminology is borrowed from OpenNTPD.

High day
Day
Daytime
     The time during the day when the Sun elevated to be 100 % visible. The time between sunrise and sunset; when it is full daylight.

High night
Night
Nighttime
     The time during the day when the Sun elevated to be 0 % visible. The time between dusk and dawn; when it is complete darkness.

GNU Free Documentation License
******************************

     [file fdl.texinfo not included]