2021-01-28 00:25:47 +00:00
|
|
|
{ config, lib, pkgs, moduleName, mainSection, programName, defaultPackage
|
|
|
|
, examplePackage, mainExecutable, appletExecutable, xdgConfigFilePath
|
|
|
|
, serviceDocumentation }:
|
2017-01-20 18:26:52 +00:00
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
2021-01-23 22:03:57 +00:00
|
|
|
cfg = config.services.${moduleName};
|
2021-01-28 00:25:47 +00:00
|
|
|
settingsFormat = pkgs.formats.ini { };
|
2017-01-20 18:26:52 +00:00
|
|
|
|
2020-02-01 23:39:17 +00:00
|
|
|
in {
|
2022-07-04 09:39:38 +00:00
|
|
|
meta.maintainers = with maintainers; [ rycee thiagokokada ];
|
2017-01-20 18:26:52 +00:00
|
|
|
|
2021-01-28 00:25:47 +00:00
|
|
|
imports = let
|
|
|
|
mkRenamed = old: new:
|
|
|
|
mkRenamedOptionModule ([ "services" moduleName ] ++ old) [
|
|
|
|
"services"
|
|
|
|
moduleName
|
|
|
|
"settings"
|
|
|
|
mainSection
|
|
|
|
new
|
|
|
|
];
|
|
|
|
in [
|
|
|
|
(mkRemovedOptionModule [ "services" moduleName "extraOptions" ]
|
|
|
|
"All ${programName} configuration is now available through services.${moduleName}.settings instead.")
|
|
|
|
(mkRenamed [ "brightness" "day" ] "brightness-day")
|
|
|
|
(mkRenamed [ "brightness" "night" ] "brightness-night")
|
|
|
|
];
|
|
|
|
|
2021-01-23 22:03:57 +00:00
|
|
|
options = {
|
2021-01-28 00:25:47 +00:00
|
|
|
enable = mkEnableOption programName;
|
|
|
|
|
|
|
|
dawnTime = mkOption {
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
default = null;
|
|
|
|
example = "6:00-7:45";
|
2021-01-28 00:25:47 +00:00
|
|
|
description = ''
|
2021-01-28 00:25:47 +00:00
|
|
|
Set the time interval of dawn manually.
|
|
|
|
The times must be specified as HH:MM in 24-hour format.
|
2021-01-28 00:25:47 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2021-01-28 00:25:47 +00:00
|
|
|
duskTime = mkOption {
|
2021-02-07 09:20:03 +00:00
|
|
|
type = types.nullOr types.str;
|
2021-01-28 00:25:47 +00:00
|
|
|
default = null;
|
2021-01-28 00:25:47 +00:00
|
|
|
example = "18:35-20:15";
|
|
|
|
description = ''
|
|
|
|
Set the time interval of dusk manually.
|
|
|
|
The times must be specified as HH:MM in 24-hour format.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
latitude = mkOption {
|
|
|
|
type = with types; nullOr (either str float);
|
|
|
|
default = null;
|
2017-01-20 18:26:52 +00:00
|
|
|
description = ''
|
2018-07-13 18:54:20 +00:00
|
|
|
Your current latitude, between <literal>-90.0</literal> and
|
|
|
|
<literal>90.0</literal>. Must be provided along with
|
|
|
|
longitude.
|
2017-01-20 18:26:52 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
longitude = mkOption {
|
2021-01-28 00:25:47 +00:00
|
|
|
type = with types; nullOr (either str float);
|
2018-07-13 18:54:20 +00:00
|
|
|
default = null;
|
2017-01-20 18:26:52 +00:00
|
|
|
description = ''
|
2018-07-13 18:54:20 +00:00
|
|
|
Your current longitude, between <literal>-180.0</literal> and
|
|
|
|
<literal>180.0</literal>. Must be provided along with
|
|
|
|
latitude.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
provider = mkOption {
|
|
|
|
type = types.enum [ "manual" "geoclue2" ];
|
|
|
|
default = "manual";
|
|
|
|
description = ''
|
|
|
|
The location provider to use for determining your location. If set to
|
|
|
|
<literal>manual</literal> you must also provide latitude/longitude.
|
|
|
|
If set to <literal>geoclue2</literal>, you must also enable the global
|
|
|
|
geoclue2 service.
|
2017-01-20 18:26:52 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
temperature = {
|
|
|
|
day = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 5500;
|
|
|
|
description = ''
|
|
|
|
Colour temperature to use during the day, between
|
|
|
|
<literal>1000</literal> and <literal>25000</literal> K.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
night = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 3700;
|
|
|
|
description = ''
|
|
|
|
Colour temperature to use at night, between
|
|
|
|
<literal>1000</literal> and <literal>25000</literal> K.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
package = mkOption {
|
|
|
|
type = types.package;
|
2021-01-23 22:03:57 +00:00
|
|
|
default = defaultPackage;
|
2021-10-09 09:14:08 +00:00
|
|
|
defaultText = literalExpression examplePackage;
|
2017-01-20 18:26:52 +00:00
|
|
|
description = ''
|
2021-01-23 22:03:57 +00:00
|
|
|
${programName} derivation to use.
|
2017-01-20 18:26:52 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2022-09-09 19:25:49 +00:00
|
|
|
enableVerboseLogging = mkEnableOption "verbose service logging";
|
|
|
|
|
2018-01-10 20:31:28 +00:00
|
|
|
tray = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
example = true;
|
|
|
|
description = ''
|
2021-01-23 22:03:57 +00:00
|
|
|
Start the ${appletExecutable} tray applet.
|
2018-01-10 20:31:28 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2021-01-28 00:25:47 +00:00
|
|
|
settings = mkOption {
|
|
|
|
type = types.submodule { freeformType = settingsFormat.type; };
|
|
|
|
default = { };
|
2021-10-09 09:14:08 +00:00
|
|
|
example = literalExpression ''
|
2021-01-28 00:25:47 +00:00
|
|
|
{
|
|
|
|
${mainSection} = {
|
|
|
|
adjustment-method = "randr";
|
|
|
|
};
|
|
|
|
randr = {
|
|
|
|
screen = 0;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
'';
|
2017-01-20 18:26:52 +00:00
|
|
|
description = ''
|
2021-01-28 00:25:47 +00:00
|
|
|
The configuration to pass to ${programName}.
|
|
|
|
Available options for ${programName} described in
|
|
|
|
<citerefentry>
|
|
|
|
<refentrytitle>${moduleName}</refentrytitle>
|
|
|
|
<manvolnum>1</manvolnum>
|
|
|
|
</citerefentry>.
|
2017-01-20 18:26:52 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-01-23 22:03:57 +00:00
|
|
|
config = {
|
2021-07-07 21:24:27 +00:00
|
|
|
assertions = [
|
|
|
|
(hm.assertions.assertPlatform "services.${moduleName}" pkgs
|
|
|
|
platforms.linux)
|
|
|
|
|
|
|
|
{
|
|
|
|
assertion = (cfg.settings ? ${mainSection}.dawn-time || cfg.settings
|
|
|
|
? ${mainSection}.dusk-time)
|
|
|
|
|| (cfg.settings.${mainSection}.location-provider) == "geoclue2"
|
|
|
|
|| ((cfg.settings.${mainSection}.location-provider) == "manual"
|
|
|
|
&& (cfg.settings ? manual.lat || cfg.settings ? manual.lon));
|
|
|
|
message = ''
|
|
|
|
In order for ${programName} to know the time of action, you need to set one of
|
|
|
|
- services.${moduleName}.provider = "geoclue2" for automatically inferring your location
|
|
|
|
(you also need to enable Geoclue2 service separately)
|
|
|
|
- services.${moduleName}.longitude and .latitude for specifying your location manually
|
|
|
|
- services.${moduleName}.dawnTime and .duskTime for specifying the times manually
|
|
|
|
'';
|
|
|
|
}
|
|
|
|
];
|
2019-10-02 20:00:58 +00:00
|
|
|
|
2021-01-28 00:25:47 +00:00
|
|
|
services.${moduleName}.settings = {
|
|
|
|
${mainSection} = {
|
|
|
|
temp-day = cfg.temperature.day;
|
|
|
|
temp-night = cfg.temperature.night;
|
|
|
|
location-provider = cfg.provider;
|
|
|
|
dawn-time = mkIf (cfg.dawnTime != null) cfg.dawnTime;
|
|
|
|
dusk-time = mkIf (cfg.duskTime != null) cfg.duskTime;
|
|
|
|
};
|
|
|
|
manual = mkIf (cfg.provider == "manual") {
|
|
|
|
lat = mkIf (cfg.latitude != null) (toString cfg.latitude);
|
|
|
|
lon = mkIf (cfg.longitude != null) (toString cfg.longitude);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
xdg.configFile.${xdgConfigFilePath}.source =
|
|
|
|
settingsFormat.generate xdgConfigFilePath cfg.settings;
|
|
|
|
|
2021-01-23 22:03:57 +00:00
|
|
|
systemd.user.services.${moduleName} = {
|
2022-08-05 20:55:25 +00:00
|
|
|
Unit = let
|
|
|
|
geoclueAgentService =
|
|
|
|
lib.optional (cfg.provider == "geoclue2") "geoclue-agent.service";
|
|
|
|
in {
|
2021-01-23 22:03:57 +00:00
|
|
|
Description = "${programName} colour temperature adjuster";
|
|
|
|
Documentation = serviceDocumentation;
|
2022-08-05 20:55:25 +00:00
|
|
|
After = [ "graphical-session-pre.target" ] ++ geoclueAgentService;
|
|
|
|
Wants = geoclueAgentService;
|
2017-06-26 16:34:09 +00:00
|
|
|
PartOf = [ "graphical-session.target" ];
|
2017-01-20 18:26:52 +00:00
|
|
|
};
|
|
|
|
|
2020-02-01 23:39:17 +00:00
|
|
|
Install = { WantedBy = [ "graphical-session.target" ]; };
|
2017-01-20 18:26:52 +00:00
|
|
|
|
|
|
|
Service = {
|
2020-02-01 23:39:17 +00:00
|
|
|
ExecStart = let
|
2021-01-23 22:03:57 +00:00
|
|
|
command = if cfg.tray then appletExecutable else mainExecutable;
|
2021-01-28 00:25:47 +00:00
|
|
|
configFullPath = config.xdg.configHome + "/${xdgConfigFilePath}";
|
2022-09-09 19:25:49 +00:00
|
|
|
in "${cfg.package}/bin/${command} " + cli.toGNUCommandLineShell { } {
|
|
|
|
v = cfg.enableVerboseLogging;
|
|
|
|
c = configFullPath;
|
|
|
|
};
|
2017-01-20 18:26:52 +00:00
|
|
|
RestartSec = 3;
|
2020-03-16 15:43:11 +00:00
|
|
|
Restart = "on-failure";
|
2017-01-20 18:26:52 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|